Yet another command line request --> Sound finder.

I couldn’t find a thread about command line support for exporting labels (Specifically, those generated by “analyse” tools), so I thought I’d post this request:

I’m trying to to encode and decode text into Morse (-code & audio). So far, the text conversion and code → audio conversions have been completed, but I’m stuck at the audio → code part.
After trying SoX’s .dat output, their “stat” function, as well as ffmpeg’s “silencedetect”, I found out about audacity’s “Sound finder” function (Though I’ve been using audacity for years). compared to SoX and ffmpeg’s output, audacity’s is a lot more accurate, not to mention easier to parse.
The only problem is that I’d have to open audacity for each file, manually.

So, for that reason, I’d like to request command line support / output for the various analysing functions in audacity.

The “Sound finder” function is written in “Nyquist”
Have a quick look at these two links for an overview:

It is possible to open files directly with Nyquist, though quite tricky to do so in a way that is cross-platform compatible due to differences in directory structures.
Nyquist is also available as a stand-alone programming language for audio ( )

Nyquist plug-ins are not currently supported in Chains (Audacity’s batch processing mechanism) though if you are able to build Audacity from the source code then there is a patch available here that adds this functionality:

Cross platform programming shouldn’t be a problem, here, since the tool’s only going to be running on a windows machine (I’m accessing the tool through php, for a web app, hence the need for command line support)

Now, I found the Nyquist plugin, installed nyquist, but to be honest, I have no idea how I could run it on a sound (After editing the plugin so it won’t try to add labels anywhere).
I managed to play a sound, though, and I think I can figure out how to change the plugin so it will just output the labels, but getting it to load a file, then run through the file…
Does anyone happen to know of any examples using nyquist though the command line?

i just found this link, containing a nice example on nyquist usasge through a .bat file: ( )
Now I just need to figure out how to load a file into it. s-read is throwing a error (I don’t quite recall it, not at my PC at the moment), but it seems Nyquist isn’t executing/loading the files in the runtime directory.

See the README.txt files in the Nyquist source.

The “labels” are created by Audacity not by Nyquist.
When the return value from Nyquist is a list in the following format, Audacity will create point labels:

((number "string") (number "string") ... )

I expect that you don’t actually need “labels”, just the data.

Unless you specify an absolute address, s-read will look for the file relative to the default sound file directory (defined by the global default-sf-dir)

With console I mean windows’ cmd console. Figured out how to run it from there, though, so that’s no longer a problem.

Now, since Nyquist seems to refuse to load the /runtime/ files, I looked up the functions it used from there, and copied them over to (a copy of) SoundFinder.ny. (I did create the “init.lsp” file in my Nyquist installation folder, as well as adding the registry key)

When I try to execute it on wav.wav, it throws a error: “error: bad argument type - 0.21”. I’m pretty sure it has to do with

(setq s1-srate (snd-srate (my-s s)))

on line 199. if I change that into:

(setq s1-srate 44100)

it runs through the file just fine, aside from it not finding any sound (probably some incorrect settings).
I’m not quite sure what to look for, to fix that error. Any tips?

(Since I’m kinda turning this into a “Nyquist help please” thread, does this thread have to be moved / continued in the proper subforum?)

SoundFinder.ny (11.8 KB)

Looks like I’ve got it :smiley:

Once I had the Soundfinder.ny running through windows’ CMD, all I had to do was make the plugin write the “l” (labels) list to a file, instead of returning it.

(setq l (reverse l)) //For some reason, I have to reverse it. It seems labels are prepended to the list, instead of appended.  Ah well. :P
(setq fp (open "output.txt" :direction :output))
(print l fp)
(close fp)

which returns the list in a format I can easily parse: ((0.21 0.31 “1”) (0.41 0.51 “2”) (0.61 0.71 “3”) (1.01 1.31 “4”) (1.41 1.71 “5”) (1.81 2.11 “6”) (2.41 2.51 “7”) (2.61 2.71 “8”) (2.81 2.91 “9”))
((Starttime endtime “number”)(etc))

Well, thanks for your support, steve! It’s very much appreciated.
Although my “command line support” request still stands, I won’t be needing it for this specific case, any more.

(setq s1-srate (snd-srate (my-s s)))


The innermost part of this command (my-s s) calls the function "my-s" and pass "s" as the argument.
"S" is a special global variable that is specific to the Audacity implementation of Nyquist. Audacity passes the sound from the audio track to Nyquist as the value of this symbol. If the track is a mono track then the value of "s" is a sound object. If the track is stereo then the value of "s" is an array containing two sound objects (one for each channel).

To modify the plug-in for use with the standalone version of Nyquist you could set "s", for example for a mono, 16 bit, 44100 Hz WAV file, something like:

(setf s (s-read absolute-path-to-file))

At the moment, the plugin’s working, standalone, but there’s a small difference with how you suggested setting the “s” variable. What I have:

(setq s (s-read (strcat "C:/TextEncoder/a/generated/" folder "/wav.wav")))

(folder is a variable 32 character hash string)

Is there a significant difference between setf and setq?

I presume that’s a typo :wink:
That command looks fine.

“setf” is a more powerful command than “setq” though often they are interchangeable.

“setq” stands for “set quoted”
If you try to set the value of an undefined symbol without “quoting” the symbol, you will get an error:

(set var 10)
> error: unbound variable - VAR

because LISP tries to evaluate “VAR”.

(set 'var 10)

works as expected but is more usually written:

(setq var 10)

“setf” stands for “set field”
When used with simple symbols and values it will behave the same as setq except that it makes use of the full namespace of the symbol.
An example of when you must use setf rather than setq is if you wish to set the value of an element in an array.

(setq (aref myarray 1) val)
> error: bad argument type - (AREF myarray 1)

should be:

(setf (aref myarray 1) val)

Whoops! Fix’d.

Thanks a lot for your explanations! It was fun getting to know this language a little, especially now that I’ve got results rolling out of it :smiley: