Saffire 6USB technical details for driver developers

As promised in my previous post, here is some information that may prove useful for those attempting to write USB drivers for Saffire 6USB Mk I (MkII is audio class 2 compliant and should not need a driver on Linux).  Its not going to be that different for our other USB 1.1 products (Ultranova, VRM Box etc.) so could be extended for those devices later.

Before we get started, a word of warning – this is a work in progress and quite likely to be error prone, so please bear with us – we’ll try to correct any mistakes or omissions as they are discovered.

Finally, you may want to get access to a USB bus analyser, we find them incredibly useful for development!

Audio

Audio is transferred to and from Saffire 6USB on Interface 0, alternate setting 1.  Endpoint 0x01 is the output, transmitting four channels, interleaved in 24-bit little-endian format.  Endpoint 0x82 provides two channels of input in the same format.

Saffire 6USB runs from the USB SOF (start of frame) clock, as such it transfers a predictable number of samples for each 1ms USB frame.

At 48kHz, each packet contains 48 samples per channel.  At 44.1kHz, its not possible to transfer an integer number of samples per frame, so instead we transmit / receive nine transfers of 44 samples followed by one of 45 samples (hence transferring 441 samples every 10ms).

To read and set the sample rate, we use the same format as for USB audio class devices, documented in section 5.2.3.2.1 and 5.2.3.2.3.1.

After changing sample rates, it is advisable to wait for a few hundred milliseconds before attempting to start transfers again (the device needs to resynchronise its PLL).

MIDI

MIDI is transferred on Interface 1, transmitting up to 8 bytes of data per packet on endpoint 0x03, and receiving up to 16 bytes on endpoint 0x84.  The format is raw MIDI, not USB class formatted.  The hardware does not process the stream in any way, it just passes it directly to / from the physical ports.

No data will be transferred unless the device has been set to configuration 1.

Descriptor

Below is a dump of the device descriptor, in case it proves useful!

    Device Descriptor   
        Descriptor Version Number:   0x0100
        Device Class:   0   (Composite)
        Device Subclass:   0
        Device Protocol:   0
        Device MaxPacketSize:   8
        Device VendorID/ProductID:   0x1235/0x0010   (unknown vendor)
        Device Version Number:   0x0100
        Number of Configurations:   1
        Manufacturer String:   1 "Focusrite Audio Engineering"
        Product String:   2 "Saffire 6USB"
        Serial Number String:   0 (none)
    Configuration Descriptor   
        Length (and contents):   64
            Raw Descriptor (hex)    0000: 09 02 40 00 02 01 00 80  F9 09 04 00 00 00 FF 00  
            Raw Descriptor (hex)    0010: 00 00 09 04 00 01 02 FF  00 00 00 07 05 01 01 4C  
            Raw Descriptor (hex)    0020: 02 01 07 05 82 01 26 01  01 09 04 01 00 02 FF 00  
            Raw Descriptor (hex)    0030: 00 00 07 05 03 03 08 00  01 07 05 84 03 10 00 01  
            Unknown Descriptor   0040: 
        Number of Interfaces:   2
        Configuration Value:   1
        Attributes:   0x80 (bus-powered)
        MaxPower:   498 ma
        Interface #0 - Vendor-specific   
            Alternate Setting   0
            Number of Endpoints   0
            Interface Class:   255   (Vendor-specific)
            Interface Subclass;   0   (Vendor-specific)
            Interface Protocol:   0
        Interface #0 - Vendor-specific (#1)   
            Alternate Setting   1
            Number of Endpoints   2
            Interface Class:   255   (Vendor-specific)
            Interface Subclass;   0   (Vendor-specific)
            Interface Protocol:   0
            Endpoint 0x01 - Isochronous Output   
                Address:   0x01  (OUT)
                Attributes:   0x01  (Isochronous no synchronization data endpoint)
                Max Packet Size:   588
                Polling Interval:   1 ms
            Endpoint 0x82 - Isochronous Input   
                Address:   0x82  (IN)
                Attributes:   0x01  (Isochronous no synchronization data endpoint)
                Max Packet Size:   294
                Polling Interval:   1 ms
        Interface #1 - Vendor-specific   
            Alternate Setting   0
            Number of Endpoints   2
            Interface Class:   255   (Vendor-specific)
            Interface Subclass;   0   (Vendor-specific)
            Interface Protocol:   0
            Endpoint 0x03 - Interrupt Output   
                Address:   0x03  (OUT)
                Attributes:   0x03  (Interrupt no synchronization data endpoint)
                Max Packet Size:   8
                Polling Interval:   1 ms
            Endpoint 0x84 - Interrupt Input   
                Address:   0x84  (IN)
                Attributes:   0x03  (Interrupt no synchronization data endpoint)
                Max Packet Size:   16
                Polling Interval:   1 ms
10 comments
  1. Hi Dave. Thanks for taking the time to post this. I’m hoping to write an ALSA driver for the Saffire 6 over summer (or as long as it takes!) once my college exams are finished.

    Going to be a huge challenge as I’ll need to know C inside out and there is hardly any ALSA documentation. Is there anything special that you need to do to get it ‘activated’? For example, it doesn’t light up on Linux but after a few seconds on Windows – all the lights come on as they should. I’m new to all this so hopefully this happens when all of the endpoints are defined in the driver. Are there any skeleton drivers you could recommend? Don’t worry if not!

    I’ll be studying Software Engineering at University. I follow you on twitter and saw that you tweeted about Raspberry Pi. In case you’re interested: I volunteer for the Raspberry Pi foundation by administering their downloads server. I put together a mirror system and my job is to basically take new images and push them out to our mirror network, create torrents and keep the server running. I also do video tutorials around the device at http://www.youtube.com/raspberrypitutorials 🙂

    Thanks again,

    Liam.

  2. Hi Liam, glad it was of interest. Driver development is *hard*, so good luck! I’d strongly recommend getting access to a bus analyser, it will help you enormously (maybe you can borrow or hire one).

    I’m afraid I know virtually nothing of the Linux kernel or ALSA, so I can’t help there. What I can say is that you need to match the device, and set configuration 1 before it will light up and say hello.

    Have a read of the USB spec, it will help (but its a lot to learn!).
    http://www.usb.org/developers/docs/usb_20_101111.zip

    We’re looking forward to getting a couple of Pi’s here, should be fun for prototyping and experimenting with.

    Best of luck!
    Dave

  3. Hi Dave, Thanks for your reply. USB Bus analysers look very expensive. I’m going to try using vmwares usb logging feature or any other software logging stuff I can find! Vmware should be fairly good as it can be captured at low level (regardless of it being emulated).

    I’m also going to try and comment my code with loads of detail because the alsa documentation is pretty poor.

    I won’t be trying to start this project untill the middle of june when my exams are out of the way so might not post here for a while. Hopefully it wont take too long to light it up. Then I know I’ll be getting somewhere!

    Cheers,

    Liam.

  4. We’ve never had any luck streaming audio on Windows under VMware, but MIDI does work. It will just about stream (very glitchy) audio on OS X Lion running in a VM. You might have more luck with Linux, though it does complicate matters!

    Good luck, let us know how you get on.

    • I’ve actually managed to get decent quality ASIO audio quality from a Windows 7 VM… as long as the buffer size is set pretty high – so hopefully that will do.

      Thanks again,

      Liam.

  5. I know this is bringing an old (ish) post to life, but is there any work being done to allow the scarlett series to directly record to a USB storage device? I know some basic transport controls might be needed, but, to me at least, this would be a killer feature (just being able to record), esp with the live recording market.

    • Do you mean adding a USB port for thumb drive recording on the hardware in standalone mode? I’m always interested to hear feature requests, but can’t really comment on what we’re doing with future products, sorry.

  6. Hello!

    Starting with version 3.14 of the Linux kernel supports playback and midi for this audio card. Now I solve the problem with the placement of the two endpoints on the same interface. If there are owners of this audio card wishing to test the recording, please use the patch http://comments.gmane.org/gmane.linux.alsa.devel/122915.
    Furthermore, necessary to add in the configuration file “.asoundrc” something like this:

    pcm.saffire_card {
    type hw
    card “USB”
    rate 48000
    }

    pcm.saffire_mic_1 {
    type route
    slave {
    pcm “saffire_card”
    channels 2
    }
    ttable.0.0 1
    ttable.0.1 0
    }

    pcm.saffire_mic_2 {
    type route
    slave {
    pcm “saffire_card”
    channels 2
    }
    ttable.0.0 0
    ttable.0.1 1
    }

    pcm.dmixer {
    type dmix
    ipc_key 43567
    ipc_key_add_uid true
    slave {
    pcm “saffire_card” # Saffire 6 USB
    period_time 0
    period_size 1024
    buffer_size 8192
    }
    bindings {
    0 0
    1 1
    }
    }

    pcm.!default {
    type asym
    playback.pcm {
    type plug
    slave.pcm “dmixer”
    }
    capture.pcm {
    type plug
    slave.pcm “saffire_mic_1” # Saffire 6 USB microphone 1
    # slave.pcm “saffire_mic_2” # Saffire 6 USB microphone 2
    }
    }

  7. I am new to Linux and do not know these settings. How can you help me ??

Leave a reply to liamfraser28036 Cancel reply