Mix and master stems
doseedo_mixMIXING and MASTERING: mix the stems instead of summing them: each part levelled for how loud it plays, panned, high-passed, given its depth on a shared reverb, and mastered to a loudness target — returned as a WAV AND as mixgraph, the mix as a document you edit. After doseedo_render_score pass from_job (its parts and the instruments they play are the stems); or stems: [{name, audio_url, instrument?}] (result links work as-is). An orchestra (strings / winds / brass / timpani / harp…) is SEATED by default (film-orchestral: violins left, low strings right, winds centre, brass behind, each seat with its own depth in a 2.3 s hall, written dynamics riding the faders; room / dynamics_ride change that); other stems get the blind default. style: film-orchestral, film-scoring-stage, concert-hall, film-epic-hybrid, cathedral-choral, classical-chamber, cartoon-studio, golden-age-cartoon, jazz-combo, ambient, country-pop, metal-modern, 1950s-mono, 1960s-lcr-pop, 1970s-analog-rock, 1970s-dub, 1980s-pop-gated, 1990s-rock-dry, 1990s-hiphop, 2000s-loudness-rock, 2010s-edm, 2010s-trap, 2020s-pop, 2020s-hyperpop — an id or words ("dry 90s rock"). balance {part: dB} moves parts on top of the levelling (+3 brings a melody forward). Change the mix: edit the returned mixgraph — strips[] {stem, gain_db, pan, seat, chain, sends}, buses[] (verb = the hall), master.chain, automation [{target: "strips..gain_db", points: [[seconds, dB]…]}] for rides — and call again with mixgraph + the same from_job / stems — or mix_job (this job_id) + only your edits: rendered as written (safety rails apply, reported), no credits. report.strips..active_lufs = how loud each part plays in the mix. Then doseedo_session_from_stems {from_job, mix_job: } → the DAW project at this mix's levels and pans. Async: job_id → doseedo_wait_task (~15–90 s). Cancel: the plane has no stop for a running mix — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| room | No | An orchestra's room: "studio" (intimate scoring stage, ~1.2 s, close), "stage" (~1.8 s), "hall" (the default scoring hall, ~2.3 s), "cathedral" (~4 s, wet) — or 0..1 between them. Sets the decay, size and how wet every seat sits. | |
| stems | No | [{name, audio_url, instrument?}] — the stems (≤ 32). instrument = the sound it plays (a doseedo_instruments id: "violin", "timpani", "harp"), which decides how it is mixed; without it the name decides. | |
| style | No | A mix style: an id or words ("dry 90s rock"). Pick it for the picture — the default (film-orchestral, a 2.3 s scoring hall) suits film drama, not every orchestra: cartoon-studio = a cartoon / animation orchestra (a close, dry, wide scoring stage, punchy rides); golden-age-cartoon = a 1940s–50s cartoon (mono, small studio, tape); film-scoring-stage = intimate TV / documentary; concert-hall; film-epic-hybrid = trailer / action; cathedral-choral; classical-chamber; or jazz-combo, ambient, 1970s-analog-rock, 2020s-pop … | |
| balance | No | {part name: dB in -12..12} — your balance on top of the levelling (and of the written dynamics a from_job reads). | |
| mix_job | No | MCP: a doseedo_mix job_id to edit — its whole stored mix (every ride) is the base, mixgraph is applied on top, and its stems are reused when you pass no from_job / stems. | |
| vintage | No | A period medium over any style, after the mix: "tape" = 7.5 ips tape (saturation, wow and flutter, a low hiss); "shellac" = a 78 played back (mono, ~90 Hz–5.5 kHz with the reproducer's presence, a 1.3 Hz wow, surface noise that swishes once a turn, crackle). "none" takes a style's own medium off (golden-age-cartoon carries tape). Its node (master.chain type vintage: noise_db, crackle, hi_hz …) is editable in the returned mixgraph. | |
| dynamics | No | Fader rides from written dynamics: {part name: [[onset_seconds, velocity 0-127], …]}. from_job fills it from the score (pp to ff ≈ 17 dB); pass {} for no rides. | |
| from_job | No | MCP: a doseedo_render_score job_id — its parts are the stems, each with the instrument it plays, and each part's written dynamics (its mean velocity) set its balance. | |
| mixgraph | No | An edited mix — the mixgraph a doseedo_mix returned, changed — rendered against the same stems (from_job or stems). With mix_job: ONLY what you change (strips[] by stem, automation[] rides by target — points: [] removes one, buses[] by id, master) — the rest is that mix as stored. A mixgraph marked `partial` (its rides summarized) is refused without mix_job. Omit for a fresh mix. | |
| target_lufs | No | Master loudness, -24..-6 LUFS (default: the style's — -18 for film-orchestral, -14 for the blind default). | |
| tonal_match | No | Nudge the master toward professionally mixed orchestral references (default on for the orchestral styles). Its presence and air are judged only where the score is written loud (written_level), so a pp passage keeps its darkness. | |
| dynamics_ride | No | How hard the written dynamics move the faders: 1 = default (pp to ff ≈ 17 dB), 0 = no rides, up to 1.5. | |
| written_level | No | [[seconds, velocity], …] — the whole score's written level, the loudest part sounding, held until the next row (0 = nothing plays). The tonal match reads only the passages it writes loud (f and louder), so a pp passage keeps its darkness. from_job fills it. | |
| idempotency_key | No | Optional. Any unique string for THIS request (e.g. a UUID). Re-sending the same call with the same key after a timeout returns the same job instead of starting a second one. | |
| dynamics_carried | No | {part name: top velocity} — parts whose stems already play their written level (a render part's dynamics_level receipt, up to its top_vel). Their rides count it: no doubled swing. from_job fills it. |