最近做音频传输用到A律μ律编解码,记录一下遇到的问题。采用ALSA做音频输入输出,将音频数据编码后便于传输。
原始数据: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, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60,0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960,0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0,0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0,0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280,0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80,0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940,0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40,0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00,0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00,0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500,0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500,0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128,0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8,0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028,0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8,0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0,0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0,0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250,0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350,
};static unsigned char MuLawCompressTable[] =
{0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,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,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,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 MuLawDecompressTable[] =
{0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84,0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84,0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84,0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84,0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804,0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004,0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444,0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844,0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64,0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64,0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74,0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74,0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC,0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C,0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0,0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000,0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C,0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C,0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C,0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C,0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC,0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC,0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC,0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC,0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C,0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C,0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C,0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C,0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084,0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
};/* Alaw
* Linear Input Code Compressed Code
* ------------------------ ---------------
* 0000000wxyza   000wxyz
* 0000001wxyza   001wxyz
* 000001wxyzab   010wxyz
* 00001wxyzabc   011wxyz
* 0001wxyzabcd   100wxyz
* 001wxyzabcde   101wxyz
* 01wxyzabcdef   110wxyz
* 1wxyzabcdefg   111wxyz
*/unsigned char LinearToAlawSample(short sample)
{int sign   = 0;int exponent = 0;int mantissa = 0;unsigned char compressedByte = 0;sign = ((~sample) >> 8) & 0x80;if (sign == 0){sample = (short)-sample;}if (sample > 0x7F7B){sample = 0x7F7B;}if (sample >= 0x100){exponent = (int)ALawCompressTable[(sample >> 8) & 0x7F];mantissa = (sample >> (exponent + 3)) & 0x0F;compressedByte = (unsigned char)((exponent << 4) | mantissa);}else{compressedByte = (unsigned char)(sample >> 4);}compressedByte ^= (unsigned char)(sign ^ 0x55);return compressedByte;
}short AlawToLinearSample(unsigned char sample)
{return ALawDecompressTable[sample];
}/* ulaw
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza   000wxyz
* 0000001wxyzab   001wxyz
* 000001wxyzabc   010wxyz
* 00001wxyzabcd   011wxyz
* 0001wxyzabcde   100wxyz
* 001wxyzabcdef   101wxyz
* 01wxyzabcdefg   110wxyz
* 1wxyzabcdefgh   111wxyz
*/unsigned char LinearToMuLawSample(short sample)
{int cBias = 0x84;int cClip = 0x7F7B;int sign = (sample >> 8) & 0x80;if (sign != 0){sample = (short)-sample;}if (sample > cClip){sample = (short)cClip;}sample = (short)(sample + cBias);int exponent = (int)MuLawCompressTable[(sample >> 7) & 0xFF];int mantissa = (sample >> (exponent + 3)) & 0x0F;int compressedByte = ~(sign | (exponent << 4) | mantissa);return (unsigned char)compressedByte;
}short MuLawToLinearSample(unsigned char sample)
{return MuLawDecompressTable[sample];
}

2.编解码映射表初始化

//alaw_table[256][3]映射表
//第一列:原始数据 -32767 ~ 32767
//第二列:编码数据 0 ~ 255
//第三列:解码数据 -32767 ~ 32767中的256个
short alaw_table[256][3]; //alaw_table_init生成A律坐标映射表
void alaw_table_init()
{short i, count, sample16;unsigned char sample8;count = 0;for(i=-32767; i<32767; i++){sample8 = LinearToAlawSample(i);           //编码数据sample16 = AlawToLinearSample(sample8);    //解码数据if(i==-32767){alaw_table[0][0] = i;alaw_table[0][1] = sample8;alaw_table[0][2] = sample16;}else{if(sample8 != alaw_table[count][1]){count++;alaw_table[count][0] = i;alaw_table[count][1] = sample8;alaw_table[count][2] = sample16;}}}
}

3.用查表法实现编解码

//linear->alaw
unsigned char l2a(short val)
{int max=255;int i;for(i=0; i<max; i++){if(val<alaw_table[0][0])return alaw_table[0][1];if(val>alaw_table[i][0] && val<=alaw_table[i+1][0])return alaw_table[i+1][1];if(val>alaw_table[255][0])return alaw_table[255][1];}
}
//alaw->linear
short a2l(unsigned char val)
{short i;for(i=0; i<256; i++)if(val == alaw_table[i][1])return alaw_table[i][2];return 0;
}

原始音频数据存储在*sendbuffer,16位小端存储,双声道交叉存储。提取出单声道数据进行转换,然后存入编码数据指针*sendbuffer_alaw用于传输。

short sample;
unsigned char result;for(i=0; i<frames; i++)
{sample = *(sendbuffer+i*4+1);     //注意原始数据是小端存储sample <<= 8;sample +=  *(sendbuffer+i*4)  ;result = l2a(sample);*(sendbuffer_alaw+i) = result;
}

接收到的编码数据存于*recvbuffer_alaw,解码获得16位双声道数据存放于*recvbuffer。

short sample;
unsigned char result;for(i=0; i<frames; i++){result = *(recvbuffer_alaw+i);   sample = a2l(result);*(recvbuffer+i*4) = sample;*(recvbuffer+i*4+1) = sample >> 8;*(recvbuffer+i*4+2) = sample;*(recvbuffer+i*4+3) = sample >> 8;}

PCM A律μ律编码相关推荐

  1. java pcm转adpcm_音频编码:ADPCM

    未经本人同意 请务转载 David QQ:435398366 0.前言 最近智能音响.AI蓝牙耳机.语音助手.翻译机器很火呀,为了跟上时代的步伐,我最近也开始语音相关的开发工作. 1.PCM PCM( ...

  2. pcm 采样率转换_PCM编码与Waveform音频文件(.wav)格式详解

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是PCM编码及Waveform音频文件格式. 嵌入式里有时候也会和音频打交道,比如最近特别火的智能音箱产品,离不开前端的音频信号采集.降噪 ...

  3. alsa录制pcm音频及fdk-aac编码

    1. 利用alsa库录制PCM音频,并保存为音频文件. (该部分代码摘自网络,原链接不记得了,侵删.但是代码亲测可用,在此做个demo备用) /*** @file record_pcm.c* @bri ...

  4. java pcm转adpcm_音频编码(PCM,ADPCM,WAVE文件)

    二.给个英文参考网址吧 这两个讲的很详细,请仔细阅读!通过阅读我发现细节在与adpcm格式的wav文件的block的特点,每一个block包含header和data两部分, Typedef struc ...

  5. A律十三折线法G711编解码介绍

    A律十三折线法G711编解码介绍 简介 G711国际电信联盟ITU-T定制出来的一套语音压缩标准,主要用于对PCM音频数据编码,将PCM16bit数据压缩为为8Bit,它是主流的波形音频编码器,相当于 ...

  6. 通信原理day7:第三章:抽样;均匀量化;非均匀量化;A律;增量(ΔM)调制

    模拟信号的数字化 1.抽样定理 1.1低通信号的抽样定理 1.2带通信号的抽样定理 2.量化 2.1 均匀量化 2.1.1.抽样频率,传输速率 2.1.2.量化位数,量化电平,量化间隔 2.1.3.量 ...

  7. pcma和pcmu pcm编码_语音编码分类及编解码标准

    G.711类型:Audio 制定者:ITU-T 所需频宽:64Kbps 特性:算法复杂度小,音质一般 优点:算法复杂度低,压缩比小(CD音质>400kbps),编解码延时最短(相对其它技术) 缺 ...

  8. FFmpeg音频编码 ---- pcm转aac(使用新版ffmpeg API,亲测可用)

    /** * @projectName 08-01-encode_audio * @brief 音频编码 * 从本地读取PCM数据进行AAC编码 * 1. 输入PCM格式问题,通过AVCodec的sam ...

  9. ffmpeg实战教程(三)音频PCM采样为AAC,视频YUV编码为H264/HEVC

    ffmpeg实战教程(三)音频PCM采样为AAC,视频YUV编码为H264/HEVC https://blog.csdn.net/King1425/article/details/71180330 音 ...

最新文章

  1. 2012年A股可能再跌20%~30%
  2. python的__init__几种方法总结【转载】
  3. JSON之三:获取JSON文本并解释(以google的天气API为例)
  4. 广东农信迁移上阿里云:系统建设从按月缩短至按天
  5. Mvvm、第一个Vue程序、Vue基本语法
  6. 面试题_分层遍历二叉树
  7. postgreSQL分页
  8. c语言学生管理系统write to a text file,语言编程学生成绩管理系统.doc
  9. Python教程:丛入门到实践
  10. Perl读取文件的两种常用方式
  11. c php curl post,php curl post
  12. win10资源管理器如何添加PDF文件预览
  13. 文献阅读-CSC-中文错别字-有关论文搜集-+CGED
  14. GitHub新手使用教学(从安装到使用)
  15. 计算机教室消防说明,6.7 消防专用电话的设置
  16. C语言计算个人所得税
  17. 水电图纸——管道的预埋和盒子的放置-1
  18. jquery mobile_使用jQuery Mobile改善Web应用程序的安全性
  19. Faiss相似性搜索类库
  20. c语言while语句1阶层加到10阶层,用C++编程:1的阶层加到10的阶层,使用For语句,还有While和Do While语句编程!!...

热门文章

  1. 如何构建固定网(PSTN)短消息系统(转)
  2. 【技术评网】说说豆瓣的URL设计
  3. MicroDicom viewer相关
  4. UDID与OpenUDID的区别联系
  5. 一键下载网页所有图片(含dataurl格式图片)
  6. 深度学习入门的建议_来自《简单粗暴Tensorflow2》
  7. android 年终盘点总结报告,2013 Android年终总结 - 盘点五年来的各种定制界面
  8. 泡泡堂段王一进去服务器不稳定,为什么泡泡堂游戏进入不了,只是点了选择了三区,然后就什么也没有了,过半天出来一个服务器连接中断...
  9. 15 OpenCV4图像处理与视频分析实战(50.背景分析-)
  10. 易优cms伪静态,EyouCms去除URL中的index.php