I’m using some Nyquist code that Steve provided for finding a zero crossing point on this forum a while back.
When I run it in the prompt, it works fine, but when I install it as a plugin, having added some headers, and then run it, I get: “Nyquist returned the value: 399797.500000” instead of a label showing the zero crossing point I’m expecting …
The original code that works fine in the prompt is:
(defun find-zero (sig)
(let ((prev0 (plusp (snd-fetch (aref sig 0)))) ; is left positive
(prev1 (plusp (snd-fetch (aref sig 1)))) ; is right positive
new0 ;new sample (left)
new1 ;new sample (right)
rslt
zx0 ; zero crossing flag (left)
zx1); zero crossing flag (right)
(do ((val0 (snd-fetch (aref sig 0)) (snd-fetch (aref sig 0)))
(val1 (snd-fetch (aref sig 1)) (snd-fetch (aref sig 1)))
(count 0.5 (1+ count))) ; rslt flag will be placed between previous and current samples
((not val0) rslt)
(setf new0 (plusp val0)) ; is left still positive
(setf new1 (plusp val1)) ; is right still positive
;; Previous and current sign both positive, or both “not positive”.
;; When both are the same sign, we have not crossed zero.
(setf zx0 (or (and prev0 new0)
(and (not prev0) (not new0))))
(setf zx1 (or (and prev1 new1)
(and (not prev1) (not new1))))
(when (and (not zx0) (not zx1)) ; left and right have crossed zero
(setf rslt count))
;; Update previous sample flags
(setf prev0 new0)
(setf prev1 new1))))
(setf z (find-zero *track*))
(if z
(list (list (/ z *sound-srate*) “Z”))
“Zero crossing not found”)
and the headers I added are:
;nyquist plug-in
;version 4
;type analyze
;name "Find Zero Crossing Point"
; code given by steve
If someone could point me in the right direction, I’d be very grateful.
You have “magic quotes” rather than ordinary quotes around the “Z”. It is essential that Nyquist code is only edited using a “plain text” editor (such as NotePad++).
The line should be:
(list (list (/ z *sound-srate*) "Z"))
and again in this line:
“Zero crossing not found”))
Should be:
"Zero crossing not found"))
The code only supports stereo tracks, and only with track that don’t use real-time time stretch.
Also, there is currently a bug in Audacity that will prevent the plug-in from working if a label track is included in the selection. Sadly there have been no attempts to fix this bug since the issue was discovered in 2023.
Here is a modified version of the plug-in.
I have included a check to ensure the track is stereo (an error message is raised if not stereo), and the plug-in now adds a label at the first zero crossing, rather than the last zero crossing. This second change will often make the plug-in complete more quickly as it stops processing as soon as a zero crossing (in both channels at the same time) is found.
;nyquist plug-in
;version 4
;type analyze
;name "Stereo Zero Crossing Point"
;copyright "GPLv2"
;author "Steve Daulton"
;debugflags trace
(defun find-zero (sig)
(let ((prev0 (plusp (snd-fetch (aref sig 0)))) ; is left positive
(prev1 (plusp (snd-fetch (aref sig 1)))) ; is right positive
new0 ;new sample (left)
new1 ;new sample (right)
zx0 ; zero crossing flag (left)
zx1); zero crossing flag (right)
(do ((val0 (snd-fetch (aref sig 0)) (snd-fetch (aref sig 0)))
(val1 (snd-fetch (aref sig 1)) (snd-fetch (aref sig 1)))
(count 0.5 (1+ count))) ; rslt flag will be placed between previous and current samples
((not val0))
(setf new0 (plusp val0)) ; is left still positive
(setf new1 (plusp val1)) ; is right still positive
;; Previous and current sign both positive, or both “not positive”.
;; When both are the same sign, we have not crossed zero.
(setf zx0 (or (and prev0 new0)
(and (not prev0) (not new0))))
(setf zx1 (or (and prev1 new1)
(and (not prev1) (not new1))))
(when (and (not zx0) (not zx1)) ; left and right have crossed zero
(return-from find-zero count))
;; Update previous sample flags
(setf prev0 new0)
(setf prev1 new1))))
(cond ((arrayp *track*)
(setf z (find-zero *track*))
(if z
(list (list (/ z *sound-srate*) "Z"))
"Zero crossing not found"))
(t "This effect requires a stereo track."))
The line ;debugflags trace tells Audacity to automatically open the debug window if it contains any text - this is a handy feature for catching bugs while developing a plug-in.