Skip to content

Instantly share code, notes, and snippets.

@rbnpi rbnpi/ReadMe.md
Last active Oct 21, 2018

Embed
What would you like to do?
Sonic Pi Record / Player version 1.2 (not Pi3 friendly) See REadMe file.

Sonic Pi Record / Player version 1.2

The two other files enable a TouchOSC interface to be used with Sonic Pi 3 and above to allow notes to be played on Sonic Pi, and also recorded in real time for subsequent replay. Recordings can also be stored in files on your computer.

The Sonic Pi program is too long to run in a buffer, and should be run using the run_file command eg

run_file "/path/to/file/recordplayercombined-RF.rb"

(The RF in the name reminds you to do this)

The TouchOSC template is the file index.xml This should be downloaded and then compressed or zipped with the resulting file renamed as spRecordPlayer12.touchosc This file should then be loaded into your TouchOSC editor and from there synced to your iPad/iPhone/Android device which is running TouchOSC

You should adjust the IP addresses in the Sonic Pi program to point to your TouchOSC device, and also adjust the OSC settings of that device to point back to your computer running Sonic Pi. The Host address should be set equal to the IP address of your Sonic Pi computer, and the outgoing port set to 4559 with the incoming port set to 9000. The Sonic Pi programs should point to the host address of your TouchOSC device.

This version does not run well on a Raspberry Pi burt requires a more powerful machine like a Mac.

Full details about the program and how to use it are in an article at https://rbnrpi.wordpress.com/sonic-pi-3-player-recorder-version-1-2-using-touchosc/

<?xml version="1.0" encoding="UTF-8"?><layout version="16" mode="1" orientation="horizontal"><tabpage name="cnA=" scalef="0.0" scalet="1.0" li_t="" li_c="gray" li_s="14" li_o="false" li_b="false" la_t="" la_c="gray" la_s="14" la_o="false" la_b="false" ><control name="c3ludGg=" x="46" y="902" w="680" h="60" color="green" scalef="0.0" scalet="1.0" type="multitoggle" number_x="10" number_y="1" ex_mode="true" local_off="false" ></control><control name="bGFiZWw1NA==" x="233" y="51" w="167" h="20" color="yellow" type="labelh" text="YnkgUm9iaW4gTmV3bWFu" size="18" background="true" outline="false" ></control><control name="bGFiZWwzMQ==" x="711" y="183" w="25" h="25" color="red" type="labelh" text="TQ==" size="18" background="true" outline="false" ></control><control name="bGFiZWwyNg==" x="711" y="403" w="25" h="25" color="pink" type="labelh" text="Rg==" size="18" background="true" outline="false" ></control><control name="bGFiZWwyNQ==" x="706" y="655" w="35" h="25" color="yellow" type="labelh" text="bWV0" size="18" background="true" outline="false" ></control><control name="bGFiZWwyNA==" x="711" y="577" w="25" h="25" color="pink" type="labelh" text="Uw==" size="18" background="true" outline="false" ></control><control name="bXQz" x="699" y="428" w="50" h="50" color="pink" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="bXQx" x="699" y="601" w="50" h="50" color="pink" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="bGFiZWwzMA==" x="625" y="858" w="66" h="20" color="yellow" type="labelh" text="bGVkcyBvbg==" size="18" background="true" outline="false" ></control><control name="bGFiZWwx" x="233" y="13" w="20" h="25" color="yellow" type="labelh" text="Uw==" size="24" background="true" outline="false" ></control><control name="bXVsdGlwdXNoMQ==" x="86" y="87" w="600" h="600" color="red" scalef="0.0" scalet="1.0" type="multipush" number_x="8" number_y="8" local_off="false" ></control><control name="bGFiZWwy" x="61" y="923" w="44" h="20" color="green" type="labelh" text="cGlhbm8=" size="14" background="true" outline="false" ></control><control name="bGFiZWwz" x="615" y="843" w="80" h="20" color="yellow" type="labelh" text="cGxheWJhY2s=" size="18" background="false" outline="false" ></control><control name="a2V5" x="176" y="828" w="420" h="60" color="purple" scalef="0.0" scalet="1.0" type="multitoggle" number_x="7" number_y="1" ex_mode="true" local_off="false" ></control><control name="bWFqbWlu" x="102" y="828" w="60" h="60" color="purple" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="bWFqbWluTGFiZWw=" x="108" y="849" w="47" h="20" color="yellow" type="labelh" text="bWFqb3I=" size="16" background="true" outline="false" ></control><control name="bGFiZWw1" x="198" y="849" w="20" h="20" color="yellow" type="labelh" text="Qw==" size="16" background="true" outline="false" ></control><control name="bGFiZWw2" x="257" y="849" w="20" h="20" color="yellow" type="labelh" text="RA==" size="16" background="true" outline="false" ></control><control name="bGFiZWw3" x="316" y="849" w="20" h="20" color="yellow" type="labelh" text="RQ==" size="16" background="true" outline="false" ></control><control name="bGFiZWw4" x="375" y="849" w="20" h="20" color="yellow" type="labelh" text="Rg==" size="16" background="true" outline="false" ></control><control name="bGFiZWw5" x="434" y="849" w="20" h="20" color="yellow" type="labelh" text="Rw==" size="16" background="true" outline="false" ></control><control name="bGFiZWwxMA==" x="493" y="849" w="20" h="20" color="yellow" type="labelh" text="QQ==" size="16" background="true" outline="false" ></control><control name="bGFiZWwxMQ==" x="553" y="849" w="20" h="20" color="yellow" type="labelh" text="Qg==" size="16" background="true" outline="false" ></control><control name="bTE=" x="117" y="638" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTk=" x="114" y="115" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTg=" x="333" y="188" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTc=" x="560" y="263" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTY=" x="259" y="336" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTU=" x="485" y="412" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTQ=" x="191" y="491" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTM=" x="413" y="564" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTI=" x="636" y="638" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bTEw" x="633" y="115" w="25" h="25" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="bGFiZWwxNQ==" x="248" y="13" w="49" h="25" color="green" type="labelh" text="b25pYw==" size="24" background="true" outline="false" ></control><control name="bGFiZWwxNw==" x="317" y="13" w="20" h="25" color="green" type="labelh" text="aQ==" size="24" background="true" outline="false" ></control><control name="bGFiZWwxNg==" x="303" y="13" w="20" h="25" color="yellow" type="labelh" text="UA==" size="24" background="true" outline="false" ></control><control name="bGFiZWwyMA==" x="359" y="13" w="195" h="25" color="yellow" type="labelh" text="UmVjb3JkIC8gUGxheWVy" size="24" background="true" outline="false" ></control><control name="bGFiZWwyMQ==" x="692" y="681" w="64" h="20" color="pink" type="labelh" text="TWV0IE9u" size="18" background="true" outline="false" ></control><control name="bGFiZWwyMg==" x="129" y="923" w="44" h="20" color="green" type="labelh" text="cGx1Y2s=" size="14" background="true" outline="false" ></control><control name="bGFiZWwyMw==" x="711" y="353" w="25" h="25" color="yellow" type="labelh" text="cGI=" size="18" background="true" outline="false" ></control><control name="bGFiZWwyNw==" x="711" y="270" w="25" h="25" color="red" type="labelh" text="Uw==" size="18" background="true" outline="false" ></control><control name="bGFiZWwyOA==" x="711" y="93" w="25" h="25" color="red" type="labelh" text="Rg==" size="18" background="true" outline="false" ></control><control name="bGVkcGxheWJhY2s=" x="699" y="836" w="50" h="50" color="yellow" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="bWV0cm9ub21l" x="699" y="706" w="50" h="50" color="pink" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="cGIz" x="699" y="120" w="50" h="50" color="red" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="cGIy" x="699" y="208" w="50" h="50" color="red" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="cGIx" x="699" y="297" w="50" h="50" color="red" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="dm9sdW1l" x="23" y="163" w="50" h="221" color="red" scalef="0.0" scalet="1.0" type="faderv" response="absolute" inverted="true" centered="false" ></control><control name="ZHVyYXRpb24=" x="25" y="463" w="50" h="221" color="red" scalef="0.0" scalet="1.0" type="faderv" response="absolute" inverted="true" centered="false" ></control><control name="bW9kaWZpZXI=" x="247" y="724" w="280" h="90" color="red" scalef="0.0" scalet="1.0" type="multipush" number_x="2" number_y="1" local_off="false" ></control><control name="bGFiZWw1NQ==" x="195" y="923" w="44" h="20" color="green" type="labelh" text="dHJp" size="14" background="true" outline="false" ></control><control name="bGFiZWw1Ng==" x="263" y="923" w="44" h="20" color="green" type="labelh" text="dGIzMDM=" size="14" background="true" outline="false" ></control><control name="bGFiZWw1Nw==" x="330" y="923" w="44" h="20" color="green" type="labelh" text="YmxhZGU=" size="14" background="true" outline="false" ></control><control name="bGFiZWw1OA==" x="389" y="923" w="62" h="20" color="green" type="labelh" text="Y2hpcGxlYWQ=" size="14" background="true" outline="false" ></control><control name="bGFiZWw1OQ==" x="670" y="923" w="37" h="20" color="green" type="labelh" text="Zm0=" size="14" background="true" outline="false" ></control><control name="bGFiZWw2MA==" x="599" y="923" w="44" h="20" color="green" type="labelh" text="c2luZQ==" size="14" background="true" outline="false" ></control><control name="bGFiZWw2MQ==" x="516" y="923" w="76" h="20" color="green" type="labelh" text="dGVjaHNhd3M=" size="14" background="true" outline="false" ></control><control name="bGFiZWw2Mg==" x="458" y="923" w="59" h="20" color="green" type="labelh" text="cHJvcGhldA==" size="14" background="true" outline="false" ></control><control name="bGFiZWw2Mw==" x="7" y="129" w="74" h="25" color="red" type="labelh" text="Vm9sdW1l" size="18" background="true" outline="false" ></control><control name="bGFiZWw2NA==" x="20" y="428" w="58" h="25" color="red" type="labelh" text="RGVjYXk=" size="18" background="true" outline="false" ></control><control name="bGFiZWw2NQ==" x="429" y="696" w="58" h="25" color="red" type="labelh" text="U2hhcnA=" size="18" background="true" outline="false" ></control><control name="bGFiZWw2Ng==" x="286" y="697" w="58" h="25" color="red" type="labelh" text="RmxhdA==" size="18" background="true" outline="false" ></control><control name="bGFiZWw2OA==" x="564" y="17" w="69" h="25" color="red" type="labelh" text="RW5hYmxl" size="18" background="true" outline="false" ></control><control name="bGFiZWw2OQ==" x="563" y="40" w="69" h="25" color="red" type="labelh" text="UmVjb3Jk" size="18" background="true" outline="false" ></control><control name="cmVwZWF0" x="27" y="733" w="136" h="50" color="red" scalef="0.0" scalet="1.0" type="multitoggle" number_x="4" number_y="1" ex_mode="true" local_off="false" ></control><control name="bGFiZWw3MA==" x="42" y="702" w="104" h="23" color="yellow" type="labelh" text="UEIgUmVwZWF0cw==" size="16" background="true" outline="false" ></control><control name="bGFiZWw3MQ==" x="35" y="793" w="20" h="20" color="yellow" type="labelh" text="MQ==" size="16" background="true" outline="false" ></control><control name="bGFiZWw3Mg==" x="101" y="793" w="20" h="20" color="yellow" type="labelh" text="Mw==" size="16" background="true" outline="false" ></control><control name="bGFiZWw3Mw==" x="69" y="793" w="20" h="20" color="yellow" type="labelh" text="Mg==" size="16" background="true" outline="false" ></control><control name="bGFiZWw3NA==" x="123" y="793" w="43" h="20" color="yellow" type="labelh" text="Y29udA==" size="16" background="true" outline="false" ></control><control name="bGFiZWw3NQ==" x="418" y="51" w="114" h="20" color="yellow" type="labelh" text="KHZlcnNpb24gMS4yKQ==" size="18" background="true" outline="false" ></control><control name="ZHJ1bXM=" x="614" y="707" w="50" h="50" color="pink" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="bGFiZWw3OQ==" x="541" y="726" w="67" h="27" color="pink" type="labelh" text="RHJ1bXM=" size="18" background="true" outline="false" ></control><control name="bGFiZWw4MA==" x="538" y="707" w="74" h="24" color="pink" type="labelh" text="U3luY2Vk" size="18" background="true" outline="false" ></control><control name="bGFiZWw4MQ==" x="711" y="490" w="25" h="25" color="pink" type="labelh" text="TQ==" size="18" background="true" outline="false" ></control><control name="bXQy" x="699" y="514" w="50" h="50" color="pink" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="cmVzdHgy" x="169" y="43" w="45" h="30" color="blue" scalef="1.0" scalet="2.0" type="toggle" local_off="false" ></control><control name="bGFiZWw4Mg==" x="90" y="44" w="73" h="27" color="yellow" type="labelh" text="cmVzdCB4IDI=" size="18" background="true" outline="false" ></control><control name="aGVscGVyTGVkcw==" x="699" y="771" w="50" h="50" color="yellow" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="bGFiZWw4Mw==" x="625" y="799" w="65" h="20" color="yellow" type="labelh" text="bGVkcyBvbg==" size="18" background="true" outline="false" ></control><control name="bGFiZWw4NA==" x="628" y="781" w="62" h="20" color="yellow" type="labelh" text="aGVscGVy" size="18" background="true" outline="false" ></control><control name="cmVzdEhhbGY=" x="169" y="8" w="45" h="30" color="blue" scalef="1.0" scalet="0.5" type="toggle" local_off="false" ></control><control name="bGFiZWw4NQ==" x="84" y="10" w="83" h="25" color="yellow" type="labelh" text="cmVzdCB4IDAuNQ==" size="18" background="true" outline="false" ></control><control name="cmVjb3Jk" x="697" y="8" w="60" h="60" color="red" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="cGxheWJhY2s=" x="16" y="8" w="60" h="60" color="blue" scalef="0.0" scalet="1.0" type="toggle" local_off="false" ></control><control name="bGFiZWwxMw==" x="34" y="26" w="23" h="23" color="yellow" type="labelh" text="UA==" size="18" background="true" outline="false" ></control><control name="bGFiZWwxNA==" x="713" y="24" w="27" h="27" color="yellow" type="labelh" text="Ug==" size="18" background="true" outline="false" ></control><control name="ZW5hYmxlUmVjb3Jk" x="642" y="15" w="45" h="45" color="red" scalef="0.0" scalet="1.0" type="push" local_off="false" sp="true" sr="true" ></control><control name="bGVkUmVj" x="655" y="28" w="20" h="20" color="yellow" scalef="0.0" scalet="1.0" type="led" ></control></tabpage><tabpage name="c2F2" scalef="0.2" scalet="0.5" li_t="" li_c="gray" li_s="14" li_o="false" li_b="false" la_t="" la_c="gray" la_s="14" la_o="false" la_b="false" ><control name="bGFiZWw1Mg==" x="232" y="269" w="75" h="25" color="green" type="labelh" text="Q29udGVudA==" size="16" background="true" outline="false" ></control><control name="c2xvdA==" x="172" y="311" w="60" h="500" color="yellow" scalef="0.0" scalet="1.0" type="multitoggle" number_x="1" number_y="10" ex_mode="true" local_off="false" ></control><control name="c2xvdGJhbms=" x="513" y="256" w="120" h="60" color="yellow" scalef="0.0" scalet="1.0" type="multitoggle" number_x="2" number_y="1" ex_mode="true" local_off="false" ></control><control name="cmVhZA==" x="511" y="408" w="50" h="50" color="green" scalef="0.0" scalet="1.0" type="push" local_off="false" sp="true" sr="true" ></control><control name="d3JpdGU=" x="512" y="567" w="50" h="50" color="red" scalef="0.0" scalet="1.0" type="push" local_off="false" sp="true" sr="true" ></control><control name="ZW5hYmxlU2F2ZQ==" x="587" y="485" w="50" h="50" color="red" scalef="0.0" scalet="1.0" type="push" local_off="false" sp="true" sr="true" ></control><control name="bGFiZWwzMw==" x="95" y="83" w="102" h="25" color="green" type="labelh" text="U2F2ZSBGb2xkZXI=" size="18" background="true" outline="false" ></control><control name="cGF0aA==" x="94" y="107" w="531" h="25" color="green" type="labelh" text="U2V0IHRoaXMgaW4gc2F2ZS5yYiBwcm9ncmFt" size="16" background="true" outline="false" ></control><control name="YmFuaw==" x="529" y="219" w="80" h="25" color="yellow" type="labelh" text="U2xvdCBCYW5r" size="18" background="true" outline="false" ></control><control name="bGFiZWwzNg==" x="152" y="219" w="104" h="20" color="yellow" type="labelh" text="U2xvdCBTZWxlY3Q=" size="18" background="true" outline="false" ></control><control name="bGFiZWwzNw==" x="568" y="420" w="73" h="25" color="green" type="labelh" text="TG9hZCBGaWxl" size="14" background="true" outline="false" ></control><control name="bGFiZWwzOA==" x="488" y="495" w="87" h="25" color="red" type="labelh" text="RW5hYmxlIFNhdmU=" size="14" background="true" outline="false" ></control><control name="bGFiZWwzOQ==" x="567" y="578" w="80" h="25" color="red" type="labelh" text="U2F2ZSBGaWxl" size="14" background="true" outline="false" ></control><control name="bGFiZWw0MA==" x="130" y="324" w="25" h="25" color="blue" type="labelh" text="MQ==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0MQ==" x="129" y="769" w="25" h="25" color="blue" type="labelh" text="MTA=" size="14" background="true" outline="false" ></control><control name="bGFiZWw0Mg==" x="129" y="720" w="25" h="25" color="blue" type="labelh" text="OQ==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0Mw==" x="130" y="670" w="25" h="25" color="blue" type="labelh" text="OA==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0NA==" x="130" y="620" w="25" h="25" color="blue" type="labelh" text="Nw==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0NQ==" x="130" y="571" w="25" h="25" color="blue" type="labelh" text="Ng==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0Ng==" x="130" y="521" w="25" h="25" color="blue" type="labelh" text="NQ==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0Nw==" x="130" y="472" w="25" h="25" color="blue" type="labelh" text="NA==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0OA==" x="130" y="422" w="25" h="25" color="blue" type="labelh" text="Mw==" size="14" background="true" outline="false" ></control><control name="bGFiZWw0OQ==" x="130" y="373" w="25" h="25" color="blue" type="labelh" text="Mg==" size="14" background="true" outline="false" ></control><control name="bGFiZWw1MA==" x="197" y="22" w="320" h="25" color="blue" type="labelh" text="UmVjb3JkIC8gUGxheWVyIHNhdmUgc2NyZWVu" size="24" background="true" outline="false" ></control><control name="bGVkU2F2ZQ==" x="651" y="498" w="20" h="20" color="red" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDI=" x="272" y="375" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDE=" x="272" y="326" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDEw" x="270" y="771" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDk=" x="272" y="722" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDg=" x="272" y="672" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDc=" x="272" y="623" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDY=" x="272" y="573" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDU=" x="272" y="524" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDQ=" x="272" y="474" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDM=" x="272" y="425" w="20" h="20" color="blue" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDEy" x="300" y="375" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDEx" x="300" y="326" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDIw" x="302" y="771" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDE5" x="300" y="722" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDE4" x="300" y="672" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDE3" x="300" y="623" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDE2" x="300" y="573" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDE1" x="300" y="524" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDE0" x="300" y="474" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="ZDEz" x="300" y="425" w="20" h="20" color="purple" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTI=" x="80" y="375" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTE=" x="80" y="326" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTEw" x="80" y="771" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTk=" x="79" y="722" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTg=" x="80" y="672" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTc=" x="80" y="623" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTY=" x="80" y="573" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTU=" x="80" y="524" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTQ=" x="80" y="474" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTM=" x="80" y="425" w="20" h="20" color="orange" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTEy" x="107" y="375" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTEx" x="107" y="326" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTIw" x="107" y="771" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTE5" x="107" y="722" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTE4" x="107" y="672" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTE3" x="107" y="623" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTE2" x="108" y="573" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTE1" x="108" y="524" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTE0" x="108" y="474" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="YTEz" x="107" y="425" w="20" h="20" color="brown" scalef="0.0" scalet="1.0" type="led" ></control><control name="bGFiZWw1MQ==" x="87" y="270" w="104" h="25" color="green" type="labelh" text="TGFzdCBBY2Nlc3M=" size="16" background="true" outline="false" ></control><control name="bWlzc2luZw==" x="494" y="634" w="191" h="25" color="yellow" type="labelh" text="IA==" size="16" background="true" outline="false" ></control><control name="ZW5hYmxlTG9hZA==" x="584" y="343" w="50" h="50" color="green" scalef="0.0" scalet="1.0" type="push" local_off="false" sp="true" sr="true" ></control><control name="bGFiZWw4Ng==" x="487" y="359" w="87" h="25" color="green" type="labelh" text="RW5hYmxlIExvYWQ=" size="14" background="true" outline="false" ></control><control name="bGVkTG9hZA==" x="649" y="360" w="20" h="20" color="green" scalef="0.0" scalet="1.0" type="led" ></control><control name="bGFiZWw4Nw==" x="152" y="823" w="101" h="25" color="yellow" type="labelh" text="Q3VycmVudCBCYW5r" size="16" background="true" outline="false" ></control><control name="YmFuazI=" x="237" y="855" w="101" h="25" color="purple" type="labelh" text="IA==" size="18" background="true" outline="false" ></control><control name="YmFuazE=" x="72" y="856" w="101" h="25" color="blue" type="labelh" text="IA==" size="18" background="true" outline="false" ></control><control name="bGFiZWw5MA==" x="240" y="324" w="25" h="25" color="purple" type="labelh" text="MTE=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5MQ==" x="239" y="769" w="25" h="25" color="purple" type="labelh" text="MjA=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5Mg==" x="239" y="720" w="25" h="25" color="purple" type="labelh" text="MTk=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5Mw==" x="240" y="670" w="25" h="25" color="purple" type="labelh" text="MTg=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5NA==" x="240" y="620" w="25" h="25" color="purple" type="labelh" text="MTc=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5NQ==" x="240" y="571" w="25" h="25" color="purple" type="labelh" text="MTY=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5Ng==" x="240" y="521" w="25" h="25" color="purple" type="labelh" text="MTU=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5Nw==" x="240" y="472" w="25" h="25" color="purple" type="labelh" text="MTQ=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5OA==" x="240" y="422" w="25" h="25" color="purple" type="labelh" text="MTM=" size="14" background="true" outline="false" ></control><control name="bGFiZWw5OQ==" x="240" y="373" w="25" h="25" color="purple" type="labelh" text="MTI=" size="14" background="true" outline="false" ></control></tabpage></layout>
#spRecordPlayer.rb
#Sonic Pi Record / Player control using TouchOSC written by Robin Newman, March 2018
#handles recording and playback, real time or double speed, key changes, metronome,
#10 synth choices, optional percussion. It is possible to loop recordings, and play them
#seamlessly if recorded using the inbuilt metronome. Adjustment can be made
#to the time between repeats.
#uses Ableton push2 style layout. Does not run well on a Pi3 as it taxes Sonic Pi quite heavily and requires
#low latency audio output. Works well on a Mac.
#release version 1.2
use_osc "192.168.1.240",9000 #adjust for the address of your TouchOSC device
#next line path to folder in which recored json files are saved
JSONfilePath="/Users/rbn/Documents/SPfromXML/recordplayer/" #adjust path for your system
use_osc_logging false
use_debug false
use_cue_logging false
use_bpm 60
st=Time.now
#intialise various flags
set :playing,false
set :recflag,false
set :recenable,false
set :leds,true
set :key,1
set :majmin,0
set :metroflag,false
set :ms,60
set :pb,60
set :synptr,1
set :vol,0.5
set :dur,0.4
set :mod,0
set :repeat,1
set :rtime,1
set :restx2,1
set :restHalf,1
set :slot,01;set :bank,0;set :saveFlag,0;set :helpLeds,1;set :minFileSize,60
set :loadFlag,0
delta= 0.03 #experimental time tuning "tuning"
#extract wild card matches from osc addresses
define :parse_sync_address do |address|
v= get_event(address).to_s.split(",")[6]
if v != nil
return v[3..-2].split("/")
else
return ["error"]
end
end
#turn on blue dots on note input matrix
define :blueledsOn do
10.times do |x|
osc "/rp/m"+(x+1).to_s,1
sleep 0.01
end
end
#belt and braces make sure all note indicators are off
define :noteIndictorsOff do
8.times do |x|
8.times do |y|
osc "/rp/multipush1/"+(x+1).to_s+"/"+(y+1).to_s,0
end
end
end
define :init do #intialise TouchOSC screens
osc "/rp/record",0
osc "/rp/playback",0
osc "/rp/key/1/1",1
osc "/rp/majmin",0
osc "/rp/majminLabel","major"
osc "/rp/mt1",1
osc "/rp/mt2",0
osc "/rp/pb1",1
osc "/rp/pb2",0
osc "/rp/pb3",0
osc "/rp/synth/1/1",1
osc "/rp/metronome",0
osc "/rp/ledplayback",1
osc "/rp/helperLeds",1
osc "/rp/volume",0.8
osc "/rp/duration",0.2
osc "/rp/ledRec",0
osc "/rp/repeat/1/1",1
osc "/rp/drums",0
blueledsOn
noteIndictorsOff
osc "/sav/slot/1/1",1
osc "/sav/slotbank/1/1",1
osc "/sav/ledSave",0
osc "/sav/missing"," "
osc "/sav/bank1","<== 1-10"
osc "/sav/bank2"," "
osc "/sav/path",JSONfilePath
end
init # run the screen init
#control helper leds on note matrix
define :doExtraToggles do |c,r,state|
osc "/rp/multipush1/"+(c.to_i-3).to_s+"/"+(r.to_i-1).to_s,state if c.to_i-3>0 and r.to_i-1 > 0
osc "/rp/multipush1/"+(c.to_i-6).to_s+"/"+(r.to_i-2).to_s,state if c.to_i-6>0 and r.to_i-2 > 0
osc "/rp/multipush1/"+(c.to_i+3).to_s+"/"+(r.to_i+1).to_s,state if c.to_i+3<9 and r.to_i+1 < 9
osc "/rp/multipush1/"+(c.to_i+6).to_s+"/"+(r.to_i+2).to_s,state if c.to_i+6<9 and r.to_i+2 < 9
end
#change note +/- a semitone
define :modchange do |n|
v =0
v=1 if n == -1
v=2 if n == 1
return v
end
#clear data stored in arrays
define :clearData do
recn=[].clear;timn=[].clear
set :recn,recn;set :timn,timn
sleep 0.2
end
#set flag to turn metronome on or off
live_loop :setmetronome do
use_real_time
b = sync "/osc/rp/metronome "
if b[0]==1
set :metroflag,true
else
set :metroflag,false
end
end
#select metronome bpm, and adjust indicators
live_loop :adjustMetro do
use_real_time
b = sync "/osc/rp/mt*"
res = parse_sync_address "/osc/rp/mt*"
if b[0]==1
if res[2][-1]=="1"
osc "/rp/mt2",0
osc "/rp/mt3",0
set :ms,60
elsif res[2][-1]=="2"
osc "/rp/mt1",0
osc "/rp/mt3",0
set :ms,90
elsif res[2][-1]=="3"
osc "/rp/mt1",0
osc "/rp/mt2",0
set :ms,120
end
end
end
#generate the metronome
live_loop :metro do
use_real_time
use_bpm get(:ms)
play :c5,release:0.05 if get(:metroflag)
sleep 1
end
#select playback tempo, and adjust indicators
live_loop :adjustPBtempo do
use_real_time
b = sync "/osc/rp/pb*"
res = parse_sync_address "/osc/rp/pb*"
if b[0]==1
if res[2][-1]=="1"
osc "/rp/pb2",0
osc "/rp/pb3",0
set :pb,60
elsif res[2][-1]=="2"
osc "/rp/pb1",0
osc "/rp/pb3",0
set :pb,90
elsif res[2][-1]=="3"
osc "/rp/pb1",0
osc "/rp/pb2",0
set :pb,120
end
end
end
#flash note and modifier pushed and update vol slider, decay slider and synth indicators
define :flashPush do |c,r,m,v,d,s,k,mm|
osc "/rp/multipush1/"+c.to_s+"/"+r.to_s,1
osc "/rp/modifier/"+m.to_s+"/1",1
osc "/rp/key/"+k.to_s+"/1",1
osc "/rp/majmin/",mm
osc "/rp/volume",v
osc "/rp/duration",d
osc"/rp/synth/"+s.to_s+"/1",1
sleep 0.17
osc "/rp/multipush1/"+c.to_s+"/"+r.to_s,0
osc "/rp/modifier/"+m.to_s+"/1",0
end
#play a note using supplied parameters and update leds/sliders if selected
define :playNote do |c,r,synptr,majmin,key,dur,vol,m|
use_synth [:piano,:pluck,:tri,:tb303,:blade,:chiplead,:prophet,:tech_saws,:sine,:fm][synptr.to_i-1]
sc=["c","d","e","f","g","a","b"][key.to_i-1]
type = [:major,:minor][majmin.to_i]
use_transpose m #for flat or sharp or neither -1 or 1 or 0
cue :rhythm
with_fx :reverb,room: 0.8,mix: 0.6 do
play scale(sc+"2",type,num_octaves: 4)[(c.to_i-1)+3*(8-r.to_i)],release: dur,amp: vol
end
if get(:leds)
in_thread do
flashPush c,r,modchange(m),vol,durchange(dur),synptr,key,majmin
end
end
end
#deal with button on note input matrix being pushed. Play note and Record data if enabled
#also deals with helper leds on note display when note is pressed if enabled
live_loop :noteKeyPushed do
use_real_time
b= sync "/osc/rp/multipush1/*/*"
res = parse_sync_address "/osc/rp/multipush1/*/*"
if b[0]==1
doExtraToggles(res[3],res[4],1) if get(:helpLeds)==1
if get(:recflag)
recn=get(:recn);timn=get(:timn)
rn=recn + [[res[3],res[4],get(:synptr),get(:majmin),get(:key),get(:dur),get(:vol),get(:mod)]]
tn=timn + [Time.now-st]
set :recn,rn
set :timn,tn
puts "tn #{tn}"
end
playNote res[3],res[4],get(:synptr),get(:majmin),get(:key),get(:dur),get(:vol),get(:mod)
else
doExtraToggles(res[3],res[4],0) if get(:helpLeds)==1
end
end
#plays back recorded sequence. Handles repeat and rest input, cues precussion if enabled
#kills playback at end of notes, or if playbutton turned off
define :playRecordedNotes do
use_real_time
use_bpm get(:pb)
recn= get(:recn)
timn = get(:timn)
puts recn
puts timn
puts get(:rtime)
sleep 0.2
if recn != nil
get(:repeat).times do
recn.length.times do |x|
if x==0
#puts "delay: #{get(:rtime)*get(:restx2)}" #for debugging
sleep 0
else
kk= timn[x]-timn[x-1]+delta
#puts "kk #{kk}" #for debugging
sleep kk
end
cue :first
playNote(recn[x][0],recn[x][1],recn[x][2],recn[x][3],recn[x][4],recn[x][5],recn[x][6],recn[x][7])
break if get(:kill)
end
sleep get(:rtime) * get(:restx2) * get(:restHalf) -delta
break if get(:kill)
end
end
puts "finished notes playback"
set :notesfinish,true
end
#deals with Major/Minor switch. Storesd result in :majmin and updates switch display
live_loop :getMajminChanges do
use_real_time
b = sync "/osc/rp/majmin"
set :majmin,b[0]
if b[0]==1
osc "/rp/majminLabel","minor"
else
osc "/rp/majminLabel","major"
end
end
#deals with key changes, saving current key number
live_loop :keySwitchChanged do
use_real_time
b= sync "/osc/rp/key/*/*"
res = parse_sync_address "/osc/rp/key/*/1"
if b[0]==1
set :key,res[3]
end
end
#gets inout from synth selector buttons and updates pointer stored in :synptr
live_loop :chooseSynth do
use_real_time
b = sync "/osc/rp/synth/*/1"
if b[0]==1
v = parse_sync_address "/osc/rp/synth/*/1"
set :synptr,v[3]
end
end
#reads rest x 2 button and sets :rest2x flag. Used to adjust delay between repeat
live_loop :getRestx2 do
use_real_time
b = sync "/osc/rp/restx2"
set :restx2,b[0]
end
#reads rest x 0.5 button and sets :restHalf flag. Used to adjust delay between repeat
live_loop :getRestHalf do
use_real_time
b = sync "/osc/rp/restHalf"
set :restHalf,b[0]
end
#reverts scaled reading from the decay slider back to range 0->1 for updating the slider
define :durchange do |d|
return (d-0.1)/1.9
end
#deals with safety enable record button. Sets :recenable flag and updates indicator led
live_loop :enablerecord do
use_real_time
b = sync "/osc/rp/enableRecord"
if b[0]==1
if get(:recenable)==false
osc "/rp/ledRec",1
set :recenable,true
else
osc "/rp/ledRec",0
set :recenable,false
end
end
end
#deals with recdord button being pressed. Checks if enabled. Clears existing data
#sets rest time for repeats :rtime appropriate for current metronome bpm
#records start time st from which to work out durations of notes
#sets :recflag to prevent playback. Updates record led. If logic says not to record
#resets record button and enable button
live_loop :recording do
use_real_time
b = sync "/osc/rp/record"
if b[0]==1
if get(:playing)==false and get(:recenable)==true
clearData #initialise for recording
set :rtime,60.0/get(:ms) * get(:restx2) * get(:restHalf)
sleep 0.1
st=Time.now
set :recflag,true
puts "recording"
else
osc "/rp/record",0
osc "/rp/ledRec",0
set :recenable,false
end
else
set :recflag,false
set :recenable,false
osc "/rp/ledRec",0
puts "stopped recording"
end
end
#loop check if playing should be disabled because all notes played, or recording enabled
#and switches button off if necessary
live_loop :checkNotPlaying do
use_real_time
if get(:notesfinish)==true
set :playing,false
osc "/rp/playback",0
end
if get(:rec)==true
osc "/rp/playback",0
end
sleep 0.75
end
#handles play button pushed. checks logic to see if allowed, sets notesfinished to false
#sets kill (used for stop interrupt) to false, playing to true and starts
#playback in a thread. If released, sets kill flag to stop any playback.
live_loop :handlePlayButtonOn do
use_real_time
b = sync "/osc/rp/playback"
if b[0]==1
if get(:recflag)==false and get(:playing)==false
set :notesfinish,false
set :kill,false
sleep 0.2
set :playing, true
puts "starting playback"
in_thread do
playRecordedNotes
end
end
else
osc "/rp/playback",0
set :kill,true
set :playing,false
puts "kill set"
end
end
#enables or disables using leds on note matrix during playback. Sets :leds flag
live_loop :getledplayback do
use_real_time
b = sync "/osc/rp/ledplayback"
if b[0]==1
set :leds,true
else
set :leds,false
end
end
#gets reading from volume slider (range 0->1 Stored in :vol)
live_loop :getvol do
use_real_time
b = sync "/osc/rp/volume"
set :vol,b[0]
end
#gets reading from Decay slider (range 0->1 is modified to 0.1->2 and stored in :dur)
live_loop :getduration do
use_real_time
b = sync "/osc/rp/duration"
set :dur,b[0]*1.9+0.1
end
#gets input from multi (2) push switches used for flat and sharp
#transforms input to set :mod as 0 (neither pushed,0 flat -1, sharp +1)
#if both pushed last one registered wins!
live_loop :getmodifiers do
use_real_time
b = sync "/osc/rp/modifier/*/1"
if b[0]==1
res = parse_sync_address "/osc/rp/modifier/*/1"
set :mod,[-1,1][res[3].to_i-1]
else
set :mod,0
end
end
#reads the 4 way repeat toggle and sets :repeat to 1,2,3 or 500 (continous!)
live_loop :getRepeats do
use_real_time
b = sync "/osc/rp/repeat/*/1"
if b[0]==1
res = parse_sync_address "/osc/rp/repeat/*/1"
set :repeat,[0,1,2,3,500][res[3].to_i]
end
end
#reads switch to turn on/off helper leds indicating buttons with the same note
#sored in :helpLeds (only for pushed notes, not for playback notes)
live_loop :getHelperLeds do
use_real_time
b = sync "/osc/rp/helperLeds"
set :helpLeds,b[0]
end
#experimental simple percussion loop wihc can be activated and started by playback
#it is also synced to a note being played at the start of each loop
#This allows for some discrepancy of the manually entered timings
#the rate of teh loop is set by the currently seledted metronome bpm, whether toe
#metronome is playing or not.
#it is advisable to disable the synced drums button before stopping playback
#or a spurious burst of drums may result next time playback starts
live_loop :perc do
use_real_time
b = sync "/osc/rp/drums"
if b[0]==1
puts "arming drums"
set :kDrums,false
#add some reverb
with_fx :reverb,room: 0.8,mix: 0.6 do
live_loop :amen,sync: :first do
sync :rhythm
use_bpm get(:ms)
sample :bd_haus
sleep 0.5
sample :drum_cymbal_closed
sleep 0.25
sample :drum_cymbal_closed
sleep 0.25
stop if get(:kDrums)
end
end
else
set :kDrums,true
end
end
################################### Following code deals with second screen
#function checks if file in teh given slot n exists, and its size
#if size > minFileSize it illuminates a led to indicate the file has recored notes in it.
#ie it is not an empty file with some structure but no data saved
define :setFileIndicator do |n|
if File.exists?(JSONfilePath+(n).to_s+".json")
if File.size(JSONfilePath+(n).to_s+".json") > get(:minFileSize)
osc "/sav/d"+n.to_s,1
else
osc "/sav/d"+n.to_s,0
end
end
end
#initial setup of all file indicator leds, parsing the existing json files for content
20.times do |n|
setFileIndicator n+1
end
#clears all the leds shwoing the last file accessed
define :clearLastAccess do
20.times do |n|
osc "/sav/a"+(n+1).to_s,0
end
end
#clears all the last access leds, then illuminates the led for the input parameter n
define :setLastAccess do |n|
clearLastAccess
sleep 0.02
osc "/sav/a"+n.to_s,1
end
#initial clearing of all las access leds when program is started
clearLastAccess
#gets the data read from a file to hash :restore and allocates it
#to :recn,:timn: and :rtime for use by the "playing" part of the program
define :restoreHash do
restore=get(:restore)
puts restore
set :timn, restore["Vtimn"]
set :recn, restore["Vrecn"]
set :rtime, restore["Vrtime"]
end
#eals with the select slot 10 way switch, updating :slot with 1-> 10
#bank is applied separately to get overall final slot 1 -> 20
live_loop :setSlot do
use_real_time
b = sync "/osc/sav/slot/1/*"
if b[0]==1
res=parse_sync_address "/osc/sav/slot/1/*"
slot=res[4].to_i
set :slot,slot
puts "slot is #{slot}"
end
end
#stores the data from the arrays :recn,:timn and the value of :rtime in a Hasn vals
#then writes the hash to the relevant json file specified by the input parameter n
#updates the File Indicator led appropriately (off if an empty file otherwise on)
define :writeJson do |n|
vals=Hash.new
vals[:Vtimn]=get(:timn)
vals[:Vrecn]=get(:recn)
vals[:Vrtime]=get(:rtime)
File.open(JSONfilePath+(n).to_s+".json", 'w') do |f|
f.write(MultiJson.dump(vals, pretty: true))
f.close
sleep 0.2
setFileIndicator n
end
end
#checks if the file in slot n exists, and gives error info if not. Otherwise loads file
#and uses restoreHash functio to extract data to playing part of the program
define :readJson do |n|
if File.exist?(JSONfilePath+n.to_s+".json")==false
sample :misc_crow
osc "/sav/missing",n.to_s+".json file missing"
sleep 0.4 #time to read message
else
osc "/sav/missing",n.to_s+".json file found"
content =File.read(JSONfilePath+n.to_s+".json")
set :restore,MultiJson.load(content)
sleep 0.4
restoreHash
end
end
#deals with the two way slotbank selector switch, setting :bank to 0 or 1
#updates the display to show current bank range
live_loop :slotbank do
use_real_time
b = sync "/osc/sav/slotbank/*/1"
if b[0]==1
res = parse_sync_address "/osc/sav/slotbank/*/1"
bank= res[3].to_i - 1
set :bank,bank
if bank==0
puts "bank selected is 1-10"
osc "/sav/bank1","<== 1-10"
osc "/sav/bank2"," "
else
puts "bank selected is 11-20"
osc "/sav/bank2","11-20 ==>"
osc "/sav/bank1"," "
end
end
end
#deals with Enable Save switch. When pushed sets saveLed on for 1.5 seconds, and
#enables toe :saveflag for the same length of time
live_loop :enableSave do
use_real_time
b = sync "/osc/sav/enableSave"
if b[0]==1
osc "/sav/ledSave",1
set :saveFlag,1
sleep rt(1.5)
osc "/sav/ledSave",0
set :saveFlag,0
end
end
#deals wtih Save File button. checks if save flag set, and gives error if not, exiting
#Otherwise calculates the final slot value (slot + 10*bank), calls writeJson
#for this number, then updates the lastAccess led for this number. Puts message
#on TouchOSC screen.
live_loop :writeData do
use_real_time
b = sync "/osc/sav/write"
if get(:saveFlag)==0
puts "Save not enabled"
osc "/sav/missing","Enable Save First!"
sample :misc_crow
else
if b[0]==1
slot=get(:slot)+10*get(:bank)
writeJson(slot)
setLastAccess slot
puts "data written to slot #{slot}"
osc "/sav/missing","File #{slot}.json saved"
end
end
end
#deals with enableLoad button. Enables loadFlag for 1.5 seconds, displaying a led
#for the same period
live_loop :enableLoad do
use_real_time
b = sync "/osc/sav/enableLoad"
if b[0]==1
osc "/sav/ledLoad",1
set :loadFlag,1
sleep rt(1.5)
osc "/sav/ledLoad",0
set :loadFlag,0
end
end
#deals with Load File button. Checks in loadFlag is 1,and gives error if not,exiting.
#Otherwise calculates the final slot value (slot + bank*10)< calls readJson
#for this number, then sets the lastAccess led for this number. Info messages are displayed
#on the touchOSC screen
live_loop :readData do
use_real_time
b = sync "/osc/sav/read"
if get(:loadFlag)==0
puts "Load not enabled"
osc "/sav/missing","Enable Load First!"
sample :misc_crow
else
if b[0]==1
slot=get(:slot)+10*get(:bank)
readJson(slot)
setLastAccess(slot)
puts "data read from slot #{slot}"
osc "/sav/missing","File #{slot}.json loaded"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.