shithub: m8c

Download patch

ref: 587e3dbdd9e05591f3e360a08308ed4dc8409e5b
parent: d8a05cb2d85fa46fbd6d72b199db700d66aad37a
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Mon Apr 7 10:24:18 EDT 2025

- remove forced audio out spec, let SDL decide the output format
- check whether rtmidi enable screen command is successful, exit on error
- double command queue max size to avoid glitches
- hide home indicator on iOS

--- a/src/backends/audio_sdl.c
+++ b/src/backends/audio_sdl.c
@@ -10,7 +10,6 @@
 static unsigned int audio_paused = 0;
 static unsigned int audio_initialized = 0;
 static SDL_AudioSpec audio_spec_in = {SDL_AUDIO_S16LE, 2, 44100};
-static SDL_AudioSpec audio_spec_out = {SDL_AUDIO_S16LE, 2, 44100};
 
 static void SDLCALL audio_cb_out(void *userdata, SDL_AudioStream *stream, int length, int unused) {
   // suppress compiler warnings
@@ -121,15 +120,20 @@
     SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, audio_buffer_size_str);
   }
 
-  audio_stream_out =
-      SDL_OpenAudioDeviceStream(output_device_id, &audio_spec_out, audio_cb_out, NULL);
+  audio_stream_out = SDL_OpenAudioDeviceStream(output_device_id, NULL, audio_cb_out, NULL);
 
+  SDL_AudioSpec audio_spec_out;
+  int audio_buffer_size_real = 0;
+
+  SDL_GetAudioDeviceFormat(output_device_id, &audio_spec_out, &audio_buffer_size_real);
+
   if (!audio_stream_out) {
     SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error opening audio output device: %s", SDL_GetError());
     return 0;
   }
-  SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "Audiospec Out: format %d, channels %d, rate %d",
-               audio_spec_out.format, audio_spec_out.channels, audio_spec_out.freq);
+  SDL_LogDebug(
+      SDL_LOG_CATEGORY_AUDIO, "Audiospec Out: format %d, channels %d, rate %d, buffer size %d",
+      audio_spec_out.format, audio_spec_out.channels, audio_spec_out.freq, audio_buffer_size_real);
 
   audio_stream_in = SDL_OpenAudioDeviceStream(m8_device_id, &audio_spec_in, NULL, NULL);
   if (!audio_stream_in) {
--- a/src/backends/m8_rtmidi.c
+++ b/src/backends/m8_rtmidi.c
@@ -24,6 +24,7 @@
 const unsigned char sysex_message_end = 0xF7;
 
 bool midi_processing_suspended = false;
+bool midi_sysex_received = false;
 
 bool message_is_m8_sysex(const unsigned char *message) {
   if (memcmp(m8_sysex_header, message, m8_sysex_header_size) == 0) {
@@ -95,6 +96,10 @@
   if (midi_processing_suspended || message_size < 5 || !message_is_m8_sysex(message))
     return;
 
+  if (!midi_sysex_received) {
+    midi_sysex_received = true;
+  }
+
   unsigned char *decoded_data;
   size_t decoded_length;
   midi_decode(message, message_size, &decoded_data, &decoded_length);
@@ -119,6 +124,16 @@
   }
 }
 
+void close_and_free_midi_ports(void) {
+  SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Freeing MIDI ports");
+  rtmidi_close_port(midi_in);
+  rtmidi_close_port(midi_out);
+  rtmidi_in_free(midi_in);
+  rtmidi_out_free(midi_out);
+  midi_in = NULL;
+  midi_out = NULL;
+}
+
 int initialize_rtmidi() {
   SDL_Log("Initializing rtmidi");
   midi_in = rtmidi_in_create(RTMIDI_API_UNSPECIFIED, "m8c_in", 1024);
@@ -185,25 +200,25 @@
 }
 
 int m8_enable_and_reset_display(void) {
+  SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Sending enable command sysex");
   rtmidi_in_set_callback(midi_in, midi_callback, NULL);
   const unsigned char enable_sysex[8] = {0xF0, 0x00, 0x02, 0x61, 0x00, 0x00, 'E', 0xF7};
   int result = rtmidi_out_send_message(midi_out, &enable_sysex[0], sizeof(enable_sysex));
   if (result != 0) {
-    SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Failed to enable display");
+    SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Failed to send remote display enable command");
     return 0;
   }
+  // Wait a second to get a reply from the device
+  const Uint64 timer_wait_for_response = SDL_GetTicks();
+  while (!midi_sysex_received) {
+    if (SDL_GetTicks() - timer_wait_for_response > 1000) {
+      SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM,"No response from device. Please make sure you're using M8 firmware 6.0.0 or newer.");
+      close_and_free_midi_ports();
+      return 0;
+    }
+  }
   result = m8_reset_display();
   return result;
-}
-
-void close_and_free_midi_ports(void) {
-  SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Freeing MIDI ports");
-  rtmidi_close_port(midi_in);
-  rtmidi_close_port(midi_out);
-  rtmidi_in_free(midi_in);
-  rtmidi_out_free(midi_out);
-  midi_in = NULL;
-  midi_out = NULL;
 }
 
 int disconnect(void) {
--- a/src/backends/queue.h
+++ b/src/backends/queue.h
@@ -7,7 +7,7 @@
 
 #include <SDL3/SDL.h>
 
-#define MAX_QUEUE_SIZE 4096
+#define MAX_QUEUE_SIZE 8192
 
 typedef struct {
   unsigned char *messages[MAX_QUEUE_SIZE];
--- a/src/main.c
+++ b/src/main.c
@@ -137,7 +137,7 @@
   SDL_Log("Shutting down.");
 }
 
-static unsigned char handle_device_initialization(unsigned char wait_for_device,
+static unsigned char handle_device_initialization(const unsigned char wait_for_device,
                                                   const char *preferred_device) {
   const unsigned char device_connected = m8_initialize(1, preferred_device);
   if (!wait_for_device && device_connected == 0) {
@@ -205,7 +205,9 @@
 static void main_loop(config_params_s *conf, const char *preferred_device) {
 
   do {
-    device_connected = m8_initialize(1, preferred_device);
+    if (!device_connected) {
+      device_connected = m8_initialize(1, preferred_device);
+    }
     if (device_connected && m8_enable_and_reset_display()) {
       if (conf->audio_enabled) {
         audio_initialize(conf->audio_device_name, conf->audio_buffer_size);
@@ -214,6 +216,7 @@
       app_state = RUN;
     } else {
       SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Device not detected.");
+      device_connected = 0;
       app_state = conf->wait_for_device ? WAIT_FOR_DEVICE : QUIT;
     }
 
@@ -250,11 +253,10 @@
   config_params_s conf = initialize_config(argc, argv, &preferred_device, &config_filename);
   initialize_signals();
 
-  const unsigned char initial_device_connected =
-      handle_device_initialization(conf.wait_for_device, preferred_device);
+  device_connected = handle_device_initialization(conf.wait_for_device, preferred_device);
   if (!renderer_initialize(conf.init_fullscreen)) {
     SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Failed to initialize renderer.");
-    cleanup_resources(initial_device_connected, &conf);
+    cleanup_resources(device_connected, &conf);
     return EXIT_FAILURE;
   }
 
--- a/src/render.c
+++ b/src/render.c
@@ -87,6 +87,10 @@
 
   renderer_set_font_mode(0);
 
+#ifdef TARGET_OS_IOS
+  SDL_SetHint(SDL_HINT_IOS_HIDE_HOME_INDICATOR, "1");
+#endif
+
   dirty = 1;
 
   return 1;
--