Interpolation über drop-Outs mit eingebaut. Nun erfolgreich

This commit is contained in:
Fischlurch 2014-09-05 02:24:07 +02:00
parent 109adce56c
commit 8cd333bba7
2 changed files with 75 additions and 9 deletions

View file

@ -153,6 +153,13 @@ class EventScore
/**
* single sound channel with the ability to investigate itself.
* Internally holds a work buffer to be filled through libsndfile.
* The #visit function performs the decision logic to detect a defect
* at the "current" position, including the next neighbouring samples.
*/
class Channel class Channel
{ {
SNDFILE *in_ = nullptr, SNDFILE *in_ = nullptr,
@ -267,6 +274,15 @@ class Channel
event.recordNeutral(); event.recordNeutral();
} }
/** if it ain't broken, don't fix it */
bool
reallyNeedsFix()
{
float changeFactor = delta(workPos_) / (ema_ + EPSILON);
return changeFactor > 0.25 * TRIGGER_FACTOR;
}
private: private:
float float
sampleLevel() sampleLevel()
@ -351,20 +367,44 @@ class Patch
void void
reconstructMirroredSignal() reconstructMirroredSignal()
{ {
for (uint i=0; i < LEN; ++i) for (size_t i=0; i < LEN; ++i)
workBuff[i] = rawBuff[LEN-1 - i]; workBuff[i] = rawBuff[LEN-1 - i];
} }
void
public: maybe_fix_Gap()
Patch (Channel& c)
: rawBuff{c.accessCurrentContext()}
{ {
reconstructMirroredSignal(); const size_t CENTRE = CONTEXT;
size_t i = CENTRE-1;
while (i > 0 && 0.0f == workBuff[i]) --i;
if (i < CENTRE-1)
fix_Gap_by_Interpolation(i, CENTRE);
i = CENTRE;
while (i < LEN-1 && 0.0f == workBuff[i]) ++i;
if (i > CENTRE)
fix_Gap_by_Interpolation(CENTRE-1, i);
} }
void void
apply() fix_Gap_by_Interpolation(size_t s, size_t e)
{
assert (s+1 < e);
assert (0 <= s && s+1 < LEN);
assert (0 <= e && e < LEN);
float before = workBuff[s];
float after = workBuff[e];
for (size_t i = s+1; i<e; ++i)
{
float fade = float(i-s) / float(e-s);
workBuff[i] = rawBuff[LEN-1 - i]
= (1.0-fade)*before + fade*after;
}
}
void
mix_faded_with_mirroredSignal()
{ {
for (uint i=0; i < LEN; ++i) for (uint i=0; i < LEN; ++i)
{ {
@ -382,6 +422,21 @@ class Patch
rawBuff[i] = q*rawBuff[i] + p*workBuff[i]; rawBuff[i] = q*rawBuff[i] + p*workBuff[i];
} }
} }
public:
Patch (Channel& c)
: rawBuff{c.accessCurrentContext()}
{
reconstructMirroredSignal();
}
void
apply()
{
maybe_fix_Gap();
mix_faded_with_mirroredSignal();
}
}; };
@ -460,7 +515,8 @@ process()
{ {
cout << "PATCH at: "<< absStartPos+i <<"\n"; cout << "PATCH at: "<< absStartPos+i <<"\n";
for (Channel& channel : streams) for (Channel& channel : streams)
Patch(channel).apply(); if (channel.reallyNeedsFix())
Patch(channel).apply();
} }
} }

View file

@ -117,5 +117,15 @@ Die Wirklichkeit ist eben _widerständig_ -- einfache Methoden funktionieren nur
Umgebung. Hier führen also die Verschiebungen dazu, daß Ereignisse nicht, oder doppelt erkannt werden. 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 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 dazu, daß ein weiterer Sprung (am anderen Ende des drop-Out) _rückwärts_ in das ursprünglich saubere Signal
verschleppt wird. Das heitßt, in diesem Fall verschlimmert die ``Korrektur'' den Schaden. 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