- JavaScript 57.1%
- Python 23.4%
- HTML 10%
- CSS 6.8%
- Kotlin 2.6%
| android | ||
| lib | ||
| server | ||
| tests | ||
| werkzeug | ||
| .gitignore | ||
| COPYRIGHT | ||
| docker-compose.yml | ||
| lib-in-app.sh | ||
| LICENSE | ||
| README.md | ||
Liederbuch
Eine eigene Sammlung von Liedern mit Gitarrengriffen: gesammelt am Rechner, gespielt am Telefon.
Es gibt genug Akkord-Apps mit zwei Millionen Songs. Genau das macht sie unbrauchbar, wenn man die vierzig Lieder spielen will, die man wirklich kann. Hier zählt die Kuratierung — und dass die Sammlung einem selbst gehört.
Aufbau
lib/ Der gemeinsame Kern. Einmal geschrieben, von Server UND App benutzt.
chordpro.js ChordPro lesen, darstellen, transponieren
harmonie.js Akkorde: Töne, Rollen, Stufen, Funktionen
griffe.js Griffdiagramme — gerechnet, nicht abgetippt
griffeingabe.js eigene Griffe antippen statt abtippen
skalen.js Tonleitern: Lagen auf dem Brett, Akkordskalen, Quintenzirkel
griffbrett.js das liegende Griffbrett als Bild
noten.js Akkorde und Tonleitern auf Notenlinien
notenzeichen.js Schlüssel, Vorzeichen und Notenköpfe als Umrisse
(erzeugt, siehe „Die Notenschrift" unten)
akkordwahl.js / skalenwahl.js die geordneten Vorräte
zirkel.js der Quintenzirkel zum Antippen
ansicht.js die Liedansicht, überall gleich
ansicht.css und ihr Aussehen
mitlaufen.js die Tempo-Skala fürs Auto-Scroll, von Server und App geteilt
tonuebung.js „Töne finden": die Übung selbst — Aufgabe, Brett, Urteil
tonuebung.css und ihr Aussehen
tonhoehe.js aus Schall eine Frequenz: Tonhöhe messen und stimmen
klang.js und zurück: der Referenzton a′ = 440 Hz
mikrofon.js das Mikrofon dazwischen: getUserMedia → Frequenzen
stimmen.js das Stimmgerät: nächster Ton und Abweichung in Cent
stimmen.css und sein Aussehen
server/ FastAPI + SQLite: importieren, bearbeiten, ordnen
android/ Android-WebView-App: anzeigen, spielen, offline
Das Format ist ChordPro — Klartext, seit Jahrzehnten stabil, mit jedem Texteditor zu retten:
{title: Blowin' in the Wind}
{key: G}
How many [G]roads must a [C]man walk [G]down
Server
cd server && pip install -r requirements.txt
LIED_DB_PATH=data/liederbuch.db uvicorn app.main:app --reload
python -m app.cli setpw # Konto anlegen, zeigt den App-Schlüssel
Oder als Container: podman-compose up -d (Build-Kontext ist die Projektwurzel,
damit lib/ mit ins Bild kommt).
Üben: Tonleitern und Quintenzirkel
Zu jedem Akkord steht dabei, womit man darüber spielt, und zu jedem Lied, welche Tonleiter über das ganze Stück passt — samt der Stellen, an denen sie es nicht tut („außer über E7, da fehlt G♯"). Auch das ist gerechnet: die Lagen werden auf dem Griffbrett konstruiert, und welche Skala zu einem Akkord passt, folgt aus dessen Tönen statt aus einer Zuordnungstabelle.
Zwei Modelle für die Lagen: Kästen (was die Hand ohne Rutschen greift) und Läufe (gleich viele Töne je Saite). Wie viele Töne auf eine Saite gehören, ergibt sich aus dem Saitenabstand — bei sechstönigen Skalen wie der Blues-Skala geht das nicht auf, dort gibt es deshalb nur Kästen.
Die Tonart eines Liedes muss nicht dabeistehen: fehlt sie, wird sie aus den
Akkorden gerechnet (alle 24 Tonarten im Vergleich) — mit ehrlicher Angabe, wie
sicher das ist. Bei Am F C G steht dann „unsicher", weil beides stimmt.
Eigene Griffe
Die Diagramme sind gerechnet — meistens ist das genau richtig, manchmal aber
nicht: G mit dem D auf der H-Saite ist immer noch G-Dur und greift sich doch
anders. Solche Griffe gehören ins Lied, nicht in eine Tabelle irgendwo:
{define: G* base-fret 1 frets 3 2 0 0 3 3}
Das ist die ChordPro-Schreibweise (die Kurzform {define: G* 320033} geht
auch); im Editor trägt man sie durch Antippen ins Griffbrett ein, statt sie
zu tippen. Der Stern am Namen ist ein Variantenmarker: G* ist harmonisch
G — dieselben Töne, dieselbe Stufe, dieselben Skalen —, im Lied aber ein
eigener Akkord, sodass [G] und [G*] nebeneinander stehen können. Ohne Stern
ersetzt die Definition den gerechneten Griff überall im Lied.
Beim Transponieren wandert die Form mit, solange sie sich verschieben lässt. Ein Griff mit leeren Saiten lässt sich das nicht — er fällt dann zurück auf den gerechneten, und die Akkordkarte sagt, warum. Beim Capo bleibt die Form dagegen stehen: man greift dasselbe, es heißt nur anders.
Die Notenschrift
Die Zeichen auf den Notenlinien — Violinschlüssel, ♯ ♭ ♮ 𝄪 𝄫, Notenköpfe —
stammen aus Bravura, der Referenzschrift für SMuFL (Steinberg Media
Technologies, SIL Open Font License 1.1; Wortlaut in lib/BRAVURA-OFL.txt).
Eingebunden ist sie nicht als Schriftdatei, sondern als SVG-Umrisse in
lib/notenzeichen.js — 9 kB statt 500 kB, und vor allem: nichts muss geladen
werden, bevor das Bild stimmt. Die App rechnet ihre Breiten selbst aus und
kennt keine Textmaße; eine Schrift, die erst später ankommt, käme zu spät.
Neu erzeugen (nur nötig, wenn Zeichen dazukommen):
python3 werkzeug/notenzeichen-bauen.py Bravura.otf bravura_metadata.json
Tests
node tests/test_griffe.js # Griffe gegen die üblichen Standardformen
node tests/test_kern.js # ChordPro, Harmonie, Transponieren
node tests/test_skalen.js # Lagen, Akkordskalen, Zirkel, gezeichnete Punkte
node tests/test_noten.js # Schreibweise, Umkehrungen, Vorzeichen, Notenköpfe
node tests/test_griffvarianten.js # eigene Griffe: lesen, speichern, verschieben
node tests/test_stueck.js # was die Übungsseite über die Stücke behauptet
node tests/test_tonuebung.js # Stimmung, Stellen, Aufgabenvorrat, Rollenfarben
node tests/test_tonhoehe.js # Tonhöhe aus synthetischen Signalen
node tests/test_mitlaufen.js # die Tempo-Skala fürs Mitlaufen
python3 -m pytest server/tests
python3 tests/test_app_tempo.py # App in Chromium (braucht playwright)
python3 tests/test_app_griffvarianten.py # dito: eigene Griffe in der App
python3 tests/test_ueben_seite.py # dito: Übungsseite (Tafel und Tonübung)
python3 tests/test_app_tonuebung.py # dito: „Töne finden" quer auf Telefonmaßen
python3 tests/test_app_klang.py # dito: Referenzton, offline gerechnet
python3 tests/test_mikrofon.py # dito: echtes WAV durch getUserMedia —
# Spiel-Modus und Stimmgerät
python3 tests/test_lied_seite.py # Web-Liedansicht: Skalen zum Akkord, Mitlaufen