OSC to SuperCollider ==================== *Example directory* (scamp): `examples/Tutorial/24_osc_to_supercollider `__ *Download:* :download:`24_osc_to_supercollider.zip ` Playing back notes by sending OSC messages to the SuperCollider, which receives them and spawns Synths in response. Start SuperCollider and run the code blocks in `receive_from_supercollider.scd`, then run `osc_to_supercollider.py`. Note that the easy way to receive note events from SCAMP in SuperCollider specifically is with the ScampUtils quark, as demonstrated by `receive_from_supercollider_scamputils.scd`. *Topics:* :doc:`Playback › Playback implementations ` .. raw:: html
score
.. raw:: html
.. code-block:: python from scamp import * import random random.seed(42) s = Session() # on the other end, an OSC receiver is setup to play notes that take vibrato and OSC messages as well as the usual vib = s.new_osc_part("vibrato", 57120) s.start_transcribing() # any property entries starting or ending with "param" will be treated as extra playback parameters while s.beat < 20: note_length = random.uniform(0.3, 3) # glissando between three random values pitch_env = [random.randint(60, 82) for _ in range(3)] volume_env = random.choice([ # percussive envelope Envelope.ar(0.1, note_length - 0.1), # fp crescendo envelope Envelope([1, 0.2, 1], [0.1, note_length - 0.1], curve_shapes=[-2, 3]) ]) vib_width_env = [random.uniform(0, 5) for _ in range(2)] vib_freq_env = [random.uniform(3, 13) for _ in range(2)] vib.play_note( pitch_env, volume_env, note_length, {"param_vibWidth": vib_width_env, "param_vibFreq": vib_freq_env}, blocking=False ) wait(random.uniform(0.5, 3)) wait_for_children_to_finish() performance = s.stop_transcribing() engraving_settings.max_voices_per_staff = 1 performance.to_score(max_divisor=6, simplicity_preference=3).show() .. code-block:: supercollider :caption: receive_from_supercollider.scd // -------------------------------------------------------------------------------------------------- // Corresponding SuperCollider Code for OSC-to-SuperCollider SCAMP example. Run this before the Python // script by booting the server and then running the code blocks below in order. // -------------------------------------------------------------------------------------------------- // If it's not working, make sure the port printed here matches the port that the Python file is sending to NetAddr.langPort.postln; ( // ----------------------------- 1) Define vib synth ---------------------------------- SynthDef(\vibSynth, { |out=0, freq=440, gain=0.1, vibFreq=20, vibWidth=0.5, gate=1| var envelope = EnvGen.ar(Env.asr(releaseTime:0.5), gate, doneAction: 2); var vibHalfSteps = SinOsc.ar(vibFreq) * vibWidth; var vibFreqMul = 2.pow(vibHalfSteps / 12); var vibSine = SinOsc.ar(freq * vibFreqMul) * gain; Out.ar(out, (envelope * vibSine / 5) ! 2); }, [\ir, 0.1, 0.1, 0.1, 0.1, \kr]).add; ) ( // ---------------------------- 2) Set up OSC Receivers ------------------------------- // This dictionary maps the note-id's sent by SCAMP to their associated Synths ~notesPlaying = Dictionary(); // START NOTE OSCFunc({ arg msg, time, addr, recvPort; var id = msg[1], pitch = msg[2], volume = msg[3]; // Start a new Synth and place it in the ~notesPlaying dictionary under its associated id ~notesPlaying.put(id, Synth(\vibSynth, [\freq, pitch.midicps, \gain, (-40 * (1-volume)).dbamp] )); }, '/vibrato/start_note'); // END NOTE OSCFunc({ arg msg, time, addr, recvPort; var id = msg[1]; ~notesPlaying[id].set(\gate, 0); }, '/vibrato/end_note'); // CHANGE PITCH OSCFunc({ arg msg, time, addr, recvPort; var id = msg[1], pitch = msg[2]; ~notesPlaying[id].set(\freq, pitch.midicps); }, '/vibrato/change_pitch'); // CHANGE VOLUME OSCFunc({ arg msg, time, addr, recvPort; var id = msg[1], volume = msg[2]; ~notesPlaying[id].set(\gain, (-40 * (1-volume)).dbamp); }, '/vibrato/change_volume'); // CHANGE VIBRATO FREQUENCY OSCFunc({ arg msg, time, addr, recvPort; var id = msg[1], freq = msg[2]; ~notesPlaying[id].set(\vibFreq, freq); }, '/vibrato/change_parameter/vibFreq'); // CHANGE VIBRATO WIDTH OSCFunc({ arg msg, time, addr, recvPort; var id = msg[1], width = msg[2]; ~notesPlaying[id].set(\vibWidth, width); }, '/vibrato/change_parameter/vibWidth'); ) .. code-block:: supercollider :caption: receive_from_supercollider_scamputils.scd // -------------------------------------------------------------------------------------------------- // Corresponding SuperCollider Code for OSC-to-SuperCollider SCAMP example. Run this before the Python // script by booting the server and then running the code blocks below in order. // -------------------------------------------------------------------------------------------------- // If it's not working, make sure the port printed here matches the port that the Python file is sending to NetAddr.langPort.postln; ( // ----------------------------- 1) Define vib synth ---------------------------------- ScampUtils.instrumentFromSynthDef( SynthDef(\vibSynth, { |out=0, freq=440, volume=0.1, vibFreq=20, vibWidth=0.5, gate=1| var envelope = EnvGen.ar(Env.asr(releaseTime:0.5), gate, doneAction: 2); var vibHalfSteps = SinOsc.ar(vibFreq) * vibWidth; var vibFreqMul = 2.pow(vibHalfSteps / 12); var vibSine = SinOsc.ar(freq * vibFreqMul) * volume; Out.ar(out, (envelope * vibSine / 5) ! 2); }, [\ir, 0.1, 0.1, 0.1, 0.1, \kr]); ) )