Version: 0.42
MPX Prime Studio is an FM composite (MPX) generator written in Swift. It takes live audio input or a test tone, applies optional broadcast-style processing, generates stereo FM baseband with pilot and optional RDS, and sends the MPX (plus optional decoded monitor audio) to the sound hardware.
It runs on two platforms:
- macOS — a native SwiftUI application: the MPX Prime Studio encoder plus its companion MPX Prime Meter analyzer, both shipped in one DMG (Core Audio, full GUI).
- Linux — the encoder runs headless from the command line (ALSA output, no GUI), with the embedded REST API + web dashboard as its interface. SIMD-accelerated so the full chain runs in real time on low-power hardware (a fanless Celeron J4105 handles it); shipped as a Debian/Ubuntu package with a systemd service.
The same DSP core drives both: a full broadcast-style processing chain — phase rotator, wideband AGC, 4-band parametric EQ, 3-/5-band multiband compressor, stereo widener, PrimeBass, bass and audio-band clippers, L/R pre-emphasis, pre-encode true-peak limiter, BS.412 power limiting, and an oversampled composite clipper — ahead of a pilot-locked stereo encoder, keeping the pilot and RDS subcarriers out of all peak control (post-clipper injection). The Linux build is bit-for-bit the same processing; only the audio backend and the front end differ.
Intended use and status. MPX Prime Studio is for experimental, hobby, and small-budget broadcast — community / LPFM stations, pirate and SDR-fed exciters, prosumer encoding, and study of FM signal processing. It implements core behavior from EN 50067 / IEC 62106 and common FM-stereo practice, but it is experimental and not certified — no conformity or compliance is promised. Do not rely on it for regulated production broadcast.
The macOS GUI is organised into these sections. The Linux build has no GUI — the web dashboard (see Remote control) mirrors this same layout (Monitoring, per-stage Processing, RDS, Interfaces, Test Tone), so the two front ends feel the same.
Monitoring: live status, transport, interfaces summary, DSP status, RDS snapshotProcessing: Overview, Core, Phase Rotator, AGC, Parametric EQ, Multiband (with optional transient-aware attack + inter-band gain coupling), Expander, MB Limiter, Stereo Widener, PrimeBass, Bass Clipper, DC Clipper, Audio Limiter, Composite Clipper (optional look-ahead peak control and experimental multiband composite clipping on top of the soft-clipper), BS.412, Final StageRDS: status (master enable + live snapshot), identity (PI / PTY / PTYN / ECC + PS banks + runtime flags TP / TA / MS / DI), radiotext (RT / RT+ / Now Playing), long PS, alt. frequencies (AF), schedule (group sequence + clock-time), subcarrier (injection level + frequency + Gaussian shaping)Tools: Test Tone (sine / pink / white, four stereo modes, frequency presets, dBFS level — replaces the audio input live when enabled, ⌘T)Settings: configuration path, interfaces, output mode (MPX composite vs processed audio), audio engine, spectrum options- Separate windows:
Scopes,Spectrum(composite spectrum with FM band captions -- Mono L+R, 19 kHz Pilot, Stereo L-R, 57 kHz RDS, SCA),Levels,Help
The RDS detail tabs are organised per UECP message-class taxonomy
(AF is a peer of PS, RT+ lives under ODA, etc.). Every operationally
toggled RDS setting applies live without restarting the transport —
PI, PTY, PTYN, TP/TA/MS/DI flags, AF list, group sequence, CT
enable, all RT/PS/Long PS text. Only physical-layer settings
(rds_level, Gaussian shaping FIR taps/BW) require a
transport restart since they reconfigure the modulator.
Makes the FM multiplex. Runs as a macOS GUI app or headless on macOS/Linux.
- Real-time MPX generation with 19 kHz pilot and 38 kHz stereo subcarrier
- Premium receiver-side stereo separation at the default config (0.28): 65 dB at 1 kHz, 50.5 dB at 10 kHz, 43.4 dB at 14 kHz, measured by
--verify-receiverthrough the reusableMPXDecoder(matches Optimod 8x00 / Stereotool published numbers) - Optional RDS generation with pilot-locked 57 kHz subcarrier
- Live input source or built-in Test Tone generator (sine / pink / white, mono / L=−R / left-only / right-only modes, frequency presets, −60..0 dBFS level slider, live Enable toggle that replaces the audio input without restarting the engine)
- Optional wideband AGC, HPF, program lowpass, HF trim, PrimeBass, mono bass, stereo widener, and multiband processing (including 0.28 opt-in transient-aware attack + inter-band gain coupling)
- Broadcast-style Final Stage (Broadcast Preset + Final Drive + Composite Deviation + Final-MPX safety limiter with look-ahead) and a separate Audio Limiter tab (pre-encode 4× oversampled stereo-linked true-peak limiter with default-on look-ahead and Dolby HF-subband-aware detector —
US 5,579,404, expired 2013 — for audibly cleaner HF transients and preserved LF punch), feeding the 16× oversampled composite clipper (with optional OS-rate sliding-window-max look-ahead peak control and experimental default-off multiband composite clipping) with live clipper telemetry - Calibrated MPX line output in dBFS for repeatable exciter drive
- TX-path engine toggles on the Core tab: linear-phase FIR encoder lowpass and FIR multiband splitters (latency vs. quality choices, restart-required)
- Composite budget telemetry with pilot/RDS/audio visibility, safety-limiter readout, and a composite budget governor that holds the audio path under the post-injection clamp so pilot/RDS subcarrier amplitude stays constant for sane configs (over-budget flag for impossible configs)
- Broadcast preset picker for AGC/final-stage tuning (
Balanced Music,CHR / Dance,Punchy Music,Speech / Talk) - Italo / disco / dance multiband presets (
5B Italo,3B Italo) with pumped low-band character - Decoded MPX monitor output on a selectable monitor device
- Processed-audio output mode (Settings - Output Mode): emit processed stereo L/R instead of the FM composite, to feed an external stereo coder + RDS encoder on transmitters that only accept L/R / AES3 audio. Runs the full audio chain (no composite clipper / BS.412 / pilot / RDS), with selectable pre-emphasis (apply it here, or stay flat if the coder does); runs at the audio device rate (48 kHz / 24-bit recommended). Composite-only and RDS controls hide while it is active.
- Scopes, spectrum, levels, sticky peaks, and live monitoring views (macOS GUI; mirrored by the web dashboard)
- Remote control — an embedded, default-off REST API + web dashboard for local or remote operation (see below); it is the primary interface on the headless Linux build
- Linux command-line build (experimental): the encoder runs headless with ALSA output, SIMD-accelerated so the full chain fits low-power hardware; shipped as Debian/Ubuntu packages with a systemd service. No GUI, no Meter.
- Config persisted to the INI (
~/Library/Application Support/MPX Prime Studio/MPX Prime Studio.inion macOS;~/.local/share/...or/var/lib/mpxprime/on Linux)
The receive/analyze counterpart, shipped as MPX Prime Meter.app in the same
DMG. Where Studio makes the composite, the Meter measures it: feed it an
MPX composite (a Core Audio input device, or a live station via an in-process
RTL-SDR / SDRplay tuner) and it decodes stereo + full RDS on one dashboard
window. Its deviation, MPX-power, and SM.1268 readings were cross-validated
against a Profline SFP-X measuring receiver (pilot / RDS matched exactly, peak
deviation within the SM.1268 +/-2 kHz tolerance). macOS only, Apple Silicon
(the SDR tuner is arm64) — there is no Linux or Intel Meter.
- Decoded scopes (composite, decoded L, decoded R) and a stereo vectorscope
- MPX spectrum (0-100 kHz) with band captions (Mono L+R, 19 kHz Pilot, Stereo L-R, 57 kHz RDS, 67.65 kHz Direct Band, 92 kHz SCA)
- Measurement-grade deviation + modulation metering to ITU-R SM.1268-5 / BS.412-9: IN / L / R / M / S levels + correlation; pilot / RDS / total (MAX) deviation; MPX power (ITU-R BS.412 uniform sliding 60 s window) with the worst-window MPX MAX; trailing-60 s peak +/- deviation; the OVER 77 kHz SM.1268 exceedance statistic; best stereo separation; SIGNAL (SDR RSSI); and deviation / MPX-power trend graphs
- Full RDS decode: PI / PS / PTY / RT / RT+ / Long PS / CT / AF / group histogram + live BER
- WAV recording: the decoded stereo audio, or the raw MPX composite (24-bit, capture rate), for later re-analysis
- Input: an audio device, or in-process SDR tuning (
Source -> SDR) -- RTL-SDR and SDRplay RSP (auto-preferred when present) are decoded by a linked-in tuner library (no helper process, no Homebrew for end users), just a connected dongle. Frequency, IF bandwidth, gain / auto gain, LNA, antenna, Bias-T, PPM, and RTL AGC all retune live (no restart). Headless terminal modes also exist (./run-meter.sh --device <n>/--stdin)
See the MPX Prime Meter manual for details.
An embedded, default-off REST API + web dashboard ([CONTROL] in the
INI, or the GUI Settings tab) controls the encoder locally or remotely:
transport, live meters, RDS text/TA, sound presets, and every INI setting
with live-apply where the engine supports it. Localhost needs no
authentication; any wider bind requires an API key. See the
user manual.
This is a MPX Prime Studio (encoder) feature only — on both macOS and Linux. The MPX Prime Meter has no REST API or web interface for now; it is operated from its own window (or its headless terminal modes).
MPX Prime Studio drives its main output device in one of two modes, chosen in Settings → Output Mode (restart-required). What you need from your hardware depends on which you use:
- MPX Composite (default) — the finished FM multiplex: mono sum + 38 kHz stereo subcarrier + 19 kHz pilot + optional 57 kHz RDS, for a transmitter / exciter that accepts a composite ("MPX" / "wideband" / baseband) input. Needs a 192 kHz output device so the ~59 kHz upper RDS sideband stays below Nyquist. A 96 kHz device can carry stereo but not RDS.
- Processed Audio — the processed stereo L/R audio only (no pilot / subcarrier / RDS / composite clipper / BS.412), for transmitters that accept only L/R analog or AES3 audio and have their own stereo coder + RDS encoder. 48 kHz / 24-bit is all you need — the high composite sample rates do not apply. Pre-emphasis is selectable (apply it here, or stay flat if the coder does), with an optional final loudness clipper. See the user manual.
A separate, optional Decoded Monitor output (any sample rate) demodulates the internal composite back to L/R for headphone monitoring on a second device — a listening aid, not the on-air signal.
- macOS 15+ (primary platform). An experimental Linux command-line port
of the encoder (headless
--noguiinto an ALSA device, verifier, benchmark; no GUI, no Meter) builds from the same source tree -- see docs/BUILDING.md. - Platform support tiers: Apple Silicon (arm64) is Tier 1 — the primary, fully-supported target. Intel (x86_64) is Tier 2, best-effort — the universal binary runs and the audio chain is identical, but performance tuning (e.g. the GUI refresh profile) targets Apple Silicon first; Intel gets lighter-weight fallbacks where they help but is not the optimization priority.
- Xcode command line tools / Swift 6 toolchain (only needed for building from source — download the DMG below if you just want to run it)
- Audio output device — depends on the output mode (see above):
- MPX Composite with RDS: an external USB / Thunderbolt interface that runs 192 kHz natively. Built-in Mac audio tops out at 96 kHz, which cannot carry the 57 kHz RDS subcarrier; 96 kHz can do stereo-without-RDS.
- Processed Audio (feeding an external coder): 48 kHz / 24-bit is sufficient — built-in audio or any interface works.
- The output device's format in Audio MIDI Setup must match the configured
sample_rate, or Core Audio's implicit resampling starves the render thread. - Input devices may run at any rate; the app converts internally.
Pre-built universal binaries (Apple Silicon + Intel) ship as macOS .dmg files on the project's GitHub Releases page:
github.com/bkram/MPXPrime/releases
Each release is built and signed by GitHub Actions from the matching tag. Pick the latest version, download MPX_Prime-<version>.dmg, and drag the apps into /Applications (or any folder you prefer). The DMG contains two apps: MPX Prime Studio (the encoder) and MPX Prime Meter (the companion analyzer, below) — install whichever you need.
Linux (encoder only): the same releases attach Debian/Ubuntu packages
mpxprime_<version>-ubuntu24.04_amd64.deb and ...-ubuntu26.04_amd64.deb.
Install with sudo dpkg -i mpxprime_*.deb (or sudo apt install ./mpxprime_*.deb
to pull dependencies); it provides the headless encoder as a mpxprime
systemd service with the web dashboard. This is the CLI encoder only — no GUI,
no Meter. See docs/BUILDING.md for setup.
MPX Prime Studio is ad-hoc signed, not Apple-notarized. The DMG is built and signed by an automated GitHub Actions workflow with a self-managed signing identity — it is not enrolled in the Apple Developer Notary Service. As a result, macOS Gatekeeper will refuse to open the app on first launch with a message similar to:
"MPX Prime Studio" cannot be opened because Apple cannot check it for malicious software.
This is the standard macOS warning for any app distributed outside the Mac App Store / Apple Notarization. To approve the app once:
- Open System Settings → Privacy & Security.
- Scroll to the Security section near the bottom. You will see a message like "MPX Prime Studio was blocked from use because it is not from an identified developer".
- Click Open Anyway next to that message.
- The next time you launch MPX Prime Studio, macOS will prompt one more time — click Open.
After the first approval, MPX Prime Studio launches normally on subsequent runs. This is a one-time per-version operation; updating to a new release will trigger the prompt again on first launch.
If you would rather skip the Gatekeeper dialog entirely, build from source (see docs/BUILDING.md) — locally built binaries are not subject to the same check.
- docs/manual.md — MPX Prime Studio manual: usage, first-time setup, configuration, RDS text, monitoring windows, verification, and the RDS PI/ECC + PTY reference tables
- docs/manual-meter.md — MPX Prime Meter manual: SDR/audio input, the measurement readouts, WAV recording, and calibration
- docs/BUILDING.md — build, run, verify, test, and package from source
- docs/ARCHITECTURE.md — detailed DSP chain and stage descriptions
AGENTS.md— contributor / agent workflow guidance and release checklistplan.md— roadmapCHANGELOG.md— version history
- Standards PDFs and notes live in
documents/(EN 50067 / IEC 62106-2 / IEC 62106-6 / UECP SPB 490 / ITU-R BS.450)
The block-level RDS bit encoder in BasicRDSCoder — CRC (0x5B9), offset words, and the four-block group assembly shared by groups 0/2/3A/4A/10A/11A/15A — was initially ported from the Python RDSHelper in ryanginn/rds-master. Everything around it is MPX Prime Studio's own work: the 1187.5 bit/s biphase + Gaussian shaping FIR, the pilot-locked 57 kHz subcarrier generation, the audio-thread real-time pipeline (pre-allocated bit buffer, atomic CT cache, monotonic-clock timing), the RDSRuntimeConfig live-apply path, AF Method B, RT+ ODA (AID 0x4BD7), Group 4A clock-time with MJD + TZ, Group 10A PTYN, Group 15A Long PS, Group 1A ECC/LIC, the Stereotool-compatible text grammar, and the full FM composite chain that the encoder feeds into.
MPX Prime Studio is an independent open-source project and is not affiliated with, endorsed by, or sponsored by any of the companies named in this documentation. Product and company names — including Orban, Optimod, Omnia, Stereo Tool / Stereotool, Aphex, Waves, and others — are trademarks of their respective owners and are used here descriptively only, to identify published behavior, prior art, and platform APIs for comparison.
GPL-3.0. See LICENSE.