Одновременное воспроизведение (10+) с AudioQueueServices - PullRequest
1 голос
/ 12 сентября 2011

Может кто-нибудь показать мне, как это делается для iPhone?Я пытаюсь сделать так, чтобы игра воспроизводила около 12 звуков одновременно, и я не могу понять, как использовать AudioQueueServices.Я понимаю, что вы должны инициализировать, добавлять буферы, воспроизводить их и использовать AudioQueueEnqueueBufferWithParameters для одновременного воспроизведения, но я не знаю, как превратить это в код.Любой, у кого есть код или кто-то, кто мог бы объяснить мне это, был бы потрясающим!

Если вы слышали о Tone Grid / Tone Board, это именно то, что я пытаюсь сделать.Я знаю, что в Appstore уже есть несколько приложений, которые делают это, но я не знаю, как это делается.

TLDR;Нужна помощь с одновременным воспроизведением AudioQueueServices с 10+ звуками.

Пример:

Новое воспроизведение

    if (isPlaying == NO) {
err = AudioQueueNewOutput (&streamFormat, AudioEngineOutputBufferCallback, self, nil, nil, 0, &outputQueue);
if (err != noErr) NSLog(@"AudioQueueNewOutput() error: %d", err);

Буферизация очереди

outputBuffersToRewrite = 3;
bufferByteSize = (sampleRate > 16000)? 2176 : 512; // 40.5 Hz : 31.25 Hz 
for (i=0; i<3; i++) {
    err = AudioQueueAllocateBuffer (outputQueue, bufferByteSize, &buffer); 
    if (err == noErr) {
        [self generateTone: buffer];
        err = AudioQueueEnqueueBuffer (outputQueue, buffer, 0, nil);
        if (err != noErr) NSLog(@"AudioQueueEnqueueBuffer() error: %d", err);
    } else {
        NSLog(@"AudioQueueAllocateBuffer() error: %d", err); 
        return;
    }
}

Запуск воспроизведения

isPlaying = YES;
err = AudioQueueStart(outputQueue, nil);
if (err != noErr) { NSLog(@"AudioQueueStart() error: %d", err); isPlaying= NO; return; }
} else {
NSLog (@"Error: audio is already playing back.");

Настройка полей формата потока

BOOL isHighSampleRate = (sampleRate > 16000);
int bufferByteSize;
AudioQueueBufferRef buffer;

AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = sampleRate;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
streamFormat.mBitsPerChannel = 16;
streamFormat.mChannelsPerFrame = 1;
streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame;
streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame;
streamFormat.mFramesPerPacket = 1;
streamFormat.mReserved = 0;

Ответы [ 3 ]

1 голос
/ 28 октября 2011

AudioQueue может воспроизводить звуки одновременно.

от apple:

Как воспроизводить несколько звуков одновременно?

Использование интерфейсов в службах Audio Queue Services (AudioToolbox/AudioQueue.h).Создайте один объект аудио-очереди для каждого звука, который вы хотите воспроизвести.Затем укажите время одновременного запуска первого аудиобуфера в каждой аудио-очереди, используя функцию AudioQueueEnqueueBufferWithParameters.

Следующие ограничения относятся к одновременным звукам в iPhone OS в зависимости от формата аудиоданных:

Аудио AAC, MP3 и ALAC (Apple Lossless): вы можете воспроизводить несколько звуков формата AAC, MP3 и ALAC одновременно;воспроизведение нескольких звуков этих форматов потребует ресурсов ЦП для декодирования.

Линейный PCM и IMA / ADPCM (аудио IMA4): Вы можете воспроизводить несколько звуков линейного формата PCM или IMA4 одновременно без проблем с ресурсами ЦП.

1 голос
/ 09 августа 2012

Помните, что вы имеете дело с одним аудиопотоком, поэтому вам нужно либо создать объединенный поток самостоятельно, либо использовать микшерный пульт, который позволит вам подавать его на несколько потоков.См. Пример кода «Audio Mixer (MixerHost)» от Apple.

0 голосов
/ 14 сентября 2011

AudioQueue не может воспроизводить несколько звуков одновременно. Он просто отправляет значения аудиоданных одно за другим из буфера в очереди. Таким образом, вам нужно объединить все звуки, которые вы хотите играть одновременно, в один. Как вы можете это сделать? Если данные не сжаты, это не слишком сложно. Например. у вас есть два разных звука. Каждое из них вы можете описать как массив значений с плавающей запятой от -1 до 1. Когда звуки хранятся в файле или добавляются в аудио-очередь, они должны быть представлены в соответствующем формате. В вашем случае (kAudioFormatLinearPCM, streamFormat.mBitsPerChannel = 16) это двухбайтовые целые числа, и каждое значение представляется в виде короткого целого числа от -32767 до 32767. Поэтому каждый из двух звуков является массивом шортов, и когда вы ставите в буфер буфер, вы заполняете его значениями этого массива (если звук не из файла и генерируется динамически, этот массив не существует, но значения рассчитываются по одному). И чтобы создать «сумму» этих двух звуковых файлов, вы должны построить каждое новое значение массива как среднее значение соответствующих значений из массива двух звуков.
то есть resultSound [i] = sound1 [i] / 2 + sound2 [i] / 2;
И все равно для любого количества звуков. Например. чтобы генерировать чистый гармонический звук, вы заполняете буфер как:

buffer[i] = sin(i * 2 * M_PI * frequency / sampleRate) * 32767;

и микширование двух гармонических звуков с разными частотами:

buffer[i] = sin(i * 2 * M_PI * frequency1 / sampleRate) + sin(i * 2 * M_PI * frequency2 / sampleRate) * 0.5 * 32767;
...