Complete Educational Guide · v2.2

ETR-NodeScope

ETR-NodeScope Channel Monitor — for audio students interested in how production software is built and why it works the way it does

PCM · 1937 TCP/IP · 1974 ASIO · 1997 OSC · 1997 MQTT · 1999 Dante · 2003 WebSocket · 2011 Wireless receiver integration
▼ SCROLL TO BEGIN
Part I

The Audio World

Chapter 1Dante and Digital Audio Networking

Before ETR-NodeScope can monitor anything, audio has to be flowing. That audio lives on a Dante network — a standard that turns ordinary Ethernet switches into a professional audio router capable of carrying hundreds of channels with submillisecond latency.

What Is Dante?

Dante (Digital Audio Network Through Ethernet) was developed by Audinate, a company founded in Sydney, Australia in 2003. It carries uncompressed PCM audio as RTP/UDP packets over standard Ethernet. Every Dante-enabled device — wireless receiver, digital console, amplifier, stage box — appears as both a source and destination on the network, addressable by name.

🎓 Concept

The maths of audio over Ethernet

48,000 samples/sec × 24 bits × 64 channels = 73,728,000 bits/sec ≈ 74 Mbps Gigabit Ethernet capacity: 1,000 Mbps That's 13× headroom — one GbE port carries the full 64-channel load easily.

How ETR-NodeScope Receives Dante Audio

ETR-NodeScope does not handle Dante UDP packets directly. It uses Dante Virtual Soundcard (DVS) — a driver that presents the Dante network as an ASIO audio device to Windows. DVS handles all the protocol work; ETR-NodeScope reads the delivered audio the same way a DAW reads from an audio interface.

LayerWhat it does
Dante network (UDP/IP)Audio flows as RTP/UDP packets between devices on the LAN
Dante Virtual SoundcardReceives UDP packets, presents them as an ASIO device to Windows
ETR-NodeScope (ASIO client)Reads audio frames via the ASIO API — same as a DAW reading a sound card
Tile metersConverts each audio frame to a dBFS/dBu level for display

From Float to dBu — How the Meter Works

ASIO delivers audio as 32-bit floats normalised to −1.0 to +1.0. ETR-NodeScope converts to dBu (a real-world voltage reference) using the EBU R68 calibration constant:

// ASIO delivers float samples where +1.0 = 0 dBFS // Professional standard: 0 dBFS ≈ +18 dBu (EBU R68) double dBFS = 20.0 * Math.Log10(Math.Abs(sample) + 1e-9); double dBu = dBFS + 18.0; // Example: sample = 0.5 → dBFS = -6.02 → dBu = +11.98
❓

Chapter 1 Quiz

Dante and Digital Audio Networking — 5 questions, pass mark 60%

Question 1 of 5

What protocol does Dante use to carry audio across the network?

Question 2 of 5

Why does ETR-NodeScope use Dante Virtual Soundcard rather than connecting to the Dante network directly?

Question 3 of 5

What is ASIO and why does it matter for ETR-NodeScope?

Question 4 of 5

At 48,000 Hz with a 512-sample ASIO buffer, how often does ETR-NodeScope's audio callback fire?

Question 5 of 5

What does the +18 dBu offset in the ETR-NodeScope level calculation represent?

Part II

History of the Protocols

Chapter 2A History of Every Protocol ETR-NodeScope Uses

Every technology in ETR-NodeScope has a story. Understanding where these standards came from — who invented them, what problem they solved, what constraints they were designed under — makes them much easier to understand and remember.

1937
PCM — Pulse Code Modulation (Alec Reeves, ITT Paris) Reeves filed French patent 852,183 on 22 October 1937 — the idea of sampling an audio waveform at regular intervals and storing each measurement as a binary number. He could not get anyone interested; the patent expired in 1954 before it was exploited. The idea only became practical when Bell Labs used it for military voice encryption (SIGSALY, 1943). PCM reached consumer audio in 1980 with the Compact Disc. Every piece of digital audio in ETR-NodeScope is PCM.
1960
RS-232 — Serial Communication Standard (EIA) The Electronic Industries Association published RS-232 in 1960 to define how computers communicate with modems. By the 1980s it became the universal AV control language — every rack-mount device had an RS-232 port accepting text commands like POWER ON\r. When Ethernet replaced RS-232 in the 2000s, manufacturers simply wrapped the same ASCII commands in TCP sockets. Wireless's port 2202 protocol — < GET 1 BATT_CHARGE > — is RS-232-era design philosophy running over modern TCP/IP.
1974
TCP/IP — Cerf and Kahn, IEEE Transactions on Communications Vint Cerf and Bob Kahn published "A Protocol for Packet Network Intercommunication" in 1974, defining the two-layer model: IP handles routing and addressing; TCP adds guaranteed delivery, in-order reassembly, and flow control. Everything ETR-NodeScope does over the network runs on TCP/IP. The three-way handshake (SYN, SYN-ACK, ACK) plus ARP resolution on link-local addresses is why ETR-NodeScope uses an 800ms TCP probe timeout for Wireless discovery.
1983
MIDI — Musical Instrument Digital Interface Published August 1983 by a consortium including Roland, Yamaha, Korg, and Sequential Circuits. MIDI's 31.25 kBaud serial connection and 7-bit value resolution (0–127) were appropriate for 1983 microcontrollers. By the 1990s its limitations — no floating-point values, no network transport, fixed message types — were painful. MIDI's shortcomings directly motivated the design of OSC.
1991
WAV File Format — Microsoft and IBM WAV was introduced as part of Windows 3.1 multimedia extensions, built on the RIFF (Resource Interchange File Format) container developed with IBM, itself derived from Electronic Arts' IFF format (1985). The format uses a 44-byte header describing the audio, followed by raw PCM samples. ETR-NodeScope writes this header before streaming audio over HTTP so media players (VLC, browser <audio> tags) can decode the stream. The format is 34 years old and every media player still reads it.
1997
ASIO — Audio Stream Input/Output (Steinberg) Steinberg created ASIO to solve Windows audio latency. Windows' 1990s audio stack was designed for game sound effects (100–200ms latency acceptable). Professional recording demands real-time monitoring at under 10ms. ASIO bypasses the Windows audio mixer and talks directly to hardware drivers, enabling 3–10ms latency. Its callback model — the driver calls your function at precise intervals — is fundamental to ETR-NodeScope's audio pipeline.
1997
OSC — Open Sound Control (Wright & Freed, CNMAT, UC Berkeley) Presented at the International Computer Music Conference in 1997. Designed as everything MIDI was not: 32-bit float values instead of 7-bit integers, arbitrary URL-like address patterns (/etr-nodescope/channel/1/battery) instead of fixed message types, UDP over any network instead of a serial wire, and 64-bit NTP timestamps for precise scheduling. ETR-NodeScope sends OSC for Qlab integration, lighting console triggers, and custom monitoring scripts.
1999
MQTT — Message Queuing Telemetry Transport (Stanford-Clark & Nipper, IBM) Invented by Andy Stanford-Clark of IBM and Arlen Nipper of Arcom to monitor oil pipelines across the Sahara desert over expensive, unreliable satellite links. Design goals: minimal bandwidth (every byte matters at USD 10/KB), reliable delivery (QoS levels), low power, publish/subscribe broker model. IBM kept it proprietary until 2013 when it was released to OASIS, coinciding with the IoT boom. ETR-NodeScope uses MQTTnet (a .NET library) to publish channel state with QoS 1 (at-least-once delivery).
2000
REST — Roy Fielding's PhD Thesis, UC Irvine Roy Fielding (co-author of HTTP/1.1) defined REST (Representational State Transfer) in his 2000 PhD thesis. REST constraints — stateless requests, uniform interface (GET/PUT/POST), self-describing messages — made web services scalable and interoperable. Wireless's SSC v2 API (used by ETR-NodeScope for digital wireless receiver receivers) is a REST API. The contrast with Wireless's ASCII protocol illustrates 20 years of API design evolution.
2001
JSON — JavaScript Object Notation (Douglas Crockford) Crockford formalised JSON around 2001, published RFC 4627 in 2006. JSON is a subset of JavaScript object literal syntax that had existed since 1995 — Crockford's contribution was identifying it as a useful standalone data format. Wireless's protocol uses JSON push messages; ETR-NodeScope's WebSocket messages to browsers are JSON; MQTT payloads are JSON. The contrast with Wireless's ASCII strings shows how data serialisation has evolved.
2002
mDNS / Bonjour (Stuart Cheshire, Apple) Apple shipped Rendezvous (later renamed Bonjour) in Mac OS X 10.2 as part of the zero-configuration networking initiative. mDNS sends DNS queries to multicast address 224.0.0.251:5353 — any device that matches responds directly, no DNS server needed. Standardised as RFC 6762 in 2013. ETR-NodeScope uses mDNS to find Wireless digital wireless receiver receivers and — critically — to find the control interface IP of digital wireless receivers (AD4D-A, AD4Q) which is different from the Dante audio interface IP.
2003
Dante — Audinate (Sydney, Australia) Audinate was founded in 2003 as a spin-out from the University of Technology Sydney. Dante went commercial around 2006. Yamaha was the first major manufacturer to adopt it (2009 digital consoles). The predecessor, CobraNet (Cirrus Logic, 1996), required special hardware and managed switches. Dante runs on commodity GbE with no special infrastructure. Today Dante is the dominant professional audio networking standard with thousands of compatible products.
2006
Server-Sent Events (Ian Hickson, Opera) Hickson developed SSE at Opera Software and included it in the WHATWG HTML Living Standard. SSE holds an HTTP connection open and streams text events as they occur — simpler than WebSocket for one-directional push use cases. Standardised as RFC 8895. Wireless chose SSE for SSC v2 because digital wireless receiver is a monitoring tool: data flows from receiver to controller. Commands (mute, gain) are separate HTTP requests, not sent back over the SSE stream.
2011
WebSocket (RFC 6455) WebSocket was developed as part of HTML5, published as RFC 6455 in December 2011. It upgrades an HTTP connection to a full-duplex TCP stream via the Upgrade header. Before WebSocket, real-time web apps used polling (GET every second), long-polling (hold response open), or HTTP streaming (Comet) — all awkward. ETR-NodeScope's WebUI uses WebSocket for JSON state updates (text frames) and PCM audio (binary frames) on the same connection simultaneously.

Complete Timeline

YearTechnologyETR-NodeScope Connection
1937PCM (Alec Reeves)Foundation of all digital audio
1958Sony WRT-57/WRR-57 — first commercial wireless micStart of the wireless microphone industry
1960RS-232 serial standard (EIA)Ancestor of Wireless's ASCII command protocol
1974TCP/IP (Cerf and Kahn)Foundation of all ETR-NodeScope network communication
1983MIDI standardContext for OSC — shows what OSC improved on
1991WAV file format (Microsoft/IBM)ETR-NodeScope HTTP audio stream format
1997ASIO (Steinberg)ETR-NodeScope's audio capture interface
1997OSC 1.0 (Wright & Freed, CNMAT)ETR-NodeScope OSC integration for Qlab etc.
1999MQTT (Stanford-Clark, IBM)ETR-NodeScope MQTT channel state publishing
2000REST (Fielding PhD thesis)Foundation of Wireless SSC v2 API
2001JSON (Crockford)Wireless protocol, WebSocket messages
2002mDNS / Bonjour (Apple)Finds Wireless and digital wireless control IPs
2003Dante development begins (Audinate)The audio network ETR-NodeScope monitors
2006Server-Sent Events (Hickson, Opera)Wireless SSC v2 real-time data delivery
2011WebSocket RFC 6455ETR-NodeScope WebUI real-time updates and audio
2017FCC 600 MHz spectrum repackForces wireless frequency coordination
2017digital wireless launched (Wireless)AD4D, AD4Q — Wireless hardware supported
2020digital wireless receiver launched (Wireless) with SSC v2Wireless hardware supported
❓

Chapter 2 Quiz

History of the Protocols — 5 questions, pass mark 60%

Question 1 of 5

PCM was invented in 1937 by Alec Reeves. Why was it not commercially exploited until the 1970s?

Question 2 of 5

Why does Wireless's TCP/2202 protocol look like RS-232 serial commands with angle brackets and spaces?

Question 3 of 5

MQTT was invented to solve a problem in which industry, and what were the three key design constraints?

Question 4 of 5

Why did Wireless choose Server-Sent Events (SSE) for digital wireless receiver receivers rather than WebSocket or raw TCP?

Question 5 of 5

What was the fundamental problem that led to the creation of WebSocket in 2011?

Part III

The Software Architecture

Chapter 3How ETR-NodeScope Is Structured

ETR-NodeScope is a C# / .NET 8 desktop application using Avalonia UI. Its architecture separates concerns into layers — each layer has one job, communicates upward via events, and knows nothing about the layers above it.

LayerClassesResponsibility
ModelsWirelessChannelState, ChannelStateDto, AlertModelPure data — no logic, no UI
ServicesShureDeviceClient, DiscoveryService, SmartAlertsEngine, WebUIServerAll business logic and hardware communication
ViewModelsMainViewModel, ChannelTileViewModelTranslate service data into bindable UI properties
ViewsMainWindow.axaml, ChannelTile.axamlXAML layout — no logic, binds to ViewModel properties
IntegrationMqttService, OscService, SessionLogServiceMQTT broker, OSC UDP, log files

The 12-Step Journey from Transmitter to Tile

1. Transmitter embeds battery % in RF side-channel (~400 bits/sec) 2. Receiver demodulates: "< REP 1 BATT_CHARGE 078 >" 3. BaseDeviceClientAdapter.ReceiveLoopAsync() reads the line 4. ShureDeviceClient.ParseMessage() routes → HandleRep() 5. case "BATT_CHARGE": state.BatteryPercent = 78 6. PublishChannelIfChanged() compares with last published snapshot 7. If changed → RaiseChannelDataReceived(channel=1, state) 8. C# event fires → all subscribers notified simultaneously 9. MainViewModel.OnDeviceChannelData() receives it 10. tile.BatteryDisplay = "78%" 11. tile.BatteryLevel = 0.78 12. Avalonia data binding updates the tile — no explicit UI code
🎓 Concept

The Observer Pattern — C# events

Step 7–9 uses C# events — a built-in implementation of the Observer pattern (Gang of Four, 1994). ShureDeviceClient fires an event; MainViewModel, SmartAlertsEngine, WebUIServer, and SessionLogService all subscribe. ShureDeviceClient knows nothing about any of them:

// ShureDeviceClient declares the event: event Action<int, WirelessChannelState>? ChannelDataReceived; // Fires it after parsing a REP message: RaiseChannelDataReceived(channel, state); // All four subscribers run — ShureDeviceClient knows nothing about them: mainViewModel.ChannelDataReceived += OnDeviceChannelData; smartAlertsEngine.ChannelDataReceived += EvaluateChannel; webUIServer.ChannelDataReceived += PushStateToClients; sessionLogger.ChannelDataReceived += MaybeLogBatterySwap;

Change Detection — Not Every Frame Reaches the UI

Wireless sends SAMPLE frames every 100ms. ETR-NodeScope filters them before the UI is updated — only meaningful changes cause a redraw:

private void PublishChannelIfChanged(int channel, WirelessChannelState state) { var snapshot = ChannelPublishSnapshot.From(state); if (_lastPublishedState.TryGetValue(channel, out var previous) && !snapshot.HasMeaningfulChangeFrom(previous)) return; // RF changed by 0.5 dBm? Skip the UI update. _lastPublishedState[channel] = snapshot; RaiseChannelDataReceived(channel, state); // Something real changed }

WebUI Audio Path — Float to Browser

// Called every 10.7ms from ASIO callback // Converts ASIO float32 → PCM int16 → WebSocket binary frames unsafe { fixed (float* pIn = frame) fixed (byte* pOut = pcm) { short* pS = (short*)pOut; for (int s = 0; s < totalSamples; s++) { float v = Math.Clamp(pIn[s * channelCount + ch], -1f, 1f); pS[s] = (short)(v * 32767f); // float → int16 } } } // 128 samples × 2 bytes = 256 bytes per WebSocket binary frame // 375 frames/sec, each 2.67ms apart
❓

Chapter 3 Quiz

Software Architecture — 5 questions, pass mark 60%

Question 1 of 5

What is the purpose of PublishChannelIfChanged() in ETR-NodeScope?

Question 2 of 5

In MVVM, what is the ViewModel's role and why is it important?

Question 3 of 5

Why does ETR-NodeScope start the receive loop before calling ConnectDeviceAsync()?

Question 4 of 5

When ETR-NodeScope converts ASIO float audio to PCM-16LE for WebSocket streaming, why multiply by 32767 rather than 32768?

Question 5 of 5

What is the Observer pattern and how does ETR-NodeScope use it?

Part IV

Wireless Protocols in Depth

Wireless

wireless receiver · digital wireless · QLX-D · SLX-D · TCP Port 2202

Chapter 4Wireless Protocol — ASCII over TCP

The Grammar

TypeFormatExample
GET< GET channel PARAM >< GET 1 BATT_CHARGE >
SET< SET channel PARAM value >< SET 1 AUDIO_MUTE ON >
REP< REP channel PARAM value >< REP 1 BATT_CHARGE 078 >
SAMPLE< SAMPLE ch v1 v2 > or keyword form< SAMPLE 1 058 142 >
// The entire Wireless protocol parser — one regex + one split: var match = Regex.Match(line, @"< (?<body>.+?) >"); string[] parts = match.Groups["body"].Value.Split(' '); switch (parts[0]) { case "REP": HandleRep(parts); break; case "SAMPLE": HandleSample(parts); break; }

Device Family Detection

case "MODEL": _model = value.Trim(); _isAxient = _model.ToUpperInvariant().StartsWith("AD") || _model.ToUpperInvariant().StartsWith("ADX"); // Fallback channel count if NUM_CH response is late: if (model.Contains("AD4Q") || model.Contains("ULXD4Q")) return 4; if (model.Contains("AD4D") || model.Contains("ULXD4D")) return 2; if (model.Contains("ULXD4") || model.Contains("AD4")) return 1;

wireless receiver vs digital wireless — Key Differences

Parameterwireless receiverdigital wireless
RF levelRX_RF_LVL (raw − 128 = dBm)RSSI (raw − 120 = dBm)
Audio levelAUDIO_LVL (0–255)AUDIO_LEVEL_RMS (raw − 120 = dBFS)
Battery %BATT_CHARGE (0–100 direct)TX_BATT_CHARGE_PERCENT or SLOT_BATT_CHARGE
MuteTX_MUTE_STATUS (ON/OFF/UNKN)TX_TALK_SWITCH (OFF = muted)
Audio gainAUDIO_GAIN reported − 18 dBAUDIO_GAIN (same offset)
RF qualityDerived from dBm onlyCHAN_QUALITY 0–5 bars

Wireless

digital wireless receiver EM2 · digital wireless receiver EM4 · Dante variants · HTTPS Port 443

Chapter 5Wireless Protocol — HTTPS + Server-Sent Events

SSC v2 Connection Sequence

// Step 1: Confirm SSC v2 supported GET https://[ip]/api/ssc/version → {"version":"2.3.0"} // Step 2: Get device identity GET https://[ip]/api/device/identity → {"name":"digital wireless receiver EM2","channels":2,"firmware":"4.2.1"} // Step 3: Open SSE stream (never closes until ETR-NodeScope disconnects) GET https://[ip]/api/ssc/state/subscriptions → {"uuid":"3f7a-..."} // Step 4: Subscribe to resource paths PUT https://[ip]/api/ssc/state/subscriptions/3f7a-.../add → {"resources":["/api/device/channels/0/audio/level", ...]} // Receiver now streams events whenever values change: data: {"/api/device/channels/0/transmitter/battery/level":{"value":78}} data: {"/api/device/channels/0/rf/level":{"value":-72.5}}

Wireless

receiver · receiver · MPR50 · MPR52 · TCP Port 32789

Chapter 6Wireless Protocol — JSON over TCP

⚠️ Critical

Wireless receivers allow only one TCP controller at a time on port 32789. If Wireless Manager is connected, ETR-NodeScope cannot connect. Disconnect all other tools before starting ETR-NodeScope.

// ETR-NodeScope sends: get_device_info // Receiver responds: {"result":"ok","data":{"product":"receiver","num_channels":2,"firmware":"1.9.3"}} // Receiver then pushes continuously: {"channels":[ {"name":"CH1","frequency":614500000, "rf_a":-68.5,"rf_b":-71.0,"audio":-14.2, "battery":78,"mute":false}, ... ]} // Parsed with System.Text.Json: using var doc = JsonDocument.Parse(json); var arr = doc.RootElement.GetProperty("channels"); foreach (var ch in arr.EnumerateArray()) { s.RfLevelA = ch.GetProperty("rf_a").GetDouble(); s.BatteryPercent = ch.GetProperty("battery").GetInt32(); ChannelDataReceived?.Invoke(chIndex - 1, s); // 1-based → 0-based }
❓

Part IV Quiz

Wireless Protocols — 5 questions, pass mark 60%

Question 1 of 5

A Wireless AD4D-A sends < REP 1 RX_RF_LVL 043 >. What is the actual RF level in dBm, and which device family is this?

Question 2 of 5

ETR-NodeScope receives: < SAMPLE 1 RSSI A 083 > from an digital wireless receiver. What does it do with this message?

Question 3 of 5

What does Wireless's SSE subscription PUT request do and why is it necessary?

Question 4 of 5

Why does Wireless's ChannelDataReceived call use chIndex - 1 when invoking the event?

Question 5 of 5

ETR-NodeScope discovers a Wireless receiver at 169.254.158.222 via multicast and at 169.254.100.134 via TCP fingerprint. It connects to 169.254.100.134. Why?

Part V

Using the Software

Chapter 7Installation, Setup and Live Operation

System Requirements

RequirementDetails
OSWindows 10 64-bit (1903+) or Windows 11
CPU4-core minimum — i5/Ryzen 5. i7/Ryzen 7 recommended for 32+ channels
RAM8 GB minimum, 16 GB recommended
NetworkWired Ethernet. Wi-Fi not recommended for ASIO audio
Dante Virtual SoundcardDVS 4.x licensed and running. No other ASIO app open simultaneously
.NET 8Bundled with the ETR-NodeScope installer

First Launch — Step by Step

1. Launch ETR-NodeScope.exe as Administrator  →  2. File → Settings → Audio → select Dante Virtual Soundcard → Channel Count = 8 → Save  →  3. Press F5  →  4. Watch Live Logs (Ctrl+L) for "Connected to x.x.x.x:2202"

💡 Tip

Use Actions → Demo Mode if you have no hardware. Simulated RF, battery, and audio will populate all tiles so you can explore the interface without a physical show.

Settings Reference

SettingDefaultNotes
ASIO Device—Must be set to Dante Virtual Soundcard
Channel Count8Maximum 64. Add more without restarting
Buffer Size512 samples10.7ms at 48 kHz
WebUI Port8080Browser access: http://[ip]:8080/
Allow Remote ClientsOffTurn on for tablet access
Enable Remote CommandsOffAllows browsers to send Start/Stop/mute
Shared SecretemptyToken for remote command auth in URL
Battery Warning %30Per-talent override in Talent Manager
Battery Critical %15Per-talent override available
RF Warning dBm−85Per-talent override available

Keyboard Shortcuts

ShortcutAction
F5Start monitoring
F6Stop monitoring
Ctrl+,Open Settings
MToggle Mic Check Mode
Ctrl+LOpen Live Logs
Ctrl+SQuick save Show Preset
Enter / SpaceMonitor/unmonitor selected channel
❓

Part V Quiz

Using the Software — 5 questions, pass mark 60%

Question 1 of 5

ETR-NodeScope's tiles are showing "---" for channel name, battery, and frequency after connecting. What is the most likely cause?

Question 2 of 5

A Wireless receiver is not appearing in ETR-NodeScope's Connected Devices panel. You have verified the IP is reachable. What should you check first?

Question 3 of 5

What is the purpose of the Release Readiness check in ETR-NodeScope?

Question 4 of 5

You want a tablet operator to view the WebUI and be able to send mute commands, protected by a password. What settings do you need?

Question 5 of 5

Why does the WebUI audio stream work in Chrome but a student reports no audio in their browser despite the connection indicator being green?

0Correct
0Wrong
0%Score