AAC音频编码 相关的原理和设置

作者&投稿:闭亮 (若有异议请与网页底部的电邮联系)
~ AAC(Advanced Audio Coding),中文名:高级 音频 编码 ,出现于1997年,基于 MPEG-2 的音频编码技术。由Fraunhofer IIS、 杜比实验室 、 AT&T 、 Sony 等公司共同开发,目的是取代 MP3 格式。2000年, MPEG-4 标准出现后,AAC重新集成了其特性,加入了SBR技术和PS技术,为了区别于传统的MPEG-2 AAC又称为MPEG-4 AAC。

iOS平台支持AAC编码器,主要使用AudioToolbox中的AudioConverter API。之所以做AAC编码器是因为在做一个HLS的功能,HLS要求的TS文件,需要视频采用H264编码,音频采用AAC编码。H264可以使用硬件或软件编码器,前面已经介绍。AAC也可以使用硬件或者软件编码,iOS全都支持。

首先需要创建一个Converter,也就是一个AAC Encoder,使用如下接口:

extern OSStatus

AudioConverterNew(      const AudioStreamBasicDescription*  inSourceFormat,

const AudioStreamBasicDescription*  inDestinationFormat,

AudioConverterRef*                  outAudioConverter)      __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0);

输入参数分别是源和目的的数据格式。

在AAC编码的场景下,源格式就是采集到的PCM数据,目的格式就是AAC。

AudioStreamBasicDescription inAudioStreamBasicDescription;

//    FillOutASBDForLPCM()

inAudioStreamBasicDescription.mFormatID = kAudioFormatLinearPCM;

inAudioStreamBasicDescription.mSampleRate = 44100;

inAudioStreamBasicDescription.mBitsPerChannel = 16;

inAudioStreamBasicDescription.mFramesPerPacket = 1;

inAudioStreamBasicDescription.mBytesPerFrame = 2;

inAudioStreamBasicDescription.mBytesPerPacket = inAudioStreamBasicDescription.mBytesPerFrame * inAudioStreamBasicDescription.mFramesPerPacket;

inAudioStreamBasicDescription.mChannelsPerFrame = 1;

inAudioStreamBasicDescription.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsNonInterleaved;

inAudioStreamBasicDescription.mReserved = 0;

AudioStreamBasicDescription outAudioStreamBasicDescription = {0}; // Always initialize the fields of a new audio stream basic description structure to zero, as shown here: ...

outAudioStreamBasicDescription.mChannelsPerFrame = 1;

outAudioStreamBasicDescription.mFormatID = kAudioFormatMPEG4AAC;

UInt32 size = sizeof(outAudioStreamBasicDescription);

AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &outAudioStreamBasicDescription);

OSStatus status = AudioConverterNew(&inAudioStreamBasicDescription, &outAudioStreamBasicDescription, &_audioConverter);

if(status != 0) {NSLog(@"setup converter failed: %d", (int)status);}

这样就创建了AAC编码器,默认情况下,Apple会创建一个硬件编码器,如果硬件不可用,会创建软件编码器。

经过我的测试,硬件AAC编码器的编码时延很高,需要buffer大约2秒的数据才会开始编码。而软件编码器的编码时延就是正常的,只要喂给1024个样点,就会开始编码。

那么如何在创建的时候指定使用软件编码器呢?需要用到下面的接口:

- (AudioClassDescription *)getAudioClassDescriptionWithType:(UInt32)type

fromManufacturer:(UInt32)manufacturer

{

static AudioClassDescription desc;

UInt32 encoderSpecifier = type;

OSStatus st;

UInt32 size;

st = AudioFormatGetPropertyInfo(kAudioFormatProperty_Encoders,

sizeof(encoderSpecifier),

&encoderSpecifier,

&size);

if (st) {

NSLog(@"error getting audio format propery info: %d", (int)(st));

return nil;

}

unsigned int count = size / sizeof(AudioClassDescription);

AudioClassDescription descriptions[count];

st = AudioFormatGetProperty(kAudioFormatProperty_Encoders,

sizeof(encoderSpecifier),

&encoderSpecifier,

&size,

descriptions);

if (st) {

NSLog(@"error getting audio format propery: %d", (int)(st));

return nil;

}

for (unsigned int i = 0; i < count; i++) {

if ((type == descriptions[i].mSubType) &&

(manufacturer == descriptions[i].mManufacturer)) {

memcpy(&desc, &(descriptions[i]), sizeof(desc));

return &desc;

}

}

return nil;

}

AudioClassDescription *desc = [self getAudioClassDescriptionWithType:kAudioFormatMPEG4AAC

fromManufacturer:kAppleSoftwareAudioCodecManufacturer];

OSStatus status = AudioConverterNewSpecific(&inAudioStreamBasicDescription, &outAudioStreamBasicDescription, 1, desc, &_audioConverter);

如果要正确的编码,编码码率参数是必须设置的。否则编码时会返回560226676错误码(!dat)。

UInt32 ulBitRate = 64000;

UInt32 ulSize = sizeof(ulBitRate);

status = AudioConverterSetProperty(_audioConverter, kAudioConverterEncodeBitRate, ulSize, &ulBitRate);

需要注意,AAC并不是随便的码率都可以支持。比如如果PCM采样率是44100KHz,那么码率可以设置64000bps,如果是16K,可以设置为32000bps。

创建完成Converter和设置完Bitrate之后,可以查询一下最大编码输出的大小,后续会用到。

UInt32 value = 0;

size = sizeof(value);

AudioConverterGetProperty(_audioConverter, kAudioConverterPropertyMaximumOutputPacketSize, &size, &value);

获取出来的Value表示编码器最大输出的包大小。

然后调用AudioConverterFillCOmplexBuffer进行编码:

AudioBufferList outAudioBufferList = {0};

outAudioBufferList.mNumberBuffers = 1;

outAudioBufferList.mBuffers[0].mNumberChannels = 1;

outAudioBufferList.mBuffers[0].mDataByteSize = value;//value是上面查询到的值

outAudioBufferList.mBuffers[0].mData = new int8[value];

UInt32 ioOutputDataPacketSize = 1;

status = AudioConverterFillComplexBuffer(_audioConverter, inInputDataProc, (__bridge void *)(self), &ioOutputDataPacketSize, &outAudioBufferList, NULL);

编码接口中,inInputDataProc是一个输入数据的回调函数。用来喂PCM数据给Converter,ioOutputDataPacketSize为1表示编码产生1帧数据即返回。outAudioBufferList用来存放编码后的数据。

inInputDataProc中的处理如下:

static OSStatus inInputDataProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData)

{

AACEncoder *encoder = (__bridge AACEncoder *)(inUserData);

UInt32 requestedPackets = *ioNumberDataPackets;

uint8_t *buffer;

uint32_t bufferLength = requestedPackets * 2;

uint32_t bufferRead;

bufferRead = [encoder.pcmPool readBuffer:&buffer withLength:bufferLength];

if (bufferRead == 0) {

*ioNumberDataPackets = 0;

return -1;

}

ioData->mBuffers[0].mData = buffer;

ioData->mBuffers[0].mDataByteSize = bufferRead;

ioData->mNumberBuffers = 1;

ioData->mBuffers[0].mNumberChannels = 1;

*ioNumberDataPackets = bufferRead >> 1;

return noErr;

}

pcmPool是一个用于存放PCM数据的环形缓冲区。

因为采集输入每次不一定有1024样点,所以可以将数据缓存起来,再满足1024样点时再调用编码。

另外,对于TS文件来说,每个AAC数据需要增加一个adts头,adts头是一个7bit的数据,通过adts可以得知AAC数据的编码参数,方便解码器进行解码。

adts头的计算方法如下:

- (NSData*) adtsDataForPacketLength:(NSUInteger)packetLength {

int adtsLength = 7;

char *packet = (char *)malloc(sizeof(char) * adtsLength);

// Variables Recycled by addADTStoPacket

int profile = 2;  //AAC LC

//39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;

int freqIdx = 8;  //16KHz

int chanCfg = 1;  //MPEG-4 Audio Channel Configuration. 1 Channel front-center

NSUInteger fullLength = adtsLength + packetLength;

// fill in ADTS data

packet[0] = (char)0xFF; // 11111111  = syncword

packet[1] = (char)0xF9; // 1111 1 00 1  = syncword MPEG-2 Layer CRC

packet[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));

packet[3] = (char)(((chanCfg&3)<<6) + (fullLength>>11));

packet[4] = (char)((fullLength&0x7FF) >> 3);

packet[5] = (char)(((fullLength&7)<<5) + 0x1F);

packet[6] = (char)0xFC;

NSData *data = [NSData dataWithBytesNoCopy:packet length:adtsLength freeWhenDone:YES];

return data;

}


德令哈市13219618109: 关于AAC格式编码!!! -
单于吴尼群: 1、CD导入电脑,想要质量高,最好的选择是用无损格式APE或者FLAC之类.对于有损的AAC,码率越高音质越接近原CD.AAC的最大码率约在500kbps左右.2、如果真的是用AAC格式,VBR选不选无所谓.因为AAC的编码器一定会用...

德令哈市13219618109: AAC音乐格式是什么?有何操作方式? -
单于吴尼群: AAC(高级音频编码) AAC(高级音频编码技术 Advanced Audio Coding),出现于1997年,是基于MPEG-2的音频编码技术.由Fraunhofer IIS、杜比、苹果、AT&T、索尼等公司共同开发,以取代mp3格式.2000年,MPEG-4标准出台,...

德令哈市13219618109: 在音频编码中,AAC和MP3有什么区别? -
单于吴尼群: 您好,两种格式音频文件中mp3的比较常见, 同码率下aac音质好 而且aac支持比320更高的码率 不过aac资源较少 播放器支持不是很好 1、AAC介绍 AAC是Advanced Audio Coding(高级音频编码)的缩写,这种音乐格式具有比MP3更高的质...

德令哈市13219618109: AAC硬件解码是什么? -
单于吴尼群: AAC(Advanced Audio Coding)实际上是高级音频编码的缩写,AAC是由Fraunhofer IIS-A、杜比和AT&T共同开发的一种音频格式,它是MPEG-2规范的一部分.AAC所采用的运算法则与MP3的运算法则有所不同,AAC通过结合其他的功能来提高编码效率.AAC的音频算法在压缩能力上远远超过了以前的一些压缩算法(比如MP3等).它还同时支持多达48个音轨、15个低频音轨、更多种采样率和比特率、多种语言的兼容能力、更高的解码效率.总之,AAC可以在比MP3文件缩小30%的前提下提供更好的音质,被手机界称为“21世纪数据压缩方式”.

德令哈市13219618109: aac是什么文件? -
单于吴尼群: 音频文件,在手机酷狗里下载的一般就是aac的、音质不好、占内存小、

德令哈市13219618109: AAC音频格式是什么? 和WMA,MP3格式有何区别?? -
单于吴尼群: Adpative Audio Coding.一种专为声音数据设计的文件压缩格式,与Mp3类似.利用AAC格式,可使声音文件明显减小,而不会让人感觉声音质量有所降低AAC格式可以用千千静听(六组件)或苹果iTunes转换从MP3到AAC早在1987年,...

德令哈市13219618109: 什么是AAC播放格式?根MP3格式有何区别?
单于吴尼群: AAC实际上是高级音频编码的缩写,目前只有苹果的硬盘式MP3支持这一种格式.AAC是由Fraunhofer IIS-A、杜比和AT&T共同开发的一种音频格式,它是MPEG-2规范的一部分.AAC所采用的运算法则与MP3的运算法则有所不同,AAC通过结合其他的功能 来提高编码效率.AAC的音频算法在压缩能力上远远超过了以前的一些压缩算法(比如MP3等).它还同时支持多达48个音轨、15个低频音轨、更多种采样率和比特率、多种语言的兼容能力、更高的解码效率.总之,AAC可以在比MP3文件缩小30%的前提下提供更好的音质.

德令哈市13219618109: mp3、aac、 m4a 这3个格式的声音,哪个最好?
单于吴尼群: AAC好,AAC(Advanced Audio Codec 高级音频编码)本身就是作为mp3的取代格式而被开发的,有着比mp3更高的压缩率,能在比mp3体积小30%的情况下提供比mp3更好的硬质.其中AAC又分为AAC LC(低复杂程度,一般的AAC就是指它),HE-AAC(高复杂编码,原理略有不同,一般仅有16kbps~96kbps,但音质已经很高)

德令哈市13219618109: 什么是ACC音乐格式 -
单于吴尼群: ACC=AAC(高级音频编码技术,Advanced Audio Coding)是杜比实验室为音乐社区提供的技术.AAC号称「最大能容纳48通道的音轨,采样率达96 KHz,并且在320Kbps的数据速率下能为5.1声道音乐节目提供相当于ITU-R广播的品质」.和MP3比起来,它的音质比较好,也能够节省大约30%的储存空间与带宽.它是遵循MPEG-2的规格所开发的技术.松下的mp3产品都采用了这种编码方式,当然也兼容mp3格式,我自己使用时发现aac是非常好用的音频格式,128kbps的aac足以和224kbps的mp3抗衡,空间却小了差不多一半,但是在空间上和结构上aac和mp3编码出来后的风格不太一样.

德令哈市13219618109: 哪种音乐格式的音乐更好听?eaac+ aac aac+ mp3 还是wma? -
单于吴尼群: ...手机...(eAAC+)是在2004年时,纳入3GPP的第6版标准中.根据3GPP,它是由MPEG-4 AAC、MPEG-4 SBR和MPEG-4“参数立体声”(Parametric Stereo)技术组合的.“参数立体声”技术能够在低传输率中,进行“立体声”的编码,其...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网