Timestretching um 10 Prozent mit atempo und rubberband: Timing, Transienten, Klang und Stereobild gemessen

Inhalt
- Wie gemessen wurde
- Zeit: rubberband trifft sie, atempo verschiebt einzelne Schläge
- Transienten: rubberband baut vor dem Schlag eine Rampe auf
- Reine Töne: die Vorgabe von rubberband bricht ein
- Obertonreiche Töne: kein Verfahren bleibt bei jedem Grundton sauber
- Stereobild, Pegel und Rechenzeit
- Was daraus folgt
- Reichweite und Grenzen
- Fragen und Antworten
- Quellen
ffmpeg bringt zwei Filter mit, die das Tempo ändern und dabei die Tonhöhe beibehalten. atempo ist direkt in ffmpeg implementiert und arbeitet nach dem Verfahren WSOLA: Es schneidet den Ton in überlappende Stücke und verschiebt jedes Stück so, dass es möglichst genau an das vorherige anschließt. rubberband reicht den Ton an die Rubber Band Library weiter, die im Frequenzbereich arbeitet und an Transienten eigene Regeln anwendet.
Gemessen wurde bei Tempo 0,9 und 1,1, also bei der Dehnung, die aus einem Titel mit 120 BPM einen mit 108 oder 132 BPM macht. Untersucht wurden die Auswirkungen auf vier Eigenschaften des Signals: Timing, einzelne Schläge, Töne und Stereobild. Welches Verfahren besser klingt, war nicht Gegenstand der Messung.

Wie gemessen wurde
- Verfahren: ffmpeg 7.1.5 mit Rubber Band Library 3.3.0, 44,1 kHz, Ausgabe in 32 Bit Gleitkomma.
atempoundrubberbandin der Vorgabe, dazurubberbandmittransients=mixed,transients=smooth,window=longundchannels=together. - Zeit: 20 kurze Klicks aus je 2 ms eines 3-kHz-Tons im Abstand von 0,5 s. Gemessen wurden die Länge der Ausgabe, die Lage jedes Klicks gegen die Sollage und ob alle Klicks ankommen.
- Schläge: 12 einzelne Kicks und Snares im Abstand von gut einer Sekunde, jeder um 37 ms weiter gegen das Raster verschoben, damit er andere Stellen der Fenster trifft. Ausgewertet wurde eine Hüllkurve aus 3 ms RMS: der Zeitpunkt, an dem sie die halbe Spitze erreicht, und ihr Pegel 10 und 20 ms davor.
- Töne: reine Sinustöne bei 110, 440 und 1760 Hz und Sägezähne bei 55, 110, 220 und 440 Hz, je 5 s, gedehnt mit den Tempi 0,9, 0,95, 1,05 und 1,1. Beim Sinus zählt, wie tief der Pegel in 10-ms-Fenstern unter seinen Mittelwert fällt. Beim Sägezahn zählt die Energie zwischen den Obertönen, bezogen auf die gesamte Energie und verglichen mit dem unbearbeiteten Sägezahn.
- Mix: 16 s Stereo aus Kick, Snare, Hi-Hats, Bass, Fläche und Lead. Gemessen wurden die Korrelation der beiden Kanäle, der Pegel und die Rechenzeit, von dieser der kürzeste von drei Läufen.
- Gegenproben: Die erste Zählung von Doppelschlägen fand schon im unbearbeiteten Schlag 10 bis 13 Einsätze, weil eine Hüllkurve aus 0,25 ms den Schwingungen des Kicks folgt; gezählt wird deshalb auf 3 ms und immer mit dem Original daneben. Der erste Lauf mit nur einem Sägezahn bei 110 Hz ließ
atemposauber erscheinen, die Reihe über vier Grundtöne zeigt, dass das eine Ausnahme war.
Zeit: rubberband trifft sie, atempo verschiebt einzelne Schläge
| Verfahren | Länge gegen Soll, 0,9 / 1,1 | Versatz im Mittel, 0,9 / 1,1 | größter Zeitfehler je Schlag, 0,9 / 1,1 |
|---|---|---|---|
atempo |
−26,6 / −20,7 ms | −15,2 / −19,9 ms | 10,84 / 8,37 ms |
rubberband, Vorgabe (crisp) |
0,0 / 0,0 ms | −3,7 / +3,0 ms | 0,37 / 0,47 ms |
rubberband, transients=mixed |
0,0 / 0,0 ms | −3,7 / +3,0 ms | 1,52 / 2,00 ms |
rubberband, transients=smooth |
0,0 / 0,0 ms | −4,2 / +3,7 ms | 0,46 / 0,62 ms |
rubberband, window=long |
0,0 / 0,0 ms | −7,3 / +5,7 ms | 0,75 / 0,61 ms |
rubberband, channels=together |
0,0 / 0,0 ms | −3,6 / +3,0 ms | 0,41 / 0,48 ms |
Ein negativer Wert heißt früher oder kürzer als gefordert. Alle 20 Klicks kamen bei jedem Verfahren an. rubberband lieferte die Länge auf den Abtastwert genau und setzte jeden Schlag in der Vorgabe, mit smooth und mit together innerhalb von 0,62 ms an seinen Platz, mit window=long innerhalb von 0,75 ms und mit mixed innerhalb von 2,00 ms. Das war nicht selbstverständlich: Der Filter startet die Bibliothek im Echtzeitmodus, und dort findet laut ihrer Dokumentation am Anfang des Signals keine Verzögerungs- oder Latenzkorrektur statt. Übrig blieb ein Versatz von 3,0 bis 7,3 ms, der mit der Richtung der Dehnung das Vorzeichen wechselt.
atempo setzte die ganze Ausgabe 15 bis 20 ms zu früh an und lieferte sie 21 bis 27 ms zu kurz. Für das Timing wiegt der wechselnde Fehler schwerer: Er war von Schlag zu Schlag verschieden und erreichte bei Tempo 0,9 bis 10,84 ms, bei 1,1 bis 8,37 ms. Das Verfahren schneidet den Ton in Fenster von 2048 Abtastwerten, bei 44,1 kHz also 46,4 ms. Jedes Fenster wird dort angesetzt, wo es am besten zum vorherigen passt. Ein Schlag innerhalb dieses Fensters wird dabei mitverschoben.
Transienten: rubberband baut vor dem Schlag eine Rampe auf
| Verfahren | Spitze Kick, 0,9 / 1,1 | Spitze Snare, 0,9 / 1,1 | Pegel 10 ms vorher, 0,9 / 1,1 | Pegel 20 ms vorher, 0,9 / 1,1 |
|---|---|---|---|---|
atempo |
−0,11 / −0,20 dB | −0,24 / −0,06 dB | −24,8 / −39,6 dB | keiner |
rubberband, Vorgabe (crisp) |
−1,43 / −0,67 dB | −1,99 / −1,75 dB | −22,8 / −16,3 dB | −35,9 / −29,3 dB |
rubberband, transients=mixed |
−0,90 / −1,64 dB | −0,54 / −1,82 dB | −14,5 / −12,3 dB | −25,6 / −20,6 dB |
rubberband, transients=smooth |
−0,73 / −1,28 dB | −0,88 / −1,60 dB | −20,3 / −14,9 dB | −33,1 / −30,4 dB |
rubberband, window=long |
−1,15 / −1,14 dB | −1,77 / −1,61 dB | −14,1 / −14,7 dB | −20,0 / −17,1 dB |
rubberband, channels=together |
−0,93 / −1,31 dB | −1,63 / −1,19 dB | −21,4 / −17,9 dB | −33,8 / −34,3 dB |
Die Pegel vor dem Schlag sind auf seine Spitze bezogen und jeweils der höchste Wert aus zwölf Schlägen. Im Original ist dort Stille. Mit rubberband steigt die Hüllkurve schon 30 ms vor dem Schlag aus dem Rauschen auf und erreicht 10 ms vorher −12,3 bis −22,8 dB, mit window=long stehen 20 ms vorher noch −17,1 dB. Der Schlag selbst verliert 0,5 bis 2,0 dB an Spitze. Das Diagramm zeigt diese Rampe bei beiden Einstellungen.
atempo hat keine Rampe; 20 ms vor dem Schlag steht nichts. Die Werte 10 ms vorher stammen von etwas anderem: Bei manchen Schlägen setzt ein Teilstück des Anschlags einige Millisekunden vor dem eigentlichen Einsatz an, dazwischen liegt ein Einbruch. Die Spitze bleibt dabei erhalten, auf 0,24 dB.
Reine Töne: die Vorgabe von rubberband bricht ein
| Verfahren | Sinus 110 Hz, 0,9 / 1,1 | Sinus 440 Hz, 0,9 / 1,1 | Sinus 1760 Hz, 0,9 / 1,1 |
|---|---|---|---|
atempo |
−0,4 / −0,4 dB | −0,1 / −0,1 dB | 0,0 / 0,0 dB |
rubberband, Vorgabe (crisp) |
−1,7 / −2,0 dB | −4,4 / −7,4 dB | −7,6 / −11,5 dB |
rubberband, transients=mixed |
−1,7 / −2,0 dB | −0,1 / −0,2 dB | −7,6 / −11,5 dB |
rubberband, transients=smooth |
−0,3 / −0,3 dB | −0,1 / −0,1 dB | −0,1 / −2,7 dB |
Die Zahlen geben an, wie tief der Pegel eines gleichmäßigen Tons in einem 10-ms-Fenster unter seinen Mittelwert fällt. In der Vorgabe erkennt rubberband auch in einem reinen Sinus Transienten und setzt dort die Phasen zurück, wie es die Dokumentation für die Einstellung crisp beschreibt. Das Ergebnis sind Einbrüche bis 11,5 dB, bei Tempo 0,95 und 110 Hz 10,4 dB. Bei 440 Hz schwankte die Tonhöhe dabei zwischen −7,0 und +11,5 Cent, bei 110 Hz war im Spektrum keine saubere Linie mehr abzulesen.
transients=mixed setzt die Phasen laut Dokumentation nur außerhalb des Bereichs typischer Grundtöne zurück, und genau so sieht die Tabelle aus: 440 Hz bleibt ruhig, 110 und 1760 Hz brechen ein wie in der Vorgabe. transients=smooth setzt nie zurück und hält den Ton bis auf einen Fall innerhalb von 0,4 dB, mit 0,0 Cent Abweichung. atempo hält den Pegel ebenso, verschiebt die Tonhöhe aber um einen festen kleinen Betrag, bei 440 Hz um +0,4 Cent bei Tempo 0,9 und −0,4 Cent bei 1,1.
Obertonreiche Töne: kein Verfahren bleibt bei jedem Grundton sauber
| Verfahren, Tempo 0,9 | 55 Hz | 110 Hz | 220 Hz | 440 Hz |
|---|---|---|---|---|
| Original, Störanteil absolut | −50,1 dB | −47,1 dB | −43,9 dB | −41,0 dB |
atempo |
+40,3 dB | +1,4 dB | +10,5 dB | +3,4 dB |
rubberband, Vorgabe (crisp) |
+40,7 dB | +41,4 dB | +37,2 dB | +28,8 dB |
rubberband, transients=mixed |
+40,8 dB | +41,0 dB | +24,8 dB | +23,3 dB |
rubberband, transients=smooth |
+26,1 dB | +4,2 dB | +10,5 dB | +15,3 dB |
Die Zeilen der Verfahren geben an, um wie viel die Energie zwischen den Obertönen über der des Originals liegt. Ein Sägezahn hat Obertöne bis in den Hochton und steht für Bass, Flächen und Leads. Über alle vier Tempi reichte der Zuwachs bei atempo von 1,4 bis 40,3 dB, in der Vorgabe von rubberband von 15,4 bis 46,5 dB, mit transients=smooth von 4,2 bis 26,1 dB.
Der Ausreißer von atempo ist der tiefe Ton. Bei 55 Hz und Tempo 0,9 liegt der Störanteil bei −9,8 dB unter der Gesamtenergie, der Pegel bricht um 5,2 dB ein, und die Tonhöhe wandert bis +20,4 Cent. Eine Periode ist dort 802 Abtastwerte lang, das Fenster 2048; es findet nicht mehr zu jeder Stelle ein passendes Gegenstück. Bei Tempo 1,1 sinkt derselbe Wert auf +10,3 dB, bei 110 Hz war atempo in allen vier Tempi innerhalb von 2,0 dB des Originals.
Stereobild, Pegel und Rechenzeit
| Verfahren | Korrelation nachher, 0,9 / 1,1 | Pegel des Mix, 0,9 / 1,1 | schneller als Echtzeit, 0,9 / 1,1 |
|---|---|---|---|
atempo |
0,922 / 0,919 | −0,03 / −0,05 dB | 26,0 / 18,9-fach |
rubberband, Vorgabe (crisp) |
0,894 / 0,903 | −0,55 / −0,65 dB | 6,5 / 6,9-fach |
rubberband, transients=mixed |
0,749 / 0,757 | −1,10 / −1,34 dB | 5,6 / 7,1-fach |
rubberband, transients=smooth |
0,531 / 0,495 | −2,61 / −2,95 dB | 5,0 / 5,5-fach |
rubberband, window=long |
0,906 / 0,909 | −0,44 / −0,71 dB | 3,7 / 6,2-fach |
rubberband, channels=together |
0,920 / 0,919 | −0,55 / −0,65 dB | 5,1 / 4,7-fach |
rubberband, smooth und together |
0,911 / 0,912 | −2,66 / −3,03 dB | 5,0 / 7,4-fach |
rubberband, mixed und together |
0,940 / 0,935 | −1,12 / −1,35 dB | 5,5 / 8,1-fach |
Vor der Dehnung lag die Korrelation bei 0,92. rubberband bearbeitet die Kanäle in der Vorgabe getrennt; laut Dokumentation führt das zu einem diffuseren Stereobild und weniger Monoverträglichkeit. Mit smooth fiel die Korrelation auf 0,49, mit mixed auf 0,75. channels=together hält sie in jeder Kombination über 0,91.
Der Pegelverlust von smooth wird dadurch nicht behoben: Der Mix ist auch mit together um 2,6 bis 3,0 dB leiser. Der Verlust entsteht also innerhalb der Kanäle. Wie sich die Korrelation Deines Mixes vor und nach der Bearbeitung verhält, zeigt die Messung von Stereo-Korrelation und Mid/Side.
Auf dem Raspberry Pi 4 lief atempo 19- bis 26-mal schneller als Echtzeit, rubberband 3,7- bis 8,1-mal. Beides reicht für jede Datei; im Takt eines laufenden Projekts wäre der Unterschied dagegen spürbar.
Was daraus folgt
- Für Schlagzeug und ganze Mixe, bei denen das Timing zählt:
rubberband=tempo=…:channels=together. Jeder Schlag lag innerhalb von 0,48 ms an seinem Platz, das Stereobild blieb bei 0,92. Der Preis sind die Einbrüche an gleichmäßigen Tönen und die Rampe vor jedem Schlag. - Für Flächen, Gesang und gehaltene Töne:
rubberband=tempo=…:transients=smooth:channels=together. Reine Töne blieben fast unverändert, das Stereobild bei 0,91, die Obertöne mit 4 bis 26 dB Zuwachs am wenigsten beschädigt. Der Mix wird 2,6 bis 3,0 dB leiser und gehört danach neu auf Lautheit gebracht. atempodort, wo keine festen Schläge und keine tiefen Töne liegen. Klang, Pegel und Stereobild blieben am besten erhalten, aber einzelne Schläge wanderten um bis zu 10,84 ms, und ein Ton von 55 Hz verlor bei Tempo 0,9 den Großteil seiner Sauberkeit.- Das Tempo als Faktor: 120 auf 132 BPM ist Tempo 1,1, 120 auf 108 BPM Tempo 0,9. Welche Verzögerungszeiten und Notenlängen zum neuen Tempo gehören, rechnet der BPM- und Delay-Rechner aus.
Reichweite und Grenzen
- Gemessen wurden synthetische Signale, keine Aufnahmen. Stimme, akustische Instrumente und Hall wurden nicht geprüft, und ein Hörtest war nicht Teil der Messung.
- ffmpeg bietet für
rubberbandkeine Wahl des Rechenkerns an und benutzt damit den älteren Kern R2. Laut Dokumentation liefert der Kern R3 bei den meisten Signalen bessere Ergebnisse, besonders bei komplexen Mixen, Gesang und viel Bass, braucht aber deutlich mehr Rechenleistung. Über ffmpeg ist er nicht erreichbar. - Die Rechenzeiten gelten für einen Raspberry Pi 4 unter wechselnder Last; auf anderer Hardware ändern sich die absoluten Werte.
- Die Grenzen der Auswertung, 3 ms für die Hüllkurve und 10-ms-Fenster für den Pegel, bestimmen mit, wie groß ein Einbruch erscheint. Kürzere Fenster zeigen tiefere Einbrüche.
Fragen und Antworten
Was ist zu beachten, wenn einzelne Spuren eines Projekts getrennt gedehnt werden?
Vor allem, dass jede Spur dieselben Fehler bekommt, sonst verschieben sich die Spuren gegeneinander. Bei rubberband sind die Fehler berechenbar: Die Länge stimmt auf den Abtastwert, und der verbleibende Versatz hängt von der Einstellung ab. Bei Tempo 0,9 lag er in der Vorgabe bei −3,7 ms, mit window=long bei −7,3 ms. Wird das Schlagzeug mit der einen und die Fläche mit der anderen Einstellung gedehnt, liegen beide danach 3,6 ms auseinander, ein fester Betrag, der sich durch Verschieben einer Spur ausgleichen lässt.
Bei atempo geht das nicht. Der Fehler je Schlag entsteht dort, wo ein Fenster über den Schlag fällt, und diese Stellen hängen vom Signal ab. Zwei getrennt gedehnte Spuren bekommen deshalb verschiedene Fehler, die im Test bis 10,84 ms reichten, und kein fester Versatz gleicht sie aus. Für Spuren, die zusammen im Takt bleiben müssen, spricht das für rubberband mit einer gemeinsamen Einstellung oder für einen kurzen Klick am Anfang jeder Spur, an dem sich der tatsächliche Versatz nach dem Dehnen ablesen lässt.
Hilft window=long gegen die Rampe vor dem Schlag?
Nein, eher im Gegenteil. Mit window=long standen 20 ms vor dem Schlag noch −17,1 dB, der höchste Wert aller Einstellungen in dieser Spalte, denn ein längeres Fenster verteilt Energie weiter in der Zeit. Kleiner bleibt die Rampe mit der Vorgabe, mit smooth oder mit together, die 20 ms vorher alle bei höchstens −29,3 dB lagen.
Quellen
- ffmpeg: Filters Documentation: die Abschnitte zu
atempoundrubberband; die Optionen und Vorgaben stammen aus der eingebauten Hilfe von ffmpeg 7.1.5. - FFmpeg, libavfilter/af_atempo.c: WSOLA als Verfahren und die Fenstergröße aus Abtastrate durch 24, aufgerundet auf eine Zweierpotenz.
- FFmpeg, libavfilter/af_rubberband.c: der Start der Bibliothek im Echtzeitmodus und ohne Wahl des Rechenkerns.
- Rubber Band Library: RubberBandStretcher: die Kerne R2 und R3 und welcher davon voreingestellt ist, die fehlende Latenzkorrektur im Echtzeitmodus, die Einstellungen für Transienten, Fenster und Kanäle.