Skip to main content

Generate line-level LRC files from audio and canonical lyrics.

Project description

wispr

wispr is a Python library and CLI for generating synchronized, standard line-level .lrc files from full-song audio plus a canonical line-by-line lyrics file.

The lyrics file is the source of truth. Transcription and alignment backends exist to recover timing, not to rewrite lyrics.

Demo contract

wispr song.wav lyrics.txt

By default this uses the WhisperX backend and writes song.lrc next to the audio file. Existing outputs are not overwritten unless --force is passed.

wispr song.wav lyrics.txt -o output.lrc --debug --force

Initial flags:

  • -o, --output: choose an output path
  • --force: overwrite an existing output file
  • --debug: write transcript.json, alignment.json, and segments.json
  • --backend mock|whisperx: choose the real WhisperX backend or mocked development timing
  • --demucs: run optional Demucs vocal separation before WhisperX
  • --model: WhisperX model name, defaulting to base
  • --device: runtime device, defaulting to auto
  • --compute-type: WhisperX compute type, defaulting to auto
  • --batch-size: WhisperX transcription batch size, defaulting by device
  • --language: WhisperX language code, defaulting to en

Install

The PyPI distribution is wispr-lrc, and it installs the wispr command. For real audio alignment, install the optional ML extra:

uv tool install "wispr-lrc[ml]"

WhisperX also requires ffmpeg to be available on your system path.

wispr song.wav lyrics.txt --model base --device auto --compute-type auto

Vocal separation is off by default. To run WhisperX on Demucs-isolated vocals, install the optional separation extra and pass --demucs:

uv tool install "wispr-lrc[ml,separation]"
wispr song.wav lyrics.txt --demucs --model base --device auto

The mock backend is still available for fast development, CI, and framework smoke tests:

wispr song.wav lyrics.txt --backend mock

Current milestone

--device auto prefers CUDA when Torch reports that CUDA is available. With --compute-type auto, wispr uses float16 on CUDA and int8 on CPU. If CUDA is requested explicitly and unavailable, the run fails with a clear message.

Batch processing uses a CSV manifest with required audio and lyrics columns and optional output, language, title, artist, and album columns. Relative paths are resolved beside the manifest.

audio,lyrics,output,language
song-a.flac,song-a.txt,out/song-a.lrc,en
song-b.flac,song-b.txt,out/song-b.lrc,en
wispr batch manifest.csv --backend whisperx --device auto --compute-type auto --debug --force

Batch runs are sequential in one process so WhisperX models can be reused without oversubscribing the GPU. Each run writes a *.summary.json file beside the manifest with per-row status and stage timings.

Benchmark commands wrap the same pipeline and write a JSON report with runtime configuration, alignment quality, warnings, stage timings, and total wall time.

wispr benchmark song.wav lyrics.txt --backend whisperx --device auto --compute-type auto --debug --force
wispr benchmark batch manifest.csv --backend whisperx --device auto --compute-type auto --debug --force

Single-song benchmark reports default to <output-stem>.benchmark.json. Batch benchmark reports default to <manifest-stem>.benchmark.json.

The emitted .lrc still uses the supplied lyrics file as canonical text. WhisperX only provides timing evidence.

For a local real-audio smoke run, place ignored files under inputs/ and write outputs back under that ignored tree:

For example:

uv run wispr inputs/03-giveon-twenties.flac inputs/lyrics.txt \
  --backend whisperx \
  --demucs \
  --model base \
  --device auto \
  --compute-type auto \
  --debug \
  --force \
  -o inputs/out/twenties.lrc

For local performance comparisons:

uv run wispr benchmark inputs/03-giveon-twenties.flac inputs/lyrics.txt --backend whisperx --device auto --compute-type auto --debug --force -o inputs/out/twenties.lrc
uv run wispr benchmark inputs/03-giveon-twenties.flac inputs/lyrics.txt --backend whisperx --demucs --device auto --compute-type auto --debug --force -o inputs/out/twenties-demucs.lrc
uv run wispr benchmark batch inputs/manifest.csv --backend whisperx --device auto --compute-type auto --debug --force

The WhisperX backend checks for both the optional Python dependency and ffmpeg before running. Debug output includes raw backend payloads, normalized dataclass state, and an alignment summary so failed or weak runs can be inspected without changing the .lrc contract.

The code is organized around:

  • typed dataclasses at stage boundaries
  • deterministic LRC formatting
  • a thin Typer CLI over reusable library code
  • debug artifacts that mirror internal pipeline state
  • structured warnings for weak alignment
  • batch summaries and stage timings for runtime profiling
  • benchmark reports for repeatable performance comparisons

Development

uv sync --dev
uv run pytest
uv run ruff check .
uv build

Slow ML tests should be marked with pytest.mark.ml and run explicitly:

uv run pytest -m ml

The local ML smoke test is skipped during the default test suite and only runs when the inputs/ smoke files are present.

GitHub Actions runs linting, tests, a package build, and a mock benchmark smoke test on Python 3.11 and 3.12. The committed Jingle Bells fixture under tests/fixtures/ is public-domain material used to exercise real file handling without requiring WhisperX, Demucs, Torch, ffmpeg, or model downloads in normal CI.

Real WhisperX benchmarking is available through the manual Manual ML Benchmark workflow. It installs ffmpeg and the ml extra, runs against the same fixture, and uploads the .lrc, debug files, and benchmark report as workflow artifacts.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wispr_lrc-0.1.2.tar.gz (6.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wispr_lrc-0.1.2-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file wispr_lrc-0.1.2.tar.gz.

File metadata

  • Download URL: wispr_lrc-0.1.2.tar.gz
  • Upload date:
  • Size: 6.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wispr_lrc-0.1.2.tar.gz
Algorithm Hash digest
SHA256 923d8377b59ca98056af8dbbdce5b964c8dc2ca483376c4d8a9abd1bb8f38949
MD5 87d38b2fc7a220493c6e71c7e6844675
BLAKE2b-256 9bea6b3129e08efaad0cbe6c3ec4aefeee80ee3c5b3b6140a6b1145783011380

See more details on using hashes here.

File details

Details for the file wispr_lrc-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: wispr_lrc-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wispr_lrc-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 249dc96433ca0ad0702de5486c155d578e1b72f8381e7421a640a775a7e45793
MD5 5254ff9c5c63a117607e345068d578e1
BLAKE2b-256 d95b2665255fa007cb11f1e3b5145cd5ff7c6cf6263b32a06116be3393665cce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page