2014-08-30 00:48:26 +02:00
|
|
|
SynKlick: Aufnahme reparieren
|
|
|
|
|
=============================
|
|
|
|
|
:Date: Sept.2014
|
|
|
|
|
|
|
|
|
|
_Reparieren einer Rohaufnahme mit synchronen 1-Sample-drop-outs auf allen Spuren_
|
|
|
|
|
|
|
|
|
|
Im Sommer 2014 habe ich die Serie der *Mycel-Performances* von Benedikt Brachtel aufgezeichnet.
|
|
|
|
|
In einigen dieser Sitzungen habe ich aus noch ungeklärtem Grund einen regelmäßigen Defekt in der Aufnahme:
|
|
|
|
|
Es findet sich ein Null-Sample synchron auf allen Spuren. Diese sehr spezifische Struktur ermöglicht eine
|
|
|
|
|
rein mechanische Reparatur, für die ich hier ein dediziertes Hilfsprogramm schreibe.
|
|
|
|
|
|
|
|
|
|
Lösungsansatz
|
|
|
|
|
-------------
|
2014-08-30 17:53:18 +02:00
|
|
|
An allen untersuchten Defekt-Stellen habe ich einen Sprung in der Wellenform gefunden, welcher
|
|
|
|
|
offensichtlich auf allen Spuren synchron auftritt. Den untersuchten Wellenformen nach zu urteilen
|
|
|
|
|
fehlen jeweils ca. 50 bis 100 Sampleworte. Da ich keinen XRun von Jack bekommen habe, vermute ich
|
|
|
|
|
einen Defekt in Ardour beim Wegschreiben der Puffer -- möglicherweise als Wechselwirkung mit dem
|
|
|
|
|
re-Draw der Wellenformen; ich hatte nämlich während der Aufnahme das Editorfenster in Anzeige,
|
|
|
|
|
bei relativ hoher Auflösung, so daß ich zur Kontrolle die Wellenform permanent sehen konnte.
|
|
|
|
|
Wackelkontakte an den 3.5-Miniklinken waren immer wieder aufgetreten.
|
2014-08-30 00:48:26 +02:00
|
|
|
|
|
|
|
|
Es geht also darum, einen Satz von Rohdateien Wort für Wort synchron zu prüfen; wenn ein bestimmtes
|
|
|
|
|
Muster auf allen Spuren auftritt, muß die Korrektur ausgelöst werden
|
|
|
|
|
|
2014-08-30 17:53:18 +02:00
|
|
|
- das Muster definiere ich als _einen Sprung in den Deltas_ zwischen benachbarten Samples. Hierfür
|
|
|
|
|
muß ich noch eine passende Triggerschwelle herausfinden.
|
|
|
|
|
- die Korrektur besteht darin, die Kurvenverläufe beidseits des Sprunges künstlich fortzusetzen
|
|
|
|
|
und dann zwischen diesen beiden synthetisierten Verläufen zu überblenden, mit einer Überblendedauer
|
|
|
|
|
von 200 Samples. Als künstliche Fortsetzung wähle ich den invertierten und rückwärts abgespielten
|
|
|
|
|
Ablauf des existierenden Materials.
|
2014-08-30 00:48:26 +02:00
|
|
|
|
|
|
|
|
Es könnte zu ``false positives'' kommen, speziell bei leisem Rauschen. Die Kombination mehrerer
|
2014-08-30 17:53:18 +02:00
|
|
|
Kanäle senkt jedoch die Wahrscheinlichkeit solcher Fehl-Korrekturen. Leider ist die Korrektur selber
|
|
|
|
|
durchaus gefährlich; jedoch stellen die Defekte eine so deutlich hörbare Tonstörung dar, daß jede,
|
|
|
|
|
auch nur graduelle Verbesserung wünschenswert ist. Die Methode der künstlichen Fortsetzung wähle
|
|
|
|
|
ich, weil es der einfachste Ansatz ist, der direkt an der Sprungstelle stetig und einigermaßen
|
|
|
|
|
kohärent, sowie zur Sprungstelle symmetrisch ist. Typischerweise wird es zu einer partiellen
|
|
|
|
|
Auslöschung kommen, also einer kurzen, geräuschhaften Störung. Um den Eingriff möglichst
|
|
|
|
|
unproblematisch zu halten, entscheide ich mich, keine Änderung der Sample-Längen
|
|
|
|
|
zu machen. Es geht hier um Schadensbegrenzung (denn egal, was meine Auftraggeber
|
|
|
|
|
sagen, letztlich bleibt doch ein Eindruck der Unprofessionalität)
|
|
|
|
|
|
2014-08-30 00:48:26 +02:00
|
|
|
|
|
|
|
|
Anmerkungen zur Implementierung
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
Ich verwende die http://www.mega-nerd.com/libsndfile[libsndfile], welche auf Linux-Systemen inzwischen
|
|
|
|
|
zur Standard-Lösung für den Zugriff auf Sound-Dateien geworden ist. Sie bietet ein sauberes API und
|
|
|
|
|
ein brauchbares Programmier-Modell, und sie unterstützt viele Datenformate. Hier konkret geht es
|
|
|
|
|
um Wave-64 mit floating-point-Samples.
|
|
|
|
|
|
|
|
|
|
Das Korrektur-Programm bekommt die Namen aller Quell-Spuren und ein Zielverzeichnis, wo es die korrigierten
|
|
|
|
|
Ströme in identisch zur Quelle benannte Sample-Dateien schreibt. In der eigentlichen Verarbeitung verwenden
|
|
|
|
|
wir nur die erste Quellspur zur Suche; ein erkanntes Muster muß dann auf allen anderen Spuren bestätigt werden.
|
|
|
|
|
Dies erfordert, von einer gegebenen Position auch stets auf das _Vorgänger-_ und __Nachfolger-__Sample zugreifen
|
|
|
|
|
zu können, was besondere Vorsicht an den Puffergrenzen bedingt. Dies werde ich durch entsprechende Abstraktion
|
|
|
|
|
und Trennung des Lese- vom Verarbeitungsvorgang lösen.
|
|
|
|
|
|
2014-09-05 00:51:58 +02:00
|
|
|
Im Detail wird die Entscheidungs-Logik einigermaßen komplex, da wir gezwungenermaßen auch einige gemischte
|
|
|
|
|
und nicht regelmäßige Fälle mit abdecken müssen. Dadurch gewinnt dieses Werkzeug aber auch eine größere
|
|
|
|
|
Einsatzbreite.
|
|
|
|
|
|
|
|
|
|
- die Entscheidung, ob tatsächlich ein zu behandelndes Ereignis vorliegt, wird durch eine
|
|
|
|
|
gewichtete Abstimmung aller beteiligten Spuren getroffen. Es zählt die Stärke des Sprunges.
|
|
|
|
|
- die genaue Stelle des Sprunges wird mit einer geringen Toleranz ggfs noch um wenige Samples
|
|
|
|
|
vor- oder zurück-justiert, so daß auch _nur fast synchrone_ Defekte mit erfaßt werden.
|
|
|
|
|
- wenn sich vor oder hinter dem Sprung ein drop-Out befindet, wird dieser _vor_ Aufbringen
|
|
|
|
|
der eigentlichen Korrektur durch eine einfache, lineare Verbindung ersetzt, so daß die
|
|
|
|
|
durch den drop-Out bedingten, zusätzlichen Sprung-Stellen schon beseitigt sind.
|
|
|
|
|
- eine Spur, welche _definitiv keinen_ Defekt aufweist, wird grundsätzlich nicht repariert.
|
|
|
|
|
|
2014-08-30 00:48:26 +02:00
|
|
|
|
|
|
|
|
Arbeitsnotizen
|
|
|
|
|
--------------
|
|
|
|
|
.Juli 2014
|
|
|
|
|
Nach Abschluß der Aufnahmen stelle ich in mindestens zwei der Sitzungen einen regelmäßigen Defekt fest.
|
|
|
|
|
Nach Analyse beschließe ich, eine Reparatur zu versuchen. Dies ist auch ein Anlaß, mich einmal mit der
|
2014-08-31 03:31:46 +02:00
|
|
|
http://www.mega-nerd.com/libsndfile[libsndfile] zu beschäftigen.
|
2014-08-30 00:48:26 +02:00
|
|
|
|
|
|
|
|
.28.8.2014
|
2014-08-30 17:22:32 +02:00
|
|
|
Nach Rückkehr von meiner üblichen Ende-August-FrOSCon-Reise wird diese Aufgabe nun dringend. +
|
|
|
|
|
Lege einen Projektrahmen an und implementiere des Öffnen der Dateien via `libsndfile`
|
2014-08-30 00:48:26 +02:00
|
|
|
|
2014-08-30 17:53:18 +02:00
|
|
|
.30.8.2014
|
|
|
|
|
_Leider_ ist die Aufgabe nicht so einfach wie vermutet. Habe mir nun die Wellenformen im Detail angeschaut
|
|
|
|
|
und drei Probe-Schnipsel zur Entwicklung und für Tests extrahiert. Es handelt sich nicht wie anfangs vermutet,
|
|
|
|
|
um punktuell auf allen Spuren auftretende Null-Werte. Sondern vielmehr um einen ganz gewöhnlichen *Verlust von
|
|
|
|
|
Samples*. Das heißt, es fehlt -- synchron auf allen Spuren -- ein Stück Tonaufzeichnung unbekannter Länge, so
|
2014-08-31 03:31:46 +02:00
|
|
|
daß an der betreffenden Stelle ein Sprung in allen Wellenformen auftritt.
|
|
|
|
|
|
|
|
|
|
- Damit ändert sich das Konzept. Ich muß wohl einen Sprung in den Deltas zwischen benachbarten Samples erkennen,
|
|
|
|
|
und dies, zur Sicherheit, auf mehreren Spuren parallel. Und ein Sprung ist nicht so einfach zu erkennen, denn
|
|
|
|
|
er kann (mit guter Wahrscheinlichkeit) zufällig ehr gering ausfallen -- für eine zuverlässige Erkennung müßten
|
|
|
|
|
wir in der Frequenzdomäne arbeiten, was hier den gegebenen Rahmen sprengen würde. +
|
|
|
|
|
So sind wir also auf eine Heuristik mit empirisch abzustimmenden Trigger-Schwellen angewiesen.
|
|
|
|
|
- Auch ist die Korrektur wesentlich mühsamer, wenn nicht sogar unmöglich.
|
|
|
|
|
In Anlehnung an mein altes `streckDich`-Skript mache ich eine kurze Kreuzblende, mit der damals als optimal
|
|
|
|
|
ausgeknobelten Länge von 4.5ms (200 Samples).
|
|
|
|
|
- das große Problem ist bloß: _woher bekomme ich das zusätzliche Material für die Kreuzblende?_
|
|
|
|
|
|
2014-09-05 00:51:58 +02:00
|
|
|
.31.8.2014
|
|
|
|
|
Nun habe ich einen ganzen Arbeitstag gebraucht, diese komplexere Entscheidungs-Logik zu implementieren,
|
|
|
|
|
zu testen und zu optimieren. Ich verwende nun ein gewichtetes Mittel, um die Stärke des erkannten Sprunges
|
|
|
|
|
in die Entscheidung einfließen zu lassen; häufig liegt nämlich auch auf den anderen Spuren ein Sprung knapp
|
|
|
|
|
unter der Trigger-Schwelle vor; das negativ-Votum solcher Spuren fällt nun geringer aus, als das Votum einer
|
|
|
|
|
Spur, die nun wirklich kontinuierlich ist. Damit komme ich an den ausgewählten Probe-Samples zu klaren
|
|
|
|
|
Entscheidungen. +
|
|
|
|
|
Als Kompensation habe ich zunächst das fehlende Signal ganz einfach durch _Rückwärts-Abspielen_ der Wellenform
|
|
|
|
|
gewonnen. Das funktioniert im _Idealfall_ verblüffend gut -- man hört nur noch ein klopfendes Geräusch.
|
|
|
|
|
Die Kompensation funktioniert allerdings oft nicht befriedigend, denn es treten zusätzliche Komplikationen auf:
|
|
|
|
|
|
|
|
|
|
- bei manchen Sprung-Ereignissen, liegt die Diskontinuität um ein bis zwei Samples verschoben auf den
|
|
|
|
|
Spuren vor. Die Sprünge sind also nur _fast_ synchron.
|
|
|
|
|
- direkt anschließend an den Sprung tritt auch öfters tatsächlich eine kurze Strecke von Null-Werten auf.
|
|
|
|
|
Dies hatte mich wohl ursprünglich zur falschen Diagnose geführt, es handele sich um drop-Outs.
|
|
|
|
|
|
|
|
|
|
Die Wirklichkeit ist eben _widerständig_ -- einfache Methoden funktionieren nur in einer konditionierten
|
|
|
|
|
Umgebung. Hier führen also die Verschiebungen dazu, daß Ereignisse nicht, oder doppelt erkannt werden.
|
|
|
|
|
Und die im Idealfall sehr gut funktionierende Reparatur mit dem gespiegelten Signal führt bei den Null-Strecken
|
|
|
|
|
dazu, daß ein weiterer Sprung (am anderen Ende des drop-Out) _rückwärts_ in das ursprünglich saubere Signal
|
2014-09-05 02:24:07 +02:00
|
|
|
verschleppt wird. Das heißt, in diesem Fall verschlimmert die ``Korrektur'' den Schaden.
|
|
|
|
|
|
|
|
|
|
.5.9.2014
|
|
|
|
|
Insgesamt hat erst die Kombination der verschiedenen Ansätze zum Erfolg geführt
|
|
|
|
|
|
|
|
|
|
- relativ elaborierte Entscheidungslogik, die mehrere Spuren korreliert
|
|
|
|
|
- Gewichtung durch die Stärke des Sprunges
|
|
|
|
|
- Suche auch in der nächsten Umgebung für die Korrelation
|
|
|
|
|
- Feinjustieren auf den maximalen Sprung in jeder bearbeiteten Spur
|
|
|
|
|
- zusätzliches Interpolieren über eine drop-out-Strecke
|
|
|
|
|
- 4.5ms langer ``Patch'' mit dem gespiegelten Signal
|
2014-08-30 17:53:18 +02:00
|
|
|
|