BILLO Universal
Wireless Audio Hub — Master Plan
Goal: any mic, any version, any phone, any DJ gear →
one stream → BILLO, anywhere in the world.
1. The
honest truth about “any wireless mic” (read this first)
Wireless mics split into two families, and open source can only
receive one of them over the air:
| Family |
Examples |
Can open source receive the RF? |
| Analog UHF/VHF |
Shure ULX/SLX (old), Sennheiser EW100 G1–G3, Audio-Technica
analog |
✅ YES — plain FM → RTL-SDR + gqrx/GNU Radio |
| Digital / encrypted / paired |
Shure Axient/ULX-D/QLX-D, Sennheiser EW-D/Digital 6000/9000, RØDE
Wireless GO/GO II, DJI Mic, Sony DWX |
❌ NO — proprietary + scrambled + paired. No
decoder exists. |
So “receive any mic on its frequency” is only true for
analog. For everything else, the universal trick that
always works is simpler: use the device’s own receiver
and plug its line-out into a mixer/interface. Every audio
device eventually outputs analog line level — that is the true
catch-all.
2. The 4 layers
Layer
1 — The catch-all (any wired device / any mic’s own receiver)
- You already own: audio mixer + Universal
Audio Apollo Twin X (needs a 22µF cap repair).
- Every mic receiver, DJ deck, camera, or mixer feeds
line-level into the interface → computer.
- Recording headless:
~/roadmics/roadmic-record.sh
(already built) or Audacity / Logic.
- Multi-track merge: macOS Aggregate Device (see
~/roadmics/SETUP.md).
Layer
2 — Old phones as wireless mics (the “place phones around the room”
wish)
- VDO.Ninja (open source, WebRTC): each old phone
opens a browser page and becomes a mic feed.
- Streams over WiFi or the internet → into
OBS (or any browser). Ultra-low latency.
- Zero hardware cost. Works with old iPhones and Androids
that still have a browser.
- Alternative: WO Mic (Android → PC virtual mic over
WiFi/USB/BT).
Layer 3 — Old analog
UHF mics, over the air
- RTL-SDR dongle (~$30) + gqrx
(open-source SDR receiver, FM demod) or GNU Radio.
- Covers the old Shure/Sennheiser analog mics. Legal
for your own gear.
Layer 4 — Route to BILLO
- Aggregate everything in OBS (open source).
- Publish as a network stream (Icecast or
WebRTC/RTMP) on a Tailscale
address.
- Any BILLO machine or Billy’s phone taps the stream from anywhere
(Tailscale = the “works anywhere” layer).
- BILLO Gateway = MOTHERSHIP:3000 (Mac Mini,
Houston). Tailscale makes it reachable worldwide.
| Tool |
What it does |
Link |
| VDO.Ninja |
Phones/cameras → OBS via WebRTC (self-hostable) |
https://github.com/teatrolab/vdo |
| gqrx |
SDR receiver GUI, FM demod |
https://gqrx.dk |
| rtl-sdr |
RTL-SDR driver |
https://github.com/osmocom/rtl-sdr |
| GNU Radio |
Custom demod flowgraphs |
https://github.com/gnuradio/gnuradio |
| uhf_recv |
Cheap hardware analog UHF receiver |
https://github.com/vill-jiang/uhf_recv |
| WO Mic |
Android phone → PC virtual mic |
https://wolicheng.com/womic |
| OBS Studio |
Open-source mixer / aggregator / streamer |
https://obsproject.com |
| Icecast |
Open-source streaming audio server |
https://icecast.org |
4. BILLO fleet (from
live tailscale status)
- This Mac (mobile field machine): 100.77.111.113 —
online now.
- Other nodes (mostly offline at check): billys-macbook-pro,
desktop-rs892l2, galaxy-tab-a11-5g, grokbot-box (linux), iphone184
(iOS), laptop-m48f32fq (windows), lordvader (windows).
- Fleet LAN IPs (10.0.0.x / 192.168.12.x) were unreachable — Mac is on
an iPhone hotspot and
--accept-routes is off.
5. Build order
- Phase 0 (now, no hardware): phones as mics via
VDO.Ninja → OBS. ⚠️ OBS is a ~200 MB download — do it on
WiFi, not the metered hotspot you’re on right now.
- Phase 1: repair Apollo Twin X (or use mixer + a USB
interface) → any wired mic/DJ.
- Phase 2: buy RTL-SDR dongle → analog UHF mics over
the air (gqrx).
- Phase 3: Icecast/Tailscale stream → BILLO Gateway
(MOTHERSHIP:3000).
6. Blockers I need cleared (3
things)
- Buy an RTL-SDR dongle (~$30) for Layer 3.
- Repair the Apollo Twin X (22µF cap) or grab a USB
interface for Layer 1.
- Get MOTHERSHIP online (which tailscale node is it?)
so BILLO:3000 can receive the stream.
7. House rules honored
- ✅ Nothing on the Desktop (standing skill
never-save-to-desktop).
- ✅ Everything lives in
~/billo-wireless-audio/ and
~/roadmics/.
8. Progress log (built
+ verified this session)
- ✅
hub.py — list / record /
stream / multi-listener broadcast all tested (test tone AND
real MacBook Pro microphone).
- ✅
phone-mic/server.py — HTTPS self-signed, page +
/push + /status verified.
- ✅
hub.py — multi-device MIXING into one stream (ffmpeg
amix) verified: record test test and
stream test test both produce a single valid output.
- ✅
billo-audio-hub.plist +
install-service.sh — always-on launchd agent;
plutil -lint OK.
- ✅
sdr-mic.sh — analog-UHF receive script (rtl_fm →
ffmpeg), ready when dongle arrives.
- ✅
billo-audio.sh — one-command orchestrator
(start/status/stop) for the whole
rig; verified start → both UP → stop → both DOWN, no stray
processes.
- ✅
hub.py — now also ingests RECORDED FILES as sources:
stream foo.wav (loops) and record a.wav b.wav
(mixes) both verified with no hardware.
- ✅
smoke-test.sh — end-to-end: live tone + phone
(Opus/webm) + SDR (PCM/wav) → ONE valid MP3 stream (3 inputs → amix).
PASS.
- ✅ Universal bus (BlackHole) — PROVEN realtime:
sox -> BlackHole 2ch -> hub -> stream (tone at
mean -6.5 dB, not silence). Helper: route-to-blackhole.sh.
Any audio routed to BlackHole converges into the single hub stream.
- ✅ WebRTC leg —
vdo-ninja-setup.sh (self-host
VDO.Ninja, node/npm/git verified present; install needs WiFi). Bluetooth
honestly documented as the weak/unsupported option.
- ✅ Supabase: project URL found + reachable (DNS resolves,
/rest/v1/ → 401 = live, not paused). Real anon/service-role
keys MISSING (.env files contain stubs). Additive SQL at
supabase/additive.sql (bucket media_assets,
table captures) — shown, not applied.
- 🅿️ PARKED (hardware/network — do NOT block software):
- RTL-SDR dongle → analog UHF mics (
sdr-mic.sh
ready).
- Apollo Twin X repair / USB interface → wired mic + DJ gear.
- MOTHERSHIP online → live stream handoff to BILLO:3000.
- Real-phone capture test + OBS install (wait for WiFi).
9. Fix + finish pass (Oct 17,
2026, late)
- ✅ Always-on service INSTALLED: hub (:8123) + phone-mic (:8200) as
launchd agents, auto-start at login, auto-restart. Verified real
MacBook-mic audio on the service stream (~-21 dB).
- ✅ hub.py: finds Homebrew ffmpeg under launchd’s bare PATH; exits (→
launchd restart) if ffmpeg dies instead of serving silence; exact
device-name match first.
- ✅ phone-mic: new file per Start press; iPhone (mp4/.m4a) vs Android
(.webm) saved correctly.
- ✅ vdo-ninja-setup.sh: was broken (expected npm/node in a static
repo). Now clones official steveseguin/vdo.ninja and serves it over
HTTPS :8443; hosted https://vdo.ninja documented.
- ✅ sdr-mic.sh / route-to-blackhole.sh: clear PARKED /
missing-dependency messages.
- ✅
./billo-audio.sh doctor: status + URLs +
parked-hardware check (RTL-SDR, Apollo, MOTHERSHIP).
- ✅ Supabase project reachable (auth health 200, not paused).
captures table not created yet. additive.sql now also
enables RLS on the new table (else the public key could read/write it).
NOT applied — waiting on Billy’s approval.