No description
Find a file
2026-07-01 14:27:03 -07:00
docs/superpowers docs: add fieldwerk implementation plan 2026-06-29 16:10:36 -07:00
examples fix(runtime): make MIDI setup work without manual device wrangling 2026-06-30 18:54:29 -07:00
packages waveforms 2026-07-01 14:27:03 -07:00
.gitignore chore: scaffold npm workspaces root 2026-06-29 16:12:25 -07:00
idea.md fieldwerrrkkkkk 2026-06-29 16:01:08 -07:00
midi-map.json fix(runtime): make MIDI setup work without manual device wrangling 2026-06-30 18:54:29 -07:00
package-lock.json feat(runtime): compose engine, server, hardware entrypoint 2026-06-29 16:28:55 -07:00
package.json chore: scaffold npm workspaces root 2026-06-29 16:12:25 -07:00
README.md fix(runtime): make MIDI setup work without manual device wrangling 2026-06-30 18:54:29 -07:00

fieldwerk

Serendipitous navigator for a personal field-recording archive. Turn knobs on a MIDI Mixer One to locate and play recordings; a monome grid shows up to six voices with live playhead timelines. A minimal browser view at localhost provides status and waveforms.

Setup

Run all Node/npm commands inside the node toolbox on Fedora:

toolbox enter node   # or: toolbox run --container node <command>
npm install
npm test

Binaries link via workspaces: fieldwerk-prep, fieldwerk.

Prep

One-time, in-place preparation of a flash drive that already holds your WAV collection:

fieldwerk-prep /path/to/drive [--dry-run]

Requires ffmpeg. Transcodes each WAV to MP3 and deletes the source WAV on success. Also deduplicates, renames files to audio/<id>.mp3, and writes index.json at the drive root.

Destructive — back up before running without --dry-run. Use --dry-run to print every transcode, delete, and rename without touching files.

Runtime

fieldwerk /path/to/drive [--port=7777] [--sim]

Serves the archive over HTTP, bridges state to the browser via WebSocket, and listens for MIDI and monome OSC. Open http://localhost:7777 for the screen view.

Hardware is optional at startup — missing monome or MIDI logs a warning and continues.

Simulation (--sim)

Hardware-free development. POST JSON to simulate inputs:

curl -X POST localhost:7777/sim/knob \
  -H 'content-type: application/json' \
  -d '{"knob":0,"cc":64}'

curl -X POST localhost:7777/sim/button \
  -H 'content-type: application/json' \
  -d '{"name":"reverse"}'

curl -X POST localhost:7777/sim/gridkey \
  -H 'content-type: application/json' \
  -d '{"x":0,"y":0,"pressed":1}'

MIDI

The map describes your controller, not the archive. fieldwerk looks for midi-map.json in this order:

  1. --midi-map=/path/to/midi-map.json
  2. ./midi-map.json (current working directory)
  3. repo root midi-map.json (included for MIDI Mixer One)
  4. ~/.config/fieldwerk/midi-map.json
  5. drive root midi-map.json (legacy fallback)

See examples/midi-map-mixer-one.json for the CC/note layout.

Device selection is automatic: fieldwerk picks the first visible input that isn't a virtual "Midi Through" loopback port, so plain fieldwerk <drive> works with a single controller plugged in. Pass --midi-device="exact name" (copy it from the "MIDI inputs visible" startup line) only if you have multiple real devices and need a specific one. Add --midi-debug to log every incoming MIDI message and whether it matched the map.

If the map loads but knobs do nothing:

  • Check the startup line — did it bind to your controller, or an unexpected device?
  • USB MIDI is sometimes not visible inside a toolbox. Run aseqdump -l (from alsa-utils) inside the toolbox to confirm the OS sees the device at all; if not, run fieldwerk on the host instead.

Monome grid

Rows Purpose
05 One voice per row
67 Reserved
Cols Purpose
0 Focus toggle (bright = focused, dim = playing)
115 15-segment playhead timeline; tap to seek

MIDI buttons

Four buttons apply to all focused voices:

Button Effect
randomSpeed Random playback rate (0.252.0×)
randomTime Seek to random position
reverse Toggle direction
remove Stop, clear slot, drop focus

Eight remaining buttons are unassigned.