Skip to content

Repository files navigation

Transcribe

A CLI tool for automatic music transcription. Separates audio stems with Demucs, transcribes the selected stem using Basic Pitch, and outputs a structured JSON representation of notes and rhythm on a 32nd-note grid — suitable for rendering as sheet music.

Primary use case: modern multi-track recordings. Works best with contemporary material; older mono recordings (pre-1960s jazz) separate poorly due to model training data.

Pipeline

Input (.mp3 / .wav)
        |
        v
  [ separate ]  ─── Demucs htdemucs_6s (6-stem)
        |
  stems.json + stem wavs
        |
        v
  [ transcribe ]  ─── stems.json + --stem + --time-sig + --bpm
        |
        +─── Basic Pitch  →  raw notes (time, pitch, confidence)
        |
        +─── librosa      →  BPM detection + beat grid
        |
        +─── Quantizer    →  align to 32nd-note grid, detect tuplets/ties
        |
        v
  output.json

Usage

# Step 1: separate stems
transcribe separate input.mp3 --output-dir ./stems/

# Step 2: transcribe a stem (auto BPM detection)
transcribe transcribe stems/stems.json --stem other --time-sig 4/4

# Step 2: transcribe with manual BPM
transcribe transcribe stems/stems.json --stem piano --time-sig 4/4 --bpm 132

Step 1 produces stems/{drums,bass,guitar,piano,vocals,other}.wav plus a stems.json config. Uses the htdemucs_6s model for dedicated guitar and piano tracks. Step 2 reads that config, runs Basic Pitch on the chosen stem, and writes output.json.

Architecture

src/transcribe/
  cli.py          entry point (Typer)
  separator.py    Demucs wrapper → stem wavs + stems.json
  transcriber.py  Basic Pitch wrapper → raw notes (sec, midi, confidence)
  quantizer.py    beat grid, note snapping, tuplet detection, tie resolution
  models.py       Pydantic data models

Quantizer

Core logic pipeline:

  1. BPM detection via librosa.beat.beat_track with half/double-time correction (or manual override via --bpm)
  2. Beat grid — divide each beat into 8 32nd-note slots per the time signature
  3. Note snapping — snap each onset to nearest grid slot
  4. Duration quantization — round to nearest valid 32nd-note multiple (1,2,4,8,16,32)
  5. Tuplet detection — identify 8th-note triplet groups (3 notes in one beat window)
  6. Tie resolution — notes crossing beat/group boundaries are split and linked with tie field

Data Model

Note
  measure    int
  position   int          0-indexed 32nd-note slot within measure
  pitch      str | None   scientific notation e.g. "A4", "Bb3"; None = rest
  duration   int          in 32nd notes (8 = quarter note)
  is_rest    bool
  tuplet     Tuplet | None
  tie        "start" | "middle" | "end" | None

Tuplet
  ratio           "3:2"
  group_id        "t1", "t2", ...
  index           0 / 1 / 2
  tuplet_duration int

Transcription
  metadata   TranscriptionMetadata
  notes      list[Note]

Grid reference (4/4)

Duration 32nd units
Whole 32
Half 16
Quarter 8
8th 4
16th 2
32nd 1

Position range per measure: 0–31 (4/4), 0–23 (3/4).

Output JSON

{
  "metadata": {
    "source_file": "input.mp3",
    "stem": "other",
    "bpm": 132.0,
    "time_signature": "4/4",
    "grid_resolution": "32nd",
    "total_measures": 24
  },
  "notes": [
    { "measure": 1, "position": 0, "pitch": "A4", "duration": 8, "is_rest": false, "tuplet": null, "tie": null },
    { "measure": 1, "position": 24, "pitch": "C5", "duration": 8, "is_rest": false,
      "tuplet": { "ratio": "3:2", "group_id": "t1", "index": 2, "tuplet_duration": 1 }, "tie": "start" }
  ]
}

Setup

Requires Python 3.11+.

uv sync
uv run transcribe --help

Tech Stack

  • Typer — CLI
  • Pydantic v2 — data models
  • Demucs — source separation (htdemucs_6s: drums, bass, guitar, piano, vocals, other)
  • Basic Pitch — polyphonic pitch detection
  • librosa — BPM detection and audio analysis

Roadmap

  • HTML sheet music rendering via VexFlow (transcribe render output.json --output sheet.html)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages