The description lines that can be specified are:
The code in the code sections is a simple language that has similarties to C. Some basic features of this language are:
x % 5 ? (
f += 1;
x *= 1.5;
) : (
f=max(3,f);
x=0;
);
In addition to the basic functions available, REAPER/JS also provides numerous advanced functions, organized into the following categories:
Looping, FFT/MDCT, Memory Utility, Slider, File, MIDI, and Graphics.
Accessing Samples
Looping
If you wish to programmatically choose which sample to access, use this function (rather than splX). This is slightly slower than splX, however has the advantage that you can do spl(variable) (enabling easily configurable channel mappings). Valid syntaxes include:
spl(channelindex)=somevalue;
spl(5)+=spl(3);
FFT/MDCT Functions
Example:
loop(32,
r += b;
b = var * 1.5;
);
Evaluates the second parameter a finite number of times, specified by the
first parameter. If the first parameter is less than 1, the second parameter
is not evaluated. Be careful with specifying large values for the first
parameter -- it is possible to hang your effect for long periods of time
doing so. The maximum for the first parameter is approximately 1 million.
The first parameter is only evaluated once (so modifying it within the code will have no effect on the number of loops). For a loop of indeterminate length, see while() below.
Example:
while(
a += b;
b *= 1.5;
a < 1000; // as long as a is below 1000, we go again.
);
Evaluates the first parameter a finite number of times, until the last
statement in the code block is zero. There is an artificial limit for
number of executions of about 1 million (If you need more than 1 million iterations you can nest while()s, but this isn't recommended as you will slow things down and likely break things).
Memory Utility
Example:
mdct(0, 512);
Performs a modified DCT (or inverse in the case of imdct()) on the data
in the local memory buffer at the offset specified by the first parameter.
The second parameter controls the size of the MDCT, and it MUST be one of
the following: 64, 128, 256, 512, 1024, 2048, or 4096. The MDCT takes the number of
inputs provided, and replaces the first half of them with the results. The
IMDCT takes size/2 inputs, and gives size results.
Note that the MDCT must NOT cross a 65,536 item boundary, so be sure to
specify the offset accordingly.
The MDCT/IMDCT provided also provide windowing, so your code is not required
to window the overlapped results, but simply add them. See the example
effects for more information.
fft_permute(index,size), fft_ipermute(index,size)
Example:
buffer=0;
fft(buffer, 512);
fft_permute(buffer, 512);
buffer[32]=0;
fft_ipermute(buffer, 512);
ifft(buffer, 512);
// need to scale output by 1/512.0, too.
Performs a FFT (or inverse in the case of ifft()) on the data in the local
memory buffer at the offset specified by the first parameter.
The size of the FFT is specified by the second parameter, which must be
32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, or 32768. The outputs
are permuted, so if you plan to use them in-order, call fft_permute(idx, size)
before and fft_ipermute(idx,size) after your in-order use.
Your inputs or outputs will need to be scaled down by 1/size, if used.
Note that the FFT/IFFT require real/imaginary input pairs (so a
256 point FFT actually works with 512 items), while the real FFT/IFFT
(rfft() and irfft(), below) provide a real-FFT.
Note that the FFT/IFFT must NOT cross a 65,536 item boundary, so be sure to
specify the offset accordingly.
Used to convolve two buffers, typically after FFTing them.
convolve_c works with complex numbers. The sizes specify number
of items (the number of complex number pairs).
Note that the convolution must NOT cross a 65,536 item boundary,
so be sure to specify the offset accordingly.
Slider Functions
The freembuf() function provides a facility for you to notify the memory
manager that you are no longer using a portion of the local memory buffer.
For example, if the user changed a parameter on your effect halving your
memory requirements, you should use the lowest indices possible, and call
this function with the highest index you are using plus 1, i.e. if you are
using 128,000 items, you should call freembuf(128001); If you are no longer
using any memory, you should call freembuf(0);
Note that calling this does not guarantee that the memory is freed or
cleared, it just provides a hint that it is OK to free it.
The memcpy() function provides the ability to quickly copy regions of the
local memory buffer. The regions may overlap, but neither region may cross
a 65,536 item boundary (they may be on different pages, however).
The memset() function provides the ability to quickly set a region of the
local memory buffer to a particular value. Unlike memcpy(), this region
may be of any length and cross any boundaries.
For these functions, the parameter can be the variables slider1-sliderN, in
which case that slider is refreshed. Otherwise, it can be a bitmask of which
sliders have changed, where 1 would be the first slider, 2 would be the
second, 4 would be the third, 32768 being the 16th slider, and so on.
File Functions
Example:
sliderchange(slider4);
or
sliderchange(2 ^ sliderindex);
The sliderchange() function provides a facility for you to notify REAPER/JS
that you have changed a sliderX variable so that
it can update the display. This function is not necessary to call from the
@slider code section, it is provided so
that other code sections can update the sliders. Note that this function only
updates the display, it does not send an automation message to the host.
Example:
slider_automate(slider4);
or
slider_automate(2 ^ sliderindex);
The slider_automate() function provides a facility for you to notify REAPER/JS
that you have changed a sliderX variable so that
it can update the display, and record the move as automation. This function is not
necessary to call from the @slider code section,
it is provided so that other code sections can write programmatic automation messages.
The following functions can be used in the @serialize section or in other sections (for reading of files specified with file: or from an extended file slider.
In a @serialize section, they can be for read or for write, but on all others they are for reading only.
For @serialize, file_open() and file_close() should not be used, and the file handle should be 0.
These functions should NOT under any circumstances be used in the @gfx section.
filename:0,myfile.wav
handle = file_open(0);
Example:
slider1:/mydata:mydef.wav:WAV File
handle = file_open(slider1);
Opens a file from either the effect filename list or from a file slider.
Once open, you may use all of the file functions available. Be sure to
close the file handle when done with it, using file_close().
file_close(handle);
Closes a file opened with file_open().
file_rewind(handle);
Use this to rewind the current file to the beginning, to re-read the file etc.
file_var(handle,myVar);
This reads (or writes if in a @serialize write) the variable from(to) the current file.
amt=file_mem(handle,offset,len);
This reads (or writes) the block of local memory from(to) the current file.
Returns the actual number of items read (or written).
len=file_avail(handle);
Returns the number of items remaining in the file, if it is in read
mode. Returns < 0 if in write mode. If the file is in text mode
(file_text(handle) returns TRUE), then the return value is simply
0 if EOF, 1 if not EOF.
file_riff(handle,nch,samplrate);
nch ? file_mem(handle,0,file_avail(0));
If the file was a RIFF WAV file, or a valid .OGG Vorbis file,
this will set the first parameter to the number of channels, and
the second to the samplerate.
istext=file_text(handle);
istext ? use_diff_avail syntax;
If the file was a text file (and ended in .txt), this will
return 1. If you need to use different file_avail() logic
for text files (you often will), you can query it this way.
midisend(0,$x90 + 0,69|(127*256)); // send note 69 to channel 0 at velocity 127 (max)
midirecv(offset,msg1,msg23);
(msg1&$xF0)==$x90 ? ( /* note on! */ )
Note: midirecv returns msg1 as a return value, as well.
while( midirecv(offs,msg1,msg23) ? ( midisend(offs,msg1,msg23); ); );
buf[0] = $xAA|0;
buf[1] = $xBB|0;
midisyx(offset,buf,2); // send sysex: F0 AA BB F7
coordinatelist=1000; // use memory slots 1000-1009 coordinatelist[0]=source_x; coordinatelist[1]=source_y; coordinatelist[2]=source_w; coordinatelist[3]=source_h; coordinatelist[4]=dest_x; coordinatelist[5]=dest_y; coordinatelist[6]=dest_w; coordinatelist[7]=dest_h; coordinatelist[8]=rotation_x_offset; // only used if rotation is set, represents offset from center of image coordinatelist[9]=rotation_y_offset; // only used if rotation is set, represents offset from center of image gfx_blitext(img,coordinatelist,angle);
isourtrig = trigger & (2^5);
Conversely, to set trigger 5:
trigger |= 2^5;
Or, to clear trigger 5:
trigger & (2^5) ? trigger -= 2^5;
It is recommended that you use this variable in @block, but only
sparingly in @sample.
pdc_bot_ch=0; pdc_top_ch=2; // delays the first two channels (spl0/spl1).
pdc_bot_ch=2; pdc_top_ch=5; // delays channels spl2,spl3, and spl4.
(this is provided so that channels you dont delay can be properly
synchronized by the host).