/ proof-of-concept / midiboot
Sign in
proof-of-concept / midiboot
midiboot / src / instruments / types.ts
61 lines · 2.0 KBBlameHistoryRaw
1// The instrument extension point. An instrument turns note events into
2// audio in two ways:
3//
4// - render(): the offline path. Given every note with times in seconds,
5// produce one mono buffer for the whole track. This is what playback
6// and WAV export use, and it may be async and arbitrarily expensive
7// (a GPU physical model, a worker, a remote call). Results are cached
8// per track and invalidated by note or instrument changes.
9//
10// - noteOn(): the optional live path, used for low-latency monitoring
11// while recording and for previewing notes from the piano roll and
12// keyboard. An instrument without it is still fully usable; monitoring
13// falls back to a small default click.
14//
15// To add a custom instrument, implement this interface and register it in
16// registry.ts. Nothing else in the application knows what an instrument is
17// made of.
19export interface NoteSpec {
20 timeSec: number;
21 durationSec: number;
22 pitch: number; // MIDI note number
23 velocity: number; // 0..1
26export interface RenderRequest {
27 notes: NoteSpec[];
28 sampleRate: number;
29 lengthSamples: number;
30 /** Fast preview for playback, full quality for export; instruments
31 * without tiers ignore it. */
32 quality?: 'preview' | 'full';
33 /** Values for the instrument's knobs (per track); missing keys mean the
34 * knob's default. */
35 settings?: Record<string, number>;
38/** A user-editable instrument parameter, declared by the instrument. */
39export interface KnobSpec {
40 key: string;
41 label: string;
42 min: number;
43 max: number;
44 default: number;
45 step?: number;
46 scale?: 'log';
49export interface LiveVoice {
50 noteOff(): void; // begin release
51 cut(): void; // stop immediately
54export interface Instrument {
55 id: string;
56 name: string;
57 render(req: RenderRequest): Float32Array | Promise<Float32Array>;
58 noteOn?(ctx: BaseAudioContext, dest: AudioNode, pitch: number, velocity: number, whenSec: number): LiveVoice;
59 /** Curated editable parameters; tracks store their values in settings. */
60 knobs?: KnobSpec[];
↑↓ move↵openescclose