Skip to content

Commit 03a2e72

Browse files
committed
Make USB MIDI interface names customizable
1 parent 8027efe commit 03a2e72

File tree

3 files changed

+176
-10
lines changed

3 files changed

+176
-10
lines changed

shared-bindings/usb_midi/__init__.c

Lines changed: 138 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,145 @@ STATIC mp_obj_t usb_midi_enable(void) {
7878
}
7979
MP_DEFINE_CONST_FUN_OBJ_0(usb_midi_enable_obj, usb_midi_enable);
8080

81+
//| def set_streaming_interface_name(interface_name: str) -> None:
82+
//| """Override the MIDI interface name in the USB Interface Descriptor.
83+
//|
84+
//| ``interface_name`` must be an ASCII string (or buffer) of at most 126 characters.
85+
//|
86+
//| This method must be called in boot.py to have any effect.
87+
//|
88+
//| Not available on boards without native USB support.
89+
//| """
90+
//| ...
91+
//|
92+
STATIC mp_obj_t usb_midi_set_streaming_interface_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
93+
static const mp_arg_t allowed_args[] = {
94+
{ MP_QSTR_interface_name, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = mp_const_none} }
95+
};
96+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
97+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
98+
99+
mp_buffer_info_t interface_name;
100+
mp_get_buffer_raise(args[0].u_obj, &interface_name, MP_BUFFER_READ);
101+
mp_arg_validate_length_range(interface_name.len, 1, 126, MP_QSTR_interface_name);
102+
103+
if (custom_usb_midi_streaming_interface_name == NULL) {
104+
custom_usb_midi_streaming_interface_name = port_malloc(sizeof(char) * 128, false);
105+
}
106+
memcpy(custom_usb_midi_streaming_interface_name, interface_name.buf, interface_name.len);
107+
custom_usb_midi_streaming_interface_name[interface_name.len] = 0;
108+
109+
return mp_const_none;
110+
}
111+
MP_DEFINE_CONST_FUN_OBJ_KW(usb_midi_set_streaming_interface_name_obj, 1, usb_midi_set_streaming_interface_name);
112+
113+
//| def set_audio_control_interface_name(interface_name: str) -> None:
114+
//| """Override the audio control interface name in the USB Interface Descriptor.
115+
//|
116+
//| ``interface_name`` must be an ASCII string (or buffer) of at most 126 characters.
117+
//|
118+
//| This method must be called in boot.py to have any effect.
119+
//|
120+
//| Not available on boards without native USB support.
121+
//| """
122+
//| ...
123+
//|
124+
STATIC mp_obj_t usb_midi_set_audio_control_interface_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
125+
static const mp_arg_t allowed_args[] = {
126+
{ MP_QSTR_interface_name, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = mp_const_none} }
127+
};
128+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
129+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
130+
131+
mp_buffer_info_t interface_name;
132+
mp_get_buffer_raise(args[0].u_obj, &interface_name, MP_BUFFER_READ);
133+
mp_arg_validate_length_range(interface_name.len, 1, 126, MP_QSTR_interface_name);
134+
135+
if (custom_usb_midi_audio_control_interface_name == NULL) {
136+
custom_usb_midi_audio_control_interface_name = port_malloc(sizeof(char) * 128, false);
137+
}
138+
memcpy(custom_usb_midi_audio_control_interface_name, interface_name.buf, interface_name.len);
139+
custom_usb_midi_audio_control_interface_name[interface_name.len] = 0;
140+
141+
return mp_const_none;
142+
}
143+
MP_DEFINE_CONST_FUN_OBJ_KW(usb_midi_set_audio_control_interface_name_obj, 1, usb_midi_set_audio_control_interface_name);
144+
145+
//| def set_in_jack_name(jack_name: str) -> None:
146+
//| """Override the MIDI IN jack name in the USB Interface Descriptor.
147+
//|
148+
//| ``jack_name`` must be an ASCII string (or buffer) of at most 126 characters.
149+
//|
150+
//| This method must be called in boot.py to have any effect.
151+
//|
152+
//| Not available on boards without native USB support.
153+
//| """
154+
//| ...
155+
//|
156+
STATIC mp_obj_t usb_midi_set_in_jack_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
157+
static const mp_arg_t allowed_args[] = {
158+
{ MP_QSTR_jack_name, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = mp_const_none} }
159+
};
160+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
161+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
162+
163+
mp_buffer_info_t jack_name;
164+
mp_get_buffer_raise(args[0].u_obj, &jack_name, MP_BUFFER_READ);
165+
mp_arg_validate_length_range(jack_name.len, 1, 126, MP_QSTR_jack_name);
166+
167+
if (custom_usb_midi_in_jack_name == NULL) {
168+
custom_usb_midi_in_jack_name = port_malloc(sizeof(char) * 128, false);
169+
}
170+
memcpy(custom_usb_midi_in_jack_name, jack_name.buf, jack_name.len);
171+
custom_usb_midi_in_jack_name[jack_name.len] = 0;
172+
173+
return mp_const_none;
174+
}
175+
MP_DEFINE_CONST_FUN_OBJ_KW(usb_midi_set_in_jack_name_obj, 1, usb_midi_set_in_jack_name);
176+
177+
//| def set_out_jack_name(jack_name: str) -> None:
178+
//| """Override the MIDI OUT jack name in the USB Interface Descriptor.
179+
//|
180+
//| ``jack_name`` must be an ASCII string (or buffer) of at most 126 characters.
181+
//|
182+
//| This method must be called in boot.py to have any effect.
183+
//|
184+
//| Not available on boards without native USB support.
185+
//| """
186+
//| ...
187+
//|
188+
STATIC mp_obj_t usb_midi_set_out_jack_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
189+
static const mp_arg_t allowed_args[] = {
190+
{ MP_QSTR_jack_name, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = mp_const_none} }
191+
};
192+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
193+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
194+
195+
mp_buffer_info_t jack_name;
196+
mp_get_buffer_raise(args[0].u_obj, &jack_name, MP_BUFFER_READ);
197+
mp_arg_validate_length_range(jack_name.len, 1, 126, MP_QSTR_jack_name);
198+
199+
if (custom_usb_midi_out_jack_name == NULL) {
200+
custom_usb_midi_out_jack_name = port_malloc(sizeof(char) * 128, false);
201+
}
202+
memcpy(custom_usb_midi_out_jack_name, jack_name.buf, jack_name.len);
203+
custom_usb_midi_out_jack_name[jack_name.len] = 0;
204+
205+
return mp_const_none;
206+
}
207+
MP_DEFINE_CONST_FUN_OBJ_KW(usb_midi_set_out_jack_name_obj, 1, usb_midi_set_out_jack_name);
208+
81209
mp_map_elem_t usb_midi_module_globals_table[] = {
82-
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) },
83-
{ MP_ROM_QSTR(MP_QSTR_disable), MP_OBJ_FROM_PTR(&usb_midi_disable_obj) },
84-
{ MP_ROM_QSTR(MP_QSTR_enable), MP_OBJ_FROM_PTR(&usb_midi_enable_obj) },
85-
{ MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple },
86-
{ MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) },
87-
{ MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) },
210+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) },
211+
{ MP_ROM_QSTR(MP_QSTR_disable), MP_OBJ_FROM_PTR(&usb_midi_disable_obj) },
212+
{ MP_ROM_QSTR(MP_QSTR_enable), MP_OBJ_FROM_PTR(&usb_midi_enable_obj) },
213+
{ MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple },
214+
{ MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) },
215+
{ MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) },
216+
{ MP_ROM_QSTR(MP_QSTR_set_streaming_interface_name), MP_OBJ_FROM_PTR(&usb_midi_set_streaming_interface_name_obj) },
217+
{ MP_ROM_QSTR(MP_QSTR_set_audio_control_interface_name), MP_OBJ_FROM_PTR(&usb_midi_set_audio_control_interface_name_obj) },
218+
{ MP_ROM_QSTR(MP_QSTR_set_in_jack_name), MP_OBJ_FROM_PTR(&usb_midi_set_in_jack_name_obj) },
219+
{ MP_ROM_QSTR(MP_QSTR_set_out_jack_name), MP_OBJ_FROM_PTR(&usb_midi_set_out_jack_name_obj) },
88220
};
89221

90222
// This isn't const so we can set ports dynamically.

shared-module/usb_midi/__init__.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,17 @@ size_t usb_midi_descriptor_length(void) {
177177
return sizeof(usb_midi_descriptor_template);
178178
}
179179

180-
static const char midi_streaming_interface_name[] = USB_INTERFACE_NAME " MIDI";
181-
static const char midi_audio_control_interface_name[] = USB_INTERFACE_NAME " Audio";
182-
static const char midi_in_jack_name[] = USB_INTERFACE_NAME " usb_midi.ports[0]";
183-
static const char midi_out_jack_name[] = USB_INTERFACE_NAME " usb_midi.ports[0]";
180+
char *custom_usb_midi_streaming_interface_name;
181+
char *custom_usb_midi_audio_control_interface_name;
182+
char *custom_usb_midi_in_jack_name;
183+
char *custom_usb_midi_out_jack_name;
184184

185185
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) {
186+
const char *midi_streaming_interface_name;
187+
const char *midi_audio_control_interface_name;
188+
const char *midi_in_jack_name;
189+
const char *midi_out_jack_name;
190+
186191
memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template));
187192

188193
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = descriptor_counts->current_interface;
@@ -200,18 +205,42 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *des
200205
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = descriptor_counts->current_interface;
201206
descriptor_counts->current_interface++;
202207

208+
if (custom_usb_midi_streaming_interface_name == NULL) {
209+
midi_streaming_interface_name = USB_INTERFACE_NAME " MIDI";
210+
} else {
211+
midi_streaming_interface_name = custom_usb_midi_streaming_interface_name;
212+
}
213+
203214
usb_add_interface_string(*current_interface_string, midi_streaming_interface_name);
204215
descriptor_buf[MIDI_STREAMING_INTERFACE_STRING_INDEX] = *current_interface_string;
205216
(*current_interface_string)++;
206217

218+
if (custom_usb_midi_audio_control_interface_name == NULL) {
219+
midi_audio_control_interface_name = USB_INTERFACE_NAME " Audio";
220+
} else {
221+
midi_audio_control_interface_name = custom_usb_midi_audio_control_interface_name;
222+
}
223+
207224
usb_add_interface_string(*current_interface_string, midi_audio_control_interface_name);
208225
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = *current_interface_string;
209226
(*current_interface_string)++;
210227

228+
if (custom_usb_midi_in_jack_name == NULL) {
229+
midi_in_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]";
230+
} else {
231+
midi_in_jack_name = custom_usb_midi_in_jack_name;
232+
}
233+
211234
usb_add_interface_string(*current_interface_string, midi_in_jack_name);
212235
descriptor_buf[MIDI_IN_JACK_STRING_INDEX] = *current_interface_string;
213236
(*current_interface_string)++;
214237

238+
if (custom_usb_midi_out_jack_name == NULL) {
239+
midi_out_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]";
240+
} else {
241+
midi_out_jack_name = custom_usb_midi_out_jack_name;
242+
}
243+
215244
usb_add_interface_string(*current_interface_string, midi_out_jack_name);
216245
descriptor_buf[MIDI_OUT_JACK_STRING_INDEX] = *current_interface_string;
217246
(*current_interface_string)++;

shared-module/usb_midi/__init__.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,9 @@ void usb_midi_setup_ports(void);
3636
size_t usb_midi_descriptor_length(void);
3737
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string);
3838

39+
extern char *custom_usb_midi_streaming_interface_name;
40+
extern char *custom_usb_midi_audio_control_interface_name;
41+
extern char *custom_usb_midi_in_jack_name;
42+
extern char *custom_usb_midi_out_jack_name;
43+
3944
#endif /* SHARED_MODULE_USB_MIDI___INIT___H */

0 commit comments

Comments
 (0)