FE_enhance.cpp
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:23k
源码类别:

语音合成与识别

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // This is a part of the Feature program.
  3. // Version: 1.0
  4. // Date: February 22, 2003
  5. // Programmer: Oh-Wook Kwon
  6. // Copyright(c) 2003 Oh-Wook Kwon. All rights reserved. owkwon@ucsd.edu
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #include "StdAfx.h"
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #include <assert.h>
  15. #include "FE_feature.h"
  16. /*------------------------------------------
  17. * Definition of Noise Reduction Parameters 
  18. *-----------------------------------------*/
  19. /* general */
  20. #ifndef DEFAULT_SAMPLING_RATE
  21. #define DEFAULT_SAMPLING_RATE        16000
  22. #endif
  23. /* Wiener filter design */
  24. #define NR_NB_FRAME_THRESHOLD_NSE      100
  25. #define NR_LAMBDA_NSE                 0.99
  26. #define NR_EPS                       1e-16 /* owkwon: originally 1e-16 */
  27. #define NR_BETA                       0.98
  28. #define NR_ETA_TH                     0.01 /* owkwon: reduced to -40 dB for kWaves, originally 0.079432823 corresponding to -22 dB */
  29. #define NR_STARTING_FREQ                 0   /* 0Hz  */
  30. /* Spectral subtraction design */
  31. #define NR_SS_TH                      0.01
  32. /* VAD for noise estimation (VADNest) */
  33. #define NR_NB_FRAME_THRESHOLD_LTE       10
  34. #define NR_LAMBDA_LTE                 0.97
  35. #define NR_SNR_THRESHOLD_UPD_LTE        20
  36. #define NR_ENERGY_FLOOR                 80
  37. #define NR_MIN_FRAME                    10
  38. #define NR_SNR_THRESHOLD_VAD            24 /* owkwon: increased, originally 15 */
  39. #define NR_MIN_SPEECH_FRAME_HANGOVER     4
  40. #define NR_HANGOVER                      5
  41. #define NR_SNR_THRESHOLD_NO_UPD_LTE     80 /* owkwon: there sometimes exist only a few silence frames less than NR_MIN_FRAME */
  42. /*----------------------
  43.  * Constant Definitions
  44.  *----------------------*/
  45. #ifndef M_PI
  46. #define M_PI        ((float)3.14159265358979323846)
  47. #endif
  48. /*----------------------
  49.  * Macro Definitions
  50.  *----------------------*/
  51. #define NR_T(z)          ((z)>0 ? (z) : 0)
  52. #define NR_SQ(z)                 ((z)*(z))
  53. #define Round(x)    ((int)((x)+0.5))
  54. /*---------------------
  55.  * Function Prototypes
  56.  *---------------------*/
  57. extern void PRFFT_NEW(float *a, float *b, int m, int n_pts, int iff);
  58. int Fe::EnhanceMain(const char *infile, const char *outfile, int sampleRate, int isWiener)
  59. {
  60. FILE *fpin=fopen(infile,"rb");
  61. if(fpin==0){
  62. fprintf(stderr, "File open error (%s)n",infile);
  63. assert(0);
  64. return 0;
  65. }
  66. fseek(fpin,0L,SEEK_END);
  67. int fsize = ftell(fpin);
  68. rewind(fpin);
  69. int sampleN=fsize/sizeof(short);
  70. vector<short> data(sampleN);
  71. fread(&data[0], sizeof(short), sampleN, fpin);
  72. fclose(fpin);
  73. enhance_basic(&data[0], sampleN, sampleRate, isWiener);
  74. FILE *fpout=fopen(outfile,"wb");
  75. if(fpout==0){
  76. fprintf(stderr, "File open error (%s)n",outfile);
  77. assert(0);
  78. return 0;
  79. }
  80. fwrite(&data[0], sizeof(short), sampleN, fpout);
  81. fclose(fpout);
  82. return 1;
  83. }
  84. void Fe::enhance_basic(short *sample, int sampleN, int samplingRate, int isWiener)
  85. {
  86. int t;
  87. Wiener wiener;
  88. wiener.Init(samplingRate, isWiener);
  89. float out[NR_MAX_WIN_SIZE];
  90. wiener.InitNewUtterance(0);
  91. int frameN=sampleN/wiener.m_shiftSize;
  92. int outN=0;
  93. for(t=0; ;t++){
  94. int i;
  95. int n=my_min(wiener.m_shiftSize,my_max(0,sampleN-t*wiener.m_shiftSize));
  96. FeReturnCode status;
  97. if(n>=wiener.m_shiftSize){
  98. status=wiener.OneFrame(sample+t*wiener.m_shiftSize, n, &out[0], t);
  99. }
  100. else{ /* feed in dummy frames */
  101. short tmpA[NR_MAX_WIN_SIZE];
  102. for(i=0;i<n;i++) tmpA[i]=sample[t*wiener.m_shiftSize+i];
  103. for(i=n;i<wiener.m_shiftSize;i++) tmpA[i]=0;
  104. status=wiener.OneFrame(tmpA, wiener.m_shiftSize, &out[0], t);
  105. }
  106. if(status==FE_NULL) continue;
  107. int r=my_min(wiener.m_shiftSize,my_max(0,sampleN-outN));
  108. assert(outN+r <= sampleN);
  109. for(i=0;i<r;i++){
  110. sample[outN+i]=(short)out[i];
  111. }
  112. outN+=r;
  113. if(outN>=sampleN) break;
  114. }
  115. #if 0
  116. wiener.SaveInput("test.input.raw",0);
  117. wiener.SaveDenoised("test.output1.raw",0);
  118. #endif
  119. wiener.Close();
  120. }
  121. Wiener::Wiener()
  122. {
  123. m_sampleRate=DEFAULT_SAMPLING_RATE;
  124. m_NumChannels=NR_NUM_CHANNELS;
  125. m_localFrameX=0;
  126. }
  127. Wiener::~Wiener()
  128. {
  129. }
  130. void Wiener::Close()
  131. {
  132. }
  133. int Wiener::GetSample(short *sample, int sampleN)
  134. {
  135. long startX=(m_inputEndX)%NR_BUF_SIZE;
  136. if(startX+sampleN <= NR_BUF_SIZE){
  137. memmove((char*)(m_inputSpeech+startX), sample, 2*(sampleN));
  138. }
  139. else{
  140. memmove((char*)(m_inputSpeech+startX), sample, 2*(NR_BUF_SIZE-startX));
  141. memmove((char*)(m_inputSpeech), sample+(NR_BUF_SIZE-startX), 2*(sampleN-NR_BUF_SIZE+startX));
  142. }
  143. m_inputEndX += sampleN;
  144. return sampleN;
  145. }
  146. int Wiener::Init(int samplingRate, int isWiener)
  147. {
  148. int i, kHz;
  149. m_isWiener=isWiener;
  150. m_sampleRate=samplingRate;
  151. /*-------------------------------------------------------------------*/
  152. /* Set parameters FrameLength, FrameShift and FFTLength              */
  153. /*-------------------------------------------------------------------*/
  154. kHz=(int)(m_sampleRate/1000.0+0.5);
  155. if (kHz == SAMPLING_FREQ_1) { /* 8 kHz */
  156. m_winSize = FRAME_LENGTH_1;
  157. m_shiftSize = FRAME_SHIFT_1;
  158. m_fftSize = FFT_LENGTH_1;
  159. }
  160. else if (kHz == SAMPLING_FREQ_2) { /* 11 kHz */
  161. m_winSize = FRAME_LENGTH_2;
  162. m_shiftSize = FRAME_SHIFT_2;
  163. m_fftSize = FFT_LENGTH_2;
  164. }
  165. else if (kHz == SAMPLING_FREQ_3) { /* 16 kHz */
  166. m_winSize = FRAME_LENGTH_3;
  167. m_shiftSize = FRAME_SHIFT_3;
  168. m_fftSize = FFT_LENGTH_3;
  169. }
  170. else {
  171. float shiftMs=10, winMs=25;
  172. m_winSize = (int)(winMs/1000*m_sampleRate);
  173. m_shiftSize = (int)(shiftMs/1000*m_sampleRate);
  174. m_fftSize = 1; while (m_fftSize<m_winSize) m_fftSize *= 2;
  175. }
  176. if(m_shiftSize>NR_MAX_FRAME_SHIFT){
  177. fprintf(stderr, "ERROR:   Too large frame shift size '%d'!rn", m_shiftSize);
  178. assert(0);
  179. return 0;
  180. }
  181. if(m_isWiener==1){
  182. m_specLength=m_fftSize/4+1;
  183. }
  184. else{
  185. m_specLength=m_fftSize/2+1;
  186. }
  187. m_inputEndX=0;
  188. #ifdef _DEBUG
  189. m_denEndX = 0;
  190. #endif
  191. m_localFrameX=0;
  192. /*-------------------------------------------------------*/
  193. /* Initialize Hanning window and scaling factor          */
  194. /*-------------------------------------------------------*/
  195. InitHanning(m_HanningWin, m_winSize);
  196. if(m_isWiener==1){
  197. m_bufStartX = m_shiftSize-20;
  198. InitHanning(m_HanningWin2, NR_FL);
  199. InitMelFilterBanks ((float)NR_STARTING_FREQ, (float)m_sampleRate, 2*(m_specLength-1), m_NumChannels);
  200. InitMelIDCTMatrix (m_melIdctMatrix, m_NumChannels);
  201. }
  202. /* amplitude scaling factor */
  203. m_scaleFactor=0;
  204. for(i=0;i<m_shiftSize;i++){
  205. float sum=0;
  206. for(int n=0;n+i<m_winSize;n+=m_shiftSize) sum += m_HanningWin[i+n];
  207. if(sum>m_scaleFactor) m_scaleFactor=sum;
  208. }
  209. /* over-subtraction factor */
  210. if(m_isWiener==0){
  211. m_oversubGain = 8;
  212. m_oversubCutoffFreq = 800;
  213. float fc=m_fftSize*m_oversubCutoffFreq/(float)m_sampleRate;
  214. for(i=0;i<m_specLength;i++){
  215. m_oversubFactor[i] = m_oversubGain/(1+i/fc);
  216. }
  217. }
  218.     return 1;
  219. }
  220. FeReturnCode Wiener::InitNewUtterance(const char *fname)
  221. {
  222. int i;
  223. m_inputEndX = 0;
  224. #ifdef _DEBUG
  225. m_denEndX = 0;
  226. #endif
  227. m_localFrameX=0;
  228. /* Wiener filter design */
  229. m_nbFrameX=1;
  230. /* VADNest */
  231. m_nbSpeechFrame=0;
  232. m_meanEn=0;
  233. m_flagVADNest=0;
  234. m_hangOver=0;
  235. m_nbFrameVADNest=0;
  236. for(i=0;i<m_specLength;i++){
  237. m_lastSpectrum2[i]=0;
  238. m_lastSpectrum[i]=0;
  239. m_sqrtNoisePSD[i]=(float)NR_EPS;
  240. m_sqrtDen3PSD[i]=0;
  241. }
  242. for(i=0;i<4*m_shiftSize;i++){
  243. m_buf_in[i]=0;
  244. m_buf_out[i]=0;
  245. }
  246. return FE_OK;
  247. }
  248. FeReturnCode Wiener::OneFrame(short *sample, int sampleN, float *out, int frameX)
  249. {
  250.     int i, k, extraFrameN;
  251. long startX=m_shiftSize*m_localFrameX;
  252. long validX;
  253. k=(m_winSize-m_shiftSize)/m_shiftSize;
  254. extraFrameN=((m_winSize-m_shiftSize)%m_shiftSize == 0 ? k : k+1);
  255. sampleN=GetSample(sample,sampleN);
  256. assert(m_localFrameX-frameX <= 4+extraFrameN);
  257. float si[NR_MAX_WIN_SIZE], so[NR_MAX_WIN_SIZE], den[NR_MAX_WIN_SIZE];
  258. FeReturnCode status;
  259. /* shift down one frame in the first buffer and insert a new frame */
  260. for(i=0;i<3*m_shiftSize;i++) m_buf_in[i]=m_buf_in[i+m_shiftSize];
  261. for(i=0;i<m_shiftSize;i++) m_buf_in[3*m_shiftSize+i]=(float)m_inputSpeech[(startX+i)%NR_BUF_SIZE];
  262. for(i=0;i<m_winSize;i++) si[i]=m_buf_in[i];
  263. if(m_isWiener==1){
  264. status=OneFrameWiener(si, so);
  265. }
  266. else{
  267. status=OneFrameSS(si, so);
  268. }
  269. if(status==FE_NULL){
  270. m_localFrameX++;
  271. return FE_NULL;
  272. }
  273. if(m_isWiener==0){
  274. /* overlap and save */
  275. for(i=0;i<3*m_shiftSize;i++) m_buf_out[i]=m_buf_out[i+m_shiftSize];
  276. for(i=0;i<m_shiftSize;i++) m_buf_out[3*m_shiftSize+i]=0;
  277. for(i=0;i<m_winSize;i++) m_buf_out[i]+=so[i];
  278. /* get the result */
  279. for(i=0;i<m_shiftSize;i++) den[i]=m_buf_out[i]/m_scaleFactor;
  280. }
  281. else{
  282. for(i=0;i<m_shiftSize;i++) den[i]=so[i];
  283. }
  284. /* save the denoised speech at the ring buffer */
  285. for(i=0;i<m_shiftSize;i++){
  286. m_outSpeech[(startX+i)%NR_OUT_BUF_SIZE]=den[i];
  287. }
  288. #ifdef _DEBUG
  289. /* save the denoised speech at the ring buffer */
  290. validX=startX-2*m_shiftSize;
  291. for(i=0;i<m_shiftSize;i++){
  292. m_denSpeech[(validX+i)%NR_BUF_SIZE]=(short)(den[i]);
  293. }
  294. #endif
  295. /* NR has 5 frame delay due to one buffer and extraFrameN delay to make one frame for feature extraction */
  296. if(m_localFrameX<5+extraFrameN){
  297. m_localFrameX++;
  298. return FE_NULL;
  299. }
  300. validX=startX-extraFrameN*m_shiftSize-((m_isWiener==1) ? 2*m_shiftSize : 0);
  301. for(i=0;i<m_winSize;i++) {
  302. out[i]=m_outSpeech[(validX+i)%NR_OUT_BUF_SIZE];
  303. }
  304. #ifdef _DEBUG
  305. m_denEndX += m_shiftSize;
  306. #endif
  307. m_localFrameX++;
  308. return FE_SPEECH;
  309. }
  310. FeReturnCode Wiener::OneFrameWiener(float *si, float *out)
  311. {
  312. VADNest(m_localFrameX, si);
  313. EstimateSpectrum(si, m_spec, m_spec_re, m_spec_im, 1);
  314. ComputeMeanPSD(m_spec, m_lastSpectrum, m_lastSpectrum2, m_flagVADNest, m_sqrtInPSD);
  315. if(m_localFrameX<2) {
  316. int i;
  317. for(i=0;i<m_winSize;i++) out[i]=si[i];
  318. return FE_NULL;
  319. }
  320. DesignWiener(m_localFrameX, m_flagVADNest, m_spec, m_sqrtInPSD, m_sqrtNoisePSD, m_sqrtDen3PSD, m_wienerFilter);
  321. if(m_isWiener==0){
  322. ApplyFilter(m_spec_re, m_spec_im, m_wienerFilter, out);
  323. }
  324. else{
  325. MelFilterBank(m_wienerFilter, m_H2mel);
  326. MelIDCT(m_H2mel, m_hWFmirr);
  327. assert(m_shiftSize-m_bufStartX > (NR_FL-1)/2);
  328. ApplyWiener(si+m_shiftSize-m_bufStartX, m_hWFmirr, m_hWFw, out);
  329. }
  330. return FE_SPEECH;
  331. }
  332. FeReturnCode Wiener::OneFrameSS(float *si, float *out)
  333. {
  334. EstimateSpectrum(si, m_spec, m_spec_re, m_spec_im, 0);
  335. ComputeMeanPSD(m_spec, m_lastSpectrum, m_lastSpectrum2, m_flagVADNest, m_sqrtInPSD);
  336. if(m_localFrameX<2) {
  337. int i;
  338. for(i=0;i<m_winSize;i++) out[i]=si[i];
  339. return FE_NULL;
  340. }
  341. DesignSpecsub(m_localFrameX, m_flagVADNest, m_spec, m_sqrtInPSD, m_sqrtNoisePSD, m_sqrtDen3PSD, m_ssFilter);
  342. ApplyFilter(m_spec_re, m_spec_im, m_ssFilter, out);
  343. return FE_SPEECH;
  344. }
  345. void Wiener::InitHanning (float *win, int len)
  346. {
  347.     int i;
  348.     for (i = 0; i < len; i++){
  349. win[i] = (float)(0.5 - 0.5 * cos (2 * M_PI * (i + 0.5)/len));
  350. }
  351. }
  352. void Wiener::EstimateSpectrum(float *s, float *spectrum, float *re, float *im, int subSample)
  353. {
  354. int i, n, m;
  355. float x[NR_MAX_WIN_SIZE];
  356. /* apply Hanning window */
  357. for(n=0;n<m_winSize;n++){
  358. re[n] = s[n]*m_HanningWin[n];
  359. im[n] = 0;
  360. }
  361. /* pad zeros */
  362. for(n=m_winSize;n<m_fftSize;n++){
  363. re[n]=0;
  364. im[n]=0;
  365. }
  366. /* do FFT */
  367. m = (int) (log10 (m_fftSize) / log10 (2));
  368. PRFFT_NEW(re, im, m, m_fftSize, 1);
  369. /* take power spectrum, P(bin)=|X(bin)|^2 */
  370. x[0] = re[0] * re[0];  /* DC */
  371. for (n = 1; n < m_fftSize / 2; n++) {
  372. x[n] = re[n] * re[n] + im[n] * im[n];
  373. }
  374. x[m_fftSize / 2] = re[m_fftSize / 2] * re[m_fftSize / 2];  /* pi/2 */
  375. if(subSample==1){
  376. /* smooth and subsample spectrum */
  377. assert(m_specLength==m_fftSize/4+1);
  378. for(i=0;i<m_fftSize/4;i++){
  379. spectrum[i]=(x[2*i]+x[2*i+1])/2;
  380. }
  381. spectrum[m_fftSize/4]=x[m_fftSize/2];
  382. }
  383. else{
  384. for(i=0;i<m_fftSize/2+1;i++){
  385. spectrum[i]=x[i];
  386. }
  387. }
  388. }
  389. void Wiener::ComputeMeanPSD(float *spectrum, float *lastSpectrum, float *lastSpectrum2, int flagVADNest, float *sqrtInPSD)
  390. {
  391. int i;
  392. for(i=0;i<m_specLength;i++){
  393. sqrtInPSD[i]=(float)sqrt((double)(lastSpectrum2[i]+lastSpectrum[i]+spectrum[i])/(double)3.0);
  394. lastSpectrum2[i]=lastSpectrum[i];
  395. lastSpectrum[i]=spectrum[i];
  396. }
  397. }
  398. void Wiener::DesignWiener(int t, int flagVADNest, const float *in, const float *sqrtInPSD, float *sqrtNoisePSD, float *sqrtDen3PSD, float *filter)
  399. {
  400. int i;
  401. float lambdaNSE;
  402. float sqrtDenPSD[NR_MAX_SPEC_LENGTH], sqrtDen2PSD[NR_MAX_SPEC_LENGTH];
  403. float sqrtEta[NR_MAX_SPEC_LENGTH], sqrtEta2[NR_MAX_SPEC_LENGTH], h[NR_MAX_SPEC_LENGTH];
  404. /* set the forgetting factor */
  405. if(t<NR_NB_FRAME_THRESHOLD_NSE)
  406. lambdaNSE=1-1/(float)(m_nbFrameX);
  407. else
  408. lambdaNSE=(float)NR_LAMBDA_NSE;
  409. if(t>=2) m_nbFrameX++;
  410. if(flagVADNest==0){ /* this is the result of the previous frame */
  411. for(i=0;i<m_specLength;i++){
  412. /* Update. Pnoise(tn)^0.5 = max(a * Pnoise(tn-1)^0.5 + (1-a) * Pin_PSD(tn)^0.5, EPS) */
  413. sqrtNoisePSD[i]=(float)my_max(lambdaNSE*sqrtNoisePSD[i]+(1-lambdaNSE)*sqrtInPSD[i], NR_EPS);
  414. }
  415. }
  416. else{
  417. /* No change. Pnoise(t)^0.5 = Pnoise(tn)^0.5 */
  418. }
  419. if(t>=2){
  420. /* Be careful about sqrt and square! */
  421. for(i=0;i<m_specLength;i++){
  422. sqrtDenPSD[i]=(float)(NR_BETA*sqrtDen3PSD[i]+(1-NR_BETA)*NR_T(sqrtInPSD[i]-sqrtNoisePSD[i]));
  423. sqrtEta[i]=sqrtDenPSD[i]/sqrtNoisePSD[i];
  424. h[i]=sqrtEta[i]/(1+sqrtEta[i]);
  425. sqrtDen2PSD[i]=h[i]*(sqrtInPSD[i]);
  426. sqrtEta2[i]=my_max(sqrtDen2PSD[i]/sqrtNoisePSD[i], (float)NR_ETA_TH);
  427. filter[i]=sqrtEta2[i]/(1+sqrtEta2[i]);
  428. sqrtDen3PSD[i]=(float)(filter[i]*sqrt(in[i]));
  429. }
  430. }
  431. }
  432. void Wiener::DesignSpecsub(int t, int flagVADNest, const float *in, const float *sqrtInPSD, float *sqrtNoisePSD, float *sqrtDen3PSD, float *filter)
  433. {
  434. int i;
  435. float lambdaNSE;
  436. float s, n;
  437. float globalFac;
  438. /* set the forgetting factor */
  439. if(t<NR_NB_FRAME_THRESHOLD_NSE)
  440. lambdaNSE=1-1/(float)(m_nbFrameX);
  441. else
  442. lambdaNSE=(float)NR_LAMBDA_NSE;
  443. if(t>=2) m_nbFrameX++;
  444. if(flagVADNest==0 && t<NR_NB_FRAME_THRESHOLD_NSE){ /* this is the result of the previous frame */
  445. for(i=0;i<m_specLength;i++){
  446. sqrtNoisePSD[i]=(float)sqrt(my_max(lambdaNSE*NR_SQ(sqrtNoisePSD[i])
  447. +(1-lambdaNSE)*(in[i]-NR_SQ(sqrtDen3PSD[i])), NR_EPS*NR_EPS));
  448. }
  449. }
  450. else{
  451. /* No change. Pnoise(t)^0.5 = Pnoise(tn)^0.5 */
  452. }
  453. if(t<2) return;
  454. /* compute filter with over-subtraction */
  455. s=0, n=0;
  456. for(i=0;i<m_specLength;i++){
  457. s+=NR_SQ(sqrtInPSD[i]); n+=NR_SQ(sqrtNoisePSD[i]);
  458. }
  459. s/=m_specLength; n/=m_specLength;
  460. globalFac=my_max(n/s,(float)NR_SS_TH);
  461. for(i=0;i<m_specLength;i++){
  462. float instSNR = NR_SQ(sqrtNoisePSD[i])/(NR_SQ(sqrtNoisePSD[i])+NR_SQ(sqrtInPSD[i]));
  463. float instSN = NR_SQ(sqrtNoisePSD[i])/NR_SQ(sqrtInPSD[i]+(float)1e-20);
  464. filter[i] = (float)sqrt(my_max(1-(1+m_oversubFactor[i]*instSNR)*instSN, (float)NR_SS_TH*NR_SS_TH*instSN));
  465. sqrtDen3PSD[i]=(float)(filter[i]*sqrt(in[i]));
  466. }
  467. return;
  468. }
  469. void Wiener::VADNest(int t, const float *s)
  470. {
  471. int i;
  472. float lambdaLTE, lambdaLTEhigherE=(float)0.99;
  473. float frameEn=0, mean=0;
  474. int M=2*m_shiftSize; /* changed to get smooth estimate */
  475. if(t<NR_NB_FRAME_THRESHOLD_LTE)
  476. lambdaLTE=1-1/(float)(m_nbFrameVADNest+1);
  477. else
  478. lambdaLTE=(float)NR_LAMBDA_LTE;
  479. for(i=0;i<M;i++) {
  480. frameEn += s[i]*s[i];
  481. mean += s[i];
  482. }
  483. frameEn = frameEn - mean*mean/M; /* owkwon: Use the AC energy only */
  484. frameEn = frameEn*80/(float)M; /* owkwon: normalize to a value for 80 samples */
  485. if(t>=2 && frameEn>0) { /* Start updating after only valid non-zero data */
  486. m_nbFrameVADNest++;
  487. }
  488. frameEn = (float)(0.5+16/log(2)*log((64+frameEn)/64)); /* 16/log(2) ~ 23.08 */
  489. if(frameEn<NR_ENERGY_FLOOR) frameEn=NR_ENERGY_FLOOR; /* to avoid the worst case of all-zero data */
  490. if(m_nbFrameVADNest==1){
  491. m_meanEn=frameEn; /* first non-zero frame */
  492. }
  493. if(frameEn-m_meanEn<NR_SNR_THRESHOLD_NO_UPD_LTE && (frameEn-m_meanEn < NR_SNR_THRESHOLD_UPD_LTE || t < NR_MIN_FRAME)){
  494. if(frameEn<m_meanEn || t<NR_MIN_FRAME)
  495. m_meanEn = m_meanEn + (1-lambdaLTE)*(frameEn-m_meanEn);
  496. else
  497. m_meanEn = m_meanEn + (1-lambdaLTEhigherE)*(frameEn-m_meanEn);
  498. if(m_meanEn<NR_ENERGY_FLOOR) m_meanEn=NR_ENERGY_FLOOR;
  499. }
  500. if(m_nbFrameVADNest>0 && frameEn-m_meanEn>=NR_SNR_THRESHOLD_NO_UPD_LTE){ /* owkwon:  */
  501. m_flagVADNest=1;
  502. m_nbSpeechFrame++;
  503. }
  504. else if(frameEn-m_meanEn > NR_SNR_THRESHOLD_VAD && t>=NR_MIN_FRAME){ /* owkwon: changed the inquality sign to '>' */
  505. m_flagVADNest=1;
  506. m_nbSpeechFrame++;
  507. }
  508. else{
  509. if((m_nbSpeechFrame < NR_MIN_SPEECH_FRAME_HANGOVER) && (m_nbSpeechFrame >= 2)){ /* owkwon: added the condition '&& (m_nbSpeechFrame >= 2)' */
  510. m_hangOver=NR_HANGOVER;
  511. }
  512. m_nbSpeechFrame=0;
  513. if(m_hangOver != 0){
  514. m_hangOver=m_hangOver-1;
  515. m_flagVADNest=1;
  516. }
  517. else{
  518. m_flagVADNest=0;
  519. }
  520. }
  521. }
  522. void Wiener::ApplyFilter(float *re, float *im, float *h, float *out)
  523. {
  524. int i;
  525. re[0] *= h[0]; im[0] = 0;
  526. for(i=1;i<m_fftSize/2;i++){
  527. re[i] *= h[i]; im[i] *= h[i];
  528. re[m_fftSize-i] = re[i]; im[m_fftSize-i] = -im[i];
  529. }
  530. re[m_fftSize/2] = 0;
  531. int m = (int) (log10 (m_fftSize) / log10 (2));
  532. PRFFT_NEW(re,im,m,m_fftSize,-1);
  533. for(i=0;i<m_winSize;i++){
  534. out[i]=re[i];
  535. }
  536. }
  537. #ifdef _DEBUG
  538. int Wiener::SaveInput(const char *fname, int offsetX)
  539. {
  540. int i, sampleN;
  541. int endX=my_max(0,m_inputEndX-offsetX*m_shiftSize);
  542. FILE *fp=fopen(fname,"wb");
  543. if(fp==0){
  544. assert(0);
  545. }
  546. sampleN=my_min(NR_BUF_SIZE,endX);
  547. for(i=endX-sampleN;i<endX;i++){
  548. fwrite((char*)(&m_inputSpeech[i%NR_BUF_SIZE]), sizeof(short), 1, fp);
  549. }
  550. fclose(fp);
  551. return 1;
  552. }
  553. int Wiener::SaveDenoised(const char *fname, int offsetX)
  554. {
  555. int i, sampleN;
  556. FILE *fp=fopen(fname,"wb");
  557. if(fp==0){
  558. assert(0);
  559. }
  560. int endX=m_inputEndX-offsetX*m_shiftSize;
  561. sampleN=my_min(NR_BUF_SIZE,endX);
  562. for(i=endX-sampleN;i<endX;i++){
  563. short s=m_denSpeech[i%NR_BUF_SIZE];
  564. fwrite((char*)&s, sizeof(short), 1, fp);
  565. }
  566. fclose(fp);
  567. return 1;
  568. }
  569. #endif
  570. void Wiener::MelFilterBank(float *h2, float *h2mel)
  571. {
  572. int i,k;
  573. for(k=0;k<=m_NumChannels+1;k++){
  574. WfMelFB *melFB=&m_MelFB[k];
  575. float sum = h2[melFB->m_centerX]; /* The center weight is always 1 */
  576. for(i=melFB->m_lowX;i<melFB->m_centerX;i++){
  577. sum += m_MelWeight[i]*h2[i];
  578. }
  579. for(i=melFB->m_centerX+1;i<=melFB->m_highX;i++){
  580. sum += (1-m_MelWeight[i])*h2[i];
  581. }
  582. h2mel[k]=sum/melFB->m_sumWeight;
  583. }
  584. }
  585. void Wiener::MelIDCT(float *h2mel, float *hWFmirr)
  586. {
  587. int n,k;
  588. float hWF[NR_NUM_CHANNELS+2];
  589. for(n=0;n<=NR_NUM_CHANNELS+1;n++){
  590. float sum=0;
  591. for(k=0;k<=NR_NUM_CHANNELS+1;k++)
  592. sum += h2mel[k]*m_melIdctMatrix[k*(NR_NUM_CHANNELS+2)+n];
  593. hWF[n]=sum;
  594. }
  595. for(n=0;n<=NR_NUM_CHANNELS+1;n++)
  596. hWFmirr[n]=hWF[n];
  597. for(n=NR_NUM_CHANNELS+2;n<=2*(NR_NUM_CHANNELS+1);n++)
  598. hWFmirr[n]=hWF[2*(NR_NUM_CHANNELS+1)+1-n];
  599. }
  600. void Wiener::ApplyWiener(float *s, float *hWFmirr, float *hWFw, float *out)
  601. {
  602. int i,n;
  603. float hWFcaus[2*(NR_NUM_CHANNELS+1)+1];
  604. float hWFtrunc[NR_FL];
  605. int FL2=(NR_FL-1)/2;
  606. float fac=0;
  607. for(n=0;n<=NR_NUM_CHANNELS;n++)
  608. hWFcaus[n]=hWFmirr[n+NR_NUM_CHANNELS+1];
  609. for(n=NR_NUM_CHANNELS+1;n<=2*(NR_NUM_CHANNELS+1);n++)
  610. hWFcaus[n]=hWFmirr[n-NR_NUM_CHANNELS-1];
  611. for(n=0;n<=NR_FL-1;n++)
  612. hWFtrunc[n]=hWFcaus[n+NR_NUM_CHANNELS+1-FL2];
  613. for(n=0;n<=NR_FL-1;n++){
  614. hWFw[n]=m_HanningWin2[n]*hWFtrunc[n];
  615. fac += m_HanningWin2[n];
  616. }
  617. for(n=0;n<m_shiftSize;n++){
  618. float sum=0;
  619. for(i=-FL2; i<=FL2; i++) sum += hWFw[i+FL2]*s[n-i];
  620. out[n]=sum;
  621. }
  622. }
  623. /*---------------------------------------------------------------------------
  624. Initialize data structure for FFT windows (mel filter bank).
  625. Computes start (bin[k-1]), center (bin[k]) and end (bin[k+1]) points
  626. of each mel filter to FFT index.
  627. Input:
  628.    m_sampleRate     Sampling frequency
  629.    m_FFTLength    FFT length
  630.    m_NumChannels  Number of channels
  631. Output:
  632.   Initialized weights and mel filters
  633.  *---------------------------------------------------------------------------*/
  634. void Wiener::InitMelFilterBanks (float startingFrequency, float samplingRate, int fftLength, int numChannels)
  635. {
  636.     int i, k;
  637.     float freq[NR_NUM_CHANNELS+2];
  638. int bin[NR_NUM_CHANNELS+2];
  639. float start_mel, fs_per_2_mel;
  640.     /* Constants for calculation */
  641. freq[0] = startingFrequency;
  642.     start_mel = (float)(2595.0 * log10 (1.0 + startingFrequency / 700.0));
  643. bin[0] = Round(fftLength * freq[0] / samplingRate);
  644. freq[numChannels+1] = (float)(samplingRate / 2.0);
  645.     fs_per_2_mel = (float)(2595.0 * log10 (1.0 + (samplingRate / 2.0) / 700.0));
  646. bin[numChannels+1] = Round(fftLength * freq[numChannels+1] / samplingRate);
  647. /* Calculating mel-scaled frequency and the corresponding FFT-bin */
  648.     /* number for the lower edge of the band                          */
  649. for (k = 1; k <= numChannels; k++) {
  650.         freq[k] = (float)(700 * (pow (10, (start_mel + (float) k / (numChannels + 1) * (fs_per_2_mel - start_mel)) / 2595.0) - 1.0));
  651. bin[k] = Round(fftLength * freq[k] / samplingRate);
  652. }
  653. /* This part is never used to compute MFCC coefficients */
  654. /* but initialized for completeness                     */
  655. for(i = 0; i<bin[0]; i++){
  656. m_MelWeight[i]=0;
  657. }
  658. m_MelWeight[fftLength/2]=1;
  659. /* Initialize low, center, high indices to FFT-bin */
  660. m_MelFB[0].m_lowX=0;
  661. m_MelFB[0].m_centerX=bin[0];
  662. m_MelFB[0].m_highX=bin[1]-1;
  663. for (k = 1; k <= numChannels; k++) {
  664. m_MelFB[k].m_lowX=bin[k-1]+1;
  665. m_MelFB[k].m_centerX=bin[k];
  666. m_MelFB[k].m_highX=bin[k+1]-1;
  667. }
  668. m_MelFB[numChannels+1].m_lowX=bin[numChannels]+1;
  669. m_MelFB[numChannels+1].m_centerX=bin[numChannels+1];
  670. m_MelFB[numChannels+1].m_highX=bin[numChannels+1];
  671. for (k = 1; k <= numChannels+1; k++) {
  672. for(i = bin[k-1]; i<bin[k]; i++){
  673. m_MelWeight[i]=(i-bin[k-1])/(float)(bin[k]-bin[k-1]);
  674. }
  675.     }
  676. m_MelWeight[bin[numChannels+1]]=0;
  677. m_MelFB[0].m_sumWeight=(bin[1]-bin[0]+1)/(float)2;
  678. for (k=1;k<=numChannels;k++){
  679. m_MelFB[k].m_sumWeight=(bin[k+1]-bin[k-1])/(float)2;
  680. }
  681. m_MelFB[numChannels+1].m_sumWeight=(bin[numChannels+1]-bin[numChannels]+1)/(float)2;
  682.     return;
  683. }
  684. /*---------------------------------------------------------------------------
  685. Initializes matrix for IDCT computation (IDCT is implemented
  686. as matrix-vector multiplication). The DCT matrix is of size
  687. (numChannels+2)-by-(numChannels+2).
  688.  *---------------------------------------------------------------------------*/
  689. int Wiener::InitMelIDCTMatrix (float *idctMatrix, int numChannels)
  690. {
  691.     int k, n;
  692. float center[NR_NUM_CHANNELS+2], df[NR_NUM_CHANNELS+2];
  693. float fac=m_sampleRate/(float)(2*(m_specLength-1));
  694. center[0]=0;
  695. center[NR_NUM_CHANNELS+1]=m_sampleRate/(float)2;
  696. for(k=1;k<=NR_NUM_CHANNELS;k++){
  697. int i;
  698. WfMelFB *melFB=&m_MelFB[k];
  699. float sum = (float)melFB->m_centerX;  /* The center weight is always 1 */
  700. for(i=melFB->m_lowX;i<melFB->m_centerX;i++) sum += m_MelWeight[i]*i;
  701. for(i=melFB->m_centerX+1;i<=melFB->m_highX;i++) sum += (1-m_MelWeight[i])*i;
  702. center[k]=sum*fac/melFB->m_sumWeight; /* owkwon: Use normalized W(k,i) */
  703. }
  704. df[0]=(center[1]-center[0])/(float)m_sampleRate;
  705. for(k=1;k<=NR_NUM_CHANNELS;k++){
  706. df[k]=(center[k+1]-center[k-1])/(float)m_sampleRate;
  707. }
  708. df[NR_NUM_CHANNELS+1]=(center[NR_NUM_CHANNELS+1]-center[NR_NUM_CHANNELS])/(float)m_sampleRate;
  709.     for (k = 0; k < numChannels+2; k++){
  710.         for (n = 0; n < numChannels+2; n++)
  711.             idctMatrix[k*(numChannels+2)+n] = (float) cos ((2*M_PI*n*center[k])/(float)m_sampleRate) * df[k];
  712. }
  713. return 1;
  714. }