Send an array through OSC


I am trying to send an array via OSC into Sonic Pi and am having trouble storing it into a variable and accessing the values within the array.

This is the array I am trying to send:

[62, 50, 62, 61, 54, 57, 50, 57, 54, 51, 48, 53, 52, 53, 54, 60, 54, 52, 52, 48, 48, 51, 53, 48, 45, 45, 50, 49, 48, 59, 60, 45, 61, 39, 45, 44, 41, 41]

I tried using set and get but had no luck.

# a = [] # -> initializing 'a' as an array didn't help

live_loop :foo do
  a = sync "/osc/wek/outputs"
  set :notes, a

live_loop :magenta do
  puts get[:notes] # prints out '[]'
  puts get[:notes[0]] # prints out 'nil'
  sleep 1

Any help is appreciated. If I can get this to work, my next step would be to send multiple arrays, so if there would be more then just repeating the same process, any insight would also be appreciated.


Here is a demo program that sends an array (or a ring if you prefer) in an OSC message and extracts it when received using the eval function, but see the caveats…

use_osc "localhost",4559

#loop detects the arrival of an OSC message addressed to "/hello"
#note Sonic Pi addes the preceeding /osc (/osc* needed if using 3.2dev)
live_loop :getOsc do
  b = sync "/osc*/hello"
  puts b[0]
  notes= eval b[0] #this turns "[.......]" into [.......]
  puts notes
  play_pattern_timed notes,[0.2],release: 0.2
#send an osc message from SonicPi to itself
osc "/hello",[67, 69, 71, 72, 74, 76, 78, 79]

sleep 4 #leave a delay
#eg 2
live_loop :getScale do
  data,duration,volume,synth = sync "/osc*/getScale"
  notes = eval data
  use_synth synth
  (4*n).times do
    play notes.tick,release: duration,amp: volume
    sleep duration

data = scale(:g4,:major,num_octaves: 2)
duration = 0.1
volume = 0.7
synth = "tb303"
#send osc message. data will be a ring
osc "/getScale",data,duration,volume,synth

NB eval is potentially a dangerous function as it will evaluate anything inside it for example
eval “play 72” will play the note 72!
eval “stop” will stop the live_loop
so you only want to use it in situations where you have control, and there is no likeleyhood of unwanted messages being received that could affect your program. They would need to have the correct OSC address and port number so it is unlikely.


Thanks @robin.newman

When I ran the first block of code I got this error message:

Here is the exact code I ran:

live_loop :getOsc do
  b = sync "/osc/wek/outputs"
  puts b[0]
  notes= eval b[0] #this turns "[.......]" into [.......]
  puts notes
  play_pattern_timed notes,[0.2],release: 0.2

However, I am no longer having the original issue for some reason. Now the entire array is stored in that variable. In fact, I am sending 3 different arrays over OSC which get sent as one long array, so I am using the each_slice method to separate them into 3 arrays which is working fine.

Here is a simplified version of the code I’m using

live_loop :getOsc do
  b = sync "/osc/wek/outputs"
  use_synth :saw
  notes, dur, time = b.each_slice((b.length/3.0).round).to_a
  notes.length.times do
    play notes.ring.tick, release: dur.ring.look
    sleep dur.ring.look

Just to give you some insight into what I’m doing:
I’ve been playing around with standalone apps that were just released by the Magenta project by Google which is a Creative Machine Learning project built with Tensorflow.

One of the apps generates 8 measure melodies into a midi file. I’ve been converting those midi files into JSON files and playing around with them in p5.js

I wanted to try and play some of these melodies in Sonic Pi but I have no clue how to work with data files in Ruby, so I just made a script in Javascript to push the pertinent info (notes, duration, start times) into arrays and send them via OSC into Sonic Pi. The code I put above does the trick although it doesn’t account for rests or melodies that don’t start right at 0, but I’ve been playing around with that.

I intend to look deeper into this thread about playing Midi files in Sonic Pi, but since I already had a program in p5 and feel more comfortable working in javascript, I’m just happy to get the melodies to play for now.

Thanks again for your help!