Обратный вызов служб Audio Queue Services: AudioStreamPacketDescription не может быть скопировано? - PullRequest
3 голосов
/ 08 января 2012

Я создаю простое приложение для iOS, которое записывает звук с круговым буфером.Это означает, что он постоянно записывает аудио, но сохраняет в памяти только последние 15 буферов.

Я делаю это, копируя все данные, которые я получаю с AudioInputCallback:

void AudioInputCallback(
                    void *inUserData, 
                    AudioQueueRef inAQ, 
                    AudioQueueBufferRef inBuffer, 
                    const AudioTimeStamp *inStartTime, 
                    UInt32 inNumberPacketDescriptions, 
                    const AudioStreamPacketDescription *inPacketDescs) 

Этоотлично работает, и я могу правильно записать файл AIF, когда я сохраняю все свои буферы в файл после остановки записи.Таким образом, копирование данных в другие буферы работает правильно.

Проблема, однако, в том, что когда я использую M4A, который использует переменные пакеты, та же самая процедура не работает.Когда я помещаю метод AudioFileWritePackets в функцию обратного вызова, он работает правильно, но когда я впоследствии использую его для хранимых буферизованных данных, он терпит неудачу.

Оказывается, это вызвано данными const AudioStreamPacketDescription *inPacketDescsКогда я изменяю это в самой функции обратного вызова (запись там) на мою копию, это немедленно терпит неудачу.Однако сами данные идентичны.

Это формат:

struct AudioStreamPacketDescription {
   SInt64  mStartOffset;
   UInt32  mVariableFramesInPacket;
   UInt32  mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;

Я создаю копию в своем коде, используя следующий метод:

item.inPacketDescs = (AudioStreamPacketDescription *)(malloc(sizeof(AudioStreamPacketDescription)));

    item.inPacketDescs->mDataByteSize = inPacketDescs->mDataByteSize;
    item.inPacketDescs->mStartOffset = inPacketDescs->mStartOffset;
    item.inPacketDescs->mVariableFramesInPacket = inPacketDescs->mVariableFramesInPacket;

Однако,если затем использовать item.inPacketDescs вместо inPacketDescs, это немедленно завершится неудачей.И это пока данные этих трех полей идентичны.(Я проверял с помощью отладчика).

У меня немного больше нет вариантов.Я вижу, что поставляемая переменная const, поэтому я боюсь, что это имеет какое-то значимое назначение, например, AudioFileWritePackets требует, чтобы это был тот же адрес памяти или так?Это было бы поразительно глупо, но я больше не знаю.

Есть идеи, что вызвало это?Идеи о том, как сохранить его по-другому в кольцевой буфер?

1 Ответ

2 голосов
/ 10 января 2012

Оказывается, что inPacketDescs является array из AudioStreamPackedDescription. Поэтому копирование только первого значения было неудачным.

Решение:

AudioStreamPacketDescription * test = (AudioStreamPacketDescription *)(malloc(inNumberPacketDescriptions * sizeof(AudioStreamPacketDescription)));
    memcpy(test, inPacketDescs, inNumberPacketDescriptions * sizeof(AudioStreamPacketDescription));
...