Date time formatting possible? (For label plugin)

I’d like to either modify the “regular interval labels” plugin or write a new one to create “real” time labels to indicate the actual time at regular points in some long field recordings. E.g. “05:55am”, “06:00am”, etc.

I haven’t looked too hard yet, but are there date/time functions available for Nyquist plugins? I will need to be able to add an offset to the track times, and then to be able to format them as above. Or do I need to write my own?

Nyquist does not have date/time functions, but it should not be too difficult to make something.

For anyone else reading this thread, the background to this topic is here:

What are you after - labels in 5 minute intervals? Half hour intervals?

Not sure yet. 5 minutes will probably be what I try first, but I’ll make it less if it adds so many labels that it turns it into a mess.

I’ll have a play with the existing plugin, as it almost does what I want with a little bit of mental effort. If it annoys me too much I’ll have a go at modifying the plugin, but I can also directly edit the aup file.

It’s a pity those functions don’t exist, they’d make the job much simpler, especially for someone new to the language. I haven’t used Lisp for a decade.

Thanks a lot for your help.

I think this will save you a bit of time (attached).
Feel free to customise it to your needs.
If you have any questions or comments regarding the code please say.

It’s called “Time Labels…” and when installed it will appear in the Analyze menu.
Note that for Analyze type effects there must be a selection.
It will probably be easiest to select the entire track that you are working on as that will put you at the correct zoom level to see the labels when they appear.

The maximum total duration is 11 hours 59 minutes.
timelabels.ny (1.48 KB)

That will do what I want. Did you write this for me today? Thanks, that’s incredibly kind of you.

I’ve also discovered the standard plugin doesn’t work for anything but 1 minute increments because I can’t specify the increment, so no use to me unmodified. Is this an appropriate place to suggest that enhancement for it?

Some comments on the new plugin:

  • I initially thought I couldn’t specify the starting point of the labels, but it seems like I can do that with a selection.
  • This selection needs to be longer than 0 seconds, or it selects the whole thing. I can’t see where in the code it does that.
  • The end of the selection is ignored, which is slightly non intuitive given that the start isn’t. Text explaining how this works would be enough to resolve the ambiguity for most people I think.
  • I don’t know how to control which label track it appears in, I think it uses the uppermost one, but not always. Having it work on the selected track might be handy for people with lots of tracks, but I doubt it’ll ever be anything but a minor nuisance for me as is. It might be worth adding some text explaining which track will get the labels so one doesn’t have to learn by trial and error.
  • I’m not sure exactly how it chooses. At one stage I had two label tracks but it kept adding more each time I used it. It also adds one set of labels to the label track it chooses for each audio track - three audio tracks means three sets of duplicate labels.
  • The ability to add a prefix and suffix would be nice.
  • The ability to add “am” and “pm” automatically would also be nice.

Yes that was written a few hours ago, hence there is no documentation for it and you are the official “beta tester” :wink:

Also the plug-in has no error checking built in, so it won’t stop you from doing anything stupid. I don’t think it will do anything “bad”. Silly values such as negative time are likely to output just one label and stop. I think you’ll need to do something pretty inventive to make it crash.

Several of the points that you raise are standard behaviours for Plug-ins, or for Analyze plug-ins, or for “Nyquist” plug-ins.

  • All Nyquist Analyze plug-ins require that there is an audio selection (more than 0 seconds).
  • All Nyquist plug-ins use the start of the selection as “the start”.
  • If one label track is selected (as well as one audio track), the labels will appear in the selected label track.
  • If several label tracks are selected, (as well as an audio track), the labels will appear in the uppermost selected label track.
  • If no label tracks are selected, a new label track will be created below all other tracks.
  • A slightly unfortunate behaviour (a “feature” of Nyquist Analyze plug-ins) is that each selected audio track is processed independently. That means, if you have 2 audio tracks selected, each label will appear twice (once for each track).

In the case of this plug-in, the “Duration” settings override the length of the selection, which I thought might be useful for anyone that was wanting to make a “time line” and then add multiple recordings along that time line.

Opinion among the Audacity documentation folk at the moment is that plug-ins should avoid excessive text in the interface (more in keeping with the built-in effects), so if that is to be documented it would go into a separate “help” file.

As I said - it’s currently undocumented (other than this forum topic).
If you think that this plug-in might have wider appeal than just yourself, please feel free to write a little “Help” file and post it in this forum topic.

That would be fairly simple to add. Do you want to have a go at editing the plug-in?

There would need to be an additional “control” widget for prefix and/or suffix text. Each of these would be a “Text Input Widget”

As you see from the plug-in code, the “controls” are defined by a line beginning with ;control
We could add prefix and suffix text by adding the following code below (or above or between) the current controls:

;control prefx "Prefix label text" string "" "" ""
;control sufx "Suffix label text" string "" "" ""

This sets the variable prefx and sufx to the (optional) prefix and suffix text. If no text is entered the values will be null strings.

At around line 40 is the “Make labels” function.

;;; Make labels
(defun makelabel ()
  (let* ((nowabs (hm2s hr mins))
        (time (if (>= nowabs start)
                (- nowabs start)
                (- (+ nowabs 43200) start)))
        (text (format nil "~a:~a" hr (pad-mins mins))))
    (setf labels (cons (list time text) labels))))

The relevant part is the second to last line in which we construct the label text:

(text (format nil "~a:~a" hr (pad-mins mins)))

We can simply add in the prefix and suffix text here:

(text (format nil "~a~a:~a~a" prefx hr (pad-mins mins) sufx))

so the Make Labels function now looks like this:

;;; Make labels
(defun makelabel ()
  (let* ((nowabs (hm2s hr mins))
        (time (if (>= nowabs start)
                (- nowabs start)
                (- (+ nowabs 43200) start)))
        (text (format nil "~a~a:~a~a" prefx hr (pad-mins mins) sufx)))
    (setf labels (cons (list time text) labels))))

and that’s it.

I’m not actually convinced of the benefits of prefix/suffix text in each label. I think it makes the labels too cluttered, but please do try it and see what you think.
If label text is to be added to just the first label then it’s probably easier to just manually edit that label.

With “am/pm” I’d probably agree if the tracks were days long, but as the plug-in is limited to less than 12 hours it’s probably easier to just add “am” or “pm” manually in the first label and leave it at that.

I’ve played with this some more with test tracks: I created 8 audio tracks and two label tracks.

*If I make a selection in any one of the audio tracks, the plugin creates a new label track and adds a single set of labels.
*If I select one audio track but don’t make a selection, if that’s the right terminology, it selects them all and adds duplicate labels to the first label track.
*If I select one label track, irrespective of whether I make a selection or not, it selects all tracks and adds duplicate labels to the first label track.

The only way I have any control is to, as you say, select one audio track AND the required label track. I will put that in the documentation, as that will puzzle anyone who isn’t familiar with Analyze plugin behaviour. Only the first case above is probably useful to anyone.

I’ll have a go at adding the prefix and suffix (now that you’ve practically done it for me), and writing up the documentation. Do I submit them here?

1. AFAIK the Audacity Nyquist interface cannot handle multiple label tracks. The code for returning labels from a Nyquist plugin is probably still the code from Audacity_1.0 or something similar old age.

2. There already exists a “Regular Interval Labels” (or similar) plugin, where only the initial time offset is missing. I have not looked in detail if Steve’s plugin is a modified version of the “Regular Interval Labels” plugin, but if not, then it would make sense to combine both plugins instead of creating a new one.

3. In case of doubt post the documentation here into a text box (if Steve doesn’t tell something different).


  • edgar

pshute originally proposed modifying the equal label track. I wasn’t actually planning to write the plug-in, I was just writing some snippets to help pshute do the job, but I got a bit carried away. I don’t know how similar it is to the “Regular Interval Labels” code - I’ve not looked. Basically this is just a “hours + minutes” counter with the “time” output to a list.

Yes just post the “help” here, that’ll be fine.

“Regular Interval Labels” is probably still original David Sky code (that can only be read by a screen reader but not by human eyeballs :smiley:). I will try to find it and then we can see if the old code can be replaced by a new plugin.

IIRC the “Regular Interval Labels” makes nothing but spitting out a list of labels every seconds, but nothing more sophisticated. A plugin with a settable initial time offset and prefabricated labels in HMS (hous minutes seconds) would be of course clearly better.

  • edgar

Few minutes later, already found, it’s one of the “official” plugins under
The source code can be seen under

The Nyquist code is “David Sky style” and the plugin is overloaded with help texts. I’m not really interested to edit such a mess. In case of doubt we should dump the “Regular Interval Labels” and replace it by a new one.

  • edgar

On the same general theme, there is also a “Beat Per Minute labels” plug-in for making “bars and beats” labels.

Trying to sort the plugins somehow:

  • “Beat Per Minute labels” is a Generate plugin.

  • “Time Labels” as well as “Regular Interval Labels” are an Analyze plugins.

Having read Beat Per Minute labels thread I think that the functionality of “Beat Per Minute labels” is different to “Time Labels” or “Regular Interval Labels”, so I think that “Beat Per Minute labels” shold be left a separate plugin, but “Time Labels” and “Regular Interval Labels” could probably be unified.

I just realized that a “Regular Interval Labels” plugin is part of the official Audacity distribution. I installed the “Regular Interval Labels” download version from the Audacity homepage in ~/.audacity-files/plugins and suddenly I had two “Regular Interval Labels” plugins. On a closer look it turns out that the GUI of the two plugins is pretty much different. To me it looks as if the “Regular Interval Labels” plugin included in the Audacity distribution is a much later and better version of the “Regular Interval Labels” plugin from the Audacity homepage, what seems to be an original David Sky plugin.

Question: What is the deeper sense of having two different plugins with the same name, one as part of the official Audacity distribution, and a different one with similar functionality as an additional download on the the Audacity homepage?

“Time Labels” vs. “Regular Interval Labels”

The code of “Time Labels” to me looks much better than the code of “Regular Interval Labels” from the Audacity distribution, but the question is if there are fundamental differences in the use-cases? Also, adding the “Time Labels” functionality to the already existing “Regular Interval Labels” plugin would mean to overload the “Regular Interval Labels” GUI even more than it already is. And even if we add three sliders for hours, miutes, seconds, the next user would come and ask for milliseconds or samples, because Audacity selections usually do not start at full seconds.

Question: Is there any good way known how to specify times in hours, minutes, seconds, milleseconds, samples, beats-per-minute, and whatever time units exist, as text in a text input widget? This would save a lot of sliders. Unfortunately the Audacity Nyquist interface cannot read the time from the Audacity timeline.

I think specifying an “easy to understand” text input format is the main problem in this case, everything else would be rather trivial to implement.

  • edgar

Yes the one on the Audacity site Nyquist plug-ins is the original David Sky plug-in.
I did some bug fixing on it back in 2010, then added enhanced label numbering, error checking, and a couple of other bug fixes in 2011.
I tried to keep close to the original but in the end needed to make fairly substantial changes to the code layout so that I could see what was going on.

The Audacity site Nyquist plug-ins page is due (overdue) for retirement. It is in the most part superseded by the Download Nyquist Plug-ins page on the wiki
One of the hold ups is that I need to go through all of the plug-ins on the Audacity main site page and check if any still need to be transferred to the wiki page. Also, we’re not sure what to do with “retired” plug-ins. I’d like there to be an archive of some sort for old plug-ins, particularly as David’s web site no longer exists.

Regarding plug-in names - I don’t think that any of the Audacity effects have version numbers shown in the GUI. Where different versions of Nyquist plug-ins exist there should be at least version number or date in a comment block near the top of the code. In the case of the equalabel.ny plug-in there is quite an extensive comment block with the plug-in history:

;; Regular interval labels by David R. Sky, June-October 2007.
;; Code for label placement based on silencemarker.ny by Alex S.Brown.
;; Released under terms of the GNU General Public License version 2
;; .
;; Thanks Sami Jumppanen for plug-in suggestion.
;; Thanks Dominic Mazzoni, Pierre M.I., Gale Andrews 
;; for improvement suggestions.
;; Disallow labels before zero by Steve Daulton, September 2010.
;; Enhanced label numbering by Steve Daulton, April 17th 2011.
;; Error checking by Steve Daulton, April 18th 2011.
;; Final Label bug fixed and minor GUI modifications. SD Apr 2011
;; Requires Audacity 1.3.4 or later.

Personally I’d prefer that they were all Generate plug-ins, but currently if a Generate plug-in is run without an audio track selected then an empty audio track is produced.
My reasoning is that all of these plug-ins “generate” labels. They do not “analyse” anything.
One of my “feature requests” is for Generate type plug-ins to not create an audio track until the code is executed, and then to only create the audio track if audio is returned. Currently an audio track is created before the code is run.

I think there probably are.
In the case of both “Time Labels” and “Beat Per Minute labels”, these were written to provide functionality that is missing from the Audacity “Time Line”.

The most common usage for “Regular Interval Labels” is for splitting tracks with “Export Multiple”.
I’m currently working on a plug-in that sets markers close to regular intervals but adjusts the label position so that labels occur during “silences”. This option is intended primarily for people wishing to split lecture recordings or audio books into shorter tracks. While related to “Equal Labels” this plug-in is more closely related to “Sound Finder”. This plug-in is not yet complete but it may make the “Regular Interval Label” plug-in redundant (unless a more simple “Regular Interval Label” is also wanted).

The danger of Feature Creep :smiley:

Text input is a possibility. The down side is that the approach is prone to user error as the user must use exactly the correct format in order to get the expected results. Not to forget the problem with commas as decimal separators :imp:

Another possibility that may help the situation would be for a “multiple input” widget, similar to a text input widget but with the text box split into multiple “fields”. Of course this would require one of the Audacity developers to take an interest in further developing the Nyquist plug-in GUI.

Many hours later:

Looking at the Audacity source code I see that in “audacity/src/effects/nyquist/nyquist.cpp” the initial value for the Audacity Nyquist “len” variable is computed from the absolute start and stop times of the Audacity selection, in function “EffectNyquist::Process()”:

mCurStart[0] = mCurTrack[0]->TimeToLongSamples(mT0);
sampleCount end = mCurTrack[0]->TimeToLongSamples(mT1);
mCurLen = (sampleCount)(end - mCurStart[0]);

Here “mCurStart[0]” holds the value of the abolute start time of the selection in the Audacity track, “end” holds the value of the absolute stop time, and “mCurLen” holds the value that is later assigned to the Audacity Nyquist “len” variable.

This means it would be possible to give the absolute “start” and “stop” times in some variables to Nyquist, where I first must look-up how this could be managed via the Nyquist transformation environment instead of brainlessly introducing two further “start” and “stop” variables.

Question: Are there any specific use-cases for this (beside the obvious usefulness in the “Time Labels” plugin)?

  • edgar

Well you’d only need to introduce one new value as we already have len.

The first thing that people would want to do is to place sounds at arbitrary time positions, but for Nyquist “time zero” is the start of the selection. If I have a plug-in that produces a sound at say t=10 seconds (Audacity timeline) then that’s fine as long as the selection begins at or before t=10 seconds, but if the selection begins after t=10 then it will fail because Nyquist cannot create a sound at negative time. This is unless Nyquist used absolute (Audacity) time so that Nyquist time zero is the same as Audacity time zero, but that could have a lot of major knock on effects.

The “len” variable was a mis-feature, that had been later repaired by putting the length into warp, in order to make (get-duration 1) work. Only for backwards compatibility the “len” variable was never removed. I do not want to build another mis-feature on an existing mis-feature.

The main problem is the the physical Nyquist start time 0.0 is the absolute start time of the Audacity selection. Changing this will cause lots of problems, because Audacity cannot start inserting sound samples outside of the selection. It’s only possible to extend the selection if the first sample is inserted inside the selection.

The only valid solution would be to rewrite the Nyquist snd-read and snd-save functions to give Nyquist access to the AU-files in the Audacity project folder, so Nyquist could copy and paste at arbitrary times of all Audacity audio tracks. But this is a major undertaking that probably never will happen.

The question is if it makes sense to add another mis-feature variable for a functionality that is nearly never needed?

  • edgar

That’s exactly what I was thinking.

I think we’d need a compelling reason to do so, but I can’t think of one.

An Audacity variable that I do think would be useful is the absolute min and max values of the sound - that would enable us to normalize before further processing without running into memory problems.

I’ve modified equalabel.ny to include the time labels I wanted, the file is attached below. I think this version is working ok. I’ve also made a few cosmetic changes with wording on the form, hope I haven’t trodden on any toes as I’ve read some postings where the wording was thrashed out.

Changes include (working down the form):

  • Changed “label placement method” to “label spacing method”
  • Changed the wording of one of the choices for that control from “Label interval” to “Fixed interval”
  • There are now two text fields - one to prepend, one to append - and it always does this. If people don’t want that then they can blank them out. This simplifies the number of choices in the next control.
  • “Maximum number of digits in labels” is now “Labels style” because the former made no sense when applied to h:mm style labels.
  • The choices are now
;control labelnum "Labels style" choice "Text only,Min 1 digit between text,Min 2 digits between text,Min 3 digits between text,h:mm between text" 2

instead of

;control labelnum "Minimum number of digits in label" choice "None - text only,1 (before label),2 (before label),3 (before label),1 (after label),2 (after label),3 (after label)" 2
  • Added hours and minutes sliders as an alternative to the “Begin numbering from” slider, to be used when the h:mm style is chosen
  • Choice of whether to add am/pm or not. I think that will be helpful for anyone with times crossing midday or midnight, if indeed anyone other than me ever uses it. Probably should allow for a 24 hour format too, but I haven’t.
  • “Adjust label interval to fit length” is overriden with “No” if h:mm style is chosen, as I suspect people won’t want their chosen interval messed up for h:mm.
  • I’ve reindented some bits of code and moved a few parentheses around to help me understand it, sorry I know people have their favourite ways of doing that. My way uses a lot more vertical space than the original code.

I haven’t done much testing of the non h:mm styles, but I think my changes shouldn’t have affected them. I’ve tested the h:mm code on some big files, with some odd results. A freshly opened 12 hour files worked ok with 5 minute labels, but a 3 day file kept complaining that I had only selected 1 second, then behaved oddly till closed. It was only labelling the first few hours.

I’m not sure how many people will have files longer than 12 hours.

I’d appreciate if someone would try it out and comment. It’s my first plugin work, and my first play with Lisp since about 2000.

Edit: Just found an am/pm bug, fixed and file replaced.
equalabel2.ny (8 KB)

There’s a bug in Audacity that causes the length to be calculated incorrectly above 2147483647 samples (2^31) which is about 13 1/2 hours at 44.1 kHz.

This is listed in the Release Notes but the issue is a little more widespread than suggested there:

Known Issues at Release
Headline issues
Large Projects

Projects with more than 2^31 samples (just over 13.5 hours at 44100 Hz) will not re-open correctly. Higher sample rates mean proportionally shorter times - so just over 6 hours at 96,000 Hz. We know the cause, and do intend to address this bug. Workaround: Before saving or closing the project, export to audio files of appropriate size, or cut and paste sections of audio containing less than 2^31 samples to new Audacity projects and save those.