MCP reference
Every tool an agent can call, what it takes, and whether it changes your project.
Every call that changes the project is exactly one undo step.
Protocol: 2025-06-18
Reading
project_describe
Summarise the open project: tempo, meter, and every channel, pattern, playlist track, mixer insert and automation by name and id.read
Start here. It returns counts and names, and not one note, clip or automation point, so it costs a few hundred tokens whatever the size of the arrangement.
Use the ids it returns to address everything else. Reach for project_read only when you need the contents of something this named.
Takes no arguments.
project_read
Read the whole project document, or one top-level member of it, exactly as a .dew file stores it.read
The document through the same schema that reads and writes the file, so what you get back is what is on disk rather than a summary of it.
This is large: a real arrangement is tens of thousands of tokens of notes. Pass member to take one part - 'channels', 'patterns', 'playlist', 'mixer' - and prefer project_describe when you only need to know what exists.
| Argument | Type | Notes |
|---|---|---|
| member | text | One top-level member to return instead of the whole document. |
params_list
List every parameter at one address, with its range, its default, whether it can be automated, and what it holds now.read
How to find out what is writable before writing it. An address is a target (project, channel, mixerTrack, master), an id, a group and a slot - the same five fields every parameter operation takes.
Leave group off for the target's own parameters. Set it to 'oscillators', 'amp', 'sample' or 'soundfont' for part of a channel's instrument, or to 'effects' with a slot for one effect. What a channel offers depends on what kind of instrument it carries, which project_describe reports as its source.
| Argument | Type | Notes |
|---|---|---|
| target | text | requiredproject, channel, mixerTrack or master. |
| id | integer | The channel id or mixer track id. Unread by project and master. |
| group | text | oscillators, amp, sample, soundfont or effects. Omit for the target's own parameters. |
| slot | integer | Which oscillator or which effect slot, counting from 0. |
| param | text | requiredThe parameter's name, as params_list gives it. |
params_read
Read the current value of any number of parameters.read
Takes a list of addresses and answers with a value for each. An address that names nothing comes back with found=false rather than failing the batch, so one stale id does not cost you the other forty answers.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe addresses to read. |
| entries[].target | text | requiredproject, channel, mixerTrack or master. |
| entries[].id | integer | The channel id or mixer track id. Unread by project and master. |
| entries[].group | text | oscillators, amp, sample, soundfont or effects. Omit for the target's own parameters. |
| entries[].slot | integer | Which oscillator or which effect slot, counting from 0. |
| entries[].param | text | requiredThe parameter's name, as params_list gives it. |
presets_list
List the factory presets, for instruments and for effects.read
Filter by kind ('instrument' or 'effect') and by type - the id of an effect or an instrument, as project_describe reports a channel's source. A preset is refused if its type is not the slot's, so filtering first is worth doing.
| Argument | Type | Notes |
|---|---|---|
| kind | text | instrument or effect. |
| type | text | An effect or instrument id, such as reverb. |
patterns_read
Read one pattern's notes, optionally for one channel only.read
The piano roll's contents. Ask for one channel when you only mean one - a pattern holds every channel's notes, so the whole of a busy one is a lot of tokens for a question about the bass.
| Argument | Type | Notes |
|---|---|---|
| id | integer | requiredThe pattern to read. |
| channelId | integer | Return only this channel's notes. |
automation_targets_list
List every parameter in this project that a curve can be pointed at.read
Whether a parameter can carry a curve is declared beside the parameter itself, so this is a curated set. A read-pointer discontinuity (a sample's reverse and loop), a soundfont's tuning offsets and a pattern's length are absent from it.
Answers in the same five-field address params_write takes, so a parameter you have just set can be automated without translating anything.
| Argument | Type | Notes |
|---|---|---|
| contains | text | Only targets whose display name contains this. |
automation_read
Read one automation curve's points.read
Points come back exactly as they are stored: a value from 0 to 1, a bend and a segment shape. The mapping onto the parameter's own units happens where the curve is PLAYED, not here, so what this answers is what automation_points_write took.
stale is true when the curve points at something that no longer applies - an effect slot that changed type, an oscillator switched out of wavetable mode. A stale curve is inert rather than misapplied.
| Argument | Type | Notes |
|---|---|---|
| id | integer | requiredThe automation to read. |
score_read
Read the project's score source, and whether it still compiles.read
A dew project can carry the text of the arrangement language that produced it. Checking is free and writes nothing, so this reports the diagnostics without putting a single note on the undo stack.
Read the dew://guide/score resource for the language itself.
| Argument | Type | Notes |
|---|---|---|
| check | flag | Compile it to report diagnostics. True if absent. |
transport_read
Report whether dew is playing, in which mode, and where it is.read
A read, so it is available to a read-only grant. Use it to tell whether something you started is still going.
Takes no arguments.
render_status
Report whether a render is going, and how far along it is.read
Progress runs 0 to 1 across the whole job, stems included. stage names which stem is being written.
Takes no arguments.
Changing
project_command
Create, open or save the project, or step its undo history.changes the project
Verbs about the document rather than edits to it. 'new' and 'open' replace what is open and may be refused when there are unsaved changes; 'save' writes to the project's own file, or to path if you give one.
'undo' and 'redo' step the same history the user's own Cmd-Z steps. Every operation in this table is exactly one step of it, however many entries its batch carried.
| Argument | Type | Notes |
|---|---|---|
| verb | text | requirednew, open, save, undo or redo. |
| path | text | The file to open, or to save to. Required by 'open'. |
structure_write
Set the project's name, tempo, metre or length in bars.changes the project
The metre is not a tempo. Changing beatsPerBar redefines what a bar IS, so the bar lines move - but nothing you have written moves with them: a clip is stored in STEPS, so every note and every clip stays exactly where it sounded. What does change is the song's LENGTH, which is counted in bars: it is rounded up to cover what was already there, in the same undo step.
beatUnit is notational: it names the metre and labels the snap divisions, and does not change how long anything sounds for.
| Argument | Type | Notes |
|---|---|---|
| name | text | The project's title. |
| tempoBpm | number | Beats per minute. |
| beatsPerBar | integer | The top of the time signature. Load-bearing: it is the bar. |
| beatUnit | integer | The bottom of the time signature. Notational only. |
| barsInSong | integer | How long the arrangement is. |
params_write
Set any number of parameters anywhere in the project, as one undo step.changes the project
The one tool for every value in the document: a channel's volume, an oscillator's detune, an envelope's release, a sample's fade, a soundfont's tuning, any parameter of any effect, a mixer fader, the master, the tempo.
Every address is resolved before anything is written, so a batch with a bad entry changes nothing at all rather than half of what it asked for. A value outside a parameter's range is clamped to it; a choice given a name it does not have fails and says which names it has.
The whole call is one undo step, however many entries it carried.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe parameters to set, and what to set them to. |
| entries[].target | text | requiredproject, channel, mixerTrack or master. |
| entries[].id | integer | The channel id or mixer track id. Unread by project and master. |
| entries[].group | text | oscillators, amp, sample, soundfont or effects. Omit for the target's own parameters. |
| entries[].slot | integer | Which oscillator or which effect slot, counting from 0. |
| entries[].param | text | requiredThe parameter's name, as params_list gives it. |
| entries[].value | any | requiredA number, or the id of a choice, or true/false. params_list says which this parameter takes. |
channels_write
Add channels, or change the name, colour, routing or mute of existing ones, as one undo step.changes the project
An upsert: an entry with an id changes that channel, an entry without one adds a channel of kind. A field an entry does not mention is left alone, so changing a name does not blank a colour.
This is the channel as an object in the rack. For the sound it makes, use params_write, which reaches every oscillator, envelope and effect parameter it has.
A project holds 64 channels, which is as many as the engine renders. A batch that would take it past that is refused whole rather than adding the ones that fit.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe channels to add or change. |
| entries[].id | integer | An existing channel to change. Omit to add a new one. |
| entries[].kind | text | synth, audio or soundfont. Read only when adding. |
| entries[].name | text | What the channel is called. |
| entries[].colour | text | A hex colour. Empty means inherit the colour of its position. |
| entries[].mixerTrackId | integer | The mixer insert to route into. |
| entries[].muted | flag | Whether the channel is silent. |
channels_remove
Remove channels and the notes that belong to them.changes the project
One undo step. A channel's notes live in patterns and become unreachable once it is gone, so they go with it. Refuses the whole batch if any id names nothing, rather than removing the ones it recognised.
| Argument | Type | Notes |
|---|---|---|
| ids | array of integer | requiredThe channel ids to remove. |
source_write
Point an audio channel at a sample file, or a soundfont channel at a file and a sound inside it.changes the project
Only audio and soundfont channels have a source; a synth channel makes its own sound and this refuses it.
For a soundfont, giving a bank and program with no file chooses a different sound inside the font the channel already has, which is deliberately not the same as re-pointing it: re-pointing reloads the whole font.
A soundfont is referenced and never copied. A sample is gathered into the project's Assets folder when the project is saved.
| Argument | Type | Notes |
|---|---|---|
| channelId | integer | requiredThe channel to point. |
| file | text | The path to the sample or soundfont. Omit to keep the current file. |
| sourceSampleRate | integer | The sample's own rate, in Hz. |
| lengthSamples | integer | How long the sample is, in samples. |
| bank | integer | Soundfont bank. Drum kits are bank 128. |
| program | integer | Soundfont program within the bank. |
| presetName | text | What that sound is called, stored so the channel can name it when the font is missing. |
effects_write
Add effects to a channel, mixer insert or the master, or bypass and preset existing ones.changes the project
An entry with a slot changes the effect already there; an entry without one appends an effect of type to the end of the chain. A chain holds 9, and one past that is refused rather than silently dropped - an effect the engine does not render is an effect that appears to have stopped working.
The effect's own parameters are params_write's, addressed with group 'effects' and the same slot. preset here is a shorthand for the whole set of them at once; presets_list says what is available.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe effects to add or change. |
| entries[].target | text | requiredchannel, mixerTrack or master. |
| entries[].id | integer | The channel or mixer track id. |
| entries[].slot | integer | An existing slot to change. Omit to append a new effect. |
| entries[].type | text | What effect to add. Read only when adding. |
| entries[].enabled | flag | False bypasses the slot. |
| entries[].preset | text | A factory preset's name, applied to this slot. |
effects_move
Move one effect to another position in its chain.changes the project
Order is audible: a distortion before a reverb is not a distortion after one. Positions count effects only, so the instrument a channel also carries cannot shift the result.
An effect keeps its own DSP unit across the move - the pool is keyed on the effect's identity rather than its position - so reordering a chain does not cut the reverb tail the slots after it were in the middle of.
| Argument | Type | Notes |
|---|---|---|
| target | text | requiredchannel, mixerTrack or master. |
| id | integer | The channel or mixer track id. |
| slot | integer | requiredWhich effect to move. |
| toSlot | integer | requiredWhere it should end up. |
effects_remove
Remove effects from chains, as one undo step.changes the project
Slots are resolved before anything is removed, so removing slots 0 and 1 in one call removes the two you meant rather than the first and whatever slid up into its place.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe effects to remove. |
| entries[].target | text | requiredchannel, mixerTrack or master. |
| entries[].id | integer | The channel id or mixer track id. Unread by master. |
| entries[].slot | integer | requiredWhich effect in that chain, counting from 0. |
mixer_write
Add mixer inserts, or rename and recolour existing ones.changes the project
An upsert, like channels_write: an entry with an id changes that insert, one without adds a new one.
A fader and a pan are parameters rather than fields here: reach them with params_write, target 'mixerTrack'. The master is addressed as target 'master', and carries a fader only.
The mixer holds 32 inserts, which is as many as the engine renders. A batch that would take it past that is refused whole rather than adding the ones that fit.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe inserts to add or change. |
| entries[].id | integer | An existing insert to change. Omit to add one. |
| entries[].name | text | What the insert is called. |
| entries[].colour | text | A hex colour. Empty means inherit the colours routed into it. |
mixer_remove
Remove mixer inserts, their effects and the routing they leave behind.changes the project
Channels routed into a removed insert are re-pointed at the first remaining one in the same undo step, because a channel that has lost its insert is still a channel with notes in it - unlike a clip that has lost its pattern.
Refuses the last insert and refuses the master. Skipped entries are counted in the answer rather than reported as failures.
| Argument | Type | Notes |
|---|---|---|
| ids | array of integer | requiredThe insert ids to remove. |
patterns_write
Add, duplicate or rename patterns, as one undo step.changes the project
A pattern holds every channel's notes for its span, which is why a section of an arrangement is one pattern rather than one per instrument.
duplicateOf deep-copies a pattern, notes and all, under a new id - which is what a repeat that will be varied wants. A repeat that is identical wants one pattern and two clips instead.
A pattern's LENGTH is not settable, here or anywhere. It is derived from the notes the pattern holds, rounded up to a whole bar and never less than one. lengthSteps is reported back for reference and is not an argument.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe patterns to add or change. |
| entries[].id | integer | An existing pattern to change. Omit to make a new one. |
| entries[].duplicateOf | integer | Copy this pattern, notes and all, instead of making an empty one. |
| entries[].name | text | What the pattern is called. |
patterns_remove
Remove patterns and every playlist clip that played them.changes the project
One undo step. A clip pointing at a missing pattern would be dropped by the next engine rebuild anyway, so removing it here keeps the document consistent rather than merely tidy.
Refuses the last pattern: a project with none has nothing to edit and nothing to play. A refusal is counted as skipped rather than failing the batch.
| Argument | Type | Notes |
|---|---|---|
| ids | array of integer | requiredThe pattern ids to remove. |
notes_write
Write notes into a pattern, as one undo step.changes the project
An upsert on the three fields that identify a note - channel, step and pitch - so sending the same bar twice does not double it.
Time is whole steps. A step is 1/stepsPerBeat of a beat, which project_describe reports; at the default 4 a step is a sixteenth note. There is no fractional step and no tuplet that the grid does not divide.
The pattern's length FOLLOWS its notes and is not set directly: writing a note further in lengthens the pattern, and removing the notes at the end shortens it again. Refuses the whole batch on a bad channel or an out-of-range pitch rather than writing half of it.
For anything longer than a few bars, prefer score_write and score_compile: the language says what the music IS, and this says where every note goes.
| Argument | Type | Notes |
|---|---|---|
| patternId | integer | requiredThe pattern to write into. |
| notes | array of objects | requiredThe notes. |
| notes[].channelId | integer | requiredWhich channel sounds the note. |
| notes[].step | integer | requiredWhen it starts, in steps from the pattern's 0. |
| notes[].pitch | integer | requiredMIDI note number. 60 is middle C. |
| notes[].lengthSteps | integer | How long it lasts. One step if absent. |
| notes[].velocity | number | How hard it is struck, 0.05 to 1. |
notes_remove
Remove notes from a pattern, by list or by range.changes the project
Give notes to remove exactly those. Give none and it removes every note in the channel and step range you describe - with no channel and no range, that is every note in the pattern.
One undo step either way.
| Argument | Type | Notes |
|---|---|---|
| patternId | integer | requiredThe pattern to remove from. |
| notes | array of objects | Exactly these notes. |
| notes[].channelId | integer | requiredWhich channel sounds the note. |
| notes[].step | integer | requiredWhen it starts, in steps from the pattern's 0. |
| notes[].pitch | integer | requiredMIDI note number. 60 is middle C. |
| notes[].lengthSteps | integer | How long it lasts. One step if absent. |
| notes[].velocity | number | How hard it is struck, 0.05 to 1. |
| channelId | integer | Limit a range removal to one channel. |
| fromStep | integer | First step of the range, inclusive. |
| toStep | integer | Last step of the range, inclusive. |
notes_transform
Quantize or transpose every note on one channel of a pattern.changes the project
Quantizing rounds each note's START to the grid and deliberately leaves lengths alone: quantizing length as well turns an eighth-note line into a legato blur. Two notes that land on the same step and pitch are collapsed into one, keeping the longer - they retrigger one voice at one instant, so the second was never audible.
Transposing clamps the notes as a GROUP, so a chord against the top of the range keeps its intervals rather than compressing. The answer says how many semitones were actually applied, which is zero when the group is already against a limit.
A snap division is named, not numbered. The answer repeats the name it used, so a caller can see it got the division it asked for.
| Argument | Type | Notes |
|---|---|---|
| patternId | integer | requiredThe pattern to transform. |
| channelId | integer | requiredWhich channel's notes. |
| verb | text | requiredquantize or transpose. |
| snap | text | For quantize, one of: off, thirtysecond, sixteenthTriplet, sixteenth, eighthTriplet, eighth, quarter, half, bar. sixteenth if absent. off is the identity, because a step is already the finest position a note holds; a division this project's grid cannot place is refused rather than quietly doing nothing. |
| semitones | integer | For transpose: how far, and which way. |
playlist_tracks_write
Add arrangement lanes, or rename, mute and recolour existing ones.changes the project
A lane carries no id: lanes are positional, unlike channels and mixer inserts, so an index is the whole address. An entry with an index changes that lane and one without appends a new one.
A lane is not a channel. Any lane can carry a clip of any pattern, and a pattern holds every channel's notes - so lanes are sections of the song, not instruments.
| Argument | Type | Notes |
|---|---|---|
| entries | array of objects | requiredThe lanes to add or change. |
| entries[].index | integer | An existing lane. Omit to append a new one. |
| entries[].name | text | What the lane is called. |
| entries[].mute | flag | Silence everything on the lane. |
| entries[].colour | text | A hex colour, or empty to inherit. |
playlist_tracks_remove
Remove arrangement lanes and the clips on them.changes the project
One undo step. The clips go with the lane. Automations do NOT - an automation is a reusable definition that can be placed again, unlike the notes a removed channel leaves behind, which nothing can reach.
Removing a lane renumbers the ones after it, so give every index you mean in one call rather than calling repeatedly.
| Argument | Type | Notes |
|---|---|---|
| indexes | array of integer | requiredThe lane indexes to remove. |
clips_write
Place clips on the arrangement: patterns, audio takes or automation curves.changes the project
A clip is measured in BARS, and a bar is stepsPerBeat * beatsPerBar steps - 16 in a default 4/4 project, which project_describe reports. Placing two clips of one pattern is how a section repeats identically; duplicating the pattern first is how it repeats with variation.
The song grows to fit what you place, and never shrinks: trailing empty bars are a deliberate silence.
Refuses the whole batch rather than placing some of it: on a bad lane, pattern, channel or automation, on a negative start, and on an audio clip aimed at a channel that has no recording to play.
| Argument | Type | Notes |
|---|---|---|
| clips | array of objects | requiredThe clips to place. |
| clips[].track | integer | requiredWhich lane, counting from 0. |
| clips[].kind | text | pattern, audio or automation. Pattern if absent. |
| clips[].startBar | integer | Where it begins, counting from 0. |
| clips[].lengthBars | integer | How many bars it spans. |
| clips[].startStep | integer | Where it begins, in steps. Overrides startBar, and is the only way to start a clip off a bar line. |
| clips[].lengthSteps | integer | How many steps it spans. Overrides lengthBars. |
| clips[].patternId | integer | For a pattern clip. |
| clips[].channelId | integer | For an audio clip. |
| clips[].automationId | integer | For an automation clip. |
clips_remove
Remove the clip covering a bar on a lane.changes the project
Addressed by where it is rather than by an id, because that is how a clip is identified on screen: a lane and a bar. A bar with no clip on it is skipped rather than failing the batch, so clearing a range is safe to ask for twice.
| Argument | Type | Notes |
|---|---|---|
| clips | array of objects | requiredLane-and-bar pairs. |
| clips[].track | integer | requiredWhich lane. |
| clips[].atBar | integer | Any bar the clip covers. |
| clips[].atStep | integer | Any step the clip covers. Overrides atBar, and is how to reach a clip that does not begin on a bar line. |
automation_write
Create an automation curve for a parameter, and place a clip for it.changes the project
Creating the curve and placing its clip is one call because it is one action: a curve with nowhere to play is a curve nothing hears. The clip lands on the first lane with room at startBar, and a lane is added if every one is occupied there.
A fresh curve has two points rather than none, so it is something you can hear before you shape it - a line for a continuous parameter, and a pair of steps for a discrete one, because half-on is not a state a toggle has. Shape it with automation_points_write.
Refuses a parameter that is not automatable, and says so - which is a different answer from a parameter that does not exist.
| Argument | Type | Notes |
|---|---|---|
| target | text | requiredproject, channel, mixerTrack or master. |
| id | integer | The channel or mixer track id. |
| group | text | oscillators, amp, soundfont or effects. Omit for the target's own parameters. |
| slot | integer | Which oscillator or effect slot. |
| param | text | requiredThe parameter to automate. |
| placeClip | flag | Place a clip for it. True if absent. |
| startBar | integer | Where the clip begins. |
| lengthBars | integer | How many bars it spans. |
automation_points_write
Add or move points on an automation curve, as one undo step.changes the project
A point is a step and a value from 0 to 1. Two points on one step is a curve with no defined value there, so a point written where one already sits moves it rather than duplicating it.
Three shapes are offered and two are stored: 'line' is a curve with no bend, so switching to 'step' and back returns the curve you had. A stepped segment ignores its bend rather than losing it.
replace removes whatever was there that you did not write, which is how you redraw a curve rather than add to it. A curve always keeps at least two points - one with fewer has no shape to evaluate - so replacing with a single point leaves one of the old ones behind, and the answer's points count says so.
| Argument | Type | Notes |
|---|---|---|
| id | integer | requiredThe automation to shape. |
| replace | flag | Clear the existing points first. |
| points | array of objects | requiredThe points. |
| points[].step | number | requiredWhere, in steps from the clip's start. |
| points[].value | number | requiredWhat, from 0 to 1. |
| points[].shape | text | line, curve or step. Applies to the RIGHT. |
| points[].bend | number | How the curve bends, -1 to 1. |
automation_remove
Remove automation curves and every clip that played them.changes the project
One undo step. A clip pointing at a removed automation would have nothing to drive, so it goes too.
| Argument | Type | Notes |
|---|---|---|
| ids | array of integer | requiredThe automation ids to remove. |
score_write
Store score source in the project, without compiling it.changes the project
Storing and compiling are separate on purpose: a compile writes notes, and text that is being worked on should not fill the undo stack with them.
The answer says whether what you stored compiles and why not, so you can fix it before asking for the notes.
| Argument | Type | Notes |
|---|---|---|
| source | text | requiredThe whole score, as text. |
| sourceName | text | What to call it in diagnostics. |
score_compile
Compile the score into real patterns, notes and clips, as one undo step.changes the project
The language says what the music IS - key, harmony, rhythm, voicing, counterpoint - and the compiler works out the notes. One call arranges a whole section; notes_write places one note at a time.
The language owns notes, patterns and clips; you own channels, instruments, effects and the mixer. Recompiling is an UPDATE rather than a second copy, and hand edits are kept unless you say otherwise.
Refuses outright if the score has errors, rather than baking half of it. Note that the same source always compiles to the same notes, on any machine.
| Argument | Type | Notes |
|---|---|---|
| source | text | Compile this instead of what is stored, and store it too. |
| sourceName | text | What to call it in diagnostics. |
| discardHandEdits | flag | Overwrite notes edited by hand since the last compile. |
transport_write
Start or pause playback, choose song or pattern mode, and move the playhead or the start marker.changes the project
Not an edit: nothing here touches the document or the undo history. It is what the transport bar does.
Any pending change to the document is applied to the engine first, so playing immediately after writing notes plays the notes you just wrote.
| Argument | Type | Notes |
|---|---|---|
| playing | flag | True plays, false pauses - which returns to the start marker. |
| mode | text | song plays the arrangement, pattern loops the current pattern. |
| playheadSteps | number | Move the playhead, in steps. |
| startMarkerSteps | number | Where playback begins and where pausing returns to, in steps. Moves the playhead with it. |
| rewind | flag | Return to the start: the playhead and the marker both. |
render_audio
Start rendering the project to an audio file, or to one file per mixer insert.changes the project
Answers as soon as the render STARTS, because a render is seconds to minutes of work. Poll render_status for progress, and do not start a second one while one is going.
The format follows the extension. MP3 needs the lame binary to be installed and reports itself unavailable when it is not.
A stem is a full render with the other inserts muted, so it carries the effects and the routing it has in the mix. That also means stems do not sum back to the mix when the master chain holds a non-linear effect.
| Argument | Type | Notes |
|---|---|---|
| path | text | requiredWhere to write. A file, or the folder to fill when stems is set. |
| mode | text | song renders the arrangement, pattern renders one pattern. Song if absent. |
| patternId | integer | Which pattern, in pattern mode. |
| stems | flag | Write one file per MIXER INSERT instead of one mix. Not one per channel - a new project has twenty inserts and usually fewer channels than that. |
| seconds | number | Render exactly this long, letting the material loop. 0, or absent, renders it once. |
export_midi
Write the project's notes to a MIDI file.changes the project
Synchronous, unlike an audio render: writing MIDI is arithmetic over the notes rather than a pass over every sample.
The metre's beatUnit goes into the file's time signature. Audio channels have no notes to write and are reported as warnings rather than silently dropped.
| Argument | Type | Notes |
|---|---|---|
| path | text | requiredWhere to write the file. |
| mode | text | song renders the arrangement, pattern renders one pattern. Song if absent. |
| patternId | integer | Which pattern, in pattern mode. |