You can use a function like this , which extracts wild cards from an OSC address
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
EDITED TO FIT YOUR EXAMPLE. I posted this late last night after a “night out” and thought it needed a bit more detail and explanation this morning!
So the program below works with the example requirement you gave in your post.
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
live_loop :getModulate do
use_real_time
#the * after osc in the next line allows this to work on 3.2dev as well as 3.2
#you can miss it out on 3.2 if you wish,althouhg it will work with it
p,q,r,s= sync "/osc*/modulate/*"
puts "values",p,q,r,s
#the FIRST * after osc in the next line allows this to work on 3.2dev as well as 3.2
#you can miss it out on 3.2 if you wish,although it will work with it
res = parse_sync_address "/osc*/modulate/*"
puts "channel",res[2].to_i #track activated extracts the 3rd element of the osc address, ie the value of the *
end
#sample osc messages now sent to test this
use_osc "localhost",4559
osc "/modulate/1",1,2,3,4
sleep 1
osc "/modulate/2",5,6,7,8
See my project
for a practical demonstration of this.
The function uses an undocumented function get_event from Sonic PI. It may change in the futre, but works at present with all version 3 including latest dev version.
The * following /osc in the address lines ie /osc*/ allows this to work in version 3.2dev as well as 3.1 If you will only use 3.1 then you can miss out this *, although it will work if you leave it there. Currently it IS necessary to be there to work with version 3.2dev.
This gives output.
├─ "values" 1 2 3 4
└─ "channel" 1
├─ "values" 5 6 7 8
└─ "channel" 2
To help understand how the parseAddress function works add some puts statements as below:
define :parse_sync_address do |address|
puts get_event(address)
puts get_event(address).to_s.split(",")
v= get_event(address).to_s.split(",")[6]
if v != nil
puts v
puts v[3..-2].split("/")
return v[3..-2].split("/")
else
return ["error"]
end
end
With the example based on your requirements the program will then give output
├─ "values" 1 2 3 4
├─ #<SonicPi::CueEvent:[[1550307484.7874072, 0, #<SonicPi::ThreadId [-1]>, 0, 0.0, 60.0], "/osc/modulate/1", [1, 2, 3, 4]]
├─ ["#<SonicPi::CueEvent:[[1550307484.7874072", " 0", " #<SonicPi::ThreadId [-1]>", " 0", " 0.0", " 60.0]", " \"/osc/modulate/1\"", " [1", " 2", " 3", " 4]]"]
├─ " \"/osc/modulate/1\""
├─ ["osc", "modulate", "1"]
└─ "channel" 1
and
├─ "values" 5 6 7 8
├─ #<SonicPi::CueEvent:[[1550307485.7777338, 0, #<SonicPi::ThreadId [-1]>, 0, 0.0, 60.0], "/osc/modulate/2", [5, 6, 7, 8]]
├─ ["#<SonicPi::CueEvent:[[1550307485.7777338", " 0", " #<SonicPi::ThreadId [-1]>", " 0", " 0.0", " 60.0]", " \"/osc/modulate/2\"", " [5", " 6", " 7", " 8]]"]
├─ " \"/osc/modulate/2\""
├─ ["osc", "modulate", "2"]
└─ "channel" 2
for the two osc messages