Kapitel 1
Das Riff
Tommy the Cat von Primus. 210 BPM. Les Claypools Original ist — sagen wir mal — nicht das, was man abends mal eben vom Blatt spielt. Ich hab’s trotzdem versucht, auf meine Art.
Meine Interpretation: vereinfacht, aber bei Original-Tempo spielbar. Kein Slapping im Claypool-Stil, aber Flamenco-Strokes, Hammer-Ons und Groove. Wer das Riff zum ersten Mal hört, denkt an Chaos — in Wirklichkeit ist es ein präzises 16-Note-Muster, das sich wiederholt. Jede Note hat eine definierte Technik, eine definierte Saite, einen definierten Bund.
Das Tab unten zeigt meine Vereinfachung. Der erste Takt startet mit einem Flamenco-Down-Stroke auf Bund 7 (A-Saite) und Bund 9 (D-Saite) gleichzeitig — ein Quint-Akkord. Dann kommt der Up-Stroke, gefolgt von zwei Thumb-Schlägen auf die gemutete E-Saite. Ab Note 5 wird es interessant: ein Hammer-On von G nach G♯ auf der E-Saite, ein gepoppter Hammer-On F nach G auf der D-Saite, dann abwechselnde Slap-Ghost-Notes und offene G-Saite als Pop. Das Muster wiederholt sich — der zweite und alle folgenden Takte starten mit einem Hammer-On statt dem initialen Flamenco-Down-Stroke.
Wer das Riff üben will, sollte es ganz langsam beginnen — 80 BPM, einzelne Noten, bis die Handhaltung stimmt. Das Tempo kommt von selbst.
G|-------------------------------------0-----------0-------------|-------------------------------------0-----------0-------------| D|-9---9-------------------3---5h------------------------------0-|-9h--9-------------------3---5h------------------------------0-| A|-7---7---------------------------------------------------------|-7h--7---------------------------------------------------------| E|---------X---X---3---4-----------4-------4---3-------X---X-----|---------X---X---3---4-----------4-------4---3-------X---X-----| ↓ ↑ T T T H P H T P T T P T T P H ↑ T T T H P H T P T T P T T P 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Legende: ↓ = Flamenco-Down-Stroke ↑ = Flamenco-Up-Stroke T = Thumb (Slap) P = Pop H = Hammer-On h = Hammer-On im Tab (z.B. 5h = Hammer-On auf Bund 5) X = Muted Note (Ghost Note) Takt 1, Note 1-16: 1) Flamenco-Down-Stroke: Bund 7 (A) + Bund 9 (D) gleichzeitig — Quint-Akkord 2) Flamenco-Up-Stroke: Quint-Akkord, andere Saiten stumm (linke Hand) 3) Thumb auf muted E-Saite 4) Thumb auf muted E-Saite 5) Geslapter Hammer-On von G nach G# auf E-Saite 6) G# auf E-Saite (Ziel des Hammer-Ons) 7) Gepoppter Hammer-On F nach G auf D-Saite (Zeigefinger) 8) G auf D-Saite (Ziel des Hammer-Ons) 9) Slap G# (E-Saite, Bund 4) 10) Pop leere G-Saite 11) Slap muted E-Saite 12) Slap G (E-Saite, Bund 3) 13) Pop leere G-Saite 14) Slap muted E-Saite 15) Slap muted E-Saite 16) Pop D-Saite (leer) Ab Takt 2: Note 1 wird zu Hammer-On auf Bund 7 (A) + Bund 9 (D), anschließend Flamenco-Up-Stroke. Alles andere identisch. So weiter.
Zum interaktiven Üben gibt es eine Browser-App unter pmmathias.github.io/TommyTheCat — Tempo justierbar, Drums und Bass getrennt stummschaltbar.
Ehrliche Einschätzung: Meine aktuelle Version liegt bei 210 BPM. Das Primus-Original dürfte eher bei ~230 BPM liegen. Ich übe weiter — und sobald ich es sauberer und näher am Originaltempo spielen kann, werde ich es vermutlich nochmal neu einspielen. Die Practice-App deckt daher den Bereich 180–240 BPM ab: von gemütlich üben bis über das Original hinaus.
Kapitel 2
Die Practice-App
Wer ein Riff bei 210 BPM lernen will, fängt nicht bei 210 BPM an. Das Problem: Drumcomputer-Loops bei 60 % Tempo klingen falsch, weil die Pitches mitskalieren. Ein Schlagzeug bei 100 BPM klingt nicht wie ein Schlagzeug bei 210 BPM in Zeitlupe — es klingt wie ein anderen Instrument.
Die Practice-App löst das mit dem WSOLA-Algorithmus (Waveform Similarity Overlap-Add), implementiert über die SoundTouch-Bibliothek. WSOLA verändert das Tempo, hält aber die Tonhöhe konstant. Ein Snare-Hit bei 60 BPM klingt genau so hoch wie bei 210 BPM — nur langsamer.
Die App läuft vollständig im Browser, braucht keine Installation und funktioniert auf dem Smartphone. Empfohlene Vorgehensweise: Drums an, Bass stumm, Tempo auf 180 BPM runterdrehen. Das Riff auf dem eigenen Bass mitspielen, bis die Finger die Bewegungssequenz kennen. Dann schrittweise hoch — 190, 200, 210 und wer mutig ist: 230+.
WSOLA teilt das Audio-Signal in kurze Überlappungs-Fenster und fügt sie mit angepassten Kreuzkorrelationen neu zusammen — so entsteht ein längeres oder kürzeres Signal ohne Pitch-Shift. Der Algorithmus gehört zur Familie der Time-Scale-Modification-Methoden und ist Standard in professionellen Playback-Systemen.
Kapitel 3
Der Tech-Stack — FFT-Cross-Correlation
Dieses Video besteht aus ZWEI separaten Kamera-Aufnahmen. Ich habe Schlagzeug und Bass getrennt aufgenommen, jedes mit einer eigenen Kamera, und die Aufnahmen waren nicht synchronisiert. Wie bringt man zwei Videos, die zu verschiedenen Zeitpunkten gestartet wurden, auf Sample-genaue Übereinstimmung?
Die Aufnahme-Situation
In GarageBand wurden zwei Audiospuren gleichzeitig über eine Interface-Box aufgezeichnet: E-Drums und Bass. Aber zwei separate Kameras liefen unabhängig — eine auf das Schlagzeug gerichtet, eine auf den Bass. Kein Klatschholz, kein gemeinsamer Auslöser. Die Videos haben also einen unbekannten zeitlichen Versatz, der irgendwo zwischen 0 und mehreren Sekunden liegt.
Manuelles Synchronisieren per Waveform in einem Video-Editor? Möglich — aber fehleranfällig, unreproduzierbar und nervig. Die Alternative: Python + scipy + FFmpeg.
Schritt 1: Audiospuren extrahieren
Jedes Video-File enthält eine Audiospur, die das aufgenommene Instrument (plus Umgebungsgräusche) enthält. FFmpeg extrahiert sie als WAV-Datei. Die Herausforderung: Bass und Schlagzeug haben sehr unterschiedliche Frequenzspektren. Ein Butterworth-Bandpass-Filter trennt die relevanten Signale:
- Schlagzeug: 150–6000 Hz (Snare-Transient, Hi-Hat, Kick-Oberton)
- Bass: 40–300 Hz (Grundton und erste Obertöne)
Der Butterworth-Filter ist ein Standardwerkzeug der Signalverarbeitung: er dämpft Frequenzen außerhalb des Bandes mit maximaler Flachheit im Durchlassbereich. scipy.signal.butter + sosfilt erledigt das in zwei Zeilen.
Schritt 2: Cross-Correlation im Frequenzraum
Die Cross-Correlation zweier Signale \(f\) und \(g\) misst, wie gut sie bei einem bestimmten Zeitversatz übereinstimmen. Der Peak der Kreuzkorrelation liegt genau beim Zeitversatz, bei dem die Signale am besten passen. Statt sie zeitdomänen-weise zu berechnen (langsam, \(O(n^2)\)), nutzen wir das Faltungstheorem:
corr(f, g) = IFFT( FFT(f) · conj(FFT(g)) )
Genau dieselbe Fourier-Transformation, die in unserem Vogelsimulator-Post Ozeanwellen erzeugt, synchronisiert hier Bass und Schlagzeug. Im Frequenzraum wird aus einer zeitaufwendigen Faltung eine einfache Multiplikation — von \(O(n^2)\) auf \(O(n \log n)\).
Das Python-Kern-Snippet (der eigentliche Synchronisations-Code):
import numpy as np
from scipy.signal import butter, sosfilt
def bandpass(signal, lo, hi, sr):
sos = butter(4, [lo, hi], btype='band', fs=sr, output='sos')
return sosfilt(sos, signal)
def find_offset(ref, query, sr):
# FFT-based cross-correlation
n = len(ref) + len(query) - 1
R = np.fft.rfft(ref, n=n)
Q = np.fft.rfft(query, n=n)
corr = np.fft.irfft(R * np.conj(Q), n=n)
peak = np.argmax(corr)
if peak > n // 2:
peak -= n # negative lag
# Sub-sample precision via parabolic interpolation
if 1 <= abs(peak) < len(corr) - 1:
y0, y1, y2 = corr[peak-1], corr[peak], corr[peak+1]
peak += (y2 - y0) / (2 * (2*y1 - y0 - y2))
return peak / sr # offset in seconds
Schritt 3: Parabolische Sub-Sample-Interpolation
Der naive Ansatz nimmt einfach den Index des Korrelations-Peaks und rechnet ihn in Sekunden um. Das Problem: Bei 44.100 Hz Samplerate ist die Auflösung etwa 22 Mikrosekunden — bei 25 fps entspricht ein Frame 40.000 Mikrosekunden. Das reicht.
Aber für 60-fps-Videos lohnt sich die parabolische Interpolation: Wir fitten eine Parabel durch den Peak und seine zwei Nachbarn und berechnen das exakte Subpixel-Maximum. Die Formel steht im Snippet oben. Das Ergebnis: Sub-Sample-genaue Zeitversatz-Bestimmung, die bei 60 fps weit unter einem Frame bleibt.
Schritt 4: FFmpeg-Render
Mit dem berechneten Offset-Wert (in Sekunden) rendert FFmpeg das finale Video. Container-Level Seeks sind dabei effizienter als Re-Encoding:
# offset_s = berechneter Versatz in Sekunden (positiv oder negativ)
# Positiver Offset: Video 2 beginnt später als Video 1
ffmpeg -ss {offset_s} -i drums.mp4 \
-i bass.mp4 \
-filter_complex "[0:v][1:v]hstack=inputs=2[v]" \
-map "[v]" -map 0:a \
output.mp4
Kein Premiere Pro nötig. Kein manuelles Ausrichten von Waveforms. Nur Python + FFmpeg + ein KI-Agent, der das Skript geschrieben hat. Das gesamte Rendering dauert — abhängig von der Videoqualität — unter zwei Minuten.
GarageBand (Aufnahme) → FFmpeg (Audiospuren extrahieren) → scipy Butterworth-Filter (Frequenztrennung) → numpy FFT Cross-Correlation (Offset berechnen) → Parabolische Interpolation (Sub-Sample-Präzision) → FFmpeg (finales Rendering). Vollständig automatisiert, reproduzierbar, frame-genau.
Kapitel 4
Für Content-Producer — So macht ihr das auch
Das Verfahren ist nicht auf Bass-Covers beschränkt. Wer mit mehreren Kameras filmt — Interviews, Konzerte, Tutorials — kann dieselbe Pipeline nutzen, solange die Audiospuren ein gemeinsames Referenzsignal enthalten (was sie fast immer tun: Raumhall, Stimme, Musik).
Das Rezept in fünf Schritten
- Audiospuren getrennt aufnehmen — pro Instrument oder Quelle eine Spur, über ein Audio-Interface oder direkt in die DAW. Kein Click-Track nötig, aber er schadet nicht.
- Videos getrennt aufnehmen — jede Kamera läuft unabhängig. Kein Sync-Signal, kein gemeinsamer Auslöser. Das Python-Skript findet den Versatz automatisch.
- Bandpass-Filter pro Instrument — Drums: 150–6000 Hz, Bass: 40–300 Hz, Gitarre: 80–2000 Hz, Stimme: 100–8000 Hz. Anpassen je nach Quelle.
- Cross-Correlation im Frequenzraum — numpy + scipy, das Snippet von oben. Gibt den Zeitversatz in Sekunden zurück. Typische Laufzeit unter einer Sekunde für 10-Minuten-Audio.
- FFmpeg Render — mit dem berechneten Offset. Nebeneinander (
hstack), übereinander (vstack), Picture-in-Picture (overlay) — alles möglich.
Der Vorteil gegenüber manueller Synchronisation
Manuelles Ausrichten von Waveforms in einem Video-Editor dauert — je nach Länge des Materials — zwischen einer Minute und einer Stunde. Es ist augengesteuertes Schätzen. Wer einmal eine schlecht synchronisierte Aufnahme hochgeladen hat, weiß: Man sieht es sofort. Ein Gitarren-Anschlag, der 80 Millisekunden vor dem Hören sichtbar ist, stört den Zuschauer mehr als man denkt.
Die FFT-Methode ist frame-genau, automatisch und reproduzierbar. Wenn sich am Material etwas ändert — neue Takes, anderer Schnitt — läuft das Skript einfach neu. Kein manuelles Nachjustieren. Kein Premiere Pro. Kein Abonnement.
Das komplette Python-Skript (inklusive FFmpeg-Aufruf, Fortschrittsanzeige und Fehlerbehandlung) lässt sich mit einem KI-Agenten in unter zehn Minuten generieren — Eingabe: die obige Beschreibung. Ausgabe: lauffähiger Code. Genau das ist hier passiert.
pip install numpy scipy soundfile — plus eine FFmpeg-Installation im PATH. Keine weiteren Abhängigkeiten. Das Skript läuft auf macOS, Linux und Windows.
Häufige Fragen
Ist das Les Claypools Originalversion?
Nein. Claypools Originalversion von Tommy the Cat ist eine der technisch anspruchsvollsten Bass-Parts der Rockgeschichte — Slap, Pop, Ghost-Notes und ein perkussiver Stil, der eigene Jahrzehnte der Entwicklung widerspiegelt. Diese Version ist eine vereinfachte Interpretation: kein Claypool-Slapping, stattdessen Flamenco-Strokes und Hammer-Ons. Das Tempo ist original (210 BPM), die Technik ist zugänglicher.
Was ist WSOLA?
WSOLA steht für Waveform Similarity Overlap-Add. Es ist ein Algorithmus zur zeitlichen Skalierung von Audiosignalen ohne Veränderung der Tonhöhe (Pitch-Preservation). Das Signal wird in kurze, überlappende Fenster aufgeteilt; die Fenster werden mit Hilfe von Kreuzkorrelation optimal ausgerichtet und wieder zusammengefügt — länger oder kürzer, je nach gewünschtem Tempo. Das Ergebnis: Ein Schlagzeug-Loop bei 60 BPM klingt genau so wie bei 210 BPM — nur langsamer.
Wie funktioniert die FFT-basierte Video-Synchronisation?
Die Cross-Correlation zweier Audiosignale misst ihre Übereinstimmung bei verschiedenen Zeitversätzen. Der Peak der Kreuzkorrelation liegt genau beim optimalen Versatz. Statt die Korrelation zeitdomänen-weise zu berechnen (\(O(n^2)\)), nutzt das Faltungstheorem die Fourier-Transformation: Im Frequenzraum wird aus der Faltung eine punktweise Multiplikation (\(O(n \log n)\)). Mit parabolischer Interpolation um den Peak herum erreicht man Sub-Sample-Präzision — besser als ein einzelner Videoframe bei 60 fps.