]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Applied "midimenu" changes to Linux case.
authorc vw <dl1ycf@darc.de>
Mon, 10 May 2021 18:09:30 +0000 (20:09 +0200)
committerc vw <dl1ycf@darc.de>
Mon, 10 May 2021 18:09:30 +0000 (20:09 +0200)
alsa_midi.c

index bf124202707b0b796d7329070adee56d322931a3..ab8a98b13b5fe766711130a7e5a780a29adacfe3 100644 (file)
  *       program amidi.c in alsautils.
  */
 
+#include <gtk/gtk.h>
 #include "midi.h"
+#include "midi_menu.h"
+#include "alsa_midi.h"
 
 #ifndef __APPLE__
 
 #include <pthread.h>
 #include <alsa/asoundlib.h>
 
-static pthread_t midi_thread_id;
+MIDI_DEVICE midi_devices[MAX_MIDI_DEVICES];
+int n_midi_devices;
+
 static void* midi_thread(void *);
 
 static enum {
@@ -41,9 +46,17 @@ static enum {
        CMD_PITCH,
 } command;
 
-static void *midi_thread(void *data) {
+static gboolean configure=FALSE;
+
+static snd_rawmidi_t *input;
+
+void configure_midi_device(gboolean state) {
+  configure=state;
+}
+
+static void *midi_thread(void *arg) {
     int ret;
-    snd_rawmidi_t *input;
+    MIDI_DEVICE *midi_device=(MIDI_DEVICE *)arg;
     int npfds;
     struct pollfd *pfds;
     unsigned char buf[32];
@@ -51,11 +64,10 @@ static void *midi_thread(void *data) {
     unsigned short revents;
     int i;
     int chan,arg1,arg2;
-    char *portname = (char *) data;
+    snd_rawmidi_t *input;
 
-    if ((ret = snd_rawmidi_open(&input, NULL, portname, SND_RAWMIDI_NONBLOCK)) < 0) {
-        fprintf(stderr,"cannot open port \"%s\": %s\n", portname, snd_strerror(ret));
-        free(portname);
+    if ((ret = snd_rawmidi_open(&input, NULL, midi_device->port, SND_RAWMIDI_NONBLOCK)) < 0) {
+        fprintf(stderr,"cannot open port \"%s\": %s\n", midi_device->port, snd_strerror(ret));
         return NULL;
     }
     snd_rawmidi_read(input, NULL, 0); /* trigger reading */
@@ -65,6 +77,7 @@ static void *midi_thread(void *data) {
     snd_rawmidi_poll_descriptors(input, pfds, npfds);
     for (;;) {
        ret = poll(pfds, npfds, 250);
+        if (!midi_device->active) break;
        if (ret < 0) {
             fprintf(stderr,"poll failed: %s\n", strerror(errno));
            // Do not give up, but also do not fire too rapidly
@@ -81,7 +94,7 @@ static void *midi_thread(void *data) {
        ret = snd_rawmidi_read(input, buf, 64);
         if (ret == 0) continue;
         if (ret < 0) {
-            fprintf(stderr,"cannot read from port \"%s\": %s\n", portname, snd_strerror(ret));
+            fprintf(stderr,"cannot read from port \"%s\": %s\n", midi_device->port, snd_strerror(ret));
             continue;
         }
         // process bytes in buffer. Since they no not necessarily form complete messages
@@ -129,19 +142,39 @@ static void *midi_thread(void *data) {
                           // messages with velocity == 0 when releasing
                           // a push-button
                           if (arg2 == 0) {
-                            NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                             if(configure) {
+                              NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                             } else {
+                              NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                            }
                           } else {
-                            NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+                             if(configure) {
+                              NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+                             } else {
+                              NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+                            }
                           }
                           break;
                        case CMD_NOTEOFF:
-                          NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                           if(configure) {
+                            NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                           } else {
+                            NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                          }
                           break;
                        case CMD_CTRL:
-                          NewMidiEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+                           if(configure) {
+                            NewMidiConfigureEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+                           } else {
+                            NewMidiEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+                          }
                           break;
                        case CMD_PITCH:
-                          NewMidiEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+                           if(configure) {
+                            NewMidiConfigureEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+                           } else {
+                            NewMidiEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+                          }
                           break;
                     }
                    state=STATE_SKIP;
@@ -149,42 +182,67 @@ static void *midi_thread(void *data) {
            }
         }
     }
+    // no longer active: close and quit
+    if((ret = snd_rawmidi_close(input)) < 0) {
+       g_print("%s: cannot close port: %s\n",__FUNCTION__, snd_strerror(ret));
+    }
+}
+
+int register_midi_device(int index) {
+    int i;
+    int ret=0;
+    pthread_t midi_thread_id;
+
+    if (index < 0 || index > MAX_MIDI_DEVICES) return -1;;
+
+    ret = pthread_create(&midi_thread_id, NULL, midi_thread, &midi_devices[index]);
+    if (ret < 0) {
+      g_print("%s: Failed to create MIDI read thread\n",__FUNCTION__);
+      return -1;
+    }
+    midi_devices[index].active=1;
+    return 0;
+}
+
+void close_midi_device(int index) {
+  g_print("%s\n",__FUNCTION__);
+  midi_devices[index].active=0;
+  usleep(500000L);  // make sure the reading thread has noticed 
 }
 
-void register_midi_device(char *myname) {
+void get_midi_devices() {
 
-    int mylen=strlen(myname);
     snd_ctl_t *ctl;
     snd_rawmidi_info_t *info;
     int card, device, subs, sub, ret;
     const char *devnam, *subnam;
     int found=0;
-    char name[64];
-    char *portname;
+    char portname[64];
 
+    n_midi_devices=0;
     card=-1;
     if ((ret = snd_card_next(&card)) < 0) {
         fprintf(stderr,"cannot determine card number: %s\n", snd_strerror(ret));
         return;
     }
     while (card >= 0) {
-       fprintf(stderr,"Found Sound Card=%d\n",card);
-       sprintf(name,"hw:%d", card);
-        if ((ret = snd_ctl_open(&ctl, name, 0)) < 0) {
+        //fprintf(stderr,"Found Sound Card=%d\n",card);
+        sprintf(portname,"hw:%d", card);
+        if ((ret = snd_ctl_open(&ctl, portname, 0)) < 0) {
                 fprintf(stderr,"cannot open control for card %d: %s\n", card, snd_strerror(ret));
                 return;
         }
-       device = -1;
-       // loop through devices of the card
-       for (;;) {
-           if ((ret = snd_ctl_rawmidi_next_device(ctl, &device)) < 0) {
+        device = -1;
+        // loop through devices of the card
+        for (;;) {
+            if ((ret = snd_ctl_rawmidi_next_device(ctl, &device)) < 0) {
                 fprintf(stderr,"cannot determine device number: %s\n", snd_strerror(ret));
                 break;
             }
-           if (device < 0) break;
-           fprintf(stderr,"Found Device=%d on Card=%d\n", device, card);
-           // found sub-device
-           snd_rawmidi_info_alloca(&info);
+            if (device < 0) break;
+            //fprintf(stderr,"Found Device=%d on Card=%d\n", device, card);
+            // found sub-device
+            snd_rawmidi_info_alloca(&info);
             snd_rawmidi_info_set_device(info, device);
             snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT);
             ret = snd_ctl_rawmidi_info(ctl, info);
@@ -192,10 +250,10 @@ void register_midi_device(char *myname) {
                 subs = snd_rawmidi_info_get_subdevices_count(info);
             } else {
                 subs = 0;
-           }
-           fprintf(stderr,"Number of MIDI input devices: %d\n", subs);
-           if (!subs) break;
-           // subs: number of sub-devices to device on card
+            }
+            //fprintf(stderr,"Number of MIDI input devices: %d\n", subs);
+            if (!subs) break;
+            // subs: number of sub-devices to device on card
             for (sub = 0; sub < subs; ++sub) {
                 snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT);
                 snd_rawmidi_info_set_subdevice(info, sub);
@@ -205,47 +263,43 @@ void register_midi_device(char *myname) {
                                    card, device, sub, snd_strerror(ret));
                     break;
                 }
-               devnam = snd_rawmidi_info_get_name(info);
-               subnam = snd_rawmidi_info_get_subdevice_name(info);
-               if (!strncmp(myname, devnam, mylen)) {
-                   found=1;
-                    // free() portname at the end of midi_thread
-                    portname=malloc(64);
-                   // If there is only one sub-device and it has no name, we  use
-                   // devnam for comparison and make a portname of form "hw:x,y",
-                   // else we use subnam for comparison and make a portname of form "hw:x,y,z".
-                    if (sub == 0 && subnam[0] == '\0') {
-                       sprintf(portname,"hw:%d,%d", card, device);
-                   } else {
-                       sprintf(portname,"hw:%d,%d,%d", card, device, sub);
-                       devnam=subnam;
-                   }
-                   fprintf(stderr,"MIDI device >%s< selected (PortName=>%s<)\n", devnam, portname);
-               } else {
-                    fprintf(stderr,"MIDI device >%s< not matching >%s<\n", devnam, myname);
-               }
                 if (found) break;
-           }
-            if (found) break;
-       }
-       snd_ctl_close(ctl);
-        if (found) break;
-       // next card
+                devnam = snd_rawmidi_info_get_name(info);
+                subnam = snd_rawmidi_info_get_subdevice_name(info);
+                // If there is only one sub-device and it has no name, we  use
+                // devnam for comparison and make a portname of form "hw:x,y",
+                // else we use subnam for comparison and make a portname of form "hw:x,y,z".
+                if (sub == 0 && subnam[0] == '\0') {
+                    sprintf(portname,"hw:%d,%d", card, device);
+                } else {
+                    sprintf(portname,"hw:%d,%d,%d", card, device, sub);
+                    devnam=subnam;
+                }
+
+                if (midi_devices[n_midi_devices].name != NULL) {
+                  g_free(midi_devices[n_midi_devices].name);
+                }
+                midi_devices[n_midi_devices].name=g_new(gchar,strlen(devnam)+1);
+                strcpy(midi_devices[n_midi_devices].name,devnam);
+
+                if (midi_devices[n_midi_devices].port != NULL) {
+                  g_free(midi_devices[n_midi_devices].port);
+                }
+                midi_devices[n_midi_devices].port=g_new(gchar,strlen(portname)+1);
+                strcpy(midi_devices[n_midi_devices].port,portname);
+                n_midi_devices++;
+            }
+        }
+        snd_ctl_close(ctl);
+        // next card
         if ((ret = snd_card_next(&card)) < 0) {
             fprintf(stderr,"cannot determine card number: %s\n", snd_strerror(ret));
             break;
         }
     }
-    if (!found) {
-       fprintf(stderr,"MIDI device %s NOT FOUND!\n", myname);
-        return;
-    }
-    // Found our MIDI input device. Spawn off a thread reading data
-    // (use the same variable midi_thread_id for all MIDI threads
-    // since it is not used again).
-    ret = pthread_create(&midi_thread_id, NULL, midi_thread, portname);
-    if (ret < 0) {
-       fprintf(stderr,"Failed to create MIDI read thread\n");
+
+    for(int i=0;i<n_midi_devices;i++) {
+        g_print("%s: %d: %s %s\n",__FUNCTION__,i,midi_devices[i].name,midi_devices[i].port);
     }
 }
 #endif