iPhone:使用音频转换器FillComplexBuffer将32KHz PCM编码为96Kbit AAC时出现问题
有人在iPhone/iOS上成功地将32KHz PCM转换为96Kbit AAC吗 我无法让它在任何硬件设备上正常工作。我写的代码只能在模拟器中正常工作。在当前一代iPad/iPod/iPhone上运行时,我的代码会“跳过”大量音频 生成的编码流包含约640ms的“好”音频和约640ms的“坏”音频的重复模式 对16位线性和8.24定点PCM进行编码得到了相同的结果 以下是设置音频转换器以对MPEG4-AAC 96kbits@32KHz进行编码的代码:iPhone:使用音频转换器FillComplexBuffer将32KHz PCM编码为96Kbit AAC时出现问题,iphone,ios,audio,encoding,aac,Iphone,Ios,Audio,Encoding,Aac,有人在iPhone/iOS上成功地将32KHz PCM转换为96Kbit AAC吗 我无法让它在任何硬件设备上正常工作。我写的代码只能在模拟器中正常工作。在当前一代iPad/iPod/iPhone上运行时,我的代码会“跳过”大量音频 生成的编码流包含约640ms的“好”音频和约640ms的“坏”音频的重复模式 对16位线性和8.24定点PCM进行编码得到了相同的结果 以下是设置音频转换器以对MPEG4-AAC 96kbits@32KHz进行编码的代码: AudioStreamBasicDescr
AudioStreamBasicDescription descPCMFormat;
descPCMFormat.mSampleRate = 32000;
descPCMFormat.mChannelsPerFrame = 1;
descPCMFormat.mBitsPerChannel = sizeof(AudioUnitSampleType) * 8;
descPCMFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
descPCMFormat.mFramesPerPacket = 1;
descPCMFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
descPCMFormat.mFormatID = kAudioFormatLinearPCM;
descPCMFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
AudioStreamBasicDescription descAACFormat;
descAACFormat.mSampleRate = 32000;
descAACFormat.mChannelsPerFrame = 1;
descAACFormat.mBitsPerChannel = 0;
descAACFormat.mBytesPerPacket = 0;
descAACFormat.mFramesPerPacket = 1024;
descAACFormat.mBytesPerFrame = 0;
descAACFormat.mFormatID = kAudioFormatMPEG4AAC;
descAACFormat.mFormatFlags = 0;
AudioConverterNew(& descPCMFormat, & descAACFormat, &m_hCodec);
UInt32 ulBitRate = 96000;
UInt32 ulSize = sizeof(ulBitRate);
AudioConverterSetProperty(m_hCodec, kAudioConverterEncodeBitRate, ulSize, & ulBitRate);
简单的转换程序。此例程每32毫秒调用一次,块为1024个PCM样本,需要384字节的编码AAC:
OSStatus CMyObj::Convert(
const AudioUnitSampleType * pSrc,
const size_t ulSrc,
uint8_t * pDst,
size_t & ulDst)
{
// error and sanity checking removed..
// assume caller is converting 1024 samples to at most 384 bytes
OSStatus osStatus;
m_pSrcPtr = (uint8_t*)pSrc;
m_ulSrcLen = ulSrc; // verified to be 1024*sizeof(AudioUnitSampleType);
AudioBufferList destBuffers;
destBuffers.mNumberBuffers = 1;
destBuffers.mBuffers[0].mNumberChannels = 1;
destBuffers.mBuffers[0].mDataByteSize = 384;
destBuffers.mBuffers[0].mData = pDst;
AudioStreamPacketDescription destDescription;
destDescription.mStartOffset = 0;
destDescription.mVariableFramesInPacket = 0;
destDescription.mDataByteSize = 384;
UInt32 ulDstPackets = 1;
osStatus = AudioConverterFillComplexBuffer(
m_hCodec,
InputDataProc,
this,
& ulDstPackets,
& destBuffers,
& destDescription);
ulDst = destBuffers.mBuffers[0].mDataByteSize;
return osStatus;
}
输入数据过程仅向编码器提供1024个样本:
static OSStatus CMyObj::InputDataProc(
AudioConverterRef hCodec,
UInt32 *pulSrcPackets,
AudioBufferList *pSrcBuffers,
AudioStreamPacketDescription **ppPacketDescription,
void *pUserData)
{
// error and sanity checking removed
CMyObj *pThis = (CMyObj*)pUserData;
const UInt32 ulMaxSrcPackets = pThis->m_ulSrcLen / sizeof(AudioUnitSampleType);
const UInt32 ulRetSrcPackets = min(ulMaxSrcPackets, *pulSrcPackets);
if( ulRetSrcPackets )
{
UInt32 ulRetSrcBytes = ulRetSrcPackets * sizeof(AudioUnitSampleType);
*pulSrcPackets = ulRetSrcPackets;
pSrcBuffers->mBuffers[0].mData = pThis->m_pSrcPtr;
pSrcBuffers->mBuffers[0].mDataByteSize = ulRetSrcBytes;
pSrcBuffers->mBuffers[0].mNumberChannels = 1;
pThis->m_pSrcPtr += ulRetSrcBytes;
pThis-> m_ulSrcLen -= ulRetSrcBytes;
return noErr;
}
*pulSrcPackets = 0;
pSrcBuffers->mBuffers[0].mData = NULL;
pSrcBuffers->mBuffers[0].mDataByteSize = 0;
pSrcBuffers->mBuffers[0].mNumberChannels = 1;
return 500; // local error code to signal end-of-packet
}
在模拟器上运行时,一切正常
但是,在设备上运行时,不会一致地调用InputDataProc。连续20次,对AudioConverterFillComplexBuffer的调用会引发对InputDataProc的调用,一切看起来都很好。然后,对于对AudioConverterFillComplexBuffer的下21次调用,将不会调用InputDataProc。这种模式永远重复:
-> Convert
-> AudioConverterFillComplexBuffer
-> InputDataProc
-> results in 384 bytes of 'good' AAC
-> Convert
-> AudioConverterFillComplexBuffer
-> InputDataProc
-> results in 384 bytes of 'good' AAC
.. repeats up to 18 more times
-> Convert
-> AudioConverterFillComplexBuffer
-> results in 384 bytes of 'bad' AAC
-> Convert
-> AudioConverterFillComplexBuffer
-> results in 384 bytes of 'bad' AAC
.. repeats up to 18 more times
转换器在哪里获取输入数据以创建“坏”AAC,因为它没有调用InputDataProc
有人认为这种方法有什么明显的错误吗
是否需要在硬件编解码器(MagicCookies或?)上进行任何特殊设置
HW AAC编解码器是否支持32000采样率?我发现:32KHz输入PCM的默认输出比特率为48000位,44.1KHz-input-PCM的默认输出比特率为64000位。 当使用默认输出比特率时,32KHz输入会产生巨大的噪声。 即使使用,44.1KHz的输入也有一点噪声 然后我将输出比特率固定为64kbs、32KHz和44.1KHz,这两种情况都很好
UInt32 outputBitRate = 64000; // 64kbs
UInt32 propSize = sizeof(outputBitRate);
if (AudioConverterSetProperty(m_converter, kAudioConverterEncodeBitRate, propSize, &outputBitRate) != noErr) {
} else {
NSLog(@"upyun.com uplivesdk UPAACEncoder error 102");
}
我可以通过强制使用AudioConverterNewSpecific并指定mManufacturer KappleSoftwareAudoCodecManufacturer来实现与模拟器相同的硬件行为。了解如何使用硬件编解码器仍然很好!罗托瓦,你能对我的问题发表意见吗。我看你在这方面有经验。