Skip to content

Commit 8dab8c4

Browse files
committed
Added USBMIDI tests + bugfix MIDI OUT
1 parent 20759f0 commit 8dab8c4

File tree

3 files changed

+147
-4
lines changed

3 files changed

+147
-4
lines changed

libraries/USBDevice/USBMIDI/USBMIDI.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ void USBMIDI::write(MIDIMessage m) {
3131
for(int p=1; p < m.length; p+=3) {
3232
uint8_t buf[4];
3333
// Midi message to USBMidi event packet
34-
buf[0]=m.data[p] >> 4;
34+
buf[0]=m.data[1] >> 4;
3535
// SysEx
3636
if(buf[0] == 0xF) {
37-
if(p < m.length-1) {
37+
if((m.length - p) > 3) {
3838
// SysEx start or continue
3939
buf[0]=0x4;
4040
} else {
@@ -55,8 +55,16 @@ void USBMIDI::write(MIDIMessage m) {
5555
}
5656
}
5757
buf[1]=m.data[p];
58-
buf[2]=m.data[p+1];
59-
buf[3]=m.data[p+2];
58+
59+
if(p+1 < m.length)
60+
buf[2]=m.data[p+1];
61+
else
62+
buf[2]=0;
63+
64+
if(p+2 < m.length)
65+
buf[3]=m.data[p+2];
66+
else
67+
buf[3]=0;
6068

6169
USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK);
6270
}

libraries/tests/usb/device/midi/main.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,70 @@
44
USBMIDI midi;
55
Serial pc(USBTX, USBRX);
66

7+
// MIDI IN
8+
void transmitMessage(MIDIMessage msg) {
9+
switch (msg.type()) {
10+
case MIDIMessage::NoteOnType:
11+
wait(0.1);
12+
midi.write(MIDIMessage::NoteOn(msg.key()));
13+
break;
14+
case MIDIMessage::NoteOffType:
15+
wait(0.1);
16+
midi.write(MIDIMessage::NoteOff(msg.key()));
17+
break;
18+
case MIDIMessage::ProgramChangeType:
19+
wait(0.1);
20+
midi.write(MIDIMessage::ProgramChange(msg.program()));
21+
break;
22+
case MIDIMessage::SysExType:
23+
wait(0.1);
24+
unsigned char tmp[64];
25+
for(int i=0;i<msg.length-1;i++) {
26+
tmp[i]=msg.data[i+1];
27+
}
28+
midi.write(MIDIMessage::SysEx(tmp,msg.length-1));
29+
break;
30+
default:
31+
break;
32+
}
33+
}
34+
735
int main(void)
836
{
37+
wait(5);
38+
// MIDI OUT
39+
40+
// set piano
41+
midi.write(MIDIMessage::ProgramChange(1));
42+
wait(0.1);
43+
44+
// play A
45+
midi.write(MIDIMessage::NoteOn(21));
46+
wait(0.1);
47+
midi.write(MIDIMessage::NoteOff(21));
48+
wait(0.1);
49+
50+
// GM reset
51+
unsigned char gm_reset[]={0xF0,0x7E,0x7F,0x09,0x01,0xF7};
52+
midi.write(MIDIMessage::SysEx(gm_reset,6));
53+
wait(0.1);
54+
55+
// GM Master volume max
56+
unsigned char gm_master_vol_max[]={0xF0,0x7F,0x7F,0x04,0x01,0x7F,0x7F,0xF7};
57+
midi.write(MIDIMessage::SysEx(gm_master_vol_max,8));
58+
wait(0.1);
59+
60+
// GS reset
61+
unsigned char gs_reset[]={0xF0,0x41,0x10,0x42,0x12,0x40,0x00,0x7F,0x00,0x41,0xF7};
62+
midi.write(MIDIMessage::SysEx(gs_reset,11));
63+
wait(0.1);
64+
65+
// GS Master volume max
66+
unsigned char gs_master_vol_max[]={0xF0,0x41,0x10,0x42,0x12,0x40,0x00,0x04,0x7F,0x3D,0xF7};
67+
midi.write(MIDIMessage::SysEx(gs_master_vol_max,11));
68+
wait(0.1);
69+
70+
midi.attach(transmitMessage);
71+
972
while(1);
1073
}

workspace_tools/host_tests/midi.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from __future__ import print_function
2+
import sys
3+
import re
4+
import time
5+
import mido
6+
from mido import Message
7+
8+
9+
def test_midi_in(port):
10+
expected_messages_count=0
11+
while expected_messages_count < 7:
12+
for message in port.iter_pending():
13+
if message.type in ('note_on', 'note_off', 'program_change', 'sysex'):
14+
yield message
15+
expected_messages_count+=1
16+
time.sleep(0.1)
17+
18+
def test_midi_loopback(input_port):
19+
expected_messages_count=0
20+
while expected_messages_count < 1:
21+
for message in input_port.iter_pending():
22+
print('Test MIDI OUT loopback received {}'.format(message.hex()))
23+
expected_messages_count+=1
24+
25+
def test_midi_out_loopback(output_port,input_port):
26+
print("Test MIDI OUT loopback")
27+
output_port.send(Message('program_change', program=1))
28+
test_midi_loopback(input_port)
29+
30+
output_port.send(Message('note_on', note=21))
31+
test_midi_loopback(input_port)
32+
33+
output_port.send(Message('note_off', note=21))
34+
test_midi_loopback(input_port)
35+
36+
output_port.send(Message('sysex', data=[0x7E,0x7F,0x09,0x01]))
37+
test_midi_loopback(input_port)
38+
39+
output_port.send(Message('sysex', data=[0x7F,0x7F,0x04,0x01,0x7F,0x7F]))
40+
test_midi_loopback(input_port)
41+
42+
output_port.send(Message('sysex', data=[0x41,0x10,0x42,0x12,0x40,0x00,0x7F,0x00,0x41]))
43+
test_midi_loopback(input_port)
44+
45+
output_port.send(Message('sysex', data=[0x41,0x10,0x42,0x12,0x40,0x00,0x04,0x7F,0x3D]))
46+
test_midi_loopback(input_port)
47+
48+
portname=""
49+
50+
while portname=="":
51+
print("Wait for MIDI IN plug ...")
52+
for name in mido.get_input_names():
53+
matchObj = re.match( r'Mbed', name)
54+
55+
if matchObj:
56+
portname=name
57+
time.sleep( 1 )
58+
59+
try:
60+
input_port = mido.open_input(portname)
61+
output_port = mido.open_output(portname)
62+
63+
print('Using {}'.format(input_port))
64+
65+
print("Test MIDI IN")
66+
67+
for message in test_midi_in(input_port):
68+
print('Test MIDI IN received {}'.format(message.hex()))
69+
70+
test_midi_out_loopback(output_port,input_port)
71+
except KeyboardInterrupt:
72+
pass

0 commit comments

Comments
 (0)