将 .wav 加载到内存中然后在 C++ 中播放
Loading a .wav into memory then playing it in C++
None 我能找到的其他答案似乎对我有用。我已经将 sound.wav
的内容放入一个变量中,以便将声音数据嵌入到可执行文件中 而无需处理资源文件 :
sound.h
:
std::string sound = R"(RIFFÆø^ WAVEfmt ...)";
由于这个声音文件大约有 30 秒长,它是一个非常大的变量,由 12,624 行 垃圾组成(这可能是问题的根源)。
我在 main.cpp
中包含 sound.h
然后尝试使用 windows playsoundapi
:
播放声音
int main() {
std::cout << "Hello" << std::endl;
PlaySoundA(sound.c_str(), nullptr, SND_MEMORY | SND_SYNC);
return 0;
}
程序简单地编译,打印“Hello”,并以代码 0 退出,没有任何错误。感觉我此时已经尝试了所有方法,所以任何信息都有帮助。
您正在调用的 std::string
构造函数构造一个 std::string
从源序列到第一个 NUL 字符的对象。
WAVE 文件使用 Resource Interchange File Format。在 RIFF
块标识符之后,有一个指定长度的 4 字节序列。对于小于 ~16.4MiB 的文件,第四个字节为零,因此您得到长度为 7 的 std::string
。即使对于较大的文件,最终也会有值为 0 的字节,导致 std::string
来存储输入的截断版本。
您有多种选择来处理这个问题(从最不推荐到最推荐):
- 使用带有显式
count
参数的 std::string
constructor。这避免了通常会发生的输入截断。
- 使用数组,例如
unsigned char const sound[] = R"(RIFF ...)";
。由于 C++ 不提供描述二进制文字的方法,因此建议使用数值初始化每个元素,例如unsigned char const sound[] = { 0x52, 0x49, 0x46, 0x46, ... };
.
- Link将音频文件放入可执行映像的资源中。这是将二进制资产放入可执行映像的推荐方法。 Playing WAVE Resources 有用于检索数据的示例代码。
请注意 PlaySound
有一个 return 值,您的代码将忽略该值。完全有可能以您调用它的方式调用 return FALSE
。在诊断问题时,观察错误应该是您的首要行动。
None 我能找到的其他答案似乎对我有用。我已经将 sound.wav
的内容放入一个变量中,以便将声音数据嵌入到可执行文件中 而无需处理资源文件 :
sound.h
:
std::string sound = R"(RIFFÆø^ WAVEfmt ...)";
由于这个声音文件大约有 30 秒长,它是一个非常大的变量,由 12,624 行 垃圾组成(这可能是问题的根源)。
我在 main.cpp
中包含 sound.h
然后尝试使用 windows playsoundapi
:
int main() {
std::cout << "Hello" << std::endl;
PlaySoundA(sound.c_str(), nullptr, SND_MEMORY | SND_SYNC);
return 0;
}
程序简单地编译,打印“Hello”,并以代码 0 退出,没有任何错误。感觉我此时已经尝试了所有方法,所以任何信息都有帮助。
您正在调用的 std::string
构造函数构造一个 std::string
从源序列到第一个 NUL 字符的对象。
WAVE 文件使用 Resource Interchange File Format。在 RIFF
块标识符之后,有一个指定长度的 4 字节序列。对于小于 ~16.4MiB 的文件,第四个字节为零,因此您得到长度为 7 的 std::string
。即使对于较大的文件,最终也会有值为 0 的字节,导致 std::string
来存储输入的截断版本。
您有多种选择来处理这个问题(从最不推荐到最推荐):
- 使用带有显式
count
参数的std::string
constructor。这避免了通常会发生的输入截断。 - 使用数组,例如
unsigned char const sound[] = R"(RIFF ...)";
。由于 C++ 不提供描述二进制文字的方法,因此建议使用数值初始化每个元素,例如unsigned char const sound[] = { 0x52, 0x49, 0x46, 0x46, ... };
. - Link将音频文件放入可执行映像的资源中。这是将二进制资产放入可执行映像的推荐方法。 Playing WAVE Resources 有用于检索数据的示例代码。
请注意 PlaySound
有一个 return 值,您的代码将忽略该值。完全有可能以您调用它的方式调用 return FALSE
。在诊断问题时,观察错误应该是您的首要行动。