ASIO notice: ASIO support is currently experimental and may have device enumeration, channel pairing, or recording issues with some drivers. For reliable measurements, use WASAPI on Windows unless you have verified your ASIO setup locally.
DMS Fastgraph is a PyQt6 desktop app for headphone frequency-response
measurement. It plays log sweeps through sounddevice, records the fixture
response, plots live/kept curves with pyqtgraph, supports HRTF compensation,
and can export or upload TXT measurements for Squiglink workflows.
Current beta version: 0.3.5
The former Console tab is now Automation. It keeps the diagnostic console on the left and adds an Events builder on the right for local, Blockland-style workflow automation.
Automations are saved as individual .fastgraph-automation.json files in a
local folder, defaulting to Documents/Fastgraph Automations. The Events panel
loads that folder as a library and lets users build rows from typed dropdown
actions, conditions, prompts, variables, tab navigation, input device/channel
selection, measurement actions, R&D actions, Curator actions, and export
actions. Risky hardware, file, and review actions ask for confirmation unless a
step explicitly skips that confirmation.
The Automation tab also includes a Guide button. Opening it temporarily replaces the console pane with a cheat-sheet, action reference, and example automations while leaving the Events editor visible on the right.
Fastgraph now has customizable keyboard shortcuts. Defaults include Enter to
start a measurement in the active Measure or R&D workspace, F to fail/redo a
reviewed sweep, and Shift+1 through Shift+5 to switch between the main tabs.
Shortcut bindings can be edited or reset from the right side of Settings.
The R&D tab now includes a between-viewport smoothing control with 1/48,
1/24, 1/12, 1/6, and 1/3 options. The selected smoothing applies to R&D
plotting, TXT export, and Send to Curator while leaving saved raw session curves
unchanged.
R&D also adds bottom-viewport Delta Mode. When enabled, the first bottom item is used as the reference and later bottom-visible measurements or Var bands are shown as deltas from that reference. The top viewport remains normal.
The R&D measurement list now has a more obvious vertical scrollbar and supports measurement multi-select. Ctrl/shift selection can be used to pick measurements, and New Group moves the selected measurements into a new group in visual order.
R&D session HRTF selections now save both the original file path and the HRTF
name. When a session is opened on another machine or install folder, Fastgraph
tries to reconnect the selection to a matching file in the current HRTFs
folder. If an HRTF is still missing, the R&D status line and row dropdown show
that clearly, and export/Curator transfer is blocked until the row is changed to
an available HRTF or None.
R&D Var behavior is stricter: when a group has Var enabled, its original traces are hidden even if there are not yet enough measurements to draw the band. The status line reports that the group needs at least two measurements. The group Bottom toggle continues to show the full group in the bottom viewport.
R&D groups now draw Var with the same confidence-style band used by Measure and Curator: p10-p90 outer fill, p25-p75 inner fill, and a median line. When a group's Var is active, the band replaces that group's individual traces in that viewport. Multiple visible group variation bands use distinct colors.
The R&D tab also adds top-of-viewport preference bounds, an importable custom session target with its own dB offset, row-level Curator-style dB offsets for measurements and groups, and a default HRTF dropdown next to the R&D Measure button. Group and measurement offsets are additive, so a group can shift a whole prototype set while individual measurements can still be fine-tuned. New R&D measurements inherit the default R&D HRTF selection when they are kept.
R&D session saves include the new offset, target, HRTF, and preference-bounds
state. Older R&D session files still load with offsets set to 0 dB, no target,
and bounds off.
Fastgraph now includes an R&D tab for exploratory single-sweep measurement sessions. R&D measurements are kept as individual named entries with metadata, input/channel identity, notes, milestone flags, per-measurement HRTF selection, top-view visibility, and bottom-view visibility. Measurements can be organized into named groups with group notes, show/pin controls, milestone marking, and optional group variation bands.
R&D group variation follows the viewports where the group is visible: Show
controls top-viewport group visibility, Bottom controls bottom-viewport
group visibility, and Var adds the variation band only to those active
group viewports. R&D sessions can be saved and loaded as .fastgraph-rnd.json
files; Settings includes a default folder for those session files.
Selected R&D measurements and groups can also keep photo notes. Use Capture
to take a webcam photo or Import to attach an existing image, then click a
thumbnail to view, caption, or remove it. Photos are saved as compact JPEGs in
a sibling <session-name>.attachments folder, so move or copy that folder with
the .fastgraph-rnd.json file when sharing a session.
R&D exports operate on the selected measurement or group. Measurements export as TXT, groups with variation enabled export as variation TXT, and selected measurements or group variations can be sent directly to Curator.
Fastgraph now includes Curator, a graph image generation tool for comparing headphone frequency-response and variation-band measurements and turning them into presentation-ready graph images. Curator lives between the Measure and Automation tabs, shares Fastgraph's HRTF library and theme, and reports its actions to the same diagnostic console.
The Measure tab can send its current average or variation view directly to Curator. The transferred layer receives an editable 1 kHz offset so it sits at 0 dB without changing the source data or frequency-response shape. Any active HRTF remains selected and can be changed or removed in Curator.
python -m venv .venv
# macOS/Linux:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate
pip install -r requirements.txt
python main.py- Standard mode plays a short DAC/headphone wake primer, waits 0.24 seconds, waits the configured pre-sweep silence, then plays the sweep. Alignment stays sweep-correlation based with SNR reporting; no coded timing markers or Bluetooth drift retries are used.
- Bluetooth Headphone Mode applies Bluetooth-safe timing defaults, keeps coded start/end timing markers around the sweep, reports timing diagnostics, and can allow marginal drift to reach review with a visible warning when marker evidence is still usable. If end markers are missing or weak, it can use a guarded sweep-correlation fallback when sweep confidence, SNR, and sweep-window match checks are strong enough; fallback runs are clearly marked with a warning before review.
- Bluetooth mode is reversible: custom standard-mode measurement settings are restored when Bluetooth mode is turned off.
Drop one or more local .txt measurement files onto the top plot to import
them as kept curves without live fixture hardware. Files should contain two
columns: frequency in Hz and magnitude in dB. Whitespace- or comma-delimited
REW-style text is accepted; comments/header rows are skipped when possible.
The Measure tab contains the normal measurement interface. Input level, bottom-view controls, Undo, and the guarded Clear All action sit between its two plots. Export directory, TXT export, Curator transfer, and Squiglink upload sit below the bottom plot. Send to Curator adds the currently selected average or variation view to the Curator workspace and switches to that tab. The new layer is offset to 0 dB at 1 kHz without changing its source data or frequency-response shape, and its HRTF selection remains editable.
The tab header keeps the current headphone and rig visible alongside Headphone Metadata, Clear Metadata, and Bluetooth mode controls. These application-wide controls remain available while moving between Measure, R&D, Curator, Automation, and Settings.
The R&D tab is a single-sweep exploratory measurement workspace. New kept measurements default to the top viewport, can be shown in the bottom viewport, and can be grouped for product-development comparisons. Groups support notes, show/bottom toggles, milestone marking, drag/drop organization, optional confidence-style variation bands, and additive dB offsets. Each measurement can choose its own HRTF from the shared HRTF library and can be shifted with its own dB offset. R&D sessions save processed measurement curves and workspace state to JSON; raw recordings are not saved.
R&D measurement, input-channel, HRTF, target, and bounds controls share a responsive toolbar above the plots. Session and export actions sit below the bottom viewport, and the Notes panel can be collapsed to give the measurement list more room. The R&D and Measure input-channel selectors stay synchronized.
The Curator tab is a graph image generation tool. It imports and compares two-column frequency-response TXT files and six-column Fastgraph variation exports, with per-layer visibility, color, offset, and HRTF controls. It also supports combined variation layers, optional preference bounds, fixed graph presentation controls, and composed 1920x1080 PNG export. Curator state is kept only for the current application launch.
TXT files can also be dropped directly onto Curator. Its right-side layer list supports editable measurement names, while View provides fractional-octave smoothing and an optional color-keyed name legend shared by the preview and PNG export. Long export titles automatically shrink and elide to stay in frame.
The Automation tab shows live application, device, sweep, processing, Curator, automation, and timing diagnostics in the left console pane. The right Events pane manages local automation JSON files, row-based workflow steps, and manual/app-event triggered runs. The Guide button swaps the console pane for an in-app cheat-sheet and examples until it is closed. Console history is kept in memory only for the current launch.
Type help in the Automation console for safe Fastgraph commands. Available commands can
inspect status, devices, settings, and the latest diagnostics; apply temporary
measurement-setting overrides; start/cancel a queue; pass or fail a pending
measurement; export average/variation TXT files; and launch Squiglink upload.
Temporary settings are persisted only with settings save.
The Settings tab saves sweep and timing changes immediately and contains SPL Calibration, Test Level, and options to restore the measurement and metadata clearing warnings. Its controls are grouped in a compact left-aligned column and remain visible but disabled while a measurement queue or R&D sweep is active. Settings also includes default folders for R&D session save/load dialogs and Automation event libraries. Keyboard shortcut mapping lives in a separate right-side Settings column so it does not add more vertical scrolling to the measurement settings.
Type curator help for the built-in command reference. Curator commands include:
curator status | curator layers | curator send
curator import <path> [<path>...]
curator layer <n> show|hide|remove
curator layer <n> offset <db> | color <#RRGGBB> | hrtf <name|none>
curator combine <n> <n> [...] | curator clear
curator bounds on|off
curator view limits <min_db> <max_db> | aspect on|off
curator view background <#RRGGBB|theme>
curator text title|fixture|footer <text>
curator reset | curator export <path>
Layer numbers are one-based and are shown by curator layers. Quote paths or
text containing spaces.
Fastgraph starts in Dark mode. Use the sun/moon switch beside the feedback button in the bottom status bar to change themes immediately. The selected theme is saved and restored the next time Fastgraph starts.
Plain TXT, two columns: frequency_hz magnitude_db
One header line is OK if it is non-numeric.
Mono files apply to both ears equally.
The app can upload exported measurement TXT files over SFTP for Squiglink use.
Uploads require Brand, Model, and Channel Side metadata. The upload flow
can prompt for missing metadata, write side-aware TXT filenames into the remote
data/ directory, and merge measurement entries into the account's
data/phone_book.json when available.
Configure the Squiglink SFTP host in the app settings file:
- macOS:
~/Library/Application Support/DMSFastgraph/settings.json - Windows:
%APPDATA%/DMSFastgraph/settings.json - Linux:
${XDG_CONFIG_HOME:-~/.config}/DMSFastgraph/settings.json
Example:
{
"squiglink_sftp_host": "your-sftp-host.example"
}If sounddevice has no devices, install PortAudio:
# Debian/Ubuntu
sudo apt install libportaudio2 portaudio19-dev
# Arch
sudo pacman -S portaudioCoreAudio is used automatically. No extra steps.
WASAPI is preferred for normal measurements. The app hides advanced Windows
driver entries by default, can reveal them with the Advanced Windows Drivers
toggle, and blocks mismatched input/output host APIs before queue start.
ASIO support is experimental and may not behave reliably across all drivers.
If timing is unstable, use matched input/output devices on the same backend and try high latency mode.
Before packaging or tagging a beta, run:
PYTHONPATH=. .venv/bin/pytest -q
PYTHONPATH=. .venv/bin/python -m py_compile main.py dms/*.py dms/curator/*.py dms/rnd/*.py dms/ui/*.py
git status --shortLinux packaging is experimental and currently documented for Ubuntu 26.04. Install the required system packages, then run the build with its test gate:
cd /path/to/fastgraph
sudo ./.linux/ubuntu_deps.sh
./build_linux.sh --testTo build without running pytest, use ./build_linux.sh. The finished app folder
will be created at:
dist/FastGraph BetaThis is currently a local application folder rather than an AppImage or distro package. Runtime measurement behavior still needs wider Linux hardware testing.
Build the Windows app on a Windows machine:
cd C:\path\to\fastgraph
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt pyinstaller
.\build_windows.ps1The Windows build regenerates fastgraph.ico from the tracked
fastgraph icon.png source before running PyInstaller.
The finished app folder and shareable zip will be created at:
dist\FastGraph Beta
dist\FastGraph Beta-windows-x64.zipOn your Mac:
cd /path/to/fastgraph
python3 -m venv .venv
source .venv/bin/activate
./build_macos.shThe finished app bundle will be created at:
dist/FastGraph Beta.appBoth macOS and Windows builds use the tracked fastgraph icon.png as their
shared icon source. The macOS build converts it to an .icns bundle icon
automatically, while the Windows build converts it to fastgraph.ico before
running PyInstaller. Replace the PNG and rerun the platform build script to
package a new icon.
Notes:
- The app bundle includes a microphone usage description for macOS permission prompts.
- Packaged apps include the shared HRTF library and Curator preference bounds.
- If Gatekeeper warns about the app because it is unsigned, right-click the app and choose
Open.
GitHub Actions builds release packages for Apple Silicon macOS, Windows x64, and
Linux x64. Update dms/version.py and CHANGELOG.md, push the release commit
to main, then choose one of these release paths:
- Push a tag such as
v0.3.5; the workflow builds all three packages and publishes a GitHub release automatically. - In Actions → Release builds → Run workflow, choose the source ref, enable
Create or update a GitHub release, and enter a release tag such as
v0.3.5. This creates the tag at the selected ref and publishes the release.
Leaving Create or update a GitHub release disabled runs a build-only job.
Its downloadable artifacts are useful for testing before publishing. Release
notes are taken from the matching version section in CHANGELOG.md; if no
section exists, GitHub generates notes automatically.
The app supports a non-intrusive update badge in the bottom-right status area. It appears only when a newer version is found.
Add these keys to your settings file:
{
"update_check_enabled": true,
"update_feed_url": "https://example.com/dms-fastgraph-update.json"
}The feed URL should return JSON like:
{
"version": "0.3.5",
"url": "https://github.com/DMS3tv/fastgraph/releases/tag/v0.3.5",
"summary": "Adds Automation tab event builder"
}