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) andChordEvent(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
- model.py: Data structures for events and playable states
- fretboard.py: Pitch helpers and fretboard modeling
- templates.py: Chord shape library
- candidates.py: Generate playable fingering candidates
- cost.py: Cost functions for transitions and states
- optimize.py: Dynamic programming optimizer
- render.py: Output formatting
- 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
- Minimal Dependencies: Core functionality requires only Python 3.10+
- Typed: Full type hints for better IDE support
- Extensible: Easy to add new chord templates and cost functions
- Focused: Audio detection is out of scope; assumes pre-detected events
- 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:
- Define a
ChordTemplatewith accurate fret positions - Specify pitch classes and tags
- Add to
V1_TEMPLATESintemplates.py - 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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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 logRelease 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 logSecurity 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.
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 logA 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.