Editing midi in reaper using osara and Js programming: Difference between pages

From Reaper Accessibility Wiki
(Difference between pages)
Jump to navigation Jump to search
(initial page migration)
 
 
Line 1: Line 1:
= introduction and a brief concept explanation =
=js Programming=


In most digital audio workstations, midi can work alongside audio, or in conjunction with, audio. This is because there are a number of resources and tools available to produce great sounding arrangements using midi and you could probably want to record a live, real  instrument to supplement the song you are producing. The user guide has got some of the common htings some folks are used to, some behaviors if you will,  in other software based editors like qws, and you shoudl go  [[Chapter 13: Manipulating and Editing MIDI Items#13.2 Monitoring an External Synthesizer|here if you want to hear your keyboard coming through as you play it]] and [[Chapter 13: Manipulating and Editing MIDI Items#13.3 Using Track Controls with MIDI|here if you want to control some basic parameters like pan and volume of a track]] . We will deal with patches and other things [[#patch and bank changes|in a little while]] . Lastly, [[Useful Links and Resources#using Yamaha SYXG 50 on modern machines|go here]] if you want to have a gm compatible synth (for the more tech-inclined users).
== Introduction ==
js plugins are Reaper's own plugin format similar in many ways to VST plugins.  A js plugin can process and generate audio and midi data and expose parameters to the user which can be automated.


For now thtough, there are two main ways that midi is used into modern digital audio workstations.
js plugins have a number of advantages such as easy to start writing, all parameters are exposed and these parameters are easy to interact with via a keyboard either directly in the user interface or by the OSARA parameter dialogue.  They also support graphics making them good for sighted users and it is also possible to add keyboard support though this is almost vanishingly rare.  Disadvantages are around limited to non-existent file handling.
# by using an external synth or keyboard or midi module, any hardware that can produce sound based on midi and then recording the audio directly from that equipment. For Configuration basics to get your midi devices working in reaper, check out the article on [[Enabling Midi Devices]] if you haven't done so already and the one mentioned at the top of this section. Also check out [[Chapter 3: recording audio and midi#3.28 Recording a Track's Output|this procedure for recording the sound directly from your keyboard when using midi]]
# By using a virtual instrument inserted as an effect in a track. You need to have for this any kind of virtual instruments or instrument libraries as they are called and will still need any kind of midi device for input.


Note. If you just want to have midi played back by using a system installed synthesizer (such as the default Microsoft gs wave table synth or an external keyboard) select the track that has midi in it, then press [[Useful Links and Resources#numpad emulation and applications key script|alt plus applications key]], and then arrow up once. You should have a submenu called midi output. From there you can select the hardware midi output to use.  
== View and existing js plugin ==
js plugins are written in plain text files and there are plenty to take a look at.  From the Reaper Help Options menu select Resource path.  In here is a folder called "Effects" in which are all the js plugins that come with Reaper.


The second option is becoming very popular nowadays because of the higher quality and flexibility of the libraries and instruments. Which means that a great majority of those instruments are no longer gm compatible and also usually have a few, very few or even just one kind of instrument, since they are usually specialized, responding to very specific needs. SO the more virtual instruments you might want to have per song, the more ram you will need.  
Typically a js plugin either has no file extension or an extension of jsfx.  Use your favourite plain text editor to open up any of the files to see what they look like.


== recommended settings ==
It is useful to turn the vebosity of your screen reader so it speaks all characters.  It is important to capture all the code when programming.  For example, a semicolon is required at the end of each command and most people dont set their screen reader to announce these.


Before continuing, make sure that the following is set.
In NVDA, the verbosity can be cycled with NVDA+P.
*Under Editing Behavior>midi editor, the Behavior for "open items in built-in MIDI editor":  should be: Open the clicked MIDI item only
*Active MIDI item follows selection changes in arrange view. Should be checked.
*Avoid automatically setting MIDI items from other tracks editable. Checked


from the midi editor, you should set the following options too, by opening any midi item [[#Piano Roll View|as described on the first couple of steps here if you don't know how,]] and then pressing alt plus O once the editor is open.
== Structure of a plugin ==
* Allow MIDI note edit to extend the media item: checked.
A js plugin is made up of a header and then a series of sections which have a predefined named and purpose.
*Sync editor transport to project transport : checked
*note preview submenu: all options checked


== the grid concept ==


one of the ways audio and especially midi is being edited in many modern programs uses what is called a grid, which is just a visual representation in timing. It looks just like a square grid , composed of vertical bar lines, which are the equivalent of.. you guessed it, musical bars. In reaper you have different grid divissions which will let you move notes, adjust their duration, or quantice them to different rhythm values. For this you must always set first the grid size (or grid unit), and then perform the desired operation. Common rhythm values follow. You will notice that they just divide musical bars by a certain ammount.
The header can be as short as a declaration of the name of the plugin but can also hold much more information such as the author, date, version, release notes, instructions on usage and other information that helps with reaPack integration.
{|
! grid unit size (division type
! time signature
! corresponding note value
|-
| 1/2
| 4/4
| half note, or minim
|-
| 1/4
| 4/4
| quarter note, or crotchet
|-
| 1/12
| 4/4
| one third of a quaver (useful for eight note triplets)
|-
| 1
| 6/8
| a whole bar in 6/8 time, which can be translated as a doted half note or a dotted minim.
|}
As you see, setting the grid to a certain ammount is always dependent on the time signature, not on the strict value that is mentioned  or specified.
Whenever you set grid units to a specified size, any actions that depend on the grid (move audio items by grid size, move notes or cursor to next grid unit ETC) will perform and affect notes by that ammount. for example  You could probably set the grid to 1/2 and move audio items by that distance sooner (left) or later (right)  during playback, when editing.
You can set the midi grid to different sizes or divisions, by using the upper numeric row on the keyboard once you are in the midi editor. Those actions do have the equivalents already calculated for you. [[Chapter 5: Project Arrangement Basics#5.12 Displaying Grid Lines|you can also set them for audio separately]]


= editing midi notes in reaper =


==  Piano Roll View ==
The header is followed by definition of the plugin parameters which is done by defining a slider for each parameter.  A slider has a min value, a max value, an increment value and a default value.  These are seen by the user in the plugin user interface as a slider and edit box for each parameter.


Reaper comes with its built in midi editor. It has two usable views. This one which is described is called piano roll view. [[#using the event list|the event list view will be described later]]. You can work on one midi item at a time. To edit a midi item that you have recorded, follow this general procedure:
* First select the midi item with control left or right arrows, respectively.
*Bind or invoque the action named, Item: Open in built-in MIDI editor (set default behavior in preferences) (I have set this to control plus w)
*Once the midi item ahs been opened, you will be in the piano roll view by default.
*You can then use the actions (bound to the arrow keys and shift and the arrow keys) to move by chord or note. Osara makes a distinction between notes and chords since there can be many notes in the same place or beat, sounding simultaneously. And you can select or manipulate all of them or just some. Usually every isolated note is technically considered a chord. You should hear the notes or chords when you are moving being played through your keyboard, synth or virtual instrument. For more information on how all of this is handled you can consult the [[OSARA_readme#Notes_and_Chords_in_the_MIDI_Editor|specific section]] of the OSARA read me.
*you can then use any of the actions that perform the operation you want. Delete, move copy, ETC. selected notes, quantice. Don't forget to set the grid size first!
*When you are done editing, press escape to close the midi editor window, otherwise it will remain open and sometimes will make some midi items not be editable, plus take up some space!


Normally, the midi editor will focus or be directly on the bar that you have last paused or placed the cursor. If this however is not the case, you can use the page up and down keys in the midi editor to move forward or backwards by measures respectively.  You can also use OSARA: Report edit/play cursor position bound to command/control shift j to check where you are directly within the midi editor.  
The @init block is run when the plugin first starts which is typically when it is first loaded onto an FX chain and when play starts. It is used to initialise variables to default values.  Note that the js plugin language does not require variables to be declared before they are used so this section does not need to include initialisation of all variables if this is done elsewhere.  Also, the default initialisation of a variable is to set it to zero.


Lastly, remember that reaper has different [[Chapter 3: recording audio and midi#3.31 Other MIDI Recording Modes|various midi recording modes]] that you can use to your advantage. For example, you can use the  overdub mode to record fader movements, or pedal sustain events as the track is playing which are just midi control messages for situations on which you only have a portable, smaller  midi controller available.


=== changing propperties for one or more notes ===
The @slider block is run whenever a parameter is changed either through automation or by the user.  For example, a parameter might be presented to the user as a percentage from 0 to 100 but the code needs this rescaling from -1 to 1.


there will be times when you wish to move a note to a very specific desired location, to extend or shorten its length, to even change the channel it is played on, or to change the pitch, or strength (velocity). Of course, all of those things can be done by using actions that you have bound to keys (usually and by default the [[Useful Links and Resources#numpad emulation and applications key script|numpad keys]]) to achieve all of this, but if for one you know the value, and wish to be very specific about it, you can select any note and then press control plus f2 on it to open the note properties dialog.
The [[Chapter 13: Manipulating and Editing MIDI Items#13.16 Using the Keyboard|guide ]] has more information on some useful actions. When clicking or dragging is mentioned on that section, you can usually accomplish the ssame by selecting all notes and then opening the note properties dialog instead, so yes you can absolutely select many notes (using shift and the arrows) and then open the properties dialog to change them all to the same length or put them all in the same position, or even use multiplier values like *2 for example, to double the current length of each note regardless of the value it has now.


==  using the event list ==
The @block code is run as a new block of samples arrives.  The block size as defined in Reaper preferences in the devices section dictates how many sampless.  This is an area of code commonly used to process MIDI as all the MIDI notes and events coming up in the next block of samples can be processed and action taken accordingly.  Also, MIDI notes and events can be inserted so they are played once the block enters Reaper's play buffer.


Once inside the midi editor, pressing alt plus 3 will bring the [[Chapter 13: Manipulating and Editing MIDI Items#13.20.1 Note Modes|event list]] which will let you have a finer control when editing any note or parameter.


This list is accessible with NVDA. All columns will be read as they should. If you wish  to move the focused NVDA selection to the current sounding note, or to the last place that you were on when editing in the piano roll view, you can use the action bound to the keystroke Ctrl+F, called  OSARA: Focus event nearest edit cursor just after switching to the event list view and before startling to navigate through the list. When editing events this procedure requires that you navigate until you find the event you need to edit (like the piano sustain on message) however, it hopefully should not be too much of a problem because you could memorize the approximate position and you can also use the page up and down keys to quickly scroll through the list.
The@sample block is run every sample.  So yes, many thousands of times a second.  Commonly used to process audio as there is easy access to the value of the audio in each channel.
Pressing the applications key on any item of that list will bring up a menu which will let you do a number of tasks including adjusting properties for midi cc's and notes (the dialog that comes up for notes is exactly the same one you can access from the piano roll view [[#Piano Roll View|described earlier]]). When you are done editing a cc event, you can go back to the default piano roll view by pressing alt plus number one of the upper numeric row.


== Midi Step recording or step input in reaper ==


Many times it is desirable to input notes that consist of a complex rhythmic figure in step time rather than playing them in real time. This method can prevent the need to clean up sloppy playing that results from executing complex figures at high speed.  Besides the [[Chapter 13: Manipulating and Editing MIDI Items#13.26 Step Recording|procedure described in the manual]], the following instructions are designed to let you enter a complex rhythmic figure in a short amount of time with a minimum of mistakes:
The @gfx block is used to draw graphics and process keyboard input.  I'm not sure when it is run.


# Make a time selection.
== First Audio Plugin ==
# Insert a midi Item which corresponds to that time selection on the desired track (can be a new or an existing armed one) by using the insert menu, then select the item you just inserted.
Let's dive in with a very simple js plugin that includes a volume control for audio.  Open up a plain text editor and copy and paste the following code into it.
#  Enter the MIDI Editor with CTRL Alt E (assigned by default) for this track.
#  Use the Applications Key and choose Use All Inputs for Step Recording.  Ensure you undo this choice after you are done with step recording.  This is particularly important if you intend to continue entering MIDI data conventionally on the same track.
#  Now, you use the upper numeric row keys to determine grid division and combine these with the CTRL key to determine note length.  Having made those choices play the notes or chord you want.
#  To join notes together, select the two notes with Shift and Arrow until the notes you want are selected and hit J.  


To start a pattern with a rest on the initial downbeat of the first bar of your pattern you Set both note length and grid division to the same value. , then you advance by grid division using actions bound to either CTRL Shift Right Arrow, or CTR:L Numpad 6 with Numlock ON.  For this example, we’ll say that the objective is to place an eighth rest on the first downbeat. In other words,  beat one of the bar.
#  Set both note length and grid division to an 8th note.
#  Advance the cursor one eighth note by pressing either CTRL Shift Right Arrow or CTRL Numpad 6 with Numlock ON.
#  Confirm your position by pressing CTRL Shift J.  You should be at beat 1 50%.  At this point, set your note length and grid division as desired to begin inserting notes or chords.
NOTE:  You can copy and paste (for repetitions of a pattern) and can even transpose notes, chords or entire repetitions as desired.


(Special thanks to Gianluca Apollaro for largely contributing to the information this section)
Desc: My first audio plugin


= patch and bank changes =


(editors note: please clean this up, its from an old e-mail from the rwp list)
slider:100<0,100,1>Volume


This procedure depends on the instrument. If you have  a virtual instrument (vst) loaded, you can usually change patches straight from your keyboard, which is acting as
a controller in this case, assuming that your vst supports the standard program and bank change messages it will respond as it
should. For me this is the easiest setup. You simply load your vst and control everything from your midi keyboard or controller.


For the other way, which is using the sound from the external synth or keyboard itself, or for midi control messages when there is no external controller available the procedure is a bit more involved.
@slider
There are two ways to access a plug-in that allows you to change patches and banks but they show the same options. You can either:
#insert the effect called reaControl into the midi track or
#Press control applications on it, then select show/hide midi track controls


In both cases the effect called [[ReaEffects guide#3 ReaControlMIDI|reaControlMidi]] will be added to the track. And in the case of having a virtual instrument inserted that responds to the standard midi messages, the reaControlMidi effect should be the first one in the fx chain list, by moving it up or inserting it first, before the virtual instrument. Good news is that it is pretty accessible.  This plug-in is used because reaper has
scaler = slider1/100;
no native support for sending control messages to external midi modules or hardware or vsts... and also because  you can work with those parameters at will, changing patches or banks or parameters by [[Implementing accessible automation|using automation]]


== reaControlmIdi description ==


When ReaControlmIdi is inserted, opening the fx chain or fx dialog  by pressing the f key on the selected track will bring a window with chekboxes that allow you to send control messages, bank and patch change messages. They have to be checked otherwise controls (such as sliders and combo boxes) will not move and even if you put values on the edit boxes those messages do not get sent. The rest of the options are just settings for the behavior of the reaControl vst.
@sample
(note: some of those checkboxes just say "enable" before the corresponding group of controls, or parameters and thus are not propperly labelled). However, you can get an idea because NVDA will read the group of parameters you are about to control, for example: "bank/program select grouping: Enable  check box  not checked"


You can also, load a patch list or reabank file or convert from a .ins file if you have one that is specific to your keyboard by using the "load file" button. You can look into the [https://stash.reaper.fm/tag/Bank-Patches reaper stash at the reaper website] for reaBank files. That way you can select things from combo boxes with patch names instead of having to type in all of those values. And that would be pretty much it.
spl0 *= scaler;
Also, make sure that your keyboard has or is set to a multiTimbral mode, where it can send and receive data from every midi channel at the same time and that you select one midi channel per instrument. I say this because Korg has a way of working that I never liked. In program mode for instance, you have only two channels that respond to external midi messages, which are channel 2 I believe which plays the current program or patch you have selected at a given time. and another which is the drumtrack channel but I don't think it is 10 anymore. Then in combi mode you have just.. the same thing, plus another channel which is the arpeggiator channel and .. that option is a bit silly because it enables a channel to have two different patches into one, according to ranges you have set. The one that works is simply, sequencer mode. There everything responds as it really should.
You should make sure too that only one track is armed and monitoring, because you then can create double parts on instruments you did not intend when recording.


== editing of control messages ==
spl1 *= scaler;


in reaper there are two main accessible ways to edit control change messages, or midi cc as reaper calls it. Those can be anything from volume or pan changes on a midi item, to piano sustain events and so on. Unfortunately, they are quite involved since osara does not yet report cc events as you select or move through them. There are also no real commands for moving to next or previous cc event. Still, you can get some use from reaper's cc editing features. One of these ways was hinted at earlier, when the [[#using the event list|use of the event list was described]]


=== using the cc lane ===
Save this in the Reaper resources Effects folder, ideally in a new subfolder to contain all your plugins.  Start up Reaper and it should do a rescan and make your new js plugin available to use.


once you open an item in reaper's built in midi editor, you can press f4 and bind the following (suggested) actions to keys:
*CC: Next CC lane 
*CC: Previous CC lane 
*Edit: Increase value a little bit for CC events
*Edit: Decrease value a little bit for CC events
*Edit: Move CC events left by grid, Edit: Move CC events right by grid
*pixel movement actions are also available, but they are not as reliable and would depend on your horizontal zoom levels. (note: apparently reliability and accuracy of these has improved on latest reaper version)
*Edit: Select all CC events under selected notes
*Edit: Select all CC events in time selection (in last clicked CC lane)


When you are back in the midi editor, you can use object nav and you will arrive at an unlabeled  combo box (its the first one reported by NVDA). Clicking the combo box with the mouse and then using the arrow keys will let you quickly select a cc lane to edit or draw events on. If the lane does contain data already in it, a bullet sign, a •  will be spoken before the name of the lane, for example: combo box •Velocity  collapsed. Focusing the lane will unfortunately cause the main editor window to lose focus so when you are done selecting a lane, you have to alt tab away and then to reaper again. Even if you close the midi editor the last selected lane will be preserved, even across projects so you probably will not have to change it that often. You can insert cc events manually as well, even by using a controller as the file is playing which would be the equivalent of drawing. If you know which lane you are on at the time and do not want to use object navigation you can then use the previous and next cc lane commands.  
Create a track and add some audio to it for example recording yourself speaking, by inserting an audio file or selecting something from media explorer.  Hit F on the track to bring up the FX chain dialogue and use the Add button to add your plugin.  Type in "first" as this is text included in the first line of the code copied into the plugin and is the name given to the plugin.  Arrow down and you should find the plugin.  Hit enter and it will get loaded onto the FX chain for the track.  Press tab to work your way through the plugin and you will come to the slider and edit controls for the volume parameter.


Although really if you find that only a part of the song did not have sustain events at the right places, your best bet is to use the select cc events in time selection or select cc events under selected notes and either move them until you are satisfied, or change their values with the commands, or finally erase those events and record them again.


= usage tips for some midi tools =
Press space to play the audio and then adjust the volume with either the slider or entering a new value in the edit field.  The volume changes.  Your first plugin.


In adition to using the midi editor for manipulation of midi data, reaper does ahve a few more tools you can use to generate or modify midi.
== First MIDI Plugin ==
Here is a simple plugin that has a slider to change the pitch of any incoming MIDI notes.  The minimum code for MIDI is a little more than for audio.


== accessing and using the midi filter window ==


Reaper has a [[Chapter 13: Manipulating and Editing MIDI Items#13.6 The MIDI Editor Window|midi filter]] (described on detail in the second paragraph). When using the NVDA screen reader focus is not automatically changed when the "filter events..." option from the view menu is used.
Desc: My first MIDI js plugin


note: these instructions are becoming obsolete, since a recent osara update has attempted to address this issue (thanks to programmer Alexey Zhelezov)


There are two ways to get to that window:
slider:0<-24,24,1>Semitone shift
#After you choose the option filter events from the view menu, do a physical move of your mouse or trackpad up and to the left and you should be able to hear the title of the filter window, or parts of the filter window  being announced. Click once with the left button when you do and that should focus the window.
#If you are more comfortable using the object navigation functions of NVDA, when you choose the filter events... option from the view menu, you should move two times to the parent object. Press numpad shift 8 on your numeric pad if you are using a desktop, or NVDA shift up arrow if you are using a laptop. Then, move to the two previous objects by pressing NVDA+4 on the numeric pad if you are using a desktop, or NVDA shift left arrow if you are using a laptop. Then you can move focus to that window by pressing NVDA shift minus on the numeric pad if using a desktop or NVDA shift backSpace if using a laptop.
#make your changes or customizations to the filter, then press shift plus space bar or route the mouse (with NVDA slash on the numeric pad in desktops, or NVDA shift M in laptops) on the clear filter, add to selection, set selection buttons.
#press escape when you are finished to close the window.


== using the virtual midi keyboard==


Accessed by pressing alt plus b or from the view menu once inside a project, in other words, outside the midi editor, this keyboard will let you input midi notes by using the majority of the keys from your computer keyboard. However, its operation can be tricky at times because it sometimes offsets the range or scale you are using. So to set a range, you might try the following:
@slider
There's a text box labelled "Center note (right click a key to set):". If you get focus into that text box, you can delete what's there and type, for example, "c4". The tricky bit is getting focus into that text box and then getting it back into the keyboard. With NVDA:
#Ensure you have simple review enabled (default).
#With focus in the virtual MIDI keyboard, press NVDA's next object command twice (desktop: NVDA+numpad6, laptop: NVDA+shift+rightArrow).
#Press NVDA's move focus to review command (desktop: NVDA+shift+numpadMinus, laptop: NVDA+shift+backspace). This should focus the center note text box.
#Press control+a and delete to delete what's there, then type, for example, c4 to centre at note c4.
#Now, press NVDA's previous object command twice (desktop: NVDA+numpad4, laptop: NVDA+shift+leftArrow).
#Press NVDA's move focus to review command (desktop: NVDA+shift+numpadMinus, laptop: NVDA+shift+backspace). This should return focus to the MIDI keyboard.


Many thanks to Jamie (James Teh) for this information
shift = slider1;
 
 
@block
 
while( midirecv( offset, msg1, msg2, msg3 ) )
 
(
 
  msg1 & 0xF0 = 0x90 ?
 
  (
 
   midisend( offset, msg1, msg2 + shift, msg3 );
 
  )
 
  :
 
  (
 
   midisend( offset, msg1, msg2, msg3 );
 
  );
 
);
 
 
In the same way as with the audio plugin, copy this code into a plain text file and save it in the Effects subfolder in the Reaper resource path ideally in your own subfolder holding all your plugins. Start up Reaper so it does a rescan and then insert reaSynth onto a track as as a VSTi.  Test you can play notes.  Now add your first MIDI plugin onto this track as well.  Before it has any effect thugh yu need to move reaSynth so it is below your first MIDI plugin since the plugin needs to update the MIDI data between it being played and it arriving at reaSynth.  Do this by either cutting and pasting reaSynth so it is second in the chain, or using the action bound to control-shift alt page down (Windows).
 
 
Tab to the Semitone shift slider in your new plugin. Play a note and then change the slider.  The pitch of notes is shifted.
 
== Tools to help write plugins ==
The most basic tool is your plain text editor of choice.  Reaper does have an inbult editor but it is not easily accessible.  So writing code in a plain text editor is the next best thing.  If you make a change to your code and save it though, you will need to return to Reaper and the FX chain , press contrl R on your plugin and replace the plugin with a new instance of itself to for the changes take effect.
 
 
It is possible to view all the variables used in a plugin along with their values.  This can be done with NVDA object navigation by tabbing to the edit button in the FX dialogue, hitting enter , and uing object navigation to move right until a list control is reached.  Gone down and you can then review each variable.
 
 
Debugging is difficult though in js plugins.  There is no option to display a message box or output diagnostic info to a file. And some variables will change their value with every sample or every block making them impossible to track.  You cannot step through the code one line at a time reviewing variable values like you can in more complex IDE's.
 
==Resources ==
 
There are not a whole bunch of great resources for writing js plugins.  Probably the most comprehensive source of information are all the plugins that come with Reaper and found in the Effects folder.  But these can be complex and difficult to work out how they work.
 
There is a good tutorial made by [https://www.admiralbumblebee.com/music/2018/02/08/Write-a-Reaper-MIDI-JSFX-from-scratch.html Admiral Bumblebeee] which goes through a modestly complex project to write a MIDI plugin.  There is also other useful content on this web site.
 
[https://www.reaper.fm/sdk/js/basiccode.php#js_basic The JSFX Programming Reference - Language Essentials] is on Reaper's web site.  It is a reference manual though and not a tutorial but if you get into JSFX programming you will come to appreciate this resource.
 
The Reaper community are a helpful bunch.  [https://forum.cockos.com/forumdisplay.php?f=3 The JSFX forum]. Use the search feature or search with something like Google putting reaper jsfx forum in as part of your search.  Sign up to post a question. 

Revision as of 19:45, 7 November 2023

js Programming

Introduction

js plugins are Reaper's own plugin format similar in many ways to VST plugins.  A js plugin can process and generate audio and midi data and expose parameters to the user which can be automated.

js plugins have a number of advantages such as easy to start writing, all parameters are exposed and these parameters are easy to interact with via a keyboard either directly in the user interface or by the OSARA parameter dialogue.  They also support graphics making them good for sighted users and it is also possible to add keyboard support though this is almost vanishingly rare.  Disadvantages are around limited to non-existent file handling.

View and existing js plugin

js plugins are written in plain text files and there are plenty to take a look at.  From the Reaper Help Options menu select Resource path.  In here is a folder called "Effects" in which are all the js plugins that come with Reaper.

Typically a js plugin either has no file extension or an extension of jsfx.  Use your favourite plain text editor to open up any of the files to see what they look like.

It is useful to turn the vebosity of your screen reader so it speaks all characters.  It is important to capture all the code when programming.  For example, a semicolon is required at the end of each command and most people dont set their screen reader to announce these.

In NVDA, the verbosity can be cycled with NVDA+P.

Structure of a plugin

A js plugin is made up of a header and then a series of sections which have a predefined named and purpose.


The header can be as short as a declaration of the name of the plugin but can also hold much more information such as the author, date, version, release notes, instructions on usage and other information that helps with reaPack integration.


The header is followed by definition of the plugin parameters which is done by defining a slider for each parameter.  A slider has a min value, a max value, an increment value and a default value.  These are seen by the user in the plugin user interface as a slider and edit box for each parameter.


The @init block is run when the plugin first starts which is typically when it is first loaded onto an FX chain and when play starts. It is used to initialise variables to default values.  Note that the js plugin language does not require variables to be declared before they are used so this section does not need to include initialisation of all variables if this is done elsewhere.  Also, the default initialisation of a variable is to set it to zero.


The @slider block is run whenever a parameter is changed either through automation or by the user.  For example, a parameter might be presented to the user as a percentage from 0 to 100 but the code needs this rescaling from -1 to 1.


The @block code is run as a new block of samples arrives.  The block size as defined in Reaper preferences in the devices section dictates how many sampless.  This is an area of code commonly used to process MIDI as all the MIDI notes and events coming up in the next block of samples can be processed and action taken accordingly.  Also, MIDI notes and events can be inserted so they are played once the block enters Reaper's play buffer.


The@sample block is run every sample.  So yes, many thousands of times a second.  Commonly used to process audio as there is easy access to the value of the audio in each channel.


The @gfx block is used to draw graphics and process keyboard input.  I'm not sure when it is run.

First Audio Plugin

Let's dive in with a very simple js plugin that includes a volume control for audio.  Open up a plain text editor and copy and paste the following code into it.


Desc: My first audio plugin


slider:100<0,100,1>Volume


@slider

scaler = slider1/100;


@sample

spl0 *= scaler;

spl1 *= scaler;


Save this in the Reaper resources Effects folder, ideally in a new subfolder to contain all your plugins.  Start up Reaper and it should do a rescan and make your new js plugin available to use.


Create a track and add some audio to it for example recording yourself speaking, by inserting an audio file or selecting something from media explorer.  Hit F on the track to bring up the FX chain dialogue and use the Add button to add your plugin.  Type in "first" as this is text included in the first line of the code copied into the plugin and is the name given to the plugin.  Arrow down and you should find the plugin.  Hit enter and it will get loaded onto the FX chain for the track.  Press tab to work your way through the plugin and you will come to the slider and edit controls for the volume parameter.


Press space to play the audio and then adjust the volume with either the slider or entering a new value in the edit field.  The volume changes.  Your first plugin.

First MIDI Plugin

Here is a simple plugin that has a slider to change the pitch of any incoming MIDI notes.  The minimum code for MIDI is a little more than for audio.


Desc: My first MIDI js plugin


slider:0<-24,24,1>Semitone shift


@slider

shift = slider1;


@block

while( midirecv( offset, msg1, msg2, msg3 ) )

(

  msg1 & 0xF0 = 0x90 ?

  (

   midisend( offset, msg1, msg2 + shift, msg3 );

  )

  :

  (

   midisend( offset, msg1, msg2, msg3 );

  );

);


In the same way as with the audio plugin, copy this code into a plain text file and save it in the Effects subfolder in the Reaper resource path ideally in your own subfolder holding all your plugins. Start up Reaper so it does a rescan and then insert reaSynth onto a track as as a VSTi.  Test you can play notes.  Now add your first MIDI plugin onto this track as well.  Before it has any effect thugh yu need to move reaSynth so it is below your first MIDI plugin since the plugin needs to update the MIDI data between it being played and it arriving at reaSynth.  Do this by either cutting and pasting reaSynth so it is second in the chain, or using the action bound to control-shift alt page down (Windows).


Tab to the Semitone shift slider in your new plugin. Play a note and then change the slider.  The pitch of notes is shifted.

Tools to help write plugins

The most basic tool is your plain text editor of choice.  Reaper does have an inbult editor but it is not easily accessible.  So writing code in a plain text editor is the next best thing.  If you make a change to your code and save it though, you will need to return to Reaper and the FX chain , press contrl R on your plugin and replace the plugin with a new instance of itself to for the changes take effect.


It is possible to view all the variables used in a plugin along with their values.  This can be done with NVDA object navigation by tabbing to the edit button in the FX dialogue, hitting enter , and uing object navigation to move right until a list control is reached.  Gone down and you can then review each variable.


Debugging is difficult though in js plugins.  There is no option to display a message box or output diagnostic info to a file. And some variables will change their value with every sample or every block making them impossible to track.  You cannot step through the code one line at a time reviewing variable values like you can in more complex IDE's.

Resources

There are not a whole bunch of great resources for writing js plugins.  Probably the most comprehensive source of information are all the plugins that come with Reaper and found in the Effects folder.  But these can be complex and difficult to work out how they work.

There is a good tutorial made by Admiral Bumblebeee which goes through a modestly complex project to write a MIDI plugin.  There is also other useful content on this web site.

The JSFX Programming Reference - Language Essentials is on Reaper's web site.  It is a reference manual though and not a tutorial but if you get into JSFX programming you will come to appreciate this resource.

The Reaper community are a helpful bunch.  The JSFX forum. Use the search feature or search with something like Google putting reaper jsfx forum in as part of your search. Sign up to post a question.