A Windows tray client that streams NMS alert audio from monitoring PCs to a FreePBX conference bridge over SIP/RTP, so operators can hear alarms from anywhere on the network.
Network Management Systems (NMS) and monitoring tools play audio alerts on the PCs where they run. If an operator is away from that machine — or if alerts are spread across 20–40 monitoring PCs — alarms can be missed.
LoopcastUA captures the audio output of each monitoring PC and aggregates it into a single conference bridge. Operators listen in from any endpoint and can hear what kind of alarm is sounding in real time.
Identifying which PC is alerting is handled by the batch execution feature: when audio is detected, LoopcastUA runs a configurable script on that PC — for example to send an SNMP trap or a notification that names the source machine. This works even when no operator is present and is the primary mechanism for per-PC identification.
For environments without an upstream NMS, visual identification of the active talker is also possible through optional FreePBX features:
- Conference Pro module (commercial FreePBX add-on) — shows a real-time participant list with a talking indicator in the UCP web interface.
- Asterisk AMI — Asterisk fires
ConfbridgeTalkingevents when a participant's audio crosses the VAD threshold. A custom AMI client can consume these events to build a dashboard or trigger notifications.
[NMS-PC-A] LoopcastUA ─┐
[NMS-PC-B] LoopcastUA ─┤ SIP/RTP (Opus) ┌─────────────────┐
[NMS-PC-C] LoopcastUA ─┼─────────────────▶│ FreePBX │──▶ Operators
... │ │ ConfBridge 8000 │
[NMS-PC-N] LoopcastUA ─┘ └─────────────────┘
│
on alert detected ▼
[SNMP trap / upstream NMS]
Key features:
- Direct capture (default) — uses WASAPI Process Loopback (
ActivateAudioInterfaceAsync) to capture audio at the OS mix stage, completely independent of the master volume slider. Requires Windows 10 20H2 (build 19042) or later. - Rendered capture (fallback) — standard WASAPI loopback via NAudio, for Windows 7 SP1 and later. Audio level follows the master volume.
- Silence detection with hysteresis — fires a configurable script on alert start / alert end
- Opus 48 kHz / 48 kbps encoding for low-latency, low-bandwidth delivery
- Exponential backoff auto-reconnect on disconnect
- System-tray icon shows connection state at a glance (yellow = connecting / green = connected / green+waves = alerting / red = error)
- EN / JA bilingual UI — follows system language automatically, with a manual override in Settings
- MSI installer with silent-install support for GPO mass deployment
| Item | Requirement |
|---|---|
| OS | Windows 10 20H2 (build 19042) or later for Direct capture (default); Windows 7 SP1 or later for Rendered capture |
| Runtime | .NET Framework 4.7.2 or later |
| Audio | WASAPI loopback-capable audio device |
| Network | UDP 5060 (SIP) and UDP 10000+ (RTP) reachable to the FreePBX server |
| Item | Recommended |
|---|---|
| Distribution | FreePBX 17 (Debian 12-based) |
| Asterisk | 22 (LTS) |
| vCPU | 4 |
| RAM | 4 GB |
| NIC | 100 Mbps |
See docs/freepbx-runbook.md for server setup instructions.
| Tool | Where to get it |
|---|---|
| Build Tools for Visual Studio 2022+ | visualstudio.microsoft.com — select the .NET desktop build tools workload |
NuGet CLI (nuget.exe) |
nuget.org/downloads — place in C:\tools\ and add to PATH |
| WiX Toolset v3.14 (MSI only) | github.com/wixtoolset/wix3/releases |
cd client
nuget restore LoopcastUA.sln
msbuild LoopcastUA.sln /p:Configuration=Release "/p:Platform=Any CPU"
# Output: client/LoopcastUA/bin/Release/LoopcastUA.exe# Run after building the EXE
cd installer
powershell -ExecutionPolicy Bypass -File build.ps1 -Version 1.1.0
# Output: installer/bin/Release/LoopcastUA-1.1.0.msiDouble-click LoopcastUA-x.y.z.msi and follow the wizard.
On first launch, the Settings dialog opens automatically. Enter your SIP server details, click Save, and the client starts connecting.
msiexec /i LoopcastUA-1.1.0.msi /qnAfter installation, place a per-machine config file at:
%ProgramData%\LoopcastUA\config.json
Run the new MSI directly — the old version is uninstalled automatically before the new one is installed. config.json is preserved.
You do not need to edit any config files for normal use.
On first launch after installation, the Settings dialog opens automatically. Enter your SIP server details, click Save, and the client connects. You can reopen Settings at any time from the tray icon's right-click menu.
Settings are saved automatically to %ProgramData%\LoopcastUA\config.json.
This section is for administrators who need to pre-deploy config.json via silent install or generate per-machine files via script. A template is available at installer/config.template.json.
Saving via the Settings dialog encrypts the password automatically using DPAPI (Windows Data Protection API).
To encrypt manually from the command line:
"C:\Program Files\LoopcastUA\LoopcastUA.exe" --encrypt-configFor testing/debugging you can store the password in plaintext by adding "passwordPlaintext": true.
For large-scale silent deployments, prepare a per-machine config.json and place it in %ProgramData%\LoopcastUA\ on each PC. A common approach is to generate the files from the same CSV used to bulk-import extensions in FreePBX Bulk Handler.
LoopcastUA detects when a monitoring PC starts or stops producing audio and executes a configurable script at each transition. The primary intended use is forwarding alerts to upstream systems without requiring an operator to be present.
| Event | Config key | Typical use |
|---|---|---|
| Alert starts (silence → audio) | batch.onPlaybackStart |
Send SNMP trap to upstream NMS, trigger ticketing system, notify on-call |
| Alert ends (audio → silence) | batch.onPlaybackStop |
Clear alert state, send resolution trap |
Supports .bat, .cmd, .exe, and .ps1. Use executionTimeoutMs to cap execution time.
Example: sending an SNMP trap on alert start
@echo off
snmptrap -v 2c -c public 192.168.1.10 "" 1.3.6.1.4.1.99999.1 1.3.6.1.4.1.99999.1.1 s "%COMPUTERNAME% audio alert detected"loopcast/
├── client/
│ ├── LoopcastUA.sln
│ └── LoopcastUA/
│ ├── LoopcastUA.csproj
│ ├── config.sample.json
│ └── src/
│ ├── Program.cs # Entry point
│ ├── TrayContext.cs # Tray icon and lifecycle management
│ ├── Forms/
│ │ └── SettingsForm.cs # Settings dialog (code-first WinForms)
│ ├── Audio/
│ │ ├── ILoopbackCapturer.cs # Capturer interface
│ │ ├── LoopbackCapturerFactory.cs # Selects Direct or Rendered based on config
│ │ ├── ProcessLoopbackCapturer.cs # Direct: WASAPI Process Loopback (Win10 20H2+)
│ │ ├── LoopbackCapturer.cs # Rendered: standard WASAPI loopback
│ │ ├── AudioMixer.cs # Stereo → mono downmix
│ │ ├── OpusEncoder.cs # Concentus (pure C# Opus)
│ │ └── SilenceDetector.cs # Hysteresis-based silence detection
│ ├── Sip/
│ │ ├── SipClient.cs # SIPSorcery control and reconnect logic
│ │ └── RtpSender.cs # RTP transmission
│ ├── Config/
│ │ ├── AppConfig.cs # Settings POCO
│ │ ├── ConfigStore.cs # Read/write and ConfigChanged event
│ │ ├── ConfigValidator.cs # Validation
│ │ └── DpapiProtector.cs # Password encryption
│ ├── Batch/
│ │ └── BatchRunner.cs # Script execution with timeout
│ └── Infrastructure/
│ ├── Logger.cs # Rolling file logger
│ ├── BufferPool.cs # byte[] pool
│ └── Strings.cs # i18n strings (EN / JA)
├── installer/
│ ├── Product.wxs # WiX v3 MSI definition
│ ├── build.ps1 # Build script
│ └── config.template.json # Config file template
├── docs/
│ └── freepbx-runbook.md # FreePBX setup guide
└── tools/
└── generate_extensions.py # FreePBX extension CSV generator (planned)
| Library | Version | License | Purpose |
|---|---|---|---|
| SIPSorcery | 10.0.3 | BSD-3-Clause + additional clause (details) | SIP / RTP stack |
| NAudio | 2.3.0 | MIT | WASAPI loopback capture |
| Concentus | 2.2.2 | BSD-3-Clause | Opus encoder (pure C#) |
| Newtonsoft.Json | 13.0.3 | MIT | JSON config read/write |
For dependency licenses and copyright notices, see THIRD_PARTY_NOTICES.md.
{ "sip": { "server": "192.168.11.29", // FreePBX server IP or hostname "port": 5060, "username": "9001", // Extension number "password": "DPAPI:AQAAn...", // DPAPI-encrypted password (plaintext also accepted; see below) "conferenceRoom": "8000", // ConfBridge number "displayName": "NMS-PC-A" }, "audio": { "captureMode": "direct", // "direct" (Process Loopback, Win10 20H2+, volume-independent) | "rendered" (standard WASAPI, Win7+) "opusBitrate": 48000 // bps (8000–128000) }, "silenceDetection": { "thresholdDbfs": -50.0, // Alert detection threshold "enterSilenceMs": 1500, // Silence duration before "alert end" is declared "exitSilenceMs": 300 // Audio duration before "alert start" is declared }, "batch": { "onPlaybackStart": "C:\\scripts\\alert_start.bat", "onPlaybackStop": "C:\\scripts\\alert_stop.bat", "executionTimeoutMs": 5000 } }