Nyquist Programming in C ?

Hi all,

New to Nyquist programing with the aim of making plug-ins for Audacity and “tuning” it with more functions that I find useful.

My question is, are Lisp and SAL the only options to program in?

I’m really struggling with Lisp, just find it completely weird (especially the brackets and quoting) and judging my the very small amount
of people making Nyquist plug-ins, I’m not the only one.
Even a cursory look at a simple introduction to Lisp https://www.cs.cmu.edu/~dst/LispBook/book.pdf is enough to send many running for the hills.

Also read somewhere on this forum, that the Audacity user base that dabble in Nyquist (and hence Lisp) is probably much less than 1%.
Wondering if the actual Lisp language does not have a lot to do with this very small uptake.
Audacity is one of a few (or even the only) sound recorder/editor that allows scripting and making plug-ins without one having to resort
to the complexities of VST, AU or LADSPA compiled plug-ins.

The way I see it, there are many more sound enthusiasts and professionals that know (or are willing to learn) C versus Lisp.

SAL on the other hand, is much easier, makes more sense (to me anyway) but unfortunately, there is very little in the way of SAL examples and code.

So, anyone know of a good resource for SAL code/examples or perhaps contemplating a C to Lisp converter for Nyquist under Audacity?

In summary, I think it was a stroke of genius for the developers of Audacity to include Nyquist but the Lisp part is really off-putting.

Just my 2c worth.

Paul

+1 on the whole post. You’d think there’d be way more people writing plug-ins and I suspect LISP is a big reason for the lack. I struggle with it, give up, then come back to try again and it’s not like I’m a complete stranger to programming. Anybody got a BASIC to LISP converter? :nerd:

Funny you should ask that… :wink: been searching all over the net and found something that may just fit the bill.
It’s essentially a BASIC parser/lexar written in javascript+html that allows BASIC code to be run in a web browser.
However, it should be relatively easy to press it into service to convert BASIC to Lisp syntax, in fact can think of two ways to do that.

I have created a zip file with all the required files and more help and information is in the included pdf file.
Will also attach the pdf by itself.

@Steve

Since you are the local Lisp guru, care to also have a look and see if you could help out, time permitting?
I think it will be a great project to hopefully get more people interested in writting plug-ins and thus further increase Audacity’s versatility.

Thanks.
Paul
AboutSimpleWebBasic.zip (36.7 KB)
SimpleBasicInterpreter.zip (74.4 KB)

The Nyquist manual is the best source for SAL documentation: https://www.cs.cmu.edu/~rbd/doc/nyquist/

Personally, I much prefer LISP syntax to SAL, but that is probably because I came to Nyquist with very little previous programming experience. It seems simple to me that virtually everything is in the same form:

  • Open parenthesis
  • Function name
  • List of arguments
  • Close parenthesis


That’s the big problem :smiley:

I started work on a graphical language, based on Blockly, but never had time to finish it. One of the main Audacity developers is interested in developing a “block” style visual editor for handling Audacity preferences and menus, so in the long term, that may also be used for writing plug-ins and macros - but that’s likely to be a long way off. In the shorter term, I think it might be most useful if I can find time to write more Nyquist tutorials - particularly simple ones to help people get started.

Hi steve,

Thanks for your feedback.

Blocky does look interesting, especially if it could be used as an “abstraction” layer to Lisp.
The user just puts blocks together and it creates the required functions in Lisp, even if it means copying and pasting to the Nyquist prompt.

Similar type “block” based projects include, scratch https://scratch.mit.edu/ and
node-red https://nodered.org/ and Flow (can’t seem to find a web site for it).

Your idea of Nyquist tuts for beginners is also a good one, especially if accompanied by some videos.

Paul.

I apologize for taking a three year break from this thread! As I said, I try to work with LISP, give up and then later come back to try again. I’m in the try again phase. A question or comment- I think one problem with LISP programming is a non-intuititive choice of variable names. In other languages people will use meaningful names like “rocknumber” or “cyclecount” or “voltage” or “hairsblonde”. In LISP is seems cryptic single-letter mysteries are the rule. Is this just for the simple examples or is there some history or reason things aren’t more readable?

There is no reason as to why LISP variables should be non-descriptive names.
Other than the usual rule of, don’t use reserved words, it’s pretty much up to you.

Below, part of some of Steve’s code from one of his plugins:

;control text "Aligns the second selected track to the first selected.\n"
;control threshold "Detection threshold" float "" 0.5 0 1
;control channel "When stereo track" choice "Use Left,Use Right" 0

;; Maximum number of samples to analyze
(setf maxlen 1000000)

As can be seen, Steve used sensical names for the vars, “text”, “threshold” and “channel”.

As a side note, when I first started with Nyquist, I preferred SAL as it looked more familiar.
However, it’s been a while now and have come to enjoy LISP and actually prefer it over SAL.
Still trips me up at times though.

As Steve wrote several posts above, the important things in LISP are:

Open parenthesis
Function name
List of arguments
Close parenthesis

A good editor (that understands the syntax) is also hugely beneficial.
For Windows use Notepad++, for the MAC, Sublime text and for Linux, Geany.
Those are my go-to’s anyway, as they have syntax highlighting and will show you matched pairs of parentheses,
or when one is missing.
Very important with LISP.

I would always recommend using meaningful names for functions / variables / classes… with the exception of local variables that have very restricted scope.
A couple of examples where I think it’s OK to use a short, or single letter names:

(defun iterate-hp (sig hz n)
  ;;; Apply high pass filter multiple times
  (dotimes (j n sig)
    (setf sig (highpass2 sig hz))))

(iterate-hp *track* 1000 4)

In the above example, the name of the function is “iterate-hp”, which I think is reasonably meaningful for a function that applies a high pass filter multiple times. Given that functions may be called from anywhere in a program, it is particularly important that they have meaningful names.

The function arguments “sig”, “hz”, and “n” are all quite short names, where:
sig = sound (singal) being passed to the function
hz = filter frequency in Hz
n = number of times to apply the filter
The final argument “n” is possibly a bit cryptic, but given the context of “applying something n times” is still reasonably obvious in my opinion.
Although “hz” is only a 2 character name, it is obvious.

The variable “j” is virtually meaningless, but it has very limited scope as it is simply being used as a loop counter. The scope is limited to the two lines if the “dotimes” block.


Unfortunately, many of the very old Nyquist plug-ins were written rather badly. This is understandable when considering that they were mostly written by Audacity users that were total beginners to any kind of programming. Some of my early attempts at Nyquist programming make me cringe at the poor style, though I always try to improve my programming and follow “best practices”.

I’ve published some guidelines about some of the common “best practices” here: https://audionyq.com/indentation/

Excellent best practices, very useful- thanks!
Conrad

I’ve started to figure this out and have a working plug-in. Thanks for the assist! I’ll start a new thread for what I’m doing.
Conrad