AudioConverterFillComplexBuffer return -50 (paramErr) - PullRequest
2 голосов
/ 11 октября 2011

Я пытаюсь преобразовать 32-битный аудиопоток PCM в ALAC. Я нашел несколько рабочих примеров для сборки, но мой собственный код продолжает получать -50 (paramErr) от AudioConverterFillComplexBuffer. Мои глаза смотрят на этот код; Я не вижу, что отличается от моих примеров.

Я настроил форматы ввода и вывода и создал конвертер:

UInt32 numChannels = 2;

// Describe the input stream
AudioStreamBasicDescription inputFormat;
memset(&inputFormat, 0, sizeof(AudioStreamBasicDescription));
inputFormat.mSampleRate = 44100;
inputFormat.mFormatID = kAudioFormatLinearPCM;
inputFormat.mFramesPerPacket = 1; 
inputFormat.mChannelsPerFrame = numChannels;  
inputFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked;
inputFormat.mBitsPerChannel = sizeof(Float32) * 8;
inputFormat.mBytesPerPacket = numChannels * (inputFormat.mBitsPerChannel / 8);
inputFormat.mBytesPerFrame = inputFormat.mBytesPerPacket * inputFormat.mFramesPerPacket;

// Describe the output stream
AudioStreamBasicDescription outputFormat;
memset(&outputFormat, 0, sizeof(AudioStreamBasicDescription));
outputFormat.mSampleRate = 44100;
outputFormat.mFormatID = kAudioFormatAppleLossless;
outputFormat.mFramesPerPacket = 4096;

OSStatus err = AudioConverterNew(&inputFormat, &outputFormat, &_alacConverter);

Затем я получаю максимальный размер выходного пакета и выделяю буфер для хранения преобразованных данных:

size = sizeof(UInt32);
UInt32 maxOutputSize;
AudioConverterGetProperty(_alacConverter, 
                          kAudioConverterPropertyMaximumOutputPacketSize, 
                          &size, 
                          &maxOutputSize);

_outputBuffer = [[NSMutableData dataWithCapacity:maxOutputSize] retain];

Наконец, я вызываю AudioConverterFillComplexBuffer для получения некоторых данных:

AudioBufferList bufferList; 
memset(&bufferList, 0, sizeof(AudioBufferList));
memset(&bufferList.mBuffers[0], 0, sizeof(AudioBuffer));

bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = numChannels;
bufferList.mBuffers[0].mDataByteSize = [_outputBuffer length];
bufferList.mBuffers[0].mData = [_outputBuffer mutableBytes];

AudioStreamPacketDescription streamDesc = {0};

UInt32 numPackets = 1;

err = AudioConverterFillComplexBuffer(_alacConverter, 
                                      _encoderDataProc, 
                                      self, 
                                      &numPackets, 
                                      &bufferList, 
                                      &streamDesc);

... где я всегда получаю ошибку -50. Кто-нибудь может дать мне подсказку, где я иду не так? Большое (большое) спасибо!

Обновление: Я просто использую функцию-заглушку в качестве источника данных, которая никогда не вызывается:

OSStatus _encoderDataProc(AudioConverterRef inAudioConverter, 
                          UInt32* ioNumberDataPackets, 
                          AudioBufferList* ioData, 
                          AudioStreamPacketDescription** outDataPacketDescription,
                          void* inUserData)
{
    TraceDebug(@"_encoderDataProc has been called");
    return -1;
}

Параметр maxOutputSize возвращается как 32776. И для хорошей меры вот что я получаю из CAShow (_alacConverter):

AudioConverter 0xa8404e (0x101c449f0):
  PCMConverter2 0x101c34370
    Input:   2 ch,  44100 Hz, 'lpcm' (0x00000009) 32-bit little-endian float
    Output:  2 ch,  44100 Hz, 'lpcm' (0x0000000C) 32-bit little-endian signed integer
  CodecConverter 0x101c44b90
    Input:   2 ch,  44100 Hz, 'lpcm' (0x0000000C) 32-bit little-endian signed integer
    Output:  2 ch,  44100 Hz, 'alac' (0x00000004) from 32-bit source, 4096 frames/packet
    codec: 'aenc'/'alac'/'appl'
    Input layout tag: 0x650002
    Output layout tag: 0x650002

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

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

Я застрял в той же ситуации (в основном после использования вашего кода в качестве шаблона). Похоже, решение заключается в распределении памяти для AudioBufferList. Внедрение этого ответа помогло мне (хотя моя цель-C недостаточно хороша, чтобы увидеть точную разницу:))

0 голосов
/ 27 марта 2012

Я столкнулся с той же проблемой (AudioConverterFillComplexBuffer возвращает -50)
-
, но он появился только после перезапуска того же конвертера со вторым файлом после того, как первый проигран до конца.Первый файл конвертировался без проблем.

С помощью ответа Клода (СПАСИБО!) Я обнаружил, что конвертер фактически изменяет размер AudioBufferList на 0, если достигнут конец файла.

После сброса размеров AudioBufferList к исходным значениям теперь все работает как положено.

...