DirectSound---捕获音频、Qml/C++ 集成交互

DirectSound的音频捕获原理和播放原理差很少,内部在一个缓冲区上循环写入捕获到的数据,而且提供notify通知功能。git

1. 音频捕获

由于捕获流程和播放流程相似,咱们就不在这里赘述了,只给出简单的函数引用和图示: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

capture-pic

2. 写入Wav

写入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

wav-pic

3. Qml/C++ 集成交互

此次我尝试使用了Qml来进行界面绘制,怎么说呢:数据绑定确实很好用,许多仅停留在UI层的相互逻辑能够直接在UI代码上解决,不用深刻到C++逻辑代码;可是C++数据类型转换到Qml不是很方便,且二者的类型系统衔接不天然(例如在Qml中使用C++类型的时候,须要register,额外操做太多)。继承

在Qml中私用C++类型,必需要借助Qt的元对象系统,所以咱们须要:接口

  • 继承自QObject而且带上Q_OBJECT宏。
  • 属性用Q_PROPERTY声明。
  • 枚举用Q_ENUM描述。
  • 信号、槽是默认支持的,其余的函数须要用Q_INVOKABLE声明。

在这个例子中,我须要传给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);

    ...
}

4. 运行结果

result-pic1 result-pic2 result-pic3

完整代码见连接

相关文章
相关标签/搜索