Skip to content

Schematics

Every effect that borrows from a circuit, that is every effect with circuit notes, has a KiCad schematic of it. A schematic makes the circuit notes easier to check: which part sits where, which RC pair sets which corner frequency, and which values are sourced and which are inferred or chosen. It is redrawn from the public sources listed in the circuit notes, never a copy of someone else's drawing, because a third party's drawing has its own copyright.

The drawing is the modelled circuit, the one src/<name>.dsp implements, not a trace of the hardware. Where the model departs from the hardware (a missing schematic, a digital filter, a control the pedal doesn't have), the sheet draws the model and its note says so. A digital filter with no circuit behind it is drawn as a standard analogue stand-in, all of whose parts are chosen.

The schematics so far:

Effect Sheets Basis
BassDrive 8 No public schematic of the reference pedal; mostly inferred and chosen
BassPreamp 8 A public trace of the earlier version, with its designators; a chosen stand-in for the later version's EQ
MidHump 6 Published analyses of the reference circuit, plus MidHump's Blend and its modelled tone stage
BassEras 11 No public schematic of the reference pedal; every stage an analogue stand-in for the DSP, all chosen
BassGrit 7 A public parts list and schematic, plus BassGrit's band split (an analogue stand-in) and Low Blend

Generated from a script

Each schematic is generated by a Python script, tools/schematics/<name>.py, which describes the parts, their values, confidence and source, and where they go. The script is the source: never edit the .kicad_sch files by hand, because the next generation overwrites them. Open them in KiCad to read or check them, then change the script.

make schematic-sources FX=<name>   # regenerate docs/<name>/schematics/ from the script
make schematic-check               # fail if a committed schematic differs from its script

The scripts use tools/schematics/kicadsch.py, which looks after the conventions below, and tools/schematics/stages.py, which has the blocks the effects share: the supply-and-bias sheet, a graphic-EQ boost/cut band and a series chain to ground.

  • Symbols are copied from the stock KiCad libraries installed on the machine (KICAD_SYMBOL_DIR, by default /usr/share/kicad/symbols), rewritten into KiCad 8 syntax so the files open in KiCad 8 and later. Generation therefore needs kicad-library (or the docs image), but not kicad-cli.
  • Pins are found from the symbol definitions, so a script wires part["2"] to opamp["-"] rather than computing coordinates.
  • Checks. The script stops if a confidence or source is malformed, a designator is used twice, a pin is left unconnected, a wire end is dangling, or a part runs off the page or into the title block.
  • Values are checked too. Each script calls expect() on the corner frequencies, gains and Q factors that its parts give, against the circuit notes and the DSP constants, so a drawing can't drift from them silently. For example, BassDrive's script checks that R31 and C10 give 1.46 kHz and that its EQ stand-in centres the bass band on 110 Hz.
  • Byte-identical output. UUIDs are derived from the project, sheet and item (uuid5), so regenerating an unchanged script gives the same files, and make schematic-check can compare them.

File layout

tools/schematics/<name>.py       the generator script (committed, MIT)
docs/<name>/schematics/
├── <name>.kicad_pro             project file (generated, committed)
├── <name>.kicad_sch             root sheet: the block diagram (generated, committed)
├── 1-supply-and-bias.kicad_sch  the 9 V supply and the bias rail VB
└── 3-pre-emphasis.kicad_sch     one sub-sheet per stage (generated, committed)
  • The root sheet is <name>.kicad_sch, next to a <name>.kicad_pro of the same name. It holds the block diagram of the circuit notes' overall topology: one hierarchical sheet per stage, wired through their pins, between the input and output jacks.
  • Each stage's sheet is numbered and named like the section of the circuit notes it draws, for example "3 Pre-emphasis" in 3-pre-emphasis.kicad_sch. Sheet 1, "Supply and bias", holds the supply with its PWR_FLAGs and the half-supply bias rail VB, which the other sheets reach through a global label.
  • The .kicad_sch and .kicad_pro files are committed, so the drawings can be opened and diffed without running anything. .gitignore keeps out KiCad's local settings (*.kicad_prl), backups (*-backups/), caches (fp-info-cache) and autosaves.

Symbols

Only the stock KiCad symbol libraries are used (Device, power, Simulation_SPICE, Switch, Connector_Audio and so on), so that no custom library needs licensing. KiCad copies each symbol it uses into the schematic file, so the drawing renders without the libraries installed. Op-amps are the ideal Simulation_SPICE:OPAMP, with its supply pins tied to +9V and GND.

The KiCad libraries are licensed under CC-BY-SA 4.0 with an exception: for designs that use the library material, and the files generated from them, the copyright holders waive the share-alike condition. A schematic that places stock symbols can therefore carry its own licence, which here is CC-BY-4.0 like the rest of docs/. See the KiCad library licence for the exact wording. The generator reads the libraries where they are installed and does not redistribute them.

Confidence and sources

Every component carries two custom fields, shown on the sheet under its reference and value:

Field Value
Confidence documented, reported, inferred or chosen, as defined at the top of the circuit notes
Source the circuit notes' reference number, e.g. [2] or [2], [4], or - for a chosen value

When one part rests on claims of different strength (a reported value in an inferred position, say), Confidence gives the weaker one.

Every inferred or chosen part is drawn inside a dashed rectangle that encloses its symbol and fields. Documented and reported parts have no outline, so the guesswork stands out on the rendered sheet. A text note at the bottom of each sheet says what was inferred or chosen and why, in one line per part or group, and points to the section of the circuit notes. Corner frequencies, gains and Q factors appear as text next to the parts that set them.

Designators

Designators match the ones in the circuit notes and their sources (R31, C10, IC2_C …). Parts that have no designator there put an X after the type prefix: RX1, CX1, RVX1, UX1, JX1. They are numbered from 1 within each project. Most are parts the notes add, with no counterpart in the sources, and those are always chosen or inferred. A few are sourced parts the notes name only by their role, such as MidHump's 510 kΩ input bias resistor or BassPreamp's Presence pot, and keep their reported confidence.

Title block

Field Content
Title the effect's neutral name, plus the stage on a sub-sheet ("BassDrive: 3 Pre-emphasis")
Company "Redrawn from public sources; see circuit notes"
Comment 1 "Licence: CC-BY-4.0"
Comment 2 the reference hardware, named for identification only
Comment 3 a key to the dashed outline
Comment 4 that this is the modelled circuit, and how it relates to the hardware

The reference product name may appear only to identify the hardware, as in the circuit notes (ground rule 2). The plugin and file names stay neutral.

Adding a schematic

  1. Copy the script of the effect closest to yours, rename it tools/schematics/<name>.py, and set the project name, title, reference hardware and caveat.
  2. Add one function per section of the circuit notes that has component values. Use the notes' designators and values; for anything chosen, use the value of the DSP constant it stands for. Call expect() on every corner frequency and gain the notes quote.
  3. Run make schematic-sources erc schematics FX=<name> and read every rendered sheet in build/schematics/<name>/: overlapping text, crossed wires and outlines that clip their neighbours are layout bugs the checks don't catch.
  4. If drawing the circuit shows that the notes and the DSP disagree, or that a stage doesn't work as described, add it to the notes' open questions rather than silently changing either.
  5. Embed each sheet next to the section it illustrates in the circuit notes, and the root sheet under Signal path on the effect's page.

Licensing

REUSE.toml already licenses everything under docs/ as CC-BY-4.0, so the KiCad files need no SPDX header. The generator scripts under tools/ are code, so they are MIT with SPDX headers. reuse lint (the reuse pre-commit hook) checks both like any other file.

Building

KiCad is large, so it lives in its own image, Dockerfile.docs, together with Faust, Node.js and MkDocs. The docs workflow builds the site in it.

make schematic-sources         # regenerate the committed schematics from their scripts
make schematic-check           # check the committed schematics are up to date
make erc                       # KiCad's electrical rules check on each schematic
make schematics                # one SVG per sheet into build/schematics/<name>/
make test web schematics docs  # the whole site, schematics included

# the same in the docs image
make container DOCKERFILE=Dockerfile.docs IMAGE=pedalkit-docs RUN="schematic-check erc schematics"

All four targets take FX=<name>. schematic-sources and schematic-check fail with an install hint if the stock symbol libraries are missing, and erc and schematics if kicad-cli is (Arch: pacman -S kicad kicad-library).

  • make schematic-check regenerates into build/schematics-check/ and compares. It also fails if an effect has circuit notes but no script. The schematics-present pre-commit hook makes the same presence check without KiCad.
  • make schematics runs kicad-cli sch export svg on the root sheet. The file names are lower-cased with spaces turned into hyphens, giving <name>.svg for the root sheet and <name>-<sheet>.svg for each sub-sheet.
  • make erc fails on any ERC error, such as an unconnected pin, an undriven input or a power pin with no source. Warnings, such as a library missing from a fresh KiCad configuration, go to build/schematics/<name>/erc-all.rpt.

tools/mkdocs_hooks.py publishes build/schematics/<name>/*.svg on the site as schematics/<name>/, so a page embeds a sheet with:

![Stage 3: pre-emphasis](../schematics/bassdrive/bassdrive-3-pre-emphasis.svg)

The SVGs are generated, so they are never committed. A missing schematic is not a warning in itself, but a page that embeds a sheet that wasn't rendered fails the strict build on its broken link.