最近做音频传输用到A律μ律编解码,记录一下遇到的问题。采用ALSA做音频输入输出,将音频数据编码后便于传输。
原始数据:8000hz 双声道 S16_LE(16位) 256kbps
编码数据:8000hz 单声道 8位 64kbps
主要任务是将16位(小端存储)数据编码为8位,然后再解码回去。这里编解码用的是网上找的函数,遇到的问题是编解码之后的音频播放效果惨不忍睹,最后找到问题是在“小端存储”上。
小端存储是将高字节数据放在高位地址上。例如:10 00转换为十进制是16。地址从左往右递增,10所在是低位地址,00所在是高位地址。
大端存储是将高字节数据放在低位地址上。例如:10 00转换为十进制是4096。
原始数据:8000hz 双声道 S16_LE(16位) 256kbps
编码数据:8000hz 单声道 8位 64kbps
主要任务是将16位(小端存储)数据编码为8位,然后再解码回去。这里编解码用的是网上找的函数,遇到的问题是编解码之后的音频播放效果惨不忍睹,最后找到问题是在“小端存储”上。
小端存储是将高字节数据放在高位地址上。例如:10 00转换为十进制是16。地址从左往右递增,10所在是低位地址,00所在是高位地址。
大端存储是将高字节数据放在低位地址上。例如:10 00转换为十进制是4096。
我在将小端存储的16位数据提取出来的时候,直接把它原封不动的赋给了一个short变量,结果导致高低位混乱,最终结果就是音频混乱。下面是具体程序:
1.A律μ律编解码
static unsigned char ALawCompressTable[] =
{
1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
};
static short ALawDecompressTable[] =
{
0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80,
0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,
0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0,
0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,
0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600,
0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,
0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00,
0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00,
0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8,
0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58,
0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8,
0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58,
0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xF