音视频--------pcm数据入门知识

本文为记录自己学习雷霄骅的pcm入门的demo后,从中学到的pcm知识。

 

先介绍必要的入门知识:

 pcm 16LE 

     1. pcm 16------代表2 Byte采样值,

     2. 存储方式(LE:LITTLE-ENDIAN)--------即低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 与之对应的               是:BIG-ENDIAN(大字节序、高字节序) 详细讲解

               从左到右:高位字节 -----------------> 低位字节 

               从左到右:低地址 -----------------> 高地址 

          eg: int a =  0x12345678

                在BIG-ENDIAN的情况下存放为:数据  0x12  |  0x34  |  0x56  |  0x78(正常)

                在LITTLE-ENDIAN的情况下存放为:数据 0x78  |  0x56  |  0x34  |  0x12(倒序)

     3. 采样数据的取值范围是-32768到32767(即 2的16次幂,2Byte)

pcm 8

    1. 采样值1Byte;

    2.采样数据的取值范围是0到255(即 2的8次幂,1Byte)

 

数据处理:

对pcm数据的处理从业务层考虑有下面几种情况:

       a. 如果是多声道,可能需要分离声道

       b. 改变音量的大小

       c. 改变播放速度的快慢

       d. pcm格式的转换

在处理pcm数据之前,我们需要明白pcm 的格式,才能知道其采样大小和存储结构。如下将以pcm16le格式为例子,data[12]为pcm数据存储数据 。单位为 1Byte的二进制数据 。叙述如何实现上面的情况:

情况a:

       由于pcm16le 是双声道,存储的数据结构为 一个2Byte左声道数据然后一个2Byte右声道数据这样顺序存储。所以分离就简单了。   eg,data[12]   ------取data[0]data[1](左声道)、 data[2]data[3](右声道)、data[4]data[5] (左声道)、data[6]data[7](右声道)、data[8]data[9](左声道)、data[10]data[11](右声道)

情况b:

        将每次的采样数据变大或变小,就是改变其音量。eg,将 data[0]data[1]和data[4]data[5]和data[8]data[9](左声道) 二进制数据转换为short类型数据 然后除以2,表示左声道音量减半。

情况c:

      间隔读取数据,就可以改变播放速度。 eg,读取 data[0]data[1](左声道)、 data[2]data[3](右声道)但不读取data[4]data[5] (左声道)、data[6]data[7] 然后再读取data[8]data[9](左声道)、data[10]data[11](右声道)播放速度就变快了

情况 d:

      假如我们需要将pcm16le转为pcm8 格式。我们需要将音频采集数值范围从2Byte 降为1Byte。

      需要经过两个步骤:
      第一步是将-32768到32767的16bit(2Byte)有符号数值转换为-128到127的8bit(1Byte)有符号数值,可以通过位运算              (>>8)    eg, -32768>>8 =-128
      第二步是将-128到127的8bit有符号数值转换为0到255的8bit无符号数值。(所有数据+128)

      方法二: 我们知道pcm16le的存储格式是LITTLE-ENDIAN,我们可以直接取高位的1Byte,这样也可以和第一步的效果一            样。

int simplest_pcm16le_to_pcm8_method2(char *url){

	FILE *fp = fopen(url, "rb+");
	FILE *fp1 = fopen("output_82.pcm", "wb+");

	int cnt = 0;
	unsigned char *sample = (unsigned char *)malloc(2);

	short samplenum8;
	unsigned char samplenum8_u;
	while (!feof(fp)){
		//sample-----缓存区
		//2 ----代表一次读取2个字节
		//1 ----读取长度为1
		//fp -----数据源
		fread(sample, 2, 1, fp);
          //取值范围 -128-----127
		samplenum8 = sample[1];
		//PCM8格式的采样数据的取值范围是0到255
		samplenum8_u = samplenum8+128;
		//写入声道
		fwrite(&samplenum8_u, 1, 1, fp1);
		cnt++;
	}
	printf("Sample Cnt:%d\n", cnt);

	free(sample);
	fclose(fp);
	fclose(fp1);

	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值