c# - Help with implementing this beat-detection algorithm? -
i tried implement beat detection code found here, namely derivation , combfilter algorithm #1:: http://archive.gamedev.net/reference/programming/features/beatdetection/page2.asp
im not sure if implemented not getting results. wondering if have implemented or towards people want in general. here implementation:
//cycle through tempo's (60 200) incrementing each time 10 (int = (int)mintempo; <= maxtempo; += 10) { //clear variables used curtempo = i; fftpulse.clear(); offset = 0; energy = 0; short[] prevbuffer = null; //calculate ti ti = (60 / curtempo) * 44100; ti = math.round(ti, 0); //generate pulse train (int j = 0; j < pulsetrain.length; j++) { if ((j % ti) == 0) pulsetrain[j] = short.maxvalue; else pulsetrain[j] = 0; } //compute fft of pulsetrain array while (offset < pulsetrain.length) { //generate block samples (1024 blocksize) short[] fftpulsebuffer = new short[po.blocksize / 2]; //store samples pulsetrain in 1024 block buffer passing fft algorithm index = 0; (int j = offset; j < (offset + (po.blocksize / 2)) && j < pulsetrain.length; j++) { fftpulsebuffer[index] = pulsetrain[j]; index++; } //initialize prevbuffer, contains samples previous block, used in conjunction current block fft if (prevbuffer == null) prevbuffer = new short[po.blocksize / 2]; //calculate fft using current , previous blocks fftpulse.add(calculatefft(fftpulsebuffer,prevbuffer)); //set prevbuffer , increment next block start position prevbuffer = fftpulsebuffer; offset += (po.blocksize / 2); } //calculate energy (int j = 0; j < intendomainarr.count; j++) { double[] signalarr = intendomainarr[j]; double[] pulsearr = fftpulse[j]; (int x = 0; x < signalarr.length; x++) { energy += math.abs(signalarr[x] * pulsearr[x]); } } //get current best tempo match if (energy > maxenergy) { chosentempo = curtempo; maxenergy = energy; } } the results getting high, around 190 , 200bpm, should not case, .wav files have tempos between 60-120bpm.
note using .wav file (44.1khz, 16-bit, mono), of formulas bit modified (i.e. calculating energy) work 1 channel. confirm if there have been discrepancies in implementation? not worrying fft part because using library that.
thank much!
make plot of energy vs frequency.
i think you'll find harmonics have identical energy base signal, , if actual frequency falls halfway between frequency bins, second harmonic's peak sampled , beats 2 samples either side of true frequency.
you'll need penalize higher frequencies little bit overcome effect.
please note, while c# not unreasonable choice implementation of such algorithm in real time or bulk batch processing, it's horrible algorithm development , tweaking. i'd recommend using matlab (or free clone, octave) algorithm right, , once it's working on test cases, convert code c# (or c++).
Comments
Post a Comment