Usage Guide#

Quick Start#

1. Audio Loading#

Load and normalise audio files for analysis. The load_audio handles mono conversion and peak normalisation automatically.

import drumscript as ds
y, sr = ds.load_audio("audio_path.wav")   # y = audio samples, sr = sample rate

2. Extract Drums From Any Song#

Want to isolate the drums in your favourite song?

import drumscript as ds
extract_drums = ds.extract_drum_stem("audio_path.wav", output_dir="path_to_output_dir/") # 2. Extract drums from a song and save to local path that you can specify

extract_drum_stem() writes to your current working directory if output_dir is not specified.

3. Create Drumless Backing Track (--drumless)#

Want to jam along? Remove the drums from your favourite song:

drumscript "audio_path.wav" --drumless
# or, without installing the console script:
python -m drumscript.main "audio_path.wav" --drumless
import drumscript as ds
backing_track = ds.extract_stems("audio_path.wav", drumless=True, verbose=True)
print(f"Files written to: {backing_track['output_directory']}")

extract_stems() writes to a stems/ folder in your current working directory if output_dir is not specified.

The verbose dict returns status, drum_stem_path, original_file and output_directory. The backing track itself is named <input>_no_drums.<format> inside output_directory - its path is not yet returned directly. See the CHANGELOG for the planned fix.

4. Extracting Stems (--all-stems)#

Split a song into its constituent parts (Drums, Bass, Vocals, Other):

python -m drumscript.main "audio_path.mp3" --all-stems --format mp3

PLEASE NOTE: These stems are defined by Demucs

5. Custom Time Signatures (--ts)#

By default, DrumScript assumes 4/4 time. You can override this for waltzes or complex meters:

# Transcribe a waltz
drumscript "audio_path.wav" --ts 3/4

# Transcribe 6/8 time
drumscript "audio_path.wav" --ts 6/8

Use a forward slash. Any other form - including underscores like 3_4 or a typo like 44 - falls back to 4/4 and prints a warning.

6. Full Audio to PDF Transcription (--full-song)#

CLI:

python -m drumscript.main audio_path.mp3 --full-song

Python API:

import drumscript as ds

# Transcribe an isolated drum stem → PDF + JSON + MIDI
result = ds.transcribe("drum_audio.wav")
print(result["pdf_path"])   # PDF sheet music
print(result["json_path"])  # raw transcription data (JSON)
print(result["midi_path"])  # MIDI file for DAW import

# Transcribe a full song (separates drums automatically)
result = ds.transcribe("full_song.mp3", full_song=True)
print(result["pdf_path"])

# Get all intermediate results (tempo, onsets, events, etc.)
result = ds.transcribe("drum_audio.wav", verbose=True)
print(f"Tempo: {result['tempo']:.1f} BPM")
print(f"Events: {len(result['events'])}")
print(f"PDF: {result['pdf_path']}")
print(f"MIDI: {result['midi_path']}")

Note (v0.2.0): transcribe() now returns a dict with pdf_path, json_path, and midi_path keys. Using the return value as a plain string (e.g. pdf = ds.transcribe(...)) still works but is deprecated and will be removed in v1.0.0. Use result["pdf_path"] instead.

7. MIDI Only (--midi-only)#

If all you need is a MIDI file to drop into a DAW, --midi-only skips the sheet music and the transcription JSON. The audio is still analysed exactly as normal, because a MIDI file of drum notes cannot be produced without detecting the onsets and classifying the hits. Only the other two writes are suppressed.

CLI:

drumscript "drum_loop.wav" --midi-only

This creates outputs/drum_loop_transcription.mid.

Python API:

import drumscript as ds

result = ds.transcribe("drum_loop.wav", midi_only=True)
print(result["midi_path"])

Combine it with the other options as usual. For a full song, add full_song=True to isolate the drum stem first; for isolated hits, add is_rudiment=True.

result = ds.transcribe("full_song.wav", midi_only=True, full_song=True)

You can control where the file lands with output_dir and output_filename:

result = ds.transcribe(
    "drum_loop.wav",
    midi_only=True,
    output_dir="my_exports",
    output_filename="my_drums",
)
print(result["midi_path"])  # my_exports/my_drums.mid

Note: under midi_only=True only midi_path is populated in the returned mapping. pdf_path and json_path are None, because those files were never written. Read the key you asked for rather than assuming all three are present.

Full commands

Audio Transcription#

To run the full transcription pipeline on an audio file, use transcribe(). This will load the audio, separate the drums (if needed), classify hits, and generate PDF, JSON and MIDI output.

import drumscript as ds

result = ds.transcribe("audio_path.wav")
print(result["pdf_path"])

The CLI equivalent - main() is the orchestration function behind it, and takes the input path as its first argument:

drumscript "audio_path.wav"
from drumscript.main import main

main("audio_path.wav")               # drum-only input
main("audio_path.mp3", full_song=True)   # full song: separate drums first

Stem Splitting#

Isolate the drum track from a full music mix using extract_drum_stem(), or run a full separation with separate_audio(). Both are module-level functions - there is no class to instantiate.

from drumscript.audio_processor.stem_splitter import extract_drum_stem

# Returns the path to the isolated drum track
drum_track_path = extract_drum_stem(
    audio_path="audio_path.mp3",
    output_dir="output/",
)

print(f"Drum stem saved at: {drum_track_path}")

For full separation with backing-track and per-stem options:

from drumscript.audio_processor.stem_splitter import separate_audio

results = separate_audio(
    audio_path="audio_path.mp3",
    output_format="wav",
    drumless=True,
    all_stems=False,
    output_dir="output/",
)

print(results)   # dict of every file written, including "mix"

Audio Loading#

Load and normalise audio files for analysis. The load_audio handles mono conversion and peak normalisation automatically.

import drumscript as ds
from drumscript.audio_processor.audio_loader import load_audio
# Load audio (returns audio time series and sample rate)
y, sr = ds.load_audio("audio_path.wav") 

Extract Backing Track#

Create a drumless track to play along to. Works on any polyphonic audio.

import drumscript as ds

result = ds.extract_stems("full_song.wav", drumless=True, verbose=True)
print(f"Written to: {result['output_directory']}")

The backing track is saved as <input>_no_drums.wav inside that directory, alongside the isolated drums as <input>_only_drums.wav.

CLI equivalent:

drumscript "full_song.wav" --drumless
drumscript "full_song.mp3" --drumless --format mp3   # MP3 output needs ffmpeg

You can mute any stem, not just drums:

drumscript "full_song.wav" --mute bass
drumscript "full_song.wav" --mute bass --mute vocals

Extract Drum-Only Audio#

Pull just the drum track out of a full mix - useful for studying a groove, or for feeding into transcription separately.

import drumscript as ds

drum_path = ds.extract_stems("full_song.wav")
print(f"Drum stem: {drum_path}")

CLI equivalent:

drumscript "full_song.mp3" --full-song

--full-song extracts the drums and transcribes them. To get the stem without a score, use the Python API above, or --all-stems to export all four.