gpt4 book ai didi

c++ - 使用 OpenAL(Stream) 播放声音

转载 作者:搜寻专家 更新时间:2023-10-31 01:11:25 24 4
gpt4 key购买 nike

我需要播放从网络获取的声音。每 10 毫秒,获取 882 字节的声音(单声道,16 位,44100 赫兹)。这样做:

while (!ExitKey)
{
boost::system::error_code error;
size_t len = VoiceSocket->read_some(boost::asio::buffer(buf), error);
if (len==0)
{
continue;
}
alGenSources(1, &alSource);
alGenBuffers(1, &alSampleSet);
alBufferData(alSource, AL_FORMAT_MONO16, buf.data(), buf.size(), 44100);
alSourcei(alSource, AL_BUFFER, alSampleSet);
alSourcePlay(alSource);
}

但是我的声音没有播放。在 buf 变量中我有声音,因为如果我将它发送到文件,我在文件中有声音。

最佳答案

您的代码没有显示 alListener。这似乎是一个太明显的错误,但是没有监听器,听不到任何声音,否则发布的代码应该会产生一些声音,假设有来自套接字的非零数据。

编辑:再看一遍,您的错字很小,但后果很严重。 alBufferData(alSource, ...) 应该是 alBufferData(alSampleSet, ...)。您想要填充缓冲区对象,而不是源。否则,您正在播放一个空缓冲区,它不会发出声音也就不足为奇了。

另请注意,您的代码通常效率低下,无法按预期工作。

您绝对不想为每 10 毫秒收到的每个数据包生成一个新的源(和缓冲区)。这将产生一些 声音,但不是您想要的。即使没有网络抖动(您不可避免地会遇到),如果没有可听见的间隙,这也不会很好地播放。

在进入循环之前生成一个源和至少 3 个缓冲区(最好多一些,5 或 6 个)。只要您进行流式传输,一个源就会一直存在,并且会一直播放。

在进入循环之前至少接收 2 个缓冲区。按照您收到它们的顺序将这些缓冲区排队到源 (alSourceQueueBuffers) 并开始播放。每当您收到新数据包时,将数据读入新缓冲区(从已分配缓冲区的空闲列表中提取数据)并将其排队。

取消队列缓冲区并在它们变为空闲时将它们回收到您的空闲列表中(先查询!)。

那样的话,OpenAL 在播放声音时总是有一些数据要读取,这对于获得良好的结果至关重要。永远不要让它饿死。

关于c++ - 使用 OpenAL(Stream) 播放声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14932004/

24 4 0