Sonic Pi OSC with REAPER

As with another article on sending OSC messages to and from Ableton Live that I posted (which was significantly more difficult to set up and get working), I’ve been since using Linux with Sonic Pi and REAPER to do the same.

My goal was to have a way to record stems from whatever code blocks (usually live_loop) to separate tracks for later mixing. Turns out REAPER is incredibly efficient, works on Mac, Win, and Linux and is inexpensive. Plus, the built OSC commands available can control pretty much anything in REAPER.

Obviously, install REAPER and Sonic Pi first.

REAPER has OSC built in. Go to the preferences in REAPER and on the left column scroll down to ‘Control/OSC/web’:

Click the ‘Add’ button.

Use these settings, noting that the Device name can be whatever you want. The local listen port your can choose as well. The Device IP I left blank, but if you were sending to another computer, you’d want to fill that in, and then find your computer IP number and enter that in Local IP: (I find it has been safest to put the actual IP in and not local host. I also check the “Allow binding messages to REAPER actions and FX learn” which I believe are for custom OSC commands that you want to use, but haven’t tried that yet.

NOTE: a cool feature is to use the “Listen” button in that window. This traces all OSC commands coming in which excellent for testing.

In the Pattern config dropdown choose (open config directory):


From that directory open the “Default.reaperOSC” file which is a reference to all of the commands. The current one is:

# Make a copy of this file, rename it, and edit the file to create a 
# custom pattern configuration.

# For basic information about OSC and REAPER, see 
# .

# ----------------------------------------------------------------

# Default settings for how this device displays information.

# (these can all be overridden by the device sending OSC messages, search for these
# names below to see the messages)
# DEVICE_TRACK_COUNT is how many tracks this device can display at once 
# (the track bank size).
# DEVICE_SEND_COUNT/DEVICE_RECEIVE_COUNT is how many sends and receives this
# device can display at once.
# DEVICE_FX_COUNT is how many track insert FX this device can display at once.
# DEVICE_FX_PARAM_COUNT is how many FX parameters this device can display at once
# (the FX parameter bank size).
# DEVICE_FX_INST_PARAM_COUNT is how many FX instrument parameters this device can
# display at once (the FX instrument parameter bank size).
# DEVICE_MARKER_COUNT is how many markers for which this device would like to 
# receive information 
# DEVICE_REGION_COUNT is how many regions for which this device would like to 
# receive information 


# ----------------------------------------------------------------

# Default values for how this device behaves. The device has a selected track, bank 
# of tracks, and FX, which are not necessarily the same as the selected track or FX 
# in the REAPER window.

# REAPER_TRACK_FOLLOWS determines whether the selected track in REAPER changes
# only when the user changes it in the REAPER window, or if it follows the track
# currently selected in the OSC device.
# Allowed values: REAPER, DEVICE

# DEVICE_TRACK_FOLLOWS determines whether the selected track in the device changes
# only when the device changes it, or if it follows the last touched track in the 
# REAPER window.
# Allowed values: DEVICE, LAST_TOUCHED

# DEVICE_TRACK_BANK_FOLLOWS determines whether the selected track bank in the device 
# changes only when the device changes it, or if it follows the REAPER mixer view.
# Allowed values: DEVICE, MIXER

# DEVICE_FX_FOLLOWS determines whether the selected FX in the device changes only 
# when the  device changes it, or if it follows the last touched or currently focused
# FX in the REAPER window.

# DEVICE_EQ determines whether sending any FX_EQ message will automatically insert
# ReaEQ on the target track if it does not exist, or the message will only affect
# an existing instance of ReaEQ.
# Allowed values: INSERT, EXISTING

# DEVICE_ROTARY_CENTER defines the argument that represents no change, for rotary 
# controls.
# Allowed values: 0, 0.5




# ----------------------------------------------------------------

# Each line below is an action description in all caps, followed by a number of OSC
# message patterns. You can add, remove, or change patterns, delete lines, or comment 
# out lines by adding '#', but do not change the action descriptions.

# The patterns following the action are the messages that REAPER will send and receive
# to and from the OSC device. An action can have no patterns (and will be ignored), 
# one pattern, or many patterns.

# The patterns may contain the wildcard character '@'. (This is REAPER-only, not part
# of the OSC specification.) The '@' wildcard is used to specify the action target.

# ----------------------------------------------------------------

# The OSC device sends patterns to trigger actions, and REAPER sends patterns to the
# device as feedback.  OSC patterns can include arguments, which are be interpreted
# in various ways, defined by a flag immediately before the pattern.

# n: normalized floating-point argument. 0 means the minimum value, and 1 means the 
# maximum value.  This can be used for continous controls like sliders and knobs.

# Example: TRACK_VOLUME n/track/volume n/track/@/volume
# The device sends /track/3/volume 0.5 to set the volume to 0.5 for track 3, or
# /track/volume 0.5 to set the volume for the track that is currently selected in 
# the device. REAPER sends /track/3/volume 0.5 when track 3 volume changes to 0.5.
# If track 3 is currently selected in the device, REAPER will also send 
# /track/volume 0.5. The floating-point argument represents as the track fader 
# position in the REAPER window. 0 sets the fader all the way down, 1 sets the fader
# all the way up, 0.5 sets the fader exactly in the middle. Therefore, the actual 
# volume that is set depends on the REAPER track fader preference settings.

# f: raw floating-point argument. The argument is interpreted directly, to set or
# report a value.

# Example: TEMPO f/tempo/raw
# The device sends /tempo/raw 100.351 to change the REAPER tempo to 100.351 bpm.
# REAPER sends /tempo/raw 120 when the tempo changes to 120 bpm. 

# Normalized and raw floating-point arguments also support multiple parameters 
# sent from the device.
# Example: FX_PARAM_VALUE n/track/@/fx/@/fxparam/@/value
# The device can send /track/3/fx/1,2,5/fxparam/6,7,7/value 0.25 0.5 0.75
# to set three FX parameter values at once, to 0.25, 0.5, 0.75 respectively.

# b: binary argument, either 0 or 1. The device sets or clears the state when 
# sending the message. Can be used to emulate switches or momentary controls.

# Example: TRACK_MUTE b/track/mute b/track/@/mute
# The device sends /track/3/mute 1 to mute track 3, or /track/mute 1 to mute the 
# track that is currently selected in the device. /track/3/mute 0 will unmute
# track 3. REAPER sends /track/3/mute 1 when track 3 is muted, and /track/3/mute 0
# when track 3 is unmuted. If track 3 is currently selected in the device, REAPER 
# will also send /track/mute 1 and /track/mute 0.

# Example: REWIND b/rewind
# The device sends /rewind 1 to begin rewinding, and sends /rewind 0 to stop
# rewinding. REAPER sends /rewind 1 when the rewind button in the REAPER window is
# pressed, and /rewind 0 when the button is released. 

# t: trigger or toggle message. The device triggers the action, or toggles the
# state, when the pattern is sent with no arguments, or with an argument of 1.
# The feedback values REAPER sends are identical to those sent for binary 
# arguments.

# Example: METRONOME t/click
# The device sends /click or /click 1 to toggle the metronome on or off. REAPER 
# sends /click 1 when the metronome is enabled, and /click 0 when the metronome 
# is disabled. 

# r: rotary. The device triggers the action in the forward direction when sent 
# with an argument greater than ROTARY_CENTER, and in the reverse direction when 
# sent with an argument less than ROTARY_CENTER. For some messages, the magnitude 
# of the argument affects the rate of change. REAPER does not send feedback for 
# these messages.

# Example: SCRUB r/scrub
# The device sends /scrub 1 to scrub forward, and /scrub -1 to scrub in reverse
# (if ROTARY_CENTER is 0).

# s: string. These messages include a string argument. Many of these messages
# are sent from REAPER to the device for feedback/display, but some can be sent
# from the device to REAPER.

# Example: TRACK_NAME s/track/name s/track/@/name
# The device sends /track/3/name "vox" to rename track 3 in REAPER, or /track/name
# "vox" to rename the track that is currently selected in the device. REAPER sends 
# /track/3/name "vox" to report that name of track 3 is "vox". If track 3 is 
# currently selected in the device, REAPER will also send /track/name "vox".

# Example: DEVICE_FX_FOLLOWS s/fxfollows
# The device sends /fxfollows "FOCUSED" to inform REAPER that the selected FX in the
# device will now follow the FX that is focused in the REAPER window.

# i: integer. These messages include an integer argument, and are sent from the 
# device to REAPER.

# Example: ACTION i/action t/action/@
# The device sends /action 40757 or /action/40757 to trigger the REAPER action
# "split items at edit cursor". See the REAPER actions window for a complete list
# of action command ID numbers.

# Example: DEVICE_TRACK_BANK_SELECT i/bankedit t/bankedit/@
# The device sends /bankedit 2 or /bankedit/2 to inform REAPER that the active 
# track bank is bank 2. If NUM_TRACKS is 8, that means REAPER will now interpret
# a message like /track/1/volume as targeting the volume for track 9, and  REAPER 
# will only send the device feedback messages for tracks 9-16.

# ----------------------------------------------------------------

# Note: the default configuration includes a lot of feedback messages, which can
# flood the device. Avoid flooding by removing messages (by deleting the patterns, 
# or commenting out the lines) that the device does not want, especially the

# Note: FX parameter feedback will only be sent for the track that is currently
# selected in the device. If messages exist that can target FX on other tracks,
# feedback will be sent whenever the parameter values change. This can be a lot of
# data, so only include those messages if you want the feedback.
# Example: FX_PARAM_VALUE /fxparam/@/value /fx/@/fxparam/@/value
# This action can only target FX on the currently selected track, so feedback will
# only be sent for that track.
# Example: FX_PARAM_VALUE /fxparam/@/value /fx/@/fxparam/@/value /track/@/fx/@/fxparam/@/value
# This action can target FX on any track, so feedback will be sent for all tracks.

# Note: multiple patterns for a given action can all be listed on the same line, 
# or split onto separate lines.

# ----------------------------------------------------------------

# The default REAPER OSC pattern configuration follows. To create a custom 
# configuration, copy this file and edit the copy.

SCROLL_X- b/scroll/x/- r/scroll/x
SCROLL_X+ b/scroll/x/+ r/scroll/x
SCROLL_Y- b/scroll/y/- r/scroll/y
SCROLL_Y+ b/scroll/y/+ r/scroll/y
ZOOM_X- b/zoom/x/- r/zoom/x
ZOOM_X+ b/zoom/x/+ r/zoom/x
ZOOM_Y- b/zoom/y/- r/zoom/y
ZOOM_Y+ b/zoom/y/+ r/zoom/y

TIME f/time s/time/str
BEAT s/beat/str
SAMPLES f/samples s/samples/str
FRAMES s/frames/str

REPLACE t/replace
REPEAT t/repeat

RECORD t/record
STOP t/stop
PLAY t/play
PAUSE t/pause

AUTO_REC_ARM t/autorecarm
SOLO_RESET t/soloreset
ANY_SOLO b/anysolo

REWIND b/rewind
FORWARD b/forward

GOTO_MARKER i/marker t/marker/@
GOTO_REGION i/region t/region/@

SCRUB r/scrub

PLAY_RATE n/playrate f/playrate/raw r/playrate/rotary s/playrate/str
TEMPO n/tempo f/tempo/raw r/tempo/rotary s/tempo/str

# writing a marker or region time may change its index -- you should use the *ID_ versions below if needed
MARKER_NAME s/marker/@/name
MARKER_NUMBER s/marker/@/number/str
MARKER_TIME f/marker/@/time
REGION_NAME s/region/@/name
REGION_NUMBER s/region/@/number/str
REGION_TIME f/region/@/time
REGION_LENGTH f/region/@/length
LAST_MARKER_NAME s/lastmarker/name
LAST_MARKER_NUMBER s/lastmarker/number/str
LAST_MARKER_TIME f/lastmarker/time
LAST_REGION_NAME s/lastregion/name
LAST_REGION_NUMBER s/lastregion/number/str
LAST_REGION_TIME f/lastregion/time
LAST_REGION_LENGTH f/lastregion/length

# these are write-only, ID is the "NUMBER" field from above -- if not found, creates the marker/region
MARKERID_NAME s/marker_id/@/name
MARKERID_TIME f/marker_id/@/time
MARKERID_NUMBER i/marker_id/@/number
REGIONID_NAME s/region_id/@/name
REGIONID_TIME f/region_id/@/time
REGIONID_LENGTH f/region_id/@/length
REGIONID_NUMBER i/region_id/@/number

LOOP_START_TIME f/loop/start/time
LOOP_END_TIME f/loop/end/time

MASTER_VOLUME n/master/volume s/master/volume/str
MASTER_PAN n/master/pan s/master/pan/str
MASTER_VU n/master/vu
MASTER_VU_L n/master/vu/L
MASTER_VU_R n/master/vu/R

MASTER_SEND_NAME s/master/send/@/name
MASTER_SEND_VOLUME n/master/send/@/volume s/master/send/@/volume/str
MASTER_SEND_PAN n/master/send/@/pan s/master/send/@/pan/str

TRACK_NAME s/track/name s/track/@/name
TRACK_NUMBER s/track/number/str s/track/@/number/str

TRACK_MUTE b/track/mute b/track/@/mute t/track/mute/toggle t/track/@/mute/toggle
TRACK_SOLO b/track/solo b/track/@/solo t/track/solo/toggle t/track/@/solo/toggle
TRACK_REC_ARM b/track/recarm b/track/@/recarm t/track/recarm/toggle t/track/@/recarm/toggle

TRACK_MONITOR b/track/monitor b/track/@/monitor i/track/monitor i/track/@/monitor
TRACK_SELECT b/track/select b/track/@/select

TRACK_VU n/track/vu n/track/@/vu
TRACK_VU_L n/track/vu/L n/track/@/vu/L
TRACK_VU_R n/track/vu/R n/track/@/vu/R
TRACK_VOLUME n/track/volume n/track/@/volume
TRACK_VOLUME s/track/volume/str s/track/@/volume/str
TRACK_VOLUME f/track/volume/db f/track/@/volume/db
TRACK_PAN n/track/pan n/track/@/pan s/track/pan/str s/track/@/pan/str
TRACK_PAN2 n/track/pan2 n/track/@/pan2 s/track/pan2/str s/track/@/pan2/str
TRACK_PAN_MODE s/track/panmode s/track/@/panmode

TRACK_SEND_NAME s/track/send/@/name s/track/@/send/@/name
TRACK_SEND_VOLUME n/track/send/@/volume n/track/@/send/@/volume
TRACK_SEND_VOLUME s/track/send/@/volume/str s/track/@/send/@/volume/str
TRACK_SEND_PAN n/track/send/@/pan n/track/@/send/@/pan
TRACK_SEND_PAN s/track/send/@/pan/str s/track/@/send/@/pan/str

TRACK_RECV_NAME s/track/recv/@/name s/track/@/recv/@/name
TRACK_RECV_VOLUME n/track/recv/@/volume n/track/@/recv/@/volume
TRACK_RECV_VOLUME s/track/recv/@/volume/str s/track/@/recv/@/volume/str
TRACK_RECV_PAN n/track/recv/@/pan n/track/@/recv/@/pan
TRACK_RECV_PAN s/track/recv/@/pan/str s/track/@/recv/@/pan/str

TRACK_AUTO s/track/auto
TRACK_AUTO_TRIM t/track/autotrim t/track/@/autotrim
TRACK_AUTO_READ t/track/autoread t/track/@/autoread
TRACK_AUTO_LATCH t/track/autolatch t/track/@/autolatch
TRACK_AUTO_TOUCH t/track/autotouch t/track/@/autotouch
TRACK_AUTO_WRITE t/track/autowrite t/track/@/autowrite

TRACK_VOLUME_TOUCH b/track/volume/touch b/track/@/volume/touch
TRACK_PAN_TOUCH b/track/pan/touch b/track/@/pan/touch

FX_NAME s/fx/name s/fx/@/name s/track/@/fx/@/name
FX_NUMBER s/fx/number/str s/fx/@/number/str s/track/@/fx/@/number/str
FX_BYPASS b/fx/bypass b/fx/@/bypass b/track/@/fx/@/bypass 
FX_OPEN_UI b/fx/openui b/fx/@/openui b/track/@/fx/@/openui

FX_PRESET s/fx/preset s/fx/@/preset s/track/@/fx/@/preset
FX_PREV_PRESET t/fx/preset- t/fx/@/preset- t/track/@/fx/@/preset-
FX_NEXT_PRESET t/fx/preset+ t/fx/@/preset+ t/track/@/fx/@/preset+

FX_PARAM_NAME s/fxparam/@/name s/fx/@/fxparam/@/name
FX_WETDRY n/fx/wetdry n/fx/@/wetdry n/track/@/fx/@/wetdry
FX_WETDRY s/fx/wetdry/str s/fx/@/wetdry/str s/track/@/fx/@/wetdry/str
FX_PARAM_VALUE n/fxparam/@/value n/fx/@/fxparam/@/value n/track/@/fx/@/fxparam/@/value
FX_PARAM_VALUE s/fxparam/@/value/str s/fx/@/fxparam/@/value/str

FX_EQ_BYPASS b/fxeq/bypass b/track/@/fxeq/bypass
FX_EQ_OPEN_UI b/fxeq/openui b/track/@/fxeq/openui

FX_EQ_PRESET s/fxeq/preset s/track/@/fxeq/preset
FX_EQ_PREV_PRESET s/fxeq/preset- s/track/@/fxeq/preset-
FX_EQ_NEXT_PRESET s/fxeq/preset+ s/track/@/fxeq/preset+

FX_EQ_MASTER_GAIN n/fxeq/gain n/track/@/fxeq/gain 
FX_EQ_MASTER_GAIN f/fxeq/gain/db f/track/@/fxeq/gain/db s/fxeq/gain/str
FX_EQ_WETDRY n/fxeq/wetdry n/track/@/fxeq/wetdry
FX_EQ_WETDRY s/fxeq/wetdry/str s/track/@/fxeq/wetdry/str

FX_EQ_HIPASS_NAME s/fxeq/hipass/str
FX_EQ_HIPASS_BYPASS b/fxeq/hipass/bypass
FX_EQ_HIPASS_FREQ n/fxeq/hipass/freq n/track/@/fxeq/hipass/freq
FX_EQ_HIPASS_FREQ f/fxeq/hipass/freq/hz f/track/@/fxeq/hipass/freq/hz
FX_EQ_HIPASS_FREQ s/fxeq/hipass/freq/str s/track/@/fxeq/hipass/freq/str
FX_EQ_HIPASS_Q n/fxeq/hipass/q n/track/@/fxeq/hipass/q
FX_EQ_HIPASS_Q f/fxeq/hipass/q/oct f/track/@/fxeq/hipass/q/oct
FX_EQ_HIPASS_Q s/fxeq/hipass/q/str s/track/@/fxeq/hipass/q/str

FX_EQ_LOSHELF_NAME s/fxeq/loshelf/str
FX_EQ_LOSHELF_BYPASS b/fxeq/loshelf/bypass
FX_EQ_LOSHELF_FREQ n/fxeq/loshelf/freq n/track/@/fxeq/loshelf/freq
FX_EQ_LOSHELF_FREQ f/fxeq/loshelf/freq/hz f/track/@/fxeq/loshelf/freq/hz
FX_EQ_LOSHELF_FREQ s/fxeq/loshelf/freq/str s/track/@/fxeq/loshelf/freq/str
FX_EQ_LOSHELF_GAIN n/fxeq/loshelf/gain n/track/@/fxeq/loshelf/gain
FX_EQ_LOSHELF_GAIN f/fxeq/loshelf/gain/db f/track/@/fxeq/loshelf/gain/db
FX_EQ_LOSHELF_GAIN s/fxeq/loshelf/gain/str s/track/@/fxeq/loshelf/gain/str
FX_EQ_LOSHELF_Q n/fxeq/loshelf/q n/track/@/fxeq/loshelf/q
FX_EQ_LOSHELF_Q f/fxeq/loshelf/q/oct f/track/@/fxeq/loshelf/q/oct
FX_EQ_LOSHELF_Q s/fxeq/loshelf/q/str s/track/@/fxeq/loshelf/q/str

FX_EQ_BAND_NAME s/fxeq/band/str
FX_EQ_BAND_BYPASS b/fxeq/band/@/bypass
FX_EQ_BAND_FREQ n/fxeq/band/@/freq n/track/@/fxeq/band/@/freq
FX_EQ_BAND_FREQ f/fxeq/band/@/freq/hz f/track/@/fxeq/band/@/freq/hz
FX_EQ_BAND_FREQ s/fxeq/band/@/freq/str s/track/@/fxeq/band/@/freq/str
FX_EQ_BAND_GAIN n/fxeq/band/@/gain n/track/@/fxeq/band/@/gain
FX_EQ_BAND_GAIN f/fxeq/band/@/gain/db f/track/@/fxeq/band/@/gain/db
FX_EQ_BAND_GAIN s/fxeq/band/@/gain/str s/track/@/fxeq/band/@/gain/str
FX_EQ_BAND_Q n/fxeq/band/@/q n/track/@/fxeq/band/@/q
FX_EQ_BAND_Q f/fxeq/band/@/q/oct f/track/@/fxeq/band/@/q/oct
FX_EQ_BAND_Q s/fxeq/band/@/q/str s/track/@/fxeq/band/@/q/str

FX_EQ_NOTCH_NAME s/fxeq/notch/str
FX_EQ_NOTCH_BYPASS b/fxeq/notch/bypass
FX_EQ_NOTCH_FREQ n/fxeq/notch/freq n/track/@/fxeq/notch/freq
FX_EQ_NOTCH_FREQ f/fxeq/notch/freq/hz f/track/@/fxeq/notch/freq/hz
FX_EQ_NOTCH_FREQ s/fxeq/notch/freq/str s/track/@/fxeq/notch/freq/str
FX_EQ_NOTCH_GAIN n/fxeq/notch/gain n/track/@/fxeq/notch/gain
FX_EQ_NOTCH_GAIN f/fxeq/notch/gain/db f/track/@/fxeq/notch/gain/db
FX_EQ_NOTCH_GAIN s/fxeq/notch/gain/str s/track/@/fxeq/notch/gain/str
FX_EQ_NOTCH_Q n/fxeq/notch/q n/track/@/fxeq/notch/q
FX_EQ_NOTCH_Q f/fxeq/notch/q/oct f/track/@/fxeq/notch/q/oct
FX_EQ_NOTCH_Q s/fxeq/notch/q/str s/track/@/fxeq/notch/q/str

FX_EQ_HISHELF_NAME s/fxeq/hishelf/str
FX_EQ_HISHELF_BYPASS b/fxeq/hishelf/bypass
FX_EQ_HISHELF_FREQ n/fxeq/hishelf/freq n/track/@/fxeq/hishelf/freq
FX_EQ_HISHELF_FREQ f/fxeq/hishelf/freq/hz f/track/@/fxeq/hishelf/freq/hz
FX_EQ_HISHELF_FREQ s/fxeq/hishelf/freq/str s/track/@/fxeq/hishelf/freq/str
FX_EQ_HISHELF_GAIN n/fxeq/hishelf/gain n/track/@/fxeq/hishelf/gain
FX_EQ_HISHELF_GAIN f/fxeq/hishelf/gain/sb f/track/@/fxeq/hishelf/gain/db
FX_EQ_HISHELF_GAIN s/fxeq/hishelf/gain/str s/track/@/fxeq/hishelf/gain/str
FX_EQ_HISHELF_Q n/fxeq/hishelf/q n/track/@/fxeq/hishelf/q
FX_EQ_HISHELF_Q f/fxeq/hishelf/q/oct f/track/@/fxeq/hishelf/q/oct
FX_EQ_HISHELF_Q s/fxeq/hishelf/q/str s/track/@/fxeq/hishelf/q/str

FX_EQ_LOPASS_NAME s/fxeq/lopass/str
FX_EQ_LOPASS_BYPASS b/fxeq/lopass/bypass
FX_EQ_LOPASS_FREQ n/fxeq/lopass/freq n/track/@/fxeq/lopass/freq
FX_EQ_LOPASS_FREQ f/fxeq/lopass/freq/hz f/track/@/fxeq/lopass/freq/hz
FX_EQ_LOPASS_FREQ s/fxeq/lopass/freq/str s/track/@/fxeq/lopass/freq/str
FX_EQ_LOPASS_Q n/fxeq/lopass/q n/track/@/fxeq/lopass/q
FX_EQ_LOPASS_Q f/fxeq/lopass/q/oct f/track/@/fxeq/lopass/q/oct
FX_EQ_LOPASS_Q s/fxeq/lopass/q/str s/track/@/fxeq/lopass/q/str

FX_INST_NAME s/fxinst/name s/track/@/fxinst/name
FX_INST_BYPASS b/fxinst/bypass b/track/@/fxinst/bypass
FX_INST_OPEN_UI b/fxinst/openui b/track/@/fxinst/openui

FX_INST_PRESET s/fxinst/preset s/track/@/fxinst/preset
FX_INST_PREV_PRESET t/fxinst/preset- t/track/@/fxinst/preset-
FX_INST_NEXT_PRESET t/fxinst/preset+ t/track/@/fxinst/preset+

FX_INST_PARAM_NAME s/fxinstparam/@/name
FX_INST_PARAM_VALUE n/fxinstparam/@/value n/track/@/fxinstparam/@/value
FX_INST_PARAM_VALUE s/fxinstparam/@/value/str

LAST_TOUCHED_FX_TRACK_NAME s/fx/last_touched/track/name
LAST_TOUCHED_FX_TRACK_NUMBER s/fx/last_touched/track/number/str
LAST_TOUCHED_FX_NAME s/fx/last_touched/name
LAST_TOUCHED_FX_NUMBER s/fx/last_touched/number/str
LAST_TOUCHED_FX_PARAM_NAME s/fxparam/last_touched/name
LAST_TOUCHED_FX_PARAM_VALUE n/fxparam/last_touched/value s/fxparam/last_touched/value/str

# these send MIDI to the vkb MIDI input. parameters are raw MIDI.

# for notes, if two, first wildcard is channel (0-15). MIDI note number is required (as decimal integer only!)
# if parameter value is 0, note-off, otherwise note-on
VKB_MIDI_NOTE i/vkb_midi/@/note/@ f/vkb_midi/@/note/@ i/vkb_midi/note/@ f/vkb_midi/note/@
# similar, but for 0xA0 (poly aftertouch)
VKB_MIDI_POLYAFTERTOUCH i/vkb_midi/@/polyaftertouch/@ f/vkb_midi/@/polyaftertouch/@ i/vkb_midi/polyaftertouch/@ f/vkb_midi/polyaftertouch/@
# for CCs, if two, first wildcard is channel (0-15). MIDI CC number is required (as decimal integer only!)
VKB_MIDI_CC i/vkb_midi/@/cc/@ f/vkb_midi/@/cc/@ i/vkb_midi/cc/@ f/vkb_midi/cc/@
# program change (0xC0) can take channel as wildcard, or value only
VKB_MIDI_PROGRAM i/vkb_midi/@/program f/vkb_midi/@/program i/vkb_midi/program f/vkb_midi/program
# channel pressure (aftertouch) (0xD0) can take channel as wildcard, or value only
VKB_MIDI_CHANNELPRESSURE i/vkb_midi/@/channelpressure f/vkb_midi/@/channelpressure i/vkb_midi/channelpressure f/vkb_midi/channelpressure
# pitch can take channel as wildcard, or value only
VKB_MIDI_PITCH i/vkb_midi/@/pitch f/vkb_midi/@/pitch i/vkb_midi/pitch f/vkb_midi/pitch

ACTION i/action s/action/str t/action/@ f/action/@/cc
ACTION_SOFT f/action/@/cc/soft
ACTION_RELATIVE f/action/@/cc/relative
MIDIACTION i/midiaction t/midiaction/@
MIDILISTACTION i/midilistaction t/midilistaction/@

# ----------------------------------------------------------------

# The following messages are sent from the device, to inform REAPER
# of a change in the device state, behavior, or display capabilities.

DEVICE_TRACK_COUNT i/device/track/count t/device/track/count/@
DEVICE_SEND_COUNT i/device/send/count t/device/send/count/@
DEVICE_RECEIVE_COUNT i/device/receive/count t/device/receive/count/@
DEVICE_FX_COUNT i/device/fx/count t/device/fx/count/@
DEVICE_FX_PARAM_COUNT i/device/fxparam/count t/device/fxparam/count/@
DEVICE_FX_INST_PARAM_COUNT i/device/fxinstparam/count t/device/fxinstparam/count/@
DEVICE_MARKER_COUNT i/device/marker/count t/device/marker/count/@
DEVICE_REGION_COUNT i/device/region/count t/device/region/count/@

REAPER_TRACK_FOLLOWS s/reaper/track/follows
REAPER_TRACK_FOLLOWS_REAPER t/reaper/track/follows/reaper
REAPER_TRACK_FOLLOWS_DEVICE t/reaper/track/follows/device

DEVICE_TRACK_FOLLOWS s/device/track/follows
DEVICE_TRACK_FOLLOWS_DEVICE t/device/track/follows/device
DEVICE_TRACK_FOLLOWS_LAST_TOUCHED t/device/track/follows/last_touched

DEVICE_TRACK_BANK_FOLLOWS s/device/track/bank/follows
DEVICE_TRACK_BANK_FOLLOWS_DEVICE t/device/track/bank/follows/device
DEVICE_TRACK_BANK_FOLLOWS_MIXER t/device/track/bank/follows/mixer

DEVICE_FX_FOLLOWS s/device/fx/follows
DEVICE_FX_FOLLOWS_DEVICE t/device/fx/follows/device
DEVICE_FX_FOLLOWS_LAST_TOUCHED t/device/fx/follows/last_touched
DEVICE_FX_FOLLOWS_FOCUSED t/device/fx/follows/focused

DEVICE_TRACK_SELECT i/device/track/select t/device/track/select/@ 
DEVICE_PREV_TRACK t/device/track/-
DEVICE_NEXT_TRACK t/device/track/+

DEVICE_TRACK_BANK_SELECT i/device/track/bank/select t/device/track/bank/select/@
DEVICE_PREV_TRACK_BANK t/device/track/bank/-
DEVICE_NEXT_TRACK_BANK t/device/track/bank/+

DEVICE_FX_SELECT i/device/fx/select t/device/fx/select/@
DEVICE_PREV_FX t/device/fx/-
DEVICE_NEXT_FX t/device/fx/+

DEVICE_FX_PARAM_BANK_SELECT i/device/fxparam/bank/select t/device/fxparam/bank/select/@ 
DEVICE_FX_PARAM_BANK_SELECT s/device/fxparam/bank/str
DEVICE_PREV_FX_PARAM_BANK t/device/fxparam/bank/-
DEVICE_NEXT_FX_PARAM_BANK t/device/fxparam/bank/+

DEVICE_FX_INST_PARAM_BANK_SELECT i/device/fxinstparam/bank/select t/device/fxinstparam/bank/select/@
DEVICE_FX_INST_PARAM_BANK_SELECT s/device/fxinstparam/bank/str
DEVICE_PREV_FX_INST_PARAM_BANK t/device/fxinstparam/bank/-
DEVICE_NEXT_FX_INST_PARAM_BANK t/device/fxinstparam/bank/+

DEVICE_MARKER_BANK_SELECT i/device/marker/bank/select t/device/marker/bank/select/@
DEVICE_PREV_MARKER_BANK t/device/marker/bank/-
DEVICE_NEXT_MARKER_BANK t/device/marker/bank/+

DEVICE_REGION_BANK_SELECT i/device/region/bank/select t/device/region/bank/select/@
DEVICE_PREV_REGION_BANK t/device/region/bank/-
DEVICE_NEXT_REGION_BANK t/device/region/bank/+

NOTE: it took me a bit understand this file. It lists the constants for REAPER in the all capital letters with underscores. Then it has something like t\record. The ‘t’ and other letters are for which type of value each command expects, but you leave off the preceding letter and rather use that type of value at the end of your OSC command. It it explains all of this in the begging comments of the file.

Then in Sonic Pi you can define a function and call it just before your actual music blocks:

define :osc_setup do
  use_osc "", 7771
  osc "/tempo/raw", current_bpm
  osc "/track/1/recarm", 1 #arm track (1 is for yes)
  osc "/track/2/recarm", 1
  osc "/track/3/recarm", 1
  osc "/track/4/recarm", 0 #don't arm track (0 is for no)
  osc "/track/5/recarm", 0
  osc "/track/6/recarm", 1
  osc "/time", 0 
  osc "/restart", 1
  osc "/record", 1

use_debug false

use_bpm 140

# Run the osc setup function

That’s really it for getting Sonic Pi to Send to Reaper.

To record, you will need to do several things.

Make sure you have some system level audio patcher, like Loopback or Blackhole on Mac, and Jack on Linux. With both apps open you need to wire the 16 Supercollider (Sonic Pi) channels to the 16 inputs of REAPER. I’ve left the 1 & 2 as the main outs, but wire 3 - 16 from Supercollider to REAPER. These are mono channels. Here is an exmaple in Jack using Claudia to manage the patching on Linux:

Then make as many tracks as you need in Reaper. Set the inputs to the mono or stereo tracks you just set up.

Then in Sonic Pi, wrap whatever you want to send to one of those track numbers in REAPER with a with_fx :sound_out, or :sound_out_stereo, something like this:

with_fx :sound_out_stereo, output: 3 do
  live_loop :test do
      play scale(:D2, :minor_pentatonic).choose
      sleep 1

I tend to output stereo so it needs to be every odd channel (i.e., 3 is actually 3 and 4 in stereo, my next output is 5 - but 5 and 6 in stereo).

If set up this way, the above code should arm all tracks and start recording when you run your code in Sonic Pi.

1 Like

I’ve just seen it now and I’m going to test it and report the result :wink:

A lot of thanks for your amazing tutorial!
When i run it get an error :

What is on line 1 of your script?

@Lunatico please try to always copy / paste your code to see the whole script involved :slight_smile:

Having said that, I suspect what is going on is that @Hypostatic’s example above does not properly define the osc_setup function, as the function’s define :osc_setup is nowhere to be seen there.

Thanks for your great help !!!
In the first line i hidden my local ID.
I have tried to upload the .rb file to see all you but is forbidden.
Instead my real local ID i have written “localhost”

Sure, so I’m fairly sure I’m right then - Sonic Pi does not see the beginning of a function at the top of your script, just various seemingly unconnected lines of code.
You need to make sure that osc_setup is defined, by adding this line at the top:
define :osc_setup do
(Which will then match up with the end under the first few lines of code, to enclose the lines in between in a function.)

Excuse me nlb, here is the code

Ok ethancrawford,thanks!!!
I will try it and inform you if works :wink:

New error :

This time, the variable samples has not been defined before the code tries to use it. I don’t know what @Hypostatic had used to define the samples variable in his code, but in general terms, it’s probably the case that samples was a ring or an array of built in sample names, or perhaps paths to external samples. The point is, this variable needs to be set to something before it can be used…

it’s very rare that a copy / paste without understanding the code would teach you something

when you see an end try to check if there is a block start with a do in example.
Adios amigos

@nlb, @ethancrawford, @Lunatico -

I’m terribly sorry, I had the first line, the ‘define’ right after my three grave accents to start the code so it wasn’t showing. I didn’t catch that in my post.

Also, I’ve simplified the code example. I shouldn’t have pasted an entire loop from my file which relied on sample references I had removed.

Sorry about the errors.

Another note @Lunatico. I’m only showing one output (which is 3) here. Obviously you’d want to duplicate for your other tracks, again using odd numbers if you want stereo out. I usually use 3, 5, 7, 9, 11 etc. I believe I’m understanding that correctly as the even channels are included in the stereo. 1,2 are used for the master output from Sonic Pi.

This was meant to be a template. If you need more or less tracks, you can change the osc_setup function to have as many or few as you need. You can also toggle which ones are actually are armed and recording with the 0 or 1 after /track/recarm/(track number here)/recarm .


No worries, it happens! :slightly_smiling_face:

1 Like

Sorry @Hypostatic, it was more for @Lunatico to encourage him to try to understand the code than just copy / paste even if we all start one day and learn every day.
thanks for your shares on this forum !

1 Like

I am pretty sure if I can figure this stuff out anyone can. :slight_smile: I’m just sharing what I’ve learned so far, possibly erroneously at points as I learn as well.

I’m not sure if @samaaron or @ethancrawford know when/why the forum stops letting you edit posts, but I do see a few issues in the Ableton OSC post and can no longer edit. I realize these aren’t supposed to be help documents, but if I find an error, or a new way etc, it’d be helpful to be able to edit old posts that I’ve created (this was a couple months old). I’d hate to steer people down the wrong path. I can always reply to that thread, but gets a bit disjointed. I should ask if I’m approaching sharing this stuff in the correct way, or if there is a better way.

Excuse my absolute ignorance about Sonic Pi and programming in general.
I am a music composer and have never been involved in computer programming.
I discovered Sonic Pi a few days ago by chance and I find it a very attractive program but I must admit that it is very complicated for a person with no computer knowledge.
nlb , first of all my goal is to make things work more than to learn in less than a week the operation of such a complex program.
Little by little I’m understanding things but most of the functions and codes escape me as I imagine they would to you.
Hypostatic suggested that it was more suitable and effective to use reaper than ableton for OSC.
I told him if he could do a detailed tutorial and he agreed quickly and generously.
There have been some unintended errors that are being discovered with my insistence and solved with your wisdom.
I understand that it may make someone uncomfortable, far from it, but I understand.
I don’t want to be an inconvenience in this forum.
Believe me that I am making an effort to understand and move forward.
I really appreciate your help.

Translated with (free version)

you are not :slight_smile: and no problem

Same for me! I’m only a few months in. The tutorials are great and it’s easy to start making some neat sounds. You will pick it up. Start simple and build and experiment. I’m still very much learning as well. Total newbie I am :slight_smile:

The stuff we are doing here with OSC is a bit ‘off-topic’ and more complex and undocumented (at least for specific use, as in Ableton and REAPER). However, probably much like you for your composing - I immediately wanted to know if I could ‘stem’ out individual tracks. Why waste all of the time learning Sonic Pi if you are really about recording more than ‘live-coding’. It does work with some setup. Sorry for the errors in my post - that didn’t help matters. The key thing was to show you an example that you will likely want to modify. There are way more commands to control REAPER that I’m not even using. You can control devices and mixing as well. Mainly I just wanted to record individual code blocks from Sonic Pi. If you learn any new things, please share as well!