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 буфера.

Другие вопросы по тегам