资源描述
DSP课程设计
实 验 报 告
语音压缩、存放和回放
成绩:
工程设计50
汇报20
答辩30
总分
评语:
指导老师签字:
日期:
一、 试验背景和内容
语音通信是现代多媒体通信中一个关键组成部分,而语音信号是信息关键形式, 语音信号处理有着广泛应用领域,同时语音压缩在语音信号传输、存放等方面有很广泛作用,而且在通信领域中已经有较成熟发展和广泛应用。本设计要求采取DSP及其A/D、D/A转换器进行语音信号压缩、存放和回放。
语音数字通信不管在可靠性、抗干扰能力、保密性还是价格方面全部远优于模拟语音信号,但这是以信道占用宽频带宽为代价。所以为了降低语音信号所占用带宽或存放空间,就必需对数字语音信号进行压缩编码。一个优异语音压缩系统要求能够在软硬件资源占用百分比低和压缩编解码时间短同时,能够实现多通道语音实时压缩。
DSP仿真器用于DSP在线调试开发,能够经过软件在线控制DSP运行状态,并能够查看DSP内部寄存器。PC是开发人员和DSP系统之间交互界面,经过PC上安装CCS集成开发环境,开发人员能够在友好图形界面下对目标系统进行操作。
此次试验采取DSP C5402试验板实现语音信号压缩解压。SEED-VC5402 DSK试验板上集成了SRAM,FLASH,音频输入输出接口等部件。
二、 试验目标
1、应用DSP算法实现对语音信号压缩、存放和回放。
2、熟悉使用C语言编写较复杂程序;
3、熟悉C语言对外设(DSK板或示波器)访问(软件编程、硬件连接);
4、熟练使用软件CCS5000对程序完整调试过程。
三、试验设计要求及目标
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比特,达成语音压缩目标。
四、试验原理
1、 DSK 包含:
主芯片 1枚:100 MHz TMS320VC5402 DSP
RAM 1枚:1个软件等候64K×16bitSRAM(CY7C1021V33
FLASH 1枚:256K×16bit FLASH存放器(AM39VF400A
接口 2个:一个连接到PC机并口主机端接口HPI和用于仿真JTAG测试总线控制器
信号采集和输出端口:麦克风/耳机音频接口
Ø C5402硬件特点:
增强型哈佛结构,一个程序总线,三个独立数据总线;40bit算术逻辑单元ALU ;可寻址程序空间达1Mx16bit;4Kx16bit片内ROM ;16Kx16bit双口片内RAM;片内外设:软件可编程等候状态发生器;片内锁相环时钟发生器;两个多通道缓冲串口;增强型8bit并行HPI口;两个16bit定时器;六通道DMA控制器;节电模式IDLE1,IDLE2,IDLE3做功耗控制;单周期定点指令(100MIPS)实施时间为10ns。
Ø C5402硬件优点:
内部多总线结构确保在一个机器周期内能够数次访问程序空间和数据空间;指令实施时多重流水线结构将指令周期降低到了最小值;多处理单元能够在一个指令周期内同时进行运算,而这种结构恰好满足了数字信号处理中部分特殊要求如FIR、IIR、FFT等运算。
Ø C5402软件特点:7种有效灵活寻址方法,仅为10ns指令实施周期。
2、TMS320C5402结构及原理
TMS320C5402采取优异改善哈佛结构和8条总线结构,处理了冯诺伊曼(Von-Neumann)结构中高速数据传输时传输通道上瓶颈现象,使处理器性能大大提升,程序数据总线相互独立,许可同时访问程序存放器和数据存放器,实现高度并行操作。另外,还能够在数据总线和程序总线之间相互传送数据,从而使处理器含有在单个周期内同时实施算数运算、逻辑运算、移位操作、乘法/累加运算和访问程序和数据存放器强大功效。
TMS320C5402内部多总线结构确保在一个机器周期内能够数次访问程序空间和数据空间;指令实施时多重流水线结构将指令周期降低到了最小值;多处理单元能够在一个指令周期内同时进行运算,而这种结构恰好满足了数字信号处理中部分特殊要求如FIR、IIR、FFT等运算。因为C5402有7种有效灵活寻址方法软件特点,仅为10ns指令实施周期,还有部分特殊运算指令愈加好地满足了数字信号处理中特有运算需要。
TMS320C5402含有高速,全双工串行口,可用来和系统中其它C54x器件,编码解码器,串行A/D,D/A转换器和其它串行器件直接接口。这两个串行口均为多通道缓冲串行口McBSP(Multi-channel Buffered Serial Port)。它支持全双工通信,双缓冲数据寄存器,许可连续数据流。内置μ-律和A-律压扩硬件。
DSP结构框图
3、AD50结构和原理
AD50是单片音频接口芯片(AIC)。它内部集成了16位D/A和A/D转换器,采样速率最高可达22.05kb/s,其采样速率可经过DSP编程来设置。在DAC之前有一个插值滤波器以确保输出信号平滑和ADC以后有一个抽取滤波器以提升输入信号信噪比。 AD50内部有7个数据和控制寄存器,用于编程控制它们工作状态。它数据传输模式和采样速率全部能够经过DSP对其控制寄存器编程来实现,所以,在很多场所下,AD50全部作为DSPAIC来实现音频处理。
寄存器0:空操作寄存器。
寄存器1:软件复位
软件掉电
选择16位或15位工作方法
硬件或软件二次通信请求方法选择
寄存器2:使能ALTDATA输入端
为ADC选择16/15位方法
寄存器3:选择FS和FSD之间延迟SCLK个数
告诉主机有多个从机被联上
寄存器4:为输入和输出放大器选择放大器增益
选择N来设置采样频率,fs=MCLK/(128*N)或MCLK/(512*N)
在MCLK输入端使能外部时钟输入并旁通内部PLL
寄存器5,6:保留
AD50和C5402之间数据传送采取串行方法,包含两种传输模式:16位
和15+1位传输模式。15+1位模式时,其中D0位表示二次通信。它们各
自时序以下:
4、程序存放芯片
试验中,电路选择芯片SST39VF400是一个低功耗FLASH。
芯片硬件特点:A17至A0为外部地址管脚,D15至D0为1条数据线,CE#为片选控制管脚(低有效),OE#为输出控制管脚(低有效),WE#为写入控制管脚(低有效)。工作在2.7V至3.6V电压下,存放容量位256KW,其。中数据能够保持1以上,可反复编程次数高达10万次。
5、u_LAW/a_LAW压扩硬件处理
在电信中常常利用u律和a律对数据进行压扩处理,C5400在McBSP中提供了专门硬件试验这一功效。压扩处理时,CPU访问到全部是16位,她分别是利用线性14位数据(u律)和13位(a律)数据左对齐取得。压扩硬件结构和对应数据以下图所表示。
在本试验中,我们经过软件编程来完成线性码转换成A律。
语音信号通常是小信号概率大,大信号出现概率小,为提升小信号时量化信躁比,压缩比特速率,可为非线性量化。语音压缩是把16位数据比特转化为8位数据比特,从而抵达语音压缩目标。
在主程序中经过A/D抽样量化,能够得到16位线性编码,再由编码表经过软件计算得到8位A律编码,其中最高位为符号位,第6位到第4位为段落码,低4位为段内码。将8位压缩结果存放到系统RAM中进行缓存,依据抽样率、语音存放时间和系统RAM容量设置语音存放缓冲区大小,待缓冲区存满后,将缓冲区内数据进行解压缩,然后输出到SPEAKER接口输出端。
若使用A/D转换器,必需首先对A/D转换器进行初始化设置,即设置A/D转换器工作模式、输入增益和抽样频率等。
A律压缩编码表
线性输入编码
压缩编码
0000000wxyza
000wxyz
0000001wxyza
001wxyz
000001wxyzab
010wxyz
00001wxyzabc
011wxyz
0001wxyzabcd
100wxyz
001wxyzabcde
101wxyz
01wxyzabcdef
110wxyz
1wxyzabcdefg
111wxyz
五、程序设计思绪
DSP程序设计应包含用户程序、存放器配置程序。为了实现语音信号采集和回放,先将语音信号采集,利用a律压缩算法将信号压缩并存入存贮器中,当放音开始时利用a律解压算法将信号解压并从存放器中释放出来,实现语音回放。
1、软件设计步骤
否
2、TMS320VC5402 mcbsp串口初始化
首先将DSP串口1复位,再对串口116个寄存器进行编程,使串口1工作在以下状态:严禁SPI模式,但数据相,每帧一字,每字16位,帧同时脉冲低电平有效,而且帧同时信号和移位信号有外部时钟产生。
hHandset = codec_open(HANDSET_CODEC;
此语句调用了函数codec_open(对串口1进行了初步设置,设置成功返回codec句柄放在变量 hHandset中,作为调用其它函数实参。
3、AD50初始化:
该初始化过程调用了5个函数对AD505项参数进行了设置,包含adc和dac工作模式,模拟输入和输出增益;和AD,DA转换速率。
4、从McBSP接收通道读取A/D转换值,然后经过压缩解压后将其发送到McBSP发送通道,讲解压后数据将数据写入D/A转换器。
程序以下:
while (1
{
/* Wait for sample from handset */
while (!MCBSP_RRDY(HANDSET_CODEC
{};
/* Read sample from and write back to handset codec */
data=*(volatile int*DRR1_ADDR(HANDSET_CODEC;
pre=int2alaw(data; /*or pre=int2ulaw(data;*/
data=alaw2int(pre; /*or data=ulaw2int(pre;*/
*(volatile int*DXR1_ADDR(HANDSET_CODEC=data;
六、试验程序
1 C语言程序
/******************************************************************/
/* 头文件 */
/*******************************************************************/
#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[2];
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为片外存放器
while (1
{
while (!MCBSP_RRDY(HANDSET_CODEC {}; //等候接收handset处采样
if (i==0 brd_led_toggle(BRD_LED0; //点亮二极管0,表示录音开始
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>=44000
{
i=0;
}
if(j>=2
{
j=0;
brd_led_toggle(BRD_LED0; //熄灭数码管0 表示录音结束
brd_led_toggle(BRD_LED1; //点亮二极管1 表示放音开始
/*******************************************************************/
/* 放音部分 */
/*******************************************************************/ for(k=0;k<44000;k++
{
if(k%2==0
{
temp2=(buffer[l]>>8&0x0ff;
}
else
{
temp2=buffer[l]&0x0ff;
l++;
}
if(l>=2
l=0;
data1=alaw2data(temp2;
while (!MCBSP_XRDY(HANDSET_CODEC {};
*(volatile u16*DXR1_ADDR(HANDSET_CODEC = data1;
}
/*******************************************************************/
/* 放音结束 */
/*******************************************************************/
if(k==44000 brd_led_toggle(BRD_LED1; //熄灭二极管1 表示放音结束
}
}
} //主程序结束
/*******************************************************************/
/* 子函数 */
/****************************************************************/
/*******延时******/
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;
delay(1000;
brd_led_toggle(BRD_LED1;
delay(1000;
brd_led_toggle(BRD_LED2;
delay(1000;
}
}
/*****初始化codec**/
void initcodec(void
{
/* Open Handset 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 = ((unsigneda_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;
}
/*******************************************************************/
/* 结束 */
/*******************************************************************/
2、存放器分配(*.cmd)
MEMORY
{
PAGE 0: VECS: origin = 0080h, length = 0080h /* Internal Program RAM */
PRAM: origin = 7600h, length = 8000h /* Internal Program RAM */
PAGE 1: SCRATCH: origin = 0060h, length = 0020h /* Scratch Pad Data RAM */
DMARAM: origin = 0C00h, length = 0300h /* DMA buffer */
DATA: origin = 1100h, length = 0080h /* Internal Data RAM */
STACK: origin = 1180h, length = 0560h /* Stack Memory Space */
INRAM: origin = 1900h, length = 0100h /* Internal Data RAM */
HPRAM0: origin = 1A00h, length = 0002h /* HPI memory accessible by Host and DSP */
HPRAM1: origin = 1A02h, length = 0280h /* HPI memory accessible by Host and DSP */
HPRAM2: origin = 1C82h, length = 0280h /* HPI memory accessible by Host and DSP */
EXRAM: origin = 1F10h, length = 5A00h /* External Data RAM */
}
SECTIONS
{
.cinit > PRAM PAGE 0
.text > PRAM PAGE 0
.vectors > VECS PAGE 0
init_var > PRAM PAGE 0
detect > PRAM PAGE 0
vrcprg > PRAM PAGE 0
matprg > PRAM PAGE 0
.stack > STACK PAGE 1
.trap > SCRATCH PAGE 1
.const > EXRAM PAGE 1
.data > EXRAM PAGE 1
.bss > EXRAM PAGE 1
.cio > EXRAM PAGE 1
.switch > EXRAM PAGE 1
tables > EXRAM PAGE 1
var > EXRAM PAGE 1
svctab > EXRAM PAGE 1 /* SS_V LSP table */
vctab > EXRAM PAGE 1 /* V LSP table */
uvctab > EXRAM PAGE 1 /* UV LSP table */
cuvtab > EXRAM PAGE 1 /* Stochastic codebook */
cdbktab > EXRAM PAGE 1 /* various codebook tables*/
logtab > EXRAM PAGE 1 /* table for log2 */
powtab > EXRAM PAGE 1 /* table for pow2 */
hamtab > EXRAM PAGE 1 /* table for hamming */
lgwtab > EXRAM PAGE 1 /* table for lag window */
acostab > EXRAM PAGE 1 /* table for arccos */
sqrtab > EXRAM PAGE 1 /* table for square root */
acbtab > EXRAM PAGE 1 /* table for thresholds in acb */
pm03tab > EXRAM PAGE 1 /* table for x^(-0.3 computation */
costab > EXRAM PAGE 1 /* table for cosine */
V23 > INRAM PAGE 1
FSK > INRAM PAGE 1
hpibuff0 > HPRAM0 PAGE 1
hpibuff1 > HPRAM1 PAGE 1
hpibuff2 > HPRAM2 PAGE 1
dma_buff > DMARAM PAGE 1
}
七、CCS程序调试和结果
1、开启Setup CCS程序
设置CCS环境。选择浮动菜单Import configuration->Available configuration 列表中,然后选中C5402 Device Simulator (没接DSK板时、C5402 DSK via Parallel Port Emulation (接DSK板时。选中Import,最终选中save and quit以保留目标DSP配置。
2、运行CCS2(‘5000,出现CCS界面。新建一个工程,向工程中添加c语言程序文件、CMD程序、头文件和库文件。
Ø C程序运行支持库:
C:\ti\ c5400\cgtools\ rts.lib
相关头文件 C:\ti\ c5400\cgtools\include\*.h
Ø DSK板库文件:
C:\ti\ c5400\dsk5402\ drv5402.lib,dsk5402.lib
相关头文件 C:\ti\ c5400\dsk5402\include\*.h
在程序中还用到其它头文件:
#include
#include
#include
#include
C语言程序文件、CMD程序和库文件加入可经过Project里Add Files to Project找到对应文件直接加入。最好是将.h和.lib文件全部拷贝到自己工程中,或在CCSexample中进行调试、编译,这么通常就不会出现找不到头文件错误信息。当汇编出现找不到头文件错误时,以下图。
这时需要经过Build options里“include SearchPath(-i)option”加入头文件所指定位置。以下图:
3、程序汇编、链接经过并生成.out文件。装载.out文件后就能够运行。
4、试验现象结果显示:
经过波形及寄存器值能够具体察看程序实施情况,并观看每个时刻情况。
Ø 用到关键寄存器
选择View中RegistersCPU Registers选项,能够看到CPU中寄存器改变情况,选择View中RegistersPeripheral Regs选项,能够看到外设寄存器改变情况。寄存器及变量某瞬时值以下:
Ø 试验波形
经过View中Graph能够看到波形图。以下:
输入波形:
压缩波形:
输出波形:
5、硬件结果显示
对语音信号开始采样后,灯闪两次,初始化codec。二级管灯0亮开始采集语音数据,二极管灯0熄灭录音结束,二极管灯1亮开始放音,二极管灯1熄灭放音结束,二极管灯0亮重新开始采样语音信号。如此再循环运行程序。
八、试验总结
经过此次试验设计,我了解了DSP内部资源和各部件作用。经过应用DSP算法实现对语音信号压缩、存放和回放试验过程,使我熟悉了使用C语言编写较复杂程序,对CCS5000对程序完整调试过程有了深入了解。另外对A律算法C语言实现基础掌握,对PCM语音压缩算法基础原理有了一定认识。
设计开始时,我先熟悉了试验所要实现功效和CCS软件基础操作和调试,经过查找相关资料,对语音压缩算法,编码和解码有了一定了解。ITU-T G.711提议PCM A律和µ律语音压缩标准能够分别将13比特和14比特压缩为8比特,能够达成语音压缩目标。
试验中,需要首先了解DSK板上硬件资源结构特点和作用。软件调试过程中我们碰到了部分问题。首先,因为C语言程序文件、CMD程序和库文件加入可经过Project里Add Files to Project找到对应文件直接加入。不过,编译时出现找不到头文件错误时,这时我们经过Build options里加入头文件所指定位置。
最终经过学习及不停调适能够熟练应用软件实现自己需要功效,将程序下载到试验板上,成功运行。开始采集语音数据时二级管灯0亮,二极管灯0熄灭表示录音结束,二极管灯1亮开始放音,二极管灯1熄灭放音结束,二极管灯0亮说明重新开始采样语音信号。这么循环运行下去。
参考文件
[1] 高海林、钱满义.DSP技术及其应用讲义.10月
[2]. 周霖. DSP通信工程技术应用[M]. 北京: 国防工业出版社,.115
[3] 张勇.C/C++ 语言硬件程序设计[M]. 西安:西安电子科技大学出版社,.27-75
展开阅读全文