//////////////////////////////////RECEIVING////////////////////////////////////

// please launch the ROSETTE example in the Iannix application first

( //SEND FIRST

s = Server.local.waitForBoot({ //NOTE: your synthDef MUST have an out argument to get Iannix.fadeTime to work

SynthDef(\rosette, {|out=0, t_trig=1, vol=1, attack=0.001, freq=400, rq=0.0001, rq2=0.3, freq2=1000, envDur=1, pan=0, fond=0.2|

var env, synth;

env = EnvGen.kr(Env.perc(attack, envDur, curve: -20), t_trig, levelScale: 1-fond, levelBias: fond );

synth = Pan2.ar(RLPF.ar(BPF.ar(BrownNoise.ar(30 * vol*LFNoise2.kr(0.2).range(0.5, 1.3)), freq, rq), Lag.kr(freq2, 0.1), rq2), pan) * env;

Out.ar(out, synth.softclip);

}).add;

});

~inx = Iannix.new; //by default: receive osc from localhost, port 1234 (Iannix port app)

)

(

~inx.createSynthGroup; //connect your synths to this group (~inx.synthGroup) to take advantage of Iannix.app transports (play/stop-> synthGroup.run(true/false) )

~nbCursors = ~inx.appObjects[\cursors]; //

~nbCursors.do {~inx.cursor(send: false); ~inx.trigger(send: false)}; //just mirroring objects already created in Iannix.app (default beheviour = send: true -> would create a new obj. in Iannix.app)

//global actions for cursors and triggers

/*

must be a function, with one argument (here called args);

this arg will receive (as array ) the messages sent from Iannix.app, for this category of objects

e.g. in the Rosette script, in Iannix.app, triggers are sent this way:

iannix.execute("setMessage current 1, osc://127.0.0.1:57120/trigger trigger_id trigger_xPos trigger_yPos cursor_id");

so the input for the global function, for triggers, will be here an array of four values, respectively trigger_id, trigger_xPos, trigger_yPos, cursor_id .

*/

~inx.globalActions[\triggers] = {|args|

var trigger_id, synth_id;

trigger_id = args[0]; //we only want here the first message, from the input array, i.e trigger_id

synth_id = trigger_id - ~inx.idOffsets[\triggers]; //trigger IDs in Iannix are supposed to start from 2000 (see down there at *****)

~synths[synth_id].set(\t_trig, 1) ;

};

/*

***** ~inx.idOffsets[\triggers]; //determined at any Iannix class instantiation; can be changed if you want - todo: preferences in startup file?

*/

~inx.globalActions[\cursors] = {|args|

var cursor_id, cursor_value_x, cursor_value_y, resonz;

#cursor_id, cursor_value_x, cursor_value_y = args; //messages sent by Iannix.app cursors

resonz = sqrt(cursor_value_x**2 + cursor_value_y**2).linexp(0, 1, 100, 3000);

~synths[cursor_id].set( \freq2, resonz, \pan, (cursor_value_x*2-1)) ;

};

/*

you can also define, eventually afterwards, actions for any separate trigger or cursor object, based on their ID:

~inx.cursors[20].action_({|args| ... do something ... });

*/

)

~inx.objects; //just to see what's in there

~inx.appObjects; //objects info from the Iannix application (still buggy sometimes, if objects are created from sclang)

( // synths

~freqs = Array.exprand(~nbCursors, 40, 5000).sort;

~synth !? { ~inx.synthGroup.freeAll };

~synths = {|i| Synth(\rosette, [\freq, ~freqs[i], \vol, 1 / (i.linexp(0,~nbCursors, 1, 1.5))], ~inx.synthGroup) }!~nbCursors; //~synths created on ~inx.synthGroup node

~inx.fadeTime_(0.5); //for play and stop

//OSC receive

~inx.listen(\triggers); //get the osc messages begenning with "/trigger"

~inx.listen(\cursors); //idem with "/cursor"

)

//~inx.listen(\transport); //already done in Iannix .connect method

//transport

~inx.play;

~inx.stop;

~inx.fastrewind;

~inx.speed_(0.4);

~inx.fadeTime_(in: 1, out: 0.5); //different fade times for in and out

~inx.listen(\triggers, false);

~inx.listen(\cursors, false);

//at the end

~inx.stop;

~inx.removeAll; //remove objects from ~inx.objects;