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 needskicad-library(or the docs image), but notkicad-cli. - Pins are found from the symbol definitions, so a script wires
part["2"]toopamp["-"]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, andmake schematic-checkcan 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_proof 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 itsPWR_FLAGs and the half-supply bias railVB, which the other sheets reach through a global label. - The
.kicad_schand.kicad_profiles are committed, so the drawings can be opened and diffed without running anything..gitignorekeeps 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¶
- 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. - 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. - Run
make schematic-sources erc schematics FX=<name>and read every rendered sheet inbuild/schematics/<name>/: overlapping text, crossed wires and outlines that clip their neighbours are layout bugs the checks don't catch. - 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.
- 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-checkregenerates intobuild/schematics-check/and compares. It also fails if an effect has circuit notes but no script. Theschematics-presentpre-commit hook makes the same presence check without KiCad.make schematicsrunskicad-cli sch export svgon the root sheet. The file names are lower-cased with spaces turned into hyphens, giving<name>.svgfor the root sheet and<name>-<sheet>.svgfor each sub-sheet.make ercfails 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 tobuild/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:

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.