Skip to content

Instantly share code, notes, and snippets.

@joshg253
Last active September 2, 2022 20:08
Show Gist options
  • Save joshg253/599a39c1e13a9047ff9bec1ac899f40c to your computer and use it in GitHub Desktop.
Save joshg253/599a39c1e13a9047ff9bec1ac899f40c to your computer and use it in GitHub Desktop.
SPS Expression Help

SPS Expression Help

General

SPS allows you to program signal processing using simple expressions.

Many aspects of SPS code are similar to C (including comments).

You can create new variables just by using them, and you can read and write predefined variables (of which each effect has its own) to interact with the effect. Note that variables are all floating point numbers (no strings), and the maximum length of a variable's name is 8 characters (anything longer will be ignored).

So, to create a variable, you can simply use it, for example:

x = 5;

You can also use a variety of operators and math functions to modify variables, see the Operators and Functions tabs above.

Code can include C and C++ style comments:

// using the doubleslash comments until the end of the line

/* using the classic C comments
comment a block of text */

You can combine operators and functions into expressions, such as:

x = 5 * cos(y) / 32.0;  // this does some leetness right here

You can use multiple expressions by separating them with one or more semicolons, for example:

x = x * 17.0; x = x / 5; y = pow(x,3.0);

It is worth noting that extra whitespace (spaces, newlines) is ignored, so if you need to space things out for clarity, you can.

Variables that are predefined for your effect to use:

Variable(s) Desc Notes
nch Number of channels of PCM stream 1 or 2
srate Samplerate of stream e.g. 44100
slider1, slider2, slider3, slider4 The four sliders. Each has a range of 0.0...1.0
trig1, trig2, trig3, trig4 The four trigger buttons. These should be reset to 0.0 by your code when you've caught the trigger.

Variables that your per-sample code can modify to apply its effect:

Variable Desc Notes
spl0 left/mono channel sample -1.0...1.0
spl1 right channel sample, if nch == 2 -1.0...1.0
skip set this to > 0 to drop the current sample and not output it Can effectively be used to speed up the output.
repeat set this to > 0 to process this sample again after outputting Can effectively be used to slow down the output.
Note: due to Winamp architecture limitations, the most you can slow down the output is by 50%.

How to actually make meaningful effects:

A simple volume control might be:

spl0=spl0*slider1; spl1=spl1*slider1;

To slow down the output to half speed:

tmp=bnot(tmp); repeat=tmp;

To speed up the output to double speed:

tmp=bnot(tmp); skip=tmp;

To swap left and right channels:

tmp=spl0; spl0=spl1; spl1=tmp;

etc.

Operators

The following operators are available:

Operator Description Example
= assigns a value to a variable. var=5;
+ adds two values, returns the sum. var=5+var2;
- subtracts two values, returns the difference. var=5-var2;
* multiplies two values, returns the product. var=5*var2;
/ divides two values, returns the quotient. var=5/var2;
% converts two values to integer, performs division, returns remainder var=var2%5;
` ` converts two values to integer, returns bitwise OR of both values
& converts two values to integer, returns bitwise AND of both values var=var2&31;

Functions

Functions available from code:

Function Desc Notes
abs(value) returns the absolute value of 'value'
sin(value) returns the sine of the radian angle 'value'
cos(value) returns the cosine of the radian angle 'value'
tan(value) returns the tangent of the radian angle 'value'
asin(value) returns the arcsine (in radians) of 'value'
acos(value) returns the arccosine (in radians) of 'value'
atan(value) returns the arctangent (in radians) of 'value'
atan2(value,value2) returns the arctangent (in radians) of 'value'/'value2'
sqr(value) returns the square of 'value'
sqrt(value) returns the square root of 'value'
invsqrt(value) returns the reciprocal of the square root of 'value' (1/sqrt(value)) (uses a fast approximation, may not always = 1/sqrt(value) :)
pow(value,value2) returns 'value' to the power of 'value2'
exp(value) returns e to the power of 'value'
log(value) returns the log in base e of 'value'
log10(value) returns the log in base 10 of 'value'
floor(value) returns the largest integer less than or equal to 'value'
ceil(value) returns the smallest integer greater than or equal to 'value'
sign(value) returns the sign of 'value' (-1.0 or 1.0, or 0.0 or -0.0)
min(value,value2) returns the smallest of 'value' and 'value2'
max(var,var2) returns the greatest of 'value' and 'value2'
sigmoid(value,value2) returns sigmoid function value of x='value' ('value2'=constraint)
rand(value) returns a random integer between 0 and 'value'
band(value,value2) returns a boolean AND of 'value' and 'value2'
bor(value,value2) returns a boolean OR of 'value' and 'value2'
bnot(value) returns a boolean NOT of 'value'
if(condition,valtrue,valfalse) returns 'valtrue' if 'condition' is nonzero, returns 'valfalse' otherwise. new in AVS 2.8+: only one of valtrue/valfalse is evaluated, depending on condition
assign(dest, source) if 'dest' is a variable, assigns the value of 'source' to it. returns the value of 'source'. a little trick: assign(if(v,a,b),1.0); is like if V is true, a=1.0, otherwise b=1.0. :)
exec2(parm1, parm2) evaluates parm1, then parm2, and returns the value of parm2.
exec3(parm1, parm2, parm3) evaluates parm1, then parm2, parm3, and returns the value of parm3.
equal(value,value2) returns 1.0 if 'value' is equal to 'value2', otherwise returns 0.0
above(value,value2) returns 1.0 if 'value' is greater than 'value2', otherwise returns 0.0
below(value,value2) returns 1.0 if 'value' is less than 'value2', otherwise returns 0.0
megabuf(index) can be used to get or set an item from the 1 million item temp buffer Get: val=megabuf(index);
Set: assign(megabuf(index),val);
loop(count, statement) executes <statement> <count> times. count is evaluated once and clamped to 0..4096.
Best used with exec2() and exec3() and assign().
Note: the return value of loop() is undefined and should not be used.

Constants

Constant Value
'$PI' '3.14159'
'$E' '2.71828'
'$PHI' '1.618033'

Numbers can be specified as integers or as floating point (i.e. '5' or '5.0' or '5.00001')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment