G.729与G.723语音编码介绍及优化

本文介绍了语音编码技术的基础知识,包括波形编码、参数编码及混合编码等不同编码方式的特点和应用。重点阐述了混合编码技术如MPLPC和CELP,并讨论了人耳听觉特性与采样率的关系。此外,还深入分析了ITU制定的标准G.729和G.723的原理及其优化方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

语音编码分成波形编码、参数编码和混合编码.波形编码就是语音信号形成的波形进行处理和加工,参数编码是以语音信号产生的数字模型为基础,求出其模型参数,然后按照这些参数还原数字模型,合成语音。混合编码是综合了波形编码和参数编码的长处,在4-16kbps的速率上进行高质量的语音合成。例如多脉冲激励线性预测编码(MPLPC),码本激励线性预测编码(CELP)都是混合编码。
人耳的听觉范围在20-20KHZ,根据抽样定律要保证声音不失真,就必须用44KHZ左右采样频率,但是人说话的范围在300-3400HZ,所以就用8KHZ主要对人声采样。
波形编码前,首先对模拟语音信号进行采样,然后对采样结果进行幅度量化,再进行二进制编码。
参数编码则是对数字模型的参数进行求值,目前常用的是无损声管离散时间模型,该模型综合了人声的最重要三个因素:声门,激励和辐射。这三个因素都可以用数学函数表达。再加上在语音信号的非均匀性和相关性,非均匀性表现在小幅度信号出现的概率较大,相关性表现在相邻的两个样本点相关和相隔基音周期之间的两个样本点也相关。线性预测就是利用了相关性从原来的语音信号计算出现在的信号。而且人在正常的交谈中有50%的时间是静音,只在听对方讲话,语音检测VAD 就是用来判断是否是静音,而柔和噪声再生CNG就是用来产生一个“好听”的静音传给对方,
G.729与G.723是ITU制定的适用于IP电话语音编码,因为其高质量,低码率而得到广泛应用,下面分别做介绍:
G.729是ITU制定通过的8kbps的语音编码协议,换算成字节才1k,它采用共轭结构的算术码激励线性预测(CS-ACELP)。
G.723也是ITU制定的,不过它是双速率语音编码,它可以工作在5.3kbps和6.3kbps两个方式上,相应分别采用代数码激励线性预测(ACELP)和多脉冲最大似能量化(MP-MLQ)。
在ITU上注册一个帐号便可以下载现实的C源代码和描述文档,在VC6下编译并运行,却发现编码效率太低,编码时间基本上是优化后5-6倍。ITU的源代码中采用的是最基本的运算,而且没有做过任何优化,所以效率极度低下。在优化之前先推荐一款调试软件DevPartner Studio Professional,它能进行错误分析和性能分析,功能强大,操作简单。
通过DevPartner对源代码进行分析发现无论是G.729还是G.723大部分运算都集中在basic_op.c的函数中,basic_op.c里面都是些基本运算,L_mac(),L_mult(),L_add()和sature()又占用basic_op.c中的绝大部分运算。所以优化也应该集中在这几个函数中。在basic_op.c有个溢出标志位overflow,很多基本函数多对其判断浪费了很多时间,其实可以直接去掉,使用时直接判断结果时候为最大值即可知道是否溢出,对basic_op.c的函数采用MMX指令优化,使用其饱和特性可以减掉很多判断溢出的操作,
下面给出一个加法的例子
Word16 add(Word16 var1,Word16 var2)
{
_asm{
movd mm0,var1;
movd mm1,var2;
paddsw mm0,mm1;
movd eax,mm0;
emms;
}
}
源代码中太多的函数调用,比如L_mac就调用了L_mult和L_add函数,如果直接把L_mult和L_add代码填入L_mac中则可以省去很多函数调用浪费的时间,ITU的代码中为了详细的描述算法有很多类似循环没有合并,将其合并也可以提高效率,并且有些在循环体内的运算也可以提到循环体外,对于用For()控制的循环次数最好使用参数,这样编译器可以将循环解开。
Rebuild started: Project: Project *** Using Compiler 'V6.22', folder: 'E:\Keil_v5\ARM\ARMCLANG\Bin' Rebuild target 'Target 1' assembling startup_stm32f10x_md.s... Start/core_cm3.c(445): error: non-ASM statement in naked function is not supported 445 | uint32_t result=0; | ^ Start/core_cm3.c(442): note: attribute is here 442 | uint32_t __get_PSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(465): error: parameter references not allowed in naked functions 465 | "BX lr \n\t" : : "r" (topOfProcStack) ); | ^ Start/core_cm3.c(461): note: attribute is here 461 | void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(479): error: non-ASM statement in naked function is not supported 479 | uint32_t result=0; | ^ Start/core_cm3.c(476): note: attribute is here 476 | uint32_t __get_MSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(499): error: parameter references not allowed in naked functions 499 | "BX lr \n\t" : : "r" (topOfMainStack) ); | ^ Start/core_cm3.c(495): note: attribute is here 495 | void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); | ^ 4 errors generated. compiling core_cm3.c... compiling misc.c... compiling system_stm32f10x.c... compiling stm32f10x_adc.c... compiling stm32f10x_dac.c... compiling stm32f10x_exti.c... compiling stm32f10x_dbgmcu.c... compiling stm32f10x_dma.c... compiling stm32f10x_crc.c... compiling stm32f10x_cec.c... compiling stm32f10x_bkp.c... compiling stm32f10x_can.c... compiling stm32f10x_flash.c... compiling stm32f10x_pwr.c... compiling stm32f10x_fsmc.c... compiling stm32f10x_
03-31
<think>嗯,用户遇到了Keil V6.22在编译STM32F10x项目时,core_cm3.c文件中出现裸函数中的非汇编语句和参数引用错误。我需要仔细分析这个问题,并给出解决方案。 首先,根据用户提供的引用资料,问题似乎是由于Keil的编译器版本不兼容引起的。引用[3]提到,江科大的启动文件使用的是版本5的编译器,而新版的MDK默认使用版本6,导致不兼容。用户现在用的是V6.22,可能默认也是版本6编译器,而core_cm3.c中的裸函数可能包含非汇编语句,这在版本6中不被支持。 裸函数(naked function)通常用于直接编写汇编代码,不允许有C语句,否则编译器会报错。版本6可能对此检查更严格。引用[4]指出,将编译器版本切换回5可以解决这个问题。但用户可能不想降级,或者最新版MDK已经没有版本5选项,这时候可能需要修改项目设置或调整代码。 另一个解决方法是修改core_cm3.c文件中的相关函数。例如,检查报错的445行,是否在裸函数中使用了C语句。可能需要将其替换为纯汇编代码,或者将函数声明为非naked。不过,修改库文件需谨慎,可能影响其他部分。 用户可能需要指导他们如何切换编译器版本到5,如果安装包中没有,可能需要单独安装旧版本编译器,或者从Keil官网下载。同时,检查项目配置中的编译器选项是否正确设置为版本5。 另外,引用[2]提到可以不用替换文件,而是选择使用编译器版本5,这需要用户安装MDK版本5并配置项目使用它。但用户可能已经安装了较新版本,所以可能需要调整项目设置而非整个MDK版本。 总结可能的解决步骤:1. 检查并切换项目中的编译器版本到5;2. 修改core_cm3.c中的裸函数,移除非汇编语句;3. 如果无法切换编译器,考虑更新固件库到兼容版本6的版本。 需要确保回答结构清晰,分步骤说明,并提供相关引用支持。同时,生成相关问题,帮助用户进一步理解可能遇到的问题。</think>### 解决Keil V6.22编译core_cm3.c的裸函数错误 #### 问题分析 1. **根本原因**:Keil MDK默认使用Compiler V6,而STM32F10x的固件库(如`core_cm3.c`)可能仅兼容Compiler V5,导致裸函数(`naked function`)中出现非汇编语句或参数引用错误[^3][^4]。 - 裸函数要求仅包含汇编指令,V6编译器对此检查更严格。 - 编译器版本不兼容时,原有代码中的C语句或参数操作会触发报错。 --- #### 解决方案 ##### 方法1:切换为Compiler V5 1. **安装Compiler V5**(若未预装): - 下载并安装**Legacy Support for ARM Compiler 5**(需Keil官网账户)[^2]。 2. **配置项目使用V5**: - 在Keil中打开项目,进入`Project -> Options for Target -> Target`选项卡。 - 将`ARM Compiler`选项从`V6.22`改为`Use default compiler version 5`。 3. **重新编译**:验证是否解决报错。 ##### 方法2:修改core_cm3.c的裸函数(高风险) 1. **定位错误位置**: - 找到报错行(如`core_cm3.c`第445行),检查裸函数`__ASM void ...`中的非汇编语句。 2. **重写为纯汇编**: - 将C语句替换为内联汇编,例如: ```c __ASM void FunctionName(...) { // 替换为汇编指令,如MOV、BX LR等 } ``` 3. **注意**:此操作需熟悉ARM汇编,且可能影响库功能,建议优先切换编译器。 ##### 方法3:更新固件库(推荐) 1. **下载兼容V6的库**: - 从STM官网或CubeMX获取最新`CMSIS`包,确保支持Compiler V6。 2. **替换旧文件**: - 将项目中的`core_cm3.c`、`startup_stm32f10x_xx.s`等替换为新版本文件。 3. **验证兼容性**:重新编译项目,检查是否消除报错。 --- #### 扩展建议 - **兼容性检查**:若使用Keil V6.22,建议逐步迁移到官方支持的库版本,避免长期依赖旧编译器。 - **调试技巧**:若报错涉及参数引用,检查裸函数是否直接操作了C语言参数(如`int x`),需改用寄存器传递(如`R0`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值