DSP课程设计语音压缩存储回放

更新时间:2024-03-24 14:09:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

DSP课程设计

实验报告

语音压缩、存储与回放

小组成员: 自动化0801 宋晓美 08212012

自动化0801 王 丹 08212014

指导教师: 高海林

2011年1月

概述

? 数字信号处理(DSP)课程设计是信息与通信、自动化和电子科学技术专业

本科生进行综合能力培养的实践课程,是培养学生DSP系统的软硬件工程设计能力的重要实践教学环节,对于全面、系统、深入地理解与掌握信号处理知识与设计方法具有重要的教学意义。作为通信专业的毕业生,理应牢固掌握数字信号处理的相关知识,了解集成开发环境的使用和调试方法,内化信号处理的基本理论知识。 ? 本次实验采用DSP C5402实验板实现语音信号的压缩与解压的。

? 语音信号是信息的重要形式, 语音信号处理有着广泛的应用领域,而语音压

缩在语音信号的传输、存储等方面有非常广泛的作用,而且在通信领域中以及有较成熟的发展并且已经广泛应用。 ? 实验主要分为语音信号接收、压缩、解压和输出几部分。

? 信号的接收和输出采用DMA方式,DMA是C5400 DSP系统中非常重要的

片上外设,其控制器可以在不影响CPU的情况下完成数据的传输,因此数据传输速度快,其数据的源和目的可以是片内存储器片上外设和片外设备。C5402的DMA拥有6个独立的可编程通道,允许6个不同的DMA操作。另外DMA控制器还相应HPI的服务请求。SEED-VC5402 DSK实验板上集成了SRAM,FLASH,音频输入输出接口等部件。这些外设为我们提供了极大的方便。 ? 语音信号模数、数模转换采用AD50,这是一款SIGMA-DELTA型单片音频

接口芯片(AIC)。它内部集成了16位的D/A和A/D转换器,采样速率最高可达22.05kb/s,其采样速率可通过DSP编程来设置。在DAC之前有一个插值滤波器以保证输出信号平滑和ADC之后有一个抽取滤波器以提高输入信号的信噪比。

一、 设计任务书

1、设计要求及目标

(1)使用DSP实现语音压缩和解压缩的基本算法,算法类型自定,例如可以采用G.711、G.729等语音压缩算法。

(2)采用A/D转换器从MIC输入口实时采集语音信号,进行压缩后存储到DSP的片内和片外RAM存储器中,存储时间不小于10秒。

(3)存储器存满之后,使用DSP进行实时解压缩,并从SPEAKER输出口进行回放输出。

(4) 使用指示灯对语音存储和回放过程进行指示。

2、设计思路

语音信号的幅度(发音强度)并非均匀分布,由于小信号占的比例比大信号大很多,因此可以进行非均匀量化。达到这一目标的基本做法是,对大信号使用大的量化间隔,而小信号则使用小的台阶。ITU-T G.711建议的PCM A律和μ律语音压缩标准可以分别将13比特和14比特压缩为8比特,达到语音压缩的目的。

3、 设计任务

(1)编写C语言程序,并在CCS集成开发环境下调试通过。 (2)实现设计所要求的各项功能。 (3)按要求撰写设计报告。

二、实验原理

1.语音编码

(1)概念:语音编码一般分为两类:一类是波形编码,一类是被称为“声码器技术”的编码。PCM编码即脉冲编码调制。波形编码的最简单形式就是脉冲编码调制(Pulse code modulation),这种方式将语音变换成与其幅度成正比的二进制序列,而二进制数值往往采用脉冲表示,并用脉冲对采样幅 度进行编码,所以叫做脉冲编码调制。 脉冲编码调制没有考虑语音的性质,所以信号没有得到压缩。 (2)量化:脉冲编码调制用同等的量化级数进行量化,即采用均匀量化,而均匀量化是基本的量化方式。但是均匀量化有缺点,在信号动态范围较大而方差较小的时候,其信噪比会下降 。

国际上有两种非均匀量化的方法:A律和μ律,μ律是最常用的一种。在美国,7位μ律是长途电话质量的标准。 而我国采用的是A律压缩,而且有标准的A律PCM编码芯片。

2.压缩、解压原理

由于语音信号是模拟信号,要对语音信号进行压缩、存储就必须对语音信号进行模/数转换,把转换后的语音数字信号输入DSP系统,由DSP系统对语音数字信号进行处理。把处理后的数字信号进行数/模转换,转变成原来的模拟语音信号,然后通过耳机或其他音频输出设备把语音进行回放。语音的采集和回放的基本结构图如图3所示。 数字逻 模拟 A/D转 D/A转 模拟信 辑电路 信号源 换电路 换电路 号输出 DSP

图3 语音的采集和回放的基本结构图

数据压缩技术是信息系统的重要技术。为了实现对模拟信号的高效处理,往往在模/数转换的过程中就须要压缩主要程序。目前通信系统中最常用的就是A律和u律两种压缩编码技术。

u律/A律压缩解压编码是CCITT国际电报电话协会最早推出的G.711语音压缩解压编码的一种格式的主要内容。其中欧洲和中国等国家采用A律压缩解压编码,美国和日本等国家采用u律压缩解压编码。A律算法:本实验所用的A律压缩解压编码,通过DSP将传输来的压缩后的数据进行行解压成16位,然后对解压后的数据进行分析、处理。然后将处理后的数据按照要求压缩成8位的数据格式输出到相应设备,供其它设备读取。

A律算法公式:

下图是DSP将数据解压的值,DSP将压缩的8位数据解压成16位的DSP通用数据格式。其中高13位为解压后的数据,低3位补0。这是因为G.711的A律压缩只能对13位的数据操作。DSP将解压后的数据放在缓冲串口的发送寄存器中。只要运行发送指令缓冲串口就会将数据发送出去。

图4 数据压缩解压流程图

DSP的内部缓冲串口带有硬件实现的u律和A律压缩解压,用户只需在相应寄存器中设置就可以了。TMS320C5402硬件支持μ律和A律压缩算法无需重新设置,直接编程调用查找表即可,在进行A律压缩时,对于采样到的12(应改为13)位数据,默认其最高位为符号位,压缩时要保证最高位即符号位不变,原数据后11(应改为12)位要压缩成7位。这7位码由3位段落码和4位段内码组成。

压缩后数据的最高位(第7位)表示符号,量价分别为1、1、2、4、8、16、32、64,由压缩后数据的第6位到第4位决定,第三位到第0位是段内码。压缩后的数据有一定的失真,数据压缩前后的对照表如表1所示。 12位码(十进制) 量价 0~15 16~31 32~63

符号位 0 0 0 段落码(二进制) 段内码(二进制) 000 001 010 0000~1111 0000~1111 0000~1111 1 1 2

64~127 128~255 256~511 512~1023 1024~2047 4 8 16 32 64 0 0 0 0 0 011 100 101 110 111 0000~1111 0000~1111 0000~1111 0000~1111 0000~1111 表1 A律数据压缩表

μ律算法:采用μ律算法对采集的语音数据进行处理,μ律编码是一种

针对语音信号进行对数压缩非均匀量化的方案。采用μ律对信号进行对数形式的压缩,以便在不提高数据量的前提下提高信噪比,尽管量化的位数保持不变,但动态范围增加了。μ律压缩的语音信号一般用8比特抽样数据表示,携带小信号信息量比大信号信息量多。从统计意义上讲,有用信号更可能在小信号区间而非大信号区间。因此,在小信号区间需要更多的量化点数。 μ律算法公式:

其中Xmax是信号x(n)的最大幅度,u是控制压缩程序的参数,u越大压缩就越厉害 μ律查找表内共有256个数,分别用来获得0—7段量化电压,其由16×16组数组成。

由下表看大信号多数由第7段表示,三个指数位用来表示第0-7段,4个尾数位用于表示后4个有效位,还有一位符号位没有给出。16比特输入数据是由线性数据变换成8比特μ律数据(模拟传输),然后再从μ律转成16比特的线性数据(模拟接收),再输出到编解码器。 压缩前码字 丢弃压缩后的码字 的比量化后的值偏置的输入(模值,无符号位) (无符号位) 比特:14 13 12 11 10 9 8 7 6 5 4 3 2 1 特数 比特: 6 5 4 3 2 1 0 0 0 0 0 0 0 0 0 1 a b c d 1 ╳ 3 0 0 0 a b c d ╳ 0 0 0 0 0 0 1 a b c d 1 ╳ ╳ 4 0 0 1 a b c d ╳ 0 0 0 0 0 1 a b c d 1 ╳ ╳ 5 0 1 0 a b c d ╳ ╳ 0 0 0 0 1 a b c d 1 ╳ ╳ ╳ 6 0 1 1 a b c d ╳ ╳ 0 0 0 1 a b c d 1 ╳ ╳ ╳ 7 1 0 0 a b c d ╳ ╳ ╳ 0 0 1 a b c d 1 ╳ ╳ ╳ ╳ 8 1 0 1 a b c d ╳ ╳ ╳ 0 1 a b c d 1 ╳ ╳ ╳ ╳ 9 1 1 0 a b c d

╳ ╳ ╳ ╳ 1 a b c d 1 ╳ ╳ ╳ ╳ ╳ 10 1 1 1 a b c d ╳ ╳ ╳ ╳ 表2 线性到U律转换表(压缩表) 上表为压缩表:其中压缩后的数据为8位,符号位未写出。其解压表与之相反:由8位U律变换到线性16位。

上图给出了按?律压扩算法的输入输出特性曲线,?为确定压缩量的参数,它反映最大量化间隔和最小量化间隔之比。由图可见,?值越大,压缩量越大。由于? 律压扩的输入和输出关系是对数函数关系,所以这种编码又称为对数PCM。 A律压扩与?律压扩相比,则压缩的动态范围略小些,小信号振幅时质量要比?律稍差。无论是A律还是?律算法,它们的特性在输入信号振幅小时都呈线性,在输入信号振幅大时呈对数压缩特性。

对于采样频率为8kHz,样本精度为16位的输入信号,使用A律压扩或?律压扩编码,经过PCM编码器之后每个样本的精度为8位,输出的数据率为64kb/s。这个数据就是CCITT ,(国际电话与电报顾问委员会)推荐的G.711标准:话音频率脉冲编码调制。

3.存储和回放

通过定义适当大的缓冲区,将压缩后的8位或4位数据经过相应的整合,存储到16位的RAM中,这种操作目的主要是充分利用存储器中的资源,以保证能够录入足够多的语音数据。利用缓冲区的目的是进行音效的实时处理.系统中各模块是同时进行处理的,一部分信号正在ADC中进行转换,而另一部分信号则在DSP处理器中同时进行算法处理,即整个系统是以流水线的方式进行工作的。 通过解压缩,将8位或4位数据还原成相应的语音数据,在经过AD50C将数字信号还原成语音信号(即模拟信号)通过多通道缓冲串口输出,达到放音的目的。

三、软件设计

程序流程图:

开始 实验板初始化 CODEC与McBSP 初始化与工作方式设置 输入语音信号 语音压缩、存储 定时器延时 解压、回放 是否结束? Y 结束

N

1.DSK板的初始化:

首先将DSP的串口1复位,再对串口1的16个寄存器进行编程,使串口1工作在以下状态:禁止SPI模式,但数据相,每帧一字,每字16位,帧同步脉冲低电平有效,并且帧同步信号和移位信号有外部时钟产生。DSP给AD50编程用查询方式,A/D转换数据的接收和D/A转换的数据发送采用查询方式。

此语句调用了函数codec_open()对串口1进行了初步设置,设置成功返回codec的句柄放在变量hHandset中,作为调用其他函数的实参。

2.AD50(即CODEC)的初始化:

? hHandset = codec_open(HANDSET_CODEC);

? codec_dac_mode(hHandset, CODEC_DAC_15BIT); /* DAC15bit模式 */

? codec_adc_mode(hHandset, CODEC_ADC_15BIT); /* ADC15bit模式 */ ? codec_ain_gain(hHandset, CODEC_AIN_6dB); /* 输入6dB增益 */ ? codec_aout_gain(hHandset, CODEC_AOUT_MINUS_6dB); /*输出-6dB增益

*/

? codec_sample_rate(hHandset,SR_16000); /* 16KHz采样率 */

该初始化过程调用了5个函数对AD50的5项参数进行了设置,包括ADC和DAC的工作模式,模拟输入和输出的增益;以及AD/DA的转换速率。 1) 用TMS320VC5402实现语音的A率压缩解压有两种方法:

(1)使用多通道缓冲串口(McBSP)的缩展器

在多缓冲通道串口(McBSP)内部装置了硬件电路,支持A律格式缩展器,对数据进行压缩与扩展,A律缩展器允许14比特的动态范围。

(2)用软件实现

主程序的功能是从McBSP的接收通道读取A/D转换的值,然后经过压缩解压后将其发送到McBSP的发送通道,构成AD50 CODEC模拟输入和输出通道的自环,是否能接收到A/D转换的数据是通过查询串口1的接收标志RRDY来进行的。

四、程序设计:

主程序:

#include /* 头文件*/ #include #include #include

/* 宏定义 */

#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */

/* 函数声明 */

void delay(s16 period); void led(s16 cnt);

void initcodec(void); void flashenable(void);

unsigned char data2alaw(s16 pcm_val); int alaw2data(unsigned char a_val);

static int search(int val,short *table,int size);

/* 全局变量 */

HANDLE hHandset; s16 data; s16 data1; u16 i=0; u16 temp1; u16 j=0; u16 k,l=0; u8 temp2;

u16 buffer[20000];

static short seg_end[8]={0x1F,0x3F,0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF};

/* 主函数 */

void main() {

if (brd_init(100)) return;

led(2); //闪灯两次 initcodec(); //初始化codec

flashenable(); //选择片外FLASH为片外存储器

/*

delay(100);

brd_led_toggle(BRD_LED0); for(i=0x9000;i<0xefff;i++) {

REG_WRITE(i,*(volatile u16*)DRR1_ADDR(HANDSET_CODEC)); delay(20); }

brd_led_toggle(BRD_LED1); delay(200);

for(i=0x9000;i<0xefff;i++) {

*(volatile u16*)DXR1_ADDR(HANDSET_CODEC)=REG_READ(i); delay(20); }

brd_led_toggle(BRD_LED2);

*/

while (1) {

while (!MCBSP_RRDY(HANDSET_CODEC)) {}; //等待接收handset处的采样

brd_led_toggle(BRD_LED0);

data = *(volatile u16*)DRR1_ADDR(HANDSET_CODEC); //从handset处读取采样

temp1=data2alaw(data); //对采样进行a律压缩

/* 把低地址数据放在高八位 高地址数据放在低八位 */

i=i+1; if(i%2==1) { buffer[j]=(temp1<<=8); /*奇数数据左移8位 temp1=abcdefgh00000000 buffer[j]=temp1*/ } else { buffer[j]=(buffer[j]|temp1); /*偶数数据与temp1取或 组成新的数据 buffer[j]=abcdefghiabcdefghi*/ j++; //j加1 }

if(i>=40000) { i=0; }

if(j>=20000) { j=0; brd_led_disable(BRD_LED0); brd_led_toggle(BRD_LED1);

//点亮二极管1 表示放音开始

/* 放音部分 */

for(k=0;k<40000;k++) { if(k%2==0) { temp2=(buffer[l]>>8)&0x0ff; } else { temp2=buffer[l]&0x0ff; l++; } if(l>=20000) l=0; data1=alaw2data(temp2); // a律解压 while (!MCBSP_XRDY(HANDSET_CODEC)) {}; *(volatile u16*)DXR1_ADDR(HANDSET_CODEC) = data1; //将数据写入D/A转换器 }

/* 放音结束 */

brd_led_toggle(BRD_LED0);

brd_led_toggle(BRD_LED1); } }

} //主程序结束

/* 子函数 */

/*******延时******/ void delay(s16 period) {

int i, j;

for(i=0; i

{

for(j=0; j>1; j++); } }

/*******闪灯******/ void led(s16 cnt) {

while ( cnt-- ) { brd_led_toggle(BRD_LED0); //切换LED指示灯0的显示状态 delay(1000); brd_led_toggle(BRD_LED1); delay(1000); brd_led_toggle(BRD_LED2); delay(1000); } }

/*****初始化codec**/ void initcodec(void) {

/* Open Handset Codec 获取设置codec的句柄*/

hHandset = codec_open(HANDSET_CODEC); // Acquire handle to codec

/* Set codec parameters */

codec_dac_mode(hHandset, CODEC_DAC_15BIT); // DAC in 15-bit mode

codec_adc_mode(hHandset, CODEC_ADC_15BIT); // ADC in 15-bit mode

codec_ain_gain(hHandset, CODEC_AIN_6dB); // 6dB gain on analog input to ADC

codec_aout_gain(hHandset, CODEC_AOUT_MINUS_6dB);

// -6dB gain on analog output from DAC

codec_sample_rate(hHandset,SR_8000); // 8KHz sampling rate }

/*****设置flash****/ void flashenable(void) {

CPLD_CTRL2_REG|=0x0010; CPLD_DMCTRL_REG|=0x0040;

}

/*****a律压缩******/

unsigned char data2alaw(s16 pcm_val) {

int mask; int seg;

unsigned char aval;

if (pcm_val >= 0) { mask = 0xD5; // 标记 (7th) bit = 1 } else { mask = 0x55; // 标记 bit = 0 pcm_val = -pcm_val; } // Convert the scaled magnitude to segment number. seg = search(pcm_val, seg_end, 8);

// Combine the sign, segment, and quantization bits. if (seg >= 8) // out of range, 返回最大数. return (0x7F ^ mask); else { aval = seg << SEG_SHIFT; if (seg < 2) aval |= (pcm_val >> 1) & QUANT_MASK; else aval |= (pcm_val >>seg) & QUANT_MASK; return (aval ^ mask); } }

/****alaw的子程序**/

static int search(int val,short *table,int size) {

int i;

for (i = 0; i < size; i++) { if (val <= *table++)

return (i); }

return (size); }

/*****a律解压******/

int alaw2data(unsigned char a_val) {

int t; int seg;

a_val ^= 0x55;

t = (a_val & QUANT_MASK) << 4;

seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; if(seg==0) {

t += 8; t=(t>>3); }

if((seg<4)&&(seg>0)) {

t +=0x108; t=(t>>(4-seg)); }

if(seg>3) { t+=0x108; t=(t<<=(seg-4)); }

return ((a_val & SIGN_BIT) ? t : -t); }

/* 结束 */

四、一辈子孤单并不可怕,如果我们可以从中提炼出自由,那我们就是幸福的。许多长久的关系都以为忘记了当初所坚持与拥有的,最后又开始羡慕起孤单的人。 五、恋爱,在感情上,当你想征服对方的时候,实际上已经在一定程度上被对方征服了。首先是对方对你的吸引,然后才是你征服对方的欲望。 六、没有心如刀割,不再依依不舍,只有,沉默相隔……

七、和你在一起只是我不想给任何人机会。 八、一个人总要走陌生的路,看陌生的风景,听陌生的歌,然后在某个不经意的瞬间,你会发现,原本是费尽心机想要忘记的事情真的就那么忘记了。 九、无论我们爱过还是就这样错过,我都会感谢你。因为遇见你,我才知道思念一个人的滋味;因为遇见你,我才知道感情真的不能勉强;因为遇见你,我才知道我的心不是真的死了;因为遇见你,我才知道我也能拥有美丽的记忆。所以,无论你怎么对待我,我都会用心去宽恕你的狠,用心去铭记你的好。 十、爱情需要的是彼此互相的照顾,当我们心爱的人累了,我们不是坐在一边不理,而是多陪对方谈谈心,对方需要什么的时候,自己尽量的满足对方的需求,至少可以让对方知道,在自己身边的感觉是如此的温暖。 十一、自从你出现後,我才知道原来有人爱是那麽的美好 十二、有的人与人之间的相遇就像是流星,瞬间迸发出令人羡慕的火花,却注定只是匆匆而过。 十三、有一些人,这一辈子都不会在一起,但是有一种感觉却可以藏在心里守一辈子。 十四、不要轻易说爱,许下的承诺就是欠下的债! 十五、不管你是多么的爱对方,但千万不可当第三者。细想,默然。因为知道,这样的故事一开始便注定了结局,一开始就注定在这个故事里,很多人会受伤。离开的总是要离开,挽留不住,就像彼岸花,穷其一生,花叶仍是生生相错。 十六、什么叫快乐?就是掩饰自己的悲伤对每个人微笑。 十七、爱情与视力无关,任你看得再怎么清楚,在爱里只有模糊。因为太聪明太理智就没有办法恋爱,爱情根本是盲目的。 十八、恋爱就像剪头发,这种事情不到最后是不知道结果的,结果能否令每个人皆大欢喜,无人保障,但是一切都是自己的选择。 十九、因为爱过,所以慈悲:因为懂得,所以宽容。 二十、那些随风散落的微笑眼神,仿似落寞诗人的爱情诗句,一段一段,错落成行。孤独的钟鸣彻夜悲鸣,那些如花容颜,终不敌过时间切割的颓败,我们忧伤的仰望阳光,看流年未亡,年华尽耗。 二十一、一个人一生可以爱上很多的人,等你获得真正属于你的幸福之后,你就会明白一起的伤痛其实是一种财富,它让你学会更好地去把握和珍惜你爱的人。 二十二、爱一个人,由天由人却由不得自己。不由自主只因刻骨铭心,不离不弃只因无法代替。总是心有期待,才有灯火阑珊处的望眼等待;总是情怀善待,才有心甘情愿地付出所有,习惯的依赖。也许你的世界一无所有,但在爱你人的心里,你就是全世界。珍惜一个深爱你的人,更要珍藏一颗为你融入生命的心。 二十三、就在我以为一切都没有改变只要我高兴就可以重新扎入你的怀抱一辈子不出来的时候,其实一切都已经沧海桑田了,我像是一躲在壳里长眠的鹦鹉螺,等我探出头来打量这个世界的时候,我原先居住的大海已经成为高不可攀的山脉,而我,是一块僵死在山崖上的化石 二十四、幸福,不是长生不老,不是大鱼大肉,不是权倾朝野。幸福是每一个微小的生活愿望达成。当你想吃的时候有得吃,想被爱的时候有人来爱你。 二十五、有时,爱也是种伤害。残忍的人,选择伤害别人,善良的人,选择伤害自己。

二十六、如果,不幸福,如果,不快乐,那就放手吧;如果,舍不得、放不下,那就痛苦吧。 二十七、这个世界就这么不完美。你想得到些什么就不得不失去些什么。 二十八、有的人与人之间的相遇就像是流星,瞬间迸发出令人羡慕的火花,却注定只是匆匆而过。 二十九、无数次在梦的意境,勾勒你的样子,那样的虔诚,和你的心灵一样,一生刻骨。 三十、有叛你,你却想挽回。有人不爱你,你却讨好他。何必为爱委屈自己。一个人如真心爱你,绝不会对你忽冷忽热;一个人如真心想追你,绝不会跟你玩暧昧。与其卑微的恋爱,不如选择单身。

人背

本文来源:https://www.bwwdw.com/article/0g78.html

Top