USB MIDI Interface
dear horo,
I've studied your project
and now I can implement the USB-MIDI In already
next step,
how Can I do the USB-MIDI-Out
(Host send midi data to AVR
and AVR Generate MIDI out to UART TX @31250bps)
And I've read the MIDI10.pdf
and found that it is possible to do the
multiple midi port on one USB
how can I do this?
thank you
I've studied your project
and now I can implement the USB-MIDI In already
next step,
how Can I do the USB-MIDI-Out
(Host send midi data to AVR
and AVR Generate MIDI out to UART TX @31250bps)
And I've read the MIDI10.pdf
and found that it is possible to do the
multiple midi port on one USB
how can I do this?
thank you
Hi hs4pmh,
I didn't implement midi out but pat did it - look about 5 postings ^above^. He used a piece of code from http://x37v.info/projects/microcontroll ... idi/files/
Concerning multi midi the doc midi10.pdf (p.13) says:
So you have to define the number of endpoints and the endpoints in your descriptor starting from section B.4 in my source code - it's a bit trial and error. It would help if you draw the connections from endpoint to internal and external midi jack to understand the data flow (look for bJackID, BaSourceID and baAssocJackID). You connect an embedded midi in to an external midi out and vice versa.
Ciao Martin
I didn't implement midi out but pat did it - look about 5 postings ^above^. He used a piece of code from http://x37v.info/projects/microcontroll ... idi/files/
Concerning multi midi the doc midi10.pdf (p.13) says:
USB-MIDI converters can connect to multiple Embedded MIDI Jacks. Each MIDI Endpoint in a USB-MIDI
converter can be connected to up to 16 Embedded MIDI Jacks. Each Embedded MIDI Jack connected to one
MIDI Endpoint is assigned a number from 0 to 15. MIDI Data is transferred over the USB in 32-bit USBMIDI
Event Packets, with the first 4 bits used to designate the appropriate Embedded MIDI Jack.
So you have to define the number of endpoints and the endpoints in your descriptor starting from section B.4 in my source code - it's a bit trial and error. It would help if you draw the connections from endpoint to internal and external midi jack to understand the data flow (look for bJackID, BaSourceID and baAssocJackID). You connect an embedded midi in to an external midi out and vice versa.
Ciao Martin
Re: USB MIDI Interface
hi martin,
i am very happy to say that i am now using an atmega164p (new version of atmega16). it's cheaper and faster (20 mhz). i want to ask you a question about optimization for the usb communication. here's my function that send the noteon, noteoff:
this function takes 8ms to finish (i am running the obdev usb firmware at 20mhz). sending all 8 ADC takes 8ms * 8 = 64ms. long enough to miss an hit (i'm making an electronic drum). i was wondering if you have an advice for me? or maybe someone else (hi christian!). is it the limitation of usb-midi or the limitation of my knowledge?
cheers!
pat
i am very happy to say that i am now using an atmega164p (new version of atmega16). it's cheaper and faster (20 mhz). i want to ask you a question about optimization for the usb communication. here's my function that send the noteon, noteoff:
Code: Select all
void usbsend(unsigned char note, unsigned char velo) {
while (!usbInterruptIsReady()) {
wdt_reset();
usbPoll();
}
midiMsg[0] = 0x09;
midiMsg[1] = MIDI_NOTEON|MIDI_CHAN;
midiMsg[2] = note;
midiMsg[3] = velo;
midiMsg[4] = 0x08;
midiMsg[5] = MIDI_NOTEOFF|MIDI_CHAN;
midiMsg[6] = note;
midiMsg[7] = 0;
sendEmptyFrame = 1;
usbSetInterrupt(midiMsg, 8);
}
this function takes 8ms to finish (i am running the obdev usb firmware at 20mhz). sending all 8 ADC takes 8ms * 8 = 64ms. long enough to miss an hit (i'm making an electronic drum). i was wondering if you have an advice for me? or maybe someone else (hi christian!). is it the limitation of usb-midi or the limitation of my knowledge?
cheers!
pat
USB MIDI Interface updated
Hi,
I've just uploaded a new version of my project - it's got a new name V-USB-MIDI according to the new driver name.
I made no big changes but I updated to the last version of v-usb (2009-04-15).
V-USB-MIDI-0.2
hi pat,
I have no idea how to speed up the communication - but maybe christian knows??
Ciao Martin
I've just uploaded a new version of my project - it's got a new name V-USB-MIDI according to the new driver name.
I made no big changes but I updated to the last version of v-usb (2009-04-15).
V-USB-MIDI-0.2
hi pat,
I have no idea how to speed up the communication - but maybe christian knows??
Ciao Martin
Re: USB MIDI Interface
Hi Horo,
Thank you for your update!
About the speed, there is no way to make it faster when using usbSetInterrupt() (up to 8 bytes may be passed in one call) which take 8ms (homemade measurement). The only way i found was to get rid of MIDI_NOTEOFF since i only want to trig a sound percussion and add a second MIDI_NOTEON instead.
Cheers,
Patrick
Thank you for your update!
About the speed, there is no way to make it faster when using usbSetInterrupt() (up to 8 bytes may be passed in one call) which take 8ms (homemade measurement). The only way i found was to get rid of MIDI_NOTEOFF since i only want to trig a sound percussion and add a second MIDI_NOTEON instead.
Code: Select all
void usbsend(unsigned char first_note, unsigned char first_velo, unsigned char second_note, unsigned char second_velo) {
while (!usbInterruptIsReady()) {
wdt_reset();
usbPoll();
}
midiMsg[0] = 0x09;
midiMsg[1] = MIDI_NOTEON|MIDI_CHAN;
midiMsg[2] = first_note;
midiMsg[3] = first_velo;
midiMsg[4] = 0x09;
midiMsg[5] = MIDI_NOTEON|MIDI_CHAN;
midiMsg[6] = second_note;
midiMsg[7] = second_velo;
sendEmptyFrame = 1;
usbSetInterrupt(midiMsg, 8);
}
Cheers,
Patrick
USB MIDI Interface in Bulk mode 2 ms
Hi Patrick,
I've read the descriptor section in main.c again and changed some values and suddenly -tada! - my test program sends data (4 or 8 byte) every two milliseconds! Then I started again step by step - it's only necessary to change the values of bmAttributes from 3 to 2 (Interrupt -> Bulk) in section B.5.1 and B.6.1.
My Laptop uses sidux - a debian sid based linux - with new sidux kernel version 2.6.29.1 / or the actual realtime kernel version. I don't know which system do you have - please check it out.
So long
Martin
I've read the descriptor section in main.c again and changed some values and suddenly -tada! - my test program sends data (4 or 8 byte) every two milliseconds! Then I started again step by step - it's only necessary to change the values of bmAttributes from 3 to 2 (Interrupt -> Bulk) in section B.5.1 and B.6.1.
Code: Select all
/* Name: main.c
* ...
*/
// ...
// B.5 Bulk OUT Endpoint Descriptors
//B.5.1 Standard Bulk OUT Endpoint Descriptor
9, /* bLenght */
USBDESCR_ENDPOINT, /* bDescriptorType = endpoint */
0x1, /* bEndpointAddress OUT endpoint number 1 */
2, /* bmAttributes: 2:Bulk, 3:Interrupt endpoint <=== CHANGE HERE TO BULK */
8, 0, /* wMaxPacketSize */
10, /* bIntervall in ms */
0, /* bRefresh */
0, /* bSyncAddress */
// B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor
5, /* bLength of descriptor in bytes */
37, /* bDescriptorType */
1, /* bDescriptorSubtype */
1, /* bNumEmbMIDIJack */
1, /* baAssocJackID (0) */
//B.6 Bulk IN Endpoint Descriptors
//B.6.1 Standard Bulk IN Endpoint Descriptor
9, /* bLenght */
USBDESCR_ENDPOINT, /* bDescriptorType = endpoint */
0x81, /* bEndpointAddress IN endpoint number 1 */
2, /* bmAttributes: 2: Bulk, 3: Interrupt endpoint <=== CHANGE HERE TO BULK */
8, 0, /* wMaxPacketSize */
10, /* bIntervall in ms */
0, /* bRefresh */
0, /* bSyncAddress */
// B.6.2 Class-specific MS Bulk IN Endpoint Descriptor
5, /* bLength of descriptor in bytes */
37, /* bDescriptorType */
1, /* bDescriptorSubtype */
1, /* bNumEmbMIDIJack (0) */
3, /* baAssocJackID (0) */
};
// ...
My Laptop uses sidux - a debian sid based linux - with new sidux kernel version 2.6.29.1 / or the actual realtime kernel version. I don't know which system do you have - please check it out.
So long
Martin
Re: USB MIDI Interface
Hi Horo,
How nice! From 8 ms to 2 ms just by changing the bmAttributes. It's working very well, however i have this warning(?) when plugging the device:
Linux mbp 2.6.24-23-rt #1 SMP PREEMPT RT Wed Apr 1 23:40:34 UTC 2009 i686 GNU/Linux
I didn't try on Windows or Mac.
There's something i am wondering:
Since we are now using bulk endpoint (are we?) is this a concern for us?
Gives 2 μs (the CPU doesn't seem busy).
Gives 2 ms - Wonderful!
Patrick
How nice! From 8 ms to 2 ms just by changing the bmAttributes. It's working very well, however i have this warning(?) when plugging the device:
Code: Select all
[ 8848.352583] usb 1-2: new low speed USB device using uhci_hcd and address 14
[ 8848.456365] usb 1-2: config 1 interface 1 altsetting 0 endpoint 0x1 is Bulk; changing to Interrupt
[ 8848.456379] usb 1-2: config 1 interface 1 altsetting 0 endpoint 0x81 is Bulk; changing to Interrupt
[ 8848.473328] usb 1-2: configuration #1 chosen from 1 choice
Linux mbp 2.6.24-23-rt #1 SMP PREEMPT RT Wed Apr 1 23:40:34 UTC 2009 i686 GNU/Linux
I didn't try on Windows or Mac.
There's something i am wondering:
Consumes 90% or more of the AVR's CPU time because bulk endpoints are polled aggressively by the host. Real-time applications on the AVR are close to impossible.
Since we are now using bulk endpoint (are we?) is this a concern for us?
Code: Select all
for (;;) {
PORTD ^= 0x80;
wdt_reset();
usbPoll();
}
Gives 2 μs (the CPU doesn't seem busy).
Code: Select all
for (;;) {
PORTD ^= 0x80;
wdt_reset();
usbPoll();
usbSetInterrupt(midiMsg, 8);
}
Gives 2 ms - Wonderful!
Patrick
Re: USB MIDI Interface
psc wrote:...
There's something i am wondering:Consumes 90% or more of the AVR's CPU time because bulk endpoints are polled aggressively by the host. Real-time applications on the AVR are close to impossible.
Since we are now using bulk endpoint (are we?) is this a concern for us?
...
Patrick
Hi Patrick,
I don't think we're using bulk xfer because:
Code: Select all
[ 8848.456365] usb 1-2: config 1 interface 1 altsetting 0 endpoint 0x1 is Bulk; changing to Interrupt
[ 8848.456379] usb 1-2: config 1 interface 1 altsetting 0 endpoint 0x81 is Bulk; changing to Interrupt
The linux driver changed it to int - I see activity on usb lines every 2 ms for about 120 µs (and the SOF "heartbeat" on D- every 1ms). So we have 6% usb load and more than 90% cpu time remaining for our application - that's ok.
Ciao Martin
P.S.: it would be helpful if someone could verify this for win and mac.
Re: USB MIDI Interface
Hi,
did some "research":
linux:
bmAttributes=2 (bulk), bIntervall don't care -> 2ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=1..3 -> 2ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=4..7 -> 4ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=8..15 -> 8ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=16..31 -> 16ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=0 or 32..63 -> 32ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=64..127 -> 64ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=128..255 -> 128ms poll, low cpu load
winxp:
bmAttributes=2 (bulk), bIntervall don't care -> permanent poll, high cpu load
bmAttributes=3 (interrupt), bIntervall don't care -> 8ms poll, low cpu load
So I think it's best to use
bmAttributes=3 (interrupt), bIntervall=2
this gives fastest access for linux and no heavy load for win.
Ciao Martin
P.S.: mac users - please test
did some "research":
linux:
bmAttributes=2 (bulk), bIntervall don't care -> 2ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=1..3 -> 2ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=4..7 -> 4ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=8..15 -> 8ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=16..31 -> 16ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=0 or 32..63 -> 32ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=64..127 -> 64ms poll, low cpu load
bmAttributes=3 (interrupt), bIntervall=128..255 -> 128ms poll, low cpu load
winxp:
bmAttributes=2 (bulk), bIntervall don't care -> permanent poll, high cpu load
bmAttributes=3 (interrupt), bIntervall don't care -> 8ms poll, low cpu load
So I think it's best to use
bmAttributes=3 (interrupt), bIntervall=2
this gives fastest access for linux and no heavy load for win.
Ciao Martin
P.S.: mac users - please test
Re: USB MIDI Interface
Hi Martin,
I was wondering if there is a reason that only 2 midi events AKA 8 bytes are sent at a time. I don't recall this from the doc midi10.pdf. Is it a limit of usb 1.1 or just the default in the v-usb driver? Couldn't a larger packet also increase speed or at least throughput but not latency?
-- EDIT
Ok, after further research I've found that that interrupt packets are limited to 8 bytes at low-speed. That means the max you can transfer is 800 bytes (200 midi events) per second with 10ms "interrupt". These numbers all assume that you abide by the official usb spec. The AVR-CDC project uses bulk over low-speed and this apparently can increase throughput significantly but isn't within official usb spec. on low speed. He even has a driver for vista at http://www.recursion.jp/avrcdc/lowbulk.html that might be useful but none of this helps decrease latency. I would recommend one of the full-speed capable usb integrated AVRs for use in a midi drumset.
BTW I tested the default descriptor from your project on Windows 7 beta build 7000 and it enumerates and functions great.
Thanks for your work on this project,
Dave
I was wondering if there is a reason that only 2 midi events AKA 8 bytes are sent at a time. I don't recall this from the doc midi10.pdf. Is it a limit of usb 1.1 or just the default in the v-usb driver? Couldn't a larger packet also increase speed or at least throughput but not latency?
-- EDIT
Ok, after further research I've found that that interrupt packets are limited to 8 bytes at low-speed. That means the max you can transfer is 800 bytes (200 midi events) per second with 10ms "interrupt". These numbers all assume that you abide by the official usb spec. The AVR-CDC project uses bulk over low-speed and this apparently can increase throughput significantly but isn't within official usb spec. on low speed. He even has a driver for vista at http://www.recursion.jp/avrcdc/lowbulk.html that might be useful but none of this helps decrease latency. I would recommend one of the full-speed capable usb integrated AVRs for use in a midi drumset.
BTW I tested the default descriptor from your project on Windows 7 beta build 7000 and it enumerates and functions great.
Thanks for your work on this project,
Dave
Re: USB MIDI Interface
Hi Dave,
could you please test my recommendation:to verify that it works well on win7.
Ciao Martin
Any Mac users around
could you please test my recommendation:
Code: Select all
bmAttributes=3 (interrupt), bIntervall=2
Ciao Martin
Any Mac users around
Re: USB MIDI Interface
Martin,
I tested the 2ms interrupt setting on the same Windows 7 install and it works great.
Above you stated that under winxp that polling is 8ms regardless of bInterval. How
did you come to that conclusion? Are you probing the usb signal lines with a scope?
In the win utility "USB View" it lists back this:
Endpoint Descriptor:
bEndpointAddress: 0x01
Transfer Type: Interrupt
wMaxPacketSize: 0x0008 (8)
wInterval: 0x0002
bSyncAddress: 0x00
I'm sure that it is just reporting back the descriptor that we gave it and not reporting
what's actually happening.
Laters Dave
I tested the 2ms interrupt setting on the same Windows 7 install and it works great.
Above you stated that under winxp that polling is 8ms regardless of bInterval. How
did you come to that conclusion? Are you probing the usb signal lines with a scope?
In the win utility "USB View" it lists back this:
Endpoint Descriptor:
bEndpointAddress: 0x01
Transfer Type: Interrupt
wMaxPacketSize: 0x0008 (8)
wInterval: 0x0002
bSyncAddress: 0x00
I'm sure that it is just reporting back the descriptor that we gave it and not reporting
what's actually happening.
Laters Dave
Re: USB MIDI Interface
Hi Dave,
I've tested the timing with a program fragment like Patrick's (some posts above ^^). I checked the usb lines and the debug port pins with a scope. Pin D.7 toggles permanently with some inactivity (about 120µs) every 2 ms. So there's more than 90% of cpu activity for user program.
Ciao Martin
I've tested the timing with a program fragment like Patrick's (some posts above ^^). I checked the usb lines and the debug port pins with a scope. Pin D.7 toggles permanently with some inactivity (about 120µs) every 2 ms. So there's more than 90% of cpu activity for user program.
Ciao Martin
Re: USB MIDI Interface
Hi Martin,
This is all just great! Your research on this descriptor and the use of these cheap 8bit avr
chips has opened the door for so many homebrew midi devices I can't even describe how
grateful that I am for your time. All we need now is confirmation from mac users and this
will be a universal FREE music interface that is future proof. Cheers to you Martin. If you
ever make your way to Texas the beer is on me. I might be American but you make me
proud to be German too. Long live open source!
Laters, David Burmeister
--EDIT Your awesome too Christian, sorry
This is all just great! Your research on this descriptor and the use of these cheap 8bit avr
chips has opened the door for so many homebrew midi devices I can't even describe how
grateful that I am for your time. All we need now is confirmation from mac users and this
will be a universal FREE music interface that is future proof. Cheers to you Martin. If you
ever make your way to Texas the beer is on me. I might be American but you make me
proud to be German too. Long live open source!
Laters, David Burmeister
--EDIT Your awesome too Christian, sorry
-
- Posts: 4
- Joined: Tue Mar 03, 2009 1:42 pm
Re: USB MIDI Interface
Hi horo
First of all, great job what you have done.
I took your example changed the ADC and KEY handling and it is working fine.
Now to my question. If I try to send data to the V-USB device there is no feedback on my debug LED. So I am quiet sure that there comes no data to my V-USB devcie. Have you tried that yourself or could give me a hint what is going wrong.
If I send some data to the Windows Midi device with my testsoftware it is working fine. So I think my testapp is OK.
Thank you for your help.
MB
First of all, great job what you have done.
I took your example changed the ADC and KEY handling and it is working fine.
Now to my question. If I try to send data to the V-USB device there is no feedback on my debug LED. So I am quiet sure that there comes no data to my V-USB devcie. Have you tried that yourself or could give me a hint what is going wrong.
If I send some data to the Windows Midi device with my testsoftware it is working fine. So I think my testapp is OK.
Thank you for your help.
MB