OpenAL Soft - петля с введением
Я использовал OpenAL soft для Win32, и я столкнулся с определенной проблемой.
Моя цель - воспроизвести зацикленный звук, состоящий из вступительной части, состоящей из одного выстрела, подобно файлу.WAV с маркером петли. Насколько я понимаю, это должно быть достигнуто в OpenAL путем использования нескольких буферов в источнике. В общем, мой подход состоит в том, чтобы поставить в очередь оба буфера, затем дождаться воспроизведения второго буфера и установить источник в цикл. Это работает, но проблема в том, что, как только я буду готов остановить звук, я, похоже, не смогу убрать последний буфер. Мой код выглядит примерно так:
// set up the sound
alSourceQueueBuffers(source, 1, &buffer1);
alSourceQueueBuffers(source, 1, &buffer2);
alSourcePlay(source);
...
// check to loop sound in update
ALint buffer;
alGetSourcei(source, AL_BUFFER, &buffer);
if (buffer == buffer2)
{
alSourcei(source, AL_LOOPING, true);
}
..
// check to stop sound in update
if (shouldStop)
{
alSourcei(source, AL_LOOPING, false);
alSourceStop(source);
alSourceUnqueueBuffers(source, 1, &buffer1);
alSourceUnqueueBuffers(source, 1, &buffer2); // AL_INVALID_OPERATION
}
В результате получается, что буфер не был должным образом освобожден и будет слышен при следующем воспроизведении этого источника. Я знаю, что обычно вы можете снять буфер только после того, как он закончил играть, но я думаю, что я могу свободно снять любые буферы на остановленном звуке. Мне интересно, может быть, такое поведение вызывает мое использование флага цикла?
Буду очень признателен за любой совет.
Спасибо майк
2 ответа
Похоже, что есть способ обойти это. Я не могу снять буфер воспроизведения, но могу полностью очистить очередь с помощью этой строки:
alSourcei(source, AL_BUFFER, AL_NONE);
Это будет работать нормально после остановки звука.
Я считаю правильное использование alSourceUnqueueBuffers(source, 1, &buffer1);
состоит в том, чтобы создать массив ваших буферов и отправить его, вместо того, чтобы дважды вызывать его, вы вызываете его один раз для массива следующим образом:
ALuint buffers[2] = { buffer1, buffer2 };
alSourceUnqueueBuffers(source, 2, buffers);
Обратите внимание, что мы используем размер 2, чтобы указать 2 буфера.