Skip to content

Instantly share code, notes, and snippets.

@rbnpi
Last active July 4, 2022 07:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbnpi/d4a6757032cce7f232d29efd2b9444bd to your computer and use it in GitHub Desktop.
Save rbnpi/d4a6757032cce7f232d29efd2b9444bd to your computer and use it in GitHub Desktop.
Sonic Pi program to display lissajous figures controlled by TouchOSC. Requires SP 2.12 midi-alpha6 or later. Video with details at https://youtu.be/coDyIySAZbw

This program runs on Sonic Pi midi version. It works on SP 2.12-midi-alpha6 released recently to patreon subscribers of Sam Aaron see https://patreon.com/samaaron It also requires the program TouchOSC which is available for iPad or iPhone users at a very modest price. The TouchOSC file required to run this program is contained in the file index.xml To produce the TouchOSC file, download the raw file index.xml, right click it and select the Compress function. Rename the resulting file SPlissajous.touchosc and say Yes when it asks if you want to change the file extension. Open the file using the TouchOSC editor and download it to your iPad or other compatible device using the sync function. The layout is designed to fit on an iPhone or iPad. The SPlissajousTouchOSC.rb file should be downloaded and opened or pasted into a blank Sonic Pi buffer.

<?xml version="1.0" encoding="UTF-8"?><layout version="15" mode="0" orientation="vertical"><tabpage name="MQ==" scalef="0.0" scalet="1.0" ><control name="ZmFkZXIy" x="93" y="35" w="160" h="26" color="green" scalef="0.0" scalet="1.0" type="faderh" response="absolute" inverted="false" centered="false" ><midi var ="x" type="0" channel="1" data1="1" data2f="0" data2t="127" sysex="" /></control><control name="ZmFkZXIz" x="93" y="108" w="160" h="26" color="yellow" scalef="0.0" scalet="1.0" type="faderh" response="absolute" inverted="false" centered="false" ><midi var ="x" type="0" channel="1" data1="2" data2f="0" data2t="127" sysex="" /></control><control name="ZmFkZXI0" x="93" y="182" w="160" h="26" color="purple" scalef="0.0" scalet="1.0" type="faderh" response="absolute" inverted="false" centered="false" ><midi var ="x" type="0" channel="1" data1="3" data2f="0" data2t="127" sysex="" /></control><control name="ZmFkZXI1" x="93" y="256" w="160" h="26" color="red" scalef="0.0" scalet="1.0" type="faderh" response="absolute" inverted="false" centered="false" ><midi var ="x" type="0" channel="1" data1="4" data2f="0" data2t="127" sysex="" /></control><control name="ZmFkZXI2" x="93" y="330" w="160" h="26" color="red" scalef="0.0" scalet="1.0" type="faderh" response="absolute" inverted="false" centered="false" ><midi var ="x" type="0" channel="1" data1="5" data2f="0" data2t="127" sysex="" /></control><control name="ZmFkZXI3" x="93" y="404" w="160" h="26" color="red" scalef="0.0" scalet="1.0" type="faderh" response="absolute" inverted="false" centered="false" ><midi var ="x" type="0" channel="1" data1="6" data2f="0" data2t="127" sysex="" /></control><control name="bXVsdGl0b2dnbGUx" x="6" y="131" w="50" h="200" color="blue" scalef="0.0" scalet="1.0" type="multitoggle" number_x="1" number_y="6" ex_mode="true" local_off="false" ><midi var ="x4" type="0" channel="1" data1="14" data2f="0" data2t="127" sysex="" /><midi var ="x3" type="0" channel="1" data1="13" data2f="0" data2t="127" sysex="" /><midi var ="x2" type="0" channel="1" data1="12" data2f="0" data2t="127" sysex="" /><midi var ="x1" type="0" channel="1" data1="11" data2f="0" data2t="127" sysex="" /><midi var ="x6" type="0" channel="1" data1="16" data2f="0" data2t="127" sysex="" /><midi var ="x5" type="0" channel="1" data1="15" data2f="0" data2t="127" sysex="" /></control><control name="QnBt" x="254" y="25" w="25" h="44" color="red" type="labelv" text="QnBt" size="14" background="true" outline="false" ></control><control name="RGVsYXk=" x="254" y="98" w="25" h="44" color="red" type="labelv" text="RGVsYXk=" size="14" background="true" outline="false" ></control><control name="Vm9s" x="254" y="172" w="25" h="44" color="red" type="labelv" text="Vm9s" size="14" background="true" outline="false" ></control><control name="QXR0YWNr" x="254" y="246" w="25" h="44" color="red" type="labelv" text="QXR0YWNr" size="14" background="true" outline="false" ></control><control name="U3VzdGFpbg==" x="254" y="316" w="25" h="54" color="red" type="labelv" text="U3VzdGFpbg==" size="14" background="true" outline="false" ></control><control name="UmVsZWFzZQ==" x="254" y="386" w="25" h="61" color="red" type="labelv" text="UmVsZWFzZQ==" size="14" background="true" outline="false" ></control><control name="U1lOVEg=" x="33" y="353" w="25" h="60" color="blue" type="labelv" text="U1lOVEg=" size="14" background="true" outline="false" ></control><control name="dkJwbQ==" x="62" y="13" w="26" h="69" color="green" type="labelv" text="dkJwbQ==" size="14" background="true" outline="false" ></control><control name="dkRlbGF5" x="62" y="86" w="26" h="69" color="yellow" type="labelv" text="dkRlbGF5" size="14" background="true" outline="false" ></control><control name="dkF0dGFjaw==" x="62" y="233" w="26" h="69" color="red" type="labelv" text="dkF0dGFjaw==" size="14" background="true" outline="false" ></control><control name="dlN1c3RhaW4=" x="62" y="307" w="26" h="69" color="red" type="labelv" text="dlN1c3RhaW4=" size="14" background="true" outline="false" ></control><control name="dlJlbGVhc2U=" x="61" y="381" w="26" h="69" color="red" type="labelv" text="dlJlbGVhc2U=" size="14" background="true" outline="false" ></control><control name="c3ludGhOYW1l" x="6" y="343" w="26" h="88" color="blue" type="labelv" text="U3ludGhOYW1l" size="14" background="true" outline="false" ></control><control name="dlZvbA==" x="62" y="160" w="26" h="69" color="purple" type="labelv" text="dlZvbA==" size="14" background="true" outline="false" ></control><control name="VGl0bGUx" x="33" y="7" w="25" h="117" color="yellow" type="labelv" text="U29uaWMgUGkgTGlzc2Fqb3Vz" size="12" background="true" outline="false" ></control><control name="VGl0bGUy" x="6" y="7" w="25" h="117" color="yellow" type="labelv" text="YnkgUm9iaW4gTmV3bWFu" size="12" background="true" outline="false" ></control></tabpage></layout>
#Sonic Pi Lissajous investigator by Robin Newman
#using a TouchOSC controller
use_osc "192.168.1.50",9000 #adjust to suit your ipad/iphone ip
flip=1 #flips x and y plots on each iteration
use_debug false
use_cue_logging false
use_midi_logging false
use_debug false
use_osc_logging false
use_arg_checks false
synthList=[:sine,:tri,:saw,:square,:fm,:pulse]
#intial values for variables
vBpm=60
vDelay=2
vVol=3
vAttack=1
vSustain=2
vRelease=1
synthName=:sine
midiVals=[0.2,0.333,1,0.25,0.80,0.25] #starting settings for sliders
#setup TouchOSC screen initial values
osc "/1/vBpm",vBpm
osc "/1/vDelay",vDelay
osc "/1/vVol",vVol
osc "/1/vAttack",vAttack
osc "/1/vSustain",vSustain
osc "/1/vRelease",vRelease
osc "/1/synthName",synthName
sleep 0.1
6.times do |i| #initialise sliders usinb mdi_cc commands
midi_cc i+1,midiVals[i]*127
end
midi_cc 11,127 #select switch for :sine synth
#list of frequency pairs
a=(ring [600,600],[600,540],[600,400],[300,600],[200,600],[150,600],[100,600])
ts=(ring 0,2,4,5,7,5,4,2,0,-1,-3,-5,-3,-1) #transpose settings
live_loop :liss,auto_cue: false do #main program live_loop
use_bpm vBpm
use_synth synthName
tick
tick_set :tp, look/7
b=a.look
flip = -flip
use_transpose ts.look(:tp)
play hz_to_midi(b[0]),attack: vAttack,amp: vVol,sustain: vSustain,release: vRelease,pan: 1*flip
play hz_to_midi(b[1]),attack: vAttack,amp: vVol,sustain: vSustain,release: vRelease,pan: -1*flip
sleep vDelay
end
live_loop :control,auto_cue: false do #live loop to get input from TouchOSC
use_real_time
b= sync "/midi/*/*/*/control_change" #wait for next midi input (any device/port)
case b[0] #process according to control source b[0] range 1-6 and 11-16
when 1
vBpm=30+150*b[1].to_f/127 #get and scale bpm
osc "/1/vBpm",(vBpm*100).round.to_f/100 #update TouchOSC display
when 2
vDelay=1+b[1].to_f/127*3 #get and scale delay
osc "/1/vDelay",(vDelay*100).round.to_f/100 #update TouchOSC display
when 3
vVol=0.5+2.5*b[1].to_f/127 #get and scale volune
osc "/1/vVol",((vVol*100).to_f/100).round #update TouchOSC display
when 4
vAttack=0.5+2*b[1].to_f/127 #get and scale attack
osc "/1/vAttack",(vAttack*100).round.to_f/100 #update TouchOSC display
when 5
vSustain=2.5*b[1].to_f/127 #get and scale sustain
osc "/1/vSustain",(vSustain*100).round.to_f/100 #update TouchOSC display
when 6
vRelease=0.5+2*b[1].to_f/127 #get and scale release
osc "/1/vRelease",(vRelease*100).round.to_f/100 #update TouchOSC display
when 11,12,13,14,15,16 #deal with synths select multi toggle switch
if b[1]!=0 #only deal with switch turning on
synthNum=b[0]-11 #get synth offset in synthList
synthName=synthList[synthNum]
osc "/1/synthName",synthName #update TouchOSC displayed synth name
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment