|
好久没有发帖了,今天闲下来,和大家分享一下自己研究了大半年的Speex语音压缩库。自己水平也不咋样,如果有讲错的地方还望大家指出来,大家一起学习,这个帖子我会以连载的方式来写,好进入正题:
1,:先讲一讲这个东西怎么用
其实讲到这里,很多人都会想到ST有提供的现成的基于F103系列的库,没错我就是从这个库里面研究起来的,这个库有他的优点:ST专门对几个滤波器函数优化过,使用汇编写的,删除了一些子模式,并且使用定点运算,再这里先贴一下被ST优化过得那几个函数名称:filter_mem16(), inner_prod(),vq_nbest()等等,之所以这样才得以在103上面可以运行起来,缺点嘛:就是被阉割过了,只能使用一个模式,你如果想要更高的语音质量就别想用这个库了,它里面默认的质量是4,最好的质量等级是10,,具体的可以看下面的那个结构体:
初始值
其实如果真做语音压缩一类的话,我推荐用F407,开启FPU。或者DSP,优点嘛有很多,其中我认为最有用的就是里面的VBR了,可以做动态变比,也就是当你有语音信息的时候就会编出比较多的数据,没有语音信息时编出的数据非常少,只有1个Byte,这个也就引出了后面的DTX,它的意思就是说你没有语音信号的时候可以不传数据,想想这是不是很方便呢。好这个先提到这里,后面还有预处理什么的,这个VBR就放到后面来讲。有了上面这些参数的定义我们可以初始化到Speex里面去了,可以这样操作:
在这里特别提醒一下大家,这个库使用了一些内存分配,需要从堆里面去开辟内存,所以你的程序如果一运行到初始化就进入硬件错误,没关系,堆开大点就好了,一般对于编码解码来说 :0x8000的大小就可以了。后面说说怎么编码吧:
这里注意这个Nbyte,不要被ST提供的那个库给迷惑了,正确的用法是这样。
解码是这样:
这里有一些代码是用于缓存语音的,所以自己写了一个环形队列,为了方便大家阅读,我把代码贴出来:
- /**
- ******************************************************************************
- * @file MemQueue.C
- * @author Luoxianhui R&D Driver Software Team
- * @version V1.0.0
- * @date 06/09/2013
- * @brief MemQueue»·ÐζÓÁлº´æ
- ******************************************************************************
- **/
-
- /* Includes ------------------------------------------------------------------*/
- #include "MemQueue.h"
- #include "define.h"
- #include "includes.h"
- /** @addtogroup MemQueue_Driver
- * @{
- */
- /** @addtogroup Mem
- * @{
- */
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- SqQueueChar TestQueue;
- // SqQueueChar RxQueue;
- // SqQueueChar TxQueue;
- SqJitterQueueChar RxQueue;
- SqQueueShort AdQueue;
- SqQueueShort DaQueue;
- /* Private function prototypes -----------------------------------------------*/
- /* Private functions ---------------------------------------------------------*/
- void InitQueueChar(SqQueueChar *Q, INT32U F, INT32U E);
- INT16U QueueLenthChar(SqQueueChar *Q);
- SqQueueSta EnQueueChar(SqQueueChar *Q, INT8U Data);
- SqQueueSta DeQueueChar(SqQueueChar *Q, INT8U *Data);
- SqQueueSta EnQueueStrChar(SqQueueChar *Q, INT8U *Data,INT16U No);
- SqQueueSta DeQueueStrChar(SqQueueChar *Q, INT8U *Data,INT16U No);
- void InitQueueShort(SqQueueShort *Q, INT32U F, INT32U E);
- INT16U QueueLenthShort(SqQueueShort *Q);
- SqQueueSta EnQueueShort(SqQueueShort *Q, INT16S Data);
- SqQueueSta DeQueueShort(SqQueueShort *Q, INT16S *Data);
- SqQueueSta EnQueueStrShort(SqQueueShort *Q, INT16S *Data,INT16U No);
- SqQueueSta DeQueueStrShort(SqQueueShort *Q, INT16S *Data,INT16U No);
- void InitJitterQueueChar(SqJitterQueueChar *Q, INT32U F, INT32U E);
- INT16U JitterQueueLenthChar(SqJitterQueueChar *Q);
- SqQueueSta DeJitterQueueChar(SqJitterQueueChar *Q, INT8U *Data, INT16U *No);
- SqQueueSta EnJitterQueueChar(SqJitterQueueChar *Q, INT8U *Data, INT16U No);
- void InitQueueShort(SqQueueShort *Q, INT32U F, INT32U E)
- {
- Q->sRear = 0;
- Q->sFront = 0;
- Q->BufFullShortScal = F;
- Q->BufEmptyShortScal = E;
-
- }
- INT16U QueueLenthShort(SqQueueShort *Q)
- {
- return(((Q->sRear) - (Q->sFront) + BufSizeShort) % BufSizeShort);
- }
- SqQueueSta EnQueueShort(SqQueueShort *Q, INT16S Data)
- {
- if((((Q->sRear)+1) % BufSizeShort) == (Q->sFront)) return FALSE;
- (*Q).gBuf[Q->sRear] = Data;
- Q->sRear = (Q->sRear + 1) % BufSizeShort;
- return TRUE;
- }
- SqQueueSta DeQueueShort(SqQueueShort *Q, INT16S *Data)
- {
- if(Q->sRear == Q->sFront) return FALSE;
-
- *Data = (*Q).gBuf[Q->sFront];
- Q->sFront = (Q->sFront + 1) % BufSizeShort;
- return TRUE;
- }
- SqQueueSta EnQueueStrShort(SqQueueShort *Q, INT16S *Data,INT16U No)
- {
- OS_CPU_SR cpu_sr=0;
- INT16U i = 0;
- INT16U Len = 0;
- Len = QueueLenthShort(Q);
- if(Len >= Q->BufFullShortScal)
- {
- Q->BufEmpty = BufFull;
- }
- if(Len <= Q->BufEmptyShortScal)
- {
- Q->BufEmpty = BufEmpty;
- }
- if( Len >= (BufSizeShort-No)) return FALSE;
- OS_ENTER_CRITICAL();
- for(i=0; i<No; i++)
- {
- EnQueueShort(Q,Data[i]);
- }
- OS_EXIT_CRITICAL();
- return TRUE;
-
- }
- SqQueueSta DeQueueStrShort(SqQueueShort *Q, INT16S *Data,INT16U No)
- {
- INT16U i = 0;
- INT16U Len = 0;
- OS_CPU_SR cpu_sr=0;
- Len = QueueLenthShort(Q);
- if(Len >= Q->BufFullShortScal)
- {
- Q->BufEmpty = BufFull;
- }
- if(Len <= Q->BufEmptyShortScal)
- {
- Q->BufEmpty = BufEmpty;
- }
- if(Len <= No) return FALSE;
- OS_ENTER_CRITICAL();
- for(i=0; i<No; i++)
- {
- DeQueueShort(Q,&(Data[i]));
- }
- OS_EXIT_CRITICAL();
- return TRUE;
- }
- void InitQueueChar(SqQueueChar *Q, INT32U F, INT32U E)
- {
- Q->sRear = 0;
- Q->sFront = 0;
- Q->BufFullCharScal = F;
- Q->BufEmptyCharScal = E;
- }
- INT16U QueueLenthChar(SqQueueChar *Q)
- {
- return(((Q->sRear) - (Q->sFront) + BufSizeChar) % BufSizeChar);
- }
- SqQueueSta EnQueueChar(SqQueueChar *Q, INT8U Data)
- {
- if((((Q->sRear)+1) % BufSizeChar) == (Q->sFront)) return FALSE;
- (*Q).gBuf[Q->sRear] = Data;
- Q->sRear = (Q->sRear + 1) % BufSizeChar;
- return TRUE;
- }
- SqQueueSta DeQueueChar(SqQueueChar *Q, INT8U *Data)
- {
- if(Q->sRear == Q->sFront) return FALSE;
-
- *Data = (*Q).gBuf[Q->sFront];
- Q->sFront = (Q->sFront + 1) % BufSizeChar;
- return TRUE;
- }
- SqQueueSta EnQueueStrChar(SqQueueChar *Q, INT8U *Data,INT16U No)
- {
- INT16U i = 0;
- INT16U Len = 0;
- OS_CPU_SR cpu_sr=0;
- Len = QueueLenthChar(Q);
- if(Len >= Q->BufFullCharScal)
- {
- Q->BufEmpty = BufFull;
- }
- if(Len <= Q->BufEmptyCharScal)
- {
- Q->BufEmpty = BufEmpty;
- }
- if(Len >= (BufSizeChar-No)) return FALSE;
- OS_ENTER_CRITICAL();
- for(i=0; i<No; i++)
- {
- EnQueueChar(Q,Data[i]);
- }
- OS_EXIT_CRITICAL();
- return TRUE;
- }
- SqQueueSta DeQueueStrChar(SqQueueChar *Q, INT8U *Data,INT16U No)
- {
- INT16U i = 0;
- INT16U Len = 0;
- OS_CPU_SR cpu_sr=0;
- Len = QueueLenthChar(Q);
- if(Len >= Q->BufFullCharScal)
- {
- Q->BufEmpty = BufFull;
- }
- if(Len <= Q->BufEmptyCharScal)
- {
- Q->BufEmpty = BufEmpty;
- }
- if(Len <= No) return FALSE;
- OS_ENTER_CRITICAL();
- for(i=0; i<No; i++)
- {
- DeQueueChar(Q,&(Data[i]));
- }
- OS_EXIT_CRITICAL();
- return TRUE;
- }
- void InitJitterQueueChar(SqJitterQueueChar *Q, INT32U F, INT32U E)
- {
- Q->sRear = 0;
- Q->sFront = 0;
- Q->BufFullJitterCharScal = F;
- Q->BufEmptyJitterCharScal = E;
- }
- INT16U JitterQueueLenthChar(SqJitterQueueChar *Q)
- {
- return(((Q->sRear) - (Q->sFront) + BufSizeJitterChar) % BufSizeJitterChar);
- }
- SqQueueSta EnJitterQueueChar(SqJitterQueueChar *Q, INT8U *Data, INT16U No)
- {
- INT16U i = 0;
- INT16U Len = 0;
- if((((Q->sRear)+1) % BufSizeJitterChar) == (Q->sFront)) return FALSE;
-
- Len = JitterQueueLenthChar(Q);
-
- if(Len >= Q->BufFullJitterCharScal)
- {
- Q->BufEmpty = BufFull;
- }
- if(Len <= Q->BufEmptyJitterCharScal)
- {
- Q->BufEmpty = BufEmpty;
- }
-
- (*Q).gBuf[Q->sRear][0] = No;
- for(i=0; i<No; i++)
- {
- (*Q).gBuf[Q->sRear][i + 1] = Data[i];
- }
- Q->sRear = (Q->sRear + 1) % BufSizeJitterChar;
- return TRUE;
- }
- SqQueueSta DeJitterQueueChar(SqJitterQueueChar *Q, INT8U *Data, INT16U *No)
- {
- INT16U i = 0;
- INT16U Len = 0;
- if(Q->sRear == Q->sFront) return FALSE;
-
- Len = JitterQueueLenthChar(Q);
-
- if(Len >= Q->BufFullJitterCharScal)
- {
- Q->BufEmpty = BufFull;
- }
- if(Len <= Q->BufEmptyJitterCharScal)
- {
- Q->BufEmpty = BufEmpty;
- }
- *No = (*Q).gBuf[Q->sFront][0];
- for(i=0; i<(*Q).gBuf[Q->sFront][0]; i++)
- {
- Data[i] = (*Q).gBuf[Q->sFront][i + 1];
- }
- Q->sFront = (Q->sFront + 1) % BufSizeJitterChar;
- return TRUE;
- }
复制代码
下面是头文件
- #ifndef _MEMQUEUE_H_
- #define _MEMQUEUE_H_
- #include "define.h"
- #define BufSizeChar 2160
- #define BufSizeShort 3200
- #define BufFullChar BufSizeChar - 920
- #define BufFullShort BufSizeShort - 960
- #define BufEmptyChar 60
- #define BufEmptyShort 640
- #define BufSizeJitterChar 250
- #define FramSizeJitterChar 70
- #define BufFullJitterChar BufSizeJitterChar - 200
- #define BufEmptyJitterChar 10
- typedef enum {FALSE, TRUE, BufFull, BufEmpty} SqQueueSta;
- typedef struct _SqJitterQueueChar
- {
- INT8U gBuf[BufSizeJitterChar][FramSizeJitterChar];
- INT16U sFront;
- INT16U sRear;
- INT32U BufFullJitterCharScal;
- INT32U BufEmptyJitterCharScal;
- SqQueueSta BufEmpty;
- }SqJitterQueueChar;
- typedef struct _SqQueueChar
- {
- INT8U gBuf[BufSizeChar];
- INT16U sFront;
- INT16U sRear;
- INT32U BufFullCharScal;
- INT32U BufEmptyCharScal;
- SqQueueSta BufEmpty;
- }SqQueueChar;
- typedef struct _SqQueueShort
- {
- INT16S gBuf[BufSizeShort];
- INT16U sFront;
- INT16U sRear;
- INT32U BufFullShortScal;
- INT32U BufEmptyShortScal;
- SqQueueSta BufEmpty;
-
- }SqQueueShort;
- extern SqQueueChar TestQueue;
- // extern SqQueueChar RxQueue;
- // extern SqQueueChar TxQueue;
- extern SqJitterQueueChar RxQueue;
- // extern SqJitterQueueChar TxQueue;
- extern SqQueueShort AdQueue;
- extern SqQueueShort DaQueue;
- void InitQueueChar(SqQueueChar *Q, INT32U F, INT32U E);
- INT16U QueueLenthChar(SqQueueChar *Q);
- SqQueueSta EnQueueChar(SqQueueChar *Q, INT8U Data);
- SqQueueSta DeQueueChar(SqQueueChar *Q, INT8U *Data);
- SqQueueSta EnQueueStrChar(SqQueueChar *Q, INT8U *Data,INT16U No);
- SqQueueSta DeQueueStrChar(SqQueueChar *Q, INT8U *Data,INT16U No);
- void InitQueueShort(SqQueueShort *Q, INT32U F, INT32U E);
- INT16U QueueLenthShort(SqQueueShort *Q);
- SqQueueSta EnQueueShort(SqQueueShort *Q, INT16S Data);
- SqQueueSta DeQueueShort(SqQueueShort *Q, INT16S *Data);
- SqQueueSta EnQueueStrShort(SqQueueShort *Q, INT16S *Data,INT16U No);
- SqQueueSta DeQueueStrShort(SqQueueShort *Q, INT16S *Data,INT16U No);
- void InitJitterQueueChar(SqJitterQueueChar *Q, INT32U F, INT32U E);
- INT16U JitterQueueLenthChar(SqJitterQueueChar *Q);
- SqQueueSta DeJitterQueueChar(SqJitterQueueChar *Q, INT8U *Data, INT16U *No);
- SqQueueSta EnJitterQueueChar(SqJitterQueueChar *Q, INT8U *Data, INT16U No);
- #endif
复制代码
好今天先说到这里,后续,希望对大家有用。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|