I dont know the answer either. but a wild guess says put the osc values into
a set: statement, in one loop, and in the loop you want to control use a get
statement to change the value… roughly like:
(syntax may be wrong, but the idea’s sound)
use_bpm 60
live_loop :get_value_from_osc do
osc_value = incomingoscsignal / 2
set :rate, osc_value
sleep 0.01
end
live_loop :rate_changer do
get rate, :rate
sample :ambi_choir, rate: rate, amp: 2
sleep 1
end
here is a lengthy example, which might help and provide some ideas how to cope with incoming messages from different controllers or switches. The live_loop:simulate_a_rotary_controller does what it says: Acctually Sonic Pi sends OSC messages to itself in this example:
use_osc "127.0.0.1", 9000
use_bpm 120
live_loop :simulate_a_rotary_controller do
osc_send "127.0.0.1", 4559, "/rotary/controller/0", (line 0, 1, inclusive: true, steps: 20).reflect.tick
sleep 0.25
end
# A very useful function provided by Robin Newman
define :parse_osc do | path |
v = get_event(path).to_s.split(",")[6]
if v != nil
return v[3..-2].split("/")
else
return "Could not decipher osc path..."
end
end
live_loop :osc_device_watcher do
use_real_time
m = "/osc/**" # everything which comes in as osc ...
data = sync m
seg = parse_osc m
puts "Seg contains these elements: #{seg}"
puts "With 'seg' you can find out, which controller was used ..."
puts "... and build contitional statements like the following ..."
if seg[3] == "0" # if the controller 0 is being turned, change the volume from 'the_sample'
puts "Simulated rotary controller sends: #{data[0]}"
# now store what's coming in into a variable
set :vol_rotary_0, data[0]
# and set the desired element via 'control' to this value during runtime
control get(:the_sample), amp: get(:vol_rotary_0)
end
end
live_loop :amen_controlled_by_osc do
#stop
s = sample :loop_amen, beat_stretch: 4, amp: get(:vol_rotary_0)
set :the_sample, s
sleep 4
end
Yes, I thought so. Otherwise you can do things like (untested code sketch):
# map 0 - 1 to 0 - 500;
# in case of negative values e. g. from -500 - 500 it'll
# be a bit more complicated but basically you will map
# -500 - 0 to 0 - 0.5 and 1 - 500 to 0.51 - 1.0 or some similar way
set(:vol), 1 / 500.0 * data[0]
@robin.newman Is it possible to describe you example even more because I’m trying to get values from sensors in with OSC and manipulate my effects or panning.
# A very useful function provided by Robin Newman
define :parse_osc do | path |
v = get_event(path).to_s.split(",")[6]
if v != nil
return v[3…-2].split("/")
else
return “Could not decipher osc path…”
end
end
I don’t get this at all. Does this look for any incoming OSC command?
I want to achieve something like
set pan
set fx
set sample2
etc…
Or do I need to set certain values in the live loops? Or I’m to tired an should just called it a day
I decided to develop a program to illustrate what you want to do. Working well. Just doing final testing then I publish the details.
EDIT
now published see here
For some reason suddenly OSC stopped working. I did work a few weeks ago though.
live_loop :foo do
use_real_time
a, b, c = sync "/osc/trigger/prophet"
synth :prophet, note: a, cutoff: b, sustain: c
end
and code from esp8266
`#include <HMC5883L.h>
//#include <Adafruit_HMC5883_U.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h> // Include the Wi-Fi library
#else
#include <WiFi.h>
#endif
#include <WiFiUdp.h> // UDP library
#include <OSCMessage.h> // OSC library
#include <Wire.h>
HMC5883L compass;
const char* ssid = "*"; // The SSID (name) of the Wi-Fi network you want to connect to
const char* password = "*"; // The password of the Wi-Fi network
WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP
//const IPAddress outIp(192,168,0,234); // remote IP of your computer
//const IPAddress outIp(172,18,96,53); // remote IP of your computer @kask
const IPAddress outIp(192,168,0,190); // remote IP of your computer @kask
const unsigned int outPort = 4559; // remote port to receive OSC
const unsigned int localPort = 8888; // local port to listen for OSC packets (actually not used for sending)
void setup() {
Serial.begin(115200); // Start the Serial communication to send messages to the computer
delay(10);
Serial.println('\n');
WiFi.begin(ssid, password); // Connect to the network
Serial.print("Connecting to ");
Serial.print(ssid); Serial.println(" ...");
int i = 0;
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
delay(1000);
Serial.print(++i); Serial.print(' ');
}
Serial.println('\n');
Serial.println("Connection established!");
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer
Serial.println("Starting UDP");
Udp.begin(localPort);
Serial.print("Local port: ");
#ifdef ESP32
Serial.println(localPort);
#else
Serial.println(Udp.localPort());
#endif
// Initialize HMC5883L
Serial.println("Initialize HMC5883L");
while (!compass.begin())
{
Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
delay(500);
}
compass.setRange(HMC5883L_RANGE_1_3GA);
compass.setMeasurementMode(HMC5883L_CONTINOUS);
compass.setDataRate(HMC5883L_DATARATE_15HZ);
compass.setSamples(HMC5883L_SAMPLES_1);
checkSettings();
}
void checkSettings()
{
Serial.print("Selected range: ");
switch (compass.getRange())
{
case HMC5883L_RANGE_0_88GA: Serial.println("0.88 Ga"); break;
case HMC5883L_RANGE_1_3GA: Serial.println("1.3 Ga"); break;
case HMC5883L_RANGE_1_9GA: Serial.println("1.9 Ga"); break;
case HMC5883L_RANGE_2_5GA: Serial.println("2.5 Ga"); break;
case HMC5883L_RANGE_4GA: Serial.println("4 Ga"); break;
case HMC5883L_RANGE_4_7GA: Serial.println("4.7 Ga"); break;
case HMC5883L_RANGE_5_6GA: Serial.println("5.6 Ga"); break;
case HMC5883L_RANGE_8_1GA: Serial.println("8.1 Ga"); break;
default: Serial.println("Bad range!");
}
Serial.print("Selected Measurement Mode: ");
switch (compass.getMeasurementMode())
{
case HMC5883L_IDLE: Serial.println("Idle mode"); break;
case HMC5883L_SINGLE: Serial.println("Single-Measurement"); break;
case HMC5883L_CONTINOUS: Serial.println("Continuous-Measurement"); break;
default: Serial.println("Bad mode!");
}
Serial.print("Selected Data Rate: ");
switch (compass.getDataRate())
{
case HMC5883L_DATARATE_0_75_HZ: Serial.println("0.75 Hz"); break;
case HMC5883L_DATARATE_1_5HZ: Serial.println("1.5 Hz"); break;
case HMC5883L_DATARATE_3HZ: Serial.println("3 Hz"); break;
case HMC5883L_DATARATE_7_5HZ: Serial.println("7.5 Hz"); break;
case HMC5883L_DATARATE_15HZ: Serial.println("15 Hz"); break;
case HMC5883L_DATARATE_30HZ: Serial.println("30 Hz"); break;
case HMC5883L_DATARATE_75HZ: Serial.println("75 Hz"); break;
default: Serial.println("Bad data rate!");
}
Serial.print("Selected number of samples: ");
switch (compass.getSamples())
{
case HMC5883L_SAMPLES_1: Serial.println("1"); break;
case HMC5883L_SAMPLES_2: Serial.println("2"); break;
case HMC5883L_SAMPLES_4: Serial.println("4"); break;
case HMC5883L_SAMPLES_8: Serial.println("8"); break;
default: Serial.println("Bad number of samples!");
}
}
void loop() {
Vector raw = compass.readRaw();
Vector norm = compass.readNormalize();
int Xmap = norm.XAxis;
float XmapDecimal = (map(norm.XAxis, -500, 600, 0, 1000));
float XmapDecimalCorrect = XmapDecimal / 1000;
//Serial.print(" Xraw = ");
//Serial.print(raw.XAxis);
//Serial.print(" XRaw is now =");
// Serial.print(XmapRound);
//Serial.print(" Yraw = ");
//Serial.print(raw.YAxis);
//Serial.print(" Zraw = ");
//Serial.print(raw.ZAxis);
Serial.print(" Xnorm = ");
Serial.println(XmapDecimalCorrect);
//Serial.print(norm.XAxis);
//Serial.print(" Ynorm = ");
//Serial.print(norm.YAxis);
//Serial.print(" ZNorm = ");
//Serial.print(norm.ZAxis);
//Serial.println();
OSCMessage msg("/trigger/prophet");
//msg.add(XmapDecimalCorrect);
msg.add(norm.XAxis);
// OSCMessage msg2("/test/amen");
// msg.add(raw.YAxis);
//msg.add(raw.ZAxis); Udp.beginPacket(outIp, outPort);
msg.send(Udp);
Udp.endPacket();
msg.empty();
delay(1000);
}`
Occasionally I get the OSC system not working. It is sometimes after my computer has gone to sleep with SP running. It fails to work when you wake it up again. A restart of SP solves this.
I assume you have receive remote OSC messages ticked in the IO prefs.
Also, you havn’t switched from Sonic PI 3.1 to 3.2dev? If so the port moves to 4560 not 4559 and you need to use /osc*/trigger/prophet to receive the osc cue, inserting a * where shown.
Are OSC messages working locally? Try the other example I posted for you
Have a look at the log files, particularly erlang.log You could build 3.2dev but you need to be aware of the changes I have pointed out (using sync “/osc*/…” instead of sync “/osc/…” and using port 4560 instead of 4559.
Ok very stupid and neglectant of me! I commented something out of my Arduino code and with the screen resized I didn’t notice it… I’m looking at your new example!! Thanks!!!