libfdk_aac音频采样数和编码字节数注意

简介: libfdk_aac音频采样数和编码字节数注意

正常人听觉的频率范围大约在20Hz~20kHz之间,根据奈奎斯特采样理论(2倍),为了保证声音不失真,采样频率应该在40kHz左右。(采样频率必须大于等于音频信号的最大频率的两倍,记住,是最大频率。)目前语音识别服务只支持16000Hz和8000Hz两种采样率,其中8000Hz一般是电话业务使用,其余都使用16000Hz。 22050的采样频率是常用的,44100已是CD音质。

44100 Hz - 音频 CD, 也常用于 MPEG-1 音频(VCD,SVCD,MP3)所用采样率48000 Hz - miniDV、数字电视、DVD、DAT、电影和专业音频所用的数字声音所用采样率8000 Hz - 电话所用采样率, 对于人的说话已经足够22050 Hz - 无线电广播所用采样率


出于历史原因,所有CD一律采用44.1KHz,而DVD/BD视频音轨一律采用48KHz。所以不出意外,你听到的那些音乐都是44.1KHz,而你看的视频,它们的音频一般都采用48KHz的采样率。

aac为有损压缩,同时48000->44100的转换对音质也有损伤。

由于人耳听觉范围是20Hz~20kHz,根据香农采样定理(也叫奈奎斯特采样定理),理论上来说采样率大于40kHz的音频格式都可以称之为无损格式。

我们的耳朵听到的频率间隔为20-20KHZ,我们的发声频率为100-3KHZ左右,所以可以看出如果只是单纯的采集发声频率可以使用8KHZ就可以,采样率必须是输入信号最高频率的2倍以上,这样才会最大可能的保存信号信息.故我们的听到的样本的采样率一般都为44.1KHZ及以上.

fdk_aac 支持的音频采样率:7350 8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000

fdk_aac 样本类型:只支持16bit pcm输入.

CBR模式:

设置目标码率,当样本之间差异较小时,可以通过该方法更好地控制文件大小,设置每个通道为64kbps.立体声为128kbps

VBR模式:

指定目标质量,而不是码率,质量从1到5由低到高.使用参数-vbr,vbr模式下大致给出了每个通道对应的码率,参考libfdk_aac介绍

首先需要了解的是AAC文件格式有ADIF和ADTS两种,其中ADIF(Audio Data Interchange Format 音频数据交换格式)的特征是解码必须在明确定义的开始处进行,不能从数据流中间开始;而ADTS(Audio Data Transport Stream 音频数据传输流)则相反,这种格式的特征是有同步字,解码可以在这个流中任何位置开始,正如它的名字一样,这是一种和TS流类似的格式。


ADTS头包含了AAC文件的采样率、通道数、帧数据长度等信息,分为固定头信息和可变头信息两部分。ADTS格式中每一帧都有头信息,具备流特征,适合于网络传输与处理,而ADIF只有一个统一的头,并且这两种格式的header格式也是不同的。目前主流使用的都是ADTS格式。ADIF只有一个统一的头,所以必须得到所有的数据后才能进行解码,一般用于磁盘文件中,实时流协议中不使用。

ADTS头和音频信息是交替存储的:



正确的说法是不同profile决定了每个aac帧含有多少个sample,即帧数据长度,具体来说,对应关系如下:

av_opt_set(encodec_ctx_a->priv_data, "profile", "lc", 0);


AACENC_GRANULE_LENGTH =

0x0105, /*!< Core encoder (AAC) audio frame length in samples:


  • 2048 HE-AAC v1/v2
  • 1024: Default configuration.//AAC-LC 1024
  • 512: Default length in LD/ELD configuration.
  • 480: Length in LD/ELD configuration.
  • 256: Length for ELD reduced delay mode (x2).
  • 240: Length for ELD reduced delay mode (x2).
  • 128: Length for ELD reduced delay mode (x4).
  • 120: Length for ELD reduced delay mode (x4). */
  • 其中LC即Low Complexity,HE即High Efficiency,注意,其中数据表示单通道的采样数,如1024,表示单通道每秒采样1024帧。每次送入编码器的数据必须是上述设定或默认的数据,如果不是的话会在缓冲区中暂存,然后够了之后再送进去。如果是mp3编码的话,每帧需要的字节长度是1152
  • 部分libfdk_aac源码如下:
aacEncInfo(aacEncHandle, &info);
int input_size       = channel * 2 * info.frameLength;


其中假如设置一包压缩的aac音频采样数为1024(术语叫帧数据长度),那么如果送进去的采样数不够1024的话,不会有输出,等到够1024时才输出一包,就是图中的AAC ES包。


声道数:

0: Defined in AOT Specifc Config

1: 1 channel: front-center

2: 2 channels: front-left, front-right

3: 3 channels: front-center, front-left, front-right

4: 4 channels: front-center, front-left, front-right, back-center

5: 5 channels: front-center, front-left, front-right, back-left, back-right

6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel

7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel

8-15: Reserved


实测记录如下:

设备 send进的采样数 声音

pulse 128 听不到

dsnoop 1024 正常

sysdefault 940 能听到,有噪音,无缓存

null 32768 超过1024,报错


实测当送进去128,1024,940时到avcodec_send_frame时,avcodec_receive_packet一对一返回,开始并没有几帧缓存,av_interleaved_write_frame也一对一执行,一没有返回。也就是三者总是保持一对一执行,后两者都有返回,并且一开始没有缓存。

当send进去的frame_a带有32768个采样数时,报错:


more samples than frame size (avcodec_encode_audio2)


因为fdk_aac默认编码是1024个字节,所以多出的字节会报错。

且当送进去128时,用代码去解码,实测frame_a->nb_samples = 1024 frame_a->linesize[0] = 8192(注意fdk_aac编码只接受16位,输出是fltp,frame_a->linesize[1] = 0),fdk_aac默认是1024个字节一次输出,因此说明,当送进去的不够1024个采样时,编码器并不会缓冲,等待填充,而是填充无效数据使其够1024个字节,然后输出,这也是播放时无法正常播放的原因。


相关文章
|
5月前
|
Java Linux
ffmpeg音频格式转换、合成、速率调整
ffmpeg音频格式转换、合成、速率调整
114 2
|
缓存 Python
如何把非1024的采样数放入aac编码器
当我们得到的采样数是不规则的,比如decklink的采集卡每次的到的采样数帧率有关,为48000/fps。那么25fps,就是1920,60fps,是800。 那么我们就需要一个缓存,来每次读取1024个采样。 这里使用ffmpeg的重采样的缓存机制
185 0
如何把非1024的采样数放入aac编码器
|
存储 编解码 Java
【Android FFMPEG 开发】FFMPEG 音频重采样 ( 初始化音频重采样上下文 SwrContext | 计算音频延迟 | 计算输出样本个数 | 音频重采样 swr_convert )(一)
【Android FFMPEG 开发】FFMPEG 音频重采样 ( 初始化音频重采样上下文 SwrContext | 计算音频延迟 | 计算输出样本个数 | 音频重采样 swr_convert )(一)
744 0
|
安全 Java 语音技术
将mp3格式的音频转换为采样率8k的wav
将mp3格式的音频转换为采样率8k的wav
516 0
|
内存技术
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(二)
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(二)
193 0
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(二)
|
内存技术
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(一)
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(一)
417 0
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(一)
|
内存技术
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(三)
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(三)
226 0
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )(三)
|
编解码 Android开发 数据格式
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(二)
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(二)
399 0
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(二)
|
数据采集 传感器 编解码
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(一)
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(一)
237 0
|
编解码 Android开发
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(三)
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(三)
270 0