Add white-only absolute keys
authorEugene Petkevich <nasedil.genio.code@gmail.com>
Tue, 5 Jul 2022 11:05:13 +0000 (14:05 +0300)
committerEugene Petkevich <nasedil.genio.code@gmail.com>
Tue, 5 Jul 2022 11:05:13 +0000 (14:05 +0300)
extensions/classes/midisynths.sc
Хэзифу/test.scd

index 4550cb6..0c7b37a 100644 (file)
@@ -34,6 +34,9 @@ MidiSynth {
     ^res;
   }
 
+  isWhiteKey {|n|
+    ^Scale.major.degrees.includesEqual(n % 12);
+  }
 }
 
 //=============================================================================
@@ -41,31 +44,41 @@ MidiSynth {
 // connect synth to midi-keyboard
 KeySynth : MidiSynth {
   var <notes;
+  var <>onlyWhite;
+  var <>scale;
 
-  *new {|midihandler, synthName=\default, bendRadius=1, panAcross=false, params=nil, amp=1.0, group=nil|
-    ^super.newCopyArgs(midihandler, synthName, bendRadius, panAcross, params, amp, group).midiInit.keyInit;
+  *new {|midihandler, synthName=\default, bendRadius=1, panAcross=false, params=nil, amp=1.0, group=nil, onlyWhite=false, scale=nil|
+    ^super.newCopyArgs(midihandler, synthName, bendRadius, panAcross, params, amp, group).midiInit.keyInit(onlyWhite, scale);
   }
 
-  keyInit {
+  keyInit {|ow=false, sc=nil|
+    onlyWhite = ow;
+    scale = sc ? Scale.chromatic();
+
     notes = Array.newClear(128);
 
     midihandler.key_{|d, v, n|
-      if (d) {
-        notes[n] = Synth(synthName, params.value.asPairs++[
-          \gate, 1,
-          \freq, (n+bend).midicps,
-          \amp, amp * v,
-        ]++this.makePanParam(n), group);
-      } {
-        notes[n].set(\gate, 0);
-        notes[n] = nil;
+      if (this.isWhiteKey(n) || onlyWhite.not) {
+        if (onlyWhite) {
+          n = 60 + this.distanceWhite(60, n);
+        };
+        if (d) {
+          notes[n] = Synth(synthName, params.value.asPairs++[
+            \gate, 1,
+            \freq, this.midiKeyToFreq(n),
+            \amp, amp * v,
+          ]++this.makePanParam(n), group);
+        } {
+          notes[n].set(\gate, 0);
+          notes[n] = nil;
+        };
       };
     };
 
     midihandler.bend_{|v|
       bend = v * bendRadius;
       notes.do{|item, i|
-        item.set(\freq, (i+bend).midicps);
+        item.set(\freq, this.midiKeyToFreq(i));
       };
     };
   }
@@ -78,6 +91,11 @@ KeySynth : MidiSynth {
     midihandler.bend = nil;
     super.free;
   }
+
+  midiKeyToFreq {|n|
+    "Playing %".format(scale.degreeToFreq(n-60, 60.midicps, 0).cpsmidi.round).postln;
+    ^scale.degreeToFreq(n-60, 60.midicps, 0) * bend.midiratio;
+  }
 }
 
 // example
@@ -223,7 +241,8 @@ KeySynthMono : MidiSynth {
 
 // connect synth to midi-keyboard, play only one note at a time, relative keys
 KeySynthRelative : KeySynthMono {
-  var <>centerKey, <>intervals, <>onlyWhite, keyNote;
+  var <>centerKey, <>intervals, keyNote;
+  var <>onlyWhite;
 
   *new {|midihandler, synthName=\default, bendRadius=1, panAcross=false, params=nil, amp=1.0, group=nil, centerKey=60, intervals=#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], onlyWhite=true|
     ^super.newCopyArgs(
@@ -247,7 +266,7 @@ KeySynthRelative : KeySynthMono {
           distance = n - centerKey;
         };
         [distance, intervals.size].postln;
-        if (distance.abs <= intervals.size) {
+        if ((distance.abs <= intervals.size) && (this.isWhiteKey(n) || onlyWhite.not)) {
           midinote = case
           { distance == 0 } {
             midinote;
index e391027..f793112 100644 (file)
@@ -134,7 +134,7 @@ s.waitForBoot{
 )
 
 //=============================================================================
-
+[ 0, 1, 3, 5, 7, 8, 10 ]+2
 ~kedi = MidiRemote25SL();
 ~kedi2 = MidiRemote25SL(\kedi2);
 
@@ -157,4 +157,21 @@ s.waitForBoot{
 ~monokeys2.amp = 2;
 ~monokeys2.synthName = \pope;
 ~monokeys2.bendRadius = 0.2;
-~monokeys.intervals = #[2, 5, 7];
\ No newline at end of file
+~monokeys.intervals = #[2, 5, 7];
+
+//=============================================================================
+
+~kedi = MidiRemote25SL();
+[ 0, 2, 8, 10, 14, 18, 20 ]/2
+[ 0.0, 2.0, 4.0, 5.0, 7.0, 8.0, 11.0 ].do{|e, i| };
+(
+~keys = KeySynth(~kedi, \dyti, 1, true, nil, 0.2, nil, false);
+~keys.onlyWhite = true;
+~keys.scale = Scale.zanjaran;
+~keys.params[\modAmp] = 0.0;
+~kedi.press_{|v|
+  var val = v * 0.02;
+  ~keys.group.set(\modAmp, val);
+  ~keys.params[\modAmp] = val;
+};
+)
\ No newline at end of file