Skip to content
This repository has been archived by the owner on Nov 23, 2023. It is now read-only.

Commit

Permalink
Merge branch 'vs-dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
victor-shepardson committed May 18, 2022
2 parents 47581b1 + 24a6f3c commit 06821ca
Show file tree
Hide file tree
Showing 20 changed files with 4,467 additions and 307 deletions.
8 changes: 5 additions & 3 deletions examples/bela/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ Unless otherwise stated, these examples assume a set up of a Bela device connect
## C++
- `cpp-osc-basic`: basic OSC communication with Bela
- `cpp-osc-arrays`: sending and receiving arrays
- `cpp-osc-gui-sliders`: Bela GUI with sliders controlled by `iipyper`
- `cpp-osc-json`: sending and receiving JSON
- `cpp-osc-resonator`: controlling a resonant filter
- `cpp-osc-resonators`: controlling a bank of resonant filters
- `cpp-osc-gui-sliders`: Bela GUI with sliders controlled by `iipyper`
- `cpp-osc-notochord-trill`: using Trill sensors to control `iipyper` `notochord` parameters

## Pure Data
- `osc-receive`: receive OSC from `iipyper`
- `osc-send`: send OSC to `iipyper`
- `pd-osc-receive`: receive OSC from `iipyper`
- `pd-osc-send`: send OSC to `iipyper`
- `pd-osc-json`: send and receive JSON over OSC https://github.com/residuum/PuRestJson

# Todo

Expand Down
19 changes: 15 additions & 4 deletions examples/iipyper/iipyper-tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,20 @@ def _(msg):
def test(address, x, y): # route is /test
print(address, x, y)
# if a value (besides None) is returned,
# it will be sent back as an OSC message to the sender
# with the route given as the first element:
# it will be sent back as an OSC message to the sender.
# you don't have to specify the IP or port of the client this way.
# the first element should be the OSC address:
return '/test', x-y, x+y

# the above works with SuperCollider, but not with Max
# the reply port Max sends doesn't seem to work conveniently.
# (you can't make a new udpsend object with that port, it's taken)
# but you can specify your own return port like this:
@osc.args(return_port=5432)
def test2(address, x, y): # route is /test2
print(address, x, y)
return '/test', x-y, x+y # will send on port 5432

# named arguments as key, value pairs in OSC
# e.g. an OSC message ["/keyword_example", "arg2", 3]
# would print "/keyword_example 0 3 99"
Expand All @@ -60,8 +70,9 @@ def keyword_example(address, arg1=0, arg2=1, arg3=99):
print(address, arg1, arg2, arg3)
# no return value: does not send OSC back

# can also give the route explicitly to the decorator,
# supporting wildcards
# you can also give the OSC address explicitly to the decorator,
# instead of using the function name.
# this supporting wildcards and other aspects of OSC addresses:
@osc.args('/math/*')
def _(address, a, b):
print(address, a, b)
Expand Down
50 changes: 27 additions & 23 deletions examples/notochord/autopitch.scd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// in this example the Linnstrument displays an interface to perform pitches
// by their likelihood under the Notochord model instead of by MIDI number
// by their likelihood under the NotePredictor model instead of by MIDI number

// the grid in the upper left gives control of pitches from
// the single most likely (cyan) to least likely (pink).
Expand All @@ -9,6 +9,9 @@

// model predictions are conditioned on performed timing and velocity.

// TODO: this example is based an older, monophonic version of notochord without noteoffs
// it is hacked to work similarly wit Notochord v3, but could use an update

(
~use_linn = true; // use linnstrument
~gui = false; // use keyboard GUI
Expand All @@ -33,7 +36,7 @@ Server.default.options.outDevice_("Built-in Output");
{y==2}{x*4+16}
{y==3}{x*8+40}
{y==4}{127-x};
idx.postln;
// idx.postln;
~midi_handle.(amp*127, idx);
}{
case
Expand Down Expand Up @@ -85,13 +88,13 @@ SynthDef(\pluck, {

// measure round-trip latency
(
OSCdef(\return, {
OSCdef(\test, {
arg msg, time, addr, recvPort;
(Process.elapsedTime - t).postln;
}, '/prediction', nil);
t = Process.elapsedTime;
b.sendMsg("/predictor/predict",
\pitch, 60+12.rand, \time, 0, \vel, 0, \fix_time, 0, \fix_vel, 0);
b.sendMsg("/notochord/predict",
\inst, 257, \pitch, 60+12.rand, \time, 0, \vel, 0, \fix_time, 0, \fix_vel, 0);
)

// set the delay for more precise timing
Expand All @@ -104,17 +107,16 @@ b.sendMsg("/predictor/predict",
// model chooses pitches
(
~gate = 1;
~instrument = 57;

~model_reset = {
~last_pitch = nil;
~last_pitch = 60;
~last_dt = nil;
~last_vel = nil;
t = Process.elapsedTime;
b.sendMsg("/predictor/reset");
b.sendMsg("/notochord/reset");
y!?{y.free};
y = nil;
b.sendMsg("/predictor/predict", \pitch, 128, \time, 0, \vel, 0);

};

~model_reset.();
Expand All @@ -128,7 +130,7 @@ MIDIdef.program(\switch, {
{3}{
~gate = 0;
SystemClock.clear;
b.sendMsg("/predictor/reset");
b.sendMsg("/notochord/reset");
y.release;
SystemClock.clear;
};
Expand All @@ -151,13 +153,17 @@ MIDIdef.program(\switch, {
// get a new prediction in light of last note,
// fixing dt and vel to performed values so just pitch is predicted
pitch.notNil.if{
b.sendMsg("/predictor/predict",
\pitch, ~last_pitch, \time, ~last_dt, \vel, ~last_vel,
\index_pitch, pitch, \fix_time, dt, \fix_vel, vel);
b.sendMsg("/notochord/feed",
\inst, ~instrument, \pitch, ~last_pitch, \time, ~delay, \vel, ~last_vel);
b.sendMsg("/notochord/predict",
\inst, ~instrument, \pitch, ~last_pitch, \time, ~last_dt, \vel, 0,
\index_pitch, pitch, \fix_time, dt, \fix_vel, vel, \fix_instrument, ~instrument);
}{
b.sendMsg("/predictor/predict",
\pitch, ~last_pitch, \time, ~last_dt, \vel, ~last_vel,
\fix_time, dt, \fix_vel, vel);
b.sendMsg("/notochord/feed",
\inst, ~instrument, \pitch, ~last_pitch, \time, ~delay, \vel, ~last_vel);
b.sendMsg("/notochord/predict",
\inst, ~instrument, \pitch, ~last_pitch, \time, ~last_dt, \vel, 0,
\fix_time, dt, \fix_vel, vel, \fix_instrument, ~instrument);
};

~last_dt = dt;
Expand All @@ -174,9 +180,10 @@ MIDIdef.program(\switch, {
// OSC return from python
OSCdef(\return, {
arg msg, time, addr, recvPort;
var pitch = msg[1]; // MIDI number of predicted note
var dt = msg[2]; // time to predicted note
var vel = msg[3]; // velocity 0-127
var inst = msg[1]; // MIDI number of predicted note
var pitch = msg[2]; // MIDI number of predicted note
var dt = msg[3]; // time to predicted note
var vel = msg[4]; // velocity 0-127

// store the pitch and immediately set (unless there is no synth,
// indicating this is the first note)
Expand All @@ -192,7 +199,4 @@ OSCdef(\return, {

~model_reset.()
// send a note manually if you don't have a midi controller
MIDIdef.all[\input].func.(64, 16) //velocity, "pitch"

// load another model
// b.sendMsg("/predictor/load", "/path/to/checkpoint");
MIDIdef.all[\input].func.(64, 16) //velocity, "pitch"
Loading

0 comments on commit 06821ca

Please sign in to comment.