Audio Stack
This page documents the 48-channel synchronous Linux audio recording infrastructure on bmo95, including hardware interface mapping, BNC Word Clock daisy-chain wiring, real-time ALSA/JACK bridging architecture, and empirical zero-drift verification.
1. Hardware Architecture & Echo AudioFire12 Mapping
The studio uses 4x Echo AudioFire12 FireWire (IEEE 1394a) audio interfaces, providing a total of 48 balanced analog line inputs and 48 balanced analog line outputs at 24-bit / 48.0 kHz.
Color Standard & ALSA Device Mapping
To simplify physical cabling and logical routing, each interface is assigned a color-coded identity tied to its hardware MAC address and ALSA index:
| Color | Interface ID | Hardware MAC (GUID) | ALSA Device Node | Physical Jack Outputs | Jack Inputs / Channels | Role |
|---|---|---|---|---|---|---|
| RED | AudioFire12_3 |
00148601c000fc79 |
hw:AudioFire12_3,0 |
Outs 1–12 | Red_01 .. Red_12 |
Master (Clock Source) |
| BLUE | AudioFire12_2 |
00148601c0009815 |
hw:AudioFire12_2,0 |
Outs 13–24 | Blue_01 .. Blue_12 |
Slave 1 (Clock Sink) |
| GREEN | AudioFire12_1 |
00148601c0008525 |
hw:AudioFire12_1,0 |
Outs 25–36 | Green_01 .. Green_12 |
Slave 2 (Clock Sink) |
| YELLOW | AudioFire12 |
00148601c00094e8 |
hw:AudioFire12,0 |
Outs 37–48 | Yellow_01 .. Yellow_12 |
Slave 3 (75Ω Terminated) |
Figure 1: The 4-unit Echo AudioFire12 stack rack-mounted in bmo95.
2. Clock Synchronization & Wiring Topology
Digital audio across 4 discrete converters requires sample-accurate phase alignment to eliminate clock drift, comb filtering, and inter-channel sample slips.
BNC Word Clock Daisy-Chain
The interfaces are synchronized via dedicated 75Ω BNC coaxial Word Clock cabling:
$$\text{Red (Source: fc79)} \longrightarrow \text{Blue (1st Sink: 9815)} \longrightarrow \text{Green (2nd Sink: 8525)} \longrightarrow \text{Yellow (3rd Sink: 94e8 / 75}\Omega\text{ Terminated)}$$
+-------------------------------------------------------------------------------+
| RED (Source: fc79) |
| Clock Mode: Internal (48000 Hz) |
| BNC Word Clock OUT --------------------------------------------------------+ |
+----------------------------------------------------------------------------|--+
|
+-------------------------------------------------------------------+
|
v
+-----------------------+ +-------------------------+ +-------------------------+
| BLUE (1st Sink: 9815) | | GREEN (2nd Sink: 8525) | | YELLOW (3rd Sink: 94e8) |
| Clock Mode: Word Clock| | Clock Mode: Word Clock | | Clock Mode: Word Clock |
| BNC Word Clock IN (T) | --> | BNC Word Clock IN (T) | --> | BNC Word Clock IN (T) |
| Pass-through to Green | | Pass-through to Yellow | | 75Ω BNC Terminator OUT |
+-----------------------+ +-------------------------+ +-------------------------+
Figure 2: 75Ω BNC feed-through T-connector with physical terminator on the final Yellow unit.
FireWire Bus Topology
The host machine (bmo95) features dual Texas Instruments PCIe FireWire host controllers. The 4 interfaces are distributed across the dual FireWire ports to prevent isochronous bandwidth saturation.
$ lspci | grep FireWire
07:00.0 FireWire (IEEE 1394): Texas Instruments XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express] (rev 01)
0a:00.0 FireWire (IEEE 1394): Texas Instruments TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
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) | | GREEN (Slave 2) | | YELLOW (Slave 3) |
| 12 In / 12 Out | | 12 In / 12 Out | | 12 In / 12 Out | | 12 In / 12 Out |
+------------------+ +------------------+ +------------------+ +------------------+
Service Architecture (jack-alsa)
wait-for-firewire.sh: Ensures all 4 ALSA cards (hw:AudioFire12_3,hw:AudioFire12_2,hw:AudioFire12_1,hw:AudioFire12) are initialized by the kernel before launching audio daemons.jack.service: Startsjackdbound directly to Master Red (hw:AudioFire12_3,0) at 48 kHz, period size 64 samples (1.33 ms latency), 3 buffer periods.zita-*-{blue,green,yellow}.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.set-port-aliases.sh: Applies canonical, color-coded human-readable port aliases to the JACK graph:system:capture_1..12→Red_01..Red_12zita-a2j-blue:capture_1..12→Blue_01..Blue_12zita-a2j-green:capture_1..12→Green_01..Green_12zita-a2j-yellow:capture_1..12→Yellow_01..Yellow_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 → Master Red In 1 (
hw:AudioFire12_3,0) - Channel B: Master Red Out 2 → Slave Yellow In 1 (
hw:AudioFire12,0viazita-a2j-yellow)
Because Yellow is the fourth and final device in the Word Clock daisy-chain, verifying zero drift against Yellow proves that all intermediate interfaces (Blue and Green) in the clock propagation path are also phase-locked.
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 s | 240,000 | 244,127 | -4,127 smp (buffer init) | Baseline |
| t = 1 min | 2,880,000 | 2,884,799 | -4,799 smp (settled) | 0.000 ms |
| t = 2 min | 5,760,000 | 5,764,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 3 min | 8,640,000 | 8,644,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 4 min | 11,520,000 | 11,524,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 5 min | 14,400,000 | 14,404,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 6 min | 17,280,000 | 17,284,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 7 min | 20,160,000 | 20,164,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 8 min | 23,040,000 | 23,044,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 9 min | 25,920,000 | 25,924,799 | -4,799 smp | 0.000 ms (0 samples) |
| t = 9.9 min | 28,512,000 | 28,516,799 | -4,799 smp | 0.000 ms (0 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,green,yellow}.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-green.service zita-j2a-green.service
$ systemctl --user start zita-a2j-yellow.service zita-j2a-yellow.service
# 5. Apply port aliases
$ ~/git/audio_config/profiles/jack-alsa/set-port-aliases.sh
No comments to display
No comments to display