一、Windows 音频体系结构
Windows的音频应用程序大部分通过微软提供的上层api完成音频处理和数据流抓取。基于api封装的媒体库或应用包括Media Foundation,MME(waveIn/waveOut),Directsound等。Wasapi:Windows audio session API
最高级别 Api
最高级别 Api 用于应用程序开发。 这些 Api 中当前正在使用和支持。
XAML MediaElement 类(C#,VB, C++)
HTML音频对象并视频对象<标记>(由网站和 Windows Web 应用)
Windows.Media.Capture 命名空间(C#,VB, C++)
Microsoft 媒体基础(C++)
这些较旧的 Api 已弃用。
Windows.Media.MediaControlContract
低级别 Api
对于音频流,建议这些低级别 Api。
Wasapi 就可以了(高性能,但更复杂)
IXAudio2 (通常用于游戏)
二、音频API和音频采集和设备之间的调用关系
Audio Engine:
混合并处理音频流
加载音频处理对象,它们是处理音频信号的特定于硬件的插件
Audio Service:
安装或控制音频流
实施winows策略,完成背景音频播放处理等
(audio)EndPoint device:
(音频)输入输出设备:speaker,microphone等
Shared Mode & Exclusive Mode
共享模式和排它模式,前者共享设备,后者独享设备
Core Audio API:
一系列音频相关的API组合,可以相互组合完成音频控制,音频流捕获和音频控制等操作
2. 常用api介绍
2.1 IAudioClient
客户端设备句柄,通过 IMMDevice Activate获取。
IMMDevice 通过IMMDeviceEnumerator枚举或者直接获取当前默认的输入输出设备。相关对象和api:IMMDeviceEnumerator EnumAudioEndpoints、GetDefaultAudioEndpoint
其中GetDefaultAudioEndpoint的第一个参数eRender 设置为输出设备speaker,eCapture为输入设备microphone。
例如:
immDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL,
reinterpret_cast<void**>(&audioClient)
对应audioClient的capture服务。启动服务前,需要初始化audioClient.
audioClient->GetService(__uuidof(IAudioCaptureClient),
reinterpret_cast<void**>(outCaputureClient));
一组相关的音频流,获取当前会话,可以单独控制当前会话的音量等属性。
IAudioClient :: Initialize 初始化时会将音频流分配不同的会话。
相关接口:IAudioSessionManager::GetAudioSessionControl
通过该接口,可以获取音频session控制和volume控制
通过该接口可以控制音频流各个通道的音量
3. 音频采集
通过扩展屏中的音频抓取通过audioClient和audioCaptureClient在共享模式下抓取默认speaker音频数据。
3.1
IMMDeviceEnumerator* deviceEnum
::CoCreateInstance(CLSID_MMDEVICE_ENUMERATOR, nullptr, CLSCTX_ALL,
IID_MMDEVICE_ENUMERATOR, reinterpret_cast<void**>(&deviceEnum))
3.2
IMMDevice* device
deviceEnum->GetDefaultAudioEndpoint(eRender, eConsole, &device)
3.3
IAudioClient* audioClient
device->Activate(IID_IAUDIO_CLIENT, CLSCTX_ALL, NULL,
reinterpret_cast<void**>(&audioClient))
3.4
WAVEFORMATEX* wavFmtX
IAudioCaptureClient** outCaputureClient
audioClient->GetMixFormat(&wavFmtX);
audioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
AUDCLNT_STREAMFLAGS_LOOPBACK,
hnsBufferDuration,
0,
wavFmtX,
nullptr);
audioClient->GetService(IID_IAUDIO_CAPTURE_CLIENT,
reinterpret_cast<void**>(outCaputureClient));
3.5
audioClient->Start()
3.6
循环获取数据
audioCaptureClient->GetBuffer(&audioData, &framesReadNum, &flag, &devPos, &pcPos)
3.7
audioClient->Stop();
audioCaptureClient->Release();
audioClient->Release();
三、代码示例
采集示例:https://docs.microsoft.com/zh-cn/windows/win32/coreaudio/capturing-a-stream
CoInitialize(NULL);
pFile = fopen("D://00.work//record.pcm", "wb");
fwrite(pData, numFramesAvailable*pwfx->nBlockAlign,1, pPcmFile);
播放示例:https://docs.microsoft.com/zh-cn/windows/win32/coreaudio/rendering-a-stream
CoInitialize(NULL);
fp = fopen("D://00.work//record.pcm", "rb");
fread(pData, numFramesAvailable*pwfx->nBlockAlign,1, fp);
示例详解:https://www.jianshu.com/p/968f684ecd83
关键数据结构:WAVEFORMATEX
//设置属性-1
//pwfx->wFormatTag = WAVE_FORMAT_PCM;
//pwfx->wBitsPerSample = 16;//FOSSID
//pwfx->cbSize = 0; //该字段一般为0,否则标识的是扩展格式的信息 WAVEFORMATEXTENSIBLE
//pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;//FOSSID
//pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;//FOSSID
//设置属性-1 end
////设置属性-2
//tmpWfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
//tmpWfx.Samples.wValidBitsPerSample = 32;
//tmpWfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
//tmpWfx.Format.wBitsPerSample = 32;
//tmpWfx.Format.cbSize = 22;
//tmpWfx.Format.nChannels = 2;
//tmpWfx.Format.nSamplesPerSec = 48000;
//tmpWfx.Format.nBlockAlign = tmpWfx.Format.nChannels * tmpWfx.Format.wBitsPerSample / 8;
//tmpWfx.Format.nAvgBytesPerSec = tmpWfx.Format.nSamplesPerSec * tmpWfx.Format.nBlockAlign;
////设置属性-2-end
WAVEFORMATEX *pwfx = NULL;
WAVEFORMATEXTENSIBLE tmpWfx = { 0 };
WAVEFORMATEXTENSIBLE* ptmpWfx = (WAVEFORMATEXTENSIBLE*)pwfx;
https://blog.csdn.net/yi7900/article/details/7481599
在windows平台上,WebRTC采用的是Windows Core Audio和Windows Wave技术来管理音频设备,还提供了一个混音管理器。利用音频设备,可以实现声音输出,音量控制等功能。源代码在webrtc\modules\audio_device\main目录下,包含接口和各个平台的源代码。