Measuring plugins
PedalScope measures distortion plugins exactly as it measures distortion pedals: same sweeps, same analysis, same library. An amp sim or drive plugin is a device under test that happens to live in software — pick it, set it, measure it, and its records sit beside your hardware’s, ready to Compare.
The scope is the same as for hardware: drive, distortion, fuzz, amp sims, saturators — devices whose job is nonlinear character. PedalScope is not a general plugin analyzer; reverbs, delays, and modulation are outside what its questions can answer.
Picking a plugin
In the measure flow’s Setup step, choose Plugin as the source — a plugin is a source in its own right, not a row in the audio-device list. The picker opens directly, listing every effect plugin on your Mac, grouped by maker.
Plugins load out-of-process: the plugin runs in its own system-managed process, so a misbehaving or license-locked plugin cannot take PedalScope down with it. A plugin that fails to load is marked in the picker with the reason, and PedalScope will not try it again behind your back — the Retry button on the marked row is the only way back, because retrying an unlicensed plugin usually pops its vendor’s license dialog. A plugin that simply never finishes loading within fifteen seconds is marked separately, as did not finish loading: a license dialog, a system permission prompt and a slow first load all look identical from here, so the mark says what was seen rather than guessing which it was.
Copy-protected plugins (iLok and similar) work: their license checks run in the plugin’s own process. If a plugin’s trial has expired, expect its license window, not a measurement.
Picking a plugin does not touch your audio hardware. Every plugin render is offline — PedalScope opens no audio device, plays nothing, and records nothing — so choosing a plugin never asks for the microphone permission, and a plugin-only user is never asked for it at all.
An Intel-only plugin — one built for the older Mac chip, with no version for Apple silicon — shows a caption in the picker disclosing that fact, but loads normally: macOS transparently translates it (Rosetta) and PedalScope hosts, edits, and measures it exactly like any other plugin. Isolating translation’s own reliability (independently-loaded instances, each measured once, so a plugin’s own preset behavior can’t hide in the comparison — see the next section for that half) found renders that agreed closely: a small, bounded jitter, nowhere near enough to read as broken. One measurement did stall outright and need recovery, and didn’t reproduce on retest — rare enough that this note exists mainly so a stall doesn’t read as user error if it ever happens: if a measurement never finishes, quitting and reloading the plugin is the recovery, not a sign your Mac is malfunctioning.
Occasionally an Intel-only plugin fails to load outright — translation itself didn’t work on this system. That is the “fails to load” case above: marked with the reason, no Retry, same as any other failed load.
The first time you load a plugin from another maker, macOS itself asks whether to lower the security settings for PedalScope (one of the three prompts inventoried under Permissions). That is a normal system consent for hosting a third-party plugin — the same one every audio app triggers — not a sign anything is wrong, and it does not weaken the app beyond allowing that plugin to load. Apple’s own plugins never prompt. A Cancel is not remembered: the picker marks the row, and its Retry makes macOS ask again — and if Retry raises no panel, log out and back in, then Retry (Permissions says why). macOS asks again after every PedalScope update, because it ties the consent to the exact build.
One plugin, many pedals
After you pick a component, PedalScope asks one question it genuinely cannot answer: which pedal is this? The plugin’s identity and version are captured automatically — the name of the library pedal it backs is yours, because for a multi-model host (Helix Native, AmpliTube, BIAS FX) the block is the pedal and the host is a pedalboard. Choose a pedal already backed by this plugin, or create another; one component backing many pedals is normal, not a workaround.
Name the circuit, not the host — “Scream 808 (Helix Native)”, not “Helix Native” — so each pedal’s history, portraits, and Compares stay about one circuit. Two patterns work well, separately or together:
Subject pedals — one pedal per block or circuit you care about. Clean identity, coherent history, and knob controls named after the block’s own parameters if you build a panel for it. This is the tier your keepers live in.
A survey pedal — one deliberate catch-all pedal for a host, with a Model switch control listing the blocks you’re scanning. A family run then walks the switch for quick reconnaissance across many models. Treat its records as throwaway scouting — when a model earns real attention, give it a subject pedal and measure properly.
Single-circuit plugins (a dedicated drive plugin, an amp sim of one amp) need none of this ceremony: the suggested name is the plugin’s own, and one click accepts it.
Existing records never move on their own — reorganizing a library that predates this choice (say, splitting a lumped “Helix Native” pedal into blocks) is a manual library operation, at your pace.
The plugin’s window is the panel
Open Plugin Window shows the plugin’s own interface — that is the control surface, exactly as a pedal’s knobs are. What the window shows when you press Run is what gets measured. Describe the setting in the variant notes the way you’d note a pedal’s knob positions (“Drive 6 · brown channel”).
Your configuration is saved with the pedal entry
The pedal entry owns its plugin configuration. While the plugin window is open, the plugin’s full state is saved to the chosen pedal entry as you configure it — every change, within a couple of seconds — and again when you close the window or start a measurement. Whenever you select that entry again, the saved configuration is applied to the plugin before the window opens or anything renders. Quit the app, relaunch, pick the entry: the plugin shows your configured chain, not its default preset, and a measurement run without ever opening the window renders through the saved configuration. A caption under the pedal row states what happened (“Saved configuration applied…”).
Quitting is safe, and deliberately boring: because the configuration is written as you make it, there is nothing left to save when the app terminates. You can quit with the plugin window still open, quit without ever measuring, or force-quit, and the chain is there when you come back. Nothing has to complete during shutdown — a save that could hang while a plugin is slow to answer would be worse than one that misses.
Two honest edges. An entry that has never been configured-and-saved (one created before this feature, or a brand-new one) has nothing to restore: the caption says so, the plugin opens in its default state, and measuring carries that caution until you open the window and change something — the app never silently adopts a default preset as your saved configuration. (Opening the window and touching nothing writes nothing: what gets saved is what you change from the state the window opened on.) And saved state is version-scoped, like the state archive on records: after a plugin update the caption discloses the version gap, and if the new version refuses the old state outright, measuring into that entry is blocked until you reconfigure and re-save — an honest error beats a different rig measured under your entry’s name.
Two helpers make the describing part cheap. Copy Settings Digest (in the plugin window’s lower panel) puts a readable list of every parameter changed from the plugin’s default state — with the plugin’s own display values — on the clipboard. And next to the notes field in the measure flow, Pre-fill from Plugin offers the same thing as a starting point for your note; the field stays yours to edit, and nothing is ever written into notes without you. One honest limit: multi-model hosts (Helix Native and kin) publish only generic automation slots — “Knob 01”, “Switch 05” — that say nothing about the model graph, so for those the digest says exactly that and leaves the chain description to you. The plugin’s identity and version are recorded automatically either way.
One thing software does better than hardware: the plugin’s version is recorded automatically in every variant label. A plugin update is the same pedal at a new operating point — so “did the 3.9 update change the model?” is answerable directly: measure before, update, measure again, Compare.
If a plugin's window looks disconnected
A few plugins (some amp sims run their processing in a separate helper engine) show their editor as blank or flash a “can’t reach the engine” message for a moment when the window first opens — PedalScope holds the plugin live while its window is up specifically to avoid this, but if you ever see it, close the window and reopen it, or just run a measurement: the plugin is fully connected during measurement regardless of what the editor showed.
The level-match meter
Hardware has Live Mode for setting levels by ear and eye; plugins can’t — PedalScope never processes live audio through a plugin. What the plugin window gets instead is a small output-level meter under the plugin’s own view: a half-second reference tone (A3 at the standard −26 dBFS drive) rendered offline through the current settings, re-rendered as you move the plugin’s controls. Nothing plays out loud; it’s the measurement path in miniature.
Its real job is level-matching before a Compare. Pick a stored Compression measurement as the match target — usually the hardware pedal you’re comparing against — and the meter shows the signed gap between the plugin’s output and that record’s touch-response curve at the very same tone and drive (”+27.1 dB to go”). Turn the block’s volume until the gap is within a dB, then measure: the Compare’s level axes will actually line up, so what’s left on the charts is character, not volume. (Louder always sounds better — matching levels first is what makes a comparison mean something.)
Levels: the drive axis is the whole story
There are no cables, no converters, and no volts here — drive levels are exact digital dBFS at the plugin’s input. The flip side: every plugin model assumes something about how hot a guitar signal is, and nothing enforces that assumption. Where you sit on the drive axis is the entire “how hard am I hitting it” story, so the Gain Map and Compression measurements — which sweep that axis — are the most revealing things you can run on a plugin.
The plugin drive ranges default wider than hardware’s (down to −80 dBFS and up to full scale): a high-gain amp sim can reach full saturation 35 dB below where a pedal would, and some models keep changing right up to 0 dBFS. Digital full scale is a legal, exact drive level — there is no converter to protect.
Calibration still exists here, but it is never your step: the render path is a constant — no cables, no knobs, nothing to stage — so PedalScope measures it by itself the first time a plugin run needs a baseline at the session’s sample rate, and just says so in a progress line. The resulting “Plugin render path” baseline sits in the calibration manager like any other (see calibration), so every downstream number rests on the same provenance chain as a hardware measurement. Each capture’s latency is measured from the audio itself, never taken from the plugin’s self-reported value.
For the curious: how exact is a render?
Renders through a given plugin at a given setting are deterministic to at or below −59 dBFS RMS between runs. Many plugins are bit-identical; some amp sims add internal noise or dither, which is real device behavior and averages out across pooled tracks exactly as interface noise does. Apple’s built-in Audio Units are bit-identical run to run, which is why the test suite uses them as fixtures.
An aliasing check nobody else does
Measure the same plugin setting at 48 kHz and again at 96 kHz, then Compare. A properly oversampled plugin measures the same at both rates; a plugin that aliases does not — its harmonic pattern shifts with the session rate. That rate-invariance check is meaningless for an analog pedal (it has no sample rate) and quietly damning for software. With plugins, the existing two-rate workflow becomes a genuine instrument — on a static chain. Read on before trusting a shift as aliasing.
Default presets can be time-variant
A large multi-model host (Helix Native, AmpliTube, BIAS FX and kin) often opens on a full rig — amp, cab, modulation, delay, reverb — not one static circuit, and some of those blocks are time-variant by design: an LFO, an envelope follower, a reverb tail still ringing. Measure that default state twice in a row and the two captures can disagree by tens of dB, not because anything is broken but because the second capture lands on a different point of the same moving target the first one caught — and the same effect can pass for an aliasing failure in the previous section’s check, since 48 kHz and 96 kHz renders will land on different points too, for a reason that has nothing to do with sample rate.
A real case makes the shape of it concrete: two identical captures of the same untouched instance, same default preset, disagreed by over 20 dB — while two freshly-loaded instances, each measured once at the same setting, agreed to a fraction of a dB. The divergence lives entirely in the moving-target default state, not in loading the plugin twice, and not in translation (see the previous section, for an Intel-only plugin specifically) — it shows up identically on a native plugin with a similarly busy default preset.
Neither the plugin’s parameter tree nor its factory-preset list is guaranteed to offer a way back to a static chain — a multi-model host’s real presets often live in a format the standard plugin API can’t see, the same coarse-surface limit the settings digest already discloses. The reliable fix lives inside the plugin’s own window: dial in (or recall) a setting with the time-variant blocks off or parked, then confirm it by measuring the same setting twice. Two Harmonic Distortion runs that read the same is the confirmation — treat a default-state measurement of a complex host as a starting point, not a comparison-grade result, until you’ve done that check once.
The app runs the core of that check for you, automatically: before every plugin run it renders the same short probe twice through the same live instance and compares — the stationarity pre-check. Renders that agree (within −50 dBFS rms of each other) are recorded as a quiet note under the run button, so the run’s provenance carries the evidence. Renders that disagree stop the run with the delta quoted: the chain is time-variant, and measurements of it will not be comparison-grade. You can measure anyway — the results describe one pass of the moving target, not the device — but the honest move is to park the moving blocks first and let the pre-check confirm the chain went still. Hardware runs have no equivalent check (repeating a sweep through a real pedal is not free the way an offline render is), which is one more reason the two-runs-agree ritual above stays in the protocol.
One subtlety the pre-check now accounts for: the first render after a saved configuration is applied is not the chain speaking — it is the instance starting up. Measured on a static one-block Helix chain, the first post-apply render disagrees with the second at around −42 dBFS rms (well past the threshold) while the second and third agree at the chain’s own noise floor; waiting — even hours — changes nothing, because the transient lives in the first render pass, not in elapsed time. The pre-check therefore renders one discarded warm-up pass before the two it compares, so a genuinely static chain passes and a genuinely time-variant one still fails. (A chain that failed the old check for this reason and was measured anyway is fine: the pre-check’s own renders had already settled the instance before the sweep ran.)
The verdict itself is now part of the record: every plugin record carries a pre-check chip next to its version chip — the measured A/A delta on a pass, an orange flag when the run was measured through a failed gate (“read these results as one pass, not the device”, now stated by the record itself), and “pre-check not recorded” on records that predate the stamp. Never a fabricated pass.
The same initiation also measures the plugin’s declared noise floor, from two measurements at once. A short silence render through the settled chain gives the chain’s floor with nothing in — but some plugins generate most of their noise with the signal (Helix’s chain reads exact silence around −93 dBFS rms yet disagrees with itself at about −62 dBFS rms while a tone plays), so a silence render alone can understate the operative noise by 30 dB. The pre-check’s own A/A comparison is an in-signal noise measurement at the run’s drive — two renders carrying independent noise disagree by exactly that noise plus 3 dB — and the declared floor is the higher of the two components. Plugin measurements run over a numerically silent render path, but the plugin itself is often not silent, and before this probe those records were read as if measured over digital silence. The Distortion-vs-Level chart reads against the declared floor exactly the way hardware records read against their capture’s noise stamp: segments within 6 dB of it draw dotted (THD+N territory), reads at or below it draw as bounds, and the chart names which floor it drew — including which component set it. A stock Apple plugin declares a digitally silent floor — exact zeros in the silence render, bit-identical A/A renders — and its chart honestly draws no floor line at all. Both components and their capture times live in the pre-check panel behind the chip.
The declared floor is what the rest of the instrument reads too. On the Gain Map, cells that sit at the plugin’s own render noise now dim and the Peak distortion tile becomes a bound, exactly as they do for a hardware record at the interface’s noise floor. In Compare, the fingerprint distance clamps both sides to the worse of the two floors — so a plugin’s harmonics that live below its own noise no longer contribute a gap the measurement cannot resolve. Expect distances involving a plugin record to read smaller than they did before that floor was declared: the part of the gap that was numerical dust is no longer counted, and what remains is what both subjects can actually resolve. Records measured before the app began declaring plugin floors carry no such stamp; their charts read as they always did, and their numbers should be re-measured rather than compared against post-stamp ones.
What the record captures about settings
Click the version chip on a plugin record to see everything the app captured about the plugin’s settings at measure time. Two distinct mechanisms feed that panel, and they promise different things:
The parameter tree. Where a plugin publishes its parameters through the standard plugin API — most single-purpose drives and EQs do — PedalScope captures the whole tree (each parameter’s address, name, and value, rendered the way the plugin’s own UI shows it) at the moment the measurement renders. That listing is genuinely better provenance than a hardware knob photo: it is exact, automatic, and readable. But a large multi-model host publishes generic automation slots (“Knob 01”, “Switch 12”) instead of its model graph, and the panel says so rather than presenting the slot list as the sound — for those plugins the chain description belongs in your notes, exactly as the settings digest suggests.
The state archive. Alongside the tree, the app captures the plugin’s full state blob — an opaque archive in the plugin’s own format. It is an exact restore point for that plugin version: a future version of the same plugin may read it differently or not at all, which is why the panel labels it “version-scoped” and never presents it as a parameter listing.
Neither mechanism guarantees a future measurement will reproduce this one — the panel states what was captured, and the two-runs-agree check above remains how you confirm a chain is measurement-stable. A plugin that publishes no parameters at all is recorded as exactly that (“publishes no parameter tree”), which is itself provenance; records made before parameter capture shipped simply say no listing was captured.
Inspect settings — the archive, shown in the plugin’s own window
Inspect settings on a plugin record opens the plugin’s own interface on a fresh inspection copy of that record’s state archive. The copy is fully interactive — that is the point: a multi-block host only reveals a block’s parameters when you select it, so reading the chain means navigating it. A banner above the view states what you are looking at: reconstructed by the plugin version installed now from the version recorded on the record — calm when the two match, marked in orange when they differ (a newer version’s reading of an older archive is an interpretation, not a photograph). Nothing you do in the inspection window is saved: the copy is discarded on close, and the record’s stored archive is never written back.
The failure paths are stated, never papered over. If the plugin isn’t installed on this Mac, or the current version refuses the archived state, Inspect says so — it will not show you a default chain wearing the record’s name.
Plugin-UI screenshots
The state archive needs the plugin to be read; a screenshot of the plugin’s window needs nothing. Plugin records carry a screenshot well — durable visual evidence that travels with exports and stays readable on a machine where the plugin was never installed.
Three sources feed it, and every image is labeled with its source and capture time:
Auto at measurement. If the plugin’s settings window is open when you start a measurement, the app renders it into the record automatically — the image then coincides with the state snapshot, which is what makes it provenance. Window closed at initiation means no image, honestly: the well says none was captured rather than showing anything stale or synthetic. Starting a measurement never asks for the Screen Recording permission below: if the grant isn’t already there, the automatic capture is skipped and a note beside the run says so. A permission panel is a modal that stops everything until someone clicks it, and nothing on the measurement path may wait on one.
The settings window. Capture Screenshot in the plugin window’s panel renders the current view; it attaches to the next measurement you store. A multi-block chain cannot show every block at once — select a block, capture, select the next, capture again.
The inspection view. The same button in an Inspect window attaches the image directly to the record being inspected, labeled as an inspection-view capture (the current version’s rendering, not the view at measure time).
One permission to know about: plugins are hosted out-of-process (a crash-isolation choice), which means their windows are drawn by a helper process that PedalScope’s own renderer cannot see into. Capturing them goes through macOS’s window capture instead, which asks you to grant PedalScope Screen Recording (System Settings → Privacy & Security → Screen & System Audio Recording) the first time — a one-time grant, used only when you capture a plugin window, and one that captures PedalScope’s own window and nothing else (Permissions has the detail, including what to do when Settings says it is granted and capture is still refused). The asking happens where you clicked: the Grant… button on the notice that appears under the plugin’s view when the permission is missing, or the capture buttons in the plugin and Inspect windows. That notice is the point — you learn what a screenshot needs, and that granting it costs a relaunch, before you configure a chain rather than after. Your configuration is saved to the entry as you make it, so relaunching then loses nothing. Until it’s granted, the capture button says exactly that; and if a capture ever comes back as a blank field, PedalScope detects it and tells you rather than storing a blank image as evidence.
Honest limits
A plugin measurement characterizes that version, at that setting, at that sample rate. The variant label carries all three.
Offline rendering asks the plugin to process faster than real time. Plugins are built for this (it is how DAW bounces work), but a plugin whose output depends on wall-clock time rather than audio time would measure differently than it plays.
PedalScope measures what comes out of the plugin — never what its marketing says, and never whether it “sounds like” the hardware it models. Measure the hardware too, and let Compare answer that.