PlaySound最简调用为PlaySound(L"sound.wav", NULL, SND_FILENAME | SND_SYNC),仅支持PCM格式WAV文件,需确保路径正确、启用Unicode(加L前缀或用TEXT宏),且链接winmm.lib;异步播放需改用SND_ASYNC,但须防程序过早退出。

Windows平台用PlaySound最简播放WAV
直接调用Win32 API的PlaySound是最快能跑起来的方式,不需要额外依赖,但仅限WAV且只支持同步阻塞播放(即播放完才继续执行后续代码)。
- 确保WAV文件路径正确,且是PCM格式(常见16位单/立体声),
PlaySound不支持压缩WAV(如IMA ADPCM) - 使用
SND_FILENAME | SND_ASYNC可避免阻塞,但需注意:若程序退出太快,声音可能被中断 - 示例:
PlaySound(L"sound.wav", NULL, SND_FILENAME | SND_ASYNC);
- 若报错
error C2664: cannot convert argument 1 from 'const char [x]' to 'LPCWSTR',说明没启用Unicode或字符串没加L前缀,改用TEXT("sound.wav")或项目属性中设置字符集为Unicode
跨平台方案:用libsndfile + libao解码+输出
libsndfile负责读WAV(支持多种格式和采样率),libao负责把PCM数据喂给声卡;二者组合能绕过Windows API限制,也适用于Linux/macOS。
-
libsndfile本身不播放,只读取——必须配合音频后端(如libao、PortAudio或SDL2)才能出声 - 常见坑:
libao默认后端可能未启用(比如Linux上没装libao-pulse包),运行时报Unable to open audio device,需显式指定驱动:ao_initialize(); ao_sample_format format = { ... }; driver_id = ao_driver_id("pulse"); - 采样率/通道数/位深必须与声卡兼容,否则
ao_open_live返回NULL;建议先用libsndfile的sf_info结构体检查WAV元信息,再匹配ao_sample_format
用SDL2实现带控制的WAV播放
如果需要暂停、音量调节、多音效混音或后续扩展(如MP3/Ogg),SDL2是最现实的选择——它封装了底层差异,API统一,且自带WAV加载函数。
-
Mix_LoadWAV加载后返回Mix_Chunk*,用Mix_PlayChannel播放;注意:WAV若含非PCM编码(如GSM 6.10),Mix_LoadWAV会返回NULL,无提示 - 必须初始化音频子系统:
SDL_Init(SDL_INIT_AUDIO),且在Mix_OpenAudio中指定的参数(如44100 Hz、AUDIO_S16SYS)要与WAV实际格式尽量一致,否则播放失真或静音 - 常见错误
Mix_OpenAudio: Failed to initialize SDL Audio: No available audio device:检查是否在主线程调用,或Linux下没权限访问/dev/snd/(加用户到audio组) - 释放资源别漏掉:
Mix_FreeChunk+Mix_CloseAudio+SDL_Quit,否则下次运行可能因设备占用失败
为什么不用std::ifstream手动解析WAV头然后写入/dev/dsp?
手动解析WAV RIFF头+data块再直写声卡设备(如Linux的/dev/dsp或旧版/dev/audio)理论上可行,但几乎没人这么做——现代系统早已废弃这类裸设备接口,且缺乏缓冲、混音、采样率转换等基础能力。
立即学习“C++免费学习笔记(深入)”;
- ALSA/PulseAudio/Core Audio都要求通过专用库交互,绕过它们等于重写音频栈底层
- WAV头解析容易出错:比如忽略
fact块、误判fmt子块长度(有扩展字段)、没跳过LIST或cue等非标准chunk - 即使解析正确,把原始PCM送进声卡前还需做字节序转换(WAV是小端,某些ARM平台默认大端)、重采样(WAV是48kHz,声卡只接受44.1kHz)、立体声/单声道适配——这些
libao或SDL2已帮你做了
真正麻烦的从来不是“怎么播”,而是“播得准、不出错、能控、跨平台”——选库时先看它对异常WAV文件的容错能力,再看文档里有没有明确写出“supports all standard PCM WAV variations”,而不是只测了自己生成的干净文件。


















