Spatial Audio Upmixer is a Python library and command-line tool for converting mono, stereo, and existing surround audio into higher-channel-count spatial beds. It combines content-aware spatial processing, optional neural source separation, and a shared mastering chain to produce standard multichannel WAV or ADM-BWF files.
The installable package, Python namespace, and command remain upmixer.
- Upmix mono, stereo, 5.0, 5.1, 7.1, 5.1.2, 5.1.4, and 7.1.2 sources.
- Produce 5.1, 7.1, 5.1.2, 5.1.4, 7.1.2, or 7.1.4 channel beds.
- Choose a fast coherence-based STFT pipeline or an instrument-aware stem pipeline.
- Adapt width, ambience, transients, and height routing with automatic or explicit spatial profiles.
- Preserve the intent of multichannel sources through zone-aware routing and optional source anchoring.
- Apply reference matching, spectral EQ, bus compression, bass control, BS.1770 loudness normalization, and true-peak control through one mastering chain.
- Write standard WAV, ADM-BWF metadata, and an optional ITU-R BS.775 stereo downmix.
- Run reproducible YAML/JSON manifests and safe batch jobs with preflight checks, atomic writes, resume state, and JSON reports.
- Python 3.11 or later
- WAV or FLAC input readable by libsndfile
- Additional CPU or GPU dependencies for stem separation
Install the core package for realtime processing:
python3 -m pip install upmixerInstall stem separation support for CPU or GPU inference:
python3 -m pip install "upmixer[separation-cpu]"
python3 -m pip install "upmixer[separation-gpu]"YAML manifests require PyYAML. JSON manifests work with the core installation.
python3 -m pip install "upmixer[manifest]"For local development:
git clone https://github.com/coderynx/audio-upmixer.git
cd audio-upmixer
python3 -m pip install -e ".[dev]"Create a 5.1 WAV from a stereo source:
upmixer input.wav output.wav --format 5.1Create a 7.1.4 bed with stem separation:
upmixer input.flac output.wav --mode stem --format 7.1.4Preview a short section before processing the complete file:
upmixer input.wav preview.wav --format 7.1.4 --preview --preview-duration 30Run a reproducible manifest:
upmixer --manifest examples/atmos_music.yamlExisting outputs are protected by default. Use --overwrite only when replacement is intentional, or --resume with
saved run state to skip outputs whose input and settings still match.
| Mode | Best for | How it works | Additional dependency |
|---|---|---|---|
realtime |
Fast previews, general files, and parallel batches | Coherence analysis separates correlated direct sound from diffuse ambience, then derives center, surround, back, height, and LFE content | None |
stem |
Music, complex mixes, and deliberate instrument placement | Separates requested sources, analyzes each stem, routes it spatially, blends native source zones when requested, and masters the result | audio-separator extra |
Realtime mode treats mono as a centered stereo pair. For multichannel input it preserves existing channels and derives only the channels needed by the target layout.
Stem mode separates every available stereo zone—front, surround, back, and height—rather than collapsing a multichannel source to stereo. Center and LFE material are retained as passthrough channels where applicable.
Use --spatial-profile auto to select a profile from the source, or choose one explicitly:
balanced, intimate, rhythmic, spacious, live, or detailed.
--spatial-intensity controls how strongly the selected profile changes the base routing. Set
--no-spatial-preanalysis when offline content analysis is not wanted.
Stem mode selects and orders separation models automatically from the requested outputs. The default set is vocals,
bass, drums, guitar, piano, and other.
Additional requested stems activate specialized stages:
crowdisolates audience content before primary instrument separation.kick,snare,toms,hi-hat,ride, andcrashsubdivide the isolated drums stem.backing-vocalsrefines the lead vocal stem and extracts backing vocals.
For example:
upmixer live.wav live_714.wav --mode stem --format 7.1.4 \
--stems vocals,backing-vocals,bass,kick,snare,toms,crowdModel files are cached under ~/.cache/upmixer-models by default. --stem-cache-dir separately caches generated stems
for repeat runs. Stem silence skipping is enabled by default, and inference batch size is selected from the available
CPU, CUDA, MPS, or CoreML resources unless --stem-batch-size is supplied.
Stem separation is provided through python-audio-separator by nomadkaraoke, using supported Demucs, MDX, and RoFormer-family models.
Spatial Audio Upmixer only adds channels: the selected output must be a strict superset of the detected input layout.
| Layout | Channels |
|---|---|
| Mono | 1 |
| Stereo | 2 |
| 5.0 | 5 |
| 5.1 | 6 |
| 7.1 | 8 |
| 5.1.2 | 8 |
| 5.1.4 | 10 |
| 7.1.2 | 10 |
Eight- and ten-channel files are ambiguous from channel count alone. Use --input-format to distinguish 7.1 from
5.1.2, or 5.1.4 from 7.1.2.
upmixer surround.wav output.wav --input-format 5.1.2 --format 7.1.4| Layout | Channels | Height channels |
|---|---|---|
| 5.1 | 6 | 0 |
| 7.1 | 8 | 0 |
| 5.1.2 | 8 | 2 |
| 5.1.4 | 10 | 4 |
| 7.1.2 | 10 | 2 |
| 7.1.4 | 12 | 4 |
Write a standard multichannel WAV and a stereo compatibility downmix:
upmixer input.wav output_714.wav --format 7.1.4 \
--downmix-output output_stereo.wavWrite a 24-bit, 48 kHz ADM-BWF bed for downstream authoring:
upmixer input.flac authoring_bed.wav --mode stem --format 7.1.4 \
--output-type adm-bwf --output-subtype PCM_24 --output-sample-rate 48000Inspect a job without writing audio:
upmixer input.wav output.wav --format 7.1.4 --dry-runEmit a machine-readable result or run report:
upmixer input.wav output.wav --format 7.1.4 --json
upmixer input.wav output.wav --format 7.1.4 --report run-report.jsonUse upmixer --help for every CLI option and upmixer --manifest-keys for manifest-configurable fields.
YAML and JSON manifests describe one or more assets with shared settings and optional per-asset overrides. A manifest
version must use MAJOR.MINOR or MAJOR.MINOR.PATCH syntax.
version: "1.0"
metadata:
name: "Album spatial masters"
author: "Example Engineer"
engine:
mode: stem
stems: [vocals, bass, drums, guitar, piano, other]
stem_cache_dir: /tmp/upmixer-stems
stem_silence_skip: true
mixing:
channel_layout: 7.1.4
stem_source_anchor_strength: 0.5
spatial:
profile: auto
intensity: 1.0
preanalyze: true
format:
type: adm-bwf
subtype: PCM_24
sample_rate: 48000
mastering:
eq:
profile: spatial-present
strength: 0.7
compressor:
profile: transparent
loudness:
normalize: true
target: -18.0
max_tp: -1.0
assets:
- input: tracks/01_intro.flac
output: masters/01_intro.wav
- input: tracks/02_single.flac
output: masters/02_single.wav
mixing:
stem_rebalance:
Vocals: 1.0Global engine, mixing, routing, format, mastering, and processing blocks apply to every asset. Per-asset
configuration blocks are deep-merged, so an override changes only the specified keys. Keep engine.mode consistent
across a manifest batch because one pipeline type is reused for the complete run.
Configuration precedence is:
CLI flags > per-asset manifest values > global manifest values > UpmixConfig defaults
| Manifest | Demonstrates |
|---|---|
stereo_to_51.yaml |
Fast stereo-to-5.1 realtime processing |
stem_714.yaml |
Full 7.1.4 stem workflow, source anchoring, and optional stem shaping |
stem_hierarchical.yaml |
Automatic crowd, primary, drum, and backing-vocal stages |
atmos_music.yaml |
YAML ADM-BWF music-authoring bed |
atmos_music.json |
Equivalent JSON ADM-BWF example |
batch_album_stem.yaml |
Explicit album jobs with shared stem settings |
batch_dir_stem.yaml |
Directory expansion and per-directory overrides |
batch_explicit_jobs.yaml |
Per-track deep-merged overrides |
batch_files_realtime.yaml |
Realtime batch from unrelated source paths |
Process a directory recursively after reviewing its resolved jobs:
upmixer --batch-dir /albums/project --output-dir /masters/project \
--recursive --output-template '{relative_stem}.wav' --format 7.1.4 --dry-runRun it and write resumable state plus a portable report:
upmixer --batch-dir /albums/project --output-dir /masters/project \
--recursive --output-template '{relative_stem}.wav' --format 7.1.4 \
--resume --report project-report.jsonUse --inputs for files from unrelated directories. Realtime batches may use --batch-workers; stem batches remain
sequential so loaded separator models can be reused. CLI stem batches created with --inputs or --batch-dir
automatically use a shared cache unless a cache directory is configured explicitly; manifest examples set their cache
directory in engine.
Both pipelines feed the same mastering chain:
- Optional spectral and RMS reference matching.
- Optional preset spectral EQ.
- Optional multichannel bus compression.
- Optional bass control and LFE trim.
- Soft peak limiting.
- ITU-R BS.1770 integrated loudness normalization and true-peak ceiling enforcement.
Loudness results, applied gain, selected spatial profile, stem names, and processing time are returned in
UpmixResult and are available from --json.
Standard WAV output supports PCM_16, PCM_24, and PCM_32. The source sample rate is retained unless
--output-sample-rate is set.
ADM-BWF output contains the PCM bed plus BWF, ADM XML, CHNA, and DBMD chunks for downstream DAW or encoding workflows. It requires:
- A
.wavoutput path. PCM_24audio.- A 48 kHz or 96 kHz output sample rate; 48 kHz is selected when no rate is specified.
- One of the supported 5.1 through 7.1.4 output layouts.
The generated file is a channel-based authoring bed, not a Dolby codec bitstream. Delivery requirements vary by platform and workflow; validate metadata, loudness, channel order, and downstream encoding in the target toolchain.
Realtime/file pipeline:
from upmixer import UpmixConfig, UpmixPipeline
config = UpmixConfig(
output_format="7.1.4",
spatial_profile="auto",
loudness_target_lkfs=-18.0,
)
result = UpmixPipeline(config).process_file("stereo.wav", "spatial.wav")
print(result.to_json())Stem pipeline with automatic model planning and deterministic cleanup:
from upmixer import UpmixConfig
from upmixer.separation.stem_pipeline import StemUpmixPipeline
config = UpmixConfig(
output_format="7.1.4",
stems=["vocals", "bass", "drums", "guitar", "piano", "other"],
stem_cache_dir="/tmp/upmixer-stems",
)
with StemUpmixPipeline(config) as pipeline:
result = pipeline.process_file("stereo.wav", "spatial.wav")
print(result.stems)Both process_file methods accept input_format_override and a progress_callback(message, fraction) callable.
The primary public imports are:
from upmixer import (
FORMAT_MAP,
INPUT_FORMAT_MAP,
StreamingProcessor,
UpmixConfig,
UpmixPipeline,
UpmixResult,
)Install development dependencies and run the complete suite:
python3 -m pip install -e ".[dev]"
python3 -m pytest -qPerformance and real-model checks are opt-in:
python3 -m pytest -m perf -sBuild distributions when the build package is installed:
python3 -m build- python-audio-separator by nomadkaraoke — external source separation library used by stem mode.
- ITU-R BS.1770 — audio programme loudness and true-peak measurement.
- ITU-R BS.2076 — Audio Definition Model.
- ITU-R BS.775 and ITU-R BS.2051 — multichannel and advanced sound-system layouts.
Dolby and Dolby Atmos are registered trademarks of Dolby Laboratories Licensing Corporation. This software is an independent open-source project. It is not affiliated with, sponsored by, authorized by, certified by, or otherwise endorsed by Dolby Laboratories. All references to Dolby Atmos and related specifications are used solely in a descriptive, nominative sense to indicate technical compatibility with publicly available industry standards.