Skip to content

Scanning Recipes

atom edited this page Sep 3, 2026 · 1 revision

Scanning Recipes

A Scanning generator moves through a designed path in an ordinary generator's three-pot control space. Use it when one repeatable macro/low-frequency oscillator (LFO) gesture is more useful than three independent modulations.

Built-in Scanning families need no recipe knowledge. Read the file-format sections when you want to import, share, hand-edit, collect, or author custom Scanning trajectories. The recipe supplies moving Pot1/Pot2/Pot3 coordinates; the selected base generator still supplies the waveform DSP.

First use a built-in Scanning generator

🎹 Before thinking about JSON, try Scanning as an instrument:

  1. In Playground or a Morph endpoint, choose a Scanning – … Generator Family. Changing the endpoint normally starts auditioning it automatically.
  2. While it is sounding, move Scan Centre, LFO Depth, and LFO Rate. If you have stopped the audition, use that endpoint’s Drone button (or P in Playground, S/E in Morph) to resume it.
  3. Open Drawn Waveform and change its shape. When Scanning is consuming Drawn as the LFO, the Drawn summary explicitly says used as LFO shape even if Drawn is not routed as audio. Drawn does not have to be a conventional LFO shape: try a hand-edited step sequence, a mathematical construction, a Fourier/Haar/Walsh-transformed Drawn waveform, browser-decodable audio, or an FWG render imported back into Drawn. Haar's dyadic block structure can be especially obvious when heard as modulation rather than as audio.
  4. Switch Smooth/Crunchy or change Wavetable Type as you would with an ordinary endpoint.

A Scanning family is therefore still an endpoint patch: the recipe supplies a moving path through one base generator's three controls, while the rest of the endpoint signal path remains ordinary FWG.

Recipe grammar

🔧 A standalone Scanning recipe contains:

  1. a human-facing recipe name;
  2. one ordinary base generator;
  3. one trajectory for Pot 1;
  4. one trajectory for Pot 2;
  5. one trajectory for Pot 3.

The path grammar is deliberately small:

  • "scan" — move 0 → 4095;
  • "inverse" — move 4095 → 0;
  • integer 0..4095 — hold one fixed value;
  • [a,b] — move linearly between two valid pot positions.

A useful production example is Scanning – FM – Ratio/Colour Exchange. The built-in holds FM Index high at 3072, scans Modulator Ratio upward, and scans Carrier Colour downward. That gives one fixed value, one scan, and one inverse in a single real recipe. The minimal standalone document that reproduces that production trajectory is:

{
  "schema_version": 13,
  "document_kind": "scanning_recipe",
  "generator": "Fractured Wavetable Generator",
  "scanning_recipe": {
    "version": 1,
    "name": "Scanning – FM – Ratio/Colour Exchange",
    "base": "FM",
    "p1": 3072,
    "p2": "scan",
    "p3": "inverse"
  }
}

The recipe core is production data, not an invented tutorial trajectory. Importing those exact base/Pot1/Pot2/Pot3 coordinates resolves to the built-in Scanning – FM – Ratio/Colour Exchange family. Pot Gang exports the same core inside a fuller standalone document that also carries application identity and a portability note.

A recipe is variant-agnostic: Smooth/Crunchy belongs to the patch using the recipe. A standalone recipe also contains no Drawn waveform. Drawn is patch state, not part of the reusable pot trajectory definition.

Built-in and custom recipes

🔧 Built-in Scanning generators are curated named recipes. A custom recipe uses the same trajectory model.

When an imported recipe exactly matches a built-in trajectory, FWG can resolve it back to the corresponding built-in Scanning family. Otherwise it becomes a session custom entry such as:

Scanning – <recipe name> (Custom)

If two different trajectories have the same recipe name, they are displayed as (Custom 1), (Custom 2), and so on. Importing the exact same named recipe again does not duplicate it. Different names are allowed to describe identical trajectories.

Session-only custom library

⚠️ Custom recipes are kept in RAM for the current page session only. Reloading FWG clears the custom library.

This is intentional. Recipe files are tiny; users who want a large personal library can keep their recipes as files and import a collection when needed.

FWG refuses additions beyond its bounded session library rather than silently evicting older entries. The current limit is 512 custom Scanning recipes per page session.

Importing one standalone recipe

🎹 Use Load JSON… from Playground or either Morph endpoint. Those buttons open FWG's general import router; the button's physical location does not restrict the destination. Loading one standalone Scanning recipe presents exactly three concrete destinations:

  • Playground;
  • Morph START;
  • Morph END.

Choosing any destination also registers the custom recipe in the shared session custom-recipe library, so it becomes available elsewhere in the application—including Explorer—without a separate “add to library” step.

The destination applies the recipe as a generator choice in that endpoint. The recipe itself remains variant-agnostic and does not carry Drawn LFO data.

Recipe collections are different: they are library-oriented because they may contain many recipes and are not one-patch destination actions.

Multiple recipes in one file

🔧 FWG supports a normal recipe collection. The same principle applies to collection examples: use real built-in trajectories when they demonstrate the grammar. This collection contains two production recipes. Sync – Source Exchange demonstrates fixed + scan + inverse; Feedback Sine – Depth/Drive Bloom adds a real bounded path [1642,1070].

{
  "schema_version": 13,
  "document_kind": "scanning_recipe_collection",
  "scanning_recipes": [
    {
      "version": 1,
      "name": "Scanning – Sync – Source Exchange",
      "base": "Sync",
      "p1": 4095,
      "p2": "scan",
      "p3": "inverse"
    },
    {
      "version": 1,
      "name": "Scanning – Feedback Sine – Depth/Drive Bloom",
      "base": "Feedback Sine",
      "p1": "scan",
      "p2": [1642, 1070],
      "p3": "scan"
    }
  ]
}

The importer also accepts concatenated complete Scanning-recipe JSON documents. This permits power-user workflows such as:

cat recipe1.json recipe2.json recipe3.json > several_recipes.json

or:

zcat recipe1.json.gz recipe2.json.gz recipe3.json.gz | gzip -n > several_recipes.json.gz

Concatenated multi-document import is deliberately restricted to Scanning recipes. A malformed middle or trailing document aborts the whole import rather than partially populating the library.

Morph and Explorer portability

🔧 If a Morph/Explorer state actually depends on custom recipes, its exported JSON embeds the required recipe definitions. The recipient therefore does not need to have already imported your local session library.

For current schema 13, those explicit dependencies are validated strictly on import. A patch that selects Scanning – Custom Recipe without a valid embedded recipe, or supplies an invalid custom recipe, aborts visibly rather than silently falling through to a safe unrelated generator. Internal live-state fallback remains a separate render-safety mechanism; it is not used to redefine imported authoritative data.

Explorer lists custom recipes individually. Importing one makes it available, but does not automatically add it to Explorer's random generator pool.

Pot Gang / Recipe Probe

🔧 The hidden Scanning Recipe Probe exports the same canonical Scanning-recipe format. It is revealed by adding the ?potgang=1 query parameter to the FWG page URL; it is a power-user recipe authoring/probing tool, not a second recipe language.

Fractured Wavetable Generator

Start here

🎹 Workspaces

🎹 Build and shape sounds

🎹 Make and keep results

🎹 Scanning and custom trajectories

Help and reference

🔧 Advanced / technical reference

Clone this wiki locally