gpt4 book ai didi

c++ - Win32 播放声音 : How to control the volume?

转载 作者:太空狗 更新时间:2023-10-29 23:38:08 25 4
gpt4 key购买 nike

我正在使用 Win32 多媒体功能 PlaySound从我的应用程序播放声音。

我希望能够动态调整正在播放的声音的音量,而不修改系统音量级别。

我能找到的关于控制通过 PlaySound 播放的声音音量的唯​​一建议是使用 waveOutSetVolume ,但是该函数设置了系统范围的音量级别(不是我想要的)。

最佳答案

两种可能的解决方案:

首先,如果您的目标是 Vista 及更高版本,则可以使用新的 Windows 音频 API 来调整每个应用程序的音量。 ISimpleAudioVolume、IAudioEndpointVolume 等...

如果这不合适,可以将 WAV 文件直接加载到内存中并就地修改样本。试试这个:

从磁盘读取 WAV 文件并将其存入内存缓冲区,然后缩减样本。我将假设所讨论的 WAV 文件是带有未压缩 (PCM) 样本的 16 位立体声。立体声或单声道。如果不是,那么其中的大部分内容都会消失。

我将把 WAV 文件字节读取到内存中作为读者的练习:但让我们从以下代码开始,其中“ReadWavFileIntoMemory”是您自己的函数。

DWORD dwFileSize;
BYTE* pFileBytes;
ReadWavFileIntoMemory(szFilename, &pFileBytes, &dwFileSize);

此时,pFileBytes 的检查将如下所示:

RIFF....WAVEfmt ............data....

这是 WAV 文件头。 “数据”是音频样本 block 的开始。

找到“data”部分,将“data”后面的4个字节读入一个DWORD。这是包含音频样本的“数据” block 的大小。样本数(假设 PCM 16 位是这个数字除以 2)。

// FindDataChunk is your function that parses the WAV file and returns the pointer to the "data" chunk.
BYTE* pDataOffset = FindDataChunk(pBuffer);
DWORD dwNumSampleBytes = *(DWORD*)(pDataOffset + 4);
DWORD dwNumSamples = dwNumSamplesBytes / 2;

现在,我们将创建一个指向内存缓冲区中第一个真实样本的样本指针:

SHORT* pSample = (SHORT*)(pDataOffset + 8);

pSample 指向 WAV 文件中的第一个 16 位样本。因此,我们已准备好将音频样本缩放到适当的音量级别。假设我们的音量范围在 0.0 到 1.0 之间。其中 0.0 是完全静音。 1.0 是正常的全音量。现在我们只需将每个样本乘以目标体积:

float fVolume = 0.5; // half-volume
for (DWORD dwIndex = 0; dwIndex < dwNumSamples; dwIndex++)
{
SHORT shSample = *pSample;
shSample = (SHORT)(shSample * fVolume);
*pSample = shSample;
pSample++;


if (((BYTE*)pSample) >= (pFileBytes + dwFileSize - 1))
break;
}

此时,您已准备好使用 PlaySound 播放内存中的 WAV 文件:

PlaySound((LPCSTR)pFileBytes, NULL, SND_MEMORY);

那应该就可以了。如果您打算使用 SND_ASYNcflags使上述调用成为非阻塞的,那么在播放结束之前您将无法释放内存缓冲区。所以要小心。

至于WAV文件头的解析。我通过声明一个名为“FindDataChunk”的假设函数来挥手摆脱这种情况。您可能应该投资于编写适当的 WAV 文件头解析器,而不是仅仅寻找您在头中第一次遇到“数据”的位置。为了简洁起见,我省略了通常的错误检查。因此,上述代码可能存在一些安全问题需要解决 - 特别是因为它涉及遍历内存缓冲区并写入其中。

关于c++ - Win32 播放声音 : How to control the volume?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2302841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com