Skip to content

Commit

Permalink
a new algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
dalatant committed Nov 8, 2016
1 parent f7bfa04 commit b0d5d28
Showing 1 changed file with 48 additions and 36 deletions.
84 changes: 48 additions & 36 deletions js/pitchdetect.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ function togglePlayback() {

var rafID = null;
var tracks = null;
var buflen = 1024;
var buflen = 2048;
var buf = new Float32Array( buflen );

var noteStrings = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
Expand All @@ -219,42 +219,8 @@ function centsOffFromPitch( frequency, note ) {
return Math.floor( 1200 * Math.log( frequency / frequencyFromNoteNumber( note ))/Math.log(2) );
}

// this is a float version of the algorithm below - but it's not currently used.
// this is the previously used pitch detection algorithm.
/*
function autoCorrelateFloat( buf, sampleRate ) {
var MIN_SAMPLES = 4; // corresponds to an 11kHz signal
var MAX_SAMPLES = 1000; // corresponds to a 44Hz signal
var SIZE = 1000;
var best_offset = -1;
var best_correlation = 0;
var rms = 0;
if (buf.length < (SIZE + MAX_SAMPLES - MIN_SAMPLES))
return -1; // Not enough data
for (var i=0;i<SIZE;i++)
rms += buf[i]*buf[i];
rms = Math.sqrt(rms/SIZE);
for (var offset = MIN_SAMPLES; offset <= MAX_SAMPLES; offset++) {
var correlation = 0;
for (var i=0; i<SIZE; i++) {
correlation += Math.abs(buf[i]-buf[i+offset]);
}
correlation = 1 - (correlation/SIZE);
if (correlation > best_correlation) {
best_correlation = correlation;
best_offset = offset;
}
}
if ((rms>0.1)&&(best_correlation > 0.1)) {
console.log("f = " + sampleRate/best_offset + "Hz (rms: " + rms + " confidence: " + best_correlation + ")");
}
// var best_frequency = sampleRate/best_offset;
}
*/

var MIN_SAMPLES = 0; // will be initialized when AudioContext is created.
var GOOD_ENOUGH_CORRELATION = 0.9; // this is the "bar" for how close a correlation needs to be
Expand Down Expand Up @@ -312,6 +278,52 @@ function autoCorrelate( buf, sampleRate ) {
return -1;
// var best_frequency = sampleRate/best_offset;
}
*/

function autoCorrelate( buf, sampleRate ) {
// Implements the ACF2+ algorithm
var SIZE = buf.length;
var rms = 0;

for (var i=0;i<SIZE;i++) {
var val = buf[i];
rms += val*val;
}
rms = Math.sqrt(rms/SIZE);
if (rms<0.01) // not enough signal
return -1;

var r1=0, r2=SIZE-1, thres=0.2;
for (var i=0; i<SIZE/2; i++)
if (Math.abs(buf[i])<thres) { r1=i; break; }
for (var i=1; i<SIZE/2; i++)
if (Math.abs(buf[SIZE-i])<thres) { r2=SIZE-i; break; }

buf = buf.slice(r1,r2);
SIZE = buf.length;

var c = new Array(SIZE).fill(0);
for (var i=0; i<SIZE; i++)
for (var j=0; j<SIZE-i; j++)
c[i] = c[i] + buf[j]*buf[j+i];

var d=0; while (c[d]>c[d+1]) d++;
var maxval=-1, maxpos=-1;
for (var i=d; i<SIZE; i++) {
if (c[i] > maxval) {
maxval = c[i];
maxpos = i;
}
}
var T0 = maxpos;

var x1=c[T0-1], x2=c[T0], x3=c[T0+1];
a = (x1 + x3 - 2*x2)/2;
b = (x3 - x1)/2;
if (a) T0 = T0 - b/(2*a);

return sampleRate/T0;
}

function updatePitch( time ) {
var cycles = new Array;
Expand Down

0 comments on commit b0d5d28

Please sign in to comment.