> On Jul 29, 2020, at 11:21 PM, Brian Willoughby <[email protected]> 
> wrote:
> 
> Hola, Andy.
> 
> If you can grab a copy of USB Prober.app from Apple and send me a dump of the 
> USB Descriptors for the working and non-working devices, I might be able to 
> help you.

Sorry for the short delay in responding. I ran a lot of tests yesterday to see 
if I could sort this out. Thanks for taking the time to consider this issue.

Ah, USB Prober, a nice piece of kit from Apple that they’ve seemed to drop on 
the floor. The version I have is 4.5.9, and I think I downloaded that as part 
of the hardware tools for 10.9. It does run on Catalina although the logging 
kext does not. But it’s good enough for dumping descriptors. Actually, that’s 
not true — it doesn’t understand the USB MIDI class and shows Audio/Streaming 
for the streaming interface and “Unknown Interface SubClass Type” for the MIDI 
Jack descriptors.

I beat WireShark into submission and was able to capture the descriptors for 
both the working (EFM32) and not-working (TM4C) devices, and they are identical 
(by design and intent). The only difference is that I assigned different PIDs 
to each (in the Device Descriptor) and that the ID strings are different make 
it obvious which is which.

The design implements the mandatory Audio Control Interface and the MIDI 
Streaming Interface. There is one Bulk In endpoint and one Bulk Out endpoint.

There are eight MIDI Jacks. The idea is to expose two “Ports” to the computer. 
Each port has one MIDI In and one MIDI Out “connector” (the word used in Audio 
MIDI Setup). So there are four Embedded MIDI Jacks and four External MIDI 
Jacks. 

While this network description doesn’t indicate it as such, Port 1 (as seen by 
the computer) is used to access stuff “inside the device.” That is, buttons and 
knobs on the device send messages back to the computer on Port 1 (which is 
actually Cable 0), and messages from the computer to set LEDs and such come in 
on Port 1 (actually Cable 0).

Port 2 (Cable 1) connects to a legacy serial MIDI port on a pair of DIN jacks.

Here is the WireShark capture of the Configuration Descriptor (from Catalina).

---------------------------------------------------------------

Frame 782: 169 bytes on wire (1352 bits), 169 bytes captured (1352 bits) on 
interface XHC20, id 0
    Interface id: 0 (XHC20)
        Interface name: XHC20
    Encapsulation type: USB packets with Darwin (macOS, etc.) headers (182)
    Arrival Time: Jul 30, 2020 20:39:33.652161000 MST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1596166773.652161000 seconds
    [Time delta from previous captured frame: 0.000328000 seconds]
    [Time delta from previous displayed frame: 0.000328000 seconds]
    [Time since reference or first frame: 4.712039000 seconds]
    Frame Number: 782
    Frame Length: 169 bytes (1352 bits)
    Capture Length: 169 bytes (1352 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: 
usb:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio:usbaudio]
USB URB
    [Source: 20.30.0]
    [Destination: host]
    Darwin header bcdVersion: 0x0101
    Darwin header length: 40
    Request type: COMPLETE (1)
    I/O length [bytes]: 129
    Request status: kIOReturnSuccess (0x00000000)
    Isochronous transfer number of frames: 0
    I/O ID: 0x00000000005c4c0a
    Device location ID: 0x14141200
    Device speed: Full (1)
    USB device index: 30
    Endpoint address: 0x80
    .... 0000 = Endpoint number: 0, Direction: IN
        1... .... = Direction: IN (1)
        .... 0000 = Endpoint number: 0
    Endpoint transfer type: Control (0)
    [Request in: 781]
    [Time from request: 0.000328000 seconds]
CONFIGURATION DESCRIPTOR
    bLength: 9
    bDescriptorType: 0x02 (CONFIGURATION)
    wTotalLength: 129
    bNumInterfaces: 2
    bConfigurationValue: 1
    iConfiguration: 5
    Configuration bmAttributes: 0xc0  SELF-POWERED  NO REMOTE-WAKEUP
        1... .... = Must be 1: Must be 1 for USB 1.1 and higher
        .1.. .... = Self-Powered: This device is SELF-POWERED
        ..0. .... = Remote Wakeup: This device does NOT support remote wakeup
    bMaxPower: 50  (100mA)
INTERFACE DESCRIPTOR (0.0): class Audio
    bLength: 9
    bDescriptorType: 0x04 (INTERFACE)
    bInterfaceNumber: 0
    bAlternateSetting: 0
    bNumEndpoints: 0
    bInterfaceClass: Audio (0x01)
    bInterfaceSubClass: Audio Control (0x01)
    bInterfaceProtocol: 0x00
    iInterface: 0
Class-specific Audio Control Interface Descriptor: Header Descriptor
    bLength: 9
    bDescriptorType: 0x24 (audio class interface)
    Subtype: Header Descriptor (0x01)
    Version: 1.00
    Total length: 9
    Total number of interfaces: 1
    Interface number: 1
INTERFACE DESCRIPTOR (1.0): class Audio
    bLength: 9
    bDescriptorType: 0x04 (INTERFACE)
    bInterfaceNumber: 1
    bAlternateSetting: 0
    bNumEndpoints: 2
    bInterfaceClass: Audio (0x01)
    bInterfaceSubClass: MIDI Streaming (0x03)
    bInterfaceProtocol: 0x00
    iInterface: 0
Class-specific MIDI Streaming Interface Descriptor: Header Descriptor
    bLength: 7
    bDescriptorType: 0x24 (audio class interface)
    Subtype: Header Descriptor (0x01)
    Version: 1.00
    Total length: 97
Class-specific MIDI Streaming Interface Descriptor: MIDI IN Jack descriptor
    bLength: 6
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI IN Jack descriptor (0x02)
    Jack Type: Embedded (0x01)
    Jack ID: 1
    String descriptor index: 0
Class-specific MIDI Streaming Interface Descriptor: MIDI OUT Jack descriptor
    bLength: 9
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI OUT Jack descriptor (0x03)
    Jack Type: External (0x02)
    Jack ID: 2
    Number of Input Pins: 1
    Connected MIDI Entity: 1
    Entity Output Pin: 1
    String descriptor index: 0
Class-specific MIDI Streaming Interface Descriptor: MIDI IN Jack descriptor
    bLength: 6
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI IN Jack descriptor (0x02)
    Jack Type: External (0x02)
    Jack ID: 3
    String descriptor index: 0
Class-specific MIDI Streaming Interface Descriptor: MIDI OUT Jack descriptor
    bLength: 9
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI OUT Jack descriptor (0x03)
    Jack Type: Embedded (0x01)
    Jack ID: 4
    Number of Input Pins: 1
    Connected MIDI Entity: 3
    Entity Output Pin: 1
    String descriptor index: 0
Class-specific MIDI Streaming Interface Descriptor: MIDI IN Jack descriptor
    bLength: 6
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI IN Jack descriptor (0x02)
    Jack Type: Embedded (0x01)
    Jack ID: 5
    String descriptor index: 0
Class-specific MIDI Streaming Interface Descriptor: MIDI OUT Jack descriptor
    bLength: 9
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI OUT Jack descriptor (0x03)
    Jack Type: External (0x02)
    Jack ID: 6
    Number of Input Pins: 1
    Connected MIDI Entity: 5
    Entity Output Pin: 1
    String descriptor index: 0
Class-specific MIDI Streaming Interface Descriptor: MIDI IN Jack descriptor
    bLength: 6
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI IN Jack descriptor (0x02)
    Jack Type: External (0x02)
    Jack ID: 7
    String descriptor index: 0
Class-specific MIDI Streaming Interface Descriptor: MIDI OUT Jack descriptor
    bLength: 9
    bDescriptorType: 0x24 (audio class interface)
    Subtype: MIDI OUT Jack descriptor (0x03)
    Jack Type: Embedded (0x01)
    Jack ID: 8
    Number of Input Pins: 1
    Connected MIDI Entity: 7
    Entity Output Pin: 1
    String descriptor index: 0
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x81  IN  Endpoint:1
        1... .... = Direction: IN Endpoint
        .... 0001 = Endpoint Number: 0x1
    bmAttributes: 0x02
        .... ..10 = Transfertype: Bulk-Transfer (0x2)
    wMaxPacketSize: 64
        .... ..00 0100 0000 = Maximum Packet Size: 64
    bInterval: 0
Class-specific MIDI Streaming Endpoint Descriptor
    bLength: 6
    bDescriptorType: 0x25 (audio class endpoint)
    Subtype: General Descriptor (0x01)
    Number of Embedded MIDI Jacks: 2
    Associated Embedded Jack ID: 4
    Associated Embedded Jack ID: 8
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x01  OUT  Endpoint:1
        0... .... = Direction: OUT Endpoint
        .... 0001 = Endpoint Number: 0x1
    bmAttributes: 0x02
        .... ..10 = Transfertype: Bulk-Transfer (0x2)
    wMaxPacketSize: 64
        .... ..00 0100 0000 = Maximum Packet Size: 64
    bInterval: 0
Class-specific MIDI Streaming Endpoint Descriptor
    bLength: 6
    bDescriptorType: 0x25 (audio class endpoint)
    Subtype: General Descriptor (0x01)
    Number of Embedded MIDI Jacks: 2
    Associated Embedded Jack ID: 1
    Associated Embedded Jack ID: 5

————————————————————————————————————————————

and here is the Device Descriptor.

Frame 764: 58 bytes on wire (464 bits), 58 bytes captured (464 bits) on 
interface XHC20, id 0
    Interface id: 0 (XHC20)
        Interface name: XHC20
    Encapsulation type: USB packets with Darwin (macOS, etc.) headers (182)
    Arrival Time: Jul 30, 2020 20:39:33.647721000 MST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1596166773.647721000 seconds
    [Time delta from previous captured frame: 0.000173000 seconds]
    [Time delta from previous displayed frame: 0.000173000 seconds]
    [Time since reference or first frame: 4.707599000 seconds]
    Frame Number: 764
    Frame Length: 58 bytes (464 bits)
    Capture Length: 58 bytes (464 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    [Source: 20.30.0]
    [Destination: host]
    Darwin header bcdVersion: 0x0101
    Darwin header length: 40
    Request type: COMPLETE (1)
    I/O length [bytes]: 18
    Request status: kIOReturnSuccess (0x00000000)
    Isochronous transfer number of frames: 0
    I/O ID: 0x00000000005c4c01
    Device location ID: 0x14141200
    Device speed: Full (1)
    USB device index: 30
    Endpoint address: 0x80
    .... 0000 = Endpoint number: 0, Direction: IN
        1... .... = Direction: IN (1)
        .... 0000 = Endpoint number: 0
    Endpoint transfer type: Control (0)
    [Request in: 763]
    [Time from request: 0.000173000 seconds]
DEVICE DESCRIPTOR
    bLength: 18
    bDescriptorType: 0x01 (DEVICE)
    bcdUSB: 0x0200
    bDeviceClass: Device (0x00)
    bDeviceSubClass: 0
    bDeviceProtocol: 0 (Use class code info from Interface Descriptors)
    bMaxPacketSize0: 64
    idVendor: Unknown (0xXYZW) [REDACTED]
    idProduct: Unknown (0xWZYZ) [REDACTED]
    bcdDevice: 0x0100
    iManufacturer: 1
    iProduct: 2
    iSerialNumber: 3
    bNumConfigurations: 1

———————————————————————————————————

Other fun facts.

1. As soon as the Set Configuration message is sent to the device and the 
device ACKs it, the host sends one SYSEX message with no data, just the start 
and end markers F0 and F7. I don’t know why it does this or what the host 
expects as a response to it. If it’s a device-identify request it’d be nice if 
there was some documentation somewhere indicating such.

2. Both designs have buttons and other controls on board. Pushing a button or 
turning an encoder sends a message to the host. Even though the computer does 
not think that the TM4C design has any ports, when I push a button, I see on 
the WireShark trace that a USB MIDI message is actually going across the bus to 
the host and the host is acknowledging it. (Obviously since the computer 
doesn’t think that the device has any MIDI ports, I can’t send messages in that 
direction.)

3. Both the EFM32 design and the TM4C design work as expected on Mojave. The 
EFM32 design works on Catalina but the TM4C design does not. This leads me to 
think that something changed from Mojave to Catalina, hence the subject of this 
request, but I’ll be damned if I can figure it out. From the WireShark captures 
it looks like both designs do exactly the same thing and respond in the same 
way. I just don’t know what is causing Catalina to trip on this.

> I've designed several USB-MIDI Devices based on the PIC18F processor, one 
> with the TMS320VC55xx, and I've also designed USB firmware for the TM4C1294, 
> but haven't gotten around to doing USB-MIDI on the TM4C. The TivaWare USB 
> library can be convoluted, but the source code is all provided, and it's 
> possible to bend it into shape if you really study it.

TivaWare USB is bending my mind, to be sure. I mean, MIDI is not difficult! I 
think it’s actually the simplest of all of the standard USB classes.

> I also have the Beagle USB Protocol Analyzer, and I recommend it for 
> diagnosing problems like this, if USB Prober.app and debugging the firmware 
> itself do not uncover the issues.

I dug out my old Ellisys USB Tracker 110 and … it doesn’t work any more. I 
might have to spring for the Beagle. Oh well, it’s not like we’re going on 
vacation this year.

> Wow! Apple used to host a USB mailing list, but I see that it seems to have 
> gone away. I was a subscriber, but I don't see any messages since December 
> 2017.

My email to that list bounced. I guess Apple shut it down. I assume that most 
developers choose to go with standard classes, so anything that accesses that 
hardware ultimately goes through APIs for that application (to be redundant). 
That is, a USB-MIDI device goes through the MIDI services. Nobody wants to 
write a driver or a kext.

Again, thanks for considering this issue. It’s certainly weird.


> Brian Willoughby
> Sound Consulting
> 
> 
> On Jul 29, 2020, at 9:43 PM, Andy Peters via Coreaudio-api 
> <[email protected]> wrote:
>> Hola, all, perhaps someone can help. This is a USB program and a MIDI 
>> problem, and I don’t know which list is best suited for the questions.
>> 
>> I’m developing a product that includes a USB MIDI device interface. I 
>> started out by implementing support for the USB MIDI Class 1.0 over Full 
>> Speed USB 2.0 on a Silicon Labs EFM8UB2 (8-bit 8051) microcontroller. The 
>> device implemented support for two MIDI Ports in each direction IN and OUT. 
>> The device descriptor includes the proper Jack descriptions to make this 
>> happen.
>> 
>> That works. And specifically, by “works” I mean:
>> 
>> a. it enumerates as a USB MIDI device on Mojave and Catalina (and Windows 7)
>> b. in Audio MIDI Setup’s MIDI Studio on both Mojave and Catalina, the device 
>> shows that it has two IN and two OUT ports.
>> c. Buttons on the micro board send MIDI messages to the host when pressed, 
>> and a MIDI monitor program like Pocket MIDI shows the proper messages on its 
>> incoming-message window.
>> d. Messages sent from Pocket MIDI or from Python (pyMidi) control LEDs on 
>> the board and the micro has a terminal UART port and I parse the received 
>> messages and route them out that terminal and they are what I sent.
>> 
>> Again, this all works on both Mojave and Catalina.
>> 
>> I ported the code to the Silicon Labs EFM32GG11 device (32-bit ARM 
>> Cortex-M4) with the same descriptors and mostly the same handling code 
>> (Silicon Labs’ USB device stacks for the ARM and 8051s is highly similar). 
>> Like the EFM8 case it is a Full Speed USB 2.0 device and it works as 
>> detailed above.
>> 
>> Next, I ported the code to the TI Tiva TM4C1294 (much faster 32-bit ARM 
>> Cortex-M4F) processor. The reason is that the Tiva can support High Speed 
>> USB 2.0 with an external PHY but it also supports Full Speed USB 2.0 over an 
>> on-chip PHY, and I am using the latter (Full Speed). The TI USB stack is not 
>> at all like the SiLabs’ stack, and to be honest it’s overcomplicated. It 
>> uses the same descriptors as the previous implementations, but I had to fit 
>> it into TI’s weird format. After more effort than I anticipated, I got to 
>> the point where it “works.” 
>> 
>> And by this I mean:
>> 
>> a. On both Mojave and Catalina, the device successfully enumerates as a USB 
>> MIDI Class Device.
>> b. On both Mojave and Catalina, the device appears in Audio MIDI Setup’s 
>> MIDI Studio.
>> 
>> But.
>> 
>> On Mojave only, the device’s two IN ports and two OUT ports show up in MIDI 
>> Studio. I can use Pocket MIDI to send messages to the device, which responds 
>> as expected (prints the messages to the terminal, lights LEDs). I can push 
>> buttons and send Note On and Note Off messages back to the computer, and 
>> Pocket MIDI displays the messages in its input monitor terminal. In other 
>> words, it behaves as expected. 
>> 
>> On Catalina, however, the device’s IN and OUT ports _do not_ show up in MIDI 
>> Studio. Pocket MIDI does not recognize the ports. I can neither send 
>> messages to nor receive messages from the device.
>> 
>> I’ve searched and searched and cannot find anything describing the 
>> differences between the USB MIDI implementation on Catalina vs Mojave. 
>> Obvious something has changed. Catalina is expecting something that was not 
>> necessary under Mojave.
>> 
>> I do see that after connection and immediately after USB configuration, both 
>> Mojave and Catalina send a two-byte SYSEX message 06 f0 f7 to the device. 
>> (06 is the cable #0 and code-index-number 6 indicating SYSEX.) I don’t 
>> respond to it, and I cannot find any documentation explaining what this 
>> message is for.
>> 
>> So, please — what are the differences between Mojava and Catalina that allow 
>> a device to work on the former and fail on the latter?
>> 
>> — a
> 

Andy Peters
5511 E Rosewood St
Tucson, AZ 85711
520-907-2262
[email protected]



 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to