fiddle-ferret is a home for small audio and media command-line tools.
music-start is useful for tracks with silence, ambience, drone, sparse intros,
pre-roll, or delayed drops. It supports two detection targets:
main: the likely main groove, drop, or recognizable start of the song.first-musical: the earliest musically meaningful note, beat, or event.
The detector analyzes the opening portion of the file, defaulting to the first 120 seconds. It ranks candidates using classic DSP features including loudness, energy changes, onset strength, beat regularity, spectral shape, and novelty.
- Python 3.12+
uvffmpegandffprobeavailable onPATH
Python dependencies are declared in pyproject.toml.
Run directly from the GitHub repo with uvx:
uvx --from git+https://github.com/popra/fiddle-ferret.git music-start analyze path/to/song.mp3Or clone the repo and run from the checkout:
git clone https://github.com/popra/fiddle-ferret.git
cd fiddle-ferret
uv run music-start analyze path/to/song.mp3Run from the source checkout:
uv run music-start analyze path/to/song.mp3Run as an installed/packaged tool from this repo:
uvx --from . music-start analyze path/to/song.mp3The default output is JSON with the top 3 candidates:
uv run music-start analyze song.mp3Example shape:
{
"file": "song.mp3",
"target": "main",
"max_seconds": 120.0,
"candidates": [
{
"rank": 1,
"timestamp": "0:14.512",
"seconds": 14.512,
"confidence": 0.812,
"label": "likely main start",
"reason": "strong energy rise, sustained loudness follows"
}
]
}Use text output for a more readable summary:
uv run music-start analyze song.mp3 --humanChoose the detection target:
uv run music-start analyze song.mp3 --target main
uv run music-start analyze song.mp3 --target first-musicalReturn more or fewer candidates:
uv run music-start analyze song.mp3 --candidates 5Limit the analyzed opening window:
uv run music-start analyze song.mp3 --max-seconds 60Only return candidates that leave enough audio after the timestamp:
uv run music-start analyze song.mp3 --min-remainder 45All CLI duration values are seconds and may be fractional.
Combine options:
uv run music-start analyze song.mp3 --target first-musical --candidates 1 --jsonmusic-start trim-start detects the first candidate and writes a trimmed copy
starting at that timestamp.
uv run music-start trim-start song.mp3
uv run music-start trim-start song.mp3 --target first-musical --overwrite
uv run music-start trim-start song.mp3 --output song.trimmed.mp3
uv run music-start trim-start song.mp3 --min-remainder 45The command leaves the original file untouched. By default it writes
song.trimmed.mp3 next to the input. Existing output files are not overwritten
unless --overwrite is provided. Use --min-remainder to require at least
that many seconds of audio after the detected timestamp.
0: candidates found1: decode or input error2: audio decoded successfully, but no confident candidate was found
Decode errors and no-candidate results are emitted as structured JSON when using the default output format.
Install and run through uv:
uv run music-start --help
uv run music-start analyze --help
uv run music-start trim-start --helpRun tests and lint:
uv run pytest
uv run ruff checkVerify packaged execution:
uvx --from . music-start --helpmusic-start uses classic signal processing rather than ML models. Results are
candidate timestamps, not authoritative edits. For workflows that create derived
files, inspect the timestamp first and keep the original file intact.
song-lengthen is a separate tool for automatic best-effort song lengthening.
It finds a stable loop region, repeats it enough times to approach a requested
duration, and writes a derived copy with crossfaded joins.
It works best on steady grooves, ambient beds, electronic music, instrumental sections, intros, and outros. It may produce poor edits on vocals, abrupt arrangements, tempo drift, or live recordings.
Lengthen a file to an approximate target duration:
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300Add a specific amount of time:
uv run song-lengthen lengthen path/to/song.mp3 --add-seconds 90Choose an output path or allow overwrite explicitly:
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300 --output path/to/song.long.mp3
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300 --overwriteInspect the edit plan without writing audio:
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300 --dry-runThe default output is JSON:
{
"input": "path/to/song.mp3",
"output": "path/to/song.lengthened.mp3",
"requested_seconds": 300.0,
"estimated_seconds": 302.154,
"original_seconds": 214.523,
"add_seconds": 85.477,
"loop": {
"rank": 1,
"start_seconds": 74.0,
"end_seconds": 98.0,
"duration_seconds": 24.0,
"confidence": 0.812,
"reason": "similar loop boundary"
},
"repeat_count": 4,
"crossfade_seconds": 3.0,
"warnings": []
}Use text output for a readable summary:
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300 --humanUseful loop controls:
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300 --crossfade-seconds 4
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300 --min-loop-seconds 12 --max-loop-seconds 40
uv run song-lengthen lengthen path/to/song.mp3 --target-seconds 300 --candidates 10The command leaves the original file untouched. By default it writes
song.lengthened.mp3 next to the input. Existing output files are not
overwritten unless --overwrite is provided. All duration values are seconds
and may be fractional.