DirectSound的音频捕获原理和播放原理差很少,内部在一个缓冲区上循环写入捕获到的数据,而且提供notify通知功能。git
由于捕获流程和播放流程相似,咱们就不在这里赘述了,只给出简单的函数引用和图示:github
最后两个是音效捕获接口,用来控制Aec(回声消除)、Noise Fill(噪音填充)、Ns(噪音压制)的开启与关闭:函数
HRESULT DirectSoundCaptureEnumerate(LPDSENUMCALLBACK lpDSEnumCallback,LPVOID lpContext)
HRESULT DirectSoundCaptureCreate8(LPCGUID lpcGUID, LPDIRECTSOUNDCAPTURE8 * lplpDSC, LPUNKNOWN pUnkOuter)
IDirectSoundCapture8::GetCaps(LPDSCCAPS pDSCCaps)
HRESULT IDirectSoundCapture8::CreateCaptureBuffer(LPCDSCBUFFERDESC pcDSCBufferDesc, LPDIRECTSOUNDCAPTUREBUFFER * ppDSCBuffer, LPUNKNOWN pUnkOuter)
HRESULT IDirectSoundBuffer8::GetObjectInPath(REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, LPVOID * ppObject)
IDirectSoundCaptureFXAec8
IDirectSoundCaptureFXNoiseSuppress8ui
流程图以下:code
写入Wav文件,咱们可使用微软自带的mmio系列函数,可是切记不能与本身读写内存位置混用操做,否则会出各类无脑问题。对象
HMMIO mmioOpen(LPTSTR szFilename, LPMMIOINFO lpmmioinfo, DWORD dwOpenFlags);
MMRESULT mmioCreateChunk(HMMIO hmmio, LPMMCKINFO lpck, UINT wFlag);
LONG mmioWrite(HMMIO hmmio, char _huge *pch, LONG cch);
MMRESULT mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT wFlags);
MMRESULT mmioClose(HMMIO hmmio, UINT wFlags);blog
此次我尝试使用了Qml来进行界面绘制,怎么说呢:数据绑定确实很好用,许多仅停留在UI层的相互逻辑能够直接在UI代码上解决,不用深刻到C++逻辑代码;可是C++数据类型转换到Qml不是很方便,且二者的类型系统衔接不天然(例如在Qml中使用C++类型的时候,须要register,额外操做太多)。继承
在Qml中私用C++类型,必需要借助Qt的元对象系统,所以咱们须要:接口
在这个例子中,我须要传给Qml一个设备列表,可是Qml的list在Qt/C++中并无直接对应的类型,这里须要用到Qt的QVariantList,在C++传给Qml时QVariantList会被直接转换成list。此外i,QVariantMap能够在Qml中能够被隐式转换成JavaScript的Array,可是不是那么天然。
ip
例子中用到的大概就是这样:
class CppDsCapture : public QObject { Q_OBJECT Q_PROPERTY(QVariantList avaiableDeviceNames READ avaiableDeviceNames) public: enum EffectType { AcousticEchoCancellationMicrosoft, AcousticEchoCancellationSystem, NoiseSuppressionMicrosoft, NoiseSuppressionSystem, None }; Q_ENUM(EffectType) ... ////////////////////////////////////////////////////////////// // QML functions Q_INVOKABLE void openDevice(unsigned deviceIndex); ... }
完整代码见连接。