Tutorial · Python · ~10 min
How to Turn a Stereo Track into an Immersive Atmos Mix in Python
No matrix upmixing tricks. Separate the sources, mix them into space, render an object-based master — with two mlslabs APIs and one pipeline.
Why this pipeline
Matrix upmixing is fake surround. This isn't.
Traditional stereo-to-surround tools use matrix upmixing: they spread the same two channels around the room and call it immersive. The AI route is different — you separate the actual sources (vocals, drums, bass, guitars), place each one independently in space, and render a 7.1.2 or object-based master. Sources stay where you put them; the mix is genuinely three-dimensional.
Step 1
Split the stereo mix into stems
Submit the stereo file to the Source Separation API. We return clean stems with independent control — the raw material for spatial placement.
import requests
API = "https://api.mlslabs.io/v1"
KEY = "YOUR_API_KEY"
split = requests.post(
API + "/source-separation/jobs",
headers={"X-API-Key": KEY},
json={
"input": "s3://bucket/mix-stereo.wav",
"output": "s3://bucket/stems/",
"stems": ["vocals", "drums", "bass", "guitar"],
},
).json()
split_id = split["job_id"]
print(split_id)Postman: Source Separation → 4. Tutorials → stereo-to-atmos (01 Split stems)
Step 2
Wait for the stems
Jobs run asynchronously. Poll until status == "done" — or register a webhook and skip the loop entirely.
import time
while True:
job = requests.get(
API + "/source-separation/jobs/" + split_id,
headers={"X-API-Key": KEY},
).json()
if job["status"] == "done":
print(job["stems"])
break
if job["status"] == "failed":
raise SystemExit("job failed (credits auto-refunded)")
time.sleep(2)Step 3
Mix the stems into space
Send the separated stems to the AI Mixing API with roles and priorities. The engine balances levels, resolves frequency masking, and renders an object-based spatial master.
mix = requests.post(
API + "/ai-mixing/jobs",
headers={"X-API-Key": KEY},
json={
"stems": [
{"url": job["stems"]["vocals"], "role": "vocals", "priority": 1},
{"url": job["stems"]["drums"], "role": "drums", "priority": 2},
{"url": job["stems"]["bass"], "role": "bass", "priority": 3},
{"url": job["stems"]["guitar"], "role": "guitar", "priority": 4},
],
"preset": "modern_pop",
"output": {"format": "7.1.2", "objects": True},
},
).json()
print(mix["job_id"])Postman: AI Mixing → 4. Tutorials → stereo-to-atmos (02 Mix to spatial)
Step 4
Deliver & verify
Download the ADM BWF master and verify channels with ffprobe. Every stem has its own position; objects carry position metadata for Atmos-style rendering on playback.
# once the AI Mixing job reports "done":
curl -L -o atmos-master.adm <mix_output_url>
# verify channel layout
ffprobe -show_streams atmos-master.adm | grep channel_layout
# => 7.1.2, object-based metadata attached