Live-Looper with touchOSC control

Hi,

I did a first prototype of my planned live looper with touchOSC control and I ran into some questions I have not been able to solve on my own yet.

There are several occasions I would like to sent feedback from Sonic Pi to touchosc but I did not manage to do that. I am under the impression that it is possible to set the state of a toggle button (including the visual feedback of a highlighted button) from Sonic Pi. E. g. I have a button with the path /rec/track1_arm:

live_loop :track1 do
  use_real_time
  c = sync "/osc/rec/track1_arm"
  set :track, c[0]
end

The button either returns 1.0 or 0.0. I tried to set the value of this button in Sonic Pi with:

osc_send "192.168.2.150", 9000,"/rec/track1_arm",0

(Of course touchOSC is set to receive on Port 9000 and my cellphone has the IP 192.168.2.150.)

This did not work. What am I doing wrong?

Also: Am I actually right, that touchOSC will respond and change the interface according to the values set? It would also be nice to have a feedback about the actual recording time via the LEDs touchosc provides as an interface object.

I case you are interested, here is the prototype so far:

  • the looper is split up in two files: lib-live-looper-touchosc.rb (residing on my harddrive) and
  • live_looper_touchosc.sps, the control script which can be conveniently loaded via a shortcut
  • the prototype just records (and plays back) one track
  • the general idea is to arm a track (where track/loop length is set in the control script), which can be done by the green toogle buttons
  • once armed you can tell Sonic Pi to actually record with the Go-button (wich just evaluates the lib-file)
  • the recording will start with the next loop cycle
  • once you recorded it’ll start play back in the next loop cycle
  • via touchosc you can also set the playback amp and you can toggle if the track is played at all (this also requires to press the Go-button as the code has to be evaluated)

As I said, just a prototype. Probably things will change and hopefully get better.

lib (stored as a file):

# Basic live looper library with touchOSC control
# filename: lib-live-looper-touchosc.rb

use_bpm get(:my_bpm)
t1 = buffer[:track1, get(:track1_len)]

defonce :track_one_vol do
  set :track1_vol, 1
end

live_loop :metro do
  sample :elec_blip, amp: get(:metro_vol), rate: 0.895
  sleep 4
end

live_loop :track1 do
  use_real_time
  c = sync "/osc/rec/track1_arm"
  set :track, c[0]
end

live_loop :track1_vol do
  use_real_time
  c = sync "/osc/rec/track1_vol"
  set :track1_vol, c[0]
end

# Record track 1
if get(:track) == 1.0
  in_thread sync: :metro do
    with_fx :record, buffer: t1 do
      live_audio :audio_in, stereo: true
    end
  end
end

live_loop :track1_play do
  use_real_time
  c = sync "/osc/rec/track1_play"
  set :track1_play, c[0]
end

# Replay Track(s)
live_loop :play_track1, sync: :metro do
  stop if get(:track1_play) == 0.0
  sample t1, amp: get(:track1_vol)
  sleep get(:track1_len)
end

controler (to be loaded and executed in a buffer):

# FIXME: most of that not yet used...
set :metro_vol, 0.5
set :my_bpm, 120
set :playback_master, 10
set :rec_level, 2
set :track1_len, 8
set :track2_len, 16
set :track3_len, 8
set :track4_len, 8

live_loop :setup do
  use_real_time
  p = sync "/osc/rec/go"
  puts "---------- #{p} --------------"
  if p[0] > 0 then
    
   # adjust this to where the file lib-live-looper-touchosc.rb
   # is on your harddrive; I did set up a function for that in init.rb 
    run_file live_looper_touchosc 
    
    if get(:track) == 0 then
      puts "-----------------------------------------"
      puts ""
      puts ""
      puts "               No Track armed.           "
      puts " "
      puts " "
      puts "-----------------------------------------"
    else
      puts "-----------------------------------------"
      puts ""
      puts ""
      puts " Prepare for recording on TRACK No. #{get(:track)} ..."
      puts " "
      puts " "
      puts "-----------------------------------------"
    end
  end
end

touchosc-layout sonicpi-live-looper.touchosc (how you can transfer to touchosc and use it as a custom layout has @robin.newman thankfully explained in a video (about 4’40) ):

<?xml version="1.0" encoding="UTF-8"?>
<layout version="16" mode="3" w="320" h="540" orientation="horizontal">
  <tabpage name="dHJhY2sxX3ZvbA==" 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="dHJhY2sxX2FybQ==" x="20" y="25" w="40" h="40" color="orange" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazFfYXJt" type="toggle" local_off="false" ></control>
    <control name="dHJhY2syX2FybQ==" x="100" y="25" w="40" h="40" color="orange" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazJfYXJt" type="toggle" local_off="false" ></control>
    <control name="dHJhY2szX2FybQ==" x="180" y="25" w="40" h="40" color="orange" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazNfYXJt" type="toggle" local_off="false" ></control>
    <control name="dHJhY2s0X2FybQ==" x="260" y="25" w="40" h="40" color="orange" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazRfYXJt" type="toggle" local_off="false" ></control>
    <control name="bGFiZWwy" x="26" y="34" w="28" h="25" color="yellow" type="labelh" text="MQ==" size="20" background="false" outline="false" ></control><control name="bGFiZWwz" x="106" y="33" w="28" h="25" color="yellow" type="labelh" text="Mg==" size="20" background="false" outline="false" ></control>
    <control name="bGFiZWw0" x="186" y="34" w="28" h="25" color="yellow" type="labelh" text="Mw==" size="20" background="false" outline="false" ></control><control name="bGFiZWw1" x="266" y="34" w="28" h="25" color="yellow" type="labelh" text="NA==" size="20" background="false" outline="false" ></control>
    <control name="Z28=" x="20" y="383" w="280" h="45" color="yellow" scalef="0.0" scalet="1.0" osc_cs="L3JlYy9nbw==" type="push" local_off="false" sp="true" sr="true" ></control>
    <control name="bGFiZWw2" x="110" y="395" w="80" h="25" color="yellow" type="labelh" text="R08=" size="26" background="false" outline="false" ></control>
    <control name="dHJhY2sxX3ZvbA==" x="20" y="96" w="40" h="220" color="green" scalef="0.0" scalet="3.0" osc_cs="L3JlYy90cmFjazFfdm9s" type="faderv" response="absolute" inverted="true" centered="false" ></control>
    <control name="dHJhY2syX3ZvbA==" x="100" y="96" w="40" h="220" color="green" scalef="0.0" scalet="3.0" osc_cs="L3JlYy90cmFjazJfdm9s" type="faderv" response="absolute" inverted="true" centered="false" ></control>
    <control name="dHJhY2szX3ZvbA==" x="180" y="96" w="40" h="220" color="green" scalef="0.0" scalet="3.0" osc_cs="L3JlYy90cmFjazNfdm9s" type="faderv" response="absolute" inverted="true" centered="false" ></control>
    <control name="dHJhY2s0X3ZvbA==" x="260" y="96" w="40" h="220" color="green" scalef="0.0" scalet="3.0" osc_cs="L3JlYy90cmFjazRfdm9s" type="faderv" response="absolute" inverted="true" centered="false" ></control>
    <control name="dHJhY2sxX3BsYXk=" x="20" y="329" w="40" h="40" color="green" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazFfcGxheQ==" type="toggle" local_off="false" ></control>
    <control name="bGFiZWw3" x="26" y="338" w="28" h="25" color="yellow" type="labelh" text="MQ==" size="20" background="false" outline="false" ></control>
    <control name="dHJhY2syX3BsYXk=" x="100" y="329" w="40" h="40" color="green" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazJfcGxheQ==" type="toggle" local_off="false" ></control>
    <control name="dHJhY2szX3BsYXk=" x="180" y="329" w="40" h="40" color="green" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazNfcGxheQ==" type="toggle" local_off="false" ></control>
    <control name="dHJhY2s0X3BsYXk=" x="260" y="329" w="40" h="40" color="green" scalef="0.0" scalet="1.0" osc_cs="L3JlYy90cmFjazRfcGxheQ==" type="toggle" local_off="false" ></control>
    <control name="bGFiZWw4" x="106" y="338" w="28" h="25" color="yellow" type="labelh" text="Mg==" size="20" background="false" outline="false" ></control>
    <control name="bGFiZWw5" x="186" y="337" w="28" h="25" color="yellow" type="labelh" text="Mw==" size="20" background="false" outline="false" ></control>
    <control name="bGFiZWwxMA==" x="266" y="338" w="28" h="25" color="yellow" type="labelh" text="NA==" size="20" background="false" outline="false" ></control>
    <control name="bGFiZWwxMQ==" x="13" y="1" w="112" h="25" color="yellow" type="labelh" text="QXJtIGZvciBSZWNvcmRpbmc=" size="10" background="false" outline="false" ></control>
    <control name="bGFiZWwxMg==" x="-10" y="71" w="112" h="25" color="green" type="labelh" text="UGxheWJhY2s=" size="10" background="false" outline="false" ></control>
  </tabpage>
</layout>

Hmm It should be able to alter the button value. I loaded in your layout (once I had updated my TouchOSC editor to the latest version which you are using) and did a simple test here.
I tried

use_osc "192.168.1.240",9000
live_loop :test do
  osc "/rec/track1_play",1
  osc "/rec/track2_vol",0.5
  sleep 2
  osc "/rec/track1_play",0
  osc "/rec/track2_vol",0
  sleep 2
end

with my iPad TouchOSC on 192.168.1.240 listening on port 9000 and it worked as expected switching the pushbutton on and off and moving the volume slider as well, so not sure what is happening with you.
You should see a red indicator flashing top right on the cellphone screen as the OSC messages are received. If it isn’t you have a comms problem.

I’ll download your full code and have a play later.

Hi Robin,

thanks you are having a look. I tested with your example. No change.

Here is a screenshot of my touchosc setting for osc messages (I am a bit confused that it says 'Found Hosts (0))

touchosc

Sending from touchosc to SP works without any problem. (Yesterday I did also transfer the layout from the editor and the host was found automatically; today I had to provide the IP.)

Hmm that is different from the screen I get on my iPad. Are you running on an Android? Also I don’t have the line with entry ZeroConfName
FoundHosts is a line I get when switched to sync setting on the editor. It should show up a value then, but I think it is OK that it is 0 when working normally. Are you using your phone as an access point or just attaching it to your network like a normal PC?
I’ll try with TouchOSC on my iPhone and see hw that behaves.

  • Yes, running on Adroid.
  • Did see a ‘Found Host’ while working with the editor (as I said: at least yesterday)
  • phone is attached the network like the laptop (found that very convenient :wink: ) …
  • … but I will check if there is a difference if I use it as access point)

Seems to be no difference between ‘phone and laptop linked via wifi’ and ‘phone as access point and laptop linked via usb’.

I just tried on my iPhone. Initially it didn’t work, and couldn’t seen any hosts for transfer. I had TouchOSC Bridge disabled, (shouldn’t be needed here), but enabled it and found that it had a different host IP set. When I set this to the ip of the Sonic Pi machine then it began to work, and I transferred the layout there, and it also works (different IP to the iPad but otherwise same set up).

I suspect your cell is Android, and the interface may be slightly different.

Have you tried comms between the phone TouchOSC and something else? Worth running the puredata example form the documentation which can test both ways I think.

1 Like

Hi Robin,

I can’t check right now, but tomorrow.

I do not have touchOSC bridge. It is the equivalent to the touchosc2midi python script I ran but don’t need, right? If yes, there is no IP that could be configured there…

Can’t install PD on Linux. It requires/installs aubio4.1; after installing Sonic Pi refuses to run. Did this a few days ago and it took me a while to realize what was going on.

Initially I checked with oscdump (but this does only check one direction). There’ll be probably something else with wich I can send osc… I’ll let you know.

Thanks again!

Found a commandline tool with which I can send osc from my linux box (send_osc). The phone does not receive anything. Tried the same also with Control, same result.

I guess you are right and it is a communication problem linked to my Android (with EMUX)j or WLAN. Did also some unsuccessful Google search concerning this one-way-communication.

Could it be that my router passes osc messages just one way? Is there an Android setting blocking incomming osc messages?

But, also without communication backwards to the phone the live looper is usable.

I have no knowledge of Android so can’t help here. Maybe you could raise something on the hexler.net site forum?
Have you checked that Sonic Pi can send OSC successfully on your system, to another receiving program? eg on ubuntu could use https://apps.ubuntu.com/cat/applications/pyliblo-utils/

That is actually a very good idea. I did try to send from Sonic Pi with:

use_osc "192.168.2.120", 9000
live_loop :test do
  osc "/rec/track1_play",1
  sleep 2
  osc "/rec/track1_play",0
  sleep 2
end

as well as:

use_osc "localhost", 9000
live_loop :test do
  osc "/rec/track1_play",1
  sleep 2
  osc "/rec/track1_play",0
  sleep 2
end

and listened with oscdump. Nothing received.

But I can send with send_osc and listen with osc_dump.

I do get a repeating error in the erlang.log:

Error in process <0.136.0> with exit value:
{badarg,[{erlang,system_time,[nanosecond],[]},
         {osc,now,0,[{file,"osc.erl"},{line,54}]},
         {pi_server,send_later,7,[{file,"pi_server.erl"},{line,177}]}]}
udp server timeout:69
udp server timeout:70  

I have also an error in `osmid_o2m.log:

sh: 1: [my_sp_install_path]/app/server/native/linux/osmid/o2m-L: not found

Maybe this is a hint?

both the erlang osc files and osmid have had updates which may not have been flagged on the SP github site. Might be worth rebuilding the erlang beam files using erlc and also checking you have the latest osmid binaries.

Did recompile the erlang files and compiled the lates osmid binaries.

Still the same error messages in the logs. Does it make sense to create an issue at Github? I do not know.

Same result concerning osc messages. Sonic Pi does not seem to send them out.

Are you building the very latest from SP github repro or the release settings for 3.0.1?
There IS an issue that I have found with the latest which prevents Mac from working. It is because of commits on 16th September Erlang -use -noshell flag when starting process and osmid _teach o2m to use loopback network. These both stopped Mac from working. If you manually change them back (no need to rebuild aprt from redoing erlc for the relevant erlang file). See if that helps. I think they were put in to try and improve Windows version behaviour.
The full numbers for the commits were
51570a3d413df9e07a0246da3e6442e6b1559ec5
and
0c1e9e402463f09c4b0f7a7f66475b6d46148817

This may be your problem.

NB SEE NEXT POST FOR A CORRECTION

OOPS I think I put the wrong ERLANG change commit. IT should be the one
Erlang - tech scheduler to only listen on loopback network
number dedc9ea6cfbf6e8c6d02e48196c5cb23c93e0b55
NOT the one I mentioned for Erlang above. It has the same date.

I am a bit embarrassed to ask: I guess you are advising me to go back to a previous commit (better the 2 that you mentioned), fetch the erlang related files (pi_server.erl and osc.erl) and exchange these in my 3.0.1 installation (which acctually is the commit about two weeks ago), right?

If yes, I haven’t done this before so I don’t know how this works… I will follow this ressource:

You could do that, but In my case I just looked at what the commits did, which were very simple changes and I edited the two files directly.
The two changes are in studio.rb line 695 was changed from

o2m_spawn_cmd = "'#{osmid_o2m_path}'" + " -b -i #{@midi_osc_out_port} -O #{@midi_osc_in_port} -m 6"

to

o2m_spawn_cmd = "'#{osmid_o2m_path}'" + "-L -b -i #{@midi_osc_out_port} -O #{@midi_osc_in_port} -m 6"

Change it back again

and
in pi_server.erl line 69

{ok, Socket} = gen_udp:open(Port, [binary]),

was changed to

{ok, Socket} = gen_udp:open(Port, [binary, {ip, loopback}]),

again change it back again, but in this case you will then have to rebuild it using
erlc pi_server.rlc to produce an updated pi_server.beam file

The studio.rb file is in /app/server/sonicpi/lib/sonicpi

If you want you can keep the original files elsewhere.

Ok, that was clear. Done.

The message from osmid_o2m.log obviously is gone now. But I get still the errors in the erlang.log (I did erlc the file pi_server.erl):

=ERROR REPORT==== 1-Nov-2017::19:27:35 ===
Error in process <0.216.0> with exit value:
{badarg,[{erlang,system_time,[nanosecond],[]},
         {osc,now,0,[{file,"osc.erl"},{line,54}]},
         {pi_server,send_later,7,[{file,"pi_server.erl"},{line,177}]}]}

Did you get rid of these?

I don’t get this erlang error. If you are still not getting the exteranl OSC messages from Sonic PI working then I suggest it may be worth raising it as an error on github, (the error message you are getting. Can you ascertain WHEN it occurs? Is it as a result of an osc message sent from SP?

Also perhaps I’ll ask @samaaron to comment on this thread The error messages certainly looks like something is being delayed.