ZBLOG

WASAPI播放pcm示例

以下是使用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助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=3468

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?