Skip to main content

48-Channel FireWire Audio Stack

48-Channel Synchronous FireWire Audio Stack (bmo95)

This page details the hardware configuration, Word Clock distribution, ALSA/JACK audio routing, and empirical drift verification for the studio's 48-channel synchronous recording backend.


1. Hardware Architecture & Color Standard

The studio uses four daisy-chained Echo AudioFire12 FireWire (IEEE 1394a) interfaces mounted in the main recording rack, providing 48 balanced analog line inputs and 48 balanced analog line outputs at 24-bit/48kHz.

Each physical interface is labeled with a dedicated color code and the last four digits of its hardware GUID:

Role Color Hardware GUID ALSA PCM Node BNC Word Clock Role Analog Channels
Master Red 001486016641fc79 hw:AudioFire12_3,0 Master Clock Generator OUT Red_01 – Red_12
Slave 1 Blue 0014860166419815 hw:AudioFire12_2,0 Slave Clock IN (75Ω BNC) Blue_01 – Blue_12
Slave 2 Yellow 00148601664194e8 hw:AudioFire12,0 Slave Clock IN (75Ω BNC) Yellow_01 – Yellow_12
Slave 3 Green 0014860166418525 hw:AudioFire12_1,0 Slave Clock IN (75Ω BNC) Green_01 – Green_12

2. Word Clock Distribution & Physical Cabling

Multi-card FireWire setups suffer from driver race conditions and buffer desynchronization if individual interfaces rely on software-based clock recovery. To achieve mathematical zero-drift sample alignment, the interfaces are synchronized via dedicated 75Ω BNC coaxial Word Clock cabling:

+-------------------------------------------------------------------------------+
| RED (Master: fc79)                                                            |
| Clock Mode: Internal (48000 Hz)                                               |
| BNC Word Clock OUT --------------------------------------------------------+  |
+----------------------------------------------------------------------------|--+
                                                                             |
         +-------------------------------------------------------------------+
         |
         v
+-----------------------+     +-------------------------+     +-------------------------+
| BLUE (Slave 1: 9815)  |     | YELLOW (Slave 2: 94e8)  |     | GREEN (Slave 3: 8525)   |
| Clock Mode: Word Clock|     | Clock Mode: Word Clock  |     | Clock Mode: Word Clock  |
| BNC Word Clock IN     |     | BNC Word Clock IN       |     | BNC Word Clock IN       |
| 75Ω Terminated        |     | 75Ω Terminated          |     | 75Ω Terminated          |
+-----------------------+     +-------------------------+     +-------------------------+

FireWire Bus Topology

The host machine (bmo95) features dual Texas Instruments XIO2213B PCIe FireWire host controllers. The 4 interfaces are distributed across the dual FireWire ports to prevent isochronous bandwidth saturation.


3. Real-Time Audio Server & ALSA Bridging Architecture

The audio stack runs under a Linux 6.13 Real-Time (PREEMPT_RT) kernel on bmo95.

Instead of binding all 4 interfaces into a single fragile ALSA pcm.multi virtual device (which crashes the kernel ALSA FireWire driver upon channel unbinding), the system runs a single master JACK daemon coupled with synchronous zita-a2j / zita-j2a duplex bridges:

                                +-------------------+
                                |   DAW / REAPER    |
                                +-------------------+
                                          |
                                    JACK API (48ch)
                                          |
                                          v
+---------------------------------------------------------------------------------------+
|                                    JACK Server                                        |
|                          (jackd -R -P 80 -r 48000 -p 64 -n 3)                         |
+---------------------------------------------------------------------------------------+
         |                        |                          |                          |
   Native ALSA Driver       zita-a2j / zita-j2a        zita-a2j / zita-j2a        zita-a2j / zita-j2a
         |                   (Resample Ratio: 1.0)      (Resample Ratio: 1.0)      (Resample Ratio: 1.0)
         v                        v                          v                          v
+------------------+     +------------------+       +------------------+       +------------------+
| RED (Master)     |     | BLUE (Slave 1)   |       | YELLOW (Slave 2) |       | GREEN (Slave 3)  |
| 12 In / 12 Out   |     | 12 In / 12 Out   |       | 12 In / 12 Out   |       | 12 In / 12 Out   |
+------------------+     +------------------+       +------------------+       +------------------+

Service Architecture (~/git/audio_config/profiles/jack-alsa/)

  1. wait-for-firewire.sh: Ensures all 4 ALSA cards (hw:AudioFire12_3, hw:AudioFire12_2, hw:AudioFire12, hw:AudioFire12_1) are initialized by the kernel before launching audio daemons.
  2. jack.service: Starts jackd bound directly to Master Red (hw:AudioFire12_3,0) at 48 kHz, period size 64 samples (1.33 ms latency), 3 buffer periods.
  3. zita-*-{blue,yellow,green}.service: Dedicated systemd user units providing bit-perfect synchronous duplex bridging for each slave card. Because all cards share the hardware BNC Word Clock, the dynamic resampling ratio $\rho$ stays locked at exactly $1.0000000000$.
  4. set-port-aliases.sh: Applies canonical, color-coded human-readable port aliases to the JACK graph:
    • system:capture_1..12 $\rightarrow$ Red_01 .. Red_12
    • zita-a2j-blue:capture_1..12 $\rightarrow$ Blue_01 .. Blue_12
    • zita-a2j-yellow:capture_1..12 $\rightarrow$ Yellow_01 .. Yellow_12
    • zita-a2j-green:capture_1..12 $\rightarrow$ Green_01 .. Green_12

4. Empirical Zero-Drift Verification (10-Minute Stress Test)

To prove mathematical clock synchronization, an empirical dual-channel continuous recording was captured across card boundaries:

  • Channel A: Master Red Out 1 $\rightarrow$ Master Red In 1 (hw:AudioFire12_3,0)
  • Channel B: Master Red Out 2 $\rightarrow$ Slave Yellow In 1 (hw:AudioFire12,0 via zita-a2j-yellow)

A continuous 1 kHz calibration tone was recorded for 600.0 seconds (10 continuous minutes / 28,801,024 audio samples).

Cross-Correlation Results

Elapsed Time Master Red Sample Index Slave Yellow Sample Index Relative Offset Cumulative Drift
$t = 5\text{ s}$ $240,000$ $244,127$ $-4,127\text{ smp}$ (buffer init) Baseline
$t = 1\text{ min}$ $2,880,000$ $2,884,799$ $-4,799\text{ smp}$ (settled) $0.000\text{ ms}$
$t = 2\text{ min}$ $5,760,000$ $5,764,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 3\text{ min}$ $8,640,000$ $8,644,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 4\text{ min}$ $11,520,000$ $11,524,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 5\text{ min}$ $14,400,000$ $14,404,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 6\text{ min}$ $17,280,000$ $17,284,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 7\text{ min}$ $20,160,000$ $20,164,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 8\text{ min}$ $23,040,000$ $23,044,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 9\text{ min}$ $25,920,000$ $25,924,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)
$t = 9.9\text{ min}$ $28,512,000$ $28,516,799$ $-4,799\text{ smp}$ $0.000\text{ ms}$ ($0\text{ samples}$)

Conclusion: Across 9 minutes of continuous multichannel streaming after buffer initialization, there was exactly 0 samples (0.0000 ms) of cumulative drift, proving absolute phase alignment.


5. Operations & Service Management

Full Audio Stack Restart

# 1. Stop slave bridges and master JACK
$ systemctl --user stop zita-*-{blue,yellow,green}.service
$ systemctl --user stop jack.service

# 2. Clear stale POSIX semaphores / mutexes
$ rm -rf /dev/shm/jack* /dev/shm/sem.jack* /dev/shm/jack_db-*

# 3. Start master JACK
$ systemctl --user start jack.service

# 4. Start slave duplex bridges
$ systemctl --user start zita-a2j-blue.service zita-j2a-blue.service
$ systemctl --user start zita-a2j-yellow.service zita-j2a-yellow.service
$ systemctl --user start zita-a2j-green.service zita-j2a-green.service

# 5. Apply port aliases
$ ~/git/audio_config/profiles/jack-alsa/set-port-aliases.sh