aboutsummaryrefslogtreecommitdiff
path: root/mfcc_matching.udo
diff options
context:
space:
mode:
Diffstat (limited to 'mfcc_matching.udo')
-rw-r--r--mfcc_matching.udo91
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
+
+