Removing dead white silence - impossible, help please

Hello,
First of all, as you may know, I’m a blind user who can’t use the mouse at all for editing jobs in Audacity. So any of the tools are out of the question for me.
So I have a recording of a livestream I recorded with the Windows Wasapi Loopback, but there are momentary spots where there is dead silence. I can solve the problem manually, but I’d rather not do that because it’s time-consuming. Here’s what I did.
I selected each part where one of those “chops” occurs, run “Trim Silence” and the threshold was set to -500, or infinitely silent. It did the job, but having to select super short samples that I can’t react to in time is just not possible to do by hand.
Then I looked on the forum for ways to do this and I found two suggestions. One was “Silence Finder”, and I did that. When I deleted the labeled audio, it didn’t change at all, even though I selected -500 as the silence level. Then I found a suggestion to Detach at Silences. When i did this too, the audio did not change at all, even after doing a Join. I guess there must be a mouse step involved? If so, why are you excluding blind people from this?
So, I was thinking of a plugin that would work like “Trim Silence”, but it would trim everything. Basically a .NY version of Truncate Silence. However, what I dislike about Truncate Silence is that you are limited to -80 DB, and I recorded in 32 bit with a very wide dynamic range. So Truncate Silence is also out of the question for me.
After looking at Trim Silence, it would seem that all that needs to be done is to delete some code so that it just clears the dead white silences. But what to delete?
Again, I can’t just simply select portions of it and then trim silence manually as it would take forever, and again Detach at Silences followed by a Join doesn’t work at all. Other than this plugin, I have no other options.
So, can I request some help with this please? I think it should also be included on the Nyquist Effect plugins. I’ve attached the code for Trim Silence so we’re on the same page as to what I’m using as a plugin. Also, I do not mind the audio having to be loaded into Ram.

;nyquist plug-in
;version 3
;type process
;categories "http://lv2plug.in/ns/lv2core/#UtilityPlugin"
;name "Trim Silence..."
;action "Trimming..."
;info "by Steve Daulton (http://www.easyspacepro.com). Released under GPL v2.\n\nTrims silence from the beginning and end of the selection.\n"

;control thresh "Silence Threshold (dB)" real "" -300 -500 0

;; TrimSilence.ny by Steve Daulton. Aug 2011.
;; Updated 24 Sept 2012.
;; Released under terms of the GNU General Public License version 2:
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
;; Requires Audacity 1.3.8 or later.

;; RAM USAGE:
;; This plug-in requires the audio to be loaded into RAM.
;; If there is insufficient free RAM Audacity may freeze or crash.
;; The line below limits RAM usage to 1.0 GB (about 47 minutes for
;; a stereo track at 44.1 kHz)
;; If your computer has more than 1GB of physical RAM available, the
;; limit may be increased.

(setq RAM-Limit 2.0) ; RAM limit in GB

; convert threhold to linear
(setq thresh (db-to-linear (min 0 thresh)))

;; Limit of duration in seconds
(setq limit
  (/ (* ram-limit 1000000000)
    (* 4.0 *sound-srate*)))
(when (arrayp s)(setq limit (/ limit 2.0)))

;;; modulo
(defun mod (x y)
  (setq y (float y))
  (round (* y
    (- (/ x y)
      (truncate (/ x y))))))
  
;;; convert to hh:mm:ss
(defun to-hhmmss (seconds)
  (let* ((hh (truncate (/ seconds 3600)))
        (mm (truncate (/ (mod seconds 3600) 60)))
        (ss (mod seconds 60)))
    (format nil "~ah:~am:~as" hh mm ss)))

;;; convert to mono and limit sample rate
(defun convert (sig ratio)
  (if (arrayp s)
      (snd-avg 
        (s-max (snd-abs (aref sig 0))
          (snd-abs (aref sig 1)))
        ratio ratio op-peak)
      (snd-avg sig ratio ratio op-peak)))

;;; find silences
(defun find-sil (sig &aux (start 0)(end 0))
  (do ((new (snd-fetch sig) (snd-fetch sig))
       (flag 0))
      ((not new))
    (if (= flag 0)
        ;; count initial silence
        (if (<= new thresh)
            (setq start (1+ start))
            (setq flag 1))
        ;; count final silence
        (if (<= new thresh)
            (setq end (1+ end))
            (setq end 0))))
  (list start end))


(if (< len (* limit *sound-srate*)) ;max length in samples
  (let* ((start 0)
         (end 0)
         (flag 0)
         ;; ratio provides tighter trimming for short selections
         ;; while maintaining reasonable speed for long selections
         (ratio (max 1 (min 0 (round (/ len 1.0)))))
         (my-srate (/ *sound-srate* ratio))
         (mysound (convert s ratio)))

    ;loop through samples and mark start and end
    (setf result (find-sil mysound))

    (let ((start (/ (first result) my-srate))
          (end (- (get-duration 1)(/ (second result) my-srate))))
      ;; ensure at least 1 sample remains
      (if (>= start (get-duration 1))
        (setq start (/ (1- len) *sound-srate*)))
      ; trim
      (multichan-expand #'extract-abs start end (cue s))))

  ;; OR print error message
  (format nil "Error.\nMax RAM usage by Trim Silence is set to ~a GB.~%This allows a maximum duration ~
              for a ~a~%track at ~a Hz of ~a.~%Selected track is ~a.~%"
              RAM-limit
              (if (arrayp s) "stereo" "mono")
              (round *sound-srate*)
              (to-hhmmss limit)
              (to-hhmmss (get-duration 1))))

So all I want to change is for it to just delete all the silences, not just the beginning or end only. Again, I’m not happy with Truncate Silence and want tighter trimming right down to the sample level. So can anybody please help me with this? Thanks,

Michael

PS. I’ve tried my best to make sense. Among the forums I’ve read where people are trying to resolve this, a lot of people have a hard time trying to grasp what they’re saying. But being an audio expert, hopefully I was clear about this.

What’s the length of the shortest silence that you want to remove (approximately)?

Well, smaller than I can estimate. Perhaps maybe 1/1000 of a second.
And I’m not trying to create a brand-new plugin, I just was thinking that one can be modified to allow this.

If you’re looking at silences greater than one millisecond, I’d suggest that you use Truncate Silence. Even though the minimum detection level is “only” -80 dB, that is a very low level and very unlikely to occur within normal audio.

So, then why does Detach at Silences not work then? I’m afraid that might be the only option? I don’t know how I’d be able to piece the clips together with no gaps.

Sure, -80 DB is unlikely, but it just doesn’t make sense not to delete absolute silence. Like for example I have a recording where a sample fades in and out at the beginning and end, a long period of silence, then another sample fades in. If I use Truncate Silence part of the fade will be deleted. That is not what I want at all. All I want is to delete every single sample containing absolute dead silence, and I’m absolutely sure a modified TrimSilence plugin will be able to handle that.
I think it would go through a loop and analyze each and every sample, increasing the counter every time it finds absolute silence. What word would I use to delete anything below this level? All I’m trying to do is modify the TrimSilence plugin so it trims ALL silences, not just beginning and end. That’s literally it. Guess I’ll have to learn Nyquist codeing if you’re not too keen on helping me… I guess I would delete Start and End throughout the plugin? No? What DO I delete? Or replace a group of words with something else… I’m confused here.

Not necessarily. If the recording was made at a higher sample format than 16-bit and then converted to 16-bit, there should be “dither noise” right to the very end of the fade, and dither noise typically has a peak amplitude higher than -80 dB. The dither noise is a good thing because it allows 16-bit to have a dynamic range of over 100 dB and no quantization noise.

You should not delete every zero amplitude sample. Normal audio crosses the zero amplitude line thousands of times per second. On some of those zero crossings there will be a sample that has a value of exactly zero, but it a valid part of the audio that should be retained. You have to decide on a minimum number of zeros in a row to count as silence.

Also, looping through individual samples with Nyquist is slow and generally avoided if possible, particularly when working with more than a few seconds of audio. The way that is done in Sound Finder and Silence finder is that a low sample rate copy of the sound is made, and that is analyzed rather than the original sound. Because the low sample rate copy has many times less samples, the analysis can be many times quicker, or rather, “less slow”.

On 32-bit operating systems, there is a 2 GB limit to the amount of RAM that Nyquist can access. On 64it machines, Nyquist “may” be able to access more RAM, but I’ve only tested on Linux. Audacity for Mac and Windows is build as a 32-bit application, so I’m not sure what the situation is there. Nevertheless, it may be possible to avoid the memory limit if the plug-in is designed as a single pass effect.

I don’t think that the Trim Silence plug-in is the best approach for what you want. A better approach, for analyzing every sample, would be to use snd-fetch-array rather than snd-fetch. The former command grabs an array of samples rather than single samples, and it is quicker and more memory efficient to loop through arrays, returning sound as you go, rather than looping through samples on one pass, and trimming the audio on a second pass.

I don’t have time to work on this plug-in right now, and I think that working on it at all will be unnecessary because I thing Truncate Silence will do the job. I’ve used Truncate Silence for this type of task and it has worked very well for me. I’d recommend that you try Truncate Silence first and see how it goes. If you find that you really do need to make a new plug-in, then I’ll be happy to help you with that, but it will take a lot of time and effort.

Even if you remove the silences, odds-are the waveform will then be discontinuous at the join: there will be a click at the join.
There is a DeClicker plugin for Audacity which automatically repairs clicks, here … Updated De-Clicker and new De-esser for speech
That plugin can be slow, (depending on the settings used), but it’s much faster than repairing individual clicks manually.