I'm trying to decode aac to pcm data, my goal is to decode the acc data received by tcp into pcm data. Currently I want to convert local aac files to pcm data first, and I encounter a problem:
[AudioConverter] CompositeAudioConverter.cpp:1063 Packet description 0 of 1 (size 1009664) exceeds maximum packet size (2048) for input format
I first convert all the aac files to data, and then directly feed it to the decoder, and get the above error.
Below is my decoder code:
- (void)setupDecoder{
AudioStreamBasicDescription outputAudioDes;
memset(&outputAudioDes, 0, sizeof(outputAudioDes));
outputAudioDes.mSampleRate = (Float64)_config.sampleRate; outputAudioDes.mChannelsPerFrame = (UInt32)_config.channelCount;
outputAudioDes.mFormatID = kAudioFormatLinearPCM;
outputAudioDes.mFormatFlags = (kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked);
outputAudioDes.mFramesPerPacket = 1;
outputAudioDes.mBitsPerChannel = 16;
outputAudioDes.mBytesPerFrame = outputAudioDes.mBitsPerChannel / 8 * outputAudioDes.mChannelsPerFrame;
outputAudioDes.mBytesPerPacket = outputAudioDes.mBytesPerFrame * outputAudioDes.mFramesPerPacket;
outputAudioDes.mReserved = 0;
AudioStreamBasicDescription inputAudioDes;
memset(&inputAudioDes, 0, sizeof(inputAudioDes));
inputAudioDes.mSampleRate = (Float64)_config.sampleRate;
inputAudioDes.mFormatID = kAudioFormatMPEG4AAC;
inputAudioDes.mFormatFlags = kMPEG4Object_AAC_LC;
inputAudioDes.mFramesPerPacket = 1024;
inputAudioDes.mChannelsPerFrame = (UInt32)_config.channelCount;
UInt32 inDesSize = sizeof(inputAudioDes);
AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &inDesSize, &inputAudioDes);
AudioClassDescription *audioClassDesc = [self getAudioClassDescriptionWithType:outputAudioDes.mFormatID fromManufacture:kAppleHardwareAudioCodecManufacturer];
OSStatus status = AudioConverterNewSpecific(&inputAudioDes,
&outputAudioDes,
1,
audioClassDesc,
&_audioConverter);
if (status != noErr){
NSLog(@"Error!: status = %d",(int)status);
return;
}
}
- (AudioClassDescription *)getAudioClassDescriptionWithType:(AudioFormatID)type fromManufacture:(uint32_t)manufacture{
static AudioClassDescription desc;
UInt32 decoderSpecific = type;
UInt32 size;
OSStatus status = AudioFormatGetPropertyInfo(kAudioFormatProperty_Decoders, sizeof(decoderSpecific), &decoderSpecific, &size);
if (status != noErr){
NSLog(@"Error!: status = %d",(int)status);
return nil;
}
unsigned int count = size / sizeof(AudioClassDescription);
AudioClassDescription description[count];
status = AudioFormatGetProperty(kAudioFormatProperty_Encoders, sizeof(decoderSpecific), &decoderSpecific, &size, &description);
if (status != noErr){
NSLog(@"Error!: status = %d",(int)status);
return nil;
}
for (unsigned int i = 0; i < count; i++) {
if (type == description[i].mSubType &&
manufacture == description[i].mManufacturer){
desc = description[i];
return &desc;
}
}
return nil;
}
- (void)decodeAudioAACData:(NSData *)aacData{
if (!_audioConverter){
return;
}
__weak typeof(self) weakSelf = self;
dispatch_async(_decoderQueue, ^{
SRAudioUserData userData = {0};
userData.channelCount = (UInt32)weakSelf.config.channelCount;
userData.data = (char *)[aacData bytes];
userData.size = (UInt32)aacData.length;
userData.packetDesc.mDataByteSize = (UInt32)aacData.length;
userData.packetDesc.mStartOffset = 0;
userData.packetDesc.mVariableFramesInPacket = 0;
const uint32_t MAX_AUDIO_FRAMES = 2048;
UInt32 pcmBufferSize = (UInt32)(MAX_AUDIO_FRAMES * self->_config.channelCount);
UInt32 pcmDataPacketSize = 1;
uint8_t *pcmBuffer = malloc(pcmBufferSize);
memset(pcmBuffer, 0, pcmBufferSize);
AudioBufferList outAudioBufferList = {0};
outAudioBufferList.mNumberBuffers = 1;
outAudioBufferList.mBuffers[0].mNumberChannels = (uint32_t)self->_config.channelCount;
outAudioBufferList.mBuffers[0].mDataByteSize = (UInt32)pcmBufferSize;
outAudioBufferList.mBuffers[0].mData = pcmBuffer;
AudioStreamPacketDescription outputPacketDesc;
memset(&outputPacketDesc, 0, sizeof(AudioStreamPacketDescription));
outputPacketDesc.mDataByteSize = MAX_AUDIO_FRAMES;
outputPacketDesc.mStartOffset = 0;
outputPacketDesc.mVariableFramesInPacket = 0;
OSStatus status = AudioConverterFillComplexBuffer(self->_audioConverter,
&AudioDecoderConverterComplexInputDataProc,
&userData,
&pcmDataPacketSize,
&outAudioBufferList,
&outputPacketDesc);
if (status != noErr){
NSLog(@"Error: AAC Decoder error, status = %d",(int)status);
return;
}
if (outAudioBufferList.mBuffers[0].mDataByteSize > 0){
NSData *rawData = [NSData dataWithBytes:outAudioBufferList.mBuffers[0].mData length:outAudioBufferList.mBuffers[0].mDataByteSize];
NSLog(@"rawData %ld", rawData.length);
dispatch_async(weakSelf.callbackQueue, ^{
[weakSelf.delegate audioDecoderCallback:rawData];
});
}
free(pcmBuffer);
});
}
- (void)dealloc{
if (_audioConverter){
AudioConverterDispose(_audioConverter);
_audioConverter = NULL;
}
}
static OSStatus AudioDecoderConverterComplexInputDataProc(AudioConverterRef inAudioConverter,
UInt32 *ioNumberDataPackets,
AudioBufferList *ioData,
AudioStreamPacketDescription **outDataPacketDescription,
void *inUserData){
SRAudioUserData *audioDecoder = (SRAudioUserData *)(inUserData);
if (audioDecoder->size <= 0){
ioNumberDataPackets = 0;
return -1;
}
if (outDataPacketDescription){
*outDataPacketDescription = &audioDecoder->packetDesc;
(*outDataPacketDescription)[0].mStartOffset = 0;
(*outDataPacketDescription)[0].mDataByteSize = audioDecoder->size;
(*outDataPacketDescription)[0].mVariableFramesInPacket = 0;
}
ioData->mBuffers[0].mData = audioDecoder->data;
ioData->mBuffers[0].mDataByteSize = audioDecoder->size;
ioData->mBuffers[0].mNumberChannels = audioDecoder->channelCount;
return noErr;
}
Below are the default property values for my _config:
self.bitrate = 6400;
self.channelCount = 2;
self.sampleSize = 16;
self.sampleRate = 44100;
This is my code to convert aac file to data:
if let audioPath = Bundle.main.path(forResource: "hello.aac", ofType: nil),
let stream = InputStream(fileAtPath: audioPath){
let audioDecoder = SRAudioDecoder(config: nil)
if let streamData = try? Data(reading: stream){
audioDecoder.decodeAudioAACData(streamData)
}
}
// Data Extension
init(reading input: InputStream) throws {
self.init()
input.open()
defer {
input.close()
}
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
defer {
buffer.deallocate()
}
while input.hasBytesAvailable {
let read = input.read(buffer, maxLength: bufferSize)
if read < 0 {
//Stream error occured
throw input.streamError!
} else if read == 0 {
//EOF
break
}
self.append(buffer, count: read)
}
}
I try to split the data into 1024 for the decoder, but there is still an error:
Error: AAC Decoder error, status = 1650549857
AACDecoder.cpp:200 Unmatched number of channel elements in payload
AACDecoder.cpp:228 Error deserializing packet
ACMP4AACBaseDecoder.cpp:1438 (0x108811840) Error decoding packet 141: err = -1, packet length: 1024
Any suggestions are greatly appreciated.