Extend Silences

Yes, but still much quicker than manually extending each silence.

If there was an option was added to “Extend silences” plug-in for setting a limiting duration and a higher second threshold, how would the plug-in know which parts to use the higher threshold on, and which to use the lower threshold?

The same way we do it manually, it should actually run two times. After the first run with the base settings, it should check if some audio segments have been left which are longer than the “limiting duration”. Then in the second run it should search within those segments for a "higher threshold" so they could be divided further.

Actually the only additional setting for this plug-in would be the “limiting duration”. For example if you wish to have audio segments no more than 3 seconds, that would be your “limiting duration” and if a 7sec segment is left after the first run, the “Extend Silences” plug-in can analyze that segment and find the smallest value as a “higher threshold” which can divide this segment to less than 3sec parts. This threshold may be different for each long segment which is left after the first run.

I want to share my modification of steve’s ExtendSilence.ny.
The repeating segment(chunk) feature is added for ‘hard’ training.
If ‘Number of exercise’ option is 1, segments won’t be repeated.

I used segrep command at final stage, which is very slow. But I don’t know the better way because I’m a novice.
So the progress indicator will be meaningless in most cases.
Please be patient to get the result.

This is my first modification of GPL program.
If my header in the source has mistakes, please let me know. I’ll correct them.

Thank steve for the original work.
ExtendSilenceThenRepeat.ny (5.73 KB)

Congratulations eg_lim on completing your first plug-in modification :smiley:

There is one problem that I see with this (modified) plug-in, which is that it requires a silence at the end, otherwise it messes up.
Here’s my test track. It has 3 sounds, each of duration 2 seconds, and each of different amplitudes so that they can be easily identified visually. The space between each sound is 3 seconds.

First Track000.png
If I select the whole thing, including the trailing silence, then it works as expected. With default settings, the result is:

First Track001.png
However, if there is no silence at the end, or only a short silence at the end, like this:

First Track002.png
then the result is:
First Track003.png
Also, it is highly recommended to set your text editor to use spaces rather than tabs, so that indentation is consistent when viewing the code.

There’s also quite a few minor things that could be improved, several of which come from improvements to Nyquist in Audacity that were made after “Extend Silences” was written. If you would like me to detail these I’d be happy to do so.

Thank steve for the review.
I also found that add-dur and add-sil-pc were ignored in repetition.
I was too careless then.

I’m attaching a bug-fixed version which doesn’t have tabs any more.
Unfortunately, It takes more time than the previous one does.

p.s. steve, would you please detail the improvements?
ExtendSilenceThenRepeat.ny (6.18 KB)

Sure.

Headers (Missing features - Audacity Support)

;version 3
The current plug-in version is version 4.
Note that version 4 plug-ins use TRACK for the audio passed from the track rather than S.

;categories
Categories are no longer used.

;name “Extend Silences, then Repeat…”
I’d suggest using a shorter name. This is the name that will appear in Audacity’s Effect menu.
Though some existing Nyquist plug-ins have quite long names, commercial plug-ins tend to have quite short names. When chatting on-line about a plug-in, it quickly becomes tedious to type out a long name. If the plug-in becomes very popular, people will become familiar with the name, whatever it is called, but for new and lesser known plug-ins, a “somewhat descriptive” name can be helpful, but it is “just a name”, not a description. Probably not the best idea to go a brief as iZotope do (with names like “Rx7”), so calling it “ESTeR” may be a bit too abbreviated, but it’s just a name, so up to you what you call it :wink:

;action
Again this is rather verbose. This is what shows in the progress bar window. All that the user needs to know, is that the plug-in is doing something.
;action “Processing…” would be adequate.
;action “ESTeR is busy…” is more fun.
;action “Extending and repeating…” hints at the name of the plug-in.
Again it’s your choice, but “Finding silences then inserting more, and repeat the segments” is rather long.

;info
This header is no longer used.


Validating user input:
This is often unnecessary in modern plug-ins. Slider widgets have a fixed range of values, and Audacity will complain if an out of range value is entered.
See: Missing features - Audacity Support
and: Missing features - Audacity Support


Style and readability:

(do ((n 0 (1+ n))
     (snd-pc-total 0)         ; running total of added '% of sound' added.
     (sil-pc-total 0)         ; running total of added '% of silence' added.
     (output (s-rest 0))      ; initialise output.
     (seg-list-reversed '())) ; initialise segment list
    ((= n (1- (length sil-list)))
      (let ((seg-list (reverse seg-list-reversed)))
        (seqrep (i (length seg-list)) (cue (extract-abs (first (nth i seg-list)) (second (nth i seg-list))  output)))))

Eughee, that’s horrible :wink:

I do tend to over-comment a lot of my plug-ins for the benefit of people learning Nyquist, but doing so is not really recommended. I think the first couple of comments are reasonable, but “initialise output”, and “initialise segment list” are pretty self evident once you know that a “DO” loop has local bindings.

But then we come to the horrible bit - the return value:

(let ((seg-list (reverse seg-list-reversed))) (seqrep (i (length seg-list)) (cue (extract-abs (first (nth i seg-list)) (second (nth i seg-list))  output)))))

Isn’t this more readable:

(do ((n 0 (1+ n))
     (snd-pc-total 0)   ; total "sound %"
     (sil-pc-total 0)   ; total "silence %"
     (output (s-rest 0))
     (seg-list '())
     (count (1- (length sil-list))))
    ((= n count) (build-output outpt seg-list))

and then define the “build-output” function somewhere nearby.

Defining short functions that do one thing each, aids readability and makes debugging much easier.


Same thing here:

(dotimes (i repeat-N) (push (list segment-start (+ segment-start section-dur pause snd-sil-len snd-sel-len)) seg-list-reversed))

or:

(dotimes (i repeat-N)
  (setf end-time (+ segment-start
                    section-dur pause
                    snd-sil-len
                    snd-sel-len))
  (setf seg-pair (list segment-start end-time) )
  (push seg-pair seg-list))

Another bit:

;;; For stereo tracks, use maximum of L/R channels
(defun mono (s-in)
  (if (arrayp s-in)               ; if stereo,
      (s-max                      ; absolute max of channels.
        (snd-abs (aref s-in 0))
        (snd-abs (aref s-in 1)))
      (snd-abs s-in)))            ; else absolute sample values.

You don’t actually need to do SND-ABS for S-IN, because SND-AVG with OP-PEAK uses absolute sample values.
It’s enough to just do:

;;; For stereo tracks, use maximum of L/R channels
(defun mono (s-in)
  (if (arrayp s-in)
      (s-max (snd-abs (aref s-in 0))
             (snd-abs (aref s-in 1)))
      s-in))

This is a nyquist plug-in version 4 of the former ExtendSilenceThenRepeat.ny.
‘ESTeR…’ you suggested sounds good, so I changed its name.

Using track instead of s resulted in some changes.

You reminded me many things which I have forgotten in programming.
Thank you very much, steve.
ESTeR.ny (6.34 KB)

I suspect that there may be a way to make this effect very much faster as a “Nyquist-Macro”, using new features in Audacity 2.3.1 (due for release in February). There is some information about Nyquist-Macros in the “2.3.1 alpha manual” https://alphamanual.audacityteam.org/man/Nyquist-Macros

I don’t have a lot of time to work on this right now - I’m still in the process of documenting these new features. I’ll try to post some relevant snippets over the next week.

Here’s a “proof of concept” for ESTeR as a Nyquist-Macro. Sadly it isn’t “much” faster. I’m not too disappointed by that as I think the speed of the pure Nyquist versions are pretty good, and this is a little bit quicker (on my machine).
I’ve been working on Audacity 2.3.1 alpha (2.3.1 is due for release in February). I’ve not tested on 2.3.0 but I suspect it will not work on any version earlier than 2.3.1.

I’ve left some debugging “print” statements in, but commented out. Uncommenting them may help with debugging / seeing how the plug-in works.
There are also a few other explanatory comments, and some “TODO’s” that would need to be addressed to make this a release quality plug-in.

Despite these shortcomings, I thought you might be interested as it demonstrates several new features.
ESTeR3.ny (4.6 KB)
Oh yes, and I’ve handled space at the end a little differently from your version. This version sets the minimum space after the last sound equal to the length of the last sound.

I’ll be happy to answer any questions you may have about the new stuff.

There appears to be a minor calculation error in this version. For practical purposes it is not noticeable, but when using with the default settings, the silences are about 20 ms too long.

Thank you for the review.

For about 10 second audio(3 tones with 3 silences) with the same calculation results(seg-list), I tried sim and simrep instead of seqrep and got no additional silences successfully.
But, unfortunately, codes using sim or simrep never ends for my 23 minutes language audio file which has more than 300 sentences.

Actually, I can’t use sim, simrep, at-abs, cue, extract-abs, and abs-env well together even though I’ve tried some combinations. I think I’ve spent too much time.
To make this plug-in perfect seems beyond my current knowlege about Audacity and nyquist.

I’m enough happy already because I can make my own training audio files now and I have been more familiar with lisp.

Thank you, steve.

Considering that this type of effect is quite difficult to get right, you’ve done very well getting it to work so well.

If I get time, I’ll see if I can fix that minor inaccuracy and post the result back here. I suspect that it is just a counting error, but it may be best for me to restructure the original plug-in a bit for it to handle the repeats more elegantly.

Great plugin, but it suffers from the same limitations as truncate silence in that it doesn’t have an upper and lower value length setting. Does anyone know of any silence extenders that allow you to specify a minimum and maximum silence length? Example: Extend silence length Min: .4 Max: .7 Meaning extend only silence with a length that falls between .4 and .7 seconds or whatever length you supply.

No, but you could modify “ExtendSilence.ny” from this post: Extend Silences

Probably the easiest way would be, at line 110, when you have grabbed the list of silences, loop through the list and copy all of the entries where the length of the silence is less than the required max length.

Hey, I am doing a language learning audio book and needed a solution to extend my pauses between phrases, wihtout actually having to pause my speech while recording and wait in front of the mic counting seconds in my mind. :smiley: I tried to manually extend the silences myself on Audacity after the recording, but with so many phrases this took me ages. This little plugin worked wonders. It extended all the silences with one click. Whoever the author is, thank you so much, you saved my life!

Wow!.. Steve, Look what my request started almost 10 years ago - Now over 2000 downloads!

I lost touch over the years and didn’t realize that the plugin was continually evolving.

I’m still using the original 2013 version you gave me and it still works perfectly fine.

In fact, I’m currently using it hundreds of times in a new language project.

Recently, I wanted to modify it to automatically drop a blank timing label in the middle of each silent stretch - but I couldn’t figure it out in Nyquist. So I made a keyboard macro - it makes the space, moves the cursor and drops the label - all “semi-automatically”… it kinda works.

Steve - Just want to say: Thanks so much for developing this plugin all those years ago!

You’re the best!

John

Thanks John, you’re very welcome.

I add my voice to all those who appreciate the ExtendSilences plug-in. However, I have repeatedly hit against limitations with it and thought I’d post those here:

  1. If the audio being extended is over 60 minutes running the plug-in doesn’t work. No change is caused to the file. But if I split that same audio into 2 pieces each under 60 minutes, it works fine on each of the pieces (although it takes about a minute). I then combine those pieces.

Here are the typical settings I use when the above happens:

and here is a screen recording of it failing:

ExtendSilenceFail

Notice that when it fails, it only takes about 20 seconds rather than the minute or so for a 60min audio.

  1. I also frequently am limited by the maximum of 10s in “Add silence duration” and 100% in “Add % of previous sound duration” Why not allow larger values, say, 60s and 500%?

I’ve looked through the code and it looks like (2) might not be too difficult to change, but I’d have no idea how to deal with (1). Anyway, .ny code is a great mystery to me and I haven’t been brave enough to try editing. But I would if guided by expert tips.

Thanks

Unfortunately that is a known limitation for this kind of plug-in. Because it is a two pass effect (the track must first be analyzed, and then processed), the selected audio has to be held in RAM (Nyquist can only read the track once), and Nyquist is limited to about 2GB RAM. It’s getting on towards a decade since I wrote this plug-in, and this limitation still exists, so I doubt that the limitation will be removed any time soon.

I posted a comment earlier in this topic about how to modify the input ranges. See the posts dated “Sept '17”.