New Plug-In: Transmorpher

<>

<>

I tried with the following settings:

Slow Morpher = 100
change = 1000

Transmorpher = 100

everything else at default values.


Should that create a pitch shift of -10 semitones?

<>

That’s what I thought, only I’m not getting that. I’m getting about 1 semitone shift, and short of using your computer I think that I am meeting all of the conditions.

No problem with that - Tuners and other audio plug-ins often use semitones and cents.

<>

Yes delay + resampling can produce some cool effects.

So I presume that is a bug then? Are you going to fix it or leave it as it is?

<>

An interesting read, though I think that you are confusing Structured programming and object oriented programming. They are two distinctly different paradigms.
Although OOP is possible in Nyquist, it is rarely used in Audacity plug-ins. I’ve not used objects in any of my plug-ins - in fact out of all of the hundreds of plug-ins that I’ve seen, I only recall ever seeing one that uses objects.

“Defun” has nothing to do with OOP. Functions are used in OOP, just as functions are used in all Nyquist code. There’s virtually nothing that you can do in Nyquist without using functions. +, -, / and * are functions. SND-XFORM is a function, as are all the other SND- functions.

“Defun” is merely a way of creating your own functions in addition to the built in functions. To put it another way, it is a way to modularise your program.

Something that you are well familiar with is the “+” function for adding values. If you have two variables “var1” and “var2” and you want a third variable “var3” to have the value of the sum of var1 and var2, you would probably write something like:

(SETQ VAR3 (+ VAR1 VAR2))

I would write:

(setq var3 (+ var1 var2))

but they are both essentially the same.


Now let’s say that rather than just adding var1 and var2 we were doing something a little more complicated.
For example if we want to set var3 to a percentage: (var1/(var1 + var2)) * 100

This could be written as:
(SETQ TEMP1 (+ VAR1 VAR2))
(SETQ TEMP2 (/ VAR1 1.0 TEMP1))
(SETQ VAR3 (* TEMP2 100))

or in a more condensed form;
(setq var3 (/ var1 0.01 (+ var1 var2)))

both versions are essentially the same, but both require a fair bit of typing.
Now imagine that we have a plug-in that needs to calculate percentages such as this, not once, but a dozen times. That’s a lot of typing and potentially a lot of places to make errors.
Wouldn’t it be useful if, just as there are built in functions for add, subtract and so on, if there was a built in function that would calculate our percentage, then all we would need to do each time would be to write something like:
(SETQ VAR3 (PERCENT VAR1 VAR2))

However, Nyquist does not have such a function.

So what can we do instead?
We can write a little “module” of code that will provide the function for us, and that is exactly what “defun” is for. It allows us to write complex bits of code in a “module” so that they can be used as simply as using any of the basic built in functions.

To create our own “percent” fuction, all we need to do is wrap the code for the calculation in a block form with “defun”.

In this case, we always have two “arguments” (variables that are used by the function), which in our example are var1 and var2. So when we define the function we need to specify that there will be two variables.

(DEFUN PERCENT (VAR1 VAR2)

then we just add the block of code:

(SETQ TEMP1 (+ VAR1 VAR2))
(SETQ TEMP2 (/ VAR1 1.0 TEMP1))
(SETQ VAR3 (* TEMP2 100))

and close the block with another “)”

(DEFUN PERCENT (VAR1 VAR2)
(SETQ TEMP1 (+ VAR1 VAR2))
(SETQ TEMP2 (/ VAR1 1.0 TEMP1))
(SETQ VAR3 (* TEMP2 100)))

One thing to note here is that a function will return the value of the last thing that it does, which in this case is multiplying TEMP2 by 100.
As this value is automatically returned by the function, there is no need to assign the value to VAR3 within the function - in fact it is better not to. So the completed function would be:

(DEFUN PERCENT (VAR1 VAR2)
(SETQ TEMP1 (+ VAR1 VAR2))
(SETQ TEMP2 (/ VAR1 1.0 TEMP1))
(* TEMP2 100))

Now there IS a function that can calculate the percentage for us, so each time we need to use it we can just type:

(SETQ VAR3 (PERCENT VAR1 VAR2))

The other thing to note is that within our function we do not need to use the same names for the variables as we do in the main code. In fact it is better if we deliberately use different variable names in the function from what are used in the main code (otherwise a variable may inadvertently get set to an unexpected value).

Your naming convention could be anything you like - I tend to use shorter variable names within functions but you could use any convention you like. The point is that once we have written the function then we can use it with:

(SETQ MYFRUIT (PERCENT APPLES PAIRS))
or
(SETQ NOISELEVEL (PERCENT INPUT OUTPUT))
or
(SETQ ANSWER (PERCENT 25 75))

or anything else, provided that you supply the function “PERCENT” with two numerical values.

So to write the function and test it we could just have:

(setq var1 25)
(setq var2 75)

(defun percent (v1 v2)
   (/ v1 0.01 (+ v1 v2)))

(print (percent var1 var2))

and we could even add a comment to remind us what the code does:

(setq var1 25)
(setq var2 75)

;; Function calculates what percentage v1 is of the total of v1+v2
(defun percent (v1 v2)
   (/ v1 0.01 (+ v1 v2)))

(print (percent var1 var2)) ; test it

and if we need to use that function a dozen times, then by using our specially made “module” we not only save a page of typing, but the code is much easier to read and once we have tested that the module works we know that it will work every time we use it, rather than having to re-code it a dozen times.

None of this has anything to do with object oriented programming - it is just a method provided in Nyquist/XLisp for putting code into modules.