/* * Calculate the Euclidean distance between a table point and an array * in: * icorpusdata Table containing MFCC corpus data * ibands Number of bands used for MFCC analysis in corpus table * kcorpusindex Start index of corpus data to compare * kmatch[] Array of MFCC values to compare against * out: * ktotal Euclidean distance */ opcode euclideandistance, k, iikk[] icorpusdata, ibands, kcorpusindex, kmatch[] xin ktotal = 0 kdx = 0 while (kdx < ibands) do kcorpusval tab kcorpusindex+kdx, icorpusdata ktotal += pow((kcorpusval - kmatch[kdx]), 2) kdx += 1 od xout sqrt(ktotal) endop /* * Get MFCC data from an audio signal * in: * asig The audio signal for analysis * ifftsize FFT size for MFCC analysis * ibands Number of MFCC bands to use * ifreqmin=100 Optional minimum frequency for analysis * ifreqmax=19000 Optional maximum frequency for analysis * out: * kmfcc[] Array of MFCC data with length ibands * ktrig Fired when new data has been output */ opcode getmfccs, k[]k, aiijj asig, ifftsize, ibands, ifreqmin, ifreqmax xin ifreqmin = ((ifreqmin == -1) ? 100: ifreqmin) ifreqmax = ((ifreqmax == -1) ? 19000: ifreqmax) kcnt init 0 ibins init ifftsize/2 kIn[] init ifftsize kIn shiftin asig kcnt += ksmps ktrig = 0 if (kcnt == ifftsize) then kFFT[] = rfft(kIn) kPows[] = pows(kFFT) kMFB[] = log(mfb(kPows, ifreqmin, ifreqmax, ibands)) kmfcc[] = dct(kMFB) kcnt = 0 ktrig = 1 endif xout kmfcc, ktrig endop /* * Get nearest matching table index of an audio signal based on MFCC analysis and distance comparison * in: * asig The driving audio signal * ifftsize FFT size for MFCC analysis * ibands Number of MFCC bands to use * icorpusdata Table containing MFCC corpus data * out: * kindex Start index of corpus audio table that best matches * ktrig Fired when new match has been output */ opcode nearest, kk, aiii asig, ifftsize, ibands, icorpusdata xin imaxitems = ftlen(icorpusdata) kmfcc[], ktrig getmfccs asig, ifftsize, ibands kouttrig = 0 if (ktrig == 1) then kcorpusindex = 0 kbest = 9999999 kbestindex = -1 while (kcorpusindex < imaxitems - ibands) do kdistance euclideandistance icorpusdata, ibands, kcorpusindex, kmfcc if (kdistance < kbest) then kbest = kdistance kbestindex = kcorpusindex endif kcorpusindex += ibands od endif xout (kbestindex/ibands)*ifftsize, ktrig endop