Skip to main content

sweeptune

Minimal macOS CLI that measures your listening room with a log sine sweep and tells you what to enter into the Fosi Audio S3 10-band EQ (31.5 Hz – 16 kHz, ±10 dB, 0.5 dB steps) to reach a neutral-but-pleasing, Harman-like in-room curve. It also reports reverberation (RT60), early reflections and room modes, because EQ cannot fix echo.

Install

brew install uv
uv tool install sweeptune     # from PyPI, puts `sweeptune` on your PATH
sweeptune --help

From a clone instead: uv sync, then prefix the commands below with uv run.

Setup

Select the Fosi S3 as the Mac's sound output (Control Center → Sound → AirPlay) before measuring. Device names can be overridden in an optional sweeptune.toml (see src/sweeptune/config.py for all keys):

output_device = "S3"        # name fragment of the AirPlay output
input_device = ""           # name fragment; empty = mic profile default
max_boost_db = 4.0
shelf_db = 6.0              # bass shelf of the harman-like target

Workflow

uv run sweeptune doctor                         # routing, mic inputs, noise floor
uv run sweeptune balance --live                 # set the amp's balance knob at the seat (L/R level + distance)
uv run sweeptune measure --mic audyssey         # 7 positions, L and R, EQ flat
uv run sweeptune eq suggest                     # table + copy string for the S3
uv run sweeptune plot                           # frequency response vs target + suggested EQ (PNG, opens in Preview)
# enter the values on the S3 (and lower its volume by the headroom shown)
uv run sweeptune verify                         # re-measure, compare to prediction, next correction
uv run sweeptune verify                         # repeat until converged
uv run sweeptune report                         # sessions/<timestamp>/report.md + PNGs

Balance

sweeptune balance --live plays L, R, L sweeps at the listening seat and shows how much louder one side is (500 Hz – 4 kHz, where the stereo image lives) and how much farther one speaker is. Turn the amp's balance knob, press Enter to re-measure, and stop within ±0.5 dB. Fix a distance difference by moving the speaker first; the balance control is for the remaining level difference. Without --live, sweeptune balance reports the same figures from the latest multi-position measurement. The S3 EQ acts on both channels equally, so balance and EQ can be set in either order.

Optional:

  • sweeptune eq probe 125 – change one band by −6 dB and learn the S3's real filter Q (saved to streamer.json).
  • sweeptune mic relcal iphone17pro --ref audyssey – derive a calibration for another mic at the same spot.
  • sweeptune sweep export + sweeptune analyze rec1.wav rec2.wav … – offline path, e.g. recording on the iPhone with an app that offers a measurement (unprocessed) mode.
  • sweeptune plot --channels – left and right speaker on a shared level, so a balance offset is visible.
  • sweeptune --simulate … – run any command against a synthetic room, no speakers needed.

Microphones

id Mic Use
audyssey Audyssey mic bundled with AV receivers, MacBook 3.5 mm jack primary; trusted 20 Hz – 10 kHz
iphone17pro iPhone 17 Pro via Continuity mic, or offline WAV secondary; AGC check first
macbook-m1pro built-in array last resort; 100 Hz – 8 kHz, compare iterations only

None of these mics has a traceable calibration, so all results are relative. The MacBook jack is CTIA TRRS; if doctor finds no external mic, the Audyssey plug needs a TRS→TRRS mic adapter.

Tests

uv run pytest

Releasing

  1. Bump version in pyproject.toml (PyPI never accepts the same version twice), commit and push.
  2. Publish a GitHub release whose tag is that version with a v prefix, e.g. v0.2.0. The publish workflow tests, builds and uploads to PyPI via trusted publishing (no token needed).

License

MIT © 2026 Maximilian Schuh. Free to use, modify and redistribute, including commercially, as long as the copyright notice and license text are kept — i.e. with acknowledgement.

Metadata

Release files for sweeptune 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sweeptune 0.1.0
File Size Uploaded
sweeptune-0.1.0.tar.gz 105.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sweeptune 0.1.0
File Interpreter ABI Platform
sweeptune-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 156.3 kB

Release files / sweeptune-0.1.0.tar.gz

Download URL sweeptune-0.1.0.tar.gz
Size 105.3 kB
Tags Source
SHA-256 checksum
How to use checksums
40618a7db0b92d5e36c01e2eaabce7bb1f0448ad5e05b80b9fe8f056e693bdeb
BLAKE2b-256 checksum
How to use checksums
15491c0a40440bc9b1063950fd9e6ae1576251db030da7ebab3b1f587a6696e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / sweeptune-0.1.0-py3-none-any.whl

Download URL sweeptune-0.1.0-py3-none-any.whl
Size 51.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
55ffe519a258ef966cc406566fa7359eb83fc2c80127b2be75d7ea5f2a0b5146
BLAKE2b-256 checksum
How to use checksums
c9d60ecf058b47fd49614828fea957cf3c16195e1fd2996afa0d62f453897986
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page