Hi,

I hope it is okay to continue sending send patches regarding svmidi to
the suckless mailing list. If not, I will send future patches directly
to Henrique.

Here is a fix to prevent MIDI notes from getting 'stuck'. For details,
see commit message and/or patch.

Regards,

Johnny Oskarsson
commit 977d7c12dcd2e420df5dc1ac9cb31564a6fad45a
Author: Johnny Oskarsson <jos...@joskar.se>
Date:   Thu Apr 7 10:25:15 2016 +0200

    Prevent 'stuck' MIDI notes
    
    Sometimes the MIDI notes get 'stuck', which seems to have been because
    the code couldn't handle interlaced KeyPresses and KeyReleases properly.
    
    Having explicit state transitions for the note statuses seems to have
    solved this issue for me. It should also make it easier if someone
    wishes to implement (*Key)->status = SUSTAINED or similar in the future.
    
    This also made the previous 'key repeat' functionality excessive.

diff --git a/main.c b/main.c
index 7119c39..22187e6 100644
--- a/main.c
+++ b/main.c
@@ -288,16 +288,12 @@ run(void)
        uint nblackkeys = (int)LENGTH(blackkeys);
        KeySym keysym;
        XEvent e;
-       uint lastpress;
 
        while (1) {
                XNextEvent(dpy, &e);
                switch (e.type) {
 
                case KeyPress:
-                       if (e.xkey.keycode == lastpress)
-                               break;
-
                                keysym = XLookupKeysym (&e.xkey, 0);
 
                                /* enter instrument select loop if Ctrl + i*/
@@ -387,7 +383,8 @@ run(void)
                                /* match key with a member of whitekeys[] or 
blackkeys[] */
                                uint i = 0;
                                for (i = 0; i < nwhitekeys; i++) {
-                                       if (whitekeys[i].keysym == keysym) {
+                                       if (whitekeys[i].keysym == keysym &&
+                                           whitekeys[i].status == RELEASED) {
                                                sendnote(NOTE_ON, 
whitekeys[i].note, 100);
                                                whitekeys[i].status = PRESSED;
                                                break;
@@ -395,7 +392,8 @@ run(void)
                                }
 
                                for (i = 0; i < nblackkeys; i++) {
-                                       if (blackkeys[i].keysym == keysym) {
+                                       if (blackkeys[i].keysym == keysym &&
+                                           blackkeys[i].status == RELEASED) {
                                                sendnote(NOTE_ON, 
blackkeys[i].note, 100);
                                                blackkeys[i].status = PRESSED;
                                                break;
@@ -403,18 +401,14 @@ run(void)
                                }
 
                                drawkeyboard();
-                               lastpress = e.xkey.keycode;
                        break;
 
                case KeyRelease:
-                       /* magic to avoid key repetition */
-                       if (e.xkey.keycode == lastpress)
-                               lastpress = 0;
-
                                keysym = XLookupKeysym (&e.xkey, 0);
                                
                                for (i = 0; i < nwhitekeys; i++) {
-                                       if (whitekeys[i].keysym == keysym) {
+                                       if (whitekeys[i].keysym == keysym &&
+                                           whitekeys[i].status == PRESSED) {
                                                sendnote(NOTE_OFF, 
whitekeys[i].note, 100);
                                                whitekeys[i].status = RELEASED;
                                                break;
@@ -422,14 +416,14 @@ run(void)
                                }
 
                                for (i = 0; i < nblackkeys; i++) {
-                                       if (blackkeys[i].keysym == keysym) {
+                                       if (blackkeys[i].keysym == keysym &&
+                                           blackkeys[i].status == PRESSED) {
                                                blackkeys[i].status = RELEASED;
                                                sendnote(NOTE_OFF, 
blackkeys[i].note, 100);
                                                break;
                                        }
                                }
                        drawkeyboard();
-                       lastpress = 0;
                        break;
 
                case ConfigureNotify:

Reply via email to