Speex 音频编解码

来源:互联网 发布:淘宝店图片怎么上传 编辑:程序博客网 时间:2024/05/06 19:27
  1. // demo.cpp : Defines the entry point for the console application.  
  2. //  
  3. #include "stdafx.h"  
  4. #include <speex/speex.h>  
  5. #include <stdio.h>   
  6. #include <ostream>  
  7.   
  8. #include <speex/speex_preprocess.h>  
  9. #include <speex/speex_echo.h>   
  10. #pragma comment(lib,"libspeexdsp.lib")   
  11. #define FRAME_SIZE 160  
  12. int main(int argc, char **argv)  
  13. {  
  14.       
  15.     char *inFile;  
  16.       
  17.     FILE *fin,*fout1,*fout2,*fout3;  
  18.       
  19.     short in[FRAME_SIZE];  
  20.     short out[FRAME_SIZE];    
  21.     float input[FRAME_SIZE];  
  22.     float output[FRAME_SIZE];     
  23.     char cbits[200];  
  24.       
  25.     int nbBytes;  
  26.       
  27.     /*保存编码的状态*/  
  28.       
  29.     void *stateEncode;  
  30.     void *stateDecode;  
  31.       
  32.     /*保存字节因此他们可以被speex常规读写*/  
  33.       
  34.       
  35.       
  36.     SpeexBits bitsEncode;  
  37.     SpeexBits bitsDecode;     
  38.     int i, tmp;  
  39.       
  40.     //新建一个新的编码状态在窄宽(narrowband)模式下  
  41.       
  42.     stateEncode = speex_encoder_init(&speex_nb_mode);  
  43.     stateDecode = speex_decoder_init(&speex_nb_mode);  
  44.     //设置质量为8(15kbps)  
  45.       
  46.     tmp=0;  
  47.     speex_encoder_ctl(stateEncode, SPEEX_SET_VBR, &tmp);  
  48.     float q=4;  
  49.     speex_encoder_ctl(stateEncode, SPEEX_SET_VBR_QUALITY, &q);  
  50.     speex_encoder_ctl(stateEncode, SPEEX_SET_QUALITY, &tmp);  
  51.       
  52.     inFile = argv[1];  
  53.       
  54.     fin = fopen("c:/demo.pcm""rb");  
  55.     fout1 = fopen("c:/demo_speex.raw""wb");  
  56.     fout2 = fopen("c:/demo1.pcm""wb");  
  57.     fout3 = fopen("c:/demo_slience.pcm""wb");  
  58.     //初始化结构使他们保存数据  
  59.   
  60.     speex_bits_init(&bitsEncode);  
  61.     speex_bits_init(&bitsDecode);  
  62.     int ret;  
  63.     int j=0;  
  64.     SpeexPreprocessState * m_st;  
  65.     SpeexEchoState *echo_state;   
  66.     m_st=speex_preprocess_state_init(160, 8000);  
  67. //  echo_state = speex_echo_state_init(160, 8000);   
  68.     int denoise = 1;  
  69.     int noiseSuppress = -25;  
  70.     speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_DENOISE, &denoise); //降噪  
  71.     speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); //设置噪声的dB  
  72.   
  73.       
  74.     int agc = 1;  
  75.     q=24000;  
  76.     //actually default is 8000(0,32768),here make it louder for voice is not loudy enough by default. 8000  
  77.     speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_AGC, &agc);//增益  
  78.     speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_AGC_LEVEL,&q);  
  79.     int vad = 1;  
  80.     int vadProbStart = 80;  
  81.     int vadProbContinue = 65;  
  82.     speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_VAD, &vad); //静音检测  
  83.     speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_PROB_START , &vadProbStart); //Set probability required for the VAD to go from silence to voice   
  84.     speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue); //Set probability required for the VAD to stay in the voice state (integer percent)   
  85.       
  86.   
  87.     while (1)  
  88.     {  
  89.         memset(out,0,FRAME_SIZE*sizeof(short));  
  90.         //读入一帧16bits的声音  
  91.         j++;  
  92.         int r=fread(in, sizeof(short), FRAME_SIZE, fin);  
  93.           
  94.         if (r<FRAME_SIZE)  
  95.             break;  
  96.           
  97.         //把16bits的值转化为float,以便speex库可以在上面工作  
  98.     spx_int16_t * ptr=(spx_int16_t *)in;  
  99.       
  100.     if (speex_preprocess_run(m_st, ptr))//预处理 打开了静音检测和降噪  
  101.     {  
  102.         printf("speech,");  
  103.         fwrite(in, sizeof(short), FRAME_SIZE, fout3);  
  104.     }  
  105.     else  
  106.     {  
  107.         printf("slience,");  
  108.         fwrite(out, sizeof(short), FRAME_SIZE, fout3);  
  109.     }  
  110.         for (i=0;i<FRAME_SIZE;i++)  
  111.               
  112.             input[i]=in[i];  
  113.           
  114.         //清空这个结构体里所有的字节,以便我们可以编码一个新的帧  
  115.           
  116.         speex_bits_reset(&bitsEncode);  
  117.           
  118.         //对帧进行编码  
  119.           
  120.         ret=speex_encode(stateEncode, input, &bitsEncode);  
  121.         //把bits拷贝到一个利用写出的char型数组  
  122.         nbBytes = speex_bits_write(&bitsEncode, cbits, 200);  
  123.         fwrite(cbits, sizeof(char), nbBytes, fout1);  
  124.         printf("%02d,",nbBytes);  
  125.           
  126.   
  127.         //清空这个结构体里所有的字节,以便我们可以编码一个新的帧  
  128.         speex_bits_reset(&bitsDecode);  
  129.         //将编码数据如读入bits  
  130.         speex_bits_read_from(&bitsDecode, cbits, nbBytes);    
  131.         //对帧进行解码  
  132.         ret = speex_decode(stateDecode, &bitsDecode,output);  
  133.         for (i=0;i<FRAME_SIZE;i++)  
  134.             out[i]=output[i];  
  135.         fwrite(out, sizeof(short), FRAME_SIZE, fout2);  
  136.     }  
  137.       
  138.     //释放编码器状态量  
  139.       
  140.     speex_encoder_destroy(stateEncode);  
  141.       
  142.     //释放bit_packing结构  
  143.       
  144.     speex_bits_destroy(&bitsEncode);  
  145.     speex_decoder_destroy(stateDecode);  
  146.       
  147.     //释放bit_packing结构  
  148.       
  149.     speex_bits_destroy(&bitsDecode);  
  150.     fclose(fin);  
  151.     fclose(fout1);  
  152.     fclose(fout2);  
  153.     fclose(fout3);  
  154.  return 0;  
  155.       
  156. }  
原创粉丝点击