From fa2936404b89a491b8446b44017a18cd30f1d2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Forment?= Date: Wed, 15 May 2024 00:35:36 +0200 Subject: [PATCH] Rewrite internal stuff --- Classes/BuboNodeProxy.sc | 50 ++++++---- Classes/EventShortener.sc | 192 +++++++++++++++++++++++++------------- dev_sessions/midi_cc.scd | 120 ++++++++++++++++++++++++ 3 files changed, 280 insertions(+), 82 deletions(-) create mode 100644 dev_sessions/midi_cc.scd diff --git a/Classes/BuboNodeProxy.sc b/Classes/BuboNodeProxy.sc index b81acd3..654abbc 100644 --- a/Classes/BuboNodeProxy.sc +++ b/Classes/BuboNodeProxy.sc @@ -56,22 +56,48 @@ ^this } + /* MIDI CC Operator */ + >>+ { + arg pattern; + var quant = this.getQuantFromPattern(pattern); + var fade = this.getFadeFromPattern(pattern); + "Fonction Control Change".postln; + pattern = EventShortener.process( + pattern, this.key, 'midicc', 0 + ); + this[0] = Pbind(*pattern); + this[0].patternpairs.postln; + this.prepareToPlay(this, quant, fade); + ^this + } + /* Player syntax sugar */ => { arg pattern; var quant = this.getQuantFromPattern(pattern); var fade = this.getFadeFromPattern(pattern); - pattern = EventShortener.process( - pattern, this.key, \buboEvent, 0 - ); - pattern = EffectChain.process( - pattern, this.key - ); + pattern = EventShortener.process(pattern, this.key, 'buboEvent', 1); + pattern = EffectChain.process(pattern, this.key); this[0] = Pbind(*pattern); this.prepareToPlay(this, quant, fade); ^this } + /* Pmono player */ + -> { + arg pattern; + var quant = this.getQuantFromPattern(pattern); + var fade = this.getFadeFromPattern(pattern); + pattern = EventShortener.process(pattern, this.key, 'pmono', 1); + pattern.do({ + arg i; + i.postln; + }); + this[0] = Pmono(*pattern); + this.prepareToPlay(this, quant, fade); + ^this + } + /* Audio Looper (sample playback) */ == { // TODO: fix this terrible mess @@ -88,18 +114,6 @@ ^this } - /* Pmono player */ - -> { - arg pattern; - var quant = this.getQuantFromPattern(pattern); - var fade = this.getFadeFromPattern(pattern); - pattern = EventShortener.process( - pattern, this.key, 'pmono', 0 - ); - this[0] = Pmono(*pattern); - this.prepareToPlay(this, quant, fade); - ^this - } getValueFromPattern { arg pattern, key, default; diff --git a/Classes/EventShortener.sc b/Classes/EventShortener.sc index 7f8206f..d7473fa 100644 --- a/Classes/EventShortener.sc +++ b/Classes/EventShortener.sc @@ -4,70 +4,147 @@ EventShortener { arg pattern, key, type, time; var new_pattern; var additionalKeys = Dictionary.newFrom([ - \midi, [ - type: \midi, - midiCmd: \noteOn, - ], - \buboEvent, [ - type: \buboEvent, - ], - \looper, [ - type: \buboLoopEvent, - legato: 1, time: time - ], - \pmono, [], + \looper, [type: \buboLoopEvent, legato: 1, time: time], ]); new_pattern = this.findShortcuts(pattern); new_pattern = this.functionsToNdef(new_pattern, key); - new_pattern = new_pattern ++ additionalKeys[type]; - if (pattern.includes('pat'), { - new_pattern = this.patternize(new_pattern, type); + new_pattern = switch(type, + 'pmono', this.patternPmono(new_pattern), + 'buboEvent', this.patternBuboEvent(new_pattern), + 'midi', this.patternMidi(new_pattern), + 'midicc', this.patternMidiCC(new_pattern), + 'looper', this.patternLooper(new_pattern), + ); + ^new_pattern + } + + *patternLooper { + arg pattern; + ^pattern + } + + *patternPmono { + arg pattern; + var new_pattern = List(); + new_pattern = new_pattern ++ pattern[0]; + pattern = pattern[1..]; + pattern.doAdjacentPairs({ | a, b, index | + if (index % 2 == 0, { + if (a === 'pat', { + var temp = Pmini(b); + new_pattern = new_pattern ++ [ + [\trig, \delta, \dur, \str, \num], Pmini(b), + ]; + new_pattern = new_pattern ++ [ + degree: Pfunc({ |e| e.str.asInteger }); + ]; + }, { + new_pattern = new_pattern ++ [a, b]; + }); + }); }); ^new_pattern } - *patternize { - arg pattern, type; + *patternBuboEvent { + arg pattern; var new_pattern = List(); - pattern.doAdjacentPairs({ - arg a, b, index; + new_pattern = new_pattern ++ [\type, 'buboEvent']; + + pattern.doAdjacentPairs({ | a, b, index | if (index % 2 == 0, { if (a === 'pat', { var temp = Pmini(b); - var additionalKeys; - if (type == 'midi', { - additionalKeys = [\trig, \delta, \dur, \str]; - new_pattern = new_pattern ++ [\type, 'midi']; - }, { - additionalKeys = [\trig, \delta, \dur, \str, \num]; - }); - new_pattern = new_pattern ++ [additionalKeys, temp]; + new_pattern = new_pattern ++ [ + [\trig, \delta, \dur, \str, \num], Pmini(b), + ]; new_pattern = new_pattern ++ [ degree: Pfunc({ |e| if (e.trig > 0, { e.str.asInteger }, { \rest - } - )}); - ]; - if (type !== 'midi', { - if (pattern.includes('i') || pattern.includes('instrument') == false, { - new_pattern = new_pattern ++ [ - sp: Pfunc { |e| e.str ? "" }, - nb: Pfunc { |e| e.num ? 0 }, - fast: 1, - ]; + }); }); - }) + ]; }, { new_pattern = new_pattern ++ [a, b]; }); - }) + }); + }); + + if (pattern.includes('i') || pattern.includes('instrument') == false, { + new_pattern = new_pattern ++ [ + sp: Pfunc { |e| e.str ? "" }, + nb: Pfunc { |e| e.num ? 0 } + ]; }); ^new_pattern } + *patternMidi { + arg pattern; + var new_pattern = List(); + new_pattern = new_pattern ++ [\type, 'midi', \midicmd, \noteOn]; + pattern.doAdjacentPairs({ | a, b, index | + if (index % 2 == 0, { + if (a === 'pat', { + var temp = Pmini(b); + new_pattern = new_pattern ++ [ [\trig, \delta, \dur, \str, \num], Pmini(b) ]; + new_pattern = new_pattern ++ [ + degree: Pfunc({ |e| + if (e.trig > 0, { + e.str.asInteger + }, { + \rest + }); + }); + ]; + }, { + new_pattern = new_pattern ++ [a, b]; + }); + }); + }); + ^new_pattern + } + + *patternMidiCC { + arg pattern; + var new_pattern = List(); + // The base requirement for a message to be considered CC + new_pattern = new_pattern ++ [ + \type: 'midi', + \midicmd: 'control' + ]; + pattern.doAdjacentPairs({ + arg a, b, index; + if (index % 2 == 0, { + if (a === 'pat', { + var temp = Pmini(b); + new_pattern = new_pattern ++ [ + [\trig, \delta, \dur, \str], Pmini(b), + ]; + new_pattern = new_pattern ++ [ + val: Pfunc({ |e| + if (e.trig > 0, { + e.str.asInteger + }, { + \rest + }); + }); + ]; + }, { + new_pattern = new_pattern ++ [a, b]; + }); + }); + }); + new_pattern = new_pattern ++ [ + 'ctlNum': Pkey(\num), + 'control': Pfunc { |e| e.val.asInteger }, + ] + ^new_pattern + } + *functionsToNdef { arg pattern, key; var new_pattern = List.new(); @@ -78,7 +155,7 @@ EventShortener { }, { new_pattern.add(element) }); - }) + }); ^new_pattern } @@ -90,43 +167,30 @@ EventShortener { // Instrument \i, \instrument, // Notes - \n, \note, - \mn, \midinote, - \vel, \velocity, - \deg, \degree, - \off, \timingOffset, - \o, \octave, - \f, \freq, - \det, \detune, + \n, \note, \mn, \midinote, + \vel, \velocity, \deg, \degree, + \off, \timingOffset, \o, \octave, + \f, \freq, \det, \detune, // Durations - \d, \dur, - \l, \legato, + \d, \dur, \l, \legato, // Amplitude \p, \pan, // Envelope - \a, \attack, - \d, \decay, - \s, \sustain, - \r, \release, + \a, \attack, \d, \decay, + \s, \sustain, \r, \release, // Filter control - \r, \resonance, - \ff, \ffreq, + \r, \resonance, \ff, \ffreq, // Modulation - \m, \mod, - \mo, \midout, - \c, \midichan, - \st, \stretch, - \rt, \root, - \scl, \scale, + \m, \mod, \mo, \midout, + \c, \midichan, \st, \stretch, + \rt, \root, \scl, \scale, ]); - pattern.do({| element, i | if (short.includesKey(element), {correctedPattern.add(short[element])}, {correctedPattern.add(element)} ); }); - ^correctedPattern; } } diff --git a/dev_sessions/midi_cc.scd b/dev_sessions/midi_cc.scd new file mode 100644 index 0000000..d695493 --- /dev/null +++ b/dev_sessions/midi_cc.scd @@ -0,0 +1,120 @@ +( +m = MIDIOut.newByName("MIDI", "Bus 1"); +~cc >>+ [num: 20, pat: "[10 50 100 [120 100]]/2", midiout: m ]; +~cc.play; +) + +( +m = MIDIOut.newByName("MIDI", "Bus 1"); +~test >> [ + midiout: m, + degree: [0, 2, 4, 5].pxrand(inf), + chan: 1, + dur: [5,8,0].eu / 4, octave: 5, + amp: 1/2, +]; +~test.play; +) + +( +m = MIDIOut.newByName("MIDI", "Bus 1"); +~cc >>+ [ + num: 20, dur: 1/8, midiout: m, + pat: "10 20 30 40 50 70 100 120", +]; +~cc.play; +) + + +// TEST: Avec des samples +( +~test => [pat: "[kick hat snare hat:5]/2", test: Pfunc { |e| e.postln; e }]; +~hat => [pat: "[hat!3 hat:5]", test: Pfunc { |e| e.postln; e }, speed: 2, release: 1/16]; +~test.play; +~hat.play; +) + +// TEST: Avec un synthétiseur +( +~test => [pat: "0 3 5 <7 ~>", i: "Pwaveshape", octave: 6, harm: 0.25]; +~test.play; +) + +// TEST: une mélodie MIDI +( +m = MIDIOut.newByName("MIDI", "Bus 1"); +~test >> [ + pat: "[0 3 5 3, [0,<3 5>,<7 10>]]/2", + midiout: m, + amp: [0.0, 1.0].pwhite(inf), + octave: 4, + chan: [0, 1].pxrand(inf), + release: 0.125/4, + legato: 0.1, +]; +~test.play; +) + +// NOTE: Je vais jouer avec jusqu'à ce qu'il casse +( +m = MIDIOut.newByName("MIDI", "Bus 1"); +~a = Pbind( + \type, \midi, + \midicmd, \control, + \ctlNum, [20,25].pseq(inf), + // chan est optionnel + \midiout, m, + \dur, [1,1/2].pseq(inf), + \val, Pseq([50, 100], inf), + \test, Pfunc { + |e| e.postln; e + } +); +~a.play; +) + +( +SynthDef('acid', { + var freq = \freq.kr(100).varlag(\glide.kr(0.05)); + var signal = PulseDPW.ar([freq / 2, freq / 1.99]) + + SawDPW.ar([freq, freq / 1.99]); + var env = Env.perc( + \attack.kr(0.1), + \release.kr(0.125)).ar(0); + var synth = signal * env; + synth = RLPF.ar(signal, + \ffreq.kr(1500).lag(\glide.kr), + \res.kr(0.2).lag(\glide.kr)); + synth = Pan2.ar(synth, \pan.kr(0)); + OffsetOut.ar(\out.kr(0), synth * \amp.kr(-24.dbamp)); +}).add; +~acid -> ['acid', dur: (1/2), amp: 0.5, pat: "[0 2 4 5]/2"]; +~acid.play; +) + +~acid.source + +( +~a = Pmono( + 'acid', \freq, [100, 150, 200, 400].pxrand(inf), + \dur, 1/2, +); +~a.play; +) + +( +~a = Pmono(*[ + 'acid', freq: [100, 150, 200, 400].pxrand(inf), + dur: 1/2, +]); +~a.play; +) + +( +a = Pmono( + 'acid', \note, [0, 2].pseq(inf), + \dur, [1, 1/2].pxrand(inf), + \release, 0.12 +); +a.play; +)