对于常见的音频播放,使用XAudio2足够了。


时间是把杀猪刀,滑稽的是我成了猪

早在Windows Vista中,M$推出了新的音频架构UAA,其中的CoreAudio接替了DSound、WaveXxx、MediaFundation,通过Core Audio APIs,Windows的音频性能可以与MacOS X相媲美(手动偷笑)。

Universal Audio Architecture (UAA)

CoreAudio属于UAA,只在用户层进行一系列音频处理,而系统内核只负责递交缓冲数据给音频驱动。 
 
在UAA出现之前,程序跑起来是这样的: 
 
现在程序在UAA跑起来是这样的: 

WASAPI和XAudio2

Core Audio APIs的明星:WASAPI

WASAPI可以不进行SRC直接输出,还能提供极低的音频延迟。 
为了降低音频延迟,更像AISO,WASAPI的使用方式分为两种:一种是push,组成缓冲区队列,常用于音频播放。一种是event(必须独占),由硬件时钟或音频API提供事件来驱动你提交音频数据(好复杂啊真心没用过,缓存欠载怎么办),这样就可以大幅降低音频延迟,好像连DMA都会跳过(未查证),适用于游戏、实时混音等对实时性要求比较苛刻的场合。 
在保真度上,WASAPI被Foobar2000用户吹得神乎其神。而它充其量就是少了个SRC过程,至于两种模式的区别,娱乐一下就行了。什么人声甜美声场宽毛刺少等等故弄玄虚之流,有这功夫还是花点钱吧,你需要更好的器材。 
对用户而言,WASAPI真正厉害的在于APO(Audio Processing Objects),基于此技术的音效理论上兼容所有设备(可能是DSP算法的问题,我遇到了采样率上的限制,一旦高于96000Hz就失效了)。

出自DirectX的XAudio2:

XAudio2在采用UAA的Windows版本中就是对WASAPI的调用。 
关于保真度,你的程序在Xp上跑的是DSound,使用UAA的系统则直接对应WASAPI,同样可以跳过SRC,而且音频低延迟的表现足以满足音乐游戏之类的需求。 
最初的XAudio用于Xbox,XAudio2一开始可用于三红机和Vista及两者以上。现在的大一统环境中(使用Windows原生API),播放音频不是WASAPI就是XAudio2。使用XAudio2最大好处是比WASAPI更易于音频编程,播放音频的时候你只需不断地提交音频缓冲区的数据逐渐组成队列就好,缺点是.。。对于音频播放的常规开发,目前没看到缺点,除了达不到那种连DMA都能跳过的超低延迟(换来的就是更高的硬件资源占用和几乎感受不出的体验提升)。对系统资源的占用还有延迟和WASAPI看不出来有什么差距。仅从音频播放上,个人推荐使用XAudio2而非WASAPI。 
目前在Windows10中它的版本是2.9,并继续在WinRT与UWP技术中供开发者使用。

说闲话 IS EASY,这就给你CODE:

这个是我做语音合成的时候写的一个简单示例,代表了最常用的音频播放场景,全是定式: 
PS:合成出来的SampleRate低于声卡工作的输出频率,必须经过软件SRC(Sample Rate Converter),否则出来的就是快放效果,创建音源时默认参数是开启其内置的SRC。

// 需要的头文件和静态库
#include <Windows.h>
#include <XAudio2.h>
#pragma comment(lib,"xaudio2.lib") /*
#include"SpeechSynthesis.h"这是SpeechSynthesis的头文件
*/
SpeechSynthesis syth(SC_Mandarin); // 语音合成器-简体中文转普通话
WAVEFORMATEX format = syth.wfx; // 波形格式 IXAudio2 * XAudioEngine = NULL; // IXAduio2音频引擎
IXAudio2MasteringVoice * pmaster = NULL; // 声音管理器
IXAudio2SourceVoice * pSource = NULL; // 音源
XAUDIO2_BUFFER sBuffer = {}; // 音源缓冲区
XAUDIO2_VOICE_STATE pState = {}; // 缓冲区状态 // 单独列出初始化和卸载,可以加入到你的构造-析构函数中
BOOL Init()
{
// XAudio2初始化
CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(XAudio2Create(&XAudioEngine)))return FALSE;
if (FAILED(XAudioEngine->CreateMasteringVoice(&pmaster)))return FALSE;
if (FAILED(XAudioEngine->CreateSourceVoice(&pSource, &format)))return FALSE;
return TRUE;
} void Uninit()
{
XAudioEngine->Release();
CoUninitialize();
}
// 语音合成与音频呈现的函数
BOOL Vocalize(wchar_t * srcSentence)
{
pSource->Start(); // 开启音源
sBuffer.pAudioData = syth.Synthesize(srcSentence); // 合成音频
sBuffer.AudioBytes = syth.pcm_data.size(); // 一次性载入音频缓冲区
if (FAILED(pSource->SubmitSourceBuffer(&sBuffer)))return 0; // 装载音频
// 等待播放完毕或者打断
for (pSource->GetState(&pState); pState.BuffersQueued; pSource->GetState(&pState))
Sleep(1);
pSource->Stop(); // 关闭音源
pSource->FlushSourceBuffers(); // 缓冲区清空(可选)
return TRUE;
} int main(int argc, char *argv[])
{
Init();
Vocalize(L"这是一段测试语音");
Vocalize(L"节选于《让我在你的心里自由自在》");
Vocalize(L"她瞬间就摘下了自己平静的面具,阳光般的笑容撒满她的眼睛。她向我投来真实的目光,她的声音让我无所适从地被打动。她时而安静、柔顺得像个邻家女孩,时而一双又黑又大的眼睛闪烁出精灵的光芒。在她的音乐里,她就是一只在草原蔚蓝澄明的天际自由翱翔的苍鹰,释放着自己宽阔的憧憬与广袤的理想。她的内心孤独而迷茫,踯躅而忧郁,但依然顽固地看守着精神的自由,也学会了在现实生活中默默承受。");
Uninit();
return 0;
}

可见流程非常简单: 
初始化之后可以先pSource->Start()也可以先配置sBuffer和SubmitSourceBuffer,三者顺序很自由,符合常理就行;对于sBuffer,这里只需要让它知道音频缓冲区的指针和缓冲区长度,至于loop等参数,使用起来顾名思义,这里没必要啰嗦。 
然后就是轮询音频缓冲区状态,以防缓冲区欠载。 
停止播放的时候可以清除音源的缓冲区队列,有些情况需要你打断并播放别的声音,需要使用FlushSourceBuffers();否则效果就是队列式地把声音全部播放完。

下次播放直接重复上述操作。

提示

前面已提到,音源初始化的时候默认是开启SRC的,也就是进行自动重采样来保证正确的播放速度。 
创建音源的时候有一个int型Flag叫做:XAUDIO2_VOICE_NOSRC。你可以在初始化的时候修改第三个参数来实现无SRC:

CreateSourceVoice(&pSource, &format,XAUDIO2_VOICE_NOSRC);

顾名思义,当你保证音频采样率和设备输出设定一致的时候就可以这样跳过SRC,你要的bit-perfect并没有因为DX而阉割,而且代码没有WASAPI那么冗杂。

Windows基础-使用XAudio2播放音频(本质是WASAPI)的更多相关文章

  1. 与众不同 windows phone (15) - Media(媒体)之后台播放音频

    原文:与众不同 windows phone (15) - Media(媒体)之后台播放音频 [索引页][源码下载] 与众不同 windows phone (15) - Media(媒体)之后台播放音频 ...

  2. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  3. windows 自带winmm.dll播放音频问题

    同事用的一个录音小程序在他机器上可以用,换了两个电脑不能用,获取音频长度时总是0,检查代码也没有发现具体问题.最后发现是电脑声卡驱动的问题.更新声卡驱动好了. 附上播放音频的代码: 首先,导入dll文 ...

  4. XAudio2播放PCM

    XAudio2 是一个跨平台的API,在Xbox 360及Windows中得到支持.在Xbox 360上, XAudio2作为一个静态库编译到游戏可执行文件中.在Windows上,XAudio2提供一 ...

  5. FFmpeg学习3:播放音频

    参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...

  6. ArcGIS API for Silverlight 当DataGrid选中项时,地图聚焦弹出窗口,并可以播放音频文件

    原文:ArcGIS API for Silverlight 当DataGrid选中项时,地图聚焦弹出窗口,并可以播放音频文件 先看效果图,然后上代码: <UserControl x:Class= ...

  7. windows 基础命令小集

    windows 基础命令小集 winver---------检查Windows版本wmimgmt.msc----打开windows管理体系结构(WMI)wupdmgr--------windows更新 ...

  8. Web开发——HTML基础(图像、音频和视频内容)

    参考: 参考:HTML中的图像 参考:视频和音频内容 目录: 1.HTML中的图像 1.1 我们如何在网页上放置图像? (1)替代文字(alt) (2)宽度和高度 (3)图片标题 1.2 用图形和图形 ...

  9. .NET winform播放音频文件

    前提:最近要求做一个在winform端做一个音频文件播放的功能,至此,总结最近搜寻的相关资料. 一.微软提供了三种方式来播放音频文件 1.通过System.Media.SoundPlayer来播放 2 ...

随机推荐

  1. 5.Mongodb聚合

    聚合 aggregate 聚合(aggregate)主要用于计算数据,类似sql中的sum().avg() 语法 db.集合名称.aggregate([{管道:{表达式}}]) 1.管道 管道在Uni ...

  2. MAC中mongodb的连接遇到的问题及调试

    今天在MAC环境下连接mongodb,遇到了一些报错,最终调试全部搞定.在此特做记录! 首先,mongod启动失败 上面有一句话是 exception in initAndListen: 20 Att ...

  3. 跨域携带cookie

    $.ajax({ type: "GET", url: "https://upload.cnblogs.com/imageuploader/upload?host=www. ...

  4. PJMEID学习之视频的捕捉与播放

    pjmedia是pjsip的视频部分,官网明确提示,要想使用pjmedia离不开directshow/sdl/ffmpeg这三个库. 软件版本的限制: ffmpeg不能高于1.25.(建议下载1.01 ...

  5. python之while/for循环

    一.while循环 (一)循环语句 while 后面接判断语句,在返回结果时有以下几种语句: 1.break 仅适用于循环语句,意思是结束最近的循环 2.continue 仅适用于循环语句,意思是跳到 ...

  6. python-configparser模块,xml.etree模块

    操作键值对文件 #文件db格式为 [section] a = 1 b = 2 [section1] d = 3 c = 4 import configparser #获取所有节点 config = c ...

  7. ehcache + spring 整合以及配置说明 ,附带整合问题 (已解决)

    新做的项目,因为流量不大 就是一个征信平台,高峰流量不多,但缓存是必须的,cache到server上就可以,不需要额外的memcache.redis之类的东西. 但是遇到一个大坑,事情是这样的: 通过 ...

  8. hnust 罚时计算器

    问题 F: 罚时计算器 时间限制: 1 Sec  内存限制: 128 MB提交: 229  解决: 63[提交][状态][讨论版] 题目描述 一般 ACM程序设计比赛都是五个小时.但是比赛结束时,DB ...

  9. CI框架入门

    本人最近在学习CI框架,网上找到一些个人觉得入门比较好的资料,记录一下: 兄弟连的CI框架入门系类: [军哥谈CI框架]之入门教程之第一讲:codeigniter的介绍和安装配置:http://bbs ...

  10. CentOS 6.3下安装Vsftp,虚拟用户

    CentOS 6.3下安装Vsftp,虚拟用户一.安装:1.安装Vsftpd服务相关部件:[root@linuxidc.com ~]# yum install vsftpd*Dependencies ...