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

1. 音频捕获

因为捕获流程和播放流程类似,我们就不在这里赘述了,只给出简单的函数引用和图示:

最后两个是音效捕获接口,用来控制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

IDirectSoundCaptureFXNoiseSuppress8

流程图如下:

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);

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,但是不是那么自然。

例子中用到的大概就是这样:

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. 运行结果

完整代码见链接

DirectSound---捕获音频、Qml/C++ 集成交互的更多相关文章

  1. QML 与 C++ 交互

    前言 文档如是说,QML旨在通过C ++代码轻松扩展.Qt QML模块中的类使QML对象能够从C ++加载和操作,QML引擎与Qt元对象系统集成的本质使得C ++功能可以直接从QML调用.这允许开发混 ...

  2. QtQuick多页面切换、多页面切换动画、多个qml文件数据交互

    一.QtQuick多页面切换方法 (1)“隐藏法” 前一个视图visible设为false或者透明度opacity设为0,相当于“隐藏”了,实际还存在: 要显示的视图visible设为true或者透明 ...

  3. QML与C++交互:在qml中使用QSqlQueryModel显示数据库数据

    QML与C++交互:在qml中使用QSqlQueryModel显示数据库数据 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 參考链接: http:// ...

  4. QML 与 C++ 交互之工厂方法

    QML 与 C++ 交互之工厂方法 先看例如以下的类声明,声明了一个产品类和工厂类. #include <QObject> class Productor : public QObject ...

  5. Jenkins2.x Pipeline持续集成交互

    原文地址:http://blog.csdn.net/aixiaoyang168/article/details/72818804 Pipeline的几个基本概念: Stage: 阶段,一个Pipeli ...

  6. QML与C++交互:登陆界面设计

    QML与C++交互:登陆界面设计 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:Qt5.2.1 说明: QML设计前 ...

  7. 在 HTML5 中捕获音频和视频

    简介 长久以来,音频/视频捕获都是网络开发中的"圣杯".多年来,我们总是依赖于浏览器插件(Flash 或 Silverlight)实现这一点.快来看看吧! 现在轮到 HTML5 大 ...

  8. qml 与C++交互

    最近一直在研究qml 怎么与C++交互,今天在网上看到一段代码忽然想明白了,哦!!!我在QT还只是一个小白,嘿嘿 首先在我们定义了CPP文件起名:比如:util.cpp,baidumusic.cpp ...

  9. QML于C++交互之信号与槽(signal&slot )

    connect c++ SIGNAL with QML SLOT 简介 QML 与 C++ 混合编程时,总结了一下qml和c++互相直接调用.及信号与槽连接 的几种情况,详细使用情况看示例代码 所有的 ...

随机推荐

  1. PCI-E配置MSI中断流程解析

    在传统的pci中断体系中,每一个pci总线上的设备被分配一个特定的中断号,然后当设备需要中断cpu时,设备直接发出int信号,然后在cpu的inta引脚拉低的时候将自己的中断号放在数据总线上,一切都要 ...

  2. Web站点错误提示页面和默认访问页面设置

    1.asp.net 定制简单的错误处理页面 通常web应用程序在发布后,为了给用户一个友好界面和使用体验,都会在错误发生时跳转至一个自定义的错误页面,而不是asp.net向用户暴露出来的详细的异常列表 ...

  3. 如何让window.open()以post请求方式调用(巧妙解法)

    问题由来: 在公司遇到一个线上bug,如下 var url = 'http://106.75.31.215:8012/onlinePreview?url=' + encodeURIComponent( ...

  4. HihoCoder - 1139

    在上一回和上上回里我们知道Nettle在玩<艦これ>,Nettle在整理好舰队之后终于准备出海捞船和敌军交战了.在这个游戏里面,海域是N个战略点(编号1..N)组成,如下图所示其中红色的点 ...

  5. 三:Linux 的基本命令、

    Ubuntu切换用户 su root sudo passwd root 使用管理员提权修改root 登录密码 连续输入两次即可..... 重置root 用户密码 例:当前登录用户为:ubuntu,但是 ...

  6. Linux 的特殊变量(2)

    1.echo $?  输出结果为0 表示命令执行成功 场景:判断上一个命令是否成功 扩展 0:成功 2 :权限拒绝 1~125:表示运行失败 126:找到命令,但是无法执行 127:未找到要运行的命令 ...

  7. 十年Java开发程序员回答,自学Java,培训Java的利和弊

    最近有一个朋友在群里面问我:是应该去培训Java还是应该自学Java,我想的说的是我并不是想给他一个去培训或者不去培训,我用自己多年对于行业的了解去分析这个问题,然后让他自己去思考,哪种更加适合他.他 ...

  8. linux系统连接的概念及删除原理

    硬连接:ln 源文件 目标文件 软连接:ln -s 源文件 目标文件 (目标文件不能事先存在) 硬连接是通过索引节点inode来进行连接. 在Linux文件系统中,多个文件名指向同一个索引节点,硬连接 ...

  9. handsontable 方法汇总

    核心方法 1.为handsontable添加钩子方法 addHook(key,callback):key为钩子方法名 例如:hot.addHook('beforeInit', myCallback); ...

  10. MyBatis笔试题

    1请写出Mybatis核心配置文件MyBatis-config.xml的内容? <?xml version="1.0" encoding="UTF-8"? ...