总的来说就是,计算机中全是二进制数据的 0 1,表示成16进制也就是字节的存储0xFF,这些二进制对于计算机是没有任何意义的,之所以变成了有符号和无符号的各种类型(int char unsigned int) ,只是针对我们人来说的,人存进去整形数据,我们取的时候就得按照4个字节这样取数据( 还需要处理最高地址字节的高位符号位 )
所以如何才能取出正确的数据,就得按照之前存储数据的人的想法取数据(一个数值用几个字节表示,有没有符号),否则数据有问题
例如计算机中是 0xC8,二进制是 1100 1000 ,如果按照char获得数据就是 -56,如果是unsigned char 就是200,为什么会这样呢,因为char能表示的最大数是-128~127,因为负数在计算机中的表示是 负数的补码,
负数的补码表示方法是:将负数表示成二进制原码(负数最高位是1,正数最高位是0)然后将原码取反(1变0,0变1),即反码,将反码加 1(最后一位上加1),即转化为补码。
最近开始弄音频数据,才发现以前学的东西全还给老师了,音频文件是 short 16位存储一个取样 样本,用来表示音量大小,但是应该如何从数据正确的取数据呢
按照音频数据是short 有符号 来讲解实例
unsigned char* inBuf = new unsigned char[2];
unsigned char* outBuf = new unsigned char[2];
此时数据是signed short 为什么按照unsigned char 的buffer来存储从文件中读到的数据呢,这个和 signed char是没有区别的,只是一个字节存储了计算机中的数值,如果是signed char 存储数据,我们取低字节数值的时候就得转成 unsigned char处理,因为(低字节是没有符号的,只有高字节的最高位才是符号位,如果是unsigned char数据存储,取高字节数值的时候,需要转换成signed char数值 才能得到正确的值)
姑且按照unsigned char* 处理,
float frame = 0.0;
char*p = NULL;
int ii = 0;
if ( (ii= ibuf[i+1] & 0x80) == 0x80) { //负数
p = (char*)&(ibuf[i+1]);
frame = (ibuf[i]+(*p)*256)/32768.0;
}
else{
frame = (ibuf[i]+ibuf[i+1]*256)/32768.0;
}
存储的时候直接按照
obuf[i+1] = (short)(frame*32768.0)>>8;
obuf[i] = (short)(frame*32768.0)%256;
short来说,16位,最高位是 符号位,也就是说 高位字节 1-7位是值,低位字节 0-8全是数值
2、双声道的数据,存储数据是 左右声道数据交替存储 LR LR LR LR ,对于16位取样大小来说,就是
short 表示范围是 (-2的15次方 ~~~~ 2的15次方-1) 也就是 32768
3、一般是小端存储,也试试 高位在高字节,低位在低字节