Skip to main content

tabsynth

Convert pre-detected musical events (notes and chords) into playable guitar tablature via candidate generation and dynamic programming optimization.

Overview

tabsynth is a production-ready Python package that transforms musical event data into optimized guitar tablature. It focuses on the synthesis and optimization of tablature from already-detected musical events—audio detection is out of scope.

Key Features

  • Event-Based Input: Accepts NoteEvent (single pitch) and ChordEvent (multiple pitches) objects
  • Candidate Generation: Creates multiple playable fingering options for each event
  • DP Optimization: Uses Viterbi-style dynamic programming to find the optimal sequence minimizing hand movement and difficulty
  • Chord Template Matching: Built-in library of common chord shapes (open chords, barre chords)
  • Multiple Output Formats: ASCII tablature, JSON, and compact text representations
  • Extensible: Easy to add custom chord templates

Installation

pip install tabsynth

Or install from source:

cd tabsynth
pip install -e .

For development with tests:

pip install -e ".[dev]"

Quick Start

Basic Usage

from tabsynth import NoteEvent, ChordEvent, events_to_tablature

# Define some musical events
events = [
    NoteEvent(pitch_hz=329.63, start=0.0, duration=0.5),  # E4
    NoteEvent(pitch_hz=369.99, start=0.5, duration=0.5),  # F#4
    NoteEvent(pitch_hz=392.00, start=1.0, duration=0.5),  # G4
    NoteEvent(pitch_hz=440.00, start=1.5, duration=0.5),  # A4
]

# Convert to tablature
tablature = events_to_tablature(events, output_format="ascii")
print(tablature)

Working with Chords

from tabsynth import ChordEvent, events_to_tablature

# E major chord
chord = ChordEvent(
    pitches_hz=[329.63, 415.30, 493.88],  # E, G#, B
    start=0.0,
    duration=1.0
)

tablature = events_to_tablature([chord], output_format="ascii")
print(tablature)

Using the Pipeline API

from tabsynth import TabSynthPipeline, NoteEvent

# Create a pipeline with custom settings
pipeline = TabSynthPipeline(
    max_fret=12,
    tolerance_cents=50.0
)

# Process events
events = [NoteEvent(pitch_hz=440.0, start=0.0, duration=0.5)]
result = pipeline.process(events, output_format="json")

Command-Line Interface

The package includes a demo CLI:

# Show help
tabsynth help

# Run demos
tabsynth demo-notes
tabsynth demo-chords
tabsynth demo-mixed

Architecture

Data Flow

Events (Notes/Chords)
    ↓
Candidate Generation (multiple fingerings per event)
    ↓
Cost Calculation (hand position, stretch, barre difficulty)
    ↓
DP Optimization (Viterbi algorithm)
    ↓
Rendering (ASCII/JSON/Compact)

Core Components

  1. model.py: Data structures for events and playable states
  2. fretboard.py: Pitch helpers and fretboard modeling
  3. templates.py: Chord shape library
  4. candidates.py: Generate playable fingering candidates
  5. cost.py: Cost functions for transitions and states
  6. optimize.py: Dynamic programming optimizer
  7. render.py: Output formatting
  8. pipeline.py: End-to-end integration

Extending with Custom Chord Templates

You can add your own chord shapes:

from tabsynth import ChordTemplate, TabSynthPipeline

# Define a custom chord
my_chord = ChordTemplate(
    id="D_major_open",
    frets=[None, None, 0, 2, 3, 2],  # Strings 6,5,4,3,2,1
    barre=False,
    pitch_classes={"D", "F#", "A"},
    span=3,
    tags={"open", "basic"}
)

# Use it in a pipeline
pipeline = TabSynthPipeline(templates=[my_chord])

Template Fields

  • id: Unique identifier
  • frets: List of 6 fret numbers or None (for strings 6→1)
  • barre: Whether the chord requires barre technique
  • pitch_classes: Set of note names in the chord
  • span: Fret span (max - min among fretted notes)
  • tags: Descriptive tags (e.g., "open", "barre", "E-shape")

Output Formats

ASCII Tablature

Guitar Tablature
========================================

e|0-5-7-5|
B|0-7-8-7|
G|1-6-7-6|
D|2-7-9-7|
A|2-7-9-7|
E|0-5-7-5|

Chords:
  E_major_open

JSON

[
  {
    "index": 0,
    "start": 0.0,
    "duration": 0.5,
    "kind": "note",
    "strings": [1],
    "frets": {"1": 5},
    "mean_fret": 5.0,
    "min_fret": 5,
    "max_fret": 5,
    "requires_barre": false,
    "chord_id": null
  }
]

Compact

0: t=0.00 note [1:5]
1: t=0.50 note [1:7]
2: t=1.00 E_major_open [6:0,5:2,4:2,3:1,2:0,1:0]

API Reference

Events

NoteEvent(pitch_hz: float, start: float, duration: float, confidence: float = 1.0)
ChordEvent(pitches_hz: list[float], start: float, duration: float, confidence: float = 1.0)

Pipeline

events_to_tablature(
    events: list[Event],
    output_format: "ascii" | "json" | "compact" = "ascii",
    templates: list[ChordTemplate] = None,
    max_fret: int = 15,
    tolerance_cents: float = 50.0
) -> str

Optimization

optimize_sequence(
    events: list[Event],
    templates: list[ChordTemplate] = None,
    max_fret: int = 15,
    tolerance_cents: float = 50.0
) -> list[PlayableState]

Testing

Run tests with pytest:

pytest tabsynth/tests/

Tests cover:

  • Fretboard and pitch calculations
  • Candidate generation
  • Optimization correctness
  • End-to-end pipeline

Design Principles

  1. Minimal Dependencies: Core functionality requires only Python 3.10+
  2. Typed: Full type hints for better IDE support
  3. Extensible: Easy to add new chord templates and cost functions
  4. Focused: Audio detection is out of scope; assumes pre-detected events
  5. Optimized: DP algorithm ensures efficient fingering sequences

Limitations

  • Audio detection not included: Requires pre-detected pitch events
  • Standard tuning focus: Primary support for EADGBE tuning
  • Template-based chords: Chord recognition relies on predefined templates
  • No timing quantization: Preserves input event timing as-is

Contributing

To add new chord templates to the library:

  1. Define a ChordTemplate with accurate fret positions
  2. Specify pitch classes and tags
  3. Add to V1_TEMPLATES in templates.py
  4. Write tests to verify matching

License

MIT License - see LICENSE file for details.

Version

Current version: 0.1.0

Metadata

Release files for tabsynth 1.0.6

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

Source distribution (sdist)

Source distribution for tabsynth 1.0.6
File Size Uploaded Provenance Actions
tabsynth-1.0.6.tar.gz 24.1 kB With provenance Details for tabsynth-1.0.6.tar.gz

Built distribution (wheel)

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

Total release size: 40.7 kB

Release files / tabsynth-1.0.6.tar.gz

Download URL tabsynth-1.0.6.tar.gz
Size 24.1 kB
Tags Source
SHA-256 checksum
How to use checksums
09edc254a68bf94380f1ec841229c344a5986f84687996dbe302b3a008e11ef1
BLAKE2b-256 checksum
How to use checksums
c1fd9bb78077449e52e65a52add30ab51d2cd47c87a1c7f0d0fc56c310fbd063
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 6, 2026.

Transparency log

Release files / tabsynth-1.0.6-py3-none-any.whl

Download URL tabsynth-1.0.6-py3-none-any.whl
Size 16.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ad69f177f0d3951eeeaa603f94eecb358122963d64a7be7840edbb1b690fa2e
BLAKE2b-256 checksum
How to use checksums
0ee3a82c9b7557308b21cbff9323516703f9dda2412d97c78d197e078f93352b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 6, 2026.

Transparency log

Security for tabsynth 1.0.6

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tabsynth-1.0.6.tar.gz

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 Jan 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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