probonopd / MiniDexed

Dexed FM synthesizer similar to 8x DX7 (TX816/TX802) running on a bare metal Raspberry Pi (without a Linux kernel or operating system)
https://github.com/probonopd/MiniDexed/wiki
1.08k stars 80 forks source link

Support the sustain button on MIDI controllers #10

Closed probonopd closed 2 years ago

probonopd commented 2 years ago

Support the sustain button on MIDI controllers.

(Once https://github.com/probonopd/MiniDexed/issues/8 is implemented I can say which MIDI message the sustain button sends.)

dcoredump commented 2 years ago

Will do this with adding MIDI processing support for Synth_Dexed (see also #9, #11)

probonopd commented 2 years ago

@rsta2:

Wild guess: MIDI B0 40 7F -> m_pSynthesizer->setSustain(1) in src/mididevice.cpp, MIDI B0 40 00 -> m_pSynthesizer->setSustain(0)?

(How does one translate the MIDI B0 40 ... to something suitable for src/mididevice.cpp?)

rsta2 commented 2 years ago

@probonopd Yes, Dexed::setSustain() gets a bool. According to this list (MIDI CC 64) everything <= 63 is off and >= 64 is on. I will provide a patch. Luckily my keyboard has a sustain button, so I can test it. ;)

rsta2 commented 2 years ago

Here is a small patch to implement MIDI CC Sustain (Damper). The behavior is different from the damper pedal of my Yamaha home keyboard. When you release the sustain button, the note does not go off. You have to press the key again, to switch it off. This is managed by Synth_Dexed. @dcoredump I don't know, if it is intended?

sustain.zip

probonopd commented 2 years ago

On my M-AUDIO Keystation Mini 32 Mk3 a LED goes on when I press the sustain key (sending B0 40 7F), and the LED goes off when I press the same key again (sending B0 40 00).

probonopd commented 2 years ago

Pressing the sustain key works.

But pressing it again, the already sustained notes keep playing forever (for voices that keep playing forever if pressed forever, like brass or organs).

No matter how often I press the sustain key, the notes never stop. Only by plaing the same note again, this time with the sustain key not lit up, will the notes stop.

This is probably not like it should be? (Or is it?)

rsta2 commented 2 years ago

The sustain code in Dexed is here. I think line 386-393 have to be added to Dexed::setSustain() in Synth_Dexed. This will trigger the keyup() events automatically, when the sustain button/pedal is released.

rsta2 commented 2 years ago

Here is a patch for Synth_Dexed, which enables the full sustain support:

diff --git a/src/dexed.cpp b/src/dexed.cpp
index be43a27..a93521a 100644
--- a/src/dexed.cpp
+++ b/src/dexed.cpp
@@ -406,6 +406,15 @@ void Dexed::setSustain(bool s)
     return;

   sustain = s;
+
+  if (!sustain) {
+      for (int note = 0; note < max_notes; note++) {
+          if (voices[note].sustained && !voices[note].keydown) {
+              voices[note].dx7_note->keyup();
+              voices[note].sustained = false;
+          }
+      }
+  }
 }

 bool Dexed::getSustain(void)

It's tested, it works.

probonopd commented 2 years ago

@dcoredump could you add it please? Thanks.

dcoredump commented 2 years ago

It's fixed now in https://codeberg.org/dcoredump/Synth_Dexed

Thanks @rsta2!