shithub: m8c

Download patch

ref: e641956fc4e42119fc587cb7129474e412d9c951
parent: de923fd0d773a575d3bff75600b0b0f0673f8790
parent: 127850b5c82f3de866274e4f799a971d8e99db1d
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Fri Apr 11 14:43:47 EDT 2025

Merge pull request #192 from laamaa/bugfix/serial_disconnect_doublecheck

Bugfix/serial disconnect doublecheck

--- a/src/backends/m8_libserialport.c
+++ b/src/backends/m8_libserialport.c
@@ -81,6 +81,33 @@
   return 0;
 }
 
+// Checks for connected devices and whether the specified device still exists
+static int serial_port_connected() {
+
+  int device_found = 0;
+
+  struct sp_port **port_list;
+
+  const enum sp_return result = sp_list_ports(&port_list);
+
+  if (result != SP_OK) {
+    SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "sp_list_ports() failed!\n");
+    abort();
+  }
+
+  for (int i = 0; port_list[i] != NULL; i++) {
+    const struct sp_port *port = port_list[i];
+
+    if (detect_m8_serial_device(port)) {
+      if (strcmp(sp_get_port_name(port), sp_get_port_name(m8_port)) == 0)
+        device_found = 1;
+    }
+  }
+
+  sp_free_port_list(port_list);
+  return device_found;
+}
+
 static void process_received_bytes(const uint8_t *buffer, int bytes_read, slip_handler_s *slip) {
   const uint8_t *cur = buffer;
   const uint8_t *end = buffer + bytes_read;
@@ -350,6 +377,12 @@
   } else {
     empty_cycles++;
     if (empty_cycles >= conf->wait_packets) {
+      // try opening the serial port to check if it's alive
+      if (serial_port_connected()) {
+        // the device is still there, carry on
+        empty_cycles = 0;
+        return DEVICE_PROCESSING;
+      }
       SDL_LogError(SDL_LOG_CATEGORY_SYSTEM,
                    "No messages received for %d cycles, assuming device disconnected",
                    empty_cycles);
--- a/src/backends/m8_rtmidi.c
+++ b/src/backends/m8_rtmidi.c
@@ -26,7 +26,7 @@
 bool midi_processing_suspended = false;
 bool midi_sysex_received = false;
 
-bool message_is_m8_sysex(const unsigned char *message) {
+static bool message_is_m8_sysex(const unsigned char *message) {
   if (memcmp(m8_sysex_header, message, m8_sysex_header_size) == 0) {
     return true;
   }
@@ -33,7 +33,7 @@
   return false;
 }
 
-void midi_decode(const uint8_t *encoded_data, size_t length, uint8_t **decoded_data,
+static void midi_decode(const uint8_t *encoded_data, size_t length, uint8_t **decoded_data,
                  size_t *decoded_length) {
   if (length < m8_sysex_header_size) {
     // Invalid data
@@ -124,7 +124,7 @@
   }
 }
 
-void close_and_free_midi_ports(void) {
+static void close_and_free_midi_ports(void) {
   SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Freeing MIDI ports");
   rtmidi_in_cancel_callback(midi_in);
   rtmidi_close_port(midi_in);
@@ -136,9 +136,9 @@
   midi_sysex_received = false;
 }
 
-int initialize_rtmidi() {
+static int initialize_rtmidi() {
   SDL_Log("Initializing rtmidi");
-  midi_in = rtmidi_in_create(RTMIDI_API_UNSPECIFIED, "m8c_in", 1024);
+  midi_in = rtmidi_in_create(RTMIDI_API_UNSPECIFIED, "m8c_in", 2048);
   midi_out = rtmidi_out_create(RTMIDI_API_UNSPECIFIED, "m8c_out");
   if (midi_in == NULL || midi_out == NULL) {
     return 0;
@@ -146,11 +146,11 @@
   return 1;
 }
 
-int detect_m8_midi_device(const int verbose, const char *preferred_device) {
+static int detect_m8_midi_device(const int verbose, const char *preferred_device) {
   int m8_midi_port_number = -1;
   const unsigned int ports_total_in = rtmidi_get_port_count(midi_in);
   if (verbose)
-    SDL_Log("Number of MIDI in ports: %d", ports_total_in);
+    SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Number of MIDI in ports: %d", ports_total_in);
   for (unsigned int port_number = 0; port_number < ports_total_in; port_number++) {
     int port_name_length_in;
     rtmidi_get_port_name(midi_in, port_number, NULL, &port_name_length_in);
@@ -171,6 +171,35 @@
   return m8_midi_port_number;
 }
 
+static int device_still_exists() {
+  if (midi_in == NULL || midi_out == NULL) {
+    return 0;
+  };
+
+  int m8_midi_port_number = 0;
+
+  SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Checking if opened MIDI port still exists");
+
+  m8_midi_port_number = detect_m8_midi_device(0, NULL);
+  if (m8_midi_port_number >= 0) {
+    return 1;
+  }
+  return 0;
+}
+
+static int disconnect(void) {
+  SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Sending disconnect message to M8");
+  const unsigned char disconnect_sysex[8] = {0xF0, 0x00, 0x02, 0x61, 0x00, 0x00, 'D', 0xF7};
+  const int result =
+      rtmidi_out_send_message(midi_out, &disconnect_sysex[0], sizeof(disconnect_sysex));
+  if (result != 0) {
+    SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Failed to send disconnect");
+  }
+  close_and_free_midi_ports();
+  return !result;
+}
+
+
 int m8_initialize(const int verbose, const char *preferred_device) {
 
   int m8_midi_port_number = 0;
@@ -226,18 +255,6 @@
   return result;
 }
 
-int disconnect(void) {
-  SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Sending disconnect message to M8");
-  const unsigned char disconnect_sysex[8] = {0xF0, 0x00, 0x02, 0x61, 0x00, 0x00, 'D', 0xF7};
-  const int result =
-      rtmidi_out_send_message(midi_out, &disconnect_sysex[0], sizeof(disconnect_sysex));
-  if (result != 0) {
-    SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Failed to send disconnect");
-  }
-  close_and_free_midi_ports();
-  return !result;
-}
-
 int m8_send_msg_controller(const unsigned char input) {
   SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "MIDI key inputs not implemented yet");
   return 0;
@@ -301,14 +318,18 @@
   } else {
     empty_cycles++;
     if (empty_cycles >= conf->wait_packets) {
+      if (device_still_exists()) {
+        empty_cycles = 0;
+        return DEVICE_PROCESSING;
+      }
       SDL_Log("No messages received for %d cycles, assuming device disconnected", empty_cycles);
       close_and_free_midi_ports();
       destroy_queue(&queue);
       empty_cycles = 0;
-      return 0;
+      return DEVICE_DISCONNECTED;
     }
   }
-  return 1;
+  return DEVICE_PROCESSING;
 }
 
 int m8_close() {
--- a/src/input.c
+++ b/src/input.c
@@ -166,7 +166,6 @@
 static void handle_sdl_events(config_params_s *conf) {
 
   static int prev_key_analog = 0;
-  static unsigned int ticks_window_resized = 0;
 
   SDL_Event event;
 
--