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

语音合成与识别

开发平台:

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 "FE_feature.h"
  10. #include <limits.h>
  11. #include <math.h>
  12. #include <assert.h>
  13. /*-----------------------------------------------
  14. * Definition of End-point Detection parameters 
  15. *----------------------------------------------*/
  16. #ifndef DEFAULT_SAMPLING_RATE
  17. #define DEFAULT_SAMPLING_RATE       16000
  18. #endif
  19. #define DEFAULT_LONG_PAUSE_IN_MS      100 /* default duration of long-pause in millisecond (=100 ms) (changed for kWaves) */
  20. /* For provision when threre is no speech detected */
  21. #define EPD_OUTPUT_ALWAYS         1 /* write speech even if no speech is detected in order to satisfy the speech recognizer. */
  22. #define EPD_DUMMY_FRAMES                1 /* number of frames to be added when no speech is detected. */
  23. #define EPD_MULTIPLE_END_POINT          1 /* detect multiple speech segments (changed for kWaves) */
  24. /* Use terminology in the Aurora-3 VADNest */
  25. #define EPD_NB_FRAME_THRESHOLD_LTE     10
  26. #define EPD_LAMBDA_LTE               0.97
  27. #define EPD_SNR_THRESHOLD_UPD_LTE       4 /* in dB scale <-- 20 */
  28. #define EPD_MIN_FRAME                  10
  29. /* The minimum power of noise and speech are assumed as 14.5 and 37.5,
  30. which roughly correspond to the amplitude levels of 5 and 71. */
  31. #define EPD_NOISE_ENERGY_FLOOR       14.5 /* ~ 0.5+10*log10(5*5) */
  32. #define EPD_SPEECH_ENERGY_FLOOR      37.5 /* ~ 0.5+10*log10(71*71) */
  33. #define EPD_NOISE_CLEAN              30.5 /* */
  34. /* Input frame is decided as speech if the difference between the log frame energy
  35.    and the log mean energy exceeds the following threshold. The thresholds 40 and 48
  36.    denote that the log frame energy of speech is 6 and 8 times larger than the log 
  37.    mean energy, respectively. Note that the threshold is 15 in the Aurora-3 VADNest. */
  38. /* high noise case: internal microphone */
  39. /* The threshold should be optimized later for the target environment. */
  40. #define EPD_LOW_SNR                    10 /* */
  41. #define EPD_LOW_SNR_ENERGY_TH          12 /* ~ 10*log10(4*4) (changed for kWaves) */
  42. #define EPD_LOW_SNR_ZCR_TH             30 /* */
  43. /* low noise case: headset microphone */
  44. /* We increase the threshold in the denosing case because the input signals have been 
  45.    denoised in the preceding noise reduction module and therefore have larger SNR. */
  46. #define EPD_HIGH_SNR                   20 /* (changed for kWaves) */
  47. #define EPD_HIGH_SNR_ENERGY_TH         20 /* ~ 10*log10(10*10). (changed for kWaves) */
  48. #define EPD_HIGH_SNR_ZCR_TH             4 /* */
  49. /* Update signal energy if frame energy is larger than mean by this value in dB scale */
  50. #define EPD_SNR_THRESHOLD_UPD_SIGNAL_EN    10
  51. #define EPD_LAMBDA_SIGNAL_EN             0.95
  52. #define EPD_LAMBDA_ZCR                   0.98
  53. #define EPD_SPEECH_END_ENERGY_OFFSET        6 /* threshold decrease at the speech end */
  54. #define EPD_ZCR_THRESHOLD_UPD_LTE          20 /* threshold to update mean ZCR */
  55. /*---------------------
  56.  * local variables
  57.  *---------------------*/
  58. static int g_longPauseInMs = 0;
  59. bool Fe::EpdMain(const char *inputfile, int sampleRate, const char *outputfile)
  60. {
  61. FILE *fi;
  62. if( (fi = fopen(inputfile, "rb")) == NULL)
  63. return 0;
  64. fseek(fi,0L,SEEK_END);
  65. int fsize = ftell(fi);
  66. rewind(fi);
  67. vector<short> sample(fsize/sizeof(short));
  68. int sampleN = FREAD(&sample[0],sizeof(short),fsize/sizeof(short),fi);
  69. vector<CSegment> endPointA;
  70. if(!epd_basic(&sample[0], sampleN, sampleRate, endPointA)){
  71. fclose(fi);
  72. return false;
  73. }
  74. FILE *fo = fopen(outputfile, "wb");
  75. if(!fo){
  76. fprintf(stderr, "Cannot open %sn", outputfile);
  77. fclose(fi);
  78. return false;
  79. }
  80. fprintf(fo, "#LABELn");
  81. for(int i=0; i<endPointA.size(); i++){
  82. fprintf(fo,"%f -1 %sn",endPointA[i].m_fSegment, endPointA[i].m_szLabel.c_str());
  83. }
  84. fclose(fi);
  85. fclose(fo);
  86. return true;
  87. }
  88. int Fe::epd_basic(short *sampleA, int sampleN, int sampleRate, vector<CSegment>& endPointA)
  89. {
  90. int i,t,frameX;
  91. Epd epd;
  92. epd.Init(sampleRate,0,1,1);
  93. epd.InitNewUtterance();
  94. vector<float> in(epd.m_config.m_winSize);
  95. vector<float> out(epd.m_config.m_winSize);
  96. int frameSize=epd.m_config.m_winSize;
  97. int shiftSize=epd.m_config.m_shiftSize;
  98. int frameN=(int)((sampleN-(frameSize-shiftSize))/float(shiftSize));
  99. float period=epd.m_config.m_shiftSize/(float)sampleRate;
  100. FeReturnCode prevStatus=FE_NULL;
  101. int prevEndPt=-1;
  102. frameX=0;
  103. for(t=0;;t++){
  104. if(t>frameN) break;
  105. FeReturnCode inStatus;
  106. EpdFrameKind frameKind;
  107. if(t<frameN) {
  108. inStatus=FE_SPEECH;
  109. for(i=0;i<frameSize;i++) in[i]=sampleA[t*shiftSize+i];
  110. }
  111. else{ /* t==frameN */
  112. inStatus=FE_EOF;
  113. }
  114. FeReturnCode status=epd.OneFrame(&in[0], &out[0], frameX, frameSize, inStatus, &frameKind);
  115. if(status==FE_NULL || status==FE_WAITING){
  116. continue;
  117. }
  118. if(((prevStatus==FE_SPEECH) && (status==FE_END_POINT||status==FE_PAUSE)) || t==frameN){
  119. if(prevEndPt<epd.m_uttBeginX && epd.m_uttBeginX<epd.m_uttEndX){
  120. epd_insert_endpoint(endPointA,epd.m_uttBeginX*period,epd.m_uttEndX*period);
  121. prevEndPt=epd.m_uttEndX;
  122. }
  123. }
  124. prevStatus=status;
  125. frameX++;
  126. }
  127. return endPointA.size();
  128. }
  129. bool Fe::epd_insert_endpoint(vector<CSegment>& endPointA, float startPt, float endPt)
  130. {
  131. CSegment segment;
  132. segment.m_fSegment = startPt;
  133. segment.m_szLabel = "1";
  134. endPointA.push_back(segment);
  135. segment.m_fSegment = endPt;
  136. segment.m_szLabel = "0";
  137. endPointA.push_back(segment);
  138. return true;
  139. }
  140. Epd::Epd()
  141. {
  142. ParmInit(&m_config, DEFAULT_SAMPLING_RATE, 1);
  143. m_absTimeX=0;  /* initialized only once */
  144. }
  145. int Epd::ParmInit(EpdParm *epdParm, int samplingRate, int isDenoised)
  146. {
  147. epdParm->m_sampleRate=samplingRate;
  148. if(samplingRate==8000){
  149. epdParm->m_shiftSize        =    80; /* 10 ms. Should be same as frameShift in feature extraction */
  150. epdParm->m_winSize          =   200; /* 25 ms. */
  151. }
  152. else if(samplingRate==11025 || samplingRate==11000){
  153. epdParm->m_shiftSize        =   110; /* 10 ms. Should be same as frameShift in feature extraction */
  154. epdParm->m_winSize          =   256; /* 23.27 ms. */
  155. }
  156. else if(samplingRate==16000){
  157. epdParm->m_shiftSize        =   160; /* 10 ms. Should be same as frameShift in feature extraction */
  158. epdParm->m_winSize          =   400; /* 25 ms. */
  159. }
  160. else{
  161. float shiftMs=10, winMs=25;
  162. epdParm->m_winSize = (int)(winMs/1000*epdParm->m_sampleRate);
  163. epdParm->m_shiftSize = (int)(shiftMs/1000*epdParm->m_sampleRate);
  164. }
  165. epdParm->m_threshFrameN         =  EPD_NB_FRAME_THRESHOLD_LTE; /* 100 ms for determining thresholds (<= m_startSilenceFrameN) */
  166. epdParm->m_startFrameN          =    10; /* 100 ms for speech start detection */
  167. epdParm->m_startSilenceFrameN   =     0; /* add 0 ms of silence before speech start (<= epdParm->m_startFrameN) (changed for kWaves) */
  168. epdParm->m_endFrameN            =    30; /* 300 ms for pause detection */
  169. epdParm->m_endSilenceFrameN     =     5; /* add 50 ms of silence after speech end (changed for kWaves) */
  170. if(g_longPauseInMs>0){
  171. epdParm->m_longPauseFrameN  = g_longPauseInMs/10;
  172. }
  173. else{
  174. epdParm->m_longPauseFrameN  = DEFAULT_LONG_PAUSE_IN_MS/10; /* 500 ms of silence for speech end detection (<= m_endSilenceFrameN) */
  175. }
  176. return 1;
  177. }
  178. int Epd::Init(int samplingRate, int isAudio, int isActive, int isDenoised)
  179. {
  180. m_isAudio=isAudio;
  181. m_isActive=isActive;
  182. ParmInit(&m_config, samplingRate, isDenoised);
  183. m_uttBeginX=0;
  184. m_uttEndX=0;
  185. m_localStatus=EPD_STATUS_WAITING;
  186. m_localFrameX=0;
  187. m_sampleEndX=0;
  188. m_absTimeX=0;  /* initialized only once */
  189. /* initial values defined in the Aurora-3 VADNest */
  190. m_lambdaLTE=(float)EPD_LAMBDA_LTE;
  191. m_lambdaLTEhigherE=(float)0.99;
  192. m_lambdaSignalE=(float)EPD_LAMBDA_SIGNAL_EN;
  193. m_nbSpeechFrame=0;
  194. m_noiseEn=0;
  195. m_signalEn=0;
  196. m_meanZcr=0;
  197. m_lastSnr = (EPD_HIGH_SNR+EPD_LOW_SNR)/2;
  198. m_flagVAD=EPD_FK_SILENCE;
  199. return 1;
  200. }
  201. void Epd::SetMaxPause(int msec)
  202. {
  203. if(msec>EPD_MAX_PAUSE_IN_MS){
  204. fprintf(stderr, "[ERROR] Too large pause duration. Must be less than %dn",EPD_MAX_PAUSE_IN_MS);
  205. assert(0);
  206. }
  207. g_longPauseInMs = msec;
  208. }
  209. Epd::~Epd()
  210. {
  211. }
  212. int Epd::InitNewUtterance()
  213. {
  214. int i;
  215. for(i=0;i<EPD_FRAME_BUF_SIZE;i++) m_isSpeechA[i]=(EpdFrameKind)(-1);
  216. for(i=0;i<EPD_FRAME_BUF_SIZE;i++) m_zcrA[i]=0;
  217. m_localStatus=EPD_STATUS_WAITING;
  218. m_uttBeginX = 0;
  219. m_uttEndX = 0;
  220. m_localFrameX = 0;
  221. m_sampleEndX = 0;
  222. m_speechSegN = 0;
  223. return 1;
  224. }
  225. int Epd::PutSample(float *sampleA, int sampleN)
  226. {
  227. int i;
  228. for(i=0;i<sampleN;i++){
  229. m_epdSpeech[(m_sampleEndX)%EPD_SPEECH_BUF_SIZE]=(short)sampleA[i];
  230. m_sampleEndX=(m_sampleEndX+1)%EPD_SPEECH_BUF_SIZE;
  231. }
  232. return sampleN;
  233. }
  234. void EpdClose(Epd *epd)
  235. {
  236. }
  237. /* This algorithm is complicated for now and I need more elegant way of endpoint detection. */
  238. FeReturnCode Epd::OneFrame(float *in, float *out, int frameX, int winSize, FeReturnCode inStatus, EpdFrameKind *frameKind)
  239. {
  240. int i;
  241. int frameShift=m_config.m_shiftSize;
  242. int maxDataN=EPD_MAX_RECORD_TIME*m_config.m_sampleRate;
  243. if(m_localFrameX==0) PutSample(in,winSize);
  244. else                 PutSample(in+my_max(0,winSize-frameShift),frameShift);
  245. *frameKind=EPD_FK_SILENCE;
  246. if(m_isActive==0){
  247. if(inStatus==FE_EOF){
  248. m_uttEndX=m_localFrameX;
  249. return FE_END_POINT; /* end-point detected */
  250. }
  251. else{
  252. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[(m_localFrameX*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  253. *frameKind=OneFrame(in);
  254. m_uttEndX=m_localFrameX;
  255. return FE_SPEECH; /* in-speech */
  256. }
  257. }
  258. if(inStatus==FE_EOF && frameX+m_uttBeginX+m_config.m_startFrameN >= m_uttEndX){
  259. if(m_isSpeechA[(m_localFrameX-1)%EPD_FRAME_BUF_SIZE]==EPD_FK_SPEECH && m_isSpeechA[(m_localFrameX-2)%EPD_FRAME_BUF_SIZE]==EPD_FK_SPEECH){
  260. /* printf("n"); Error("Epd","[ERROR] EOF found in the middle of speechn"); */
  261. return FE_EARLY_END;
  262. }
  263. else if(m_isAudio==0 && EPD_OUTPUT_ALWAYS && (m_uttBeginX>m_uttEndX || m_speechSegN<1)){
  264. /* Because subsequent frames are all assumed silence, I regard the frame after the last speech as the end-point. */
  265. m_isSpeechA[m_localFrameX%EPD_FRAME_BUF_SIZE]=EPD_FK_SILENCE;
  266. for(i=m_localFrameX-3;i>=m_localFrameX-m_config.m_endFrameN+1 && i>=0;i--){
  267. if(m_isSpeechA[i%EPD_FRAME_BUF_SIZE]==EPD_FK_SPEECH) break;
  268. }
  269. /* Let's make the speech recognizer happy by making one-frame dummy speech */
  270. if(m_uttEndX<m_uttBeginX+EPD_DUMMY_FRAMES){
  271. m_uttEndX=m_uttBeginX+EPD_DUMMY_FRAMES;
  272. }
  273. m_localStatus=EPD_STATUS_ENDPOINT;
  274. m_uttEndX=my_max(0,my_min(m_localFrameX,(i+1)+m_config.m_endSilenceFrameN));
  275. if(m_speechSegN==0) m_speechSegN++;
  276. /* printf("EPD: Endpoint detected (begin=%d, end=%d)n",m_uttBeginX,m_uttEndX); */
  277. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  278. return FE_END_POINT; /* in-speech */
  279. }
  280. else if(m_localStatus==EPD_STATUS_WAITING){
  281. /* printf("n"); Error("Epd","[ERROR] No speechn"); */
  282. return FE_NO_SPEECH;
  283. }
  284. }
  285. if(m_localStatus==EPD_STATUS_WAITING){
  286. /* find begin-point */
  287. /* printf("EPD: Searching for speech...n"); */
  288. *frameKind=OneFrame(in);
  289. if(FindBeginPoint(m_localFrameX-1)) {
  290. /* Add extra frames before the speech start-point of localFrameX-startFrameN */
  291. m_uttBeginX=my_max(0,(m_localFrameX-m_config.m_startFrameN-m_config.m_startSilenceFrameN+1));
  292. m_uttEndX=m_localFrameX;
  293. m_localStatus=EPD_STATUS_SPEECH;
  294. /* printf("EPD: Speech detected (begin=%d)n",m_uttBeginX); */
  295. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  296. return FE_SPEECH; /* in-speech */
  297. }
  298. else{
  299. return FE_WAITING;
  300. }
  301. }
  302. else if(m_localStatus==EPD_STATUS_SPEECH){
  303. if(inStatus==FE_EOF){
  304. /* Because subsequent frames are all assumed silence, I regard the frame after the last speech as the end-point. */
  305. m_isSpeechA[m_localFrameX%EPD_FRAME_BUF_SIZE]=EPD_FK_SILENCE;
  306. for(i=m_localFrameX-3;i>=m_localFrameX-m_config.m_endFrameN+1 && i>=0;i--){
  307. if(m_isSpeechA[i%EPD_FRAME_BUF_SIZE]==EPD_FK_SPEECH) break;
  308. }
  309. m_localStatus=EPD_STATUS_PAUSE;
  310. m_uttEndX=my_max(0,my_min(m_localFrameX,(i+1)+m_config.m_endSilenceFrameN));
  311. /* printf("EPD: Endpoint detected (begin=%d, end=%d)n",m_uttBeginX,m_uttEndX); */
  312. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  313. return FE_SPEECH; /* in-speech */
  314. }
  315. /* prepare to detect end-point */
  316. if(m_localFrameX<m_uttBeginX+m_config.m_endFrameN-1){
  317. *frameKind=OneFrame(in);
  318. return FE_NULL;
  319. }
  320. *frameKind=OneFrame(in);
  321. if(FindEndPoint(m_localFrameX-1, m_config.m_endFrameN)) {
  322. m_uttEndX=m_localFrameX-m_config.m_endFrameN;
  323. m_localStatus=EPD_STATUS_PAUSE;
  324. m_uttEndX=m_uttEndX+my_max(0,m_config.m_endSilenceFrameN-m_config.m_endFrameN);
  325. /* printf("EPD: Endpoint detected (begin=%d, end=%d)n",m_uttBeginX,m_uttEndX); */
  326. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  327. return FE_SPEECH; /* in-speech */
  328. }
  329. else{
  330. m_uttEndX=m_localFrameX;
  331. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  332. return FE_SPEECH; /* in-speech */
  333. }
  334. }
  335. else if(m_localStatus==EPD_STATUS_PAUSE){
  336. if(inStatus!=FE_EOF){
  337. *frameKind=OneFrame(in);
  338. }
  339. if(FindBeginPoint(m_localFrameX-1)) {
  340. m_uttEndX=m_localFrameX;
  341. m_localStatus=EPD_STATUS_SPEECH;
  342. /* printf("EPD: Speech detected again (begin=%d)n",m_localFrameX); */
  343. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  344. return FE_SPEECH; /* in-speech */
  345. }
  346. else if(m_localFrameX<m_uttBeginX+m_config.m_longPauseFrameN-1){
  347. if(frameX+m_uttBeginX < m_uttEndX){
  348. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  349. return FE_SPEECH; /* in-speech */
  350. }
  351. else if(inStatus==FE_EOF){
  352. m_uttEndX=m_uttBeginX+frameX;
  353. m_speechSegN++;
  354. return FE_END_POINT; /* end-point */
  355. }
  356. else{
  357. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  358. return FE_PAUSE; /* pause */
  359. }
  360. }
  361. else{
  362. if(FindEndPoint(m_localFrameX-1, m_config.m_longPauseFrameN)) {
  363. m_localStatus=EPD_STATUS_ENDPOINT;
  364. if(m_uttEndX < m_uttBeginX+frameX){
  365. m_speechSegN++;
  366. /* printf("EPD: Endpoint detected (begin=%d, end=%d)n",m_uttBeginX,m_uttEndX); */
  367. return FE_END_POINT; /* end-point */
  368. }
  369. else{
  370. m_uttEndX=m_uttBeginX+frameX;
  371. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  372. return FE_SPEECH; /* in-speech */
  373. }
  374. }
  375. else{
  376. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  377. return FE_PAUSE; /* pause */
  378. }
  379. }
  380. }
  381. else if(m_localStatus==EPD_STATUS_ENDPOINT){
  382. if(m_uttBeginX+frameX < m_uttEndX){
  383. for(i=0;i<winSize;i++) out[i]=m_epdSpeech[((m_uttBeginX+frameX)*frameShift+i)%EPD_SPEECH_BUF_SIZE];
  384. return FE_SPEECH; /* in-speech */
  385. }
  386. else{
  387. if(EPD_MULTIPLE_END_POINT){
  388. m_uttBeginX=m_localFrameX;
  389. m_uttEndX=m_localFrameX;
  390. m_localStatus=EPD_STATUS_WAITING;
  391. return FE_WAITING; /* wait for another speech */
  392. }
  393. else{
  394. m_speechSegN++;
  395. return FE_END_POINT; /* end-point */
  396. }
  397. }
  398. }
  399. else{
  400. assert(0);
  401. return FE_UNK_ERROR; /* unknown error */
  402. }
  403. return FE_UNK_ERROR; /* unknown error */
  404. }
  405. int Epd::FindBeginPoint(int endX) {
  406. int i, sum=0;
  407. assert(m_isSpeechA[endX%EPD_FRAME_BUF_SIZE] != -1);
  408. assert(m_localStatus==EPD_STATUS_WAITING || m_localStatus==EPD_STATUS_PAUSE);
  409. if(endX<m_config.m_startFrameN) return 0;
  410. for(i=endX;i>=endX-m_config.m_startFrameN+1;i--){ /* look back startFrameN frames */
  411. sum += (int)m_isSpeechA[i%EPD_FRAME_BUF_SIZE];
  412. }
  413. if(m_isSpeechA[endX%EPD_FRAME_BUF_SIZE]==EPD_FK_SPEECH && sum>=m_config.m_startFrameN-2) {
  414. /* Remove breath noise because it has low pitch frequency. */
  415. for(i=endX, sum=0;i>=endX-m_config.m_startFrameN+1;i--){
  416. if(m_zcrA[i%EPD_FRAME_BUF_SIZE] >= EPD_HIGH_SNR_ZCR_TH) sum++;
  417. }
  418. if(sum > m_config.m_startFrameN/2)
  419. return 1;
  420. else
  421. return 0;
  422. }
  423. else return 0;
  424. }
  425. int Epd::FindEndPoint(int endX, int reqSilN) {
  426. int i, sum=0;
  427. assert(m_isSpeechA[endX%EPD_FRAME_BUF_SIZE] != -1);
  428. assert(m_localStatus==EPD_STATUS_SPEECH || m_localStatus==EPD_STATUS_PAUSE);
  429. for(i=endX;i>=endX-reqSilN+1;i--){  /* look back endFrameN frames */
  430. sum += (int)m_isSpeechA[i%EPD_FRAME_BUF_SIZE];
  431. }
  432. if(m_isSpeechA[endX%EPD_FRAME_BUF_SIZE]==EPD_FK_SILENCE && sum<=1) return 1;
  433. else return 0;
  434. }
  435. EpdFrameKind Epd::OneFrame(const float *s)
  436. {
  437. int i, N=m_config.m_winSize;
  438. float frameEn, frameEnTh, sum, zcr, prev, snrEn, zcrTh;
  439. float x[EPD_MAX_WIN_SIZE];
  440. if(m_localFrameX<EPD_NB_FRAME_THRESHOLD_LTE)
  441. m_lambdaLTE=1-1/(float)(m_localFrameX+1);
  442. else
  443. m_lambdaLTE=(float)EPD_LAMBDA_LTE;
  444. if(m_localFrameX<EPD_NB_FRAME_THRESHOLD_LTE)
  445. m_lambdaZcr=1-1/(float)(m_localFrameX+1);
  446. else
  447. m_lambdaZcr=(float)EPD_LAMBDA_ZCR;
  448. /*
  449. owkwon: Prevent DC level from drifting and high frquency babble noise from surviving noise reduction.
  450. Here a band-pass filter with pass band 500-2800 Hz is used by cascading H1(z)=1-z^(-1)
  451. and H2(z)=z+1-z^(-1). This filter may sometimes lose unvoiced frames like /s/ and /ch/.
  452. The output of the Mel FB in the noise reduction module can be used for this purpose
  453. as the Aurora-3 uses the 2nd, 3rd, 4th FB coefficients. A more elaborate method is needed here. 
  454. */
  455. if(1){
  456. /* DC offset removal, H(z)=(1-z^(-1))/(1-0.999*z^(-1)), y[i]=x[i]-x[i-1]+(1-1/1024)*y[i-1] */
  457. float x0=0, y0=0, a=(1-1/(float)1024);
  458. for (i=0; i<N; i++){
  459. y0 = (float)(x[i] - x0 + a * y0); x0 = x[i]; x[i] = y0; /* in-place output */
  460. }
  461. /* low-pass filtering, H(z)=[1 2 1]/4 */
  462. x[0]=(s[1]+2*s[0]+s[0])/4; x[N-1]=(s[N-1]+2*s[N-1]+s[N-2])/4;
  463. for(i=1;i<N-1; i++) {
  464. x[i]=(s[i+1]+2*s[i]+s[i-1])/4;
  465. }
  466. }
  467. for(i=0, sum=0; i<N; i++) {
  468. sum += x[i]*x[i];
  469. }
  470. frameEn = (float)(0.5+10/log(10)*log(1+sum/N));
  471. /*
  472. owkwon: Added the condition (frameEn < EPD_SPEECH_ENERGY_FLOOR) for babble noise.
  473. The babble noise is not removed completely by noise reduction; there exist
  474. residual speech-like signals.
  475. */
  476. if((frameEn-m_noiseEn)<EPD_SNR_THRESHOLD_UPD_LTE || m_localFrameX<EPD_MIN_FRAME || (frameEn < EPD_SPEECH_ENERGY_FLOOR)){
  477. if((frameEn<m_noiseEn) || (m_localFrameX<EPD_MIN_FRAME) || (frameEn < EPD_SPEECH_ENERGY_FLOOR)){
  478. m_noiseEn=m_noiseEn+(1-m_lambdaLTE)*(frameEn-m_noiseEn);
  479. }
  480. else{
  481. m_noiseEn=m_noiseEn+(1-m_lambdaLTEhigherE)*(frameEn-m_noiseEn);
  482. }
  483. if(m_noiseEn<EPD_NOISE_ENERGY_FLOOR) m_noiseEn=(float)EPD_NOISE_ENERGY_FLOOR;
  484. m_noiseLevel=(float)(2*sqrt(exp(log(10)/10*(m_noiseEn-0.5))-1));
  485. }
  486. if((frameEn-m_noiseEn)>EPD_SNR_THRESHOLD_UPD_SIGNAL_EN){
  487. if(m_localFrameX>=EPD_MIN_FRAME){
  488. m_signalEn=m_signalEn+(1-m_lambdaSignalE)*(frameEn-m_signalEn);
  489. }
  490. else{
  491. m_signalEn=m_noiseEn+EPD_SNR_THRESHOLD_UPD_SIGNAL_EN;
  492. }
  493. if(m_signalEn-m_noiseEn < m_lastSnr/2)
  494. m_signalEn = m_noiseEn + m_lastSnr/2;
  495. }
  496. else if(frameEn>m_signalEn){
  497. m_signalEn=frameEn+EPD_SNR_THRESHOLD_UPD_SIGNAL_EN;
  498. if(m_signalEn-m_noiseEn < m_lastSnr/2)
  499. m_signalEn = m_noiseEn + m_lastSnr/2;
  500. }
  501. prev = x[0]-m_noiseLevel;
  502. for(i=1, zcr=0; i<N; i++) {
  503. float val  = x[i]-m_noiseLevel;
  504. float ztmp=val*prev;
  505. if(ztmp<0) zcr++;
  506. prev=val;
  507. }
  508. if((zcr-m_meanZcr) < EPD_ZCR_THRESHOLD_UPD_LTE || m_localFrameX<EPD_MIN_FRAME){
  509. m_meanZcr=m_meanZcr+(1-m_lambdaZcr)*(zcr-m_meanZcr);
  510. }
  511. snrEn=m_signalEn-m_noiseEn;
  512. {
  513. float slopeEn=(EPD_HIGH_SNR_ENERGY_TH-EPD_LOW_SNR_ENERGY_TH)/(float)(EPD_HIGH_SNR-EPD_LOW_SNR);
  514. float slopeZcr=(EPD_HIGH_SNR_ZCR_TH-EPD_LOW_SNR_ZCR_TH)/(float)(EPD_HIGH_SNR-EPD_LOW_SNR);
  515. frameEnTh=(float)(EPD_LOW_SNR_ENERGY_TH+slopeEn*(snrEn-EPD_LOW_SNR));
  516. if(m_localStatus==EPD_STATUS_SPEECH){
  517. frameEnTh = frameEnTh-EPD_SPEECH_END_ENERGY_OFFSET;
  518. }
  519. frameEnTh=my_max(EPD_LOW_SNR_ENERGY_TH,my_min(frameEnTh,EPD_HIGH_SNR_ENERGY_TH));
  520. zcrTh=(float)(EPD_LOW_SNR_ZCR_TH+slopeZcr*(snrEn-EPD_LOW_SNR));
  521. zcrTh=my_max(EPD_HIGH_SNR_ZCR_TH,my_min(zcrTh,EPD_LOW_SNR_ZCR_TH));
  522. }
  523. #if 0
  524. if(m_localFrameX%10==0){
  525. printf("%fn",snrEn);
  526. }
  527. #endif
  528. if(frameEn < EPD_SPEECH_ENERGY_FLOOR){
  529. m_flagVAD=EPD_FK_SILENCE;
  530. }
  531. else if(frameEn-m_noiseEn < EPD_LOW_SNR){
  532. m_flagVAD=EPD_FK_SILENCE;
  533. }
  534. else if((frameEn-m_noiseEn)>frameEnTh){
  535. m_flagVAD=EPD_FK_SPEECH;
  536. m_nbSpeechFrame=m_nbSpeechFrame+1;
  537. m_lastSnr=snrEn;
  538. }
  539. else{
  540. if(m_localFrameX>EPD_MIN_FRAME && m_noiseEn < EPD_NOISE_CLEAN && zcr-m_meanZcr >= zcrTh){
  541. m_flagVAD=EPD_FK_SPEECH;
  542. m_nbSpeechFrame=m_nbSpeechFrame+1;
  543. }
  544. else
  545. {
  546. m_flagVAD=EPD_FK_SILENCE;
  547. }
  548. }
  549. m_zcrA[m_localFrameX%EPD_FRAME_BUF_SIZE]=zcr;
  550. m_isSpeechA[m_localFrameX%EPD_FRAME_BUF_SIZE]=m_flagVAD;
  551. m_localFrameX++;
  552. m_absTimeX++;
  553. return m_flagVAD;
  554. }