Dekrispator
Dekrispator copied to clipboard
USB MIDI support for other MIDI Controlers
Dear fellows,
I wanted to try out Dekrispator on my STM board, controlling it with my CME MIDI Controller.
I couldn't get any response from the controller. With GDB I could see that it would always give me "unrecognized device".
After some investigation, I found out that my controller has two interface descriptors. The first is some audio interface (maybe to send audio back from a hypothetical usb synth?) and the second is the real midi interface.
So I had to make changes in two places: 1) .../Dekrispator/USB/usbh_conf.h around line 48
define USBH_MAX_NUM_INTERFACES 1
Then obviously it would not decode my second interface. I just changed it to:
define USBH_MAX_NUM_INTERFACES 2
Now I had to tell Dekrispator to get data from that second interface: .../Dekrispator/USB/MIDIstream_class/usbh_midi_core.c In function USBH_MIDI_InterfaceInit, whenever there was a Itf_Desc[0][0], I changed to Itf_Desc[interfaceToUse][0]
interfaceToUse is a constant int = 1.
Next step is making this selection automatic (don't want to mess with the support for the Korg Controller).
I am gonna request to pull after I reorganize my code (and maybe make the interface selection automatic).
Very nice project to work with!
PS. Compiling all in Ubuntu 12.10, running make from the Release dir. Debugging with GDB/Emacs.
Great ! I'm so happy someone gets interest in Dekrispator's code ! It would be marvellous if you could improve that minimalistic USB driver for which I spent a lot of time. But understanding USB arcanes was a hard stuff for me as I'm not a pro programmer... Sincerely, Xavier
Hi, guys. @MrBlueXav I've also tried few you projects, and yes with CME device too, It doesn't work for me. BTW, thank you for a great work! I really appreciate this. I want to build a synth based on discovery board for a while. ARM programming looks a bit complex after AVR(especially) arduino. Currently I've occupied and have no time, but in my plans integrate this board to
Thanks again and respect to you!
Hi!
@MrBlueXav I will try to make the midi flexible, so that we do not have to change the code when we use different synths. Supporting full USB midi will be difficult because our little board doesn't have an OS and GUIs. For example, when I connect the CME to my linux machine, I am given a list with all the interface available, and then route them to the synth I want (using "jack"). We cannot do this in the discovery board, so maybe we will have to accept any incoming midi message from all midi interfaces. Should not be a problem I think.
I am also taking a look at the audio code. I changed BUFF_LEN_DIV_4 all the way down to 1, and it still plays without glitching (slow usb recognition though, busy CPU). Means that we can achieve a very low latency, more than enough for fast keyboard playing.
I have some string physical modeling code, I will add it and we can play some tunes along with the sequencer :)
@iRet What a cool synth! That would be really awesome to play on stage!
Hi, @tomassch
Can you please explain what did you do to get "unrecognized device" message in gdb? I'm noob with this stuff. Starting st-util then arm-none-eabi-gdb. Connecting to localhost, and type continue.
I'm on a mac, it was really hard to get working environment here. Flashing via st-flash binary file. Project won't compile as is, however another code compiling well even another Xavier's project with Makefile :) Will check further.
So, I've tried to connect Novation X-station and send some midi messages according to mapping from Resources folder. Nothing...
BTW, Dekrispator sound pretty good!
Finally played a bit with paths in .mk files to .d and that's it. Not sure it's a right way, but for me build from console much simpler than config eclipse :)
awesome progress!
did it work with the novation without changing the interface number in the midistream code?
about the device unrecognized in gdb, I made a break point in the line that calls the "device unrecognized" function. then the code would always stop there when running.
yesterday I implemented noteOn noteOff functionality, and put it to test with some fast bach inventions :)
soon gonna commit the code. On Aug 9, 2014 2:34 AM, "Artyom Nikolaev" [email protected] wrote:
Finally played a bit with paths in .mk files to .d and that's it. Not sure it's a right way, but for me build from console much simpler than config eclipse :)
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51633229.
Oh, got it. I'm using simple text editors, so no built-in debugger for me. Not sure if it will work this (https://github.com/iRet/Dekrispator/blob/62ecff120d248c21b7c607226f0fd81d7e94268d/USB/MIDIstream_class/usbh_midi_core.c#L95-L153) way still no luck in novation and simple cme device but i'm not sure it last on have any intersections with mapped cc, as for novation I've tried to change CC13 and all default. Novation has a bunch of interfaces:
| | | +-o XStation@1d100000 <class IOUSBDevice, id 0x100013d63, registered, matched, active, busy 0 (1551 ms), retain 23>
| | | +-o IOUSBCompositeDriver <class IOUSBCompositeDriver, id 0x100013d67, !registered, !matched, active, busy 0, retain 4>
| | | +-o XStation@0 <class IOUSBInterface, id 0x100013d68, registered, matched, active, busy 0 (171 ms), retain 8>
| | | +-o XStation@1 <class IOUSBInterface, id 0x100013d69, registered, matched, active, busy 0 (160 ms), retain 9>
| | | | +-o IOUSBInterfaceUserClientV3 <class IOUSBInterfaceUserClientV3, id 0x100013d78, !registered, !matched, active, busy 0, retain 9>
| | | +-o IOUSBInterface@2 <class IOUSBInterface, id 0x100013d6a, registered, matched, active, busy 0 (679 ms), retain 8>
| | | | +-o NovationUSBAudioDevice <class NovationUSBAudioDevice, id 0x100013d7d, registered, matched, active, busy 0 (1 ms), retain 7>
| | | | +-o NovationUSBAudioEngine <class NovationUSBAudioEngine, id 0x100013d7e, registered, matched, active, busy 0 (1 ms), retain 9>
| | | +-o IOUSBInterface@3 <class IOUSBInterface, id 0x100013d6b, registered, matched, active, busy 0 (166 ms), retain 10>
| | | +-o IOUSBInterface@4 <class IOUSBInterface, id 0x100013d6c, registered, matched, active, busy 0 (161 ms), retain 10>
| | | +-o IOUSBInterface@5 <class IOUSBInterface, id 0x100013d6d, registered, matched, active, busy 0 (171 ms), retain 9>
| | | | +-o IOUSBHIDDriver <class IOUSBHIDDriver, id 0x100013d98, registered, matched, active, busy 0 (5 ms), retain 11>
| | | | | +-o CMUSBDevice <class com_orderedbytes_ControllerMate_driver_USBDevice, id 0x100013d9c, registered, matched, active, busy 0 (0 ms), retain 10>
| | | | | +-o CMUSBDevicesUserClient <class com_orderedbytes_ControllerMate_driver_USBDeviceUserClient, id 0x100013f13, !registered, !matched, active, busy 0, retain 5>
gdb runs on the command line, so you can still use your text editor. to set a breakpoint in line 1234 of foo.c you type:
break foo.c:1234 continue
search for a gdb tutorial, it will give you magic powers in a short time.
and about this novation ctrlr, it looks like a lot of interfaces! tomorrow morning ima take a look (and commit some organized code, I promise :) ). On Aug 9, 2014 4:01 AM, "Artyom Nikolaev" [email protected] wrote:
Oh, got it. I'm using simple text editors, so no built-in debugger for me. Not sure if it will work this ( https://github.com/iRet/Dekrispator/blob/62ecff120d248c21b7c607226f0fd81d7e94268d/USB/MIDIstream_class/usbh_midi_core.c#L95-L153) way still no luck in novation and simple cme device but i'm not sure it last on have any intersections with mapped cc, as for novation I've tried to change CC13 and all default. Novation has a bunch of interfaces:
| | | +-o XStation@1d100000 <class IOUSBDevice, id 0x100013d63, registered, matched, active, busy 0 (1551 ms), retain 23> | | | +-o IOUSBCompositeDriver <class IOUSBCompositeDriver, id 0x100013d67, !registered, !matched, active, busy 0, retain 4> | | | +-o XStation@0 <class IOUSBInterface, id 0x100013d68, registered, matched, active, busy 0 (171 ms), retain 8> | | | +-o XStation@1 <class IOUSBInterface, id 0x100013d69, registered, matched, active, busy 0 (160 ms), retain 9> | | | | +-o IOUSBInterfaceUserClientV3 <class IOUSBInterfaceUserClientV3, id 0x100013d78, !registered, !matched, active, busy 0, retain 9> | | | +-o IOUSBInterface@2 <class IOUSBInterface, id 0x100013d6a, registered, matched, active, busy 0 (679 ms), retain 8> | | | | +-o NovationUSBAudioDevice <class NovationUSBAudioDevice, id 0x100013d7d, registered, matched, active, busy 0 (1 ms), retain 7> | | | | +-o NovationUSBAudioEngine <class NovationUSBAudioEngine, id 0x100013d7e, registered, matched, active, busy 0 (1 ms), retain 9> | | | +-o IOUSBInterface@3 <class IOUSBInterface, id 0x100013d6b, registered, matched, active, busy 0 (166 ms), retain 10> | | | +-o IOUSBInterface@4 <class IOUSBInterface, id 0x100013d6c, registered, matched, active, busy 0 (161 ms), retain 10> | | | +-o IOUSBInterface@5 <class IOUSBInterface, id 0x100013d6d, registered, matched, active, busy 0 (171 ms), retain 9> | | | | +-o IOUSBHIDDriver <class IOUSBHIDDriver, id 0x100013d98, registered, matched, active, busy 0 (5 ms), retain 11> | | | | | +-o CMUSBDevice <class com_orderedbytes_ControllerMate_driver_USBDevice, id 0x100013d9c, registered, matched, active, busy 0 (0 ms), retain 10> | | | | | +-o CMUSBDevicesUserClient <class com_orderedbytes_ControllerMate_driver_USBDeviceUserClient, id 0x100013f13, !registered, !matched, active, busy 0, retain 5>
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51644167.
Nice, thanks! I've just added debug led messages. It looks like this method called few times. And first runs works and receive my current values. But then it switched to wrong interface. Looks i'm wrong somewhere, but anyway good results :) will look further. Looking forward for your commit :+1:
That's probably few interfaces that's determine this conditions:
if((pphost->device_prop.Itf_Desc[iface].bInterfaceClass == USB_AUDIO_CLASS) && \
(pphost->device_prop.Itf_Desc[iface].bInterfaceSubClass == USB_MIDISTREAMING_SubCLASS))
Looking for how-to determine which one is right by additional attributes. DAWs did it somehow :)
DAWs let you choose the interface you want, in the GUI. Since we dont have GUI capabilities in our board, we have to choose automatically.
I was thinking about sweeping all interfaces with a for loop, and sticking with the first interface that has subclass == 3.
of course, on more elaborate keyboards we might be loosing some midi controls with this. On Aug 9, 2014 1:10 PM, "Artyom Nikolaev" [email protected] wrote:
That's probably few interfaces that's determine this conditions:
if((pphost->device_prop.Itf_Desc[iface].bInterfaceClass == USB_AUDIO_CLASS) &&
(pphost->device_prop.Itf_Desc[iface].bInterfaceSubClass == USB_MIDISTREAMING_SubCLASS))Looking for how-to determine which one is right by additional attributes. DAWs did it somehow :)
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51676560.
Yep, but anyway it knows what is audio and what is midi. I'm describing ableton live behaviour. What about to allow switching by blue button in normal not demo mode? We also need some visual feedback like blinking on input packets.
ableton uses the midi subclass field to tell midi apart from audio. if its 0x03 then its midi.
we can support this using the buttons
another ideia is sweeping all interfaces, and accepting all midi messages from all interfaces. since we are making a synth (and not daw) that would be the behavoiur expected by the user (IMHO). On Aug 9, 2014 1:53 PM, "Artyom Nikolaev" [email protected] wrote:
Yep, but anyway it knows what is audio and what is midi. I'm describing ableton live behaviour. What about to allow switching by blue button in normal not demo mode? We also need some visual feedback like blinking on input packets. On Aug 9, 2014 12:47 PM, "tomassch" [email protected] wrote:
DAWs let you choose the interface you want, in the GUI. Since we dont have GUI capabilities in our board, we have to choose automatically.
I was thinking about sweeping all interfaces with a for loop, and sticking with the first interface that has subclass == 3.
of course, on more elaborate keyboards we might be loosing some midi controls with this. On Aug 9, 2014 1:10 PM, "Artyom Nikolaev" [email protected] wrote:
That's probably few interfaces that's determine this conditions:
if((pphost->device_prop.Itf_Desc[iface].bInterfaceClass == USB_AUDIO_CLASS) &&
(pphost->device_prop.Itf_Desc[iface].bInterfaceSubClass == USB_MIDISTREAMING_SubCLASS))Looking for how-to determine which one is right by additional attributes. DAWs did it somehow :)
— Reply to this email directly or view it on GitHub < https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51676560>.
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51677184.
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51677270.
Gather midi input messages all sounds good.
Behaviour you described in previous message it exactly what I did in my commit. We have a loop and break as soon as found matching device. If found nothing touch blue light and return fail code. In practice when I tweaking parameters I see blue light linking on every event and it really changes synthesis parameters as expected but after few changes about 10 it stops receive anything at all. I'm curious how this code can cause this behaviour. It looks like it called on every message.
oh, nice!
this looks like the behaviour I was getting with an usb<->midi cable. it would work for some seconds and then stop. I am out of town now, gonna check end of sunday On Aug 9, 2014 2:04 PM, "Artyom Nikolaev" [email protected] wrote:
Gather midi input messages all sounds good.
Behaviour you described in previous message it exactly what I did in my commit. We have a loop and break as soon as found matching device. If found nothing touch blue light and return fail code. In practice when I tweaking parameters I see blue light linking on every event and it really changes synthesis parameters as expected but after few changes about 10 it stops receive anything at all. I'm curious how this code can cause this behaviour. It looks like it called on every message.
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51677452.
I think we should move searching code outside of USBH_MIDI_InterfaceInit. Just leave a variable here which was defined after USB init (device was connected). But not sure where to place it for now. Have a nice day!
Just found interesting place at void USBH_USR_Configuration_DescAvailable
It also has commented check code.
@tomassch you meant you was getting same with an usb<->midi cable when in code was hardcoded interface number? If yes this is weird, it means problem not in search interface code.
yeah, but I barely tested that interface. did not investigate seriously On Aug 10, 2014 2:21 AM, "Artyom Nikolaev" [email protected] wrote:
@tomassch https://github.com/tomassch you meant you was getting same with an usb<->midi cable when in code was hardcoded interface number? If yes this is weird, it means problem not in search interface code.
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-51692874.
I've discovered that Mr Thorsten Klose has now a working USB midi host driver : http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fmios32%2FSTM32F4xx%2Fmios32_usb_midi.c It is part of his MIOS32 operating system for STM32F4 ( for personal non-commercial use only). See also his sites : uccaps.de and midibox.org In that file, the function USBH_InterfaceInit(USB_OTG_CORE_HANDLE *pdev, void *phost) has the loop for searching a midi interface in the connected device...
How are you guys getting on with the usb midi host driver? I tried the .hex file today and I can't get any response from 4 different midi devices, emu x-49 keyboard, arturia minilab keyboard and 2 arduino controllers, 1 using moco-lufa midi firmware, the other using 'teeonardu', teensy IDE support for arduino leonardo boards. Had you thought about providing serial input as a method to change settings? That would give another incredibly simple way to access them, don't need to change the messages, as midi is serial at 31250 baud.
@MrBlueXav @tomassch Here's what I've found so far, I used usbpcap and wireshark, usbpcap to capture the usb packets of my keyboard, including unplugging and replugging it in, then moving some encoders. I then opened the .pcap file in wireshark and had a look for the midi messages, this gave me the device and the endpoint, my endpoint was 81 (unless I've made a mistake), I changed the code using tomassch's original 'interfacetoUse' fix and changing the endpoint to 81 and I now have a working deskriptor :+1:
I think we need to look at the endpoints too (I know very little about usb) as well as the device that's being used.
very good to hear that it works in yet another controller.
i am all about to make it flexible, auto detecting the controller parameters.
mrBlueXav suggested using some other people's code to improve the usb interface. On Nov 13, 2014 1:06 PM, "Reggie" [email protected] wrote:
@MrBlueXav https://github.com/MrBlueXav @tomassch https://github.com/tomassch Here's what I've found so far, I used usbpcap and wireshark, usbpcap to capture the usb packets of my keyboard, including unplugging and replugging it in, then moving some encoders. I then opened the .pcap file in wireshark and had a look for the midi messages, this gave me the device and the endpoint, my endpoint was 81 (unless I've made a mistake), I changed the code using tomassch's original 'interfacetoUse' fix and changing the endpoint to 81 and I now have a working deskriptor [image: :+1:]
I think we need to look at the endpoints too (I know very little about usb) as well as the device that's being used.
— Reply to this email directly or view it on GitHub https://github.com/MrBlueXav/Dekrispator/issues/1#issuecomment-62838902.
I know very little about usb at all, I'm surprised I got it working. When I first installed the original firmware, it didn't work at all, then I tried your code tomassch and that didn't work, I didn't get any blue lights at all but with my changes it saw the device and would work for a very short time (10-20 seconds) and stop working, then the usb host would start to loop resetting the keyboard.
My solution was to unplug the stm32F4 from my PC and directly into a usb apple phone charger, so the freezing issue you talk about in previous posts could be power related or it could be related to the usb client port being plugged into a PC?
Also, if you guys are using usb hubs at all then that can cause issues, especially if they're cheap ones, cheap usb cables can also cause issues with voltage drop, which causes problems with power and stability.
apparently my endpoint being 81 is fairly irrelevant, I made a mistake changing the 0x80 mask.
It also appears that all midi devices should have an audio interface that shouldn't do anything if it's a simple keyboard/controller. so essentially we should ignore at least the first (0) interface and concentrate on anything after that.
After some great advice I used usbView to check the descriptors of my midi devices, they all have an unused audio interface as the first interface, it's part of the spec I've been told.
@tomassch @MrBlueXav I added channel filtering to my fork, it should make it much easier to keep the existing 7bit controls and any refinements we add seperate, that way it will still work as it was originally intended.
Hello everybody ! Thank you for "Dekrispatoring" ! I've not much time for programming apart from holidays time... However I'm at the moment re-diving in the arcanes of USB MIDI and see if I could rewrite the driver on top of the new Cube HAL library from ST with the new USB Host stack. I'm restarting from the demo project "wave player and recorder" as all the board configuration is done in it. It might be long...
Well, using Thorsten Klose's MIOS32 driver is too complicated for me I'm afraid... I'm trying now with the existing ST's CDC class driver which seems to be close to the MIDIStreaming class.
We have a working usb host implementation that is very stable, I think we might just need to adapt a little bit of the mios32 code for our own use. btw. @MrBlueXav did you look at this? https://github.com/norbim1/preenFM2/blob/master/src/usb/usbd_midi_core.c
It's another stm32f4 synth, it's got usb device support that could be useful.
It was not that stable for me here at home : my nanoKontrol disconnects episodically ! Work is in progress with my rewriting on HAL Cube new library : midi devices get recognized at connection/disconnection/reconnection and datas are received (and should be sent too). Connection seems very stable. No midi parsing yet, I don't know at the moment what's in the reception buffer...
I think the disconnection issue is with the nanokontrol/stm32F4 rather than the software, imho it seems to be a power issue, I have been leaving mine on for days at a time and it's been rock solid.