Formula Breakdown
Yesterday I wrote a post about the Formula Device in Renoise. I kept things pretty high level and assumed a background in programming. This approach lead to some questions so I am going to attempt to break the concept down a little further.
Set Your Destination
The destination routing controls where the output of formula device will be sent. For this example, place an analog filter following the formula device. For the three fields pick: CT (current track), Analog Filter and Cutoff. Now you will see the cutoff of your filter following the output of your formula.
Fixed Formulas
For simplicity we will not use the function definitions for the moment and instead will concentrate only on the formula. Try entering the value 0 and notice the cutoff of the filter goes to its lowest point. Now enter 1 and it will be at its highest. 0.5 will place it at the midpoint. The output of the formula will always be a decimal number between 0.0 and 1.0.
Adding Interactivity
In order to get some interactivity, we can use the variables A, B or C. These correspond with the values set by the three input sliders. Enter the value of A into your formula and you will see that the filter will follow the value of your first slider. You could scale the first 2 sliders by entering:
A * B
Now while moving the two sliders you can see the relationship each on has on the final output.
Built In Values
Click the help button and you will see a number of built in functions and variables that are already defined for you:
--[[ Input/Output variables ---------------- ]]-- A : First input parameter [0..1] B : Second input parameter [0..1] C : Third input parameter [0..1] OUTPUT : Output parameter from previous run --[[ Math constants ----------------- ]]-- PI : Pi constant TWOPI : 2*Pi constant INF : Infinity (huge positive number) --[[ Musical variables -------------- ]]-- PLAYING : Playing or stopped (1 or 0) SRATE : Actual sampling rate BPM : Beats per minute LPB : Lines per beat TPL : Ticks per line SPL : Samples per line NUMLINES : Number of lines in current pattern TICK : Tick number in current line LINE : Line number in current pattern LINEF : Line number with tick fractions SAMPLES : Absolute position in song in samples BEATS : Absolute position in song in beats LINES : Absolute position in song in lines SEQPOS : Absolute position in song in patterns SAMPLECOUNTER : Continuously running sample counter TICKCOUNTER : Continuously running tick counter LINECOUNTER : Continuously running line counter LINEFCOUNTER : Line counter with tick fractions --[[ Functions ---------------------- ]]-- abs(x) : Absolute value acos(x) : Arc cosine asin(x) : Arc sine atan(x) : Arc tangent ceil(x) : Round number to ceil cos(x) : Cosine cosh(x) : Hyperbolic cosine deg(x) : Convert to degrees exp(x) : Exponential (e^x) floor(x) : Round number to floor fmod(x) : Modulo operator for float numbers frexp(x) : Split value in fraction and exponent ldexp(x) : Float representation for a normalised number lin2db(x): Convert a 0..1 number to its decibel value db2lin(x): Convert a decibel value to its 0..1 normalised value log(x) : Natural logarithm of a number log10(x) : Logarithm base 10 of a number max(a, b [, c[, ...]]) : Maximum of two or more numbers min(a, b [, c[, ...]]) : Minimum of two or more numbers mod(x) : Modulo operator modf(x) : Integral and fractional parts of a number pow(x, n): Nth power of x rad(x) : Convert to radians random([a [, b [, c]]]) : Random value randomseed(x): Seed the random number generator sin(x) : Sine sinh(x) : Hyperbolic sine sqrt(x) : Square root tan(x) : Tangent tanh(x) : Hyperbolic tangent
Notice one of the variables is named PLAYING and contains a 0 when the sequencer is stopped and 1 when it is playing. Change your formula to:
A * B * PLAYING
Now you will notice your formula works the same as before while the sequencer is playing but will automatically be set to 0 when stopped.
Getting Functional
Now we are going to look at defining our first function. A function is a way to encapsulate and reuse a block of code. The function below is not very useful and is only being used for simple example purposes.
Enter the following into the function definitions area:
function half(num) return num / 2 end
This function divides a number by two and returns the result. Now enter the following into your formula:
half(A) + half(B)
Now as you move the first two sliders you will see the output is half of each value added together. Notice that once a function has been defined we can reuse it multiple times.
Breaking Down the Function
Let’s look at the parts of a function. A function will always begin with the keyword function; this will be followed by the name of the function. In this case we have called our function half. After the name we will specify the arguments of the function. An argument is an input value to the function. In this case we have one argument named num.
function half(num)
Next we have the body of the function. The body contains the meat of the function. We indent each line of the body to make it easier to see that it is contained within the function. The body should end with a return statement. The return statement will specify the output value of the function. In this case we only have one statement in our body and it is the return statement. We are returning our input value divided by two.
return num / 2
The final statement of a function is the keyword end. This is important because you can have multiple functions within each formula device.
end
In order to call a function you use its name followed by any arguments you wish pass in parentheses. You can examine our formula box to see this function being called twice.
What Now?
Now that you have a high level overview of the formula device I would suggest starting to look at some of the provided examples and to slowly build up your own library of useful formulas.