How to read a note/frequency from an array while a Ugen is playing?

I’m trying to build out a simple idea, where given an array of chords, e.g.

~chords = [
    [1,3,5],
    [2,4,6],
    [3,5,7],
    [4,6,8],
    [5,7,9],
    [2,6,8],
    //...
];

… I would create 3 synths who choose their frequency to play depending on MouseX. So in the above example, if those are all the chords that are there, then the screen would be separated into 6 sections, and when the mouse is on the far left, you hear a [1,3,5] chord (the first chord in the array) and when it’s on the right you hear [2,6,8] (the last chord).

But as I started writing it, I got stuck on how to use the current value of MouseX to pull values out of an array. Is there some array/buffer-reading UGen I’m not thinking of that might be useful here?

As a followup experiment, I’d like to be able to tween between the frequencies rather than have a hard transition once your mouse crosses into another region, which I’m guessing would just be some evolution of the first solution, but just trying to keep that in mind.

MouseX works on the server, and I would say array manipulations are more flexible on the client. So what I would do is to send MouseX data to the client and process it from there.
In general, you can send values from server to client with SendReply/OSCFunc (or OSCdef):

// send MouseX data to an OSC path "/mouseX"
m = {|pollRate=10| SendReply.kr(Impulse.kr(pollRate), "/mouseX", MouseX.kr)}.play

// read data from OSC path "/mouseX"
OSCdef(\mouse, {|msg|
    var pos = msg[3]; // mouseX data, from 0 to 1
    var chord = ~chords.blendAt(pos * ~chords.size);
    // now you can use that "interpolated" chord to drive your synths

    // simple example, assuming you have a list of synths called ~synths
    chord.postln.do{|c,n| ~synths[n].set(\freq, c.midicps, \amp, 1/chord.size)};
    // silence unused synths, in case you have 8 synths ready but only 3 notes
    ~synths[chord.size..].do{|sy| sy.set(\amp,0);};
}, "/mouseX");

// example synths
SynthDef(\sin){|freq=440,amp=1,out=0| 
    Out.ar(out, 
        SinOsc.ar(freq)*amp
    )
}.add;

~synths = 8.collect{ Synth(\sin,[amp:0]) };
1 Like

Thank you so much, that did the trick and I learned a ton :slight_smile:

1 Like