gpt4 book ai didi

c++ - 在 OpenAL 库中播放流

转载 作者:行者123 更新时间:2023-11-27 23:18:16 25 4
gpt4 key购买 nike

我需要在 OpenAL 中播放流。但我不明白我需要用缓冲区和源代码做什么。我的伪代码:

    FirstTime = true;

while (true)
{
if (!FirstTime)
{
alSourceUnqueueBuffers(alSource, 1, &unbuf);
}
//get buffer to play in boost::array buf (882 elements) (MONO16).
if (NumberOfSampleSet >=3)
{
alBufferData(alSampleSet[NumberOfSampleSet], AL_FORMAT_MONO16, buf.data(), buf.size(), 44100);
alSourceQueueBuffers(alSource, 1, &alSampleSet[NumberOfSampleSet++]);
if (NumberOfSampleSet == 4)
{
FirstTime = false;
NumberOfSampleSet = 0;
}
}
alSourcePlay(alSource);
}

我做错了什么?在扬声器中,我听到重复的咔哒声。请告诉我我需要用缓冲区做什么才能播放我的声音?

最佳答案

4 个缓冲区(每个缓冲区 882 个样本)和一个 44kHz 源仅提供 (4 * 882/(2 * 44100) ) = 0.04 秒的播放 - 这只是一个“咔哒”声。

要产生更长的声音,您应该加载更多数据(尽管通常只有两个缓冲区就足够了)。

假设您有一个 100Mb 的未压缩 .wav 文件。只需读取 22050 个样本(即 44100 字节的数据)并将它们排入与源关联的 OpenAL 队列。然后将另外 22050 个样本读入第二个缓冲区并将它们也加入队列。然后只需切换缓冲区(就像您现在在 NumberOfSampleSet == 4 中所做的那样)并重复直到文件未完成。

如果您想要纯正弦波,例如440Hz,然后使用相同的 22050 样本缓冲区,只需用正弦波的值填充它们:

const int BufferSize = 22050;
const int NumSamples = 44100;
// phase offset to avoid "clicks" between buffers
int LastOffset = 0;
const float Omega = 440.0f;
for(int i = 0 ; i < BufferSize ; i++)
{
float t = ( 2.0f * PI * Omega * ( i + LastOffset ) ) / static_cast<float>( NumSamples );

short VV = (short)(volume * sin(t));;

// 16-bit sample: 2 bytes
buffers[CurrentBuffer][i * 2 + 0] = VV & 0xFF;
buffers[CurrentBuffer][i * 2 + 1] = VV >> 8;
}
LastOffset += BufferSize / 2;
LastOffset %= FSignalFreq;

编辑1:

要实时处理某些内容(不幸的是,延迟很严重),您必须创建缓冲区,推送一些初始数据,然后检查 OpenAL 需要多少数据:

int StreamBuffer( ALuint BufferID )
{
// get sound to the buffer somehow - load from file, read from input channel (queue), generate etc.

// do the custom sound processing here in buffers[CurrentBuffer]

// submit more data to OpenAL
alBufferData( BufferID, Format, buffers[CurrentBuffer].data(), buffers[CurrentBuffer].size(), SamplesPerSec );
}

int main()
{
....

ALuint FBufferID[2];

alGenBuffers( 2, &FBufferID[0] );

StreamBuffer( FBufferID[0], BUFFER_SIZE );
StreamBuffer( FBufferID[1], BUFFER_SIZE );

alSourceQueueBuffers( FSourceID, 2, &FBufferID[0] );

while(true)
{
// Check how much data is processed in OpenAL's internal queue
ALint Processed;
alGetSourcei( FSourceID, AL_BUFFERS_PROCESSED, &Processed );

// add more buffers while we need them
while ( Processed-- )
{
Luint BufID;

alSourceUnqueueBuffers( SourceID, 1, &BufID );

StreamBuffer(BufID);

alSourceQueueBuffers( SourceID, 1, &BufID );
}
}

....
}

关于c++ - 在 OpenAL 库中播放流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15064742/

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