diff --git a/cores/esp32/Arduino.h b/cores/esp32/Arduino.h index 9048249a873..b5c5a456abf 100644 --- a/cores/esp32/Arduino.h +++ b/cores/esp32/Arduino.h @@ -222,6 +222,22 @@ size_t getArduinoLoopTaskStackSize(void); return sz; \ } +#define ESP32_USB_MIDI_DEFAULT_NAME "TinyUSB MIDI" +/** +* @brief Set the current device name +* 1. Name set via constructor (if any) +* 2. Name set via SET_USB_MIDI_DEVICE_NAME() macro (if defined) +* 3. Default name "TinyUSB MIDI" +* If device name is set as "", it will be ignored +*/ +#define SET_USB_MIDI_DEVICE_NAME(name) \ + const char *getUSBMIDIDefaultDeviceName() { \ + if (!name || strlen(name) == 0) { \ + return ESP32_USB_MIDI_DEFAULT_NAME; \ + } \ + return name; \ + } + bool shouldPrintChipDebugReport(void); #define ENABLE_CHIP_DEBUG_REPORT \ bool shouldPrintChipDebugReport(void) { \ diff --git a/libraries/USB/examples/MIDI/MidiController/MidiController.ino b/libraries/USB/examples/MIDI/MidiController/MidiController.ino index 2871d3b1a52..9cdd8a805de 100644 --- a/libraries/USB/examples/MIDI/MidiController/MidiController.ino +++ b/libraries/USB/examples/MIDI/MidiController/MidiController.ino @@ -20,7 +20,8 @@ void loop() {} #include "USB.h" #include "USBMIDI.h" -USBMIDI MIDI; +// Creates the MIDI device with specific descriptor +USBMIDI MIDI("ESP MIDI Device"); #define MIDI_NOTE_C4 60 diff --git a/libraries/USB/examples/MIDI/MidiInterface/MidiInterface.ino b/libraries/USB/examples/MIDI/MidiInterface/MidiInterface.ino index e3ad1c4e028..e118d5ddb9a 100644 --- a/libraries/USB/examples/MIDI/MidiInterface/MidiInterface.ino +++ b/libraries/USB/examples/MIDI/MidiInterface/MidiInterface.ino @@ -24,8 +24,12 @@ void setup() {} void loop() {} #else +// define a new USB MIDI device name using a macro +SET_USB_MIDI_DEVICE_NAME("ESP MIDI Device") + #include "USB.h" #include "USBMIDI.h" +// Creates the MIDI device with specific name defined with the SET_USB_MIDI_DEVICE_NAME() macro USBMIDI MIDI; #define MIDI_RX 39 diff --git a/libraries/USB/src/USBMIDI.cpp b/libraries/USB/src/USBMIDI.cpp index 92b4e28edcf..61b75f0144d 100644 --- a/libraries/USB/src/USBMIDI.cpp +++ b/libraries/USB/src/USBMIDI.cpp @@ -6,6 +6,13 @@ #include "Arduino.h" #include "esp32-hal-tinyusb.h" +// Initialize static members +char *USBMIDI::midiUserDeviceName = nullptr; +// Weak definition of getUSBMIDIDefaultDeviceName to provide a default name +__attribute__((weak)) const char *getUSBMIDIDefaultDeviceName() { + return ESP32_USB_MIDI_DEFAULT_NAME; +} + // Default Cable Number (for simplified APIs that do not expose this) #define DEFAULT_CN 0 @@ -18,7 +25,7 @@ extern "C" uint16_t tusb_midi_load_descriptor(uint8_t *dst, uint8_t *itf) { } tinyusb_midi_descriptor_loaded = true; - uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB MIDI"); + uint8_t str_index = tinyusb_add_string_descriptor(USBMIDI::getCurrentDeviceName()); uint8_t ep_in = tinyusb_get_free_in_endpoint(); TU_VERIFY(ep_in != 0); uint8_t ep_out = tinyusb_get_free_out_endpoint(); @@ -41,9 +48,68 @@ USBMIDI::USBMIDI() { } } +// private function for setting a not null/empty MIDI device name limited to 32 characters +void USBMIDI::setDeviceName(const char *name) { + const uint8_t maxNameLength = 32; // tinyUSB Descriptor limit + if (name != nullptr && strlen(name)> 0) { + if (strlen(name)> maxNameLength) { + log_w("USBMIDI: Device name too long, truncating to %d characters.", maxNameLength); + } + if (!midiUserDeviceName) { + midiUserDeviceName = new char[maxNameLength + 1]; // +1 for null-terminator + } + if (midiUserDeviceName) { + strncpy(midiUserDeviceName, name, maxNameLength); + // Ensure null-termination when overflowing + midiUserDeviceName[maxNameLength] = '0円'; + } else { + log_e("USBMIDI: Failed to allocate memory for device name, using default name."); + } + } else { + log_w("USBMIDI: No device name provided, using default name [%s].", getUSBMIDIDefaultDeviceName()); + } +} + +/** +* @brief Constructor for setting the current device name +* 1. Name set via constructor (if any) +* 2. Name set via SET_USB_MIDI_DEVICE_NAME() macro (if defined) +* 3. Default name "TinyUSB MIDI" +* If device name is set as "", it will be ignored +*/ +USBMIDI::USBMIDI(const char *name) { + if (!tinyusb_midi_interface_enabled) { + setDeviceName(name); + tinyusb_midi_interface_enabled = true; + tinyusb_enable_interface(USB_INTERFACE_MIDI, TUD_MIDI_DESC_LEN, tusb_midi_load_descriptor); + } else { + log_e("USBMIDI: Multiple instances of USBMIDI not supported!"); + } +} + +USBMIDI::~USBMIDI() { + if (midiUserDeviceName) { + delete[] midiUserDeviceName; + midiUserDeviceName = nullptr; + } +} + void USBMIDI::begin() {} void USBMIDI::end() {} +const char *USBMIDI::getCurrentDeviceName(void) { + if (midiUserDeviceName) { + return midiUserDeviceName; + } + // If no user name set, use the compile-time default name limited to 32 characters + setDeviceName(getUSBMIDIDefaultDeviceName()); + if (midiUserDeviceName && strlen(midiUserDeviceName)) { + return midiUserDeviceName; + } else { + return "TinyUSB MIDI"; + } +} + // uint compatible version of constrain #define uconstrain(amt, low, high) ((amt) <= (low) ? (low) : ((amt)> (high) ? (high) : (amt))) diff --git a/libraries/USB/src/USBMIDI.h b/libraries/USB/src/USBMIDI.h index 91a1bfa4be1..8f111dbfd4a 100644 --- a/libraries/USB/src/USBMIDI.h +++ b/libraries/USB/src/USBMIDI.h @@ -18,11 +18,41 @@ typedef struct { } midiEventPacket_t; class USBMIDI { +private: + static char *midiUserDeviceName; // user device name + static void setDeviceName(const char *name); // set user device name limited to 32 characters + public: + /** + * @brief Default constructor + * Will use the compile-time name if set via SET_USB_MIDI_DEVICE_NAME(), + * otherwise uses "TinyUSB MIDI" + */ USBMIDI(void); + + /** + * @brief Set the current device name + * 1. Name set via constructor (if any) + * 2. Name set via SET_USB_MIDI_DEVICE_NAME() macro (if defined) + * 3. Default name "TinyUSB MIDI" + * It has no effect if name is set as NULL or "" + */ + USBMIDI(const char *name); + + ~USBMIDI(); + void begin(void); void end(void); + /** + * @brief Get the current device name + * @return The device name in order of precedence: + * 1. Name set via constructor (if any) + * 2. Name set via SET_USB_MIDI_DEVICE_NAME() macro (if defined) + * 3. Default name "TinyUSB MIDI" + */ + static const char *getCurrentDeviceName(void); + /* User-level API */ // Note On

AltStyle によって変換されたページ (->オリジナル) /