shithub: m8c

Download patch

ref: 17d2d6f75df1eac72b70b6e9f0d4ebf215f015fb
parent: 3bcfb14f8ca9143c8e8f5c697d5ee05596cf960c
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Sun Mar 23 05:35:18 EDT 2025

unify m8 backend function names

--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,5 @@
 #Set all your object files (the object files of all the .c files in your project, e.g. main.o my_sub_functions.o )
 OBJ = src/main.o \
-src/audio.o \
 src/command.o \
 src/config.o \
 src/fx_cube.o \
@@ -10,6 +9,7 @@
 src/input.o \
 src/backends/queue.o \
 src/render.o \
+src/backends/audio.o \
 src/backends/rtmidi.o \
 src/backends/ringbuffer.o \
 src/backends/serialport.o \
@@ -18,7 +18,7 @@
 src/backends/usb_audio.o \
 
 #Set any dependant header files so that if they are edited they cause a complete re-compile (e.g. main.h some_subfunctions.h some_definitions_file.h ), or leave blank
-DEPS = src/audio.h \
+DEPS = \
 src/command.h \
 src/config.h \
 src/fx_cube.h \
@@ -26,6 +26,7 @@
 src/ini.h \
 src/input.h \
 src/render.h \
+src/backends/audio.h \
 src/backends/ringbuffer.h \
 src/backends/rtmidi.h \
 src/backends/queue.h \
--- a/src/audio.c
+++ /dev/null
@@ -1,147 +1,0 @@
-// Copyright 2021 Jonne Kokkonen
-// Released under the MIT licence, https://opensource.org/licenses/MIT
-#ifndef USE_LIBUSB
-#include "audio.h"
-#include <SDL3/SDL.h>
-#include <stdint.h>
-
-SDL_AudioStream *audio_stream_in, *audio_stream_out;
-
-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_in(void *userdata, SDL_AudioStream *stream, int length, int unused) {
-  // suppress compiler warnings
-  (void)userdata;
-  (void)unused;
-
-  Uint8 *src_audio_data = SDL_malloc(length);
-  const int bytes_read = SDL_GetAudioStreamData(stream, src_audio_data, length);
-  if (bytes_read == length) {
-    SDL_PutAudioStreamData(audio_stream_out, src_audio_data, bytes_read);
-  } else {
-    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error getting audio stream data: %s, destroying audio",
-                 SDL_GetError());
-    audio_close();
-  }
-  SDL_free(src_audio_data);
-}
-
-void audio_toggle(const char *output_device_name, unsigned int audio_buffer_size) {
-  if (!audio_initialized) {
-    audio_initialize(output_device_name, audio_buffer_size);
-    return;
-  }
-  if (audio_paused) {
-    SDL_ResumeAudioStreamDevice(audio_stream_out);
-    SDL_ResumeAudioStreamDevice(audio_stream_in);
-  } else {
-    SDL_PauseAudioStreamDevice(audio_stream_in);
-    SDL_PauseAudioStreamDevice(audio_stream_out);
-  }
-  audio_paused = !audio_paused;
-  SDL_Log(audio_paused ? "Audio paused" : "Audio resumed");
-}
-
-int audio_initialize(const char *output_device_name, const unsigned int audio_buffer_size) {
-
-  // wait for system to initialize possible new audio devices
-  SDL_Delay(500);
-
-  int num_devices_in, num_devices_out;
-  SDL_AudioDeviceID m8_device_id = 0;
-  SDL_AudioDeviceID output_device_id = 0;
-
-  SDL_AudioDeviceID *devices_in = SDL_GetAudioRecordingDevices(&num_devices_in);
-  if (!devices_in) {
-    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "No audio capture devices, SDL Error: %s", SDL_GetError());
-    return 0;
-  }
-
-  SDL_AudioDeviceID *devices_out = SDL_GetAudioPlaybackDevices(&num_devices_out);
-  if (!devices_out) {
-    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "No audio playback devices, SDL Error: %s",
-                 SDL_GetError());
-    return 0;
-  }
-
-  for (int i = 0; i < num_devices_in; i++) {
-    const SDL_AudioDeviceID instance_id = devices_in[i];
-    const char *device_name = SDL_GetAudioDeviceName(instance_id);
-    SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "%s", device_name);
-    if (SDL_strstr(device_name, "M8") != NULL) {
-      SDL_Log("M8 Audio Input device found: %s", device_name);
-      m8_device_id = instance_id;
-    }
-  }
-
-  if (output_device_name != NULL) {
-    for (int i = 0; i < num_devices_out; i++) {
-      const SDL_AudioDeviceID instance_id = devices_out[i];
-      const char *device_name = SDL_GetAudioDeviceName(instance_id);
-      SDL_LogInfo(SDL_LOG_CATEGORY_AUDIO, "%s", device_name);
-      if (SDL_strcasestr(device_name, output_device_name) != NULL) {
-        SDL_Log("Requested output device found: %s", device_name);
-        output_device_id = instance_id;
-      }
-    }
-  }
-
-  SDL_free(devices_in);
-  SDL_free(devices_out);
-
-  if (!output_device_id) {
-    output_device_id = SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK;
-  }
-
-  if (!m8_device_id) {
-    // forget about it
-    SDL_Log("Cannot find M8 audio input device");
-    return 0;
-  }
-
-  char audio_buffer_size_str[256];
-  SDL_snprintf(audio_buffer_size_str, sizeof(audio_buffer_size_str), "%d", audio_buffer_size);
-  SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, audio_buffer_size_str);
-
-  audio_stream_out = SDL_OpenAudioDeviceStream(output_device_id, &audio_spec_out, NULL, NULL);
-
-  if (!audio_stream_out) {
-    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error opening audio output device: %s", SDL_GetError());
-    return 0;
-  }
-  SDL_Log("Audiospec Out: format %d, channels %d, rate %d", audio_spec_out.format,
-          audio_spec_out.channels, audio_spec_out.freq);
-
-  audio_stream_in = SDL_OpenAudioDeviceStream(m8_device_id, &audio_spec_in, audio_cb_in, NULL);
-  if (!audio_stream_in) {
-    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error opening audio input device: %s", SDL_GetError());
-    SDL_DestroyAudioStream(audio_stream_out);
-    return 0;
-  }
-  SDL_Log("Audiospec In: format %d, channels %d, rate %d", audio_spec_in.format,
-          audio_spec_in.channels, audio_spec_in.freq);
-
-  SDL_SetAudioStreamFormat(audio_stream_in, &audio_spec_in, &audio_spec_out);
-
-  SDL_ResumeAudioStreamDevice(audio_stream_out);
-  SDL_ResumeAudioStreamDevice(audio_stream_in);
-
-  audio_paused = 0;
-  audio_initialized = 1;
-
-  return 1;
-}
-
-void audio_close() {
-  if (!audio_initialized)
-    return;
-  SDL_Log("Closing audio devices");
-  SDL_DestroyAudioStream(audio_stream_in);
-  SDL_DestroyAudioStream(audio_stream_out);
-  audio_initialized = 0;
-}
-
-#endif
--- a/src/audio.h
+++ /dev/null
@@ -1,11 +1,0 @@
-// Copyright 2021 Jonne Kokkonen
-// Released under the MIT licence, https://opensource.org/licenses/MIT
-#ifndef AUDIO_H
-#define AUDIO_H
-
-int audio_initialize(const char *output_device_name, unsigned int audio_buffer_size);
-void audio_toggle(const char *output_device_name, unsigned int audio_buffer_size);
-void audio_process();
-void audio_close();
-
-#endif
--- /dev/null
+++ b/src/backends/audio.c
@@ -1,0 +1,147 @@
+// Copyright 2021 Jonne Kokkonen
+// Released under the MIT licence, https://opensource.org/licenses/MIT
+#ifndef USE_LIBUSB
+#include "audio.h"
+#include <SDL3/SDL.h>
+#include <stdint.h>
+
+SDL_AudioStream *audio_stream_in, *audio_stream_out;
+
+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_in(void *userdata, SDL_AudioStream *stream, int length, int unused) {
+  // suppress compiler warnings
+  (void)userdata;
+  (void)unused;
+
+  Uint8 *src_audio_data = SDL_malloc(length);
+  const int bytes_read = SDL_GetAudioStreamData(stream, src_audio_data, length);
+  if (bytes_read == length) {
+    SDL_PutAudioStreamData(audio_stream_out, src_audio_data, bytes_read);
+  } else {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error getting audio stream data: %s, destroying audio",
+                 SDL_GetError());
+    audio_close();
+  }
+  SDL_free(src_audio_data);
+}
+
+void audio_toggle(const char *output_device_name, unsigned int audio_buffer_size) {
+  if (!audio_initialized) {
+    audio_initialize(output_device_name, audio_buffer_size);
+    return;
+  }
+  if (audio_paused) {
+    SDL_ResumeAudioStreamDevice(audio_stream_out);
+    SDL_ResumeAudioStreamDevice(audio_stream_in);
+  } else {
+    SDL_PauseAudioStreamDevice(audio_stream_in);
+    SDL_PauseAudioStreamDevice(audio_stream_out);
+  }
+  audio_paused = !audio_paused;
+  SDL_Log(audio_paused ? "Audio paused" : "Audio resumed");
+}
+
+int audio_initialize(const char *output_device_name, const unsigned int audio_buffer_size) {
+
+  // wait for system to initialize possible new audio devices
+  SDL_Delay(500);
+
+  int num_devices_in, num_devices_out;
+  SDL_AudioDeviceID m8_device_id = 0;
+  SDL_AudioDeviceID output_device_id = 0;
+
+  SDL_AudioDeviceID *devices_in = SDL_GetAudioRecordingDevices(&num_devices_in);
+  if (!devices_in) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "No audio capture devices, SDL Error: %s", SDL_GetError());
+    return 0;
+  }
+
+  SDL_AudioDeviceID *devices_out = SDL_GetAudioPlaybackDevices(&num_devices_out);
+  if (!devices_out) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "No audio playback devices, SDL Error: %s",
+                 SDL_GetError());
+    return 0;
+  }
+
+  for (int i = 0; i < num_devices_in; i++) {
+    const SDL_AudioDeviceID instance_id = devices_in[i];
+    const char *device_name = SDL_GetAudioDeviceName(instance_id);
+    SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "%s", device_name);
+    if (SDL_strstr(device_name, "M8") != NULL) {
+      SDL_Log("M8 Audio Input device found: %s", device_name);
+      m8_device_id = instance_id;
+    }
+  }
+
+  if (output_device_name != NULL) {
+    for (int i = 0; i < num_devices_out; i++) {
+      const SDL_AudioDeviceID instance_id = devices_out[i];
+      const char *device_name = SDL_GetAudioDeviceName(instance_id);
+      SDL_LogInfo(SDL_LOG_CATEGORY_AUDIO, "%s", device_name);
+      if (SDL_strcasestr(device_name, output_device_name) != NULL) {
+        SDL_Log("Requested output device found: %s", device_name);
+        output_device_id = instance_id;
+      }
+    }
+  }
+
+  SDL_free(devices_in);
+  SDL_free(devices_out);
+
+  if (!output_device_id) {
+    output_device_id = SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK;
+  }
+
+  if (!m8_device_id) {
+    // forget about it
+    SDL_Log("Cannot find M8 audio input device");
+    return 0;
+  }
+
+  char audio_buffer_size_str[256];
+  SDL_snprintf(audio_buffer_size_str, sizeof(audio_buffer_size_str), "%d", audio_buffer_size);
+  SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, audio_buffer_size_str);
+
+  audio_stream_out = SDL_OpenAudioDeviceStream(output_device_id, &audio_spec_out, NULL, NULL);
+
+  if (!audio_stream_out) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error opening audio output device: %s", SDL_GetError());
+    return 0;
+  }
+  SDL_Log("Audiospec Out: format %d, channels %d, rate %d", audio_spec_out.format,
+          audio_spec_out.channels, audio_spec_out.freq);
+
+  audio_stream_in = SDL_OpenAudioDeviceStream(m8_device_id, &audio_spec_in, audio_cb_in, NULL);
+  if (!audio_stream_in) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error opening audio input device: %s", SDL_GetError());
+    SDL_DestroyAudioStream(audio_stream_out);
+    return 0;
+  }
+  SDL_Log("Audiospec In: format %d, channels %d, rate %d", audio_spec_in.format,
+          audio_spec_in.channels, audio_spec_in.freq);
+
+  SDL_SetAudioStreamFormat(audio_stream_in, &audio_spec_in, &audio_spec_out);
+
+  SDL_ResumeAudioStreamDevice(audio_stream_out);
+  SDL_ResumeAudioStreamDevice(audio_stream_in);
+
+  audio_paused = 0;
+  audio_initialized = 1;
+
+  return 1;
+}
+
+void audio_close() {
+  if (!audio_initialized)
+    return;
+  SDL_Log("Closing audio devices");
+  SDL_DestroyAudioStream(audio_stream_in);
+  SDL_DestroyAudioStream(audio_stream_out);
+  audio_initialized = 0;
+}
+
+#endif
--- /dev/null
+++ b/src/backends/audio.h
@@ -1,0 +1,11 @@
+// Copyright 2021 Jonne Kokkonen
+// Released under the MIT licence, https://opensource.org/licenses/MIT
+#ifndef AUDIO_H
+#define AUDIO_H
+
+int audio_initialize(const char *output_device_name, unsigned int audio_buffer_size);
+void audio_toggle(const char *output_device_name, unsigned int audio_buffer_size);
+void audio_process(void);
+void audio_close(void);
+
+#endif
--- a/src/backends/rtmidi.c
+++ b/src/backends/rtmidi.c
@@ -127,7 +127,7 @@
   return 1;
 }
 
-int m8_connect(const int verbose, const char *preferred_device) {
+int m8_initialize(const int verbose, const char *preferred_device) {
 
   int midi_in_initialized = 0;
   int midi_out_initialized = 0;
@@ -170,7 +170,7 @@
   return 0;
 }
 
-int reset_display(void) {
+int m8_reset_display(void) {
   SDL_Log("Reset display");
   const unsigned char reset_sysex[8] = {0xF0, 0x00, 0x02, 0x61, 0x00, 0x00, 'R', 0xF7};
   const int result = rtmidi_out_send_message(midi_out, &reset_sysex[0], sizeof(reset_sysex));
@@ -181,7 +181,7 @@
   return 1;
 }
 
-int enable_and_reset_display(void) {
+int m8_enable_and_reset_display(void) {
   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));
@@ -189,7 +189,7 @@
     SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Failed to enable display");
     return 0;
   }
-  result = reset_display();
+  result = m8_reset_display();
   return result;
 }
 
@@ -206,7 +206,7 @@
   return !result;
 }
 
-int send_msg_controller(const unsigned char input) {
+int m8_send_msg_controller(const unsigned char input) {
   const unsigned char input_sysex[9] = {0xF0, 0x00, 0x02, 0x61, 0x00, 0x00, 'C', input, 0xF7};
   const int result = rtmidi_out_send_message(midi_out, &input_sysex[0], sizeof(input_sysex));
   if (result != 0) {
@@ -216,7 +216,7 @@
   return 1;
 }
 
-int send_msg_keyjazz(const unsigned char note, unsigned char velocity) {
+int m8_send_msg_keyjazz(const unsigned char note, unsigned char velocity) {
   if (velocity > 0x7F) {
     velocity = 0x7F;
   }
@@ -230,7 +230,7 @@
   return 1;
 }
 
-int process_serial(config_params_s conf) {
+int m8_process_data(config_params_s conf) {
   (void)conf; // unused parameter
 
   unsigned char *command;
--- a/src/backends/rtmidi.h
+++ b/src/backends/rtmidi.h
@@ -6,17 +6,14 @@
 
 #include "../config.h"
 
-int initialize_rtmidi(void);
-int m8_connect(int verbose, const char *preferred_device);
+int m8_initialize(int verbose, const char *preferred_device);
 int m8_list_devices(void);
-int check_serial_port(void);
-int reset_display(void);
-int enable_and_reset_display(void);
-int disconnect(void);
-int send_msg_controller(const unsigned char input);
-int send_msg_keyjazz(const unsigned char note, unsigned char velocity);
-int process_serial(config_params_s conf);
-int m8_close();
+int m8_reset_display(void);
+int m8_enable_and_reset_display(void);
+int m8_send_msg_controller(const unsigned char input);
+int m8_send_msg_keyjazz(const unsigned char note, unsigned char velocity);
+int m8_process_data(config_params_s conf);
+int m8_close(void);
 
 #endif
 #endif
\ No newline at end of file
--- a/src/backends/serialport.c
+++ b/src/backends/serialport.c
@@ -22,6 +22,8 @@
 static slip_handler_s slip;
 static uint16_t zero_byte_packets = 0; // used to detect device disconnection
 
+SDL_Thread *serial_thread = NULL;
+
 // Helper function for error handling
 static int check(enum sp_return result);
 
@@ -64,7 +66,6 @@
 
 // Checks for connected devices and whether the specified device still exists
 int check_serial_port() {
-
   int device_found = 0;
 
   /* A pointer to a null-terminated array of pointers to
@@ -95,7 +96,7 @@
   return device_found;
 }
 
-int m8_connect(const int verbose, const char *preferred_device) {
+int m8_initialize(const int verbose, const char *preferred_device) {
   if (m8_port != NULL) {
     // Port is already initialized
     return 1;
@@ -184,7 +185,6 @@
 
 // Helper function for error handling.
 static int check(const enum sp_return result) {
-
   char *error_message;
 
   switch (result) {
@@ -209,7 +209,7 @@
   return result;
 }
 
-int reset_display() {
+int m8_reset_display() {
   SDL_Log("Reset display\n");
 
   const char buf[1] = {'R'};
@@ -221,8 +221,7 @@
   return 1;
 }
 
-int enable_and_reset_display() {
-
+int m8_enable_and_reset_display() {
   SDL_Log("Enabling and resetting M8 display\n");
 
   const char buf[1] = {'E'};
@@ -232,13 +231,12 @@
     return 0;
   }
 
-  result = reset_display();
+  result = m8_reset_display();
 
   return result;
 }
 
 int disconnect() {
-
   SDL_Log("Disconnecting M8\n");
 
   const char buf[1] = {'D'};
@@ -258,7 +256,7 @@
   return sp_nonblocking_read(m8_port, serial_buf, count);
 }
 
-int send_msg_controller(const uint8_t input) {
+int m8_send_msg_controller(const uint8_t input) {
   const char buf[2] = {'C', input};
   const size_t nbytes = 2;
   const int result = sp_blocking_write(m8_port, buf, nbytes, 5);
@@ -269,7 +267,7 @@
   return 1;
 }
 
-int send_msg_keyjazz(const uint8_t note, uint8_t velocity) {
+int m8_send_msg_keyjazz(const uint8_t note, uint8_t velocity) {
   if (velocity > 0x7F)
     velocity = 0x7F;
   const char buf[3] = {'K', note, velocity};
@@ -283,7 +281,7 @@
   return 1;
 }
 
-int process_serial(config_params_s conf) {
+int m8_process_data(const config_params_s conf) {
   while (1) {
     // read serial port
     const int bytes_read = serial_read(serial_buffer, serial_read_size);
@@ -291,7 +289,6 @@
       SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Error %d reading serial.", bytes_read);
       disconnect();
       return -1;
-      break;
     }
     if (bytes_read > 0) {
       // input from device: reset the zero byte counter and create a
@@ -304,7 +301,7 @@
         const int n = slip_read_byte(&slip, *cur++);
         if (n != SLIP_NO_ERROR) {
           if (n == SLIP_ERROR_INVALID_PACKET) {
-            reset_display();
+            m8_reset_display();
           } else {
             SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SLIP error %d\n", n);
           }
@@ -330,7 +327,5 @@
   return 1;
 }
 
-int m8_close() {
-  return disconnect();
-}
+int m8_close() { return disconnect(); }
 #endif
--- a/src/backends/serialport.h
+++ b/src/backends/serialport.h
@@ -11,17 +11,14 @@
 // maximum amount of bytes to read from the serial in one read()
 #define serial_read_size 1024
 
-int m8_connect(int verbose, const char *preferred_device);
-int m8_close();
-int m8_list_devices();
-int check_serial_port();
-int reset_display();
-int enable_and_reset_display();
-int disconnect();
-int serial_read(uint8_t *serial_buf, int count);
-int send_msg_controller(uint8_t input);
-int send_msg_keyjazz(uint8_t note, uint8_t velocity);
-int process_serial(config_params_s conf);
+int m8_initialize(int verbose, const char *preferred_device);
+int m8_list_devices(void);
+int m8_reset_display(void);
+int m8_enable_and_reset_display(void);
+int m8_send_msg_controller(uint8_t input);
+int m8_send_msg_keyjazz(uint8_t note, uint8_t velocity);
+int m8_process_data(config_params_s conf);
+int m8_close(void);
 
 #endif
 #endif
--- a/src/backends/usb.c
+++ b/src/backends/usb.c
@@ -24,7 +24,7 @@
 
 static int do_exit = 0;
 
-int list_devices() {
+int m8_list_devices() {
   int r;
   r = libusb_init(&ctx);
   if (r < 0) {
@@ -54,7 +54,7 @@
 }
 
 int usb_loop(void *data) {
-  SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL);
+  SDL_SetCurrentThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL);
   while (!do_exit) {
     int rc = libusb_handle_events(ctx);
     if (rc != LIBUSB_SUCCESS) {
@@ -113,7 +113,7 @@
   return bulk_transfer(ep_out_addr, buf, count, timeout_ms);
 }
 
-int serial_read(uint8_t *serial_buf, int count) {
+int m8_process_data(uint8_t *serial_buf, int count) {
   return bulk_transfer(ep_in_addr, serial_buf, count, 1);
 }
 
@@ -201,7 +201,7 @@
   return init_interface();
 }
 
-int init_serial(int verbose, char *preferred_device) {
+int m8_initialize(int verbose, char *preferred_device) {
 
   if (devh != NULL) {
     return 1;
@@ -219,8 +219,8 @@
     char *port;
     char *saveptr = NULL;
     char *bus;
-    port = SDL_strtokr(preferred_device, ":", &saveptr);
-    bus = SDL_strtokr(NULL, ":", &saveptr);
+    port = SDL_strtok_r(preferred_device, ":", &saveptr);
+    bus = SDL_strtok_r(NULL, ":", &saveptr);
     libusb_device **device_list = NULL;
     int count = libusb_get_device_list(ctx, &device_list);
     for (size_t idx = 0; idx < count; ++idx) {
@@ -262,7 +262,7 @@
   return init_interface();
 }
 
-int reset_display() {
+int m8_reset_display() {
   int result;
 
   SDL_Log("Reset display\n");
@@ -277,7 +277,7 @@
   return 1;
 }
 
-int enable_and_reset_display() {
+int m8_enable_and_reset_display() {
   int result;
 
   SDL_Log("Enabling and resetting M8 display\n");
@@ -290,11 +290,11 @@
   }
 
   SDL_Delay(5);
-  result = reset_display();
+  result = m8_reset_display();
   return result;
 }
 
-int disconnect() {
+int m8_close() {
 
   char buf[1] = {'D'};
   int result;
@@ -331,7 +331,7 @@
   return 1;
 }
 
-int send_msg_controller(uint8_t input) {
+int m8_send_msg_controller(uint8_t input) {
   char buf[2] = {'C', input};
   int nbytes = 2;
   int result;
@@ -343,7 +343,7 @@
   return 1;
 }
 
-int send_msg_keyjazz(uint8_t note, uint8_t velocity) {
+int m8_send_msg_keyjazz(uint8_t note, uint8_t velocity) {
   if (velocity > 0x7F)
     velocity = 0x7F;
   char buf[3] = {'K', note, velocity};
--- a/src/backends/usb.h
+++ b/src/backends/usb.h
@@ -3,7 +3,17 @@
 #ifdef USE_LIBUSB
 
 #include <libusb.h>
+#include "../config.h"
+
 extern libusb_device_handle *devh;
 int init_serial_with_file_descriptor(int file_descriptor);
+int m8_initialize(int verbose, const char *preferred_device);
+int m8_list_devices(void);
+int m8_reset_display(void);
+int m8_enable_and_reset_display(void);
+int m8_send_msg_controller(uint8_t input);
+int m8_send_msg_keyjazz(uint8_t note, uint8_t velocity);
+int m8_process_data(config_params_s conf);
+int m8_close(void);
 #endif // USE_LIBUSB
 #endif // M8C_USB_H_
--- a/src/backends/usb_audio.c
+++ b/src/backends/usb_audio.c
@@ -81,7 +81,10 @@
   return 1;
 }
 
-int audio_init(int audio_buffer_size, const char *output_device_name) {
+int audio_initialize(int audio_buffer_size, const char *output_device_name) {
+  SDL_LogError(SDL_LOG_CATEGORY_AUDIO,"LIBUSB audio not implemented yet");
+  return -1;
+  /*
   SDL_Log("USB audio setup");
 
   int rc;
@@ -118,7 +121,7 @@
   }
 
   static SDL_AudioSpec audio_spec;
-  audio_spec.format = AUDIO_S16;
+  audio_spec.format = SDL_AUDIO_S16;
   audio_spec.channels = 2;
   audio_spec.freq = 44100;
   audio_spec.samples = audio_buffer_size;
@@ -153,9 +156,10 @@
 
   SDL_Log("Successful init");
   return 1;
+  */
 }
 
-int audio_destroy() {
+int audio_close() {
   if (devh == NULL) {
     return -1;
   }
@@ -193,7 +197,7 @@
   return 1;
 }
 
-void toggle_audio(unsigned int audio_buffer_size, const char *output_device_name) {
+void audio_toggle(unsigned int audio_buffer_size, const char *output_device_name) {
   SDL_Log("Libusb audio toggling not implemented yet");
 }
 
--- a/src/input.c
+++ b/src/input.c
@@ -1,10 +1,11 @@
 #include "input.h"
+#include "backends/audio.h"
 #include "backends/rtmidi.h"
 #include "backends/serialport.h"
+#include "backends/usb.h"
 #include "config.h"
 #include "gamecontrollers.h"
 #include "render.h"
-#include "audio.h"
 #include <SDL3/SDL.h>
 
 uint8_t keyjazz_enabled = 0;
@@ -26,16 +27,16 @@
   case normal:
     if (input.value != prev_input) {
       prev_input = input.value;
-      send_msg_controller(input.value);
+      m8_send_msg_controller(input.value);
     }
     break;
   case keyjazz:
     if (input.value != 0) {
       if (input.eventType == SDL_EVENT_KEY_DOWN && input.value != prev_input) {
-        send_msg_keyjazz(input.value, input.value2);
+        m8_send_msg_keyjazz(input.value, input.value2);
         prev_note = input.value;
       } else if (input.eventType == SDL_EVENT_KEY_UP && input.value == prev_note) {
-        send_msg_keyjazz(0xFF, 0);
+        m8_send_msg_keyjazz(0xFF, 0);
       }
     }
     prev_input = input.value;
@@ -49,7 +50,7 @@
         *app_state = 0;
         break;
       case msg_reset_display:
-        reset_display();
+        m8_reset_display();
         break;
       case msg_toggle_audio:
         conf.audio_enabled = !conf.audio_enabled;
--- a/src/main.c
+++ b/src/main.c
@@ -9,9 +9,10 @@
 #include <signal.h>
 
 #include "SDL2_inprint.h"
-#include "audio.h"
+#include "backends/audio.h"
 #include "backends/rtmidi.h"
 #include "backends/serialport.h"
+#include "backends/usb.h"
 #include "command.h"
 #include "config.h"
 #include "gamecontrollers.h"
@@ -21,8 +22,63 @@
 enum app_state app_state = WAIT_FOR_DEVICE;
 
 // Handle CTRL+C / SIGINT, SIGKILL etc.
-void signal_handler(int unused) { (void)unused; app_state = QUIT; }
+void signal_handler(int unused) {
+  (void)unused;
+  app_state = QUIT;
+}
 
+void do_wait_for_device(const char *preferred_device, unsigned char *m8_connected,
+                        config_params_s *conf) {
+  static Uint64 ticks_poll_device = 0;
+  static Uint64 ticks_update_screen = 0;
+
+  if (*m8_connected == 0) {
+    screensaver_init();
+  }
+
+  while (app_state == WAIT_FOR_DEVICE) {
+    // get current input
+    const input_msg_s input = input_get_msg(&*conf);
+    if (input.type == special && input.value == msg_quit) {
+      SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Input message QUIT.");
+      app_state = QUIT;
+    }
+
+    if (SDL_GetTicks() - ticks_update_screen > 16) {
+      ticks_update_screen = SDL_GetTicks();
+      screensaver_draw();
+      render_screen();
+    }
+
+    // Poll for M8 device every second
+    if (*m8_connected == 0 && SDL_GetTicks() - ticks_poll_device > 1000) {
+      ticks_poll_device = SDL_GetTicks();
+      if (app_state == WAIT_FOR_DEVICE && m8_initialize(0, preferred_device) == 1) {
+
+        if (conf->audio_enabled == 1) {
+          if (audio_initialize(conf->audio_device_name, conf->audio_buffer_size) == 0) {
+            SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Cannot initialize audio");
+            conf->audio_enabled = 0;
+          }
+        }
+
+        const int m8_enabled = m8_enable_and_reset_display();
+        // Device was found; enable display and proceed to the main loop
+        if (m8_enabled == 1) {
+          app_state = RUN;
+          *m8_connected = 1;
+          screensaver_destroy();
+        } else {
+          SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Device not detected.");
+          app_state = QUIT;
+          screensaver_destroy();
+        }
+      }
+    }
+    SDL_Delay(conf->idle_ms);
+  }
+}
+
 int main(const int argc, char *argv[]) {
 
   char *preferred_device = NULL;
@@ -57,7 +113,7 @@
   // First device detection to avoid SDL init if it isn't necessary. To be run
   // only if we shouldn't wait for M8 to be connected.
   if (conf.wait_for_device == 0) {
-    m8_connected = m8_connect(1, preferred_device);
+    m8_connected = m8_initialize(1, preferred_device);
     if (m8_connected == 0) {
       return 1;
     }
@@ -75,18 +131,18 @@
 
 #ifndef NDEBUG
   SDL_SetLogPriorities(SDL_LOG_PRIORITY_DEBUG);
-  SDL_LogDebug(SDL_LOG_CATEGORY_TEST,"Running a Debug build");
+  SDL_LogDebug(SDL_LOG_CATEGORY_TEST, "Running a Debug build");
 #endif
 
   // main loop begin
   do {
     // try to init connection to M8
-    m8_connected = m8_connect(1, preferred_device);
-    if (m8_connected == 1 && enable_and_reset_display() == 1) {
+    m8_connected = m8_initialize(1, preferred_device);
+    if (m8_connected == 1 && m8_enable_and_reset_display() == 1) {
       if (conf.audio_enabled == 1) {
         audio_initialize(conf.audio_device_name, conf.audio_buffer_size);
         // if audio is enabled, reset the display for second time to avoid glitches
-        reset_display();
+        m8_reset_display();
       }
       app_state = RUN;
     } else {
@@ -100,54 +156,7 @@
 
     // wait until device is connected
     if (conf.wait_for_device == 1) {
-      static Uint64 ticks_poll_device = 0;
-      static Uint64 ticks_update_screen = 0;
-
-      if (m8_connected == 0) {
-        screensaver_init();
-      }
-
-      while (app_state == WAIT_FOR_DEVICE) {
-        // get current input
-        const input_msg_s input = input_get_msg(&conf);
-        if (input.type == special && input.value == msg_quit) {
-          SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Input message QUIT.");
-          app_state = QUIT;
-        }
-
-        if (SDL_GetTicks() - ticks_update_screen > 16) {
-          ticks_update_screen = SDL_GetTicks();
-          screensaver_draw();
-          render_screen();
-        }
-
-        // Poll for M8 device every second
-        if (m8_connected == 0 && SDL_GetTicks() - ticks_poll_device > 1000) {
-          ticks_poll_device = SDL_GetTicks();
-          if (app_state == WAIT_FOR_DEVICE && m8_connect(0, preferred_device) == 1) {
-
-            if (conf.audio_enabled == 1) {
-              if (audio_initialize(conf.audio_device_name, conf.audio_buffer_size) == 0) {
-                SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Cannot initialize audio");
-                conf.audio_enabled = 0;
-              }
-            }
-
-            const int result = enable_and_reset_display();
-            // Device was found; enable display and proceed to the main loop
-            if (result == 1) {
-              app_state = RUN;
-              m8_connected = 1;
-              screensaver_destroy();
-            } else {
-              SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Device not detected.");
-              app_state = QUIT;
-              screensaver_destroy();
-            }
-          }
-        }
-        SDL_Delay(conf.idle_ms);
-      }
+      do_wait_for_device(preferred_device, &m8_connected, &conf);
     } else {
       // classic startup behaviour, exit if device is not found
       if (m8_connected == 0) {
@@ -165,7 +174,7 @@
     // main loop
     while (app_state == RUN) {
       input_process(conf, &app_state);
-      const int result = process_serial(conf);
+      const int result = m8_process_data(conf);
       if (result == 0) {
         // Device disconnected
         m8_connected = 0;
--