DirectSound以DMO(DirectX Nedua Objects)的方式提供了對原始音頻數據的處理,開發者能夠通過VC6.0里的 來開發自定義的DMO。實際上這個DMO開發嚮導已經不在Visual Studio裡面提供了,並且已經被MFT(Media Foundation Transfor ...
DirectSound以DMO(DirectX Nedua Objects)的方式提供了對原始音頻數據的處理,開發者能夠通過VC6.0里的Audio Effect DMO Wizard
來開發自定義的DMO。實際上這個DMO開發嚮導已經不在Visual Studio裡面提供了,並且已經被MFT(Media Foundation Transforms)替代了,但這個不是我們今天的重點。
除此之外,DirectSound提供了以下標準DMO音效(原諒鄙人對音效這塊不是很瞭解,因此沒有翻譯這些術語):
- Chorus
- Compression
- Distortion
- Echo
- Environmental Reverberation
- Flange
- Gargle
- Parametric Equalizer
- Waves Reverberation
1. 音效使用邏輯
所有標準音效都按照一致的方式來使用,首先先調用DirectSoundCreate8()
獲取設備對象介面並設置協作級別:
if (DirectSoundCreate8(&DSDEVID_DefaultPlayback, &m_directSound8, NULL) != DS_OK) {
throw std::exception("Error: maybe no default audio device in your system");
}
if (m_directSound8->SetCooperativeLevel(windowHandle, DSSCL_PRIORITY) != DS_OK) {
throw std::exception("set cooperative level on default audio device failed!");
}
容納後通過設備對象介面獲取播放聲音的次緩衝區介面:
if (soundBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&m_soundBufferInterface) != S_OK)
throw std::exception("IDirectSoundBuffer8 interface not supported!");
接著通過次緩衝區介面的GetObjectInPath()
函數獲取想要的音效介面:
IUnknown* interfacePtr;
if (m_soundBufferInterface->GetObjectInPath( guid, guidIndex, interfaceGuidMaps[guid], (LPVOID*)&interfacePtr ) != DS_OK)
throw std::exception( "GetObjectInPath error" );
最後,調用SetFX()
函數, 傳入類型為DSEFFECTDESC的音效參數一個或多個音效參數:
DSEFFECTDESC effectDescriptions = { 0 };
effectDescriptions.dwSize = sizeof(effectDescriptions);
effectDescriptions.dwFlags = DSFX_LOCSOFTWARE;
effectDescriptions.guidDSFXClass = effectGuid;
...
auto callResult = m_soundBufferInterface->SetFX(m_effects.size(), m_effects.data(), resultCodes.data());
if (callResult != DS_OK) {
...
}
2. Chorus音效簡介
Chorus音效即合聲,標準音效參數由以下幾個參數構成:
- Wet/Dry 比例:Wet代指被音效處理過的音頻信號;Dry代指原始的音頻信號。
- Depth: 延遲時間被低頻振蕩器調整的百分比。
- Feedback: 輸出音頻信號反饋到音效輸入的百分比。
- Fraquency: 低頻振蕩器的頻率。
- Waveform: 低頻振蕩器的波形形狀:三角、正弦。
- Delay: 音效的延遲播放時間。
- Phase: 左右低頻振蕩器的相位差。
3. Chorus音效展示
Demo中我只實現了Chorus音效的應用:
大家可以編譯完整代碼來體驗一下。