Known problems of Nyquist Generate plugins

Quotes from the Nyquist Wish List, posts 155498, 179094, and 179118:

Looking at the code in audacity/src/effects/Generator.cpp (that’s where the empty audio track is created) I see that the problem is that Audacity creates the sound block-wise (the .au files in the _data directory), so the Audacity sound infrastructure must be initialized before the sound is generated. This is a reasonable behavior, because otherwise Audacity would crash if the generated sound is bigger than the computer’s memory.

The proceeding is approximately like this:

  • Initialize a temporary memory buffer and draw an empty audio track
  • Compute samples until the buffer is full, draw the related part of the waveform and write the buffer into an .au file
  • Repeat the second step until the sound is fully generated

Drawing the waveform step-wise from the samples in memory is faster than from samples read from disk. But working this way also means that the creation of the Audacity sound object cannot be delayed until the code from a Nyquist plugin has finished (to investigate if the returned value is a sound or a label list), because if the returned sound is bigger than the memory, then at that time Audacity already would have crashed.

This is the reason why in case of a Nyquist plugin, the empty audio track is created first, then the plugin code is run, and if the plugin returnes a value that is not a sound, an empty audio track remains. The other reason is that the built-in Audacity Generate effects do not return anything other than a sound, so there is no infrastructure provided to remove the empty audio track if the returned value is not a sound. But it probably would look the same kind of annoying if first an empty audio track appears that some time later mystically disappears again.

Another problem is that the only reason why returning label-lists works with Process and Analyze plugins is that these plugins compute the sound in memory, so the returned value can be tested for being a sound, a string, or a label-list. This means that fixing the Nyquist memory problems would make it impossible to return strings or label-lists from Process and Analyze plugins, too.


  • The infrastructure in Generator.cpp would need to be rewritten to make Nyquist Generate effects produce label lists only, or multi-channel sounds.
  • The Nyquist s (= sixteenth) variable would need to be clobbered again to make it possible to detect the number of channels for multi-channel sounds.
  • Using the Nyquist s variable for the Audacity sound object was the most stupid idea ever.

We need a better Nyquist infrastructure. The particular problem here is that rewriting the Generator.cpp infrastructure is a non-trivial task.

I still think that putting “Regular Interval Labels” into the Analyze menu is a bug, but I also have no idea how to change this in an easy way.

Question: Has anybody an idea how a Nyquist plugin could signal the return-type (sound, string, label-list), e.g. at the time after the plugin header has been parsed by the Audacity Nyquist interface?

  • edgar

As the infrastructure in Generator.cpp i not likely to be rewritten in the foreseeable future and without that it is not possible to avoid creating an audio track for Generate plug-ins, what’s the practicalities of going back to the former suggestion of not requiring a selection for Analyze type plug-ins?
I agree that it is peculiar to have an “Analyze” plug-in that does not analyse anything, but that is the situation that we have always had and you seem to be saying that it can’t be fixed (without rewriting Generator.cpp), so would it be better to improve the current situation by not requiring a selection than doing nothing?

I wanted to understand the source code and start rewriting, instead of whimsically whining.

That would be nothing but piling bugs on bugs, and make Audacity worse than it already is.

  • edgar

If you’re able to that then that is brilliant and imho much the best option.

I totally agree about not building on bugs, but this is arguably a quirky “feature” rather than a bug. If the Analyze menu is for effects that “analyze audio” and the Generate menu is for effects that “generate audio”, then “Regular Interval Labels” is no more of a “Generate” effect than it is an “Analyze” effect, but there remain the question of which menu it goes into.

“Regular Interval Labels” could perhaps be said to “analyze time” and so go into the Analyze menu, or it could be said to “generate labels” and so go into the Generate menu. Taking a fresh look at this I don’t think that if fits well in either of these menus but would fit better into the (currently unused) “Tools” menu (where the Nyquist Workbench used to be).

Sounds reasonable, I will try to find out if it is possible to create a fourth Nyquist Tools plugin category. There are also other Nyquist plugins that would fit into a Tools category. Then Nyquist Generate plugins could be restricted to audio generators only and the Generate problem would be reduced to the question how to generate stereo sounds via Nyquist plugins.

  • edgar

How about including that information in the header?

;nyquist plug-in
;version 4
;type generate
;return sound2
;name "Stereo Noise..."
;action "Generating Stereo..."
;info ""

;return [ sound(number of channels), label-list, string, none, default ]
If not present, defaults to mono audio for Generate type plug-ins.

Any reason why not:

  • Initialize a temporary memory buffer,
  • Draw an empty audio track if no audio track and Compute samples until the buffer is full,
  • Draw the related part of the waveform and write the buffer into an .au file
  • Repeat the second step until the sound is fully generated

Because then the user can’t choose what type of object shall be returned:

;control return-type " " choice "Sound,String,Labels" 0

Defining the return type in a special plugin header line also would make it necessary to be able to define multiple return types, e.g. a sound in case of success or a string in case of an error. With multiple return types nothing would be won.

I see that my question was wrong. What I meant was “Has anybody an idea how a Nyquist plugin could signal the return-type (sound, string, label-list), e.g. at the time after the plugin window has disappeared and before the Nyquist code below the plugin header is executed?”

I think that creating an additional “tool” plugin category probably will solve this will less quirky behaviour.

Because this behaviour is hardwired into the Audacity “Generator.cpp” code, used by all builtin generators. Changing this needs substancial changes in the Audacity code, that also would affect the behaviour of all existing builtin generators.

  • edgar

Are you saying that it’s not impossible, but probably more trouble than it’s worth?

There has previously been a “Tools” menu item. I’ve not checked but I presume that it still exists and is currently unused?