From c367867757ac83ac8d481eae8e42658688b64c58 Mon Sep 17 00:00:00 2001 From: Ben Titcomb Date: Tue, 1 Mar 2016 10:38:37 -0800 Subject: [PATCH] Clean #processBuffer a bit and rely on Goertzel#eachDownsample for downsampling. --- build/dtmf.js | 26 +++++++++++--------------- build/goertzel.js | 23 +++++++++++++---------- compile.sh | 3 ++- src/dtmf.coffee | 19 ++++++------------- src/goertzel.coffee | 20 ++++++++++++-------- 5 files changed, 44 insertions(+), 47 deletions(-) diff --git a/build/dtmf.js b/build/dtmf.js index 8a2283d3..8e99dfb9 100644 --- a/build/dtmf.js +++ b/build/dtmf.js @@ -86,34 +86,30 @@ DTMF = (function() { }; DTMF.prototype.processBuffer = function(buffer) { - var badPeaks, energy, f, freq, frequency, handler, highEnergies, i, intSample, j, len, lowEnergies, ref, register, result, value, windowedSample; + var badPeaks, f, freq, handler, highEnergies, i, j, len, lowEnergies, ref, result, value; value = ''; - intSample = void 0; - register = void 0; - windowedSample = void 0; - energy = void 0; highEnergies = []; lowEnergies = []; - frequency = void 0; result = []; + Goertzel.Utilities.eachDownsample(buffer, this.downsampleRate, (function(_this) { + return function(sample, i, downSampledBufferLength) { + var windowedSample; + windowedSample = Goertzel.Utilities.exactBlackman(sample, i, downSampledBufferLength); + _this.goertzel.processSample(windowedSample); + return value = _this.energyProfileToCharacter(_this.goertzel); + }; + })(this)); i = 0; - while (i < buffer.length) { - intSample = buffer[i]; - windowedSample = Goertzel.Utilities.exactBlackman(intSample, i, buffer.length / this.downsampleRate); - register = this.goertzel.processSample(windowedSample); - value = this.energyProfileToCharacter(register); - i += this.downsampleRate; - } highEnergies = []; while (i < this.highFrequencies.length) { f = this.highFrequencies[i]; - highEnergies.push(register.energies[f]); + highEnergies.push(this.goertzel.energies[f]); i++; } lowEnergies = []; while (i < this.lowFrequencies.length) { freq = this.lowFrequencies[i]; - lowEnergies.push(register.energies[freq]); + lowEnergies.push(this.goertzel.energies[freq]); i++; } badPeaks = Goertzel.Utilities.doublePeakFilter(highEnergies, lowEnergies, this.peakFilterSensitivity); diff --git a/build/goertzel.js b/build/goertzel.js index 70a491c6..8ec31b8d 100644 --- a/build/goertzel.js +++ b/build/goertzel.js @@ -95,30 +95,33 @@ Goertzel = (function() { return Math.round(intSample); }, downsampleBuffer: function(buffer, downsampleRate, mapSample) { - var downsampledBuffer, i, sample; - downsampledBuffer = []; + var bufferLength, downsampledBuffer, i, sample; + bufferLength = buffer.length; + downsampledBuffer = new (Uint8ClampedArray || Array)(bufferLength / downsampleRate); i = 0; - while (i < buffer.length) { + while (i < bufferLength) { sample = buffer[i]; if (mapSample) { - downsampledBuffer.push(mapSample(sample, i, buffer.length, downsampleRate)); + downsampledBuffer[i] = mapSample(sample, i, buffer.length, downsampleRate); } else { - downsampledBuffer.push(sample); + downsampledBuffer[i] = sample; } i += downsampleRate; } return downsampledBuffer; }, - eachDownsample: function(buffer, downsampleRate, fn) { - var i, results, sample; + eachDownsample: function(buffer, downSampleRate, fn) { + var bufferLength, downSampledBufferLength, i, results, sample; i = 0; + bufferLength = buffer.length; + downSampledBufferLength = bufferLength / downSampleRate; results = []; - while (i < buffer.length) { + while (i < bufferLength) { sample = buffer[i]; if (typeof fn === "function") { - fn(sample, i, buffer.length, downsampleRate); + fn(sample, i, downSampledBufferLength); } - results.push(i += downsampleRate); + results.push(i += downSampleRate); } return results; }, diff --git a/compile.sh b/compile.sh index 72997831..2b2543fb 100755 --- a/compile.sh +++ b/compile.sh @@ -2,4 +2,5 @@ coffee -o build -c -b src/goertzel.coffee coffee -o build -c -b src/dtmf.coffee -coffee -c -b spec/goertzel.spec.coffee \ No newline at end of file +coffee -c -b spec/goertzel.spec.coffee +coffee -c -b spec/dtmf.spec.coffee \ No newline at end of file diff --git a/src/dtmf.coffee b/src/dtmf.coffee index 75fa8ba2..2944b1f0 100644 --- a/src/dtmf.coffee +++ b/src/dtmf.coffee @@ -64,33 +64,26 @@ class DTMF processBuffer: (buffer) -> value = '' - intSample = undefined - register = undefined - windowedSample = undefined - energy = undefined highEnergies = [] lowEnergies = [] - frequency = undefined result = [] # Downsample by choosing every Nth sample. + Goertzel.Utilities.eachDownsample buffer, @downsampleRate, (sample,i,downSampledBufferLength)=> + windowedSample = Goertzel.Utilities.exactBlackman(sample, i, downSampledBufferLength) + @goertzel.processSample(windowedSample) + value = @energyProfileToCharacter(@goertzel) i = 0 - while i < buffer.length - intSample = buffer[i] - windowedSample = Goertzel.Utilities.exactBlackman(intSample, i, buffer.length / @downsampleRate) - register = @goertzel.processSample(windowedSample) - value = @energyProfileToCharacter(register) - i += @downsampleRate # END DOWNSAMPLE # Run peak test to throw out samples with too many energy spectrum peaks or where the difference between energies is not great enough. highEnergies = [] while i < @highFrequencies.length f = @highFrequencies[i] - highEnergies.push register.energies[f] + highEnergies.push @goertzel.energies[f] i++ lowEnergies = [] while i < @lowFrequencies.length freq = @lowFrequencies[i] - lowEnergies.push register.energies[freq] + lowEnergies.push @goertzel.energies[freq] i++ badPeaks = Goertzel.Utilities.doublePeakFilter(highEnergies, lowEnergies, @peakFilterSensitivity) if badPeaks == false diff --git a/src/goertzel.coffee b/src/goertzel.coffee index bce967ef..afc48726 100644 --- a/src/goertzel.coffee +++ b/src/goertzel.coffee @@ -56,23 +56,27 @@ class Goertzel Math.round intSample downsampleBuffer: (buffer, downsampleRate, mapSample) -> - downsampledBuffer = [] + bufferLength = buffer.length + # Prefer Uint8ClampedArray for performance + downsampledBuffer = new (Uint8ClampedArray or Array)(bufferLength / downsampleRate) i = 0 - while i < buffer.length + while i < bufferLength sample = buffer[i] if mapSample - downsampledBuffer.push mapSample(sample, i, buffer.length, downsampleRate) + downsampledBuffer[i] = mapSample(sample, i, buffer.length, downsampleRate) else - downsampledBuffer.push sample + downsampledBuffer[i] = sample i += downsampleRate downsampledBuffer - eachDownsample: (buffer, downsampleRate, fn) -> + eachDownsample: (buffer, downSampleRate, fn) -> i = 0 - while i < buffer.length + bufferLength = buffer.length + downSampledBufferLength = bufferLength / downSampleRate + while i < bufferLength sample = buffer[i] - fn?(sample, i, buffer.length, downsampleRate) - i += downsampleRate + fn?(sample, i, downSampledBufferLength) + i += downSampleRate hamming: (sample, sampleIndex, bufferSize) -> sample * (0.54 - 0.46 * Math.cos(2 * Math.PI * sampleIndex / bufferSize))