MOTU Midi Timepiece AV
I hooked up a MOTU Midi Timepiece AV to my Linux box.
The context
I've read there is no driver to use the MTP AV with Linux. Well, actually, there was one (mtpav.c) included with the package alsa-driver up to version 1.0.25. But, this package is now obsolete, embedded into the source of kernel.
Since there is a driver for Windows, still available with ClockWork at MOTU site, I wanted to investigate the protocol.
Linux, Windows and Cubase SX
Tools
- A computer running Linux and enough memory. Mine is HP XW6600, 8 cores, 16GB, running Ubuntu 20.04.
- A MOTU Midi Timepiece AV (MTP AV) USB compatible. Warning: there are 2 EPROM, one for Mac, one for Windows. Mine was the Mac version, but I installed the EPROM for Windows. ordered directly from MOTU website several years ago.
- The Windows driver for MTP AV USB MIDI Installer for Windows, available from MOTU site.
- Oracle Virtual Box, latest version (currently 6.1.18) and the Extension Pack. Available from VirtualBox site. Do not use the version that comes with Ubuntu. Check this link for details
- An installable image of Windows. Mine is Windows 7 32 bits.
- A sequencer, or any other tool able to send MIDI data. I used Cubase SX version 2.2.0.
- Wireshark, latest version (currently 3.2.3)
- Some knowledge of awk, to explore the decoded protocole easily
Preparation
- In VirtualBox, create a new VM with enough memory and disk.
- Install Windows and boot the VM
- Make sure the USB are enabled. Check this link for details.
- Install USB MIDI Installer for Windows; this will also install ClockWork. From here, you should be able to see the MTP AV.
- Install your favorite sequencer.
- Check your MTP AV is recognized. Send some MIDI notes: the USB In LED from the MTP should blink.
- In Linux, open a terminal (CTRL+ALT+T)
- In Linux terminal, identify yourself, load the monitoring module for USB and add ACL to grant read access to the usbmon interfaces:
# Load the monitoring module for USB $ sudo modprobe usbmon # Identify yourself $ whoami francois # Add ACL to grant read access to the usbmon interfaces $ sudo setfacl -m u:francois:r /dev/usbmon* # Figure out which monitor to use (Bus 001 = usbmon1) $ sudo lsusb Bus 001 Device 004: ID 07fd:0001 Mark of the Unicorn MIDI Interface ...
Check this link for details. - Start Wireshark and configure it to decode the USB protocol. Check this link for details.
- In Wireshark, scan the usbmon device you've identified. If it's not the good one, do trials and errors.
- Play some notes with your sequencer and scan the USB.
Collected data
To understand how USB protocol works on Linux, please check this link.Initialization
- To capture the initialization sequence:
- Start the capture in Wireshark
- Disable the device in VirtualBox before starting the VM
- Start the VM
- Enable the device; Wireshark should detect the initialization sequence
No. Time Destination Length Info 1 0.000000 host → MTP 64 GET DESCRIPTOR Request DEVICE 2 0.000504 MTP → host 82 GET DESCRIPTOR Response DEVICE DEVICE DESCRIPTOR ... idVendor: Mark of the Unicorn (0x07fd) idProduct: MIDI Interface (0x0001) ... 3 0.000534 host → MTP 64 GET DESCRIPTOR Request CONFIGURATION 4 0.000986 MTP → host 73 GET DESCRIPTOR Response CONFIGURATION Configuration bmAttributes: 0x80 NOT SELF-POWERED NO REMOTE-WAKEUP bMaxPower: 50 (100mA) 5 0.101078 host → MTP 64 GET DESCRIPTOR Request CONFIGURATION 6 0.103001 MTP → host 201 GET DESCRIPTOR Response CONFIGURATIONThe response is 4 INTERFACE DESCRIPTORS (0 to 3), each with 2 ENDPOINT DESCRIPTORS (1 IN, 1 OUT) The last descriptor (UNKNOWN DESCRIPTOR) contains the string "MIDI Time piece AV" (apparently in Unicode).
------------------------------------------------------------ INTERFACE DESCRIPTOR (0.0): class Vendor Specific ENDPOINT DESCRIPTOR bEndpointAddress: 0x81 IN Endpoint:1 bmAttributes: 0x03 wMaxPacketSize: 32 bInterval: 2 ENDPOINT DESCRIPTOR bEndpointAddress: 0x02 OUT Endpoint:2 bmAttributes: 0x01 wMaxPacketSize: 14 bInterval: 1 ------------------------------------------------------------ INTERFACE DESCRIPTOR (1.0): class Vendor Specific ENDPOINT DESCRIPTOR ... ENDPOINT DESCRIPTOR ... ------------------------------------------------------------ INTERFACE DESCRIPTOR (2.0): class Vendor Specific ENDPOINT DESCRIPTOR ... ENDPOINT DESCRIPTOR ... ------------------------------------------------------------ INTERFACE DESCRIPTOR (3.0): class Vendor Specific ENDPOINT DESCRIPTOR ... ENDPOINT DESCRIPTOR ... ------------------------------------------------------------ UNKNOWN DESCRIPTOR ... ------------------------------------------------------------ 7 0.103338 host → MTP 64 SET CONFIGURATION Request 8 0.103617 MTP → host 64 SET CONFIGURATION ResponseFrom here, the host talks with the internal USB HUB to add new interfaces. A new configuration request is made to the MTP (?), providing the same result. Then, the host sends URB_Interrupt in to the new interface created (1.4.1). It also sends a frame URB_ISOCHRONOUS out to a new interface 1.4.2 with a SYSEX and a filler
f0 00 00 33 02 30 00 f7 ff ff ff ff 01 00Check the MTP AV SYSEX here
Output and acknowledge
Here are some data I've collected:
- When a note is played, the following frame is sent and the MTP replies back:
No Time Source Destination Protocol Length Info 1 0.000000 host 1.14.2 USB 94 URB_ISOCHRONOUS out 2 0.001753 1.14.2 host USB 80 URB_ISOCHRONOUS out
Output frame in details:
USB URB [Source: host] [Destination: 1.14.2] URB id: 0xffff9d97fe5df500 URB type: URB_SUBMIT ('S') URB transfer type: URB_ISOCHRONOUS (0x00) Endpoint: 0x02, Direction: OUT Device: 14 URB bus id: 1 Device setup request: not relevant ('-') Data: present (0) URB sec: 1614648348 URB usec: 700796 URB status: Operation now in progress (-EINPROGRESS) (-115) URB length [bytes]: 14 Data length [bytes]: 30 [Response in: 2] [bInterfaceClass: Unknown (0xffff)] ISO error count: 0 Number of ISO descriptors: 1 Interval: 1 Start frame: 0 Copy of Transfer Flags: 0x00000002, ISO ASAP Number of ISO descriptors: 1 USB isodesc 0 [Cross-device link (-EXDEV)] (14 bytes) Status: Cross-device link (-EXDEV) (-18) Offset [bytes]: 0 Length [bytes]: 14 ISO Data: 903c64ffffffffffffffffff0500 Padding: 0x00000000The field ISO Data is 14 bytes and contains the MIDI:
90 3c 64 ff ff ff ff ff ff ff ff ff 05 00 -------- Blue: standard MIDI message (Note On, Channel 1, C4, velocity 100) Black: filler Green: exact role not yet determined; it seems to increase gradually.The reply (frame 2) is 80 bytes long and contains no data.
The ISO Data field
Here are some examples I've collected (all examples on MIDI channel 1):90 3c 64 ff ff ff ff ff ff ff ff ff 05 00: Note On, C4, vel 100 80 3c 40 ff ff ff ff ff ff ff ff ff 05 00: Note Off, C4, rel 64Note on and off can be grouped in the same frame:
80 3e 40 90 3f 64 ff ff ff ff ff ff 05 00: - 80 3e 40: Note Off Chan 1, note D4, rel 64 - 90 3f 64: Note On, Chan 1, note E4, vel 100Grouped notes (chords):
90 3c 64 3d 64 3e 64 ff ff ff ff ff 09 00 80 3c 40 3d 40 3e 40 ff ff ff ff ff 09 00Several frames can be used if one is not sufficient:
90 3c 64 3d 64 3e 64 3f 64 40 64 41 0a 00 64 42 64 43 64 44 64 45 64 46 64 47 0a 00 64 ff ff ff ff ff ff ff ff ff ff ff 0a 00 80 43 40 44 40 45 40 46 40 47 40 ff 0a 00 3c 40 3d 40 3e 40 3f 40 40 40 41 40 0a 00 42 40 ff ff ff ff ff ff ff ff ff ff 0a 00When another output of MTP AV is selected:
f5 02 90 3c 64 ff ff ff ff ff ff ff 09 00 - select output 2Possible outputs are:
f5 01 output 1 f5 02 output 2 ... f5 08 output 8 f5 63 ADAT
SYSEX
The MTP AV MIDI Implementation chart is available here: SYSEX COMMANDS FOR Motu - TimepieceAV - MTP AV
Driver
The driver for MTP is calledmtpav.ko
. Historically, drivers for sound modules were packed with ALSA, in a folder called alsa-driver
. However, the source for drivers are now shipped within the kernel source. My kernel did not have this module, so I had to build it.
- Go to your home directory (not /usr/src)
- Install the source of your kernel (actually, you'll get a tarball with the sources). I also had to install lex/yacc; in Linux world flex and bison (not sure if it is used).
# apt-get install linux-source # apt-get install flex # apt-get install bison
- Untar the sources, configure and build the drivers
# tar xf linux-source-5.4.0.tar.bz2 # cd linux-source-5.4.0 # make oldconfig # make prepare # make modules-prepare # make M=sound/drivers # cp sound/drivers/snd-mtpav.ko /lib/modules/5.4.0-66-generic/kernel/sound/drivers
Unfortunatelly, it fails so far...# modprobe snd-mtpav modprobe: ERROR: could not insert 'snd_mtpav': Exec format error
Comments