How Start an Open Source project to create a replacement for RME Totalmix fx

Programming applications for making music on Linux.

Moderators: MattKingUSA, khz

User avatar
sjzstudio
Established Member
Posts: 161
Joined: Fri Apr 10, 2020 11:24 pm
Has thanked: 19 times
Been thanked: 25 times

How Start an Open Source project to create a replacement for RME Totalmix fx

Post by sjzstudio »

How to get started with Totalmix fx and opensource drivers. Personally, I’m not a coder, but I wonder how the project could get started. And gather qualified people according to it. Is it absolutely impossible to do?
j_e_f_f_g
Established Member
Posts: 2032
Joined: Fri Aug 10, 2012 10:48 pm
Been thanked: 357 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by j_e_f_f_g »

sjzstudio wrote: How to get started with Totalmix fx
First you need someone who can write C code.
I’m not a coder
Better not start the project until you learn C, and really well too, because you'd have to write an ALSA "hardware control" loadable module. And that's complicated.
gather qualified people to it. impossible?
If by that you mean... "Get someone to do it for me, so I don't need to do it myself"... then the answer is "yes, it will be nearly impossible". High-end audio support on linux is almost always achieved by someone learning how to write an ALSA kernel module so he can roll his own support. Because there are scant few people to do it for you.

Author of BackupBand at https://sourceforge.net/projects/backupband/files/
My fans show their support by mentioning my name in their signature.

User avatar
sjzstudio
Established Member
Posts: 161
Joined: Fri Apr 10, 2020 11:24 pm
Has thanked: 19 times
Been thanked: 25 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by sjzstudio »

So where should I start studying? If I think I would start studying out of curiosity on the subject.
j_e_f_f_g
Established Member
Posts: 2032
Joined: Fri Aug 10, 2012 10:48 pm
Been thanked: 357 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by j_e_f_f_g »

First, you need a book on C Programming. There are many of those, including free ones on the internet. I won't bother posting links because they are easily discoverable on Google. Kernigan and Ritchie, the creators of the C language, wrote a book, but frankly, there are better teaching sources than that one.

Author of BackupBand at https://sourceforge.net/projects/backupband/files/
My fans show their support by mentioning my name in their signature.

Drumfix
Established Member
Posts: 299
Joined: Mon Jan 26, 2009 5:15 pm
Been thanked: 11 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Drumfix »

If it is for a USB device, the device uses USB bulk endpoints for the Totalmix commmunication. These can be accessed just fine from userspace using libusb. No kernel hacking needed. And then you need to run wireshark on windows to capture the data in order to decipher the protocol used.
Drumfix
Established Member
Posts: 299
Joined: Mon Jan 26, 2009 5:15 pm
Been thanked: 11 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Drumfix »

Apparently https://github.com/agfline/RME-Fireface-UC-Drivers describes the RME protocol.

So they are using usb control message for changing values in totalmix + setting the samplerate, Isochronous endpoints with 3 alternate settings for the bandwidth used by a pair of samplerates and send/receive the data as 32 floats in isochronous streams with an extra 4 byte field at the start of a packet, which most likely contains the total number of samples transmitted since the stream was started (for detection of lost packets at the receiving end).
User avatar
sjzstudio
Established Member
Posts: 161
Joined: Fri Apr 10, 2020 11:24 pm
Has thanked: 19 times
Been thanked: 25 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by sjzstudio »

My interest is mainly in Fireface 802 and UFX + because I have these devices. I am now slowly going to sort things out. It may take years, but let's see.
User avatar
Be.
Established Member
Posts: 55
Joined: Mon Mar 16, 2015 4:51 am
Been thanked: 6 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Be. »

I've been playing around bbfpromix, Wireshark and Rust bindings for libusb to understand how RME's TotalMix FX software communicates with my Babyface Pro. There's no need to learn C for this; I've already had enough of C from briefly playing around in bbfpromix's code. I have confirmed that what @Drumfix said is correct: this can all be done with libusb from userspace (libusb_control_transfer), even with the ALSA mixer stuff in the kernel for the Babyface Pro. Of course, sending control transfer messages with libusb to manipulate the state of the hardware does not update the ALSA mixer controls, but I don't care. I don't think ALSA mixer is very appropriate for controlling these highly device-specific controls. Having a common API exposed by the kernel is useful if multiple userspace applications can make use of it. In practice though, these controls are so idiosyncratic to each device that each device/product line needs its own purpose built GUI application to be useful. Perhaps it was more helpful back when sound cards were PCI devices, but nowadays there's no problem sending a couple of bytes from userspace with libusb and leaving the audio & MIDI parts to the kernel's snd-usb-audio driver. Plus using the libusb Rust bindings means I don't have to write C. :D

I was puzzled for a long time how TotalMix FX works on iOS until I read USB In A Nutshell yesterday. I was confused because I figured TotalMix FX used some vendor defined class interface but there aren't any in class compliant mode. Then I learned that USB control transfers always use endpoint 0 so that isn't included in USB descriptors. I suspect RME did it this way because they can send control transfer signals on iOS where Apple doesn't allow hardware vendors to write their own drivers (a better alternative IMO would have been a class compliant HID interface, but alas, they didn't ask me to design it).

From my brief experiments setting the 48V phantom power switch for microphone input 1 on my Babyface Pro, it seems this protocol is the same in both class compliant and Windows mode. This is exciting because I previously thought that figuring this out required a hardware USB sniffer between the audio interface and an iPad (of course, I have neither an iPad nor a hardware USB sniffer, both of those are expensive, and I would have no use for them besides this reverse engineering), which is why I haven't bothered reverse engineering this myself despite owning a Babyface Pro since 2015. This means the protocol can be reverse engineered by forwarding a USB device to a Windows VM from Linux and recording the USB traffic from the Linux host with Wireshark's usbmon support. Another implication of this is that implementing it via libusb could work cross platform... not that anyone on Windows or macOS would care when they can use TotalMix FX, but hey, I guess that's neat? :lol:

My personal motivation for this is not so much using it for my Babyface Pro, but as a proof of concept for how it could be done for other modern RME USB Audio Class compliant audio interfaces which I am considering getting in the future. The Babyface Pro is mostly controllable from the physical controls on the hardware (with an exception for direct monitoring mono signals on stereo outputs that RME refuses to fix). I want to remote control these devices all with FOSS. It would be really neat to remote control a Fireface that is on stage while walking around an audience. Here is the technical architecture I propose for this, all in Rust:

0. A library providing a nice API to send USB control signals to manipulate the onboard DSP, mixing, and switches of RME devices
1. A server using the above library to expose that functionality over a network with OSC. Perhaps there's a way to use serde to convert between the USB control signals and OSC. TotalMix FX also has an OSC API and it would be nice to reimplement that, but not necessary.
2. A GUI application sending OSC to the above server

Here's a quick hack to send USB control transfer messages to a Babyface Pro. Just add rusb to your Cargo.toml and play around with sending different signals:

Code: Select all

use rusb::{Context, UsbContext};
use core::time::Duration;

fn main() {
    let devices = Context::new().unwrap().devices().unwrap();
    let mut device = None;
    for usb_device in devices.iter() {
        let descriptor = match usb_device.device_descriptor() {
            Ok(d) => d,
            Err(_) => continue,
        };

        if descriptor.vendor_id() == 0x2a39 && descriptor.product_id() == 0x3fb0 {
            device = Some(usb_device.open().unwrap());
            break;
        }
    }

    let device = match device {
        Some(d) => d,
        None => panic!("No RME Babyface Pro found!"),
    };
    
    // wValue gain range
    // off: 0
    // -3db: 4096
    // 0dB: 8192
    // +6db: 16384

    // wIndex mix matrix: input + 26 * output
    // hardware inputs are 0-11, software playback is 12-23, FX return is 24-25

    // direct monitor XLR inputs in mono, TS inputs in stereo to XLR outputs
    // input 0 to output 0
    device.write_control(0x40, 18, 4096, 0 + 26 * 0, &[], Duration::from_millis(10)).unwrap();
    // input 0 to output 1
    device.write_control(0x40, 18, 4096, 0 + 26 * 1, &[], Duration::from_millis(10)).unwrap();
    // input 1 to output 0
    device.write_control(0x40, 18, 4096, 1 + 26 * 0, &[], Duration::from_millis(10)).unwrap();
    // input 1 to output 1
    device.write_control(0x40, 18, 4096, 1 + 26 * 1, &[], Duration::from_millis(10)).unwrap();
    // input 2 to output 0
    device.write_control(0x40, 18, 8192, 2 + 26 * 0, &[], Duration::from_millis(10)).unwrap();
    // input 2 to output 1
    device.write_control(0x40, 18, 0000, 2 + 26 * 1, &[], Duration::from_millis(10)).unwrap();
    // input 3 to output 0
    device.write_control(0x40, 18, 0000, 3 + 26 * 0, &[], Duration::from_millis(10)).unwrap();
    // input 3 to output 1
    device.write_control(0x40, 18, 8192, 3 + 26 * 1, &[], Duration::from_millis(10)).unwrap();

    // disable all direct monitoring to headphones output
    for i in 0..12 {
        device.write_control(0x40, 18, 0, i + 26 * 2, &[], Duration::from_millis(10)).unwrap();
        device.write_control(0x40, 18, 0, i + 26 * 3, &[], Duration::from_millis(10)).unwrap();
    }
}
You need to either run the executable with sudo or write a udev rule to give unprivileged users permission to access the USB device with libusb. When this is further along, we could add these devices to systemd's hardware database so a udev rule isn't needed (like has already been done for other devices).
Last edited by Be. on Wed Apr 20, 2022 7:00 am, edited 4 times in total.
User avatar
Be.
Established Member
Posts: 55
Joined: Mon Mar 16, 2015 4:51 am
Been thanked: 6 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Be. »

I've been exploring TotalMix FX to understand its features better and I don't particularly like its design. I find the mixer view a bit confusing and the matrix view doesn't provide access to all features. I propose a design somewhat like the knob matrix of alsa-scarlett-gui:

Image

Like alsa-scarlett-gui, double clicking a knob would toggle it to negative infinity or 0 dB. I would add to this meters and a fader for each input on the left and each output on the bottom, outside of the knob grid. The faders for the input channels would control the preamp gains (not applicable for digital inputs); the faders for the output channels control the output level of that output's submix (TotalMix FX shows these values in a confusing way as the bottom part of the matrix). Each input and output would also have a button to toggle showing the parametric 3 band EQ and low cut filter controls.

In the beginning, every channel would be mono and there would be no pan knobs to keep it simple and easy to implement. In TotalMix FX, the pan knobs and grouping channels into stereo change how the GUI interacts with the mixing levels in the matrix, which you can see by switching between the mixer and matrix views in TotalMix FX. The stereo features are features of TotalMix FX, not the hardware. They could be added to this new application later after all the hardware features are supported.

The reverb and echo effects in TotalMix FX are software features of TotalMix FX (this is documented in the Babyface Pro manual). Unlike the parametric 3 band EQ and low cut filter, they are processed on the computer's CPU, not the audio interface's hardware. I do not plan to implement these, which allows for simplifying the GUI by omitting all the effects widgets.

An alternative view similar to TotalMix FX's mixer view could be implemented, but I would make it simpler than TotalMix FX. There could be a meter and fader for one output channel on the right side of the window, which could be scrolled to select other outputs. On the left side, taking up most of the window, would be meters and faders for each input channel for the submix going to the selected output, plus a knob for the preamp gain. The input channel view could be scrolled horizontally to show all the inputs. In other words, it would work like TotalMix FX's mixer view, but all channels would be in one row and you could scroll horizontally within the input and output panes to see all the channels. I think this could be more practical to use on a phone than the big knob matrix and TotalMix FX's design (TotalMix FX runs on iPads, but notably not iPhones). I think it wouldn't be as straightforward to use or implement as the matrix, so this would implemented later if at all.
User avatar
Be.
Established Member
Posts: 55
Joined: Mon Mar 16, 2015 4:51 am
Been thanked: 6 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Be. »

I have an idea for the name of this application: PartialMix :lol:
User avatar
Be.
Established Member
Posts: 55
Joined: Mon Mar 16, 2015 4:51 am
Been thanked: 6 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Be. »

Be. wrote: Mon Apr 18, 2022 6:19 pm Here is the technical architecture I propose for this, all in Rust:

0. A library providing a nice API to send USB control signals to manipulate the onboard DSP, mixing, and switches of RME devices
1. A server using the above library to expose that functionality over a network with OSC. Perhaps there's a way to use serde to convert between the USB control signals and OSC. TotalMix FX also has an OSC API and it would be nice to reimplement that, but not necessary.
2. A GUI application sending OSC to the above server
Before writing the GUI application, it would be helpful to have a simple command line application. For example:

Code: Select all

# Set input channel 1 to output channel 2 routing to 0 dB
$ partialmix-cli mix --input 1 --output 2 --gain 0

# Set input channel preamp 1 to +30 dB
$ partialmix-cli input 1 --gain 30

# Get input channel preamp 1 gain
$ partialmix-cli input 1 --gain
+30 dB

# Set input channel 1 EQ band 1 frequency cutoff to 100 Hz
$ partialmix-cli input 1 --eq 1 --freq 100

# Enable phantom power on input 1
$ partialmix-cli inout 1 --phantom-power on
For my personal needs, simply toggling direct monitoring between mono/stereo/off with the 4 analog inputs of the Babyface Pro, a CLI application would be sufficient. But making a GUI application will be fun. :D
User avatar
eikakot
Established Member
Posts: 103
Joined: Fri Jan 29, 2010 2:24 pm
Location: Vilnius, Lithuania
Has thanked: 7 times
Been thanked: 3 times
Contact:

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by eikakot »

Is this something that you are not able to do with https://github.com/MrBollie/bbfpromix?
User avatar
Be.
Established Member
Posts: 55
Joined: Mon Mar 16, 2015 4:51 am
Been thanked: 6 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Be. »

eikakot wrote: Wed Apr 20, 2022 6:11 am Is this something that you are not able to do with https://github.com/MrBollie/bbfpromix?
Not really. It uses the ALSA mixer API which is incomplete and I don't care to complete that. I find the UX confusing, it's written in C and I don't care to suffer C when I could write Rust.

So technically, yes I could improve bbfpromix, but I disagree with its technical and design decisions, so I'm starting over.
User avatar
Be.
Established Member
Posts: 55
Joined: Mon Mar 16, 2015 4:51 am
Been thanked: 6 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Be. »

They replied that it is possible to control the EQs in class compliant mode. TotalMix FX for iPad can do this. How this works though, I'm stumped without being able to record the USB traffic with an iPad.

I am also struggling to figure out how the input preamp gains and output level controls work. I see USB control transfer output messages when manipulating these, but I have not figured out how to make sense of the data. For the preamp gains, each change sends 5 control messages. 4 of them seem to stay constant and the other goes up and down when the gain is only moving in one direction. For the outputs, 2 control messages are sent, but I haven't figured out how the level is represented. For the mixing matrix, the levels are simply 16 bit unsigned integers.
Last edited by Be. on Wed Apr 20, 2022 8:03 pm, edited 1 time in total.
User avatar
Be.
Established Member
Posts: 55
Joined: Mon Mar 16, 2015 4:51 am
Been thanked: 6 times

Re: How Start an Open Source project to create a replacement for RME Totalmix fx

Post by Be. »

I made some interesting observations regarding state persistence. It seems the Babyface Pro stores all its state when powered off, but it has two separate states for PC and CC modes. I expected TotalMix FX to query the device for its state on startup, but the reverse seems to happen. TotalMix FX sends a bunch of outgoing USB control messages when the device is plugged in. This led me to wonder if TotalMix FX is saving its own state and restoring that the next time it is connected to the device. I confirmed that is what it does by setting input gains with TotalMix FX connected, plugging the device into a USB power bank, changing the gains, then plugging it back into my Windows VM with TotalMix FX. After this experiment, TotalMix FX's gain knobs were out of sync with the hardware.

This is not perfect, but in the absence of a way to query the state of the hardware, I guess it works good enough for most cases. I will implement the same state persistence in this new application.
Post Reply