I have noticed that often peaks do not coincide with real beat starts: peaks are detected "right shifted", that is some time after beat really starts. This could be due to two reasons: 1) the LP filter cuts too low: typically kick drums peaks at about 100 Hz, but if kick drum is not present at the begin of a track also higher frequency range should be considered. 2) the envelope of a typical kickdrum waveform: there is a short raise time before peak is reached. This raise time (some tens ms) could be subtracted to peak positions.

Ben Wheeler ha scritto:
On Mon, Jan 12, 2009 at 05:36:28PM -0800, Albert Santoni wrote:
Without actually knowing the Nyquist language, I think what this code is doing is: - Downsampling to 1000 Hz (the Nyquist frequency is then 500 Hz, and there's tons of aliasing introduced probably. I think aliasing is the right term to use...?) - applying a low-pass filter (so that you just get the bassy beat, probably kills the aliasing caused by the downsampling)

I think it might be the other way around. I'm not terribly familiar
with Lisp but it seems logical to me to read the parens from the
inside out, rather than from left to right.

(setf s1 (if (arrayp s) (snd-add (aref s 0) (aref s 1)) s))

If signal is stereo, sum the left and right channels.

(defun signal () (force-srate 1000 (lp (snd-follow (lp s1 50) 0.001 0.01 0.1 512) 10)))

Pass the signal through a 50Hz LPF (first-order Butterworth)
Pass that, along with args floor=0.001 risetime=0.01 falltime=0.1 lookahead=512, to function snd-follow, which is an envelope follower. I suspect this is probably an important part of the equation.
Then take a 10Hz lowpass of the result of that.
Then downsample to 1000Hz.
I don't understand why it's done that way. The docs for snd-follow
http://www.cs.cmu.edu/~rbd/doc/nyquist/part8.html
suggest a low-sample-rate input would make sense.
- If signal > threshold, we've found a peak

Not quite.

(do ((c 0.0) (l NIL) (p T) (v (snd-fetch s2))) ((not v) l)
 (if (and p (> v thres)) (setq l (cons (list c "B") l)))
 (setq p (< v thres))
 (setq c (+ c 0.001))
 (setq v (snd-fetch s2)))

A peak is the first sample that *crosses* from below to above the threshold each time, rather than just every sample above the threshold. ie only the leading edge of each peak is added to the list. That can include the first sample, if that's above threshold.

Ben



------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Mixxx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixxx-devel

Reply via email to