iPhone SDK - OpenAL, звуковой движок в стиле Beat Box

Как можно было бы создать звуковой движок в стиле «бит-бокса», в котором ряд звуков может быть поставлен в очередь заранее и во время воспроизведения. Однако эти звуки необходимо воспроизводить без каких-либо пауз или сикканий.

Я изучил OpenAL и попытался использовать alSourceQueueBuffers () для создания источника с серией предварительно буферизованных клипов, но не добился того, что искал.

Я загружаю свои аудиофайлы с помощью AudioFileOpenURL, а затем загружаю их в массив символов с помощью AudioFileReadBytes, создавая буфер с помощью alGenBuffers и затем буферизуя с помощью alBufferData.

Затем я создаю источник с помощью alGenSources и сохраняю ссылку на этот источник. Затем я несколько раз вызываю alSourceQueueBuffers (sourceId, 1, & bufferId), где bufferId - это параметр, переданный в мой метод queueClip и ссылающийся на несколько разных клипов.

После этого и вызова alSourcePlay я слышу, как будто два моих клипа воспроизводятся один за другим ... но потом ничего (я загрузил его с 3 аудиофайлами и произвольно добавлял их к источнику с помощью alSourceQueueBuffers a пару раз).

Мне также нужно знать, как лучше всего обновить свой источник, добавить в него новые звуки и удалить из него уже проигранные звуки, чтобы очистить память и т. Д.


person David Higgins    schedule 10.07.2009    source источник
comment
Почему вы не можете написать это поверх AVAudioPlayer? Задержка?   -  person zoul    schedule 13.07.2009
comment
Задержка - серьезная проблема, с AVAudioPlayer при воспроизведении элементов было смещение 0,151. Установка элемента в «цикл» на самом деле привела к тому, что он плавно зацикливался, однако я намерен ставить элементы в очередь и воспроизводить различные разные элементы. Получение настройки обратного вызова audioDidFinishPlaying и воспроизведение следующего элемента в списке ... привело к постоянному смещению 0,151 при воспроизведении. Я подумал о том, чтобы написать таймер и установить его на основе текущего времени выборки за вычетом этого известного согласованного смещения ... но это звучит «глупо» и не является «точным» или «точным».   -  person David Higgins    schedule 16.07.2009
comment
С тех пор я начал использовать библиотеку FMOD, в которой был предоставлен пример «сшивания в реальном времени», в котором для воспроизведения использовался механизм двойного буфера. Вы создаете два дополнительных звука, и пока один играет, вы переключаете другой ... и он воспроизводит два сэмпла плавно, без слышимого промежутка. Это было то, что я хотел сделать, хотя ... FMOD имеет ценник, решение OpenAL для этого было бы предпочтительнее.   -  person David Higgins    schedule 16.07.2009


Ответы (2)


Вы опрашиваете источник, чтобы узнать, когда он израсходовал буфер?

ALuint freeBuffer;
ALint processed;
alGetSourcei (myALSource, AL_BUFFERS_PROCESSED, &processed);
while (processed > 0) {
  // remove spent buffer
  alSourceUnqueueBuffers(myALSource, 1, &freeBuffer);
  // refill buffer with samples, if they're going to be different this time
  // ...
  // re-queue buffer on source
  alSourceQueueBuffers(myALSource, 1, &freeBuffer);
  // check again for more processed buffers
  alGetSourcei (myALSource, AL_BUFFERS_PROCESSED, &processed);
}

Вам нужно будет продолжить этот опрос, чтобы проверить потраченные буферы ... Я использовал простой NSTimer.

person invalidname    schedule 28.07.2009

Я упустил из виду более простой вариант. Установите свойство AL_LOOPING в вашем источнике:

alSourcei (myALSource, AL_LOOPING, AL_TRUE);
person invalidname    schedule 28.07.2009
comment
это будет просто зацикливать один звук, не так ли? - person David Higgins; 29.07.2009