Chords with osc


This post ends me up to try to send chord via OSC and then play the chord received.

It seems to work but not sure the code is very very good… Note that i meet an issue as the tempo is very hazardous. So kings of code, is you can test this, i will appreciate.

use_bpm 120

live_loop :sendChordsNotesViaOSC do
  ##| stop
  notes = chord :c, :madd11
  # we get a ring
  puts notes
  ##| play_chord notes
  ##| sleep 4
  ##| notes.each do | n |
  ##|   osc "/foo/notes", n
  ##| end
  # we can' send a ring via osc maybe using an array ?
  tab =
  notes.each_with_index do |n, idx|
    tab[idx] = n
  ##| puts tab

  ##| So no this does not work with array
  ##| osc "/foo/notes", tab
  ## so we send a string, each note separated by a space to split this string at the reception
  puts notes_sent = notes.join(" ")
  osc "/foo/notes", notes_sent
  # just send a amp integer value
  osc "/foo/notes/amp", [0.5, 1, 2].tick
  sleep 4

live_loop :player do
  msg = sync "/osc*/foo/notes"
  # we get a string
  puts msg[0]
  # but play_chord wants an array...
  # So how can i rebuilt an array from the string ?
  foo = msg[0].split
  puts foo
  # but we need to convert into an integer
  goo =
  foo.each_with_index do |s, k|
  puts goo
  arrayNotes = [:c, :e, :a, :c5, :d5]
  vol = sync "/osc*/foo/notes/amp"
  synth :dsaw, attack: 0, amp: vol[0], notes: goo
#  synth :dsaw, attack: 0, amp: vol[0], notes: arrayNotes

My reply there should give you at least a clue :wink:
The tricky bit however, is that if you want to send multiple values from a ring or array as a single parameter to osc, (rather than passing the osc function multiple data parameters as I describe in that thread) you need to lean into a trick of plain old Ruby: the splat operator :slight_smile:
So the line would become something like:

osc "/foo/notes", *(chord :a3, :minor)

(Note the *)
There’s plenty of further information around on the splat operator if needed:
See An introduction to Ruby’s *Splat and double **Splat operators for an example :slight_smile:

At the other end, to play back the chord, you could do something like:

  notes = sync "/osc*/foo/notes"
  synth :prophet, note: notes

ah ah maybe i should have ask before but no i will remember
You guess that i ignored this magical splat operator :slight_smile:

So this is a shorty version

# Splat version thanks to Ethan :-)
# A shorty solution 

use_osc "localhost", 4560
use_osc_logging false
use_debug false

use_bpm 120

live_loop :sendChordsNotesViaOSC do
  notes = chord :c, :madd11
  osc "/foo/notes", *notes
  # just send a amp integer value
  osc "/foo/notes/amp", [0.5, 1, 2].tick
  sleep 1

live_loop :player do
  n = sync "/osc*/foo/notes"
  vol = sync "/osc*/foo/notes/amp"
  synth :dsaw, attack: 0, amp: vol[0], notes: n  

EDIT : add use_real_time fix the issue :slight_smile:

But still have the issue : this is not regular…

Can you explain what you mean by not regular? :slight_smile:

the chords are not played at the tempo given by the sleep 1

I hear an occasional silence as the chord sometimes doesn’t play for a beat.
If you add use_real_time to the :sendChordsNotesViaOSC loop, then it seems to me to play the chord every beat as expected. Does that help?

of course it does :slight_smile: Thanks

1 Like