diff options
Diffstat (limited to 'mfcc_matching.udo')
-rw-r--r-- | mfcc_matching.udo | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/mfcc_matching.udo b/mfcc_matching.udo new file mode 100644 index 0000000..e67fb8a --- /dev/null +++ b/mfcc_matching.udo @@ -0,0 +1,91 @@ + +/* + * 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 + + |