USB MIDI Interface

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
solata10
Posts: 13
Joined: Sun Dec 13, 2009 3:09 pm

Re: USB MIDI Interface

Post by solata10 » Tue Dec 22, 2009 7:19 pm

hmmm, if i'm correct, this way i can send at most 4 bytes at once right ?
and i have no way to getting back return informations.

horo
Rank 2
Rank 2
Posts: 63
Joined: Tue Mar 04, 2008 2:26 pm
Location: Berlin & Lindau, Germany

Re: USB MIDI Interface

Post by horo » Wed Dec 23, 2009 11:03 am

solata10 wrote:hmmm, if i'm correct, this way i can send at most 4 bytes at once right ?
and i have no way to getting back return informations.

Hi solata10,

no, you can send eight bytes, i.e. two midi messages - if you set up some kind of state machine in your device you'll be able to send back a midi event as a return information.
For a quick hack I've just perverted my midi circuit (^^^) as a simple eight channel ADC for measurement, the 10bit are coded as four messages with two midi events:

Code: Select all

00001000  // Note off event
10000ccc  // Note off; Channel (ADC channel 0..7)
00000mmm  // Key (MSB of ADC)
0lllllll  // Velocity (LSB of ADC)

On the PC I read the midi events, no need to write a kernel driver...
It also works the other way round as an output from PC to midi device (using PWMs as four DACs).
HTH
Ciao, Martin

Alan Chatham
Rank 1
Rank 1
Posts: 28
Joined: Wed Sep 30, 2009 3:36 am
Location: Osaka, Japan
Contact:

Re: USB MIDI Interface

Post by Alan Chatham » Thu Feb 11, 2010 8:24 am

Hi there! Sorry for resurrecting this thread, but it seems to be the place to discuss your project, Horo. Thanks for your hard work!

Unfortunately, I'm having a lot of trouble getting it to work.. I've tried both the V-USB-MIDI sample code as well as the Pepper-MIDI project, to no success. I can get the device to enumerate in winXP service pack 3 and all that good stuff, but for some reason, the communication is freezing. Using LED debugging, I've found out that for some reason, after maybe exchanging a packet or two, the code won't enter into the "usbInterruptIsReady()" section if it calls "setUsbInterrupt()". If I comment out the setUsbInterrupt() calls, then the program works just fine, but of course, it's not sending any data to the computer. If anyone has any suggestions on what I could be doing wrong, it would be greatly appreciated!

horo
Rank 2
Rank 2
Posts: 63
Joined: Tue Mar 04, 2008 2:26 pm
Location: Berlin & Lindau, Germany

Re: USB MIDI Interface

Post by horo » Tue May 25, 2010 10:26 am

Hi Alan,

any success so far?

Ciao Martin

UA3MQJ
Posts: 2
Joined: Wed May 26, 2010 4:31 pm
Location: Russia, Rybinsk
Contact:

Re: USB MIDI Interface

Post by UA3MQJ » Wed May 26, 2010 5:03 pm

Hi to All!
V-USB - an excellent project!
On the basis of his project and http://cryptomys.de/horo/V-USB-MIDI I did USB-MIDI-CV converter.
The converter has an output CV (to control VCO) and CV GATE (to control ADSR).
There are 6 outputs DRUM GATE management modules analog electronic drums.

scheme - http://radiokot.ru/forum/download/file.php?id=35331
drums generators - http://sites.google.com/site/analogsynt ... ka-udarnyh

sources:

Descriptor with two cables (Need for simultaneous operation of this unit with two programs).

Code: Select all

// This descriptor is based on http://www.usb.org/developers/devclass_docs/midi10.pdf
//
// Appendix B. Example: Simple MIDI Adapter (Informative)
// B.1 Device Descriptor
//
static PROGMEM char deviceDescrMIDI[] = {   /* USB device descriptor */
   18,         /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
   USBDESCR_DEVICE,   /* descriptor type */
   0x10, 0x01,      /* USB version supported */
   0,         /* device class: defined at interface level */
   0,         /* subclass */
   0,         /* protocol */
   8,         /* max packet size */
   USB_CFG_VENDOR_ID,   /* 2 bytes */
   USB_CFG_DEVICE_ID,   /* 2 bytes */
   USB_CFG_DEVICE_VERSION,   /* 2 bytes */
   1,         /* manufacturer string index */
   2,         /* product string index */
   0,         /* serial number string index */
   1,         /* number of configurations */
};

// B.2 Configuration Descriptor
static PROGMEM char configDescrMIDI[] = {   /* USB configuration descriptor */
   9,         /* sizeof(usbDescrConfig): length of descriptor in bytes */               
   USBDESCR_CONFIG,   /* descriptor type */                                    
   101 + 32 /* cable 1 */, 0,         /* total length of data returned (including inlined descriptors) */      
   2,         /* number of interfaces in this configuration */                     
   1,         /* index of this configuration */                                 
   0,         /* configuration name string index */                              
#if USB_CFG_IS_SELF_POWERED
   USBATTR_SELFPOWER,   /* attributes */                                       
#else
   USBATTR_BUSPOWER,   /* attributes */
#endif
   USB_CFG_MAX_BUS_POWER / 2,   /* max USB current in 2mA units */                     

// B.3 AudioControl Interface Descriptors
// The AudioControl interface describes the device structure (audio function topology)
// and is used to manipulate the Audio Controls. This device has no audio function
// incorporated. However, the AudioControl interface is mandatory and therefore both
// the standard AC interface descriptor and the classspecific AC interface descriptor
// must be present. The class-specific AC interface descriptor only contains the header
// descriptor.

// B.3.1 Standard AC Interface Descriptor
// The AudioControl interface has no dedicated endpoints associated with it. It uses the
// default pipe (endpoint 0) for all communication purposes. Class-specific AudioControl
// Requests are sent using the default pipe. There is no Status Interrupt endpoint provided.
   /* AC interface descriptor follows inline: */
   9,         /* sizeof(usbDescrInterface): length of descriptor in bytes */            
   USBDESCR_INTERFACE,   /* descriptor type */                                    
   0,         /* index of this interface */                                    
   0,         /* alternate setting for this interface */                           
   0,         /* endpoints excl 0: number of endpoint descriptors to follow */         
   1,         /* */                                                      
   1,         /* */                                                      
   0,         /* */                                                      
   0,         /* string index for interface */                                 

// B.3.2 Class-specific AC Interface Descriptor
// The Class-specific AC interface descriptor is always headed by a Header descriptor
// that contains general information about the AudioControl interface. It contains all
// the pointers needed to describe the Audio Interface Collection, associated with the
// described audio function. Only the Header descriptor is present in this device
// because it does not contain any audio functionality as such.
   /* AC Class-Specific descriptor */
   9,         /* sizeof(usbDescrCDC_HeaderFn): length of descriptor in bytes */         
   36,         /* descriptor type */                                          
   1,         /* header functional descriptor */                                 
   0x0, 0x01,      /* bcdADC */                                             
   9, 0,         /* wTotalLength */                                          
   1,         /* */                                                      
   1,         /* */                                                      

// B.4 MIDIStreaming Interface Descriptors

// B.4.1 Standard MS Interface Descriptor
   /* interface descriptor follows inline: */
   9,         /* length of descriptor in bytes */                                 
   USBDESCR_INTERFACE,   /* descriptor type */                                    
   1,         /* index of this interface */                                    
   0,         /* alternate setting for this interface */                           
   2,         /* endpoints excl 0: number of endpoint descriptors to follow */         
   1,         /* AUDIO */                                                   
   3,         /* MS */                                                   
   0,         /* unused */                                                
   0,         /* string index for interface */                                 

// B.4.2 Class-specific MS Interface Descriptor
   /* MS Class-Specific descriptor */
   7,         /* length of descriptor in bytes */                                 
   36,         /* descriptor type */                                          
   1,         /* header functional descriptor */                                 
   0x0, 0x01,      /* bcdADC */                                             
   65 + 32, 0,         /* wTotalLength */                                          

//CABLE 0!
// B.4.3 MIDI IN Jack Descriptor
   6,         /* bLength */                                                
   36,         /* descriptor type */                                          
   2,         /* MIDI_IN_JACK desc subtype */                                    
   1,         /* EMBEDDED bJackType */                                       
   1,         /* bJackID */                                                
   0,         /* iJack */                                                   

   6,         /* bLength */                                                
   36,         /* descriptor type */                                          
   2,         /* MIDI_IN_JACK desc subtype */                                    
   2,         /* EXTERNAL bJackType */                                       
   2,         /* bJackID */                                                
   0,         /* iJack */                                                   

//B.4.4 MIDI OUT Jack Descriptor
   9,         /* length of descriptor in bytes */                                 
   36,         /* descriptor type */                                          
   3,         /* MIDI_OUT_JACK descriptor */                                    
   1,         /* EMBEDDED bJackType */                                       
   3,         /* bJackID */                                                
   1,         /* No of input pins */                                          
   2,         /* BaSourceID */                                                
   1,         /* BaSourcePin */                                             
   0,         /* iJack */                                                   

   9,         /* bLength of descriptor in bytes */                              
   36,         /* bDescriptorType */                                          
   3,         /* MIDI_OUT_JACK bDescriptorSubtype */                              
   2,         /* EXTERNAL bJackType */                                       
   4,         /* bJackID */                                                
   1,         /* bNrInputPins */                                             
   1,         /* baSourceID (0) */                                          
   1,         /* baSourcePin (0) */                                          
   0,         /* iJack */                                                   

//CABLE 1!
// B.4.3 MIDI IN Jack Descriptor
   6,         /* bLength */                                                
   36,         /* descriptor type */                                          
   2,         /* MIDI_IN_JACK desc subtype */                                    
   1,         /* EMBEDDED bJackType */                                       
   5,         /* bJackID */                                                
   0,         /* iJack */                                                   

   6,         /* bLength */                                                
   36,         /* descriptor type */                                          
   2,         /* MIDI_IN_JACK desc subtype */                                    
   2,         /* EXTERNAL bJackType */                                       
   6,         /* bJackID */                                                
   0,         /* iJack */                                                   

//B.4.4 MIDI OUT Jack Descriptor
   9,         /* length of descriptor in bytes */                                 
   36,         /* descriptor type */                                          
   3,         /* MIDI_OUT_JACK descriptor */                                    
   1,         /* EMBEDDED bJackType */                                       
   7,         /* bJackID */                                                
   1,         /* No of input pins */                                          
   6,         /* BaSourceID */                                                
   1,         /* BaSourcePin */                                             
   0,         /* iJack */                                                   

   9,         /* bLength of descriptor in bytes */                              
   36,         /* bDescriptorType */                                          
   3,         /* MIDI_OUT_JACK bDescriptorSubtype */                              
   2,         /* EXTERNAL bJackType */                                       
   8,         /* bJackID */                                                
   1,         /* bNrInputPins */                                             
   5,         /* baSourceID (0) */                                          
   1,         /* baSourcePin (0) */                                          
   0,         /* iJack */                                                   


// B.5 Bulk OUT Endpoint Descriptors

//B.5.1 Standard Bulk OUT Endpoint Descriptor
   9,         /* bLenght */                                                
   USBDESCR_ENDPOINT,   /* bDescriptorType = endpoint */                           
   2, //0x1,         /* bEndpointAddress OUT endpoint number 1 */                     
   3,         /* bmAttributes: 2:Bulk, 3:Interrupt endpoint */                     
   8, 0,         /* wMaxPacketSize */                                       
   10,         /* bIntervall in ms */                                          
   0,         /* bRefresh */                                                
   0,         /* bSyncAddress */                                             

// B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor
   6,         /* bLength of descriptor in bytes */                              
   37,         /* bDescriptorType */                                          
   1,         /* bDescriptorSubtype */                                       
   2,         /* bNumEmbMIDIJack  */                                          
   1,         /* baAssocJackID (0) */   
   5,         /* baAssocJackID (1) */                              


//B.6 Bulk IN Endpoint Descriptors

//B.6.1 Standard Bulk IN Endpoint Descriptor
   9,         /* bLenght */                                                
   USBDESCR_ENDPOINT,   /* bDescriptorType = endpoint */                           
   0x82,//0x81,         /* bEndpointAddress IN endpoint number 1 */                        
   3,         /* bmAttributes: 2: Bulk, 3: Interrupt endpoint */                     
   8, 0,         /* wMaxPacketSize */                                       
   10,         /* bIntervall in ms */                                          
   0,         /* bRefresh */                                                
   0,         /* bSyncAddress */                                             

// B.6.2 Class-specific MS Bulk IN Endpoint Descriptor
   6,         /* bLength of descriptor in bytes */                              
   37,         /* bDescriptorType */                                          
   1,         /* bDescriptorSubtype */                                       
   2,         /* bNumEmbMIDIJack (0) */                                    
   3,         /* baAssocJackID (0) */                                          
   7,         /* baAssocJackID (1) */                                          
   //101 + 32 (eshe odin kabel)
};

Last edited by UA3MQJ on Wed May 26, 2010 5:04 pm, edited 1 time in total.

UA3MQJ
Posts: 2
Joined: Wed May 26, 2010 4:31 pm
Location: Russia, Rybinsk
Contact:

Re: USB MIDI Interface

Post by UA3MQJ » Wed May 26, 2010 5:04 pm

Code of usbFunctionWriteOut

Code: Select all

/*---------------------------------------------------------------------------*/
/* usbFunctionWriteOut                                                       */
/*                                                                           */
/* this Function is called if a MIDI Out message (from PC) arrives.          */
/*                                                                           */
/*---------------------------------------------------------------------------*/

void usbFunctionWriteOut(uchar * data, uchar len)
{

   //usb 0x9 - note ON и МИДИ команда 9 канал не 10-й

   uchar drum_num;


   if ( ( ( data[0] & 0x0f ) == 0x09 ) & ( ( data[1]>>4 ) == 0x09 )  ) {

      //если это не 10-й канал (барабаны)
      if ( (data[1] & 0x0f) != 9 ) {
         //если ноту нажали - выводим ее на CV
         set_note( data[2] );
         PORTB = 0x01; //выводим сигнал GATE
      } else {
           //для барабанов начальной нотой будет
         //0x3c - нота ДО неведомой октавы (6-я, от начала, если считать от единицы)
         drum_num = (uchar)data[2] - 0x3c; //считая с ноля;

         PORTC |= 1<<drum_num;


      }

   }

   if ( ( ( data[0] & 0x0f ) == 0x08 ) & ( ( data[1]>>4 ) == 0x08 )  ) {

      //если это не 10-й канал (барабаны)
      if ( (data[1] & 0x0f) != 9 ) {
         //если ноту отпустили, то снимаем только GATE
         PORTB = 0x00;
      } else {
         drum_num = data[2] - 0x3c; //считая с ноля;

         PORTC &= ~(1<<drum_num);


      }



   }



}

void set_note( int note ) {

   int pwm_val = note<<3; //ноты от 0 до 127

   // pwm_val - это число от 0 до 1023

   OCR1AH = (char)(pwm_val>>8);
   OCR1AL = (char)pwm_val;

}


Small video http://www.youtube.com/watch?v=bstvCQoSSks

On video:
1. PC - FL Studio
2. V-USB-MIDI-CV
3. Drum Gens
4. Mixer ( http://www.musicfromouterspace.com/anal ... mixer.html )

TNX for All!
With best regards from Russia
de UA3MQJ Alex 73!

ps. Excuse me for my english.

horo
Rank 2
Rank 2
Posts: 63
Joined: Tue Mar 04, 2008 2:26 pm
Location: Berlin & Lindau, Germany

USB MIDI Interface

Post by horo » Mon Aug 30, 2010 3:42 pm

Hi,

beside the already known Pepper-MIDI (Control SX-150 Synth via MIDI) I just discovered some fine new projects based on V-USB-MIDI:
Wojciech Zabolotny's MIDI Expression Pedal and MIDI Drum Trigger and Yoshitaka Kuwata's Monaka, a MIDI/OSC hard- and software toolbox.

I'm just transfering my own V-USB-MIDI development over to bitbucket, stay tuned (nothing to see until now).

Ciao Martin

morecat_lab
Posts: 1
Joined: Sat Sep 04, 2010 5:17 am
Location: Tokyo, Japan
Contact:

Re: USB MIDI Interface

Post by morecat_lab » Sat Sep 04, 2010 5:27 am

Hi, Martin-san and V-USB-MIDI forks.

Thank you for introducing my projects such as monaka and Pepper-MIDI project.
I also create a new web page for my latest project; MOCO.

I enjoy V-USB and V-USB-MIDI.

morecat_lab

-Yoshi

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: USB MIDI Interface

Post by christian » Mon Sep 06, 2010 11:05 am

Thanks for your project publication! When you have published a new project, please drop us a note via

http://www.obdev.at/vusb/feedback.html

as we don't always monitor the forums.

Alan Chatham
Rank 1
Rank 1
Posts: 28
Joined: Wed Sep 30, 2009 3:36 am
Location: Osaka, Japan
Contact:

Re: USB MIDI Interface

Post by Alan Chatham » Tue Sep 28, 2010 12:09 am

I finally managed to get the code working on the following: ATmega328p, Windows 7. I haven't tested it on other setups, but I assume it shouldn't be an issue elsewhere. Thanks so much, horo; with your work I've finally been able to add USB-MIDI to my guitar project, making for a very limited but very cheap way to get MIDI data from a guitar. I guess I had some issues with getting things to work with
A) compiling in AVR Studio 4 - I've had various problems with this in the past too, I'm not sure what's behind it, since both Studio and the command line compiling I've been doing has been using WinAVR for compiling....
B) actually seeing MIDI data coming into my PC. I was trying to listen to it in Frinika for a while, but it's not ideal. Finally, I found out that FL Studio 4 (the free demo version is perfect for this) actually will show what MIDI messages it's receiving, so if you're on PC, it's a great way to be able to debug things.

I finally wound up making a MIDI version of blink, where the program just sends a C5 note on, then turns it off, every second, and I found that to be the best initial testing program for me. I'll try and post that somewhere eventually, since it may help others trying to get MIDI working and requires no inputs or ADC pins or anything other than the 2 pins for V-USB.

Now I'm looking at going ahead and turning the code into a full-blown library for people to use more easily - I'm curious as to your opinion on that, horo. If it's something that I should go forward with, I'm wondering what functions I should include for use in said library? I've not used MIDI very much at all, so I'd love to get some input from the community as to what a good set of functions would be for the library. If it's alright, with horo, I'll start putting things into a library and put it, along with MIDI-blink, in a Google Code project.

Let me know

-Alan Chatham
www.OpenChord.org

adrian.gin
Posts: 9
Joined: Thu Oct 21, 2010 12:33 pm

Re: USB MIDI Interface

Post by adrian.gin » Thu Oct 21, 2010 12:59 pm

Hi guys,

Check this out. Just finished it tonight... in a way.

I've built and improved upon the VUSB MIDI project. This one here's called AVRMIDI for change of name sake, yea I know yet another VUSB MIDI project. It's based off the VUSB-MIDI project which was based off the AVRCDC. So kudos and thanks to them for the basis. Hopefully the code is a little easier to understand too.

This one's a little different. It's only been tested on a few Win7 and WinXP SP3 machines... but I guess it works.

1. No Zener Diodes - I dont a electrical schematic drawing program at the moment. But the circuit is simple.

From the AVR out pin, we just use a 220 + 330 voltage divider to get from +5V to 3V3.
For D- which requires the pullup, we use a 2k2 + 4k7 voltage divider to get +3V3. And then we connect this junction to the AVRMega via a 220/330 or 550 ohm resisor.

Volia! Bus powered, no Zeners @ 20MHz speeds. PS from the photos you can see that I 'cheated' yes, an ATMEGA8L 8MHz part is being clocked at 20MHz - Go Overclocking!!!

2. AtMega8 or better 12MHz -> 20MHz operation you choose.
3. Using MIDI Test from earthvegaconnection, I get very good results.

Message latency: 1.20 ms Total time: 0.343 sec
Message jitter: 0.35 ms
Message max deviation: 0.75 ms

I've sent a 1MB SysEx file using MIDI-OX looping back. It's fast and has no errors. So it's all good and buffered.

I hope you enjoy it. I must say I learn a lot about USB and a bit about MIDI and stuff doing this project.

Code is here:
http://code.google.com/p/lad-drum/source/browse/#svn/trunk/UoC%20Drum/AVRMIDI
and here.
http://code.google.com/p/lad-drum/source/browse/#svn/trunk/UoC%20Drum/FuncLib/Other/USBMIDI

A bit of youtube:
http://www.youtube.com/watch?v=w_LkwHiHXw8

Homepage
Image
Image

http://code.google.com/p/lad-drum/


Adrian Gin
Auckland, New Zealand

horo
Rank 2
Rank 2
Posts: 63
Joined: Tue Mar 04, 2008 2:26 pm
Location: Berlin & Lindau, Germany

Re: USB MIDI Interface

Post by horo » Thu Oct 21, 2010 5:15 pm

Hi Adrian,

nice project - your hw interface sounds clever - I will try it. Did I understand your connections correctly? - the D+ pin is connectet to the 220/330 divider, the D- pin goes through 550 to the 2k2/4k7, the 5V may be replaced by a third pin to use the UsbDeviceConnect feature?

Code: Select all

          D+        5V      D- 
          |         |       |
          _         _       _
         | |       | |     | |
         | |220    | |2k2  | |550
         |_|       |_|     |_|
          |         |       |
USB+ -----+         +-------+------ USB-
          |         |
          _         _
         | |       | |
         | |330    | |4k7
         |_|       |_|
          |         |
          |         |
         GND       GND


Ciao, Martin

adrian.gin
Posts: 9
Joined: Thu Oct 21, 2010 12:33 pm

Re: USB MIDI Interface

Post by adrian.gin » Fri Oct 22, 2010 12:42 am

Yes, you're absolutely right.

Though the 550ohm resistor can (I think be as low as 220ohm) and as high as perhaps 680.... but my calc's showed about 550ohms as the best.

For D+
For an AVR high output
5 * 330 / (220 + 330) = 3V (close enough to 3.3V)

For an AVR low output
0 * 330 / (220 + 330) = 0V

For an USB high output
3.3 = 3.3V (high impedance input from AVR, 3V3 should result in high)

For an USB low output
0 = 0V (high impedance input from AVR, 0 should result in low)

For D-

Biased at
5*4k7 / (6k9) = 3.4V (close enough to 3.3V)

For an AVR high output
5 * 4k7 / 4k7 + 440 (eq. parallel resistance) = 4.5V (a bit high but oh well it works)

For an AVR low output
5 * 500 (eq. parallel) / (2.2k + 500) = 1V (considered a 0 by the USB)

For an USB high output
3.3 = 3.3V (high impedance input from AVR, 3V3 should result in high)

For an USB low output
0 = 0V (high impedance input from AVR, 0 should result in low)

Cheers,
Adrian

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: USB MIDI Interface

Post by christian » Mon Oct 25, 2010 11:25 pm

From the USB specification (this is from version 1.1):

7.1.6 Input Characteristics
The input impedance of D+ or D- without termination should be > 300 kOhm (ZINP). The input capacitance of a port is measured at the connector pins. [...]

You clearly don't meet this part of the spec. On the other hand, the zener approach does not meet the spec either and some parts of the firmware don't. I would be interested to hear how this approach works in practice!

adrian.gin
Posts: 9
Joined: Thu Oct 21, 2010 12:33 pm

Re: USB MIDI Interface

Post by adrian.gin » Wed Oct 27, 2010 7:51 am

We clearly don't meet the spec. But then the bulk midi out doesn't either since it's a low speed device :lol:

Does it matter if it 'just works' anyway?

Post Reply