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 );
}
}
....
}
person
Viktor Latypov
schedule
25.02.2013