Native App Model
Properties
AppModel's own blocklist — the list the Plugin Selector shows. A standalone ScanTool keeps a separate one. BlocklistEntry.timestamp in uapmd has no counterpart in uapmd_blocklist_entry_t, so it is not carried across.
UMP devices the model has instantiated.
Also reports busy while an asynchronous plug-in mutation is still capturing state, so shortcuts cannot race the capture.
Turning this off is not a plain stopAudio(): the model stops the transport, mutes the output, lets release/reverb tails drain inaudibly, then deactivates plugins on the main thread and resets processing state, so a restart cannot resume stale voices.
The last scanning error, or null.
Empty when the last clipboard call succeeded.
Reading counterpart to ProjectCommands.setMasterTrackMarkers.
The project's tempo curve, as the engine derived it from the master track. Read this rather than assembling one from the master tempo points, so that display and playback can never be working from different maps.
Owned by the model; do not close.
Progress of the slow scan. isScanning alone cannot tell a long scan from a stuck one, which is why uapmd-app's selector shows these.
The span the timeline's content actually occupies.
Functions
AppModel::addClipToTrack. Ownership of reader transfers to the engine, so do not close it afterwards - a successful call consumes it, and a failed one reports reader not found or already consumed if the same reader is offered twice.
AppModel::addDeviceInputToTrack, returning the new source node id, or a negative value on failure. The undoable counterpart is ProjectCommands.addDeviceInputToTrack, which takes the node id this returns; prefer that one from a UI.
AppModel::addMidiClipFromData, for a clip built in memory rather than read from a file - what a generator or a step sequencer produces.
AppModel::addMidiClipToTrack, reading an SMF or SMF2 from disk.
False leaves the reason in lastTimelineClipError.
Creates an empty MIDI 2.0 clip; tickResolution is ticks per quarter.
Instantiates pluginId and attaches it to trackIndex; a negative index creates a new track. The callback runs once, on the thread that finishes instantiation.
cut copies the selection before deleting it.
The device hosting a plug-in instance, or null when it has none.
Registers the instance as a virtual MIDI 2.0 device where the platform supports it.
Switches the track from the simple linear chain to the editable graph.
Reading counterpart to ProjectCommands.setClipMarkers/setClipAudioWarps.
A hidden track is skipped by paste and by the track list, but still plays.
Plug-in state to and from a file. Prefer these over the *Sync variants: a plug-in's state can be slow to produce, and on Android reading it from the main thread can deadlock.
The blocking variants, for tools and tests that have no loop to post a completion to. See the warning on loadPluginState.
Android's document-picker path: resolves a content:// handle token.
Marks the track owning this instance dirty, so the next save rewrites it.
Discards the current project and starts an empty one. Asks nothing and always replaces: whether unsaved changes may be discarded is the caller's decision. Unlike TimelineFacade.newProject this also tears down what the outgoing project instantiated and rebuilds the model's view of the result.
Startup lifecycle; uapmd-app calls both once the UI exists.
Owned by the model and shared between callers; do not close.
Runs asynchronously; watch isScanning. ScanMode.Remote launches a separate scanner process on desktop and is unavailable on WebAssembly.
The caller owns the snapshot and must close it.
Commit-source tracking.
Master-track tempo map. getTimelineState().tempo is a single value and cannot describe a project whose tempo changes; a beats view needs these. Rebuild once with refreshMasterTempoMap, then read the lists — they stay valid until the next refresh.
Asks the host to bring up this track's graph editor.
The MIDI clip an editor is open on, tracked separately from the selection.
Writes the master markers and reports why a rejected set was rejected, which ProjectCommands.setMasterTrackMarkers reduces to a boolean. This path is not undoable.
False when a render is already running or the settings are unusable.
Which tracks a paste would land on, without performing it. originalTracks pastes each clip back onto the track it came from instead of onto trackIndex.