Skip to content

Commit 1b4aea2

Browse files
authored
feat(midi): Enhance USBMIDI device name handling
1 parent b7b61c3 commit 1b4aea2

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

libraries/USB/src/USBMIDI.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
#include "esp32-hal-tinyusb.h"
88

99
// Initialize static members
10-
const char* USBMIDI::deviceName = nullptr;
11-
char USBMIDI::nameBuffer[32] = {0};
10+
char* USBMIDI::midiUserDeviceName = nullptr;
11+
// Weak definition of getUSBMIDIDefaultDeviceName to provide a default name
12+
__attribute__((weak)) const char* getUSBMIDIDefaultDeviceName() {
13+
return ESP32_USB_MIDI_DEFAULT_NAME;
14+
}
1215

1316
// Default Cable Number (for simplified APIs that do not expose this)
1417
#define DEFAULT_CN 0
@@ -45,21 +48,63 @@ USBMIDI::USBMIDI() {
4548
}
4649
}
4750

51+
52+
void USBMIDI::setDeviceName(const char* name) {
53+
const uint8_t maxNameLength = 32; // tinyUSB Descriptor limit
54+
if (name != nullptr && strlen(name) > 0) {
55+
if (strlen(name) > maxNameLength) {
56+
log_w("USBMIDI: Device name too long, truncating to %d characters.", maxNameLength);
57+
}
58+
midiUserDeviceName = new char[maxNameLength + 1]; // +1 for null-terminator
59+
if (midiUserDeviceName) {
60+
strncpy(midiUserDeviceName, name, maxNameLength);
61+
// Ensure null-termination when overflowing
62+
midiUserDeviceName[maxNameLength] = '\0';
63+
} else {
64+
log_e("USBMIDI: Failed to allocate memory for device name, using default name.");
65+
}
66+
} else {
67+
log_w("USBMIDI: No device name provided, using default name [%s].", getUSBMIDIDefaultDeviceName());
68+
}
69+
}
70+
4871
USBMIDI::USBMIDI(const char* name) {
4972
if (!tinyusb_midi_interface_enabled) {
50-
strncpy(nameBuffer, name, sizeof(nameBuffer) - 1);
51-
nameBuffer[sizeof(nameBuffer) - 1] = '\0';
52-
deviceName = nameBuffer;
73+
setDeviceName(name);
5374
tinyusb_midi_interface_enabled = true;
5475
tinyusb_enable_interface(USB_INTERFACE_MIDI, TUD_MIDI_DESC_LEN, tusb_midi_load_descriptor);
5576
} else {
5677
log_e("USBMIDI: Multiple instances of USBMIDI not supported!");
5778
}
5879
}
5980

81+
USBMIDI::~USBMIDI() {
82+
if (midiUserDeviceName) {
83+
delete[] midiUserDeviceName;
84+
midiUserDeviceName = nullptr;
85+
}
86+
}
87+
6088
void USBMIDI::begin() {}
6189
void USBMIDI::end() {}
6290

91+
/**
92+
* @brief Get the current device name
93+
* @return The device name in order of precedence:
94+
* 1. Name set via constructor (if any)
95+
* 2. Name set via SET_USB_MIDI_DEVICE_NAME() macro (if defined)
96+
* 3. Default name "TinyUSB MIDI"
97+
* If device name is set as "", it will be ignored
98+
*/
99+
const char* USBMIDI::getCurrentDeviceName(void) {
100+
if (midiUserDeviceName) {
101+
return midiUserDeviceName;
102+
}
103+
// If no user name set, use the compile-time default name limited to 32 characters
104+
setDeviceName(getUSBMIDIDefaultDeviceName());
105+
return strlen(midiUserDeviceName) ? midiUserDeviceName : "TinyUSB MIDI";
106+
}
107+
63108
// uint compatible version of constrain
64109
#define uconstrain(amt, low, high) ((amt) <= (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
65110

0 commit comments

Comments
 (0)