如何使用AudioConverterFillComplexBuffer iOS将AAC压缩帧解码为PCM

时间:2017-03-22 17:55:39

标签: ios objective-c pcm aac adts

我想在我的应用程序中实现SIP调用,我需要解决的第一个问题是将带有ADTS标头的压缩AAC格式的音频转换为线性PCM。

我的输入数据是具有不同帧大小的ADTS帧的NSArray。每个帧都是NSMutableData类型。每个帧具有相同的格式和采样率,唯一的区别是帧大小。

我试图实现示例代码,由Igor Rotaru为this issue建议,但无法使其正常工作。

现在我的代码看起来像这样。首先,我配置AudioConverter:

localhost/0:0:0:0:0:0:0:1:8080

之后我编写了回调函数:

- (void)configureAudioConverter {
    AudioStreamBasicDescription inFormat;
    memset(&inFormat, 0, sizeof(inFormat));
    inputFormat.mBitsPerChannel = 0;
    inputFormat.mBytesPerFrame = 0;
    inputFormat.mBytesPerPacket = 0;
    inputFormat.mChannelsPerFrame = 1;
    inputFormat.mFormatFlags = kMPEG4Object_AAC_LC;
    inputFormat.mFormatID = kAudioFormatMPEG4AAC;
    inputFormat.mFramesPerPacket = 1024;
    inputFormat.mReserved = 0;
    inputFormat.mSampleRate = 22050;

    AudioStreamBasicDescription outputFormat;
    memset(&outputFormat, 0, sizeof(outputFormat));
    outputFormat.mSampleRate       = inputFormat.mSampleRate;
    outputFormat.mFormatID         = kAudioFormatLinearPCM;
    outputFormat.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger;
    outputFormat.mBytesPerPacket   = 2;
    outputFormat.mFramesPerPacket  = 1;
    outputFormat.mBytesPerFrame    = 2;
    outputFormat.mChannelsPerFrame = 1;
    outputFormat.mBitsPerChannel   = 16;
    outputFormat.mReserved         = 0;

    AudioClassDescription *description = [self
                                      getAudioClassDescriptionWithType:kAudioFormatMPEG4AAC
                                      fromManufacturer:kAppleSoftwareAudioCodecManufacturer];

    OSStatus status =  AudioConverterNewSpecific(&inputFormat, &outputFormat, 1, description, &_audioConverter);

    if (status != 0) {
        printf("setup converter error, status: %i\n", (int)status);
    }
}

我的解码帧功能如下:

struct MyUserData {
    UInt32 mChannels;
    UInt32 mDataSize;
    const void* mData;
    AudioStreamPacketDescription mPacket;
};

OSStatus inInputDataProc(AudioConverterRef inAudioConverter,
                         UInt32 *ioNumberDataPackets,
                         AudioBufferList *ioData,
                         AudioStreamPacketDescription **outDataPacketDescription,
                         void *inUserData)
{
    struct MyUserData* userData = (struct MyUserData*)(inUserData);

    if (!userData->mDataSize) {
        *ioNumberDataPackets = 0;
        return kNoMoreDataError;
    }

    if (outDataPacketDescription) {
        userData->mPacket.mStartOffset = 0;
        userData->mPacket.mVariableFramesInPacket = 0;
        userData->mPacket.mDataByteSize = userData->mDataSize;
        *outDataPacketDescription = &userData->mPacket;
    }

    ioData->mBuffers[0].mNumberChannels = userData->mChannels;
    ioData->mBuffers[0].mDataByteSize = userData->mDataSize;
    ioData->mBuffers[0].mData = (void *)userData->mData;

    // No more data to provide following this run.
    userData->mDataSize = 0;

    return noErr;
}

每次,AudioConverterFillComplexBuffer都会返回状态1852797029,根据Apple API,它是kAudioCodecIllegalOperationError。如果有人成功转换这些格式,请分享一些例子或建议。

1 个答案:

答案 0 :(得分:4)

最后,我使用StreamingKit库解码了我的字节(可以找到原始的reposiory here)。