Skip to main content
╔════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                            ║
║                          ██╗  ██╗███████╗██╗   ██╗           ██╗                           ║
║                          ██║ ██╔╝██╔════╝╚██╗ ██╔╝           ██║                           ║
║                          █████╔╝ █████╗   ╚████╔╝ █████╗     ██║                           ║
║                          ██╔═██╗ ██╔══╝    ╚██╔╝  ╚════╝██   ██║                           ║
║                          ██║  ██╗███████╗   ██║         ╚█████╔╝                           ║
║                          ╚═╝  ╚═╝╚══════╝   ╚═╝          ╚════╝                            ║
║                                                                                            ║
║                    your tab, your notes, and any key plays the next one                    ║
║                                                                                            ║
╚════════════════════════════════════════════════════════════════════════════════════════════╝

PyPI Python Licence

Key-J on the command line. Guitar tablature goes in, notes come out, and any keystroke plays the next one.

pip install keyj

keyj tab solo.txt -o song.txt      tablature to notes
keyj show song.txt                 what is in a file
keyj render song.txt out.wav       notes to audio
keyj play song.txt                 notes, played by typing

Why a command line version

The browser app is where a song gets built: paste a tab, hear it, fix it. That is a workbench, and you want it once.

Afterwards you have the song, and what you want is the smallest possible thing that plays it. No window, no autostart, no login item. A process you start when you want it and stop with Ctrl-C, which ps can see and kill can end.

What it does not do

keyj play installs a system-wide keyboard listener, which is the same machinery a keylogger uses. So the design point is this:

It does not need to know which key you pressed.

In sequence mode every key plays the next note. Which key is irrelevant, so the identity of the key is never stored, never written, never counted per-key and never sent anywhere. The callback asks a key one question - is it a modifier, so that Shift does not eat a note - and then discards it. There is no buffer of keystrokes to leak, because one is never built.

That is a structural property rather than a promise. It is nine lines, in src/keyj/play.py, and you should read them before installing this.

Dependencies

tab, render and show are standard library only and never touch your keyboard. play is the one command that needs anything:

pip install 'keyj[play]'
macOS needs Accessibility permission, granted to your terminal
Linux / X11 works as installed
Linux / Wayland no global hook exists. keyj play says so and exits
Windows works unless a security tool blocks the hook

The file format

A sequence is note names separated by whitespace, with # comments stripped on the way in.

# Key-J sequence - 7 notes from tab
A3 E4 F#4 E4 D4 B3 A3

That is the same format the browser app's Save .txt writes and Load .txt reads, and a file saved in either place pastes directly into the other's note box. Anything that can emit a list of note names can feed Key-J.

Tunings

Eight, by short name: standard, dropd, eb, d, dadgad, openg, 7string, bass. A capo is --capo N.

The reader states what it read - the tuning, how many strings, how many notes - and a block whose line count does not match the tuning produces no notes and is named in the report rather than guessed at. What it cannot catch is a tab that is internally consistent and simply wrong; bad frets convert cleanly into bad notes, and only your ear will find that.

Tested against the browser

This package and keyj/app.html are two implementations of the same conversions, and Key-J has already shipped defects that existed only because two copies of one thing drifted apart. So tests/test_parity.py lifts the real functions out of app.html, runs them under node against the same inputs, and diffs the results.

python tests/test_parity.py

If node is not installed the parity checks skip and say so, because a check that cannot run must not report success.


╔════════════════════════════════════════════════════════════╗
║                                                            ║
║      ███████╗      ██╗  ██╗███████╗██╗   ██╗███████╗       ║
║      ██╔════╝      ██║ ██╔╝██╔════╝╚██╗ ██╔╝██╔════╝       ║
║      █████╗  █████╗█████╔╝ █████╗   ╚████╔╝ ███████╗       ║
║      ██╔══╝  ╚════╝██╔═██╗ ██╔══╝    ╚██╔╝  ╚════██║       ║
║      ██║           ██║  ██╗███████╗   ██║   ███████║       ║
║      ╚═╝           ╚═╝  ╚═╝╚══════╝   ╚═╝   ╚══════╝       ║
║                                                            ║
║               ·   C  R  E  A  T  I  V  E   ·               ║
║                                                            ║
║          ────────────────────────────────────────          ║
║                                                            ║
║                      Vincent Gonzalez                      ║
║                         f-keys.com                         ║
║                 ORCID 0009-0005-3640-014X                  ║
║                                                            ║
╚════════════════════════════════════════════════════════════╝

Part of F-Keys — independent hardware, software and internet products. See the working log and live status.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

keyj-0.1.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

keyj-0.1.0-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file keyj-0.1.0.tar.gz.

File metadata

  • Download URL: keyj-0.1.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for keyj-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7bd4539e701d73d4b909cf5630049ca7d1b96dfb1ece6c67f886c8a4022870a3
MD5 71274669ff135c2f772f256aa644f6a2
BLAKE2b-256 5752d973083c3a37f381905cca6676c863c370e4d6ddff981e7d3e1e8a0583c6

See more details on using hashes here.

File details

Details for the file keyj-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: keyj-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for keyj-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d74ac7a34cdc2de231b34fbd722d152dc86255597686fc31597c17c0d3337e89
MD5 8e74d690473cbe228ed0660b8da25e70
BLAKE2b-256 c202610c910ce9fce2bffe7de315030963e767b097c3fc156bca7db96718b71e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.2

2 files

0.1.1

2 files

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page