From: Eugene Petkevich Date: Sun, 22 May 2022 15:42:20 +0000 (+0300) Subject: Finish Mix-101 adapter / fix zero array in sampler X-Git-Url: https://git.zuelum.org/?a=commitdiff_plain;h=d88820553b82e3a42e483a41deb2d5b5e92c4ff0;p=scprojects.git Finish Mix-101 adapter / fix zero array in sampler --- diff --git a/extensions/classes/midimix.sc b/extensions/classes/midimix.sc index fc3b3d2..2298c63 100644 --- a/extensions/classes/midimix.sc +++ b/extensions/classes/midimix.sc @@ -1,15 +1,24 @@ MidiMix { - classvar ledValues; + classvar ledValues, ledControls; classvar controlNotes; const caro; - var <>joro, <>viro, <>wipu, <>wire; - var <>sepu, <>sere; - var <>sewo, <>luwo, <>fewo, <>viwo; - var <>sypu, <>syre; + // channel selector + var <>chanrot; + // modes + var <>sampler, <>loop, <>fx, <>vinyl; + // wheel rotation + var <>jogrot, <>scratch; + // buttons + var <>lpfA, <>lpfB, <>but1, <>but1, <>select, <>sync, <>play, <>cue, <>deck, <>rotbut1, <>rotbut2, <>rotbutload, <>jogact; + // knobs + var <>again, <>bgain, <>ahi, <>amid, <>alow, <>bhi, <>bmid, <>blow; + // faders + var <>afade, <>bfade, <>crossfade; + // endless rotators + var <>rot1, <>rot2, <>rotload; *initClass { ledValues = IdentityDictionary[ @@ -21,16 +30,34 @@ MidiMix { false -> 0 ]; - controlNotes = IdentityDictionary[ - 1 -> \da, - 2 -> \ze, - 3 -> \ku, - 4 -> \ta, - 7 -> \be, - 8 -> \bu, - 9 -> \pe, - 11 -> \gu, + ledControls = IdentityDictionary[ + \pflA -> 1, + \pflB -> 2, + \but1 -> 3, + \but2 -> 4, + \play -> 7, + \cue -> 8, + \deck -> 9, + \sampler -> 17, + \loop -> 18, + \fx -> 19, + \vinyl -> 20, + ]; + controlNotes = IdentityDictionary[ + 1 -> \lpfA, + 2 -> \lpfB, + 3 -> \but1, + 4 -> \but2, + 5 -> \select, + 6 -> \sync, + 7 -> \play, + 8 -> \cue, + 9 -> \deck, + 11 -> \rotbut1, + 12 -> \rotbut2, + 13 -> \rotbutload, + 21 -> \jogact, ]; } @@ -50,175 +77,127 @@ MidiMix { // MIDI out channel selector (back of the device) // velocity is the channel - MIDIdef.noteOn(\caro+name, {|...args| + MIDIdef.noteOn(\chanrot++name, {|...args| channel = args[0]; - caro.value(*args); + chanrot.value(*args); }, 14, srcID: idin); // == Jog wheel - // Start rotating - MIDIdef.noteOn(\wipu+name, {|...args| - wipu.value(*args); - }, 21, srcID: idin); - // Stop rotating - MIDIdef.noteOff(\wire+name, {|...args| - wire.value(*args); - }, 21, srcID: idin); // Rotating in sampler/loop/fx mode: -1/1 - MIDIdef.cc(\joro+name, {|...args| - joro.value(args[0]-64, *args); + MIDIdef.cc(\jogrot+name, {|...args| + jogrot.value(args[0]-64, *args); }, 19, srcID: idin); // Rotating in cue/vinyl mode: -1/1 - MIDIdef.cc(\viro+name, {|...args| - viro.value(args[0]-64, *args); + MIDIdef.cc(\scratch+name, {|...args| + scratch.value(args[0]-64, *args); }, 21, srcID: idin); - // == sync/select buttons - // select button pushed - MIDIdef.noteOn(\sepu+name, {|...args| - sepu.value(*args); - }, 5, srcID: idin); - // select button released - MIDIdef.noteOff(\sere+name, {|...args| - sere.value(*args); - }, 5, srcID: idin); - // sync button pushed - MIDIdef.noteOn(\sypu+name, {|...args| - sypu.value(*args); - }, 6, srcID: idin); - // sync button released - MIDIdef.noteOff(\syre+name, {|...args| - syre.value(*args); - }, 6, srcID: idin); + // == modes // sampler mode activated - MIDIdef.noteOn(\sewo+name, {|...args| - sewo.value(*args); + MIDIdef.noteOn(\sampler++name, {|...args| + sampler.value(*args); }, 17, srcID: idin); // loop mode activated - MIDIdef.noteOn(\luwo+name, {|...args| - luwo.value(*args); + MIDIdef.noteOn(\loop++name, {|...args| + loop.value(*args); }, 18, srcID: idin); // fx mode activated - MIDIdef.noteOn(\fewo+name, {|...args| - fewo.value(*args); + MIDIdef.noteOn(\fx++name, {|...args| + fx.value(*args); }, 19, srcID: idin); // cue/vinyl mode activated - MIDIdef.noteOn(\viwo+name, {|...args| - viwo.value(*args); + MIDIdef.noteOn(\vinyl++name, {|...args| + vinyl.value(*args); }, 20, srcID: idin); // == faders // channel A fader - MIDIdef.cc(\dafe+name, {|...args| - dafe.value(args[0].linlin(0, 127, 0, 1), *args); + MIDIdef.cc(\afade+name, {|...args| + afade.value(args[0].linlin(0, 127, 0, 1), *args); }, 33, srcID: idin); // channel B fader - MIDIdef.cc(\zefe+name, {|...args| - zefe.value(args[0].linlin(0, 127, 0, 1), *args); + MIDIdef.cc(\bfade+name, {|...args| + bfade.value(args[0].linlin(0, 127, 0, 1), *args); }, 34, srcID: idin); // cross fader - MIDIdef.cc(\cofe+name, {|...args| - cofe.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); + MIDIdef.cc(\crossfade+name, {|...args| + crossfade.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); }, 35, srcID: idin); // == knobs // channel A gain - MIDIdef.cc(\dage+name, {|...args| - dage.value(args[0].linlin(0, 127, 0, 1), *args); + MIDIdef.cc(\again+name, {|...args| + again.value(args[0].linlin(0, 127, 0, 1), *args); }, 36, srcID: idin); // channel B gain - MIDIdef.cc(\zege+name, {|...args| - zege.value(args[0].linlin(0, 127, 0, 1), *args); + MIDIdef.cc(\bgain+name, {|...args| + bgain.value(args[0].linlin(0, 127, 0, 1), *args); }, 37, srcID: idin); // channel A hi - MIDIdef.cc(\daha+name, {|...args| - daha.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); + MIDIdef.cc(\ahi+name, {|...args| + ahi.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); }, 38, srcID: idin); // channel B hi - MIDIdef.cc(\zeha+name, {|...args| - zeha.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); + MIDIdef.cc(\bhi+name, {|...args| + bhi.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); }, 39, srcID: idin); // channel A mid - MIDIdef.cc(\dami+name, {|...args| - dami.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); + MIDIdef.cc(\amid+name, {|...args| + amid.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); }, 40, srcID: idin); // channel B mid - MIDIdef.cc(\zemi+name, {|...args| - zemi.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); + MIDIdef.cc(\bmid+name, {|...args| + bmid.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); }, 41, srcID: idin); // channel A low - MIDIdef.cc(\dalo+name, {|...args| - dalo.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); + MIDIdef.cc(\alow+name, {|...args| + alow.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); }, 42, srcID: idin); // channel B low - MIDIdef.cc(\zelo+name, {|...args| - zelo.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); + MIDIdef.cc(\blow+name, {|...args| + blow.value(args[0].bilin(64, 0, 127, 0, -1, 1), *args); }, 43, srcID: idin); // == endless rotators // channel A rotator: -1/1 - MIDIdef.cc(\daro+name, {|...args| - daro.value(args[0]-64, *args); + MIDIdef.cc(\rot1+name, {|...args| + rot1.value(args[0]-64, *args); }, 16, srcID: idin); // channel B rotator: -1/1 - MIDIdef.cc(\zero+name, {|...args| - zero.value(args[0]-64, *args); - }, 17, srcID: idin); - // load/preview rotator: -1/1 - MIDIdef.cc(\loro+name, {|...args| - loro.value(args[0]-64, *args); + MIDIdef.cc(\rot2+name, {|...args| + rot2.value(args[0]-64, *args); }, 18, srcID: idin); + // load/preview rotator: -1/1 + MIDIdef.cc(\rotload+name, {|...args| + rotload.value(args[0]-64, *args); + }, 17, srcID: idin); - // == buttons - MIDIdef.noteOn(\buttons+name, {|...args| - - var handler = this.perform(); a.value(1); - dape.value(*args); - }, [1, 2, 3, 4, 7, 8, 9, 11, 12, 13], srcID: idin); - - // channel A pfl button pushed - MIDIdef.noteOn(\dapu+name, {|...args| - dape.value(*args); - }, 1, srcID: idin); - // channel A pfl button released - MIDIdef.noteOff(\dare+name, {|...args| - dare.value(*args); - }, 1, srcID: idin); - // channel A pfl button pushed - MIDIdef.noteOn(\zepu+name, {|...args| - zepu.value(*args); - }, 2, srcID: idin); - // channel A pfl button released - MIDIdef.noteOff(\zere+name, {|...args| - zere.value(*args); - }, 2, srcID: idin); - // channel A pfl button pushed - MIDIdef.noteOn(\dapu+name, {|...args| - dape.value(*args); - }, 3, srcID: idin); - // channel A pfl button released - MIDIdef.noteOff(\dare+name, {|...args| - dare.value(*args); - }, 3, srcID: idin); - // channel A pfl button pushed - MIDIdef.noteOn(\zepu+name, {|...args| - zepu.value(*args); - }, 4, srcID: idin); - // channel A pfl button released - MIDIdef.noteOff(\zere+name, {|...args| - zere.value(*args); - }, 4, srcID: idin); + // == buttons, first arg is true if pressed, false if released + // button pressed + MIDIdef.noteOn(\buttonDown++name, {|...args| + var handler, buttonName; + buttonName = controlNotes[args[1]]; + handler = this.perform(buttonName); + handler.value(true, *args); + }, controlNotes.keys.asArray, srcID: idin); + // button released + MIDIdef.noteOff(\buttonUp++name, {|...args| + var handler, buttonName; + buttonName = controlNotes[args[1]]; + handler = this.perform(buttonName); + handler.value(false, *args); + }, controlNotes.keys.asArray, srcID: idin); // == Starter message and animation - this.animate; + //this.animate; "Шаҫиху готов к использованию 😊".postln; } // == LED control - // pfl a - leda {|value=true| + led {|control, value=true| value = ledValues[value] ? value; - midiout.noteOn(channel, 1, value); + control = ledControls[control] ? control; + midiout.noteOn(channel, control, value); } animate {|stretch=1| diff --git a/extensions/classes/sampler.sc b/extensions/classes/sampler.sc index e193b5e..49a14f2 100644 --- a/extensions/classes/sampler.sc +++ b/extensions/classes/sampler.sc @@ -69,7 +69,9 @@ Sampler { playsTuner = false; }); buf.loadToFloatArray(startPos*buf.sampleRate, duration*buf.sampleRate, action: { |array| - var maxval = max(array.maxItem, array.minItem.neg); + var maxval; + if (array.size == 0) {array = [0]}; + maxval = max(array.maxItem, array.minItem.neg); data = array; // resample and calculate moving average to make plot more consistent when browsing data = data.resamp1(data.size/sampDiv); diff --git "a/\320\245\321\215\320\267\320\270\321\204\321\203/mix101-control.scd" "b/\320\245\321\215\320\267\320\270\321\204\321\203/mix101-control.scd" index e657462..cc33257 100644 --- "a/\320\245\321\215\320\267\320\270\321\204\321\203/mix101-control.scd" +++ "b/\320\245\321\215\320\267\320\270\321\204\321\203/mix101-control.scd" @@ -24,26 +24,123 @@ MIDIdef.sysex(\testsysex, {|...args| MKtl.find; +( ~mix = MidiMix(); -~mix.ledb(\off); -~mout = MIDIOut.newByName("Mix-101", "Mix-101 MIDI 1").latency_(0); -~mix. -~mout.noteOn(5, 20, 127); - -~mix.joro = {|i| i.postln}; -a = ~mix.perform(\joro); a.value(1); +~se = Sampler(); +) ( -(0..15).do {|i| - [i].postln; - ~mout.noteOn(i, 2, 0); +~mix.cue_ {|down| + if (down) { + ~se.startRec(); + ~mix.led(\cue, \on); + } { + ~se.stopRec(); + ~mix.led(\cue, \off); + }; +}; + +~mix.play_ {|down| + if (down) { + ~se.playSample(); + ~mix.led(\play, \on); + } { + ~se.stopPlay(); + ~mix.led(\play, \off); + }; +}; + +~fine = 0.1; +~coarse = 0.1; +~fineActive = false; + +~mix.but1_{|d| + if (d) { + ~fineActive = ~fineActive.not; + ~mix.led(\but1, ~fineActive); + }; +}; + +~mix.rot1_{|v| + var delta = v * ~coarse; + if (~fineActive) { + delta = delta * ~fine; + }; + ~se.shiftPos(delta); + ~se.startPos.postln; +}; + +// granular +~mix.again_{|v| + ~amp = v; + ~gran.set(\amp, ~amp); + "amp is %f".format(~amp).postln; +}; + +~mix.rotload_{|d| + var mul = 1.1; + if (d < 0) {mul = 1/mul; d = d.neg}; + d.do{ + ~density = ~density * mul; + }; + ~gran.set(\density, ~density); + "density is %".format(~density).postln; +}; + +~mix.rot2_{|d| + var mul = 1.1; + if (d < 0) {mul = 1/mul; d = d.neg}; + d.do{ + ~len = ~len * mul; + }; + ~gran.set(\len, ~len); + "len is %".format(~len).postln; +}; + +~mix.bfade_{|v| + ~rate = v.linexp(0, 1, 1/4, 4); + ~gran.set(\rate, ~rate); + "rate is %".format(~rate).postln; +}; + +~mix.jogrot_{|d| + var mul = 0.001; + ~pos = ~pos + (d*mul); + ~gran.set(\pos, ~pos); + "pos is %".format(~pos).postln; }; ) ( -~mix.joro = {|...args| - args.postln; -}; +Pdef(\samploop, Pbind(*[ + db: -5, + dur: 2, + midinote: 57, +]) <> ~se.makeSynthBind).quant_(2).stop; +) + +( +SynthDef(\granular, {|out=0, amp=1, buf=0, density=10, len=0.1, rate=1, pos=0| + var sig; + sig = GrainBuf.ar(1, Dust.ar(density), len, buf, rate, pos+LFNoise2.ar().range(0, len/1000), 4, 0, -1, 1024, amp); + Out.ar(out, sig!2); +}).add; +) + +( +~amp = 0.5; +~density = 10; +~len = 0.1; +~rate = 1; +~pos = 0; +~gran = Synth(\granular, [ + amp: ~amp, + buf: ~se.buf, + density: ~density, + len: ~len, + rate: ~rate, + pos: ~pos +]); ) -~mix = MidiMix() \ No newline at end of file +~gran.free; \ No newline at end of file