eth68
Kenmerken
- Zeer lage latentie: 3,620 milliseconden round trip bij 48 kHz met een buffer van 64 samples.
- Schaalbaar: meerdere eenheden kunnen worden gesynchroniseerd om het aantal kanalen te vergroten zonder de round trip audio-latentie te verhogen.
- Ingangen: 6 gebalanceerde line-level ingangen op 1/4 inch TRS-connectoren.
- Uitgangen: 8 gebalanceerde line-level uitgangen op 1/4 inch TRS-connectoren.
- Sample rates: 48 kHz en 96 kHz.
- Codec: Burr-Brown PCM3168A codec.
- Connectiviteit: DIN MIDI-connectiviteit.
- Behuizing: 1U 19-inch rackchassis.
Gebruik met JACK
eth68 draait op een aangepaste bare-metal firmware op een STM32H7-microcontroller die een netJACK1 master-endpoint emuleert. Om audio-uitwisseling met eth68 te starten, start een JACK-server met de netone-backend:
jackd -d netone
Zodra het eerste inkomende capture-pakket van eth68 wordt ontvangen, maakt JACK IO-poorten aan die gekoppeld zijn aan de fysieke eth68 IO's. Start vervolgens een JACK-compatibele applicatie en verbind deze met de eth68 IO's.
Gebruik met PipeWire
Het is ook mogelijk om direct in te pluggen op een PipeWire-sessie met behulp van de pw-eth68 client. Deze PipeWire-client implementeert een vergelijkbaar gedrag als een JACK-server met de netone-backend. Start een PipeWire-compatibele applicatie en verbind deze met de eth68 IO's.
Audiolatentie
Audiolatentie is de hoorbare latentie van het audiosignaal zelf terwijl het door de hardware- en softwarelagen van de audio beweegt. Audiolatentie ontstaat door buffering in zowel de hardware als de software, alsook door digitale filtergroepsvertraging in de audio-codec. De round trip audio-latentie kan worden gemeten met een loopback-kabel.
Op systemen met een grote audiolatentie is er een merkbare vertraging tussen het indrukken van een toets op een MIDI-keyboard en het horen van het resultaat van een software-synthesizer. Diverse experimenten hebben vastgesteld dat de drempelwaarde voor latentieperceptie ligt tussen de 5 en 20 ms, afhankelijk van de luistercontext.
eth68 behaalt een round trip audio-latentie van 3,620 milliseconden bij 48 kHz met een buffergrootte van 64 samples, gemeten met jack_delay en een loopback-kabel.
De volgende tabel vat de round trip latentiemetingen van eth68 samen met jack_delay voor verschillende buffergroottes bij 48 en 96 kHz [1, 2]:
| Buffer | 48 kHz | 96 kHz |
|---|---|---|
| 32 | 2,288 ms | 1,148 ms |
| 64 | 3,620 ms | 1,814 ms |
| 96 | 4,954 ms | 2,480 ms |
| 128 | 6,287 ms | 3,147 ms |
| 256 | 11,621 ms | 5,814 ms |
[1] Voor deze metingen werd jackd uitgevoerd in synchrone modus met jackd -S -d netone. [2] Bij gebruik van de PipeWire-client pw-eth68 waren de gemeten roundtrip latenties (met pw-jack jack_delay) exact hetzelfde.
Vergelijking met de RME HDSPe AIO Pro PCIe-kaart [3]:
| Buffer | 48 kHz | 96 kHz |
|---|---|---|
| 32 | - | - |
| 64 | 3,62 ms | 2,14 ms |
| 96 | - | - |
| 128 | 6,28 ms | 3,48 ms |
| 256 | 11,62 ms | 6,14 ms |
[3] Metingen afkomstig van bron.
eth68 komt overeen met de latentieprestaties van de RME-kaart bij 48 kHz en overtreft deze met 0,33 ms bij 96 kHz.
Synchronisatie van meerdere eenheden
Meerdere eth68-eenheden kunnen worden gesynchroniseerd om het aantal kanalen te vergroten. Synchronisatie wordt bereikt door:
- Het delen van een hogefrequentie (HF) klok. Eén eth68-eenheid fungeert als klokmaster en genereert een HF-klok die via BNC-kabels in een daisy-chain naar aanvullende eth68-eenheden wordt gestuurd. Het delen van de HF-klok elimineert sample-drift tussen de eenheden.
- Het nulstellen van de sample-offset tussen eenheden. Dit gebeurt door een broadcast UDP sync-commando te verzenden met
eth68ctl.py. Alle eenheden ontvangen het sync-broadcastbericht binnen ongeveer 1 sampletijd (20,8 $\mu$s bij 48 kHz) en starten hun DMA-transfers onmiddellijk opnieuw. Dit resulteert in een sample-offset van -1, 0, of +1 samples tussen de eenheden.
Multi-unit bediening via de JACK-interface vereist het gebruik van een tussenliggende proxy-applicatie, eth68proxy, aangezien netjack niet is ontworpen om data van/naar meerdere masters te samenvoegen of te splitsen. eth68proxy zorgt voor het samenvoegen van de capture-pakketten van meerdere eth68's in één groter netjack-compatibel capture-pakket, en splitst een groot playback-pakket van netjack om kleinere playback-pakketten naar elke eth68-eenheid te leveren.
Met twee gesynchroniseerde eth68's [4] en een draaiende eth68proxy, detecteert netjack automatisch het verdubbelde aantal kanalen en maakt de JACK-poorten aan.
[4] Ik heb slechts twee eth68 PCB's geproduceerd, dus ik heb multi-unit sync alleen met twee eenheden kunnen testen. Ik vermoed dat deze aanpak zal werken in het bereik van 4x - 8x eenheden, maar er is meer assemblage en testen nodig om dit te bevestigen.
Een scope-opname toont één output van elk van de twee gesynchroniseerde eenheden, beide aangestuurd door dezelfde zaagtand-oscillator vanuit Reaper. In de afbeelding triggert de scope op de dalende flank van de zaagtand, en het groene spoor is voor de duidelijkheid met 20 millivolt verschoven. De golfvormen zijn uitgelijnd op minder dan 1 microseconde, oftewel 1/20ste van een sample bij 48 kHz.
Bij het werken met gesynchroniseerde eth68's is de round trip audio-latentie gelijk aan die van een enkele eth68. Dit is geverifieerd door een output van de eerste eenheid terug te koppelen naar een input op de tweede gesynchroniseerde eenheid en jack_delay uit te voeren. Er is een kleine straf op de verwerkingslatentie door de extra stap via eth68proxy, maar dit is op mijn systeem niet significant genoeg om de xrun-frequentie meetbaar te verhogen.
Bij gebruik van de PipeWire-interface beheert pw-eth68 de datastromen van/naar meerdere eth68's, waardoor eth68proxy niet nodig is.
Verwerkingslatentie
Verwerkingslatentie (Processing Latency) is de tijd die nodig is om alle verwerking van een audiobuffer te voltooien. De verwerkingslatentie moet kleiner zijn dan de deadline-tijd, anders treedt er een xrun (overrun of underrun) op, wat resulteert in een hoorbare glitch. In de afwezigheid van xruns is de verwerkingslatentie niet hoorbaar. De verwerkingslatentie kan op verschillende manieren worden verminderd en gecontroleerd, waaronder het optimaliseren van het host-besturingssysteem voor responsiviteit of het gebruik van een krachtigere hostcomputer.
eth68 genereert een digitaal signaal van 3,3 V, LATMON, voor het meten en debuggen van de verwerkingslatentie. Het signaal is beschikbaar op een BNC-connector op het achterpaneel.
LATMON gaat hoog zodra capture-data beschikbaar is in de capture DMA-buffer. LATMON gaat laag wanneer eth68 klaar is met het kopiëren van de ontvangen playback-data naar de playback DMA-buffer. De breedte van de LATMON-puls is daarom een nauwkeurige maatstaf voor de totale verwerkingslatentie van elke cyclus en wordt beïnvloed door elk element in het datapad: verwerkingsvertraging in de microcontroller, netwerktransmissievertraging, vertragingen in het host-OS, signaalverwerkingsvertraging in de DAW, etc.
Het maken van een histogram van de LATMON-pulsbreedtes in realtime geeft een inzicht in de verwerkingslatentie en de bijbehorende jitter. In de betreffende grafiek is de verticale stippellijn getrokken op 1333 microseconden, wat de deadline-tijd is voor 64 sample-buffers bij 48 kHz. Pulsbreedtes die op of rechts van de stippellijn vallen, zouden leiden tot een xrun. De verwerkingslatentie voor een typische cyclus is ongeveer 625 microseconden, wat een marge van 708 microseconden (meer dan 50%) tot de deadline laat. Deze data is vastgelegd terwijl Bitwig een project draaide met een gemiddelde DSP-belasting.
We kunnen de latentieprestaties kunstmatig verslechteren door enkele "hogs" te verzenden met stress -c 6. Dit maakt het host-systeem minder responsief door het bezig te houden met zinloos werk, waardoor de distributie van de LATMON-pulsbreedte dichter bij de deadline komt te liggen.
Netwerkconfiguratie
Standaard verzendt eth68 capture-pakketten naar 12.12.12.10:3000. De eenvoudigste manier om te beginnen is door het IP-adres van je host in te stellen op 12.12.12.10 en jackd -d netone uit te voeren. Voor andere configuraties kan het script eth68ctl.py worden gebruikt om de netwerkinstellingen van de eth68 aan te passen.
Vraag de instellingen van de eth68 op met eth68ctl.py:
python eth68ctl.py 12.12.12.10 query
Output:
--------------------------
header: 2820800604
board_id: 3407900
source_ip: 12.12.12.100 (202116196)
netmask_ip: 255.255.255.0 (4294967040)
gateway_ip: 12.12.12.1 (202116097)
destination_ip: 12.12.12.10 (202116106)
destination_port: 3000
mode: 0
period_size: 64
sample_rate: 48000
capture_channels: 6
playback_channels: 8
footer: 2603798065
Uit de output kunnen we opmaken dat het IP-adres van de eth68 12.12.12.100 is en dat deze capture-pakketten verzendt naar 12.12.12.10:3000.
Het eerste argument voor eth68ctl.py is het host-IP op de interface die een LAN-verbinding deelt met eth68. eth68ctl.py gebruikt broadcast UDP op deze interface om eth68-eenheden aan te sturen. Het gebruik van broadcast UDP zorgt ervoor dat communicatie altijd mogelijk is, zelfs als de netwerkinstellingen onjuist zijn.
De instellingen kunnen worden gewijzigd met het "set" sub-commando. Bijvoorbeeld, om het bestemmings-IP te wijzigen naar 12.12.12.50:
python eth68ctl.py 12.12.12.10 --boardid 3407900 set destinationip 12.12.12.50
eth68ctl.py wordt ook gebruikt om niet-netwerkgerelateerde instellingen te wijzigen, zoals de sample rate:
python eth68ctl.py 12.12.12.10 --boardid 3407900 set samplerate 96000
Netwerkhardware
Het wordt aanbevolen om een dedicated LAN te gebruiken voor eth68-setups, die geïsoleerd is van overig verkeer. Gewone netwerkhardware kan zeer goede resultaten leveren. AVB/TSN ethernet-compatibele hardware is niet vereist. Een 1G ethernet-switch wordt aanbevolen voor multi-unit setups.
eth68 verbindt op 100M full duplex, maar een 1G full duplex verbinding tussen de host en de switch vermindert de verwerkingslatentie. Als er slechts één eth68 wordt gebruikt, kan deze direct worden verbonden met de NIC van de host zonder switch.
De resultaten hangen sterk af van de NIC van de host. Uitstekende resultaten kunnen worden behaald met Intel I210 NIC's. Een belangrijk aspect van de NIC is dat het interruptgedrag kan worden gewijzigd. NIC's implementeren vaak een vorm van interrupt coalescing, wat incompatibel kan zijn met real-time applicaties. De Intel I210 implementeert blijkbaar een redelijk standaardbeleid voor interrupt coalescing, aangezien audio met eth68 vloeiend verloopt met de standaardinstellingen. Echter, met behulp van de latency debug monitor is ontdekt dat de verwerkingslatentie met een volle 175 $\mu$s (13% van de deadline-tijd) kan worden verminderd door de interrupt coalescing timeout te wijzigen met het volgende commando:
ethtool -C enp9s0 rx-usecs 0
Audiometingen
Voor het meten van de THD+N prestaties van de (differentieële) input is een Stanford Research DS360 Ultra Low Distortion Function Generator gebruikt.
Het -1 dBFS piek-inputsignaal werd digitaal gefilterd met een steil 20 kHz laagdoorlaatfilter en een Q = 5 notch-filter op de fundamentele frequentie volgens AES17. Het PCM3168A-datasheet specificeert een THD+N van typisch -93 dB bij 1 kHz voor een sample rate van 48 kHz. De meting bij 1 kHz is THD+N = -94,8 dBFS (0,0018%).
Let op dat de plotselinge verbetering van THD+N rond 10 kHz komt doordat de tweede harmonische verschuift naar de stopband van het 20 kHz laagdoorlaatfilter.
Er is geen testapparatuur beschikbaar die gevoelig genoeg is om de THD+N van de outputs te meten. In plaats daarvan is een eth68-input gebruikt om de prestaties van de eth68-output te analyseren in een loopback-configuratie. Deze meting is in feite een bovengrens voor de outputprestaties, aangezien de input THD+N bijdraagt aan de loopback THD+N. Desalniettemin ligt de loopback THD+N binnen 0,5 - 1 dBFS van de input THD+N zoals gemeten met de DS360.
Met de loopback nog steeds verbonden, is een fijnere frequentiescan uitgevoerd om de vlakheid van de passband te controleren. De gecombineerde input + output passbandvlakheid is +/- 0,15 dBFS.
Bij het uitschakelen van de toongenerator en het meten van het ruisniveau met een A-wegingsfilter over een bandbreedte van 20 kHz, zijn de volgende resultaten behaald:
- Alleen input, input geaard: -107,8 dBFS bij 48 kHz, -110,5 dBFS bij 96 kHz. A-weighted.
- Input + output (loopback): -106,2 dBFS bij 48 kHz, -108,6 dBFS bij 96 kHz. A-weighted.
Gerekend naar de verhouding ten opzichte van een full scale -3 dBFS RMS sinusgolf, is het dynamisch bereik:
- Alleen input, input geaard: DR = -104,8 dBFS bij 48 kHz, DR = -107,5 dBFS bij 96 kHz. A-weighted.
- Input + output (loopback): DR = -103,2 dBFS bij 48 kHz, DR = -105,6 dBFS bij 96 kHz. A-weighted.
macOS en Windows
Hoewel de focus primair ligt op Linux-compatibiliteit, is JACK cross-platform en wordt eth68 succesvol gedetecteerd door de JACK-server op zowel macOS als Windows. Helaas zijn de meeste audio-applicaties op macOS en Windows niet JACK-aware; Ableton Live op macOS weet bijvoorbeeld niet hoe het met een JACK-server moet communiceren. Zelfs applicaties die op Linux JACK-aware zijn, zijn dat niet altijd op andere OS'en; Reaper ondersteunt JACK op Linux, maar niet op macOS. Het JACK-project probeert dit probleem op te lossen door een virtuele driver "JACK-Router" te bundelen, die overbrugt tussen de native audio driver interface (CoreAudio op macOS, ASIO op Windows) en de JACK-sessie.
Huidige status van JACK-Router:
- JACK-Router werkt momenteel op Windows.
- JACK-Router op macOS is momenteel defect door wijzigingen in macOS 10.15.
Workbench
eth68 Revisie B PCB op de werkbank voor loopback-testen.
Host-systeem
- OS: Ubuntu 24.04.3 LTS
- Kernel: 6.19.10-2-liquorix-amd64
- CPU: AMD Ryzen 7 5700X
- Moederbord: ASUS B450-F
- Switch: TP-LINK TL-SG608
- NIC: Intel I210
© 2026-10-04 Alex Lowell.
Groetjes,