Windows系统C++项目如何不依赖第三方API实现音频播放?
Windows原生C++音频输出实现方案
你的两个需求均可通过Windows自带API实现,无需引入第三方依赖,你猜测的winmm库是最易上手的实现方案,具体说明如下:
所需依赖与对应函数
方案1:WinMM库(实现难度低,适合绝大多数普通场景)
仅需引入两个系统头文件,链接系统自带的静态库即可:
- 头文件:
<Windows.h>、<mmsystem.h> - 链接依赖:
winmm.lib,MSVC环境下可直接在代码中添加#pragma comment(lib, "winmm.lib")自动链接,无需手动配置链接器参数
1. 播放本地mp3/mp4格式音频
直接调用mciSendString(媒体控制接口函数)即可,该接口内置了常见格式的解码逻辑,支持直接读取播放mp3、mp4的音频轨道:
// 打开目标音频文件,设置别名方便后续操作 mciSendString(L"open test.mp3 alias my_audio", NULL, 0, NULL); // 播放音频,添加wait参数可同步等待播放完成,不加则为异步播放 mciSendString(L"play my_audio", NULL, 0, NULL); // 播放结束后关闭资源 // mciSendString(L"close my_audio", NULL, 0, NULL);
如果调用出错可以通过mciGetErrorString函数获取具体错误信息。
2. 播放内存生成的声波采样
使用waveOut系列函数对接扬声器输出PCM采样即可,步骤如下:
- 填充
WAVEFORMATEX结构体,指定你生成的采样的声道数、采样率、位深等参数 - 调用
waveOutOpen打开默认音频输出设备 - 填充
WAVEHDR结构体绑定你的采样数组缓冲区,调用waveOutPrepareHeader预处理缓冲区 - 调用
waveOutWrite将缓冲区数据提交到音频设备播放 - 播放完成后调用
waveOutUnprepareHeader、waveOutClose释放资源
示例代码片段:
// 配置PCM格式参数,按你实际生成的采样参数调整 WAVEFORMATEX wfx = { .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 2, .nSamplesPerSec = 44100, .wBitsPerSample = 16, }; wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; HWAVEOUT hWaveOut; // 打开默认音频输出设备 waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL); // sampleBuf为你生成的16位PCM采样数组指针,bufSize为缓冲区总字节数 WAVEHDR hdr = { .lpData = (LPSTR)sampleBuf, .dwBufferLength = bufSize }; waveOutPrepareHeader(hWaveOut, &hdr, sizeof(WAVEHDR)); // 提交缓冲区播放 waveOutWrite(hWaveOut, &hdr, sizeof(WAVEHDR)); // 此处可通过waveOutGetPosition轮询播放进度,播放完成后释放资源即可
方案2:WASAPI(低延迟场景可选,实现难度较高)
如果你需要极低延迟的音频输出(比如实时音频合成场景),可以使用Windows Vista及以上系统自带的WASAPI接口,该接口直接对接Windows底层音频引擎,最低可实现10ms以内的播放延迟:
- 头文件:
<Audioclient.h> - 链接依赖:
audioses.lib
该方案需要处理COM初始化、音频设备枚举、缓冲区锁定解锁等逻辑,实现步骤相对繁琐,普通播放场景下无需使用。
注意事项
mciSendString仅支持提取mp4文件的音频轨道播放,如果你需要处理视频内容需要额外调用Windows Media Foundation接口,实现复杂度会大幅提升waveOut系列函数仅支持整数格式的PCM采样,如果你生成的是浮点采样需要先转换为16位整数格式,WASAPI原生支持浮点采样输入
内容的提问来源于stack exchange,提问作者ManuelWiki
相关产品推荐
相关产品推荐

