]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Further MIDI fixes, mainly for LINUX.
authorc vw <dl1ycf@darc.de>
Fri, 14 May 2021 07:45:46 +0000 (09:45 +0200)
committerc vw <dl1ycf@darc.de>
Fri, 14 May 2021 07:45:46 +0000 (09:45 +0200)
alsa_midi.c
alsa_midi.h
midi_menu.c

index ab8a98b13b5fe766711130a7e5a780a29adacfe3..c7ae59af03d3073d5b4b6988574a7d73d678a35b 100644 (file)
 MIDI_DEVICE midi_devices[MAX_MIDI_DEVICES];
 int n_midi_devices;
 
+//
+// The following must not reside in midi_devices since it
+// needs special #includes
+//
+static pthread_t midi_thread_id[MAX_MIDI_DEVICES];
+static char *midi_port[MAX_MIDI_DEVICES];
+static snd_rawmidi_t *midi_input[MAX_MIDI_DEVICES];
+
 static void* midi_thread(void *);
 
 static enum {
@@ -48,15 +56,16 @@ static enum {
 
 static gboolean configure=FALSE;
 
-static snd_rawmidi_t *input;
-
 void configure_midi_device(gboolean state) {
   configure=state;
 }
 
 static void *midi_thread(void *arg) {
+    int index = (int) arg;
+    snd_rawmidi_t *input=midi_input[index];
+    char *port=midi_port[index];
+
     int ret;
-    MIDI_DEVICE *midi_device=(MIDI_DEVICE *)arg;
     int npfds;
     struct pollfd *pfds;
     unsigned char buf[32];
@@ -64,20 +73,15 @@ static void *midi_thread(void *arg) {
     unsigned short revents;
     int i;
     int chan,arg1,arg2;
-    snd_rawmidi_t *input;
-
-    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 */
+    
+    
 
     npfds = snd_rawmidi_poll_descriptors_count(input);
     pfds = alloca(npfds * sizeof(struct pollfd));
     snd_rawmidi_poll_descriptors(input, pfds, npfds);
     for (;;) {
        ret = poll(pfds, npfds, 250);
-        if (!midi_device->active) break;
+        if (!midi_devices[index].active) break;
        if (ret < 0) {
             fprintf(stderr,"poll failed: %s\n", strerror(errno));
            // Do not give up, but also do not fire too rapidly
@@ -92,9 +96,10 @@ static void *midi_thread(void *arg) {
         if (!(revents & POLLIN)) continue;
        // something has arrived
        ret = snd_rawmidi_read(input, buf, 64);
+       g_print("%s: raw read returned %d\n", __FUNCTION__,ret);
         if (ret == 0) continue;
         if (ret < 0) {
-            fprintf(stderr,"cannot read from port \"%s\": %s\n", midi_device->port, snd_strerror(ret));
+            fprintf(stderr,"cannot read from port \"%s\": %s\n", port, snd_strerror(ret));
             continue;
         }
         // process bytes in buffer. Since they no not necessarily form complete messages
@@ -182,32 +187,61 @@ static void *midi_thread(void *arg) {
            }
         }
     }
-    // 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));
-    }
+    return NULL;
 }
 
-int register_midi_device(int index) {
+void register_midi_device(int index) {
     int i;
     int ret=0;
-    pthread_t midi_thread_id;
 
-    if (index < 0 || index > MAX_MIDI_DEVICES) return -1;;
+    if (index < 0 || index > MAX_MIDI_DEVICES) return;
+
+    g_print("%s: open MIDI device %d\n", __FUNCTION__, index);
 
-    ret = pthread_create(&midi_thread_id, NULL, midi_thread, &midi_devices[index]);
+    if ((ret = snd_rawmidi_open(&midi_input[index], NULL, midi_port[index], SND_RAWMIDI_NONBLOCK)) < 0) {
+        fprintf(stderr,"cannot open port \"%s\": %s\n", midi_port[index], snd_strerror(ret));
+        return;
+    }
+    snd_rawmidi_read(midi_input[index], NULL, 0); /* trigger reading */
+
+
+    ret = pthread_create(&midi_thead_id[index], NULL, midi_thread, (void *) index);
     if (ret < 0) {
       g_print("%s: Failed to create MIDI read thread\n",__FUNCTION__);
-      return -1;
+      if((ret = snd_rawmidi_close(midi_input[index])) < 0) {
+       g_print("%s: cannot close port: %s\n",__FUNCTION__, snd_strerror(ret));
+      }
+      return;
     }
     midi_devices[index].active=1;
-    return 0;
+    return;
 }
 
 void close_midi_device(int index) {
-  g_print("%s\n",__FUNCTION__);
+  int ret;
+
+  if (index < 0 || index > MAX_MIDI_DEVICES) return;
+  if (midi_devices[index].active == 0) return;
+
+  //
+  // Note that if this is called from get_midi_devices(),
+  // the port and device names do exist but may be wrong.
+  //
+  // Tell thread to stop
+  //
   midi_devices[index].active=0;
-  usleep(500000L);  // make sure the reading thread has noticed 
+  //
+  // wait for thread to complete
+  //
+  ret=pthread_join(midi_devices[index].midi_thread_id, NULL);
+  if (ret  != 0)  {
+    g_print("%s: cannot join: %s\n", __FUNCTION__, strerror(ret));
+  }     
+  //
+  // Close MIDI device
+  if((ret = snd_rawmidi_close(midi_input[index])) < 0) {
+   g_print("%s: cannot close port: %s\n",__FUNCTION__, snd_strerror(ret));
+  }
 }
 
 void get_midi_devices() {
@@ -276,17 +310,41 @@ void get_midi_devices() {
                     devnam=subnam;
                 }
 
-                if (midi_devices[n_midi_devices].name != NULL) {
-                  g_free(midi_devices[n_midi_devices].name);
+                //
+                // If the name was already present at the same position, just keep
+                // it and do nothing.
+                // If the names do not match and the slot is occupied by a opened device,
+                // close it first
+                //
+                int match = 1;
+                if (midi_devices[n_midi_devices].name == NULL) {
+                  midi_devices[n_midi_devices].name=g_new(gchar,strlen(devnam)+1);
+                  match = 0;
+                } else {
+                  if (strcmp(devnam, midi_devices[n_midi_devices].name) {
+                    g_free(midi_devices[n_midi_devices].name);
+                    midi_devices[n_midi_devices].name=g_new(gchar,strlen(devnam)+1);
+                    match = 0;
+                  }
                 }
-                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);
+                if (midi_port[n_midi_devices] == NULL) {
+                  midi_port[n_midi_devices]=g_new(gchar,strlen(portname)+1);
+                  match = 0;
+                } else {
+                  if (strcmp(midi_port[n_midi_devices], portname) {
+                    g_free(midi_port[n_midi_devices]);
+                    midi_port[n_midi_devices]=g_new(gchar,strlen(portname)+1);
+                    match = 0;
+                  }
+                }
+                //
+                // Close MIDI device if it was open, except if the device is
+                // the same as before. In this case, just let the thread
+                // proceed
+                //
+                if (match == 0 && midi_index[n_midi_devices].active) {
+                  close_midi_device(n_midi_devices);
                 }
-                midi_devices[n_midi_devices].port=g_new(gchar,strlen(portname)+1);
-                strcpy(midi_devices[n_midi_devices].port,portname);
                 n_midi_devices++;
             }
         }
index 234a57ed09d20c3f44d9de2727549e7e5708786a..2406b11ea4e943c4d057de445c57a82ed1edca71 100644 (file)
@@ -1,6 +1,5 @@
 typedef struct _midi_device {
   char *name;
-  char *port;
   int  active;
 } MIDI_DEVICE;
 
index bf1ca98b03a701bfc7256ee6e25f6a35fb1b30c8..9b0d273ae5abe1c2e4c79fa1e99f8d518db1520f 100644 (file)
@@ -129,14 +129,6 @@ static void cleanup() {
   }
 }
 
-static gboolean wheelclose_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
-  return TRUE;
-}
-
-static gboolean wheeldelete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
-  return FALSE;
-}
-
 static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
   cleanup();
   return TRUE;
@@ -350,7 +342,6 @@ static void wheelparam_cb(GtkWidget *widget, gpointer user_data) {
   int what = GPOINTER_TO_INT(user_data);
   int val=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
   int newval=val;
-  g_print("WHEEL CB what=%d newval=%d\n", what, newval);
 
   if (thisType != MIDI_TYPE_WHEEL) {
     // we should never arrive here
@@ -505,7 +496,6 @@ static void load_original_cb(GtkWidget *widget,gpointer user_data) {
                                       GTK_RESPONSE_ACCEPT,
                                       NULL);
   chooser = GTK_FILE_CHOOSER (load_dialog);
-  gtk_file_chooser_set_current_name(chooser,"midi.midi");
   res = gtk_dialog_run (GTK_DIALOG (load_dialog));
   if(res==GTK_RESPONSE_ACCEPT) {
     char *loadfilename=gtk_file_chooser_get_filename(chooser);
@@ -1115,7 +1105,7 @@ void midi_menu(GtkWidget *parent) {
 
   set_fl2 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
   gtk_grid_attach(GTK_GRID(WheelGrid), set_fl2, col, row, 1, 1);
-  g_signal_connect(set_vfl2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(5));
+  g_signal_connect(set_fl2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(5));
   col++;
 
   row++;