gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 03:55:38 25 4
gpt4 key购买 nike

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

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

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

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

- (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;
}

我解码帧的函数如下所示:

- (void)startDecodingAudio {
if (!_converterConfigured){
return;
}

while (true){
if ([self hasFramesToDecode]){
struct MyUserData userData = {1, (UInt32)_decoderBuffer[_currPosInDecoderBuf].length, _decoderBuffer[_currPosInDecoderBuf].bytes};

uint8_t *buffer = (uint8_t *)malloc(128 * sizeof(short int));
AudioBufferList decBuffer;
decBuffer.mNumberBuffers = 1;
decBuffer.mBuffers[0].mNumberChannels = 1;
decBuffer.mBuffers[0].mDataByteSize = 128 * sizeof(short int);
decBuffer.mBuffers[0].mData = buffer;

UInt32 numFrames = 128;

AudioStreamPacketDescription outPacketDescription;
memset(&outPacketDescription, 0, sizeof(AudioStreamPacketDescription));
outPacketDescription.mDataByteSize = 128;
outPacketDescription.mStartOffset = 0;
outPacketDescription.mVariableFramesInPacket = 0;

OSStatus status = AudioConverterFillComplexBuffer(_audioConverter,
inInputDataProc,
&userData,
&numFrames,
&decBuffer,
&outPacketDescription);

NSError *error = nil;

if (status == kNoMoreDataError) {
NSLog(@"%u bytes decoded", (unsigned int)decBuffer.mBuffers[0].mDataByteSize);
[_decodedData appendData:[NSData dataWithBytes:decBuffer.mBuffers[0].mData length:decBuffer.mBuffers[0].mDataByteSize]];
_currPosInDecoderBuf += 1;
} else {
error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
}
} else {
break;
}
}
}

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

最佳答案

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

关于ios - 如何使用 AudioConverterFillComplexBuffer iOS 将 AAC 压缩帧解码为 PCM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42959295/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com