K

Remember settings and bundle files

Save more than knobs, and ship files with your device.

Knob positions save automatically. This is for the two extras.

Remember more than knobs

For something bigger than a knob (a sequencer pattern, a recorded loop, a learned value): reserve room, then save and load it.

describe(): Manifest {
  const m = new Manifest("Sequencer");
  m.state(256); // up to 256 bytes
  return m;
}

getState(): Uint8Array {
  // pack your data into bytes and return it
}

setState(bytes: Uint8Array): void {
  // read it back
}

Msh stores the bytes in your project, and they survive both saving and editing the device's code. Saving and loading happen off the audio thread, so they can be slow.

Rather than count byte offsets by hand, pack with StateWriter and unpack with StateReader. The writer stamps a version first, so when you change your format later you branch on reader.version and still load old saves:

getState(): Uint8Array {
  const w = new StateWriter(1, 4); // version 1, 4 bytes of payload
  w.i32(this.steps);
  return w.bytes();
}

setState(bytes: Uint8Array): void {
  const r = new StateReader(bytes);
  if (r.version >= 1) this.steps = r.i32();
}

For a matrix or step grid, store a BitGrid instead of one param per cell: keep it in m.state, edit it from a click, and mirror it to the canvas. See the control surface.

Bundle files

Each device has an assets folder. Drop in samples, impulse responses, tables, images, and load one at startup:

prepare(sampleRate: f64, maxBlock: i32): void {
  const data = loadAsset("ir.bin"); // Uint8Array from assets/ir.bin
}

Msh packs these into your project, so the device still works on another machine. Signatures in the device API.