Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fireface UCX support #16

Open
tempete99 opened this issue Dec 12, 2024 · 22 comments
Open

Fireface UCX support #16

tempete99 opened this issue Dec 12, 2024 · 22 comments

Comments

@tempete99
Copy link

Hello !
I've been trying to make oscmixer work with a Fireface UCX (first generation, latest firmware), unfortunately with no success.
Here is what I get when I run lsusb on it:

Bus 002 Device 052: ID 0424:3fb9 Microchip Technology, Inc. (formerly SMSC) Fireface UCX (23648426)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x0424 Microchip Technology, Inc. (formerly SMSC)
  idProduct          0x3fb9 
  bcdDevice            0.01
  iManufacturer           1 RME
  iProduct                2 Fireface UCX (23648426)
  iSerial                 3 EC7E370355FD9C8
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x01e8
    bNumInterfaces          5
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         4
      bFunctionClass          1 Audio
      bFunctionSubClass       0 
      bFunctionProtocol      32 
      iFunction               0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol     32 
      iInterface              0 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               2.00
        bCategory               8
        wTotalLength       0x0055
        bmControls           0x00
      AudioControl Interface Descriptor:
        bLength                 8
        bDescriptorType        36
        bDescriptorSubtype     10 (CLOCK_SOURCE)
        bClockID                1
        bmAttributes            3 Internal programmable clock 
        bmControls           0x03
          Clock Frequency Control (read/write)
        bAssocTerminal          0
        iClockSource            0 
      AudioControl Interface Descriptor:
        bLength                17
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             3
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bCSourceID              1
        bNrChannels             2
        bmChannelConfig    0x00000000
        iChannelNames           0 
        bmControls         0x0000
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                17
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             5
        wTerminalType      0x0201 Microphone
        bAssocTerminal          0
        bCSourceID              1
        bNrChannels            18
        bmChannelConfig    0x00000000
        iChannelNames           0 
        bmControls         0x0000
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             4
        wTerminalType      0x0301 Speaker
        bAssocTerminal          0
        bSourceID               2
        bCSourceID              1
        bmControls         0x0000
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             6
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bSourceID               5
        bCSourceID              1
        bmControls         0x0000
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                10
        bDescriptorType        36
        bDescriptorSubtype      6 (FEATURE_UNIT)
        bUnitID                 2
        bSourceID               3
        bmaControls(0)     0x0000000c
          Volume Control (read/write)
        iFeature                0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              0 
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           3
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels             2
        bmChannelConfig    0x00000000
        iChannelNames           0 
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            4
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes           17
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Feedback
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       2
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              0 
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           3
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels            18
        bmChannelConfig    0x00000000
        iChannelNames           0 
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            4
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes           17
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Feedback
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              0 
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           6
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels            18
        bmChannelConfig    0x00000000
        iChannelNames           0 
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            4
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       2
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              0 
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           6
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels             2
        bmChannelConfig    0x00000003
          Front Left (FL)
          Front Right (FR)
        iChannelNames           0 
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            4
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      3 MIDI Streaming
      bInterfaceProtocol      0 
      iInterface              2 Fireface UCX (23648426)
      MIDIStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0061
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                 3
        bNrInputPins            1
        baSourceID( 0)          2
        BaSourcePin( 0)         1
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                 2
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                 7
        bNrInputPins            1
        baSourceID( 0)          6
        BaSourcePin( 0)         1
        iJack                   5 Port 2
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                 6
        iJack                   5 Port 2
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                11
        bNrInputPins            1
        baSourceID( 0)         10
        BaSourcePin( 0)         1
        iJack                   6 Port 3
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                10
        iJack                   6 Port 3
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 1
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                 4
        bNrInputPins            1
        baSourceID( 0)          4
        BaSourcePin( 0)         1
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 5
        iJack                   5 Port 2
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                 8
        bNrInputPins            1
        baSourceID( 0)          8
        BaSourcePin( 0)         1
        iJack                   5 Port 2
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 9
        iJack                   6 Port 3
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                12
        bNrInputPins            1
        baSourceID( 0)         12
        BaSourcePin( 0)         1
        iJack                   6 Port 3
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x07  EP 7 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 7
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         3
          baAssocJackID( 0)       1
          baAssocJackID( 1)       5
          baAssocJackID( 2)       9
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x86  EP 6 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 7
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         3
          baAssocJackID( 0)       3
          baAssocJackID( 1)       7
          baAssocJackID( 2)      11
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x88  EP 8 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x09  EP 9 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  bNumConfigurations      0
Device Status:     0xff00
  (Bus Powered)

aconnect -l shows 3 MIDI ports. Only the 3rd one shows SysEx activity.
Running aseqdump -p 20:2 I get mostly a repetition of :
20:2 System exclusive F0 00 20 0D 10 00 00 34 00 78 03 F7

And sometimes some of these messages as aseqdump starts :

20:2   System exclusive           F0 00 20 0D 10 00 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 F7
20:2   System exclusive           F0 00 20 0D 10 00 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03
20:2   System exclusive           00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00 34 00 78 03 00

I'm not sure I'll be able to make this work as I'm mostly musician and only fiddling with computers occasionally. But it would be great to be able to control this interface when it's on class compliant mode ! Fingers crossed, if anyone has time to help 🤞

@tempete99 tempete99 changed the title Fireface UCX Support Fireface UCX support Dec 12, 2024
@huddx01
Copy link
Contributor

huddx01 commented Dec 13, 2024

As the readme states: Only UCX II is supported.
If you do not modify the respective code before compiling for your UCX, it wont work.
Anyhow, it seems that although the pids are same (0x3fb9), your vid (0x0424) differs from UCXII in cc mode.
See here

What (probably means) the registers also differ...

So, you would have to capture the traffic, have look in the other units issues and the wiki, especially protocol and capture.

@tempete99
Copy link
Author

I tried to compile so that it would look for "Fireface UCX" instead of "Fireface UCX II" in oscmix and the web frontend. Turns out things are a little bit more complicated 😂
I'll try to capture traffic and see where I end up but it might be a harder computing journey than what I'm capable of. Thank you for your reply!

@huddx01
Copy link
Contributor

huddx01 commented Dec 15, 2024

As the UCX and UCX II should be quite similar...

Before trying the capturing traffic thing, maybe an idea would be to check first, if the basic register addresses work with your UCX, too. I mean as described in the wiki protocol page (which is for UCX II).
The easiest way would be to try to set some registers/values via the regtool.
F.ex. switch 48v on Mic1/Mic2 on and off (indicated by the LEDs on your UCX)...

if you did not compile it yet, you can compile it via:
make tools/regtool

Then run:
./tools/regtool -s -w 20:2 0009 0001 - to see if your 48v Mic1 LEDs turns on
./tools/regtool -s -w 20:2 0009 0000 - to see if your 48v Mic1 LEDs turns off
./tools/regtool -s -w 20:2 0049 0001 - to see if your 48v Mic2 LEDs turns on
./tools/regtool -s -w 20:2 0049 0000 - to see if your 48v Mic2 LEDs turns off

If this works, it could be an indicator that your UCX registers are quite similar to these from the UCXII.

@tempete99
Copy link
Author

With a bit of guessing I found
./tools/regtool -s -w 20:2 0008 0001 turns 48v on on channel 1
./tools/regtool -s -w 20:2 0108 0001 turns 48v on on channel 2
There are some differences already.
If I understand correctly the next step would be to try listening USB traffic when using TotalMix on macOS or Windows, and modify the registers list with new values for my device. Right?

@huddx01
Copy link
Contributor

huddx01 commented Dec 15, 2024

Interesting. Then it looks like the register address scheme is based more similar like (my) Fireface 802 (see the wiki).
I mean - the channels count raises by adding 0x0100 for each channel (instead 0x0040).

When listening USB traffic using TotalMix on macOS or Windows - your unit will have to use USB mode (instead of cc) to be able to communicate with the mac/win App. You could use and modify the lua script dissector and add your product id (see tools folder) for use with wireshark... but this way is a bit more complicated to get the registers. You have to be quite savvy with wireshark in general.

A more easier way would be if you have an ipad (and use your unit in cc mode), while capturing as described in the wiki (possible via a rpi4 or rpiPico W).
This way, you can capture the (midi-sysex) traffic directly (and get the register addresses back while running regtool without the -w flag).

Anyhow - getting the registers is just the first step.

The next step would be to add the code for your device (device_ffucx.c). See the "generic" branch how michael (and me) tried to include this. You can also check my fork of this repo. Here i addad my 802 (which is still in wip state, due lack of time - but basically works).

Feel free to ask here - i will try to do my best if i can help.

@tempete99
Copy link
Author

Ok I understand and I'm willing to try. I need to borrow most of these things, but it might happen soon. The capture wiki section looks also straightforward. Thank you!

@tempete99
Copy link
Author

I got my hands on a rpi4 and an USB-C iPad. I modified the script so that it corresponds to my Fireface UCX in cc mode.
I do see fe980000.usb in /sys/class/udc when the pi is powered by the iPad. However the line echo "$UDC" > UDC always returns write error: Device or resource busy

I have the impression the pi is detected by default as an Ethernet device. I've been trying to change config.txt and cmdline.txt without success. Most things I find on internet about gadget mode are outdated and probably non relevant to bookworm. I must admin I don't know what I'm doing :) Is it necessary to change the default configuration of raspberrypi os to be able to connect in gadget mode and run the script ?

@michaelforney
Copy link
Owner

You do have to enable the UDC by setting dtoverlay=dwc2 in config.txt, but it sounds like that's not the problem, since you have fe980000.usb.

I think there must be something in your OS setup auto-enabling the ethernet gadget that is using the UDC. Can you show your config.txt and cmdline.txt?

@tempete99
Copy link
Author

You are right, I pasted inside cmdline.txt from a tutorial without understanding what it meant
console=serial0,115200 console=tty1 root=PARTUUID=ec51e620-02 rootfstype=ext4 fsck.repair=yes rootwait modules-load=dwc2,g_ether cfg80211.ieee80211_regdom=FR
getting rid of g_ether should make it work.

As for config.txt, I added the last line.
I also tried commenting out #otg_mode=1 but I guess there was no need to do it.

# http://rptl.io/configtxt
# Some settings may impact device functionality. See link above for details

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

# Additional overlays and parameters are documented
# /boot/firmware/overlays/README

# Automatically load overlays for detected cameras
camera_auto_detect=1

# Automatically load overlays for detected DSI displays
display_auto_detect=1

# Automatically load initramfs files, if found
auto_initramfs=1

# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d
max_framebuffers=2

# Don't have the firmware create an initial video= setting in cmdline.txt.
# Use the kernel's default instead.
disable_fw_kms_setup=1

# Run in 64-bit mode
arm_64bit=1

# Disable compensation for displays with overscan
disable_overscan=1

# Run as fast as firmware / board allows
arm_boost=1

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
#otg_mode=1

[cm5]
dtoverlay=dwc2,dr_mode=host

[all]
dtoverlay=dwc2

My friend will bring her ipad on new year's eve, it will be a fantastic opportunity to test again while being half drunk and surrounded with a lot of noise

@vascosantos
Copy link

vascosantos commented Jan 6, 2025

I'm interested in helping with this.

I don't have an iPad nor a Raspberry Pi but I am willing to have a go at Wireshark, although I have just installed it for the first time.

I was able to get it to peek USB traffic on my macOS laptop:

image

There are packages constantly flowing around but I suspect that the relevant ones are the smaller ones with 40 bytes, sent from 'host' to '20.2.5'. How can I be sure?

Do the lua scripts also support the RME USB packets or only the CC ones?

@michaelforney
Copy link
Owner

I'm interested in helping with this.

I don't have an iPad nor a Raspberry Pi but I am willing to have a go at Wireshark, although I have just installed it for the first time.

TotalMix on Windows and macOS use a different protocol (the "USB" mode) than the iPad app and oscmix (the "CC" mode), but I suspect there are enough similarities in the address space to get started.

I was able to get it to peek USB traffic on my macOS laptop:

image

There are packages constantly flowing around but I suspect that the relevant ones are the smaller ones with 40 bytes, sent from 'host' to '20.2.5'. How can I be sure?

At least for the UCX II, the most relevant packets were those sent and received on bulk endpoints 12 and 13. The basics are described in
https://github.com/michaelforney/oscmix/wiki/Protocol#usb-mode

Do the lua scripts also support the RME USB packets or only the CC ones?

The rme.lua wireshark detector should work at least somewhat with the USB packets as well. However, the formatting and descriptions are specific to the UCX II.

To start, you could try adding the USB IDs for your device to https://github.com/michaelforney/oscmix/blob/main/tools/rme.lua#L455, setting up wireshark to filter out the addresses that you're not interested in (the ones you see going back and forth when you're not doing anything), and then you can observe what gets sent when you change specific controls in TotalMix.

Once you identify a particular register address and value format for some control, you could document it in the wiki in a new page for the UCX. I suspect there will be a lot of similarities with the UCX II, which is currently documented in the "Protocol" page in the wiki.

@tempete99
Copy link
Author

On my side, the pi4 was correctly recognized as a Fireface UCX by Totalmix. Sadly I'm struggling to find an USB-C iPad I could borrow for more than a few minutes and actually capture sysex traffic. I continue looking around

@vascosantos
Copy link

I changed the rme.lua script like so, around like 453:

local usb_table = DissectorTable.get('usb.product')
usb_table:add(0x2a393f82, rme_proto)  -- UCX II
usb_table:add(0x2a393fb9, rme_proto)  -- UCX
usb_table:add(0x2a393fcd, rme_proto)  -- 802

Then I added it to my personal Wireshark plugins folder but I don't think it is doing much.

I am now using TShark (command line for Wireshark) on my Windows 11 like so:

tshark.exe -i USBPcap2 -Y '(usb.dst==2.10.12)' -x -X lua_script:rme.lua

It seems that the 12 destination endpoint is where writes happen.
This still floods my screen. But if I enable a data length filter like this '(usb.dst==2.10.12 and usb.data_len>4)', then it becomes much cleaner.

I tried toggling the 48V on Mic 1 and it doesn't look obvious to me where the change is happening.
However, when I move a fader, then I see different packets flowing.

I am attaching a dump log of packet dissections without the Lua script loaded, but with filter '(usb.dst==2.10.12 and usb.data_len>4)': mic1_test.txt.
In this test, I perform a manual sequence on the Mic1 channel:

  1. toggle the 48V on mic1 a couple of times
  2. slide the mic1 fader from -inf to about 0 and then back to -inf
  3. a couple more toggles on 48V

The fader packets are the longer ones but I can't really find anything interesting on the 48V.
I might be filtering too much with the data_len or something.

I'm not savvy with Lua, but I might be able to progress if I can get at least something working.

@michaelforney
Copy link
Owner

I changed the rme.lua script like so, around like 453:

local usb_table = DissectorTable.get('usb.product')
usb_table:add(0x2a393f82, rme_proto)  -- UCX II
usb_table:add(0x2a393fb9, rme_proto)  -- UCX
usb_table:add(0x2a393fcd, rme_proto)  -- 802

Then I added it to my personal Wireshark plugins folder but I don't think it is doing much.

One quirk I seem to remember is that the usb.product dissector table doesn't work unless it saw the USB descriptors when the device was plugged in. You might try the same thing, but make sure wireshark is capturing when you first connect the UCX.

I am now using TShark (command line for Wireshark) on my Windows 11 like so:

tshark.exe -i USBPcap2 -Y '(usb.dst==2.10.12)' -x -X lua_script:rme.lua

It seems that the 12 destination endpoint is where writes happen. This still floods my screen. But if I enable a data length filter like this '(usb.dst==2.10.12 and usb.data_len>4)', then it becomes much cleaner.

I tried toggling the 48V on Mic 1 and it doesn't look obvious to me where the change is happening. However, when I move a fader, then I see different packets flowing.

That's good to observe the differences. I'm guessing the 48v is either filtered out or hidden in the noise. I also suspect that you notice the packet size difference when you use the fader since it adjusts several parameters at once (mic 1 level for output left and right channel).

Once you get the rme dissector working, you should be able to filter out addresses specifically using rme.register.

I am attaching a dump log of packet dissections without the Lua script loaded, but with filter '(usb.dst==2.10.12 and usb.data_len>4)': mic1_test.txt. In this test, I perform a manual sequence on the Mic1 channel:

  1. toggle the 48V on mic1 a couple of times
  2. slide the mic1 fader from -inf to about 0 and then back to -inf
  3. a couple more toggles on 48V

The fader packets are the longer ones but I can't really find anything interesting on the 48V. I might be filtering too much with the data_len or something.

I'm not savvy with Lua, but I might be able to progress if I can get at least something working.

Thanks. It's hard for me to make sense of the hex dump. Are these the full USB packets, or just the data payloads on endpoints 12/13? Could you do that same test again, but this time save the pcap file so that I could load it into wireshark myself?

@vascosantos
Copy link

vascosantos commented Jan 9, 2025

I tried again by starting wireshark capture before switching on the UCX but I don't see differences.
Where/how to I use rme.register? Can I use that as part of the filter expression? (I'm sorry, I've never done anything similar before..)

I am attaching a pcap with the same test from last time and another where I only turn the UCX on and off.
pcaps.zip

@michaelforney
Copy link
Owner

I tried again by starting wireshark capture before switching on the UCX but I don't see differences. Where/how to I use rme.register? Can I use that as part of the filter expression? (I'm sorry, I've never done anything similar before..)

Yes, that should be how it works.

I took a look at your capture and noticed that your device's USB IDs differ from @tempete99's (2a39:3fc9 vs 0424:3fb9, see idVendor/idProduct in packet number 26 in your mic1_test.pcap). I suspect that this is due to yours being in USB mode and theirs being in CC mode. In your post above, you added 2a39:3fb9 to rme.lua, so I think it was simply not matching your device.

I updated rme.lua to include 2a39:3fc9, which worked for me to get the RME dissector working. I also noticed that rme.lua wasn't compatible with the latest version of lua, so I fixed that as well.

I am attaching a pcap with the same test from last time and another where I only turn the UCX on and off. pcaps.zip

This looks good.

Here's the filter I used to filter out the noise: rme.register && !(rme.register in {0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f10, 0x3f50, 0x3f98})

wireshark

It looks like 0008 is Mic 1 48v, and 14e0 is the mixer for Mic 1 to whatever output you were on. Later on, I see you also adjusted some parameter 14a0. Perhaps the mixer for a different output? It only had one value at a time instead of the two for 14e0, so perhaps a mono channel?

Try fiddling around with the controls and build up a mapping of control to register address and value format.

@vascosantos
Copy link

vascosantos commented Jan 10, 2025

I am doing some slight sanity checking before I dive deep into the map.

Sometimes I get a Lua Error on the call to math.log10() on line 83:

image

This happens only when I move faders. The error goes away if I remove the call to math.log10(), but the duplicate registers still appear.

Previously, you mentioned that several values are written at once.
The packet highlighted in the screenshot above comes from moving a single fader (mono).
Does the payload on the bottom right seem right to you?

Sometimes changing the fader on mono channels shows packets with 3 addresses (the first 2 being the same).
I have also seen duplicate addresses with different values when toggling input mutes.
On other experiments, some controls do not generate packets, while on other occasions the same ones do.
Some addresses change when I perform:

  1. stop capture
  2. turn off the device
  3. reload the Lua plugins
  4. start capturing
  5. turn on the device

Here is the same fader moved after restarting as above and without the call to log10:

image

I'm suspecting something is a bit off in the dissection process.

Maybe packet parsing needs to be different for the UCX?

@vascosantos
Copy link

I had some more time to fiddle with this.
I opened the Lua console from Tools -> Lua Console.
This is what it looks like:

image

It looks like subid is nil all the time.
I am still reading rme.lua and trying to understand it in light of the info from the Wiki.

@vascosantos
Copy link

vascosantos commented Jan 10, 2025

Ok, I think I was misinterpreting some of the input controls on TotalMix (I don't use the hardware inputs that much).

Some of the toggles write more registers because of the way the channels are grouped together.
For example, if I change the input range selector (+4 dBu, -10 dBV, etc) on inputs 5 or 6, then inputs 5, 6, 7 and 8 will get the same value. That's why there are more register writes than I expected (I only expected 5 and 6 to change).

Also, some controls don't generate packets either because of the current signal gain/routing settings.
For instance, soloing an input while no other input is active generates no packet. If I raise the fader on some other input, then the solo packet appears.
Same with mic panning, etc.

Still, sometimes Wireshark misses a packet here and there, but most of the times it catches it upon retrying.
This could be a Wireshark/USBpcap thing.

I also noticed that some of the bytes change between the raw packet data and the register field. It looks like this is because of the bitwise AND with 0x7fff on line 429. This explains why some the 0x9xxx were turning into 0x1xxx, etc.

I will try to find some quiet time over the weekend to write a first attempt at the UCX register map.

@michaelforney
Copy link
Owner

Sounds like you are making good progress!

Some of the toggles write more registers because of the way the channels are grouped together. For example, if I change the input range selector (+4 dBu, -10 dBV, etc) on inputs 5 or 6, then inputs 5, 6, 7 and 8 will get the same value. That's why there are more register writes than I expected (I only expected 5 and 6 to change).

Ah, yeah. I think that the mixer (levels, pan, mute) is one of the harder things to figure out since it sometimes involves several registers, or repeated writes to the same register. What I ended up doing is starting with one mono input routed to one mono output (and -inf on all other outputs), making sense of that, then going from there.

Also, some controls don't generate packets either because of the current signal gain/routing settings. For instance, soloing an input while no other input is active generates no packet. If I raise the fader on some other input, then the solo packet appears. Same with mic panning, etc.

My understanding is that the solo function is purely a TotalMix construct. At the device level, it's just muting the other channels. So if no other input is active, nothing needs to be done.

Still, sometimes Wireshark misses a packet here and there, but most of the times it catches it upon retrying. This could be a Wireshark/USBpcap thing.

I think this is due to the packet filtering we're applying and the ones getting "skipped" getting written in the same USB packet that we're filtering out. I'm not sure if there's a better way to structure the dissector, but the rme.register and rme.value fields are lists, and the in operator in the filter matches when any of the items in the list. I don't think there is a not in operator, so the best I found to use was to just invert the set to those we're interested in.

You could try something like rme.register in {0..0x3eff, 0x4000..7fff}, which filters out more addresses, but does include packets when any of them are outside the 3Fxx range.

I also noticed that some of the bytes change between the raw packet data and the register field. It looks like this is because of the bitwise AND with 0x7fff on line 429. This explains why some the 0x9xxx were turning into 0x1xxx, etc.

This is expected. The high bit is a parity for the whole address and value. When you see 0x9xxx vs 0x1xxx, that just means there are an even number of bits set in the 1xxx and yyyy (value).

See the example here:
https://github.com/michaelforney/oscmix/wiki/Protocol#registers

I will try to find some quiet time over the weekend to write a first attempt at the UCX register map.

Cool, sounds good.

Sometimes I get a Lua Error on the call to math.log10() on line 83:

This is another Lua compatibility thing. 5.3+ use math.log(x, 10) instead. It should be fixed now.

But anyway, this is just for nice presentation of the registers/values specific to the UCX II. For the UCX, it's probably just misleading. My suggestion is to comment out

oscmix/tools/rme.lua

Lines 434 to 452 in fc5a085

if reg < 0x0500 then
format = format_input
elseif reg < 0x0a00 then
format = format_output
elseif reg >= 0x2000 and reg < 0x2500 then
format = format_mixlabel
elseif reg >= 0x3100 and reg < 0x3200 then
format = format_dynlevel
elseif reg >= 0x3200 and reg < 0x3340 then
format = format_channame
elseif reg >= 0x3380 and reg < 0x3400 then
format = format_autolevel
elseif reg >= 0x4000 and reg < 0x4500 then
format = format_mixvolume
elseif reg >= 0x4700 and reg < 0x4800 then
format = format_playbackfx
else
format = format_global
end

then build up from what you observe on your device.

Previously, you mentioned that several values are written at once. The packet highlighted in the screenshot above comes from moving a single fader (mono). Does the payload on the bottom right seem right to you?

I think it is right. My guess is that this is TotalMix uploading its state to the device. This is probably useful as a progress meter. If your dissector can make sense of that whole packet, then you probably have a pretty complete mapping of the address space.

BTW, it is more helpful to me if you send pcaps instead of screenshots, since I can't scroll around or expand fields in screenshots.

Sometimes changing the fader on mono channels shows packets with 3 addresses (the first 2 being the same). I have also seen duplicate addresses with different values when toggling input mutes. On other experiments, some controls do not generate packets, while on other occasions the same ones do. Some addresses change when I perform:

I've seen things like this before. For example, the UCX II uses address 2000 for both for setting the device LCD UI's input 1 -> output 1 volume and pan fields, depending on the high bit of the value. For example, 8010 means set pan to 16 right, but 7FC4 means set volume to -6.0dB. Probably not the exact same thing here, but see if you can figure out any pattern with the values when one address is written multiple times at once.

@vascosantos
Copy link

I think this might the whole map:

0000	input settings
	0000	mic 1
		0000	mute		0=off, 1=on
		0001	fxsend		int*10
		0002	stereo		0=off, 1=on
		0005	msproc		0=off, 1=on
		0006	phase		0=off, 1=on
		0007	gain		int*10, 0.0-65.0
		0008	mic=48v		0=off, 1=on
		0009	n/a
		000a	autoset		0=off, 1=on
		0020	lowcut		0=off, 1=on
			0021	freq		int16, 20Hz-500Hz
			0022	dB/oct		0=6, 1=12, 2=18, 3=24
		0040	eq		0=off, 1=on
			0041	band 1 type	0=peak, 1=shelf
			0042	band 1 gain	int*10, int16, -20.0dB-20.0dB
			0043	band 1 freq	int, 20Hz-20000Hz
			0044	band 1 q	int*10, 0.7-5.0
			0045	band 2 gain	int*10, int16, -20.0dB-20.0dB
			0046	band 2 freq	int, 20Hz-20000Hz
			0047	band 2 q	int*10, 0.7-5.0
			0048	band 3 type	0=peak, 1=shelf
			0049	band 3 gain	int*10, int16, -20.0dB-20.0dB
			004a	band 3 freq	int, 20Hz-20000Hz
			004b	band 3 q	int*10, 0.7-5.0
		0060	dynamics	0=off, 1=on
			0061	gain		gain*10, int16, -30.0dB-30.0dB
			0062	attack		int, 0ms-200ms
			0063	release		int, 100ms-999ms
			0064	compthres	int*10, -60.0dB-0.0dB
			0065	compratio	int*10, 1.0-10.0
			0066	expthres	int*10, -99.0dB--20.0dB
			0067	expratio	int*10, 1.0-10.0
		0080	autolevel	0=off, 1=on
			0081	maxgain		int*10, 0.0dB-18.0dB
			0082	headroom	int*10, 3dB-12dB
			0083	risetime	int*10, 0.1s-9.9s
	0100	mic 2
		...
	0200	inst 3
		...
		0207	gain		int*10, 0.0dB-12.0dB
		0208	level		0=-10 dBV, 1=+4 dBu, 2=Lo Gain
		0209	hi-z		0=off 1=on
		...
	0300	inst 4
		...
	0400	line 5
		...
		0407	level		0=-10 dBV, 1=+4 dBu, 2=Lo Gain
		0408	n/a
		0409	n/a
		...
	0500	line 6
	0600	line 7
	0700	line 8
	0800	spdif 9
		...
		0807	n/a
		0808	n/a
		0809	n/a
		...
	0900	spdif 10
	0a00	adat/spdif 11
	0b00	adat/spdif 12
	0c00	adat 13
	0d00	adat 14
	0e00	adat 15
	0f00	adat 16
	1000	adat 17
	1100	adat 18
1200	output settings
	1200	line 1
		1200	volume		int*10, -650=-inf, -65.0dB-6.0dB, step=0.5dB
		1201	balance		-100-100 (L100-0-R100)
		1202	mute		0=off, 1=on
		1203	fxreturn	-650=-inf, int*10, -64.5dB-0.0dB, step=0.5dB
		1204	stereo		0=off, 1=on, extra data?
		1207	phase		0=off, 1=on, extra data
		1208	ref level	0=-10dBV, 1=+4dBu, 2=Hi Gain
		1220	lowcut		0=off, 1=on
			1221	freq		int16, 20Hz-500Hz
			1222	dB/oct		0=6, 1=12, 2=18, 3=24
		1240	eq		0=off, 1=on
			1241	band 1 type	0=peak, 1=shelf
			1242	band 1 gain	int*10, int16, -20.0dB-20.0dB
			1243	band 1 freq	int, 20Hz-20000Hz
			1244	band 1 q	int*10, 0.7-5.0
			1245	band 2 gain	int*10, int16, -20.0dB-20.0dB
			1246	band 2 freq	int, 20Hz-20000Hz
			1247	band 2 q	int*10, 0.7-5.0
			1248	band 3 type	0=peak, 1=shelf
			1249	band 3 gain	int*10, int16, -20.0dB-20.0dB
			124a	band 3 freq	int, 20Hz-20000Hz
			124b	band 3 q	int*10, 0.7-5.0
		1260	dynamics	0=off, 1=on
			1261	gain		gain*10, int16, -30.0dB-30.0dB
			1262	attack		int, 0ms-200ms
			1263	release		int, 100ms-999ms
			1264	compthres	int*10, -60.0dB-0.0dB
			1265	compratio	int*10, 1.0-10.0
			1266	expthres	int*10, -99.0dB--20.0dB
			1267	expratio	int*10, 1.0-10.0
		1280	autolevel	0=off, 1=on
			1281	maxgain		int*10, 0.0dB-18.0dB
			1282	headroom	int*10, 3dB-12dB
			1283	risetime	int*10, 0.1s-9.9s
	1300	line 2
		...
	1400	line 3
	1500	line 4
	1600	line 5
	1700	line 6
	1800	phones 7
	1900	phones 8
	1a00	spdif 9
		...
		1a08	n/a
		...
	1b00	spdif 10
	1c00	adat/spdif 11
	1d00	adat/spdif 12
	1e00	adat 13
	1f00	adat 14
	2000	adat 15
	2100	adat 16
	2200	adat 17
	2300	adat 18
3c00	reverb		0=off, 1=on
	3c01	type		int, 0=Small Room, 1=Medium Room, 2=Large Room, 3=Walls,
				     4=Shorty, 5=Attack, 6=Swagger, 7=Old School,
				     8=Echoistic, 9=8plus9, 10=Grand Wide, 11=Thicker,
				     12=Envelope, 13=Gated, 14=Space
	3c02	predelay	int, 0ms-999ms
	3c03	lowcut		int, 20Hz-500Hz
	3c04	room scale	int*100, 0.50-3.00 (rooms only)
	3c05	attack time	int, 5ms-400ms (envelope only)
	3c06	hold time	int, 5ms-400ms (envelope and gated only)
	3c07	release time	int, 5ms-500ms (envelope and gated only)
	3c08	high cut	int, 2kHz-20kHz
	3c09	reverb time	int*10, 0.1s-4.9s (space only)
	3c0a	damp		int, 2kHz-20kHz (space only)
	3c0b	smooth		int, 0-100%
	3c0c	volume		int*10, -65.0dB-6.0dB, -650=-inf
	3c0d	width		int*100, 0.00-1.00
3c20	echo		0=off, 1=on
	3c21	echo type	0=Stereo Echo, 1=Stereo Cross, 2=Pong Echo
	3c22	delay time	int*1000, 0.000s-2.000s
	3c23	feedback	int, 0-100%
	3c24	high cut	0=off, 1=16kHz, 2=12kHz, 3=8kHz, 4=4kHz, 5=2kHz
	3c25	volume		int*10, -65.0dB-6.0dB, -650=-inf
	3c26	stereo width	int*100, 0.00-1.00
3d00	clock/hardware
		3d20	clock source		0=internal 1=spdif 2=optical 3=word
		3d21	sample rate		0=32000 1=44100 2=48000 3=64000 4=88200 5=96000 6=128000 7=176400 8=192000
		3d22	word clock single speed	0=off 1=on
		3d40	word clock termination	0=off 1=on
		3d41	optical	out		0=adat 1=spdif
		3d42	spdif format		0=consumer 1=professional

I tried to follow the same naming conventions as in the wiki page for the UCX II so it makes things easier when writing an eventual, dedicated UCX wiki page.

Some of the controls do not exactly follow a linear map.
For example, the Mic input gain controls start at 0.0, and then the first non-zero value is 10.0, and then it goes in steps of 1.0.

Other controls do steps of +/-5 (meaning +/-0.5 dB).

Frequency settings do 1 Hz steps from 20 Hz to 200 Hz, then in 10 Hz steps from 200 Hz to 2000 Hz, then it's 100 Hz steps up to 20000 Hz.

I might be missing some details here and there.
Please let me know if you spot anything relevant/inconsistent/wrong.

What's the next step?
I can help with wiki entries, C coding and obviously testing.

@michaelforney
Copy link
Owner

I tried to follow the same naming conventions as in the wiki page for the UCX II so it makes things easier when writing an eventual, dedicated UCX wiki page.

Nice work! Thanks for doing this.

Some of the controls do not exactly follow a linear map. For example, the Mic input gain controls start at 0.0, and then the first non-zero value is 10.0, and then it goes in steps of 1.0.

Other controls do steps of +/-5 (meaning +/-0.5 dB).

Frequency settings do 1 Hz steps from 20 Hz to 200 Hz, then in 10 Hz steps from 200 Hz to 2000 Hz, then it's 100 Hz steps up to 20000 Hz.

To clarify, you are talking about the TotalMix UI, right, not the 16-bit value format? I assume this is just for the UI to make adjusting values easier depending on the unit.

I might be missing some details here and there. Please let me know if you spot anything relevant/inconsistent/wrong.

It looks good to me, but one thing we're missing is the mixer functionality. Try routing a mono input to a mono output, making sure that input is set to -inf on all other outputs. Then set the volume to various values like 0dB, -3dB -6dB, -12dB, -18dB. My expectation is that the value format is something like the "Decibel to register value" formula in https://github.com/michaelforney/oscmix/wiki/Protocol#mixer-volume-formulas.

So for 0dB -> 0x8100, -3dB -> ~0x8B53, -6dB -> ~0x8805, -12dB -> ~0x2027, -18dB -> ~ 0x101D

Another thing which we need to figure out is how to dump the device state. It seems to vary from device to device, but usually, when TotalMix starts up, it writes a particular value to some address causing the device to dump its state. TotalMix can then compare this state to its last known state, and if it differs, prompt the user to choose which they want to use.

Do you see anything like this in your packet capture? Look for any packets with a large number of registers sent from the device to the host. If you find this, then look just earlier for what the host sent to the device that looks unique.

What's the next step? I can help with wiki entries, C coding and obviously testing.

You could try confirming whether that all this translates to the CC mode as well using tools/regtool from the oscmix repository (build with make tools/regtool).

Put your device in CC mode, then try running ./tools/regtool -w XX:YY RRRR VVVV, where XX:YY is the alsa sequencer port for your device, RRRR is the register address, and VVVV is the value you want to write. In the first post, @tempete99 mentioned seeing sysex data on port 2, so I suspect that's what you should use for YY.

Another thing you could try is running ./tools/regtool XX:YY on one terminal. You'll probably see some stuff come through already. You can filter this out with grep or awk (i.e. pipe to grep -v -e '^3080' -e '^3083' for my UCX II). On another terminal, try writing cycling values to 3F00 using while true; do for val in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do echo "3F00 $val"; sleep 0.2; done; done | ./tools/regtool -w 28:1. Do you see more stuff on the first terminal now? If so, filter that out as well. I'm not sure what functionality you can control from the front panel on the UCX in CC mode, but try changing everything you can and seeing if it aligns with what you expect based on your map.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants