C++中利用Speex进行音频压缩

  1. #ifdef HAVE_CONFIG_H  
  2. #include "config.h"  
  3. #endif  
  4.   
  5. #include <stdio.h>  
  6. #include <stdlib.h>  
  7. #include <speex/speex_callbacks.h>  
  8. #include <speex.h>  
  9.   
  10. #ifdef FIXED_DEBUG  
  11. extern long long spx_mips;  
  12. #endif  
  13.   
  14. #define FRAME_SIZE 160  
  15. #include <math.h>  
  16. int main(int argc, char **argv)  
  17. {  
  18.   char *inFile, *outFile, *bitsFile;  
  19.   FILE *fin, *fout, *fbits=NULL;  
  20.   short in_short[FRAME_SIZE]; // 编解码的数据  
  21.   short out_short[FRAME_SIZE];  
  22.   int snr_frames = 0;  
  23.   char cbits[200];  
  24.   int nbBits;  
  25.   int i;  
  26.   void *st;  
  27.   void *dec;  
  28.   SpeexBits bits;  
  29.   spx_int32_t tmp;  
  30.   int bitCount=0;  
  31.   spx_int32_t skip_group_delay;  
  32.   SpeexCallback callback;  
  33.   
  34.   // 初始化编解码  
  35.   st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));  
  36.   dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));  
  37.   
  38.   /* BEGIN: You probably don't need the following in a real application */  
  39.   // 设置一些回调属性,这些我没用到 :)  
  40.   callback.callback_id = SPEEX_INBAND_CHAR;  
  41.   callback.func = speex_std_char_handler;  
  42.   callback.data = stderr;  
  43.   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);  
  44.   
  45.   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;  
  46.   callback.func = speex_std_mode_request_handler;  
  47.   callback.data = st;  
  48.   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);  
  49.   /* END of unnecessary stuff */  
  50.   
  51.   tmp=1;  
  52.   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);  
  53.   tmp=0;  
  54.   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);  
  55.   tmp=8;  
  56.   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);  
  57.   tmp=1;  
  58.   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);  
  59.   
  60.   // 设置属性值  
  61.   /* Turn this off if you want to measure SNR (on by default) */  
  62.   tmp=1;  
  63.   speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp);  
  64.   speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp);  
  65.   
  66.   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);  
  67.   speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);  
  68.   skip_group_delay += tmp;  
  69.   
  70.   if (argc != 4 && argc != 3)  
  71.   {  
  72.       fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);  
  73.       exit(1);  
  74.   }  
  75.   inFile = argv[1];  
  76.   fin = fopen(inFile, "rb");// 读文件  
  77.   outFile = argv[2];  
  78.   fout = fopen(outFile, "wb+"); // 准备将编码后文件写入此文件  
  79.   if (argc==4)  
  80.   {  
  81.       bitsFile = argv[3];  
  82.       fbits = fopen(bitsFile, "wb");  
  83.   }  
  84.   speex_bits_init(&bits);  
  85.   while (!feof(fin))  
  86.   {  
  87.       fread(in_short, sizeof(short), FRAME_SIZE, fin); // 读取  
  88.       if (feof(fin))  
  89.         break;  
  90.       speex_bits_reset(&bits);  
  91.   
  92.       speex_encode_int(st, in_short, &bits);  
  93.       nbBits = speex_bits_write(&bits, cbits, 200); // 通过speex编码  
  94.       bitCount+=bits.nbBits;  
  95.   
  96.       if (argc==4)  
  97.         fwrite(cbits, 1, nbBits, fbits);  
  98.       speex_bits_rewind(&bits);  
  99.   
  100.       speex_decode_int(dec, &bits, out_short);  
  101.       speex_bits_reset(&bits);  
  102.   
  103.       fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout); // 写入  
  104.       skip_group_delay = 0;  
  105.   }  
  106.   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);  
  107.   speex_encoder_destroy(st);  
  108.   speex_decoder_destroy(dec);  
  109.   speex_bits_destroy(&bits); // 释放speex资源  
  110.   
  111. #ifndef DISABLE_FLOAT_API  
  112.   {  
  113.   float sigpow,errpow,snr, seg_snr=0;  
  114.   sigpow = 0;  
  115.   errpow = 0;  
  116.   
  117.   /* This code just computes SNR, so you don't need it either */  
  118.   rewind(fin);  
  119.   rewind(fout);  
  120.   
  121.   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin)  
  122.           &&  
  123.           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )  
  124.   {  
  125. float s=0, e=0;  
  126.         for (i=0;i <FRAME_SIZE;++i) {  
  127.             s += (float)in_short[i] * in_short[i];  
  128.             e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);  
  129.         }  
  130. seg_snr += 10*log10((s+160)/(e+160));  
  131. sigpow += s;  
  132. errpow += e;  
  133. snr_frames++;  
  134.   }  
  135.   snr = 10 * log10( sigpow / errpow );  
  136.   seg_snr /= snr_frames;  
  137.   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);  
  138.   
  139. #ifdef FIXED_DEBUG  
  140.   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));  
  141. #endif  
  142.   }  
  143. #endif  
  144.   
  145.   fclose(fin);  
  146.   fclose(fout);  
  147.   
  148.   return 0;  
  149. }   

你可能感兴趣的:(C++中利用Speex进行音频压缩)