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 ------------- 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. 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 - 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. Es könnte zu ``false positives'' kommen, speziell bei leisem Rauschen. Die Kombination mehrerer 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) 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. 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. 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 http://www.mega-nerd.com/libsndfile[libsndfile] zu beschäftigen. .28.8.2014 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` .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 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?_ .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 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