1. 什么是PCM?
PCM(Pulse Code Modulation,脉冲编码调制)音频数据是未经压缩的音频采样数据裸流,它是由模拟信号经过采样、量化、编码转换成的标准数字音频数据。
描述PCM数据的6个参数:
- Sample Rate : 采样频率。8kHz(电话)、44.1kHz(CD)、48kHz(DVD)。
- Sample Size : 量化位数。通常该值为16-bit。
- Number of Channels : 通道个数。常见的音频有立体声(stereo)和单声道(mono)两种类型,立体声包含左声道和右声道。另外还有环绕立体声等其它不太常用的类型。
- Sign : 表示样本数据是否是有符号位,比如用一字节表示的样本数据,有符号的话表示范围为-128 ~ 127,无符号是0 ~ 255。
- Byte Ordering : 字节序。字节序是little-endian还是big-endian。通常均为little-endian。字节序说明见第4节。
- Integer Or Floating Point : 整形或浮点型。大多数格式的PCM样本数据使用整形表示,而在一些对精度要求高的应用方面,使用浮点类型表示PCM样本数据。
pcm是音频的编码格式,不是文件的封装格式;aac既是编码格式也是封装格式,一般aac封装格式的内部音频数据编码格式也为aac。
pcm文件所占容量的公式:
存储量 = (采样频率 * 采样位数 * 声道) * 时间 / 8 (单位: 字节数)
故可以根据文件大小来计算时间。
2. FFmpeg数据结构
- AVCodecContext 编码器上下文
- AVCodec 编码器
- AVCodecID 编码器ID
- AVFrame 编码前、解码后保存的数据
- AVPacket 编码后、解码前保存的数据
3. 音频数据编码所必需的参数:
- sample_rate codecContext->sample_rate = frame->sample_rate;
- 采样率,即我们一秒钟采集多少次声音样本
- channels codecContext->channels = frame->channels;
- 通道数目,单通道双通道
- format codecContext->format = frame->format;
- 样本的格式,一个音频样本一般用两个字节来描述,分为大小两端。
- 例如:AV_
- channel_layout codecContext->channel_layout = AV_CH_LAYOUT_STEREO
- 用来设置输出的通道布局
如果有两个通道(即channels = 2 时)pcm中的frame->data[0],frame->data[1]用于指向不同声道的数据。
4. fread
size_t fread( void * ptr, size_t size, size_t count, FILE * stream)
- ptr, 指向一个内存块的指针,最小为size * count (Byte)
- size, 被读取的每个元素的大小 (Byte)
- count,被读取的元素的个数
- stream, 指向输入文件流的指针
5. 例子
比如在我们的程序正常采集的过程中,每次采集应该是采集1024个采样点,然后再发送给channel,pcm每个采样点的大小为16位(2Byte),故对pcm的文件采集应该是每次采集2048Byte,即fread的对象大小为2048Byte,对象个数count应该用文件大小来除以2048Byte(2KB)来计算,(fread的count为单次读取的数目,所以这里的count应该是1,每次只读取1024个采样点,2048个字节),在我们的程序中中采样频率为32000hz,意味着每秒钟采集32000个pcm的sample,故每次从文件中读取的时间间隔应该是1024/32000s.
uint8_t* pcm_buf = (uint8_t*)malloc(2048); //pcm的buffer大小
long fileLen = filelength(fileno(mikeFile)); //pcm文件的大小
while(1){
pcm_len = fread(pcm_buf, 2048, 1, mikeFile);
if (pcm_len <= 0) {//文件读取完毕,若读取文件pcm_len是1(count)
I_LOG("read file over");
break;
}
}//再将pcm_buf传给编码器encoder,用于init AVFrame,再通过编码到packet,获取packet便可以实现播放等操作。
版权声明:本文为Daibvly原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。