Plugin to find two consecutive samples of digital silence?

I need a Nyquist script that adds a label when two or more consecutive samples of absolute digital silence occur in both channels simultaneously, within a selection. The “Label Sounds” feature isn’t precise enough for what I’m looking for.

In case I haven’t explained myself clearly enough, here’s what it would look like in “Waveform (dB)” and “Connect dots” view:

@steve wrote this very helpful command in 2021 that identifies synchronous zero crossings within a selection in a stereo track:

(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 1 (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")

I need something that works in the same way for the instances I described above. I tried modifying his code, but without success.

Any assistance would be greatly appreciated.
Thank you.

Try this:

(defun find-zero (sig)
  (let ((prev0  (zerop (snd-fetch (aref sig 0)))) ; is left zero
        (prev1  (zerop (snd-fetch (aref sig 1)))) ; is right zero
        new0  ;new sample (left)
        new1  ;new sample (right)
        zeroflag  ; True when we are within a silent region.
        rslt)
    (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 (1+ count)))  ; rslt flag on first silent samples
        ((not val0) rslt)
      (setf new0 (zerop val0))  ; is left still zero
      (setf new1 (zerop val1))  ; is right still zero
      
      (cond
        ((and prev0 new0 prev1 new1 (not zeroflag))
            ; Two consecutive zero samples in both channels
            (setf zeroflag t)
            (setf rslt count))
        ((not (and prev0 new0 prev1 new1))
            ; Not in silence
            (setf zeroflag nil)))
      ;; Update previous sample flags
      (setf prev0 new0)
      (setf prev1 new1))))


(setf z (find-zero *track*))
(if z
    (list (list (/ z *sound-srate*) "Z"))
    "No silences found")
1 Like

Perfect! Thanks again Steve. Will make a donation to the project when I next get paid. :grinning:

No need for donations. Audacity is run by a commercial company (Muse Group) these days.