From c43d080bee6aa6fd598e548413cf10bda1f1b844 Mon Sep 17 00:00:00 2001 From: Cam Gorrie Date: Thu, 20 Aug 2026 23:50:49 -0400 Subject: [PATCH 1/9] SFZ Builder working! --- docs/sfz-builder-plan.md | 252 +++++++++++++++ html/css/less/main.less | 19 +- html/css/less/sfzbuilder.less | 453 ++++++++++++++++++++++++++ html/css/main.css | 10 +- html/index.html | 65 ++++ html/js/desktop.js | 12 + html/js/pedalboard.js | 6 +- html/js/sfzbuilder.js | 579 ++++++++++++++++++++++++++++++++++ mod/sfzbuilder.py | 299 ++++++++++++++++++ mod/webserver.py | 136 +++++++- test/test_sfzbuilder.py | 248 +++++++++++++++ 11 files changed, 2061 insertions(+), 18 deletions(-) create mode 100644 docs/sfz-builder-plan.md create mode 100644 html/css/less/sfzbuilder.less create mode 100644 html/js/sfzbuilder.js create mode 100755 mod/sfzbuilder.py create mode 100755 test/test_sfzbuilder.py diff --git a/docs/sfz-builder-plan.md b/docs/sfz-builder-plan.md new file mode 100644 index 00000000..17d3b345 --- /dev/null +++ b/docs/sfz-builder-plan.md @@ -0,0 +1,252 @@ +# SFZ Sound-Bank Builder — Implementation Plan + +## 1. Purpose + +This document defines the SFZ sound-bank builder for mod-ui. + +The builder is a new panel in mod-ui. It lets the user do these tasks: + +- Upload audio files to the device. +- Import audio files from a USB stick. +- Add sample-files that already exist on the device. +- Arrange the audio files into pad-slots. +- Set the pad-count and the base-note. +- Set per-sample options (gain, root-note, loop-mode). +- Listen to a sample in the browser. +- Build an SFZ file. +- Load the SFZ file into sfizz. + +The output of the builder is one SFZ file and the sample-files that it uses. + +sfizz (the sample player on the device) reads the SFZ file. The user triggers the samples with MIDI pads. Each pad plays one sample. The pads send MIDI-notes from a base-note upward. + +This document does not implement the feature. It describes the design and the build steps. + +## 2. Terms and Definitions + +| Term | Definition | +|---|---| +| SFZ file | A text-file that maps sample-files to MIDI-notes. | +| sound-bank | A folder that contains sample-files and one SFZ file. | +| pad-slot | One position in the sound-bank. One pad-slot maps to one MIDI-note. | +| base-note | The MIDI-note of the first pad-slot. | +| pad-count | The number of pad-slots in the sound-bank. | +| sample-file | An audio file (for example .wav) that one pad-slot uses. | +| mod-ui | The web-interface of the pi-Stomp device. | +| sfizz | The SFZ sample player on the device (version 1.2.3). | +| browsepy | The directory file-browser on the device (port 8081). | +| MIDI | Musical Instrument Digital Interface. | +| USB | Universal Serial Bus. | + +## 3. Background + +The device runs mod-ui on port 80. mod-ui is the pedalboard editor. It runs as the user pistomp. + +All user files live under `/home/pistomp/data/user-files`. The mod-ui service sets this path with the variable `MOD_USER_FILES_DIR`. The folder contains category folders. Each category folder maps to one file-type. The `SFZ Instruments` folder maps to the file-type `sfz`. + +The mod-ui endpoint `/files/list` lists files by file-type. It walks the category folder recursively. It returns the full path and the file-name for each file. It does not return audio metadata (duration, sample-rate, loop-points). It has no folder-tree endpoint. + +The sfizz plugin has a file parameter named `sfzfile`. The pi-Stomp fork adds the annotation `mod:fileTypes "sfz"` to this parameter. Thus, any `.sfz` file under `SFZ Instruments` appears in the sfizz file-picker. The load side needs no change. + +browsepy runs on port 8081. It is a directory file-browser with upload. mod-ui shows it in the File Manager tab. It runs as the user pistomp. + +USB sticks mount automatically at `/media/