以下是一个使用DirectSound播放音频文件的示例代码:
#include <iostream>
#include <windows.h>
#include <dsound.h>
// 定义音频缓冲区大小
#define BUFFER_SIZE 4096
// 音频文件路径
const char* audioFile = "path/to/audio.wav";
// 全局变量
LPDIRECTSOUND8 lpDirectSound = NULL;
LPDIRECTSOUNDBUFFER lpPrimaryBuffer = NULL;
LPDIRECTSOUNDBUFFER8 lpSecondaryBuffer = NULL;
// 音频播放线程函数
DWORD WINAPI AudioThread(LPVOID lpParam) {
// 打开音频文件
FILE* file;
if (fopen_s(&file, audioFile, "rb") != 0) {
std::cout << "无法打开音频文件" << std::endl;
return 0;
}
// 创建音频缓冲区
DSBUFFERDESC bufferDesc = {};
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY;
bufferDesc.dwBufferBytes = BUFFER_SIZE;
bufferDesc.guid3DAlgorithm = GUID_NULL;
WAVEFORMATEX waveFormatEx = {};
waveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
waveFormatEx.nChannels = 2; // 双声道
waveFormatEx.nSamplesPerSec = 44100; // 采样率为44.1kHz
waveFormatEx.wBitsPerSample = 16; // 每个样本16位
waveFormatEx.nBlockAlign = (waveFormatEx.nChannels * waveFormatEx.wBitsPerSample) / 8;
waveFormatEx.nAvgBytesPerSec = waveFormatEx.nSamplesPerSec * waveFormatEx.nBlockAlign;
bufferDesc.lpwfxFormat = &waveFormatEx;
if (FAILED(lpDirectSound->CreateSoundBuffer(&bufferDesc, &lpSecondaryBuffer, NULL))) {
std::cout << "音频缓冲区创建失败" << std::endl;
fclose(file);
return 0;
}
// 读取音频数据
char buffer[BUFFER_SIZE];
DWORD bytesRead;
DWORD writePos = 0;
BOOL isPlaying = FALSE;
while (fread(buffer, sizeof(char), BUFFER_SIZE, file) == BUFFER_SIZE) {
lpSecondaryBuffer->Lock(writePos, BUFFER_SIZE, (LPVOID*)&buffer, &bytesRead, NULL, NULL, 0);
// 将音频数据拷贝到缓冲区
memcpy(buffer, buffer, bytesRead);
lpSecondaryBuffer->Unlock((LPVOID)buffer, bytesRead, NULL, 0);
writePos += bytesRead;
// 开始播放音频
if (!isPlaying) {
isPlaying = TRUE;
lpSecondaryBuffer->Play(0, 0 , DSBPLAY_LOOPING);
}
}
fclose(file);
// 等待音频播放完成
DWORD status;
do {
lpSecondaryBuffer->GetStatus(&status);
Sleep(100);
} while (status & DSBSTATUS_PLAYING);
// 停止播放并释放资源
if (lpSecondaryBuffer)
{
lpSecondaryBuffer->Stop();
lpSecondaryBuffer->Release();
lpSecondaryBuffer = NULL;
}
if (lpPrimaryBuffer)
{
lpPrimaryBuffer->Release();
lpPrimaryBuffer = NULL;
}
if (lpDirectSound)
{
lpDirectSound->Release();
lpDirectSound = NULL;
}
return 0;
}
int main() {
// 初始化DirectSound
if (FAILED(DirectSoundCreate8(NULL, &lpDirectSound, NULL))) {
std::cout << "DirectSound初始化失败" << std::endl;
return 1;
}
if (FAILED(lpDirectSound->SetCooperativeLevel(GetDesktopWindow(), DSSCL_PRIORITY))) {
std::cout << "设置协作级别失败" << std::endl;
return 1;
}
// 创建主音频缓冲区
DSBUFFERDESC bufferDesc = {};
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
if (FAILED(lpDirectSound->CreateSoundBuffer(&bufferDesc, &lpPrimaryBuffer, NULL)))
{
std::cout << "主音频缓冲区创建失败" << std::endl;
return 1;
}
WAVEFORMATEX waveFormatEx = {};
waveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
waveFormatEx.nChannels = 2; // 双声道
waveFormatEx.nSamplesPerSec = 44100; // 采样率为44.1kHz
waveFormatEx.wBitsPerSample = 16; // 每个样本16位
waveFormatEx.nBlockAlign = (waveFormatEx.nChannels * waveFormatEx.wBitsPerSample) / 8;
waveFormatEx.nAvgBytesPerSec = waveFormatEx.nSamplesPerSec * waveFormatEx.nBlockAlign;
if (FAILED(lpPrimaryBuffer->SetFormat(&waveFormatEx)))
{
std::cout << "设置主音频缓冲区格式失败" << std::endl;
return 1;
}
// 创建音频播放线程
HANDLE hAudioThread = CreateThread(NULL, 0, AudioThread, NULL, 0, NULL);
// 等待线程结束
WaitForSingleObject(hAudioThread, INFINITE);
// 关闭DirectSound
if (lpPrimaryBuffer)
{
lpPrimaryBuffer->Release();
lpPrimaryBuffer = NULL;
}
if (lpDirectSound)
{
lpDirectSound->Release();
lpDirectSound = NULL;
}
return 0;
}
请确保在项目中包含dsound.lib 库文件,并将路径更改为要播放的音频文件的路径。这个示例代码通过创建一个独立的音频播放线程来实现后台播放。<br/><br/><br/><p style="color:#CCCCCC;font-size:12px;">内容由零声教学AI助手提供,问题来源于学员提问</p> |