Skip to main content
Glama

Doseedo: Film Scoring, AI Instruments, Sound Effects & Stems

Render MIDI on AI instruments (MIDI to audio)

doseedo_render_midi

MIDI to audio, a virtual instrument: plays a part you wrote. An AI instrument model (orchestral strings, brass, woodwinds, piano, guitar, bass, drums, World) performs your exact notes, in your key, at your bpm, and returns audio takes. Input ONE of: notes[] ({pitch, start_beats, duration_beats, velocity} — beats from bar 1), midi_url (a .mid ≤2 MiB: a doseedo result link or a public https URL), or session_id + track_id (that track's notes, read from the session). Required: instrument (an entry's call from doseedo_instruments, no key — stay inside its range) and bpm. The notes are sent AS GIVEN — no pitch snapping, no quantizing. One voice per part: a chord part is rendered one voice per output with voice_split:true (result.voices maps each voice to its files and notes). Takes come back best-first (takes[0] = the scorer's winner). Async: job_id → doseedo_wait_task (~1–3 min). Result: takes[{url, rank, score}] (pre-signed: curl -OJ, no auth header, 24 h), seed, duration, voices?, refine?, chain. A take may miss or change a note — read takes[].check (measured against your notes) or listen; offer the takes, never promise note-perfection. Free harmony check first: doseedo_analyze_midi. DRUMS (GM notes): the drum model (default) PLAYS a kit — the sound of acoustic drums; it can drop a hit (takes[].fit.missing). drum_engine:"oneshot" = a programmed sampler kit for drum_genre (default for "electronic"/"808"), every hit as written — drum machines only; real drums (a kit, boom bap) stay on the model (drop a hit: take again). "synth" = a one-shot patch (synth_role, synth_genre; "performed" = played, less 1-shot); result.oneshots = the samples. SOUND: a preset (timbre_preset), a recording's tone (timbre_audio_url = timbre transfer; a drum kit too: a ride / snare recording), or YOUR OWN instrument (lora_id from doseedo_train_instrument; result.lora.applied). Cancel: a render that has not reached the GPU yet is stopped and its credits refunded; one already rendering finishes on the GPU (its credits are spent), the job ends as canceled and the output is discarded.

Input Schema

NameRequiredDescriptionDefault
bpmNoREQUIRED (or tempo_map). Tempo of the notes (10–400). Written into the MIDI's tempo meta, so start_beats/duration_beats land at exactly this tempo.
nameNoOptional: a name for this job's files, e.g. "rainy-loop-3". Every file it returns downloads as <name>_<part>.<ext> (rainy-loop-3_Celesta.wav, rainy-loop-3_rough-mix.wav; one take: rainy-loop-3.wav), so the user can find them. Give each job its own name (a second take: "rainy-loop-3b"). Default: doseedo-<last 6 characters of the job id>.
seedNoRandom seed (−1 or 0–4294967295). Reuse a result's seed to re-render close to the same take.
tuneNoLight intonation (default true): a held, clearly pitched note the model rendered 15–85 cents off its written pitch is moved toward it, to a small natural residual — attack and vibrato as played, fast notes left. Winds, brass and strings. false = the take exactly as rendered.
notesNoThe part, as note rows in beats from bar 1 (beat 0 = bar 1 beat 1, quarter-note beats at `bpm`). Monophonic for one voice; chords need voice_split:true. Up to 4096 notes.
takesNoHow many takes to render, 1–4 (one GPU batch; no extra credits). Omit to let the server choose best-of-N for the part length.
lyricsNoA SUNG part (instrument "voice" — a solo singer — or "choir"): the words, one syllable per note in time order ("Hold the light a lit-tle lon-ger": hyphens split a word where you want, "_" holds a syllable over the next note; one word such as "Ah" is sung on every note). ≤ 2000 characters. Without it a sung part sings "Ooh". Any other instrument: an error.
promptNoOptional caption override (default: the instrument id), ≤ 16000 characters. Style words help a little; the notes are the control.
refineNoOpt-in post-render correction. "light": attacks re-timed onto the score, exposed wrong pitch classes re-pitched inside the played octave, misfires muted (winds/brass/strings). "shred": play exactly the written line, octave included, mute anything the score never wrote (any pitched mono part). The raw render stays downloadable (result.refine.raw_url).
vaefixNoVAE spectral corrector (default true): trims the low-mid fog the decoder adds under the instrument's register and removes mic hiss only when the take carries it. Winds, brass and strings. Receipt: vaefix. false = the decode exactly as rendered.
lora_idNoA CUSTOM INSTRUMENT: the lora_id doseedo_train_instrument returned (16 hex). The render is played by that trained instrument; pass the same instrument it was trained as. Owner-only.
dynamicsNoOne target dynamic for the whole part's tone: "pp", "p", "mp", "mf", "f", "ff", "fff", a 0–1 number, or a MIDI velocity as text. Omit it to let the notes' velocities shape the tone (dynamics_curve).
midi_urlNoAlternative to notes: https URL of a Standard MIDI File (≤2 MiB) — a doseedo result link (a stem's MIDI) or a public URL. Its own tempo map is used by the model; bpm still tags the caption and sizes the default duration.
track_idNoWith session_id: the t_… id of the MIDI/instrument track to render.
tempo_mapNoTempo CHANGES for the notes: [{beat, bpm}] — each point holds from its beat (beats from bar 1) until the next; the first point is beat 0 (or bpm covers the beats before it). Written into the MIDI, so a ritardando or a tempo that lands a cue on a film hit plays exactly. doseedo_tempo_map builds one from hit times.
drum_genreNoThe drum style. A drum machine (instrument "electronic" or "808"): the genre whose one-shot kit plays the part — "house", "techno", "trap", "drill", "dnb", "amapiano", "synthwave"… or free words. A real-drums style ("boom bap", "lo-fi", "breakbeat", "funk", "rock", "jazz"…) plays on the drum model's drum_kit instead, never a one-shot kit. Default: the instrument.
instrumentYesREQUIRED. The instrument from doseedo_instruments — its `call.instrument` (e.g. "violin", "tenor_sax", "electric_guitar", "piano"; a World name such as "koto" is resolved to its call). Keep the notes inside its range. An unknown name close to a catalog one is refused with did_you_mean before anything is spent.
session_idNoAlternative to notes: with track_id, render THAT session track's notes (read from doseedo_get_session's summary).
synth_roleNoinstrument "synth": the patch Stable Audio Open makes for the part — bass (an 808 where the genre's bass is one), 808, pad, lead, pluck. Default: from the notes (chords = pad, a low line = bass, else lead).
drum_engineNoWho plays a drum part: "model" = the drum model (the default for every kit but electronic / 808): a drummer playing the kit in a room — cymbals ring, hits vary, ghost notes speak; the sound for acoustic drums. It can drop or smear a hit: read takes[].fit and take it again. "oneshot" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins): every note lands exactly as written, but it sounds programmed (one sample per drum, the same on every hit) — for drum-machine genres only. An acoustic kit (drum_kit: rock, punk, jazz, soul, a band seen playing) stays on the model, never oneshot — and so does a real-drums drum_genre on whatever kit, which plays on drum_kit (funk, boom bap, lo-fi, breakbeat: a sampled break is a drummer; its dust comes from the mix, doseedo_mix style "1990s-hiphop" / "lofi-hiphop"; the submit reply says so, prepared.drums). A take that drops a hit is taken again (takes: 3, keep the best). Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81.
synth_genreNoinstrument "synth": the genre the patch is made for — "house", "techno", "trap", "synthwave", "lo-fi", "dnb"… or free words.
synth_wordsNoinstrument "synth": extra sound words for the patch ("reese", "warm analog", "acid"), ≤ 80 characters (a longer one is cut at a word boundary, with a warning).
voice_splitNotrue = the notes hold chords: split them into the voices one player of this instrument can hold and render every voice (result.voices). A SUNG chord (choir, voice) is sung one stem per voice, each in its register, one take each. Default false (a chord in a mono part is an error the model will fudge).
synth_engineNoWho plays a synth part: "oneshot" = a patch of one-shots made for it (the default for "synth"; every note the same sample), "performed" = that same patch (synth_role / synth_genre / synth_words pick it) played by the synth model trained on real synth loops — each note its own, the tone moving, the written notes kept (lora_strength 0.5 default; seed = another performance), "model" = the instrument model alone.
lora_strengthNoWith lora_id (or synth_engine "performed"): how strongly the custom instrument applies, 0–2 (default 1.0, or a tuned per-adapter default; ~0.6 when a small training set overshoots; performed synth 0.5 — up to ~0.75 plays it looser, past that it starts leaving the notes).
timbre_presetNoA preset from doseedo_instruments — an entry's call.timbre_preset or presets[].call.timbre_preset (e.g. "violin:pizz", "sax:alto", "koto:preset1"). Omit for the instrument default.
dynamics_curveNoWhat colours the TONE over time: omitted/"auto" = the note velocities when they vary (soft notes darker, loud brighter — every instrument but drums, LoRAs included); "off" = one colour; "cc11"/"cc1" = that CC lane of a midi_url; or "pos:level,…" (pos and level 0–1, e.g. "0:0.1,1:0.9" = a crescendo). Receipt: result.dynamics.
time_signatureNoMeter of the part, e.g. "4/4", "3/4", "6/8" (default 4/4). Written into the MIDI and the caption.
idempotency_keyNoOptional. 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.
revise_take_urlNoREVISE an earlier take instead of rendering a new one: the take's URL (as a render returned it). Only [revise_start_beats, revise_end_beats) is regenerated — steered by `notes` (send the whole part, with your corrections) — and spliced back with short crossfades; the rest of the take is kept as it was.
duration_secondsNoLength of the render in seconds (0.01–600). Default: the last note's end + 2 s of release. Each 30 s window costs 10 credits.
revise_end_beatsNoWith revise_take_url: end of the region to redo (exclusive), beats from bar 1.
timbre_audio_urlNoTIMBRE TRANSFER: https URL of a short recording (≤24 MB; its first 30 s are used) whose SOUND the render should take on — a doseedo result link or a public URL. The notes stay yours; the tone comes from the recording.
revise_start_beatsNoWith revise_take_url: start of the region to redo, beats from bar 1.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changed
    • changedInput schema / properties / lyrics / description
      Previous value: -"A SUNG part (instrument \"voice\" — a solo singer — or \"choir\"): the words, one syllable per note in time order (\"Hold the light a lit-tle lon-ger\": hyphens split a word where you want, \"_\" holds a syllable over the next note; one word such as \"Ah\" is sung on every note). ≤2000 chars. Without it a sung part sings \"Ooh\". Any other instrument: an error."New value: +"A SUNG part (instrument \"voice\" — a solo singer — or \"choir\"): the words, one syllable per note in time order (\"Hold the light a lit-tle lon-ger\": hyphens split a word where you want, \"_\" holds a syllable over the next note; one word such as \"Ah\" is sung on every note). ≤ 2000 characters. Without it a sung part sings \"Ooh\". Any other instrument: an error."
    • addedInput schema / properties / lyrics / maxLength
      Added value: +2000
    • changedInput schema / properties / prompt / description
      Previous value: -"Optional caption override (default: the instrument id). Style words help a little; the notes are the control."New value: +"Optional caption override (default: the instrument id), ≤ 16000 characters. Style words help a little; the notes are the control."
    • addedInput schema / properties / prompt / maxLength
      Added value: +16000
    • changedInput schema / properties / synth_words / description
      Previous value: -"instrument \"synth\": extra sound words for the patch (\"reese\", \"warm analog\", \"acid\"), ≤80 chars."New value: +"instrument \"synth\": extra sound words for the patch (\"reese\", \"warm analog\", \"acid\"), ≤ 80 characters (a longer one is cut at a word boundary, with a warning)."
    • addedInput schema / properties / synth_words / maxLength
      Added value: +80
  2. Changed2 schema fields changed
    • changedInput schema / properties / drum_engine / description
      Previous value: -"Who plays a drum part: \"model\" = the drum model (the default for every kit but electronic / 808): a drummer playing the kit in a room — cymbals ring, hits vary, ghost notes speak; the sound for acoustic drums. It can drop or smear a hit: read takes[].fit and take it again. \"oneshot\" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins): every note lands exactly as written, but it sounds programmed (one sample per drum, the same on every hit) — for drum-machine genres only. An acoustic kit (drum_kit: rock, punk, jazz, soul, a band seen playing) stays on the model, never oneshot: a take that drops a hit is taken again (takes: 3, keep the best). Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."New value: +"Who plays a drum part: \"model\" = the drum model (the default for every kit but electronic / 808): a drummer playing the kit in a room — cymbals ring, hits vary, ghost notes speak; the sound for acoustic drums. It can drop or smear a hit: read takes[].fit and take it again. \"oneshot\" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins): every note lands exactly as written, but it sounds programmed (one sample per drum, the same on every hit) — for drum-machine genres only. An acoustic kit (drum_kit: rock, punk, jazz, soul, a band seen playing) stays on the model, never oneshot — and so does a real-drums drum_genre on whatever kit, which plays on drum_kit (funk, boom bap, lo-fi, breakbeat: a sampled break is a drummer; its dust comes from the mix, doseedo_mix style \"1990s-hiphop\" / \"lofi-hiphop\"; the submit reply says so, prepared.drums). A take that drops a hit is taken again (takes: 3, keep the best). Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."
    • changedInput schema / properties / drum_genre / description
      Previous value: -"Electronic drums (instrument \"electronic\" or \"808\"): the genre whose one-shot kit plays the part — \"house\", \"techno\", \"trap\", \"drill\", \"lo-fi\", \"dnb\", \"amapiano\", \"synthwave\"… or free words. Default: the instrument."New value: +"The drum style. A drum machine (instrument \"electronic\" or \"808\"): the genre whose one-shot kit plays the part — \"house\", \"techno\", \"trap\", \"drill\", \"dnb\", \"amapiano\", \"synthwave\"… or free words. A real-drums style (\"boom bap\", \"lo-fi\", \"breakbeat\", \"funk\", \"rock\", \"jazz\"…) plays on the drum model's drum_kit instead, never a one-shot kit. Default: the instrument."
  3. Changed1 schema field changed
    • changedInput schema / properties / drum_engine / description
      Previous value: -"Who plays a drum part: \"model\" = the drum model (the default for every kit but electronic / 808): a drummer playing the kit in a room — cymbals ring, hits vary, ghost notes speak; the sound for acoustic drums. It can drop or smear a hit: read takes[].fit and take it again. \"oneshot\" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins): every note lands exactly as written, but it sounds programmed (one sample per drum, the same on every hit) — for drum-machine genres, or the fallback when an acoustic part's takes keep losing a hit that must land. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."New value: +"Who plays a drum part: \"model\" = the drum model (the default for every kit but electronic / 808): a drummer playing the kit in a room — cymbals ring, hits vary, ghost notes speak; the sound for acoustic drums. It can drop or smear a hit: read takes[].fit and take it again. \"oneshot\" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins): every note lands exactly as written, but it sounds programmed (one sample per drum, the same on every hit) — for drum-machine genres only. An acoustic kit (drum_kit: rock, punk, jazz, soul, a band seen playing) stays on the model, never oneshot: a take that drops a hit is taken again (takes: 3, keep the best). Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."
  4. Changed1 schema field changed
    • changedInput schema / properties / drum_engine / description
      Previous value: -"Who plays a drum part: \"oneshot\" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins) — every note lands exactly as written; use it on ANY kit when every hit must land. \"model\" = the drum model (the default for every other kit): a performance, which can drop or smear hits — read takes[].fit. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."New value: +"Who plays a drum part: \"model\" = the drum model (the default for every kit but electronic / 808): a drummer playing the kit in a room — cymbals ring, hits vary, ghost notes speak; the sound for acoustic drums. It can drop or smear a hit: read takes[].fit and take it again. \"oneshot\" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins): every note lands exactly as written, but it sounds programmed (one sample per drum, the same on every hit) — for drum-machine genres, or the fallback when an acoustic part's takes keep losing a hit that must land. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."
  5. Changed1 schema field changed
    • changedInput schema / properties / voice_split / description
      Previous value: -"true = the notes hold chords: split them into the voices one player of this instrument can hold and render every voice (result.voices). Default false (a chord in a mono part is an error the model will fudge)."New value: +"true = the notes hold chords: split them into the voices one player of this instrument can hold and render every voice (result.voices). A SUNG chord (choir, voice) is sung one stem per voice, each in its register, one take each. Default false (a chord in a mono part is an error the model will fudge)."
  6. Changed1 schema field changed
    • addedInput schema / properties / lyrics
      Added value: +{
      +  "description": "A SUNG part (instrument \"voice\" — a solo singer — or \"choir\"): the words, one syllable per note in time order (\"Hold the light a lit-tle lon-ger\": hyphens split a word where you want, \"_\" holds a syllable over the next note; one word such as \"Ah\" is sung on every note). ≤2000 chars. Without it a sung part sings \"Ooh\". Any other instrument: an error.",
      +  "type": "string"
      +}
  7. Changed1 schema field changed
    • addedInput schema / properties / name
      Added value: +{
      +  "description": "Optional: a name for this job's files, e.g. \"rainy-loop-3\". Every file it returns downloads as <name>_<part>.<ext> (rainy-loop-3_Celesta.wav, rainy-loop-3_rough-mix.wav; one take: rainy-loop-3.wav), so the user can find them. Give each job its own name (a second take: \"rainy-loop-3b\"). Default: doseedo-<last 6 characters of the job id>.",
      +  "maxLength": 80,
      +  "type": "string"
      +}
  8. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations, it discloses async timing (~1–3 min), takes returned best-first, pre-signed 24-hour URLs, note-fidelity caveats, credit refund behavior on cancellation, and detailed drum/synth engine outcomes. These details are substantive and do not contradict the supplied readOnly/openWorld/idempotent/destructive hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and core input modes are front-loaded, but the description is very dense and repeats schema-level material such as the GM drum pad mapping and note object fields. It is comprehensive and structured, yet portions could be trimmed or left to the schema descriptions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must carry return behavior; it does so by explaining job_id, doseedo_wait_task, takes with rank/score, pre-signed URLs, seed, duration, voices, refine, chain, and cancellation outcomes. That is complete for a complex 34-parameter render tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the schema already defines each parameter. The description still adds meaningful cross-parameter routing: input must be exactly one of notes[], midi_url, or session_id + track_id, and notes are sent as given with no pitch snapping or quantizing. Most per-parameter detail is rightly left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names the exact transformation (MIDI to audio) and the resource (an AI virtual instrument playing a written part). It clearly distinguishes this from doseedo_analyze_midi, doseedo_instruments, doseedo_wait_task, and doseedo_train_instrument by assigning each sibling its role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit routing: run doseedo_analyze_midi first for a free harmony check, use doseedo_wait_task for async jobs, pull instrument ids from doseedo_instruments, and use doseedo_train_instrument for custom lora_id. It also explains when to choose drum_engine "oneshot" versus "model" and synth_engine "oneshot"/"performed"/"model" based on genre and acoustic versus electronic context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources