--- /dev/null
+// Ableton push handler
+// by Eugene Zuelum
+//
+// see https://github.com/Ableton/push-interface for info about ABI:
+// https://github.com/Ableton/push-interface/blob/master/doc/AbletonPush2MIDIDisplayInterface.asc
+
+(
+~bcrFactory = {
+ var controler = Environment[
+ \version -> "33.7.3.6",
+
+ \channel -> 0,
+ ];
+
+ controler.know = true;
+
+ MIDIdef.cc(\bcr2000defaultTurn, { |...args|
+ controler.turn(*args);
+ }, (1..110), controler.channel);
+
+ "Ԃиџуту готов к использованию 😊".postln;
+
+ controler;
+};
+)
+
+//============================================================================= Testing
+
+/* Test incoming MIDI messages from push
+(
+MIDIdef.cc(\testcc, {|...args|
+(["cc"] ++ args).postln;
+});
+MIDIdef.noteOn(\testnoteon, {|...args|
+(["note on"] ++ args).postln;
+});
+MIDIdef.noteOff(\testnoteoff, {|...args|
+(["note off"] ++ args).postln;
+});
+MIDIdef.touch(\testtouch, {|...args|
+(["touch"] ++ args).postln;
+});
+MIDIdef.polytouch(\testpolytouch, {|...args|
+(["polytouch"] ++ args).postln;
+});
+MIDIdef.bend(\testbend, {|...args|
+(["bend"] ++ args).postln;
+});
+MIDIdef.sysex(\testsysex, {|...args|
+(["sysex"] ++ args).postln;
+});
+)
+*/
--- /dev/null
+~beri = ~bcrFactory.value;
+
+(
+~melmaker = Environment[
+ \current
+ \makemelody ->
+ {
+
+ }
+];
+~melmaker.know = true;
+
+)
+
+(
+SynthDef(\sinetone,
+ { arg out = 0, freq = 440, sustain = 0.05, gate=1, amp=1;
+ var env, sig;
+ sig = Pulse.ar(freq, 0.5, amp);
+ sig = LPF.ar(sig, 4000);
+ env = EnvGen.kr(Env.asr(0.01, 0.8, 0.05), gate, doneAction: Done.freeSelf);
+ sig = sig * env;
+ Out.ar(out, sig!2)
+}).add;
+)
+
+});
+
+}, {});
+
+(
+~curFreq = 110;
+~steps = (0..15);
+~intervalWeights = [1]++(0!15);
+~freqHigh = 1000;
+~freqLow = 200;
+
+~durs = (1..8);
+~durWeights = (0!7) ++ [1];
+
+~legatos = (1..8)/8;
+~legatoWeights = (0!7) ++ [1];
+
+~decibels = (0..7) * -2;
+~decibelWeights = [1] ++ (0!7);
+
+~chorus = (0..15);
+~chorusWeights = [1]++(0!15);
+
+/*~chooseWeighted = {|values, weights|
+ values.
+};*/
+)
+
+(
+~beri.turn = {|zi, val, num|
+ num.postln;
+ if (num <= 16, {
+ ~intervalWeights[num-1] = val;
+ ("interval "++~steps[num-1]++" weight changed to "++val).postln;
+ });
+ if ((num >= 17) && (num <= 32), {
+ ~chorusWeights[num-17] = val;
+ ("chorus "++~chorus[num-17]++" weight changed to "++val).postln;
+ });
+ if ((num >= 81) && (num <= 88), {
+ ~durWeights[num-81] = val;
+ ("duration "++~durs[num-81]++" weight changed to "++val).postln;
+ });
+ if ((num >= 89) && (num <= 96), {
+ ~legatoWeights[num-89] = val;
+ ("legato "++~legatos[num-89]++" weight changed to "++val).postln;
+ });
+ if ((num >= 97) && (num <= 104), {
+ ~decibelWeights[num-97] = val;
+ ("decibel "++~decibels[num-97]++" weight changed to "++val).postln;
+ });
+ ~pnotes = Pfunc({
+ var direction, step, upWeight, downWeight, chorus;
+ upWeight = 1;
+ downWeight = 1;
+ if (~curFreq > ~freqHigh, {downWeight = ~curFreq/~freqHigh;});
+ if (~curFreq < ~freqLow, {upWeight = ~freqLow/~curFreq;});
+ //[downWeight, upWeight].postln;
+ direction = [-1, 1].wchoose([downWeight**3, upWeight**3].normalizeSum);
+ //direction.postln;
+ step = ~steps.wchoose(~intervalWeights.normalizeSum);
+ ~curFreq = ~curFreq * (direction*step).midiratio;
+ chorus = ~chorus.wchoose(~chorusWeights.normalizeSum);
+ //("new chorus: "++chorus).postln;
+ [~curFreq, ~curFreq*chorus.midiratio];
+ });
+
+ ~pdurs = Pfunc({
+ var dur;
+ dur = ~durs.wchoose(~durWeights.normalizeSum);
+ //("new duration: "++dur).postln;
+ dur;
+ });
+
+ ~plegatos = Pfunc({
+ var legato;
+ legato = ~legatos.wchoose(~legatoWeights.normalizeSum);
+ //("new legato: "++legato).postln;
+ legato;
+ });
+
+ ~pdecibel = Pfunc({
+ var decibel;
+ decibel = ~decibels.wchoose(~decibelWeights.normalizeSum);
+ //("new decibel: "++decibel).postln;
+ decibel;
+ });
+
+ ~melody = ~se.makeSynthBind <> Pbind(
+ \instrument, \sinetone,
+ \freq, ~pnotes,
+ \dur, ~pdurs,
+ \legato, ~plegatos,
+ \db, -10+~pdecibel,
+ );
+ Pdef(\melody, ~melody).quant_(1).play;
+};
+)
+
+Pdef(\melody).stop;
+
+~se.shiftPos(0.05);
+~se.playSample
+
+a = ~pnotes.asStream;
+a.next
+
+TempoClock.tempo = 8;