From 8e2c00cfcb3b10a8d02c0f0737b3856e7958105d Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 14 Oct 2026 14:56:36 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=E2=80=94=20=EB=A3=A8?= =?UTF-8?q?=ED=8A=B8=EC=9D=98=20=EB=82=98=EB=A8=B8=EC=A7=80=20=EC=95=88?= =?UTF-8?q?=EB=82=B4=EC=84=9C=EB=A5=BC=20=EC=A0=9C=EC=9E=90=EB=A6=AC?= =?UTF-8?q?=EB=A1=9C=20=EC=98=AE=EA=B8=B4=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UiNXfT3BJwA4V6Ht8ZULZN From ac1e811dfb35af93d0a17368cf12bc5e97b54f2a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 14 Oct 2026 15:00:27 +0000 Subject: [PATCH 2/2] docs: move the community files to .github/ and the audio guide to docs/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The maintainer's answer to rfc-cleanup §2.13 question 1 (step 1, lane A2). CODE_OF_CONDUCT.md, SECURITY.md and SUPPORT.md go to .github/, where GitHub still finds them; AUDIO_GUIDE.md goes to docs/. Their own relative links are rewritten for the new folder with no word changed. The links into them (README.md, CONTRIBUTING.md, docs/README.md, docs/REPOSITORY.md, firmware/README.md, the audio extension's README, the issue chooser's SUPPORT.md link, the features page and the Audio guide's copy) and the mentions in AGENTS.md and the two docs maps point at the new paths. CHANGELOG.md's mentions stay as history. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UiNXfT3BJwA4V6Ht8ZULZN --- .../CODE_OF_CONDUCT.md | 2 +- .github/ISSUE_TEMPLATE/config.yml | 2 +- SECURITY.md => .github/SECURITY.md | 2 +- SUPPORT.md => .github/SUPPORT.md | 4 +- AGENTS.md | 2 +- CONTRIBUTING.md | 2 +- README.md | 10 ++-- AUDIO_GUIDE.md => docs/AUDIO_GUIDE.md | 52 +++++++++---------- docs/README.md | 7 +-- docs/REPOSITORY.md | 12 ++--- firmware/README.md | 2 +- tools/patternflow-audio-extension/README.md | 2 +- web/src/app/features/features-data.ts | 2 +- web/src/components/guide/copy/audio.ts | 11 ++-- 14 files changed, 57 insertions(+), 55 deletions(-) rename CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md (94%) rename SECURITY.md => .github/SECURITY.md (80%) rename SUPPORT.md => .github/SUPPORT.md (94%) rename AUDIO_GUIDE.md => docs/AUDIO_GUIDE.md (90%) diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 94% rename from CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md index b9531587..d07895ba 100644 --- a/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -4,7 +4,7 @@ This applies everywhere Patternflow people meet: this repository (issues, pull r ## How we treat each other -The rule was written before there was anything to build, as a short poem, and it is the sixth section of the [manifesto](docs/manifesto.md#6-how-we-treat-each-other). In full: +The rule was written before there was anything to build, as a short poem, and it is the sixth section of the [manifesto](../docs/manifesto.md#6-how-we-treat-each-other). In full: > 아무것도 몰라도, 하고자 한다면 만들 수 있습니다. > 도와주는 게 당연합니다. 고마운 게 당연합니다. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e67ad620..cdcde0f8 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -13,7 +13,7 @@ contact_links: url: https://discord.gg/Vr9QtsxeTk about: New here? Join the server, then jump into the channels above. - name: Getting help — every venue in one table - url: https://github.com/engmung/Patternflow/blob/main/SUPPORT.md + url: https://github.com/engmung/Patternflow/blob/main/.github/SUPPORT.md about: Where to ask what, including the venue that works where Discord is blocked. - name: Contributing guide url: https://github.com/engmung/Patternflow/blob/main/CONTRIBUTING.md diff --git a/SECURITY.md b/.github/SECURITY.md similarity index 80% rename from SECURITY.md rename to .github/SECURITY.md index 1193d2bb..772748ef 100644 --- a/SECURITY.md +++ b/.github/SECURITY.md @@ -13,7 +13,7 @@ Please report privately through [GitHub's report form](https://github.com/engmun ## What is a documented trust model, not a vulnerability -The device's HTTP server on the LAN has **no authentication**: anyone on the same network can call any `/api/*` route, including `POST /update`. The same holds on the panel's own hotspot (`patternflow-xxxx`, raised when it finds no network it knows), whose password is the documented default `patternflow` until it is changed on the Wi-Fi page. This is deliberate and documented in [docs/rest-api.md](docs/rest-api.md#transport) — the panel is an instrument on a home or venue network, with the same posture as ArduinoOTA's default. `PF_WEBUPDATE_ALWAYS_ARMED 0` is the one lever that narrows `/update`; the hotspot takes its own password, or is switched off, on the Wi-Fi page. Reports that amount to "the LAN API is open" will be closed with a pointer here; reports of a way to reach that API from *outside* the LAN, or from a web page on another origin, are in scope. +The device's HTTP server on the LAN has **no authentication**: anyone on the same network can call any `/api/*` route, including `POST /update`. The same holds on the panel's own hotspot (`patternflow-xxxx`, raised when it finds no network it knows), whose password is the documented default `patternflow` until it is changed on the Wi-Fi page. This is deliberate and documented in [docs/rest-api.md](../docs/rest-api.md#transport) — the panel is an instrument on a home or venue network, with the same posture as ArduinoOTA's default. `PF_WEBUPDATE_ALWAYS_ARMED 0` is the one lever that narrows `/update`; the hotspot takes its own password, or is switched off, on the Wi-Fi page. Reports that amount to "the LAN API is open" will be closed with a pointer here; reports of a way to reach that API from *outside* the LAN, or from a web page on another origin, are in scope. ## Supported versions diff --git a/SUPPORT.md b/.github/SUPPORT.md similarity index 94% rename from SUPPORT.md rename to .github/SUPPORT.md index a06b26f7..e9dc5ab2 100644 --- a/SUPPORT.md +++ b/.github/SUPPORT.md @@ -6,13 +6,13 @@ One table for "where do I ask". Issues are for things that change this repositor | :--- | :--- | | Learn to build, play, make patterns for one or give it sound and MIDI | [The guide](https://patternflow.work/guide) — each step on a 3D Patternflow in the browser. A step that didn't get you through has a **Stuck here?** link, which opens an issue with that step filled in | | Get unstuck building, soldering or flashing | [Discord → hardware-help](https://discord.com/channels/1497757947827327067/1499907910707187833) — photos and quick back-and-forth | -| Flash the DevKit for the first time, or get the panel onto Wi-Fi | [The Play guide's Flash chapter](https://patternflow.work/guide/play#flash), or [`BUILD_GUIDE.md` §8](BUILD_GUIDE.md#8-firmware) in writing. The short version is below the table | +| Flash the DevKit for the first time, or get the panel onto Wi-Fi | [The Play guide's Flash chapter](https://patternflow.work/guide/play#flash), or [`BUILD_GUIDE.md` §8](../BUILD_GUIDE.md#8-firmware) in writing. The short version is below the table | | Show a pattern I made, or get feedback on one | Publish it from the [Pattern Lab](https://patternflow.work/pattern-lab) to the [Community](https://community.patternflow.work/community), then [Discord → patterns](https://discord.com/channels/1497757947827327067/1499908302962819236) | | Put my finished build on the [build map](https://patternflow.work/inside) | [Share your build](https://github.com/engmung/Patternflow/issues/new?template=share_build.yml) — or post it in Discord | | Talk about where the project should go, or find people working on the same direction | [Discord](https://discord.gg/Vr9QtsxeTk) — the dev-log and the project channels | | Report a bug, a wrong or missing doc, or propose a feature | [New issue](https://github.com/engmung/Patternflow/issues/new/choose) — pick the template | | Report a security problem | [SECURITY.md](SECURITY.md) — privately, not as an issue | -| Contribute code, hardware files or docs | [CONTRIBUTING.md](CONTRIBUTING.md) | +| Contribute code, hardware files or docs | [CONTRIBUTING.md](../CONTRIBUTING.md) | **The first flash, in short.** diff --git a/AGENTS.md b/AGENTS.md index e2bfc0d8..ea069424 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,7 @@ Patternflow is an open-source hardware instrument: four rotary encoders controll It is standalone (not Eurorack), powered from a 5 V power bank through a screw terminal, and it is not an analog video synthesizer. Sound arrives through the Audio edition (on-board microphone, OSC, MIDI), not the default firmware. ## Repository map -- `docs/` — contracts and long-form docs: `EDITIONS.md` (the firmware seam — read it before touching firmware), `rest-api.md` / `osc-spec.md` / `midi-spec.md` / `audio-ws-spec.md` (wire contracts integrations are built against), `pfst-v2-spec.md` (show files), `panel-compatibility.md`, `RELEASING.md`, `SERVICES.md` (production server ops), the assembly map (`docs/assembly/`), the legacy v2.x build guide (`docs/legacy/BUILD_GUIDE_v2.md`), the manifesto, investigations, and media (build-guide images in `docs/build-guide/`). Root-level guides: `BUILD_GUIDE.md` (the **v3 board**: v3.9, and v3.0 the same way), `PATTERN_GUIDE.md` (community → deck → Pattern Lab → device), `FEATURE_GUIDE.md` (writing a firmware feature or edition), `AUDIO_GUIDE.md` (sound into the panel). The live roadmap is patternflow.work/journal and the `/roadmap` page. +- `docs/` — contracts and long-form docs: `EDITIONS.md` (the firmware seam — read it before touching firmware), `rest-api.md` / `osc-spec.md` / `midi-spec.md` / `audio-ws-spec.md` (wire contracts integrations are built against), `pfst-v2-spec.md` (show files), `panel-compatibility.md`, `RELEASING.md`, `SERVICES.md` (production server ops), the assembly map (`docs/assembly/`), the legacy v2.x build guide (`docs/legacy/BUILD_GUIDE_v2.md`), `AUDIO_GUIDE.md` (sound into the panel), the manifesto, investigations, and media (build-guide images in `docs/build-guide/`). Root-level guides: `BUILD_GUIDE.md` (the **v3 board**: v3.9, and v3.0 the same way), `PATTERN_GUIDE.md` (community → deck → Pattern Lab → device), `FEATURE_GUIDE.md` (writing a firmware feature or edition). The live roadmap is patternflow.work/journal and the `/roadmap` page. - `firmware/` — PlatformIO/Arduino code for the ESP32-S3. Main sketch folder: `firmware/patternflow/` with `patternflow.ino`, `config.h` (pin mappings, brightness, limits, LED calibration), `net_config.h` (Wi-Fi / Improv / OTA / self-update defaults and the lane scale — core only; a feature's own tunables live in `features//_config.h`, and settings TUNE a feature, they never add one; per-device secrets in gitignored `patternflow_secrets.h`), and `pattern_registry.h` (function-pointer pattern table; compiles in Origin alone — the rest of the curated set ships as the Basics pack). Shared engine code lives in `firmware/patternflow/src/` (`core_display.h` HUB75 driver, `core_encoders.h`, canvas/color/math/noise helpers, Wi-Fi/OTA/web-console modules, the hotspot in `core_hotspot.h`) — core only: OSC, audio, MQTT, weather, shows, MIDI and the clock all live in `features/`. `firmware/patternflow/abi/` is the frozen host ⇄ module contract. Curated patterns live in `firmware/patternflow/presets/` (`preset_origin.h`, `preset_wave_saw.h`, dated presets), each using its own pattern namespace; user patterns are `.pfm` modules uploaded to the device over Wi-Fi, built from `firmware/modules/` via `firmware/toolchain/build_module.py` (the old `custom1.h`–`custom3.h` root slots are gone). Features attach through `firmware/patternflow/features/` (named `addons/` until 2026-08-30; legacy spellings are shimmed for out-of-tree bundles — see docs/EDITIONS.md) — a directory and a descriptor of function pointers, with the core naming none of them (see its README). `firmware/bundles/` names firmwares built from the same tree (the shelf editions `audio` and `performance`, plus `clock` and `midi`, compositions the tree keeps buildable but does not publish; the default build has no bundle): two files each, saying which features compile in and what the build calls itself; `firmware/bundles/build.sh` builds the default or a named one, `shelf.sh` stages a publishable image. Device console pages are plain HTML in `firmware/patternflow/console/`, spliced into `*_index.h` by `firmware/toolchain/console_pages.py`. Tooling lives in `firmware/toolchain/` (repo-level scripts) and `firmware/patternflow/toolchain/` (PlatformIO `extra_scripts`, which must stay sketch-relative). Also: `firmware/encoder_test/` (standalone encoder diagnostic) and `firmware/CUSTOM_PATTERNS.md` (pattern authoring guide). - `hardware/` — Hardware designs. `case/` (Blender source in `source/`, STLs by printer bed size, `knobs/`, `legacy_v2/` for the v2.x board, `legacy_lasercut/` for the v1/v2 acrylic drawings, and `remixes/` — community enclosures, one folder each, whose README is its license header), `pcb/` (KiCad 10.0 source, Gerbers per revision, schematic PDF), `bom/` (`bom_v3.9.csv` — **the BOM source of truth**; the guide's table is derived from it. `bom_v3.0.csv` is kept for the previous board). - `web/` — Next.js site at patternflow.work: landing page (`/`, `/pattern`, `/build`, `/inside` are tabs of one view), the interactive guide (`/guide` is a hub over `/guide/build`, `/guide/play`, `/guide/make` and `/guide/audio`, each with a `/ko` twin; one 3D stage in `components/guide/`, the firmware simulator in `lib/guide/`), Pattern Lab (`/pattern-lab`), community (`/community/**`, SQLite + Drizzle + Better Auth, only on the Pi deployment), browser flasher (no page of its own: the **Flash Patternflow** button on `/pattern` and in the Play guide, installing `public/flash/manifest.json` and the images in `public/flash/bin/`; the bare `/flash` redirects to `/guide/play#flash`), the edition shelf (`/editions`; `/variants` redirects there), the feature catalogue (`/features`, reels per feature), device update handoff (`/update`), journal, roadmap. `lib/pattern/` is the pattern runtime and annotations, `lib/lab/` the Pattern Lab, `lib/community/` the community, `lib/ai/` the Gemini client. Architecture doc: `web/ARCHITECTURE.md`. The JS presets in `web/src/lib/presets/` are the source of truth for firmware preset headers. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cf1200a..157ffb33 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to Patternflow -Patternflow is a device, a firmware, a website and a pile of documentation, and people contribute to all of them. This page says where each kind of contribution goes, what checks it meets, and the few rules that are not negotiable. Where to *ask* things is [SUPPORT.md](SUPPORT.md); how we treat each other is [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md); what is where is [docs/REPOSITORY.md](docs/REPOSITORY.md). +Patternflow is a device, a firmware, a website and a pile of documentation, and people contribute to all of them. This page says where each kind of contribution goes, what checks it meets, and the few rules that are not negotiable. Where to *ask* things is [SUPPORT.md](.github/SUPPORT.md); how we treat each other is [CODE_OF_CONDUCT.md](.github/CODE_OF_CONDUCT.md); what is where is [docs/REPOSITORY.md](docs/REPOSITORY.md). ## Where your contribution goes diff --git a/README.md b/README.md index 33d8b887..31b6f71f 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Started by media artist SeungHun Lee ([@engmung](https://github.com/engmung)) in - **[Build](https://patternflow.work/guide/build):** you're soldering one from bare parts, about US$100–200 of them. Or read [BUILD_GUIDE.md](BUILD_GUIDE.md). - **[Play](https://patternflow.work/guide/play):** yours is built. Flash it, put it on your Wi-Fi, learn the four knobs. Or read [First light](#first-light), below. - **[Make](https://patternflow.work/guide/make):** make your own patterns, with or without a Patternflow. Or read [PATTERN_GUIDE.md](PATTERN_GUIDE.md). -- **[Audio](https://patternflow.work/guide/audio):** it plays; now add sound and MIDI with the Audio edition. Or read [AUDIO_GUIDE.md](AUDIO_GUIDE.md). +- **[Audio](https://patternflow.work/guide/audio):** it plays; now add sound and MIDI with the Audio edition. Or read [AUDIO_GUIDE.md](docs/AUDIO_GUIDE.md). ## Where it began @@ -151,7 +151,7 @@ The default firmware is the instrument and nothing else, which leaves the most m | :--- | :--- | :--- | :--- | | **MIDI over Wi-Fi** | The panel is a MIDI port in any DAW (Ableton, Logic, Bitwig); its knobs and buttons map like any controller's (Ctrl-M in Live), and CC and Program Change play it back | Audio | [MIDI in Ableton](docs/midi-ableton.md) · [spec](docs/midi-spec.md) | | **OSC, both ways** | Knobs, presses and pattern switches stream out to Max, TouchDesigner or Resolume; incoming OSC moves the panel exactly like a hand on the knob | Audio | [spec](docs/osc-spec.md) · [Max for Live bridge](integrations/ableton) | -| **Audio-react** | A browser tab's audio in four bands you shape, or a small microphone soldered to the DevKit; every pattern reacts with no audio code of its own | Audio | [AUDIO_GUIDE.md](AUDIO_GUIDE.md) · [extension](tools/patternflow-audio-extension) | +| **Audio-react** | A browser tab's audio in four bands you shape, or a small microphone soldered to the DevKit; every pattern reacts with no audio code of its own | Audio | [AUDIO_GUIDE.md](docs/AUDIO_GUIDE.md) · [extension](tools/patternflow-audio-extension) | | **MQTT** | Both ways, on the broker you already run; two panels on one broker follow each other | Performance | [spec](docs/mqtt-spec.md) | | **HTTP** | Knob state, pattern selection, brightness, status | every firmware | [API](docs/rest-api.md) | @@ -238,9 +238,9 @@ Folder by folder, and what you want to do → where to start: **[docs/REPOSITORY **Guide (interactive):** [Start here](https://patternflow.work/guide) · [Build it](https://patternflow.work/guide/build) · [Play it](https://patternflow.work/guide/play) · [Make patterns](https://patternflow.work/guide/make) · [Sound and MIDI](https://patternflow.work/guide/audio), in English and Korean
**Build:** [Build Guide](BUILD_GUIDE.md) · [Assembly Map](docs/assembly/README.md) · [Panel Compatibility](docs/panel-compatibility.md) · [Hardware files](hardware/README.md) · [v2.x board](docs/legacy/BUILD_GUIDE_v2.md)
-**Play:** [Pattern Guide](PATTERN_GUIDE.md) · [Custom Patterns](firmware/CUSTOM_PATTERNS.md) · [Audio Guide](AUDIO_GUIDE.md) · [MIDI in Ableton](docs/midi-ableton.md)
+**Play:** [Pattern Guide](PATTERN_GUIDE.md) · [Custom Patterns](firmware/CUSTOM_PATTERNS.md) · [Audio Guide](docs/AUDIO_GUIDE.md) · [MIDI in Ableton](docs/midi-ableton.md)
**Extend:** [Feature Guide](FEATURE_GUIDE.md) · [Editions](docs/EDITIONS.md) · [Firmware build](firmware/README.md) · [Web architecture](web/ARCHITECTURE.md) · [HTTP API](docs/rest-api.md) · [OSC Spec](docs/osc-spec.md) · [MIDI Spec](docs/midi-spec.md) · [MQTT Spec](docs/mqtt-spec.md) · [Director → MIDI](docs/director-midi.md)
-**Project:** [Contributing](CONTRIBUTING.md) · [Support](SUPPORT.md) · [Repository map](docs/REPOSITORY.md) · [Changelog](CHANGELOG.md) · [License Summary](docs/LICENSE-SUMMARY.md) · [Manifesto](docs/manifesto.md)
+**Project:** [Contributing](CONTRIBUTING.md) · [Support](.github/SUPPORT.md) · [Repository map](docs/REPOSITORY.md) · [Changelog](CHANGELOG.md) · [License Summary](docs/LICENSE-SUMMARY.md) · [Manifesto](docs/manifesto.md)
**Links:** [patternflow.work](https://patternflow.work) · [Community](https://community.patternflow.work/community) · [Crowd Supply](https://www.crowdsupply.com/engmung/patternflow) · [Releases](../../releases) · [Discord](https://discord.gg/Vr9QtsxeTk) · [Instagram](https://www.instagram.com/patternflow.work) ## What's new @@ -266,7 +266,7 @@ Folder by folder, and what you want to do → where to start: **[docs/REPOSITORY ## Contributing -Builds, documentation fixes, part sourcing tips, enclosure remixes, firmware features and host-software bridges are all welcome. **[CONTRIBUTING.md](CONTRIBUTING.md)** has one table of where each kind goes and what CI runs on it. Questions and ideas go to the **[Discord](https://discord.gg/Vr9QtsxeTk)**, and **[SUPPORT.md](SUPPORT.md)** says where to ask what. Patterns don't come here: publish them from the Pattern Lab to the Community. Galleries, installations and press: [patternflow.work/contact](https://patternflow.work/contact). +Builds, documentation fixes, part sourcing tips, enclosure remixes, firmware features and host-software bridges are all welcome. **[CONTRIBUTING.md](CONTRIBUTING.md)** has one table of where each kind goes and what CI runs on it. Questions and ideas go to the **[Discord](https://discord.gg/Vr9QtsxeTk)**, and **[SUPPORT.md](.github/SUPPORT.md)** says where to ask what. Patterns don't come here: publish them from the Pattern Lab to the Community. Galleries, installations and press: [patternflow.work/contact](https://patternflow.work/contact). ## Story so far diff --git a/AUDIO_GUIDE.md b/docs/AUDIO_GUIDE.md similarity index 90% rename from AUDIO_GUIDE.md rename to docs/AUDIO_GUIDE.md index a6e8536e..197c04ff 100644 --- a/AUDIO_GUIDE.md +++ b/docs/AUDIO_GUIDE.md @@ -15,7 +15,7 @@ OSC ([here](#osc--ableton-today-anything-tomorrow)). The same ground step by step, on a 3D Patternflow in the browser: [patternflow.work/guide/audio](https://patternflow.work/guide/audio). -Like the [Feature Guide](FEATURE_GUIDE.md), this page ends with a section +Like the [Feature Guide](../FEATURE_GUIDE.md), this page ends with a section written for AI coding agents; everything above it is for people. --- @@ -28,16 +28,16 @@ Any of these puts the same firmware on your panel: → Audio → **Install to my panel**. Your browser hands the image to a panel that already runs Patternflow, over Wi-Fi; patterns, networks and settings stay. A DevKit that has never run Patternflow takes the core first, from - **Flash Patternflow** ([BUILD_GUIDE §8](BUILD_GUIDE.md#8-firmware)), and + **Flash Patternflow** ([BUILD_GUIDE §8](../BUILD_GUIDE.md#8-firmware)), and then this. - A release's `patternflow-audio.ino.bin` via the console's `/update` page. - Build it yourself: `./firmware/bundles/build.sh audio` (add `flash ` to send it over Wi-Fi). The edition bundles four features: **OSC** (Max/TouchDesigner/Ableton, see -[`docs/osc-spec.md`](docs/osc-spec.md)), **audio** (the streaming path the +[`docs/osc-spec.md`](osc-spec.md)), **audio** (the streaming path the extension uses), **audio_in** (the microphone and the mapping engine) and -**MIDI** (the panel as a network MIDI port, [`docs/midi-spec.md`](docs/midi-spec.md)). +**MIDI** (the panel as a network MIDI port, [`docs/midi-spec.md`](midi-spec.md)). ## The Chrome extension @@ -47,11 +47,11 @@ locally, and streams four knob lanes to the panel over your LAN. **Install:** it's not on the Web Store — load it straight from this repo. `chrome://extensions` → enable *Developer mode* → *Load unpacked* → pick -[`tools/patternflow-audio-extension/`](tools/patternflow-audio-extension/). +[`tools/patternflow-audio-extension/`](../tools/patternflow-audio-extension/). After pulling a newer copy, press *Reload* on its card there. Reload keeps the mapping you already had, so the starting point described below is a new install's. (Every control is described in its -[README](tools/patternflow-audio-extension/README.md), and so is how to get +[README](../tools/patternflow-audio-extension/README.md), and so is how to get that starting point on an older mapping.) **Use:** open a tab with sound → click the extension → enter your panel's @@ -87,7 +87,7 @@ Boxes map to knobs 1:1 and that's fixed on purpose — K2 *is* knob 2. ## The on-board microphone - + A small PDM microphone soldered to the DevKit lets the panel react to the room itself — no browser, no phone, nothing else running. This is an @@ -187,7 +187,7 @@ and input gain; it leaves the Microphone switch and Auto range as they are. ## The phone app (for filming) -[`tools/patternflow-audio-android/`](tools/patternflow-audio-android/) is a +[`tools/patternflow-audio-android/`](../tools/patternflow-audio-android/) is a small Android app that captures whatever the phone is playing and drives the panel with it. It exists for one job: **filming content** — play a track on the phone (reels, whatever), and the panel reacts to the same audio the @@ -195,7 +195,7 @@ video records. For everyday listening the extension or the mic is the better path. It's not on any store — build and install it yourself; the -[README](tools/patternflow-audio-android/README.md) has the full recipe. It +[README](../tools/patternflow-audio-android/README.md) has the full recipe. It opens the panel's own editor page for configuration, so everything above about boxes and curves applies unchanged. @@ -206,13 +206,13 @@ protocol macOS calls *Network MIDI*). Once a session is up the panel is an ordinary MIDI port in any DAW: four knobs in (CC 20–23 absolute, CC 24–27 relative), four buttons (notes 60–63), a pattern selector (Program Change), and the same four knobs, buttons and pattern changes out as they happen. -The contract is [`docs/midi-spec.md`](docs/midi-spec.md); the walk-through +The contract is [`docs/midi-spec.md`](midi-spec.md); the walk-through with screenshots — connecting on macOS, Windows (rtpMIDI) and Linux, mapping in Ableton, the per-knob sensitivity slider, and telling the panel your computer's address so it reconnects itself after a reboot — is -[`docs/midi-ableton.md`](docs/midi-ableton.md). +[`docs/midi-ableton.md`](midi-ableton.md). -This is the missing half of [`docs/director-midi.md`](docs/director-midi.md): +This is the missing half of [`docs/director-midi.md`](director-midi.md): the Director's `.mid` export writes CC 20–23, so drop the clip on a MIDI track, set the track's output to the panel's port, and the show plays on the panel from Live's transport. The switch on the console's **MIDI** page turns it @@ -223,11 +223,11 @@ sensitivity and message counts under `midi`. The edition also speaks **OSC** — plain OSC 1.0 over UDP, both directions. The ready-made client is the **Max for Live bridge** in -[`integrations/ableton/`](integrations/ableton/): load it in Ableton and +[`integrations/ableton/`](../integrations/ableton/): load it in Ableton and your set and the panel talk to each other. But the bridge is just one client of a written contract, -[`docs/osc-spec.md`](docs/osc-spec.md) — anything that can send a UDP OSC +[`docs/osc-spec.md`](osc-spec.md) — anything that can send a UDP OSC message can drive the panel the same way. TouchDesigner, VCV Rack and Processing speak it natively; Blender does through an OSC add-on or a few lines of Python. Send `/patternflow/ping` once and the device learns your @@ -264,12 +264,12 @@ page says which source has the knobs right now. ## For the AI agent -The hard rules — the same ones humans follow — are in [`AGENTS.md`](AGENTS.md#hard-rules-do-not-violate); the contributor flow is [`CONTRIBUTING.md`](CONTRIBUTING.md). +The hard rules — the same ones humans follow — are in [`AGENTS.md`](../AGENTS.md#hard-rules-do-not-violate); the contributor flow is [`CONTRIBUTING.md`](../CONTRIBUTING.md). You were pointed here to work on Patternflow's audio path. The map: **Firmware — the mapping engine and mic** -([`firmware/patternflow/features/audio_in/`](firmware/patternflow/features/audio_in/)): +([`firmware/patternflow/features/audio_in/`](../firmware/patternflow/features/audio_in/)): | file | role | | --- | --- | @@ -277,19 +277,19 @@ You were pointed here to work on Patternflow's audio path. The map: | `core_audio_pdm.h` | PDM mic driver (GPIO 43/44). Its header comment is the authoritative wiring + driver-choice record. | | `core_audio_fft.h` | FFT and spectrum buckets. | | `core_audio_in_map.h` | Bands, curve LUTs (33-point, interpolate-only), attack/damping glide, auto-range, the defaults a reset restores, NVS persistence. Manual mode maps linearly in amplitude between a band's two edges; the page's dB axis is a conversion at the page's edge. | -| `core_audio_in_http.h` | `/audio-in` (editor page), `GET /api/audio-in` (the configuration, read once), `POST /api/audio-in` (any subset: a request changes only the fields it carries), `POST /api/audio-in/reset` (everything, or one band with `band=N`), the `?levels=1` live poll, and the frame endpoint the phone posts spectra to. The contract is [`docs/rest-api.md`](docs/rest-api.md#microphone-audio-edition); the phone app is a second client of it, so fields are added, never renamed. | +| `core_audio_in_http.h` | `/audio-in` (editor page), `GET /api/audio-in` (the configuration, read once), `POST /api/audio-in` (any subset: a request changes only the fields it carries), `POST /api/audio-in/reset` (everything, or one band with `band=N`), the `?levels=1` live poll, and the frame endpoint the phone posts spectra to. The contract is [`docs/rest-api.md`](rest-api.md#microphone-audio-edition); the phone app is a second client of it, so fields are added, never renamed. | | `audio_in_index.h` | **Generated** — never edit (chain below). | -**Firmware — MIDI** ([`firmware/patternflow/features/midi/`](firmware/patternflow/features/midi/)): +**Firmware — MIDI** ([`firmware/patternflow/features/midi/`](../firmware/patternflow/features/midi/)): `core_midi.h` is the mapping (transport-agnostic: handlers in, a sink out), `core_midi_rtp.h` the RTP-MIDI listener on UDP 5004/5005 over lathoub's -AppleMIDI library. Contract: [`docs/midi-spec.md`](docs/midi-spec.md). +AppleMIDI library. Contract: [`docs/midi-spec.md`](midi-spec.md). `tools/rtpmidi-probe/` exercises the whole map from a PC with no MIDI driver. **Firmware — the stream path** -([`firmware/patternflow/features/audio/`](firmware/patternflow/features/audio/)): +([`firmware/patternflow/features/audio/`](../firmware/patternflow/features/audio/)): `core_audio_ws.h` is a WebSocket server on port 81. The wire contract is -[`docs/audio-ws-spec.md`](docs/audio-ws-spec.md) — clients build against the +[`docs/audio-ws-spec.md`](audio-ws-spec.md) — clients build against the spec, not the source. Probe `GET /api/status` for `"audio"` in `caps`. A lane is released 500 ms after the last message that set it, so a sender that means to hold a value resends it; the spec says which senders in this tree do. @@ -319,7 +319,7 @@ Preview without building: `python firmware/toolchain/console_serve.py` assembles `/audio-in` from those sources on every request and answers its API the way the firmware does; `/mock?audio=music`, `silence`, `off`, `fresh`, `nomic`, `stalled`, `phone`, `ext` and `noread` pick what the panel hears -([`console/README.md`](firmware/patternflow/console/README.md#the-page-that-is-assembled-audio-in)). +([`console/README.md`](../firmware/patternflow/console/README.md#the-page-that-is-assembled-audio-in)). The page has a budget, `BUDGET` in `build_audio_in_page.py`: 17,500 bytes gzipped as the panel sends it. It is the heaviest page in the console and every byte crosses the panel's Wi-Fi, so whole-line comments and indentation @@ -335,7 +335,7 @@ every request rides `PF.poll`/`PF.status`, nothing is saved until the panel's mapping has been read, and a save sends only the fields that changed. **Chrome extension** -([`tools/patternflow-audio-extension/`](tools/patternflow-audio-extension/)): +([`tools/patternflow-audio-extension/`](../tools/patternflow-audio-extension/)): `mapping.js` is the mapping model, one object (`PFMap`): defaults, the curves, level → knob. `editor.js` is the single shared editor module, and `editor-adapter.js` is its extension adapter (chrome storage, the capture's @@ -350,7 +350,7 @@ the panel. The extension keeps its cream skin; only the panel's page wears the console's. **Android app** -([`tools/patternflow-audio-android/`](tools/patternflow-audio-android/)): +([`tools/patternflow-audio-android/`](../tools/patternflow-audio-android/)): `Analyzer.kt` mirrors the extension's analysis and mapping (`offscreen.js` and `mapping.js`); `DeviceLink.kt` speaks the WS contract + syncs panel config over `/api/audio-in` + posts monitor frames; @@ -364,9 +364,9 @@ its WebView is set up without the part that shows a `window.confirm` dialog, which is why the page's Reset mapping is a button pressed twice. Open the app's editor once before releasing a change to `/audio-in`. -Rules of the road: firmware changes follow [FEATURE_GUIDE.md](FEATURE_GUIDE.md) +Rules of the road: firmware changes follow [FEATURE_GUIDE.md](../FEATURE_GUIDE.md) (hooks, checkers, `build.sh all`); protocol changes update the spec in the -same PR; API changes extend [`docs/rest-api.md`](docs/rest-api.md) and never +same PR; API changes extend [`docs/rest-api.md`](rest-api.md) and never rename what is there; editor changes run `console_pages.py build` so the panel's page follows — the editor's body is one file for both surfaces, which is the point. diff --git a/docs/README.md b/docs/README.md index 194891f8..2e19b448 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # docs/ -What is here, and what is not. The rule for the split: **a guide somebody follows start to finish lives at the repository root** (`BUILD_GUIDE.md`, `PATTERN_GUIDE.md`, `FEATURE_GUIDE.md`, `AUDIO_GUIDE.md`); **a contract, a reference, a walk-through for one task, or a record lives here**; and a folder explains itself in its own README. The folder-by-folder map of the whole repository is [`REPOSITORY.md`](REPOSITORY.md). +What is here, and what is not. The rule for the split: **a guide somebody follows start to finish lives at the repository root** (`BUILD_GUIDE.md`, `PATTERN_GUIDE.md`, `FEATURE_GUIDE.md`); **a contract, a reference, a walk-through for one task, or a record lives here**; and a folder explains itself in its own README. The folder-by-folder map of the whole repository is [`REPOSITORY.md`](REPOSITORY.md). ## Contracts — other software is built against these, not against the firmware source @@ -19,6 +19,7 @@ What is here, and what is not. The rule for the split: **a guide somebody follow ## Walk-throughs — one task, start to finish +- [`AUDIO_GUIDE.md`](AUDIO_GUIDE.md) — sound into the panel - [`midi-ableton.md`](midi-ableton.md) — the panel as a MIDI port in Ableton Live, with screenshots - [`director-midi.md`](director-midi.md) — how a Director show becomes a MIDI clip - [`../firmware/CUSTOM_PATTERNS.md`](../firmware/CUSTOM_PATTERNS.md) — the hands-on pattern route (the everyday one is [`PATTERN_GUIDE.md`](../PATTERN_GUIDE.md)) @@ -34,12 +35,12 @@ What is here, and what is not. The rule for the split: **a guide somebody follow ## On the site, not in this folder -The interactive guide at [patternflow.work/guide](https://patternflow.work/guide) has four parts, each in English and Korean: [Build](https://patternflow.work/guide/build) (soldering one from bare parts), [Play](https://patternflow.work/guide/play) (the first hour with a built one: flash, knobs, patterns, console), [Make](https://patternflow.work/guide/make) (community and Pattern Lab) and [Audio](https://patternflow.work/guide/audio) (the Audio edition: a browser tab, the microphone, MIDI with a DAW). They cover the same ground as the guides in the root, and every step has a **Stuck here?** link that opens an issue with that step filled in. +The interactive guide at [patternflow.work/guide](https://patternflow.work/guide) has four parts, each in English and Korean: [Build](https://patternflow.work/guide/build) (soldering one from bare parts), [Play](https://patternflow.work/guide/play) (the first hour with a built one: flash, knobs, patterns, console), [Make](https://patternflow.work/guide/make) (community and Pattern Lab) and [Audio](https://patternflow.work/guide/audio) (the Audio edition: a browser tab, the microphone, MIDI with a DAW). They cover the same ground as the written guides, and every step has a **Stuck here?** link that opens an issue with that step filled in. ## Contributing - [`../CONTRIBUTING.md`](../CONTRIBUTING.md) — one table: what you have → where it goes → what CI runs on it -- [`../SUPPORT.md`](../SUPPORT.md) — where to ask what +- [`../.github/SUPPORT.md`](../.github/SUPPORT.md) — where to ask what - [`REPOSITORY.md`](REPOSITORY.md) — the folder-by-folder map, and the list of files that outside things link to ## Running the project diff --git a/docs/REPOSITORY.md b/docs/REPOSITORY.md index ca5adb6f..6071a2b1 100644 --- a/docs/REPOSITORY.md +++ b/docs/REPOSITORY.md @@ -9,11 +9,11 @@ A map for people. (AI coding agents get the same map with more rules in [`../AGE | `firmware/` | The ESP32-S3 firmware. `patternflow/` is the sketch: `patternflow.ino`, `config.h` (pins, brightness, limits, calibration), `net_config.h` (Wi-Fi, OTA, update defaults), `src/` (the engine: HUB75 driver, encoders, canvas, colour, noise, Wi-Fi, web console — the **core**, compiled unchanged into every published firmware), `features/` (everything optional: OSC, audio, the microphone, MQTT, MIDI, shows, weather, clock, BLE — attached through hooks the core exposes), `presets/` (the curated patterns), `abi/` (the frozen contract a `.pfm` module is compiled against), `console/` (the device's web pages as plain HTML). `bundles/` names the compositions — the shelf editions `audio` and `performance`, plus `clock` and `midi`, which CI keeps compiling but the shelf does not carry — and holds `build.sh` and `shelf.sh`. `toolchain/` is the repo-level scripts: build a module, make the Basics pack, and the `check_*.py` that CI runs. `modules/` is the module toolchain's working folder, not a place patterns are contributed to. `encoder_test/` is a standalone sketch for checking the four encoders, and `CUSTOM_PATTERNS.md` the hands-on pattern route | [`firmware/README.md`](../firmware/README.md) for building; [`EDITIONS.md`](EDITIONS.md) before touching anything | | `hardware/` | `pcb/` (KiCad source, Gerbers per revision, schematic PDF), `case/` (STLs by printer bed size, knob plates, the Blender source, legacy v2 cases, the old v1/v2 laser-cut drawings in `legacy_lasercut/`, and `remixes/` — enclosures other people designed and built, one folder each), `bom/` (the CSV that is the BOM source of truth) | [`hardware/README.md`](../hardware/README.md) | | `web/` | The Next.js site at patternflow.work: landing page, the interactive guide (`/guide`, with `/guide/build`, `/guide/play`, `/guide/make` and `/guide/audio`), Live Editor, Pattern Lab, the community (only on the community host), the browser flasher (the **Flash Patternflow** button on the Pattern tab and in the Play guide; the images it installs are `public/flash/`), edition shelf, feature catalogue, device update handoff, journal, roadmap. The JS presets in `src/lib/presets/` are the source of truth for the firmware's preset headers. The breadboard build guide is a React page here, `src/app/build/breadboard/` | [`web/README.md`](../web/README.md), then [`web/ARCHITECTURE.md`](../web/ARCHITECTURE.md) | -| `docs/` | Contracts other software is built against, how the firmware is put together, walk-throughs, the assembly map, the legacy v2.x build guide (`legacy/`), project records and media | [`README.md`](README.md) | +| `docs/` | Contracts other software is built against, how the firmware is put together, walk-throughs, the audio guide (`AUDIO_GUIDE.md`), the assembly map, the legacy v2.x build guide (`legacy/`), project records and media | [`README.md`](README.md) | | `tools/` | Clients Patternflow ships that run on their own: the audio-react browser extension (also the authoring source of the device's `/audio-in` page), the Android capture app, an RTP-MIDI probe. Also `case-models/`, the scripts that make the /build page's 3D model of each case, the official one and every remix on its case switch | [`tools/README.md`](../tools/README.md) | | `integrations/` | Bridges that run inside or beside someone else's software (Ableton / Max for Live today) and talk to the panel only through the contracts in `docs/` | [`integrations/README.md`](../integrations/README.md) | -| `.github/` | Issue and pull-request templates (including the guide's **Stuck here?** form and **Share your build**), the CI workflows (web, every firmware composition, the core-names-no-feature checks, doc links, community folders carrying their README, console-page sync, firmware release assets, Discord dev-log) and their helper scripts | the header comment of each workflow | -| root | `README.md`, the four guides (`BUILD_GUIDE.md`, `PATTERN_GUIDE.md`, `FEATURE_GUIDE.md`, `AUDIO_GUIDE.md`), `CHANGELOG.md`, `CONTRIBUTING.md`, `SUPPORT.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, `CITATION.cff`, the two license texts and the `LICENSE` pointer, `AGENTS.md` (+ `CLAUDE.md`, a one-line shim) | | +| `.github/` | Issue and pull-request templates (including the guide's **Stuck here?** form and **Share your build**), `SUPPORT.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, the CI workflows (web, every firmware composition, the core-names-no-feature checks, doc links, community folders carrying their README, console-page sync, firmware release assets, Discord dev-log) and their helper scripts | the header comment of each workflow | +| root | `README.md`, the three guides (`BUILD_GUIDE.md`, `PATTERN_GUIDE.md`, `FEATURE_GUIDE.md`), `CHANGELOG.md`, `CONTRIBUTING.md`, `CITATION.cff`, the two license texts and the `LICENSE` pointer, `AGENTS.md` (+ `CLAUDE.md`, a one-line shim) | | The rule for where a document lives: **a guide somebody follows start to finish is at the root; a contract, a reference or a record is in `docs/`; a folder explains itself in its own README.** @@ -26,7 +26,7 @@ The rule for where a document lives: **a guide somebody follows start to finish | Make a pattern | [`PATTERN_GUIDE.md`](../PATTERN_GUIDE.md) — the Pattern Lab, the community, and the device. No local toolchain involved. The same loop as a tutorial: [patternflow.work/guide/make](https://patternflow.work/guide/make). [`firmware/CUSTOM_PATTERNS.md`](../firmware/CUSTOM_PATTERNS.md) is the older, more hands-on route | | Write a firmware feature or cut an edition | [`FEATURE_GUIDE.md`](../FEATURE_GUIDE.md) → [`EDITIONS.md`](EDITIONS.md) → [`features/README.md`](../firmware/patternflow/features/README.md) → [`bundles/README.md`](../firmware/bundles/README.md) | | Control the panel from other software | [`rest-api.md`](rest-api.md) has the table for choosing between HTTP, OSC, MIDI and MQTT; then the spec for the one you chose | -| Put sound into it | [`AUDIO_GUIDE.md`](../AUDIO_GUIDE.md). The browser tab, the microphone and MIDI with a DAW, step by step: [patternflow.work/guide/audio](https://patternflow.work/guide/audio) | +| Put sound into it | [`AUDIO_GUIDE.md`](AUDIO_GUIDE.md). The browser tab, the microphone and MIDI with a DAW, step by step: [patternflow.work/guide/audio](https://patternflow.work/guide/audio) | | Work on the site | [`web/README.md`](../web/README.md) → [`web/ARCHITECTURE.md`](../web/ARCHITECTURE.md) | | Contribute anything | [`CONTRIBUTING.md`](../CONTRIBUTING.md) — one table of where each kind of contribution goes | | Cut a release, run the servers | [`RELEASING.md`](RELEASING.md), [`SERVICES.md`](SERVICES.md) | @@ -43,8 +43,8 @@ Filenames are lowercase with underscores. Tags are `vX.Y.Z`; the firmware source The site, the firmware and the release notes hold absolute `blob/main/…` links into this tree, and none of them is checked by CI. Before renaming or moving any of these, grep `web/src`, `web/content`, `firmware/patternflow/console` and `firmware/patternflow/features/*/*_index.h`: -- `README.md`, `BUILD_GUIDE.md` (the site links its section anchors — §1, §2, §4, §8, §8.2 and §10 when this was written — so a renamed heading breaks them), `AUDIO_GUIDE.md`, `FEATURE_GUIDE.md`, `PATTERN_GUIDE.md` -- `docs/assembly/README.md`, `docs/midi-ableton.md`, `docs/midi-spec.md` (the last two are baked into the Audio edition's console pages) +- `README.md`, `BUILD_GUIDE.md` (the site links its section anchors — §1, §2, §4, §8, §8.2 and §10 when this was written — so a renamed heading breaks them), `FEATURE_GUIDE.md`, `PATTERN_GUIDE.md` +- `docs/AUDIO_GUIDE.md`, `docs/assembly/README.md`, `docs/midi-ableton.md`, `docs/midi-spec.md` (the last two are baked into the Audio edition's console pages) - `docs/EDITIONS.md`, `docs/rest-api.md`, `firmware/README.md`, `hardware/bom/bom_v3.9.csv` - `web/src/app/compliance/` — the `/compliance` URL is printed on the box. Never move, redirect or noindex it. diff --git a/firmware/README.md b/firmware/README.md index c7c29014..5f99ca1f 100644 --- a/firmware/README.md +++ b/firmware/README.md @@ -945,7 +945,7 @@ A remembered pattern that is gone, or that no longer loads, falls back to Origin ## Audio-react, OSC, MIDI, MQTT -None of these is in the core. They are features, and each ships in an edition you install from [the shelf](https://patternflow.work/editions): audio-react, OSC and network MIDI in **Audio**, MQTT in **Performance**. What a client sends is a written contract in `docs/` — [`audio-ws-spec.md`](../docs/audio-ws-spec.md), [`osc-spec.md`](../docs/osc-spec.md), [`midi-spec.md`](../docs/midi-spec.md), [`mqtt-spec.md`](../docs/mqtt-spec.md) — and the guides are [`AUDIO_GUIDE.md`](../AUDIO_GUIDE.md) (sound in, MIDI, OSC) and [`docs/midi-ableton.md`](../docs/midi-ableton.md). The ready-made clients are the audio extension and phone app in [`tools/`](../tools/README.md) and the Max for Live bridge in [`integrations/ableton/`](../integrations/ableton/). +None of these is in the core. They are features, and each ships in an edition you install from [the shelf](https://patternflow.work/editions): audio-react, OSC and network MIDI in **Audio**, MQTT in **Performance**. What a client sends is a written contract in `docs/` — [`audio-ws-spec.md`](../docs/audio-ws-spec.md), [`osc-spec.md`](../docs/osc-spec.md), [`midi-spec.md`](../docs/midi-spec.md), [`mqtt-spec.md`](../docs/mqtt-spec.md) — and the guides are [`AUDIO_GUIDE.md`](../docs/AUDIO_GUIDE.md) (sound in, MIDI, OSC) and [`docs/midi-ableton.md`](../docs/midi-ableton.md). The ready-made clients are the audio extension and phone app in [`tools/`](../tools/README.md) and the Max for Live bridge in [`integrations/ableton/`](../integrations/ableton/). From a pattern's point of view every one of them is the user turning the four encoders: audio bands, OSC deltas and MIDI CCs arrive as `knobDeltas` (or pin a lane on the absolute parameter bus), so an encoder-driven pattern reacts with no transport-specific code. diff --git a/tools/patternflow-audio-extension/README.md b/tools/patternflow-audio-extension/README.md index 664875e0..ebcd3168 100644 --- a/tools/patternflow-audio-extension/README.md +++ b/tools/patternflow-audio-extension/README.md @@ -4,7 +4,7 @@ Captures the audio of a Chrome or Edge tab, splits it into four frequency bands, and sends each band to one of the panel's four knobs over your local network. The panel has to run the **Audio edition** ([patternflow.work/editions](https://patternflow.work/editions)). -[`AUDIO_GUIDE.md`](../../AUDIO_GUIDE.md) is the guide to everything around it; +[`AUDIO_GUIDE.md`](../../docs/AUDIO_GUIDE.md) is the guide to everything around it; the wire protocol is a written contract, [`docs/audio-ws-spec.md`](../../docs/audio-ws-spec.md). diff --git a/web/src/app/features/features-data.ts b/web/src/app/features/features-data.ts index bfd7a9cd..f618868a 100644 --- a/web/src/app/features/features-data.ts +++ b/web/src/app/features/features-data.ts @@ -126,7 +126,7 @@ export const FEATURES: Feature[] = [ where: "In the Audio firmware.", whereHref: "/editions#audio", links: [ - { label: "Audio guide", href: blob("AUDIO_GUIDE.md") }, + { label: "Audio guide", href: blob("docs/AUDIO_GUIDE.md") }, { label: "Source", href: tree("firmware/patternflow/features/audio_in") }, ], reel: { diff --git a/web/src/components/guide/copy/audio.ts b/web/src/components/guide/copy/audio.ts index 988667d9..a4fa90fc 100644 --- a/web/src/components/guide/copy/audio.ts +++ b/web/src/components/guide/copy/audio.ts @@ -15,9 +15,10 @@ import type { GuideLang } from "../store"; // The small print every guide shares is copy.ts's `ui`. The words of the // captures are AudioShots.tsx's, the editor window's are EditorWindow.tsx's. // -// Sources for every fact, and nothing else: AUDIO_GUIDE.md, docs/midi-ableton.md, -// docs/midi-spec.md, docs/audio-ws-spec.md, tools/patternflow-audio-extension -// (its README, popup and editor), the console pages +// Sources for every fact, and nothing else: docs/AUDIO_GUIDE.md, +// docs/midi-ableton.md, docs/midi-spec.md, docs/audio-ws-spec.md, +// tools/patternflow-audio-extension (its README, popup and editor), the +// console pages // (firmware/patternflow/console/_audio_in_bar.html, _audio_in_adapter.js, // midi.html, update.html), web/src/app/editions and the firmware // (patternflow.ino's NETWORK screen, features/midi). UI words are quoted as @@ -318,7 +319,7 @@ const en: AudioCopy = { { label: "The phone app", href: `${GH}tools/patternflow-audio-android/README.md` }, { label: "A Director show as .mid", href: `${GH}docs/director-midi.md` }, { label: "The MIDI map", href: `${GH}docs/midi-spec.md` }, - { label: "AUDIO_GUIDE.md", href: `${GH}AUDIO_GUIDE.md` }, + { label: "AUDIO_GUIDE.md", href: `${GH}docs/AUDIO_GUIDE.md` }, { label: "Editions", href: "/editions" }, { label: "All guides", href: "/guide" }, ], @@ -567,7 +568,7 @@ const ko: AudioCopy = { { label: "폰 앱", href: `${GH}tools/patternflow-audio-android/README.md` }, { label: "디렉터 쇼를 .mid로", href: `${GH}docs/director-midi.md` }, { label: "MIDI 맵", href: `${GH}docs/midi-spec.md` }, - { label: "AUDIO_GUIDE.md", href: `${GH}AUDIO_GUIDE.md` }, + { label: "AUDIO_GUIDE.md", href: `${GH}docs/AUDIO_GUIDE.md` }, { label: "Editions", href: "/editions" }, { label: "가이드 전체", href: "/guide/ko" }, ],