/* CloneStream: return a clone of given stream */ MixtureVector CloneStream(HMMSet *hset, StreamElem *ste, Boolean sharing) { int m,M; MixtureElem *sme,*tme; MixtureVector mv; M = ste->nMix; if (hset->hsKind == PLAINHS || hset->hsKind == SHAREDHS){ tme = (MixtureElem *)New(hset->hmem,M*sizeof(MixtureElem)); mv.cpdf = tme-1; sme = ste->spdf.cpdf + 1; for (m=1; m<=M; m++,sme++,tme++){ tme->weight = sme->weight; tme->mpdf = (tme->weight>MINMIX)?CloneMixPDF(hset,sme->mpdf,sharing):NULL; } } else if (hset->hsKind == TIEDHS) { mv.tpdf = CreateVector(hset->hmem,M); CopyVector(ste->spdf.tpdf,mv.tpdf); } else { mv.dpdf = CreateShortVec(hset->hmem,M); CopyShortVec(ste->spdf.dpdf,mv.dpdf); } return mv; }
/* EXPORT->InitFBank: Initialise an FBankInfo record */ FBankInfo InitFBank(MemHeap *x, int frameSize, long sampPeriod, int numChans, float lopass, float hipass, Boolean usePower, Boolean takeLogs, Boolean doubleFFT, float alpha, float warpLowCut, float warpUpCut) { FBankInfo fb; float mlo,mhi,ms,melk; int k,chan,maxChan,Nby2; /* Save sizes to cross-check subsequent usage */ fb.frameSize = frameSize; fb.numChans = numChans; fb.sampPeriod = sampPeriod; fb.usePower = usePower; fb.takeLogs = takeLogs; /* Calculate required FFT size */ fb.fftN = 2; while (frameSize>fb.fftN) fb.fftN *= 2; if (doubleFFT) fb.fftN *= 2; Nby2 = fb.fftN / 2; fb.fres = 1.0E7/(sampPeriod * fb.fftN * 700.0); maxChan = numChans+1; /* set lo and hi pass cut offs if any */ fb.klo = 2; fb.khi = Nby2; /* apply lo/hi pass filtering */ mlo = 0; mhi = Mel(Nby2+1,fb.fres); if (lopass>=0.0) { mlo = 1127*log(1+lopass/700.0); fb.klo = (int) ((lopass * sampPeriod * 1.0e-7 * fb.fftN) + 2.5); if (fb.klo<2) fb.klo = 2; } if (hipass>=0.0) { mhi = 1127*log(1+hipass/700.0); fb.khi = (int) ((hipass * sampPeriod * 1.0e-7 * fb.fftN) + 0.5); if (fb.khi>Nby2) fb.khi = Nby2; } if (trace&T_MEL){ printf("FFT passband %d to %d out of 1 to %d\n",fb.klo,fb.khi,Nby2); printf("Mel passband %f to %f\n",mlo,mhi); } /* Create vector of fbank centre frequencies */ fb.cf = CreateVector(x,maxChan); ms = mhi - mlo; for (chan=1; chan <= maxChan; chan++) { if (alpha == 1.0) { fb.cf[chan] = ((float)chan/(float)maxChan)*ms + mlo; } else { /* scale assuming scaling starts at lopass */ float minFreq = 700.0 * (exp (mlo / 1127.0) - 1.0 ); float maxFreq = 700.0 * (exp (mhi / 1127.0) - 1.0 ); float cf = ((float)chan / (float) maxChan) * ms + mlo; cf = 700 * (exp (cf / 1127.0) - 1.0); fb.cf[chan] = 1127.0 * log (1.0 + WarpFreq (warpLowCut, warpUpCut, cf, minFreq, maxFreq, alpha) / 700.0); } } /* Create loChan map, loChan[fftindex] -> lower channel index */ fb.loChan = CreateShortVec(x,Nby2); for (k=1,chan=1; k<=Nby2; k++){ melk = Mel(k,fb.fres); if (k<fb.klo || k>fb.khi) fb.loChan[k]=-1; else { while (fb.cf[chan] < melk && chan<=maxChan) ++chan; fb.loChan[k] = chan-1; } } /* Create vector of lower channel weights */ fb.loWt = CreateVector(x,Nby2); for (k=1; k<=Nby2; k++) { chan = fb.loChan[k]; if (k<fb.klo || k>fb.khi) fb.loWt[k]=0.0; else { if (chan>0) fb.loWt[k] = ((fb.cf[chan+1] - Mel(k,fb.fres)) / (fb.cf[chan+1] - fb.cf[chan])); else fb.loWt[k] = (fb.cf[1]-Mel(k,fb.fres))/(fb.cf[1] - mlo); } } /* Create workspace for fft */ fb.x = CreateVector(x,fb.fftN); return fb; }