以下是使用WASAPI在Windows上播放PCM音频的示例代码:
#include <iostream>
#include <mmdeviceapi.h>
#include <audioclient.h>
#include <functiondiscoverykeys_devpkey.h>
#define REFTIMES_PER_SEC 10000000
#define REFTIMES_PER_MILLISEC 10000
int main() {
HRESULT hr;
IMMDeviceEnumerator* pEnumerator = NULL;
IMMDevice* pDevice = NULL;
IAudioClient* pAudioClient = NULL;
IAudioRenderClient* pRenderClient = NULL;
// 获取设备枚举器
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator);
if (FAILED(hr)) {
std::cout << "Failed to create device enumerator." << std::endl;
return -1;
}
// 获取默认音频渲染设备
hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
if (FAILED(hr)) {
std::cout << "Failed to get default audio endpoint." << std::endl;
pEnumerator->Release();
return -1;
}
// 创建音频客户端
hr = pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient);
if (FAILED(hr)) {
std::cout << "Failed to activate audio client." << std::endl;
pDevice->Release();
pEnumerator->Release();
return -1;
}
// 设置音频格式,这里假设为16位单声道的PCM格式
WAVEFORMATEX waveFormat;
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.nChannels = 1;
waveFormat.nSamplesPerSec = 44100;
waveFormat.nAvgBytesPerSec = 44100 * 2; // 每秒的数据量,采样率*每个样本的字节数
waveFormat.nBlockAlign = 2; // 每个采样帧的字节数
waveFormat.wBitsPerSample = 16;
waveFormat.cbSize = 0;
// 初始化音频客户端
hr = pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, REFTIMES_PER_SEC, 0, &waveFormat, NULL);
if (FAILED(hr)) {
std::cout << "Failed to initialize audio client." << std::endl;
pAudioClient->Release();
pDevice->Release();
pEnumerator->Release();
return -1;
}
// 获取缓冲区大小
UINT32 bufferFrameCount;
hr = pAudioClient->GetBufferSize(&bufferFrameCount);
if (FAILED(hr)) {
std::cout << "Failed to get buffer size." << std::endl;
pAudioClient->Release();
pDevice->Release();
pEnumerator->Release();
return -1;
}
// 创建音频渲染客户端
hr = pAudioClient->GetService(__uuidof(IAudioRenderClient), (void**)&pRenderClient);
if (FAILED(hr)) {
std::cout << "Failed to get audio render client." << std::endl;
pAudioClient->Release();
pDevice->Release();
pEnumerator->Release();
return -1;
}
BYTE* pData;
hr = pRenderClient->GetBuffer(bufferFrameCount, &pData);
if (FAILED(hr)) {
std::cout << "Failed to get render buffer." << std::endl;
pRenderClient->Release();
pAudioClient->Release();
pDevice->Release();
pEnumerator->Release();
return -1;
}
// TODO: 将PCM音频数据写入pData指向的缓冲区
hr = pRenderClient->ReleaseBuffer(bufferFrameCount, 0);
if (FAILED(hr)) {
std::cout << "Failed to release render buffer." << std::endl;
pRenderClient->Release();
pAudioClient->Release();
pDevice->Release();
pEnumerator->Release();
return -1;
}
pRenderClient->Release();
pAudioClient->Stop(); // 停止音频流
CoTaskMemFree(pwstrDeviceId);
pDevice->Release();
pEnumerator->Release();
return 0;
}
这是一个简单的使用WASAPI播放PCM音频的示例,其中需要你根据自己的需求将PCM音频数据写入到pData
指向的缓冲区中。请确保安装了Windows SDK,并在项目中添加必要的头文件和链接库。
注意:上述代码仅演示了使用WASAPI播放PCM音频的基本过程,实际应用中可能还需要处理错误、设置事件通知等。
内容由零声教学AI助手提供,问题来源于学员提问