Hi there,
it looks like the current value of p3
is nil
. Could you share the code where that is set?
# Sonic Pi init file
# Code in here will be evaluated on launch.
live_loop:listen do
n1=sync "/osc/play_this1"
n2=sync "/osc/play_this2"
n3=sync "/osc/play_this3"
p1=n1[0]
p2=n2[0]
p3=n3[0]
'-----------------------'
use_synth :beep
if p1<=11 then
play :C4
sleep(0.1)
elsif p1<21 then
play :D4
sleep(0.1)
elsif p1<31 then
play :E4
sleep(0.1)
elsif p1<41 then
play :F4
sleep(0.1)
elsif p1<51 then
play :G4
sleep(0.1)
end
'-----------------------'
use_synth :chipbass
if p2<=11 then
play :C4
sleep(0.1)
elsif p2<21 then
play :D4
sleep(0.1)
elsif p2<31 then
play :E4
sleep(0.1)
elsif p2<41 then
play :F4
sleep(0.1)
elsif p2<51 then
play :G4
sleep(0.1)
end
'------------------'
use_synth :piano
if p3<=11 then
play :C4
sleep(0.1)
elsif p3<21 then
play :D4
sleep(0.1)
elsif p3<31 then
play :E4
sleep(0.1)
elsif p3<41 then
play :F4
sleep(0.1)
elsif p3<51 then
play :G4
sleep(0.1)
end
end
`
> indent preformatted text by 4 spaces
`
THANKS A LOT IF YOU COULD ALSO SEE OUR PYTHON CODE!!!
from time import sleep
from pythonosc import osc_message_builder
from pythonosc import udp_client
import RPi.GPIO as GPIO
import timesender = udp_client.SimpleUDPClient(‘127.0.0.1’,4559)
def checkdist(trigger,echo):
GPIO.setmode(GPIO.BCM)
GPIO.setup(trigger,GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(echo,GPIO.IN)
GPIO.output(trigger,GPIO.HIGH)
time.sleep(0.00015)
GPIO.output(trigger,GPIO.LOW)
while not GPIO.input(echo):
pass
t1 = time.time()
while GPIO.input(echo):
pass
t2 = time.time()
return (t2-t1)*340/2while True:
print(‘Distance1:%0.2f m’%checkdist(3,2))
print(‘Distance2:%0.2f m’%checkdist(17,27))
print(‘Distance3:%0.2f m’%checkdist(24,23))time.sleep(0.1)
pitch1=round(float(‘%0.2f’%checkdist(3,2))*100)
sender.send_message(‘/play_this1’,pitch1)pitch2=round(float(‘%0.2f’%checkdist(17,27))*100)
sender.send_message(‘/play_this2’,pitch2)pitch3=round(float(‘%0.2f’%checkdist(24,23))*100)
sender.send_message(‘/play_this3’,pitch3)
Interesting.
What happens if you add
puts "p3: #{p3}, n3: #{n3}"
prior to the line:
if p3<=11 then
What do you see in the log?
Have you very recently installed python-osc? There is a bug in the latest release version. You need to install with
sudo pip3 install python-osc==1.6.4
Version 1.6.5 has the bug which prevents values of 1 or 0 being sent as data in an OSC message.
I think it may affect sending some floats too.
The author is aware and hopes to release 1.6.6 soon
If you have version 1.6.5 installed just uninstall using sudo pip3 uninstall python-osc and then reinstall 1.6.4
Also looking at your code I’m not sure if three syncs one after the other will work. It will wait for the n1 sync then for the n2 sync then for the n3 sync. Do you not want a separate live loop for each one, OR use a wild card and work out which message was received, as I have done using my parse_sync_address function as featured in code
Just received notification that python-osc 1.6.6 has been released, so
sudo pip3 install python-osc
should be OK to use again.
As you can see, we’re working on a DIY theremin project but we met some problem, we have an video to describe our problem…Do you have WeChat (or other IM apps) number so that we can send it to u? <3
Hi Micki
Not sure if you only want notes a tone apart, but a more sliding sound (like a theremin) is obtained with the following code. Also, treat each input separately in its own live loop.
I simulated your inputs using three sldiers on TouchOSC, hence the slightly different OSC addresses, but try removing the /test from three addresses and see if this code works with your system
# Sonic Pi init file
# Code in here will be evaluated on launch.
live_loop:listen1 do
use_real_time
b=sync "/osc/test/play_this1"
p1=b[0]
'-----------------------'
use_synth :beep
play 60+7*p1,attack: 0.05,release: 0.15,amp: 1.5
sleep 0.1
end
live_loop:listen2 do
use_real_time
b=sync "/osc/test/play_this2"
p2=b[0]
'-----------------------'
use_synth :chipbass
play 60+7*p2,attack: 0.05,release: 0.2
sleep 0.1
end
live_loop:listen3 do
use_real_time
b=sync "/osc/test/play_this3"
p3=b[0]
'-----------------------'
use_synth :piano
play 60+7*p3,attack: 0.05,hard: 0.3,vel: 0.12,amp: 1.5
sleep 0.1
end
Also, do you need to put this in the init.rb file rather than run it in a normal buffer?
we used to set three loops, but the sound overlaps,that’s annoying
the contents printed on python is more easier to stop refreshing,too. we couldn’t find the reason
OK. Here is another version nearer to your original which works with TouchOSC input.
Try it on your system, altering the OSC addresses by removing /test
ie
n=sync "/osc/test/play_this*"
becomes
n=sync "/osc/play_this*"
and
res = parse_sync_address "/osc/test/play_this*"
becomes
res = parse_sync_address "/osc/play_this*"
# Sonic Pi init file
# Code in here will be evaluated on launch.
define:parse_sync_address do |address| #gets info on wild cards used
v= get_event(address).to_s.split(",")[6]
if v != nil
return v[3..-2].split("/")
else
return ["error"]
end
end
live_loop:listen do
use_real_time
n=sync "/osc/test/play_this*" #remove the /test for your system
nv=n[0].to_i
res = parse_sync_address "/osc/test/play_this*" #remove the /test for your system
p=res[2][9..-1].to_i
puts p,nv
case p
when 1
use_synth :beep
when 2
use_synth :chipbass
when 3
use_synth :piano
end
if nv<=11 then
play :C4
elsif nv<21 then
play :D4
elsif nv<31 then
play :E4
elsif nv<41 then
play :F4
elsif nv<51 then
play :G4
end
sleep(0.1)
end
I can’t really comment on the python code without access to suitable hardware. I have one ultrasound sensor, but unfortunately I think it is damaged. However I think you said that osc messages were being sent OK.
ACTUALLY I FORGOT TO SAY YOU WILL HAVE TO CHANGE THE LINE WITH THE ERROR TO
p=res[1][9..-1].to_i
when you alter the OSC address line and remove the /test as you want to get data from the 2nd element not the third, and they number from 0.
i set some rhymes using 1.times do in each “in_thread” replace the former pitches.
so every 0.1s it will play the rhyme…it’s bad.
i am now wondering about how to play audio in particular range of distance,and stop the audio when the distance is out of a specific number…
does it have functions such as ‘stop all the audio’?
I use two techniques to switch live_loop audio on and off. The first stops the live loop and restarts it when required. The second leaves the live_loop running but controls its volume using an fx :level wrapper.
In the first example you could use osc messages to call doloop to start and to set :go,0 to stop.
In the second example you could use osc messages to adjust the value of :vol using set :vol,0 or set :vol,1
use_bpm 120
#technique 1 use stop to stop a live loop
#the function call will restart it next time it is called
define :doLoop do
use_synth :tb303
set :go,1
live_loop :doodle do
n=scale(:c3,:minor_pentatonic,num_octaves: 2).choose
play n, cutoff: rrand(50,110),release: 0.1 if spread(5,8).tick
sleep 0.2
stop if get(:go)==0
end
end
#illustrate starting and stopping the loop 4 times
4.times do
doLoop
sleep 4
set :go,0
sleep rrand_i(1,4)
end
#technique 2
# have a continously running live loop
#and embed it within fx :level
#control the level to switch the loop audio off and on
with_fx :level,amp: 1 do |v| #could start with amp: 0 if you want the loop to start silently
in_thread do
loop do
control v,amp: get(:vol),amp_slide: 0.1
sleep 0.1
end
end
use_synth :tb303
live_loop :doodle2 do
n=scale(:c4,:minor_pentatonic,num_octaves: 2).tick
play n, cutoff: rrand(50,110),release: 0.1 if spread(5,8).look
sleep 0.2
end
end
#illustrate controlling the volumn on and off 4 times
4.times do
set :vol,1
sleep 4
set :vol,0
sleep 4
end