Expression Generator

I have …

Looks like this …

Yes, that did the trick. Appreciate your quick reply on a three year old thread :slight_smile: Thanks Steve!

Hello there. This is my first reply to a thread on this forum, so I might not fit in the atmosphere.

… wow. The last reply is almost 4 years old?! This thread is getting way less attention, than it deserves.

Anyway, I’ve noticed a problem/phenomenon with the interpretation of the plug-in.
Specifically, the ‘power’ function is causing me some issues with the output of the plugin.
Initially, I wanted to Implement a very simple function to generating a periodical square wave.
That function being:
squarewave(x) = (-1)^⌊2x⌋ ; x ∈ ℝ.
Since the floor function doesn’t seem to exist in Nyquist language, as far, as my research goes (List of functions), we can rewrite (-1)^⌊2x⌋ to (-1)^round((* 2 x)-1/2) instead, which is basically the same.
Cool, I thought, converting it into LISP as: (power (- 1) (round(- (* 2 x) 0.5))), plotting from -1≤x<1, with a lenght of 1s/128 and uuh…
It returns a track, with every sample, seemingly at +INF. I assume, that’s because the track is in ‘32-Bit float’, with the datatype ‘float’, being infamous for having ±INF values, which are often unchangable by definition (I’ve btw figured out a half-solution to this, by changing the track’s format to any PCM one, setting every sample to ~0, just after starting to write this). Now, this seems to be, because of 2 problems. The first being, that the ‘power’ function is kinda messed up, maybe? I don’t want to slam down wrong statements, here, but the function seems to fail to plot something as simple as x² (power x 2), over -1≤x<1

, although x×x (* x x) seems to work fine.
It seems to not handle the power of negative numbers, very well… although in this case, the exponent is always an integer.
Funnily enough, it has no problem plotting 2^x (power 2 x) instead, even for negative numbers, which I find pretty impressive, to be honest.
That somehow just works. After seeing previous replies to this thread, not stating this issue and me from experience, never noticing this in the past, I’m just gonna assume, it’s because of newer Audacity versions.
Also, there’s tons of functions on this thread, having singularities/discontinuities via. division by 0.
These functions would never generate on my side (and understandably so), while it did on their end.
I’ve noticed, that there would be a prompt with exceptions, explaining on what went wrong on older versions of Audacity, while in the current version… the plugin window just closes with no message box, without generating everything.

I know, I’m sounding like the definition of complaining and I am sorry about that, but I would gladly appreciate any info and or tips on this topic. I’m honestly baffled at how unknown this plug-in is, since this is basically my dream, come true. Thanks for understanding and especially, reading this.

Have a beautiful day.

GoldWave has something similar, (if you need a plan B)
https://www.goldwave.com/features.php#Evaluator

You’re correct that Nyquist’s power function does not handle negative values.

(print (power -2 2)) ; returns -nan

If you look at the Nyquist source code, the power function is defined as:

;; power -- raise a number to some power x^y
;;
(defun power (x y)
  (exp (* (log (float x)) y)))

and the logarithm of a negative number is not a real number.

Hello Trebor and thank you very much for your suggestion. I’m gonna try that out, if every other idea fails.

Good day steve.

Thanks for your detailed explanation on the function. With your help, I might find a workaround to this. Thank you alot!

I gave a simple example of generating a square wave earlier in this topic:

(if (< (rem (truncate (* dur 10 x)) 10) 5) 0.8 -0.8)

Thanks for the tip, although this function isn’t equal to (-1)^⌊2x⌋ and thus, not working for me.
The general definition of the square wave 4⌊x⌋-2⌊2x⌋+1 (* (+ (* 4 (round(- (* 0.5 x) 0.5))) (* (- 2) (round(- x 0.5))) 1)) still works of course, which is what I’ve been using before, since this function is actually continuous.

In hindsight, I should not have stated the issue with powers of a negative base before, if (power (- 1) (round(- x 0.5))) would at most just have been a bit shorter, than the function before (if it worked, that is).
Usually, it’s not an issue, if a function is unnecessarily longer, than it has to be, especially, if the LISP function textbox literally doesn’t seem to have any limit, regarding the input string.
In the case of Xfer’s Serum VST, which happens to be the only program, which has a parser for function-to-wave purposes that I could find… it, for some reason has a character limit of 255 (as of my testing), documented nowhere, that becomes a real problem, when trying to input functions, consisting of “infinite” sums, or heavy frequency modulation.

Thank you for your support, steve.

You could modify the Expression Generator plug-in by adding these two functions below the ;control lines:


(defun floor (val)
  (if (>= val 0)
      (truncate val)
      (truncate (1+ val))))
(defun pow(val n)
  (setf rslt 1)
  (dotimes (i n rslt)
    (setf rslt (* rslt val))))

Then write your expression as:

(pow -1 (floor (* 2 x)))

Oh. Thank you so much. You’re such a helper!
Unfortunately, the ‘floor’ function doesn’t seem to be accurate enough, so after some struggling with this programming language, I’ve rewritten it to

(defun floor (val)
  (if (or (> val 0) (= val (truncate val)))
      (truncate val)
      (truncate (- val 1))))

.
That seems to work. For the pow funtion… I’ve figured out the integrated ‘expt’ function… which has no problems, handling negative bases, too (as long, as the exponent ∈ ℤ, obviously).

So, finally, we can write (expt -1 (floor(* 2 x))); -1≤x<1, press ‘Generate’ and…

It doesn’t generate anything, once again. *Sigh. At this point, I was kinda on an emotional rollercoaster.
Eventually, I’ve figured it out (I think). Apparently the first argument must(?) contain ‘x’ for some reason,
so trying out something as stupid as (expt (- (* 0 x) 1) (floor(* 2 x))) instead:


… ‘Wow. That worked?’

Uhm… okay. So there, we have it: a LISP expression, for easily making square waves:
(expt (- (* 0 x) 1) (floor(* a x))); a ∈ ℝ; a = amount of cycles; -1≤x<1 (don’t forget to add the floor function)
Keep in mind, that this doesn’t account for phase, so you’d have to figure that out, on your own.

I know, this is a forum, but in case, you’re curious, what I’m doing with this: Try: (/ (+ (expt (- (* 0 x) 1) (floor(* 50 x))) (expt (- (* 0 x) 1) (floor(* -63 x))) (expt (- (* 0 x) 1) (floor(* -75 x)))) 3); Values of X from = -1; Values of X to = 1; Length of output = 0.390625, for example.

Yep. That’s an approximation of a major chord in the 0th inversion at C3 (A4 = 256*2^(3/4) ≈ 430.53896, or easier: C4 = 256), in 12-tet. I’m doing a lot of other chords, too and with a lot more periodical waveforms as well.

A big Thank you! to you, steve, for providing me with tips and in-depth information on the plug-in and especially, the creation of it.
Thank you too, Trebor, for your contribution.

Have a wonderful day.

Oops, sorry. It should have been:

(defun floor (val)
  (if (>= val 0)
      (truncate val)
      (truncate (1- val))))