Erkennung von Signal-Sprüngen implementiert
This commit is contained in:
parent
7f6ea5e614
commit
910e85a90a
1 changed files with 50 additions and 11 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
SynKlick - repair synchronous drop-outs in raw sound recording
|
||||
SynKlick - repair synchronous skips in raw sound recording
|
||||
|
||||
(C) Ichthyostega (Hermann Vosseler), 2014
|
||||
|
||||
|
|
@ -14,19 +14,25 @@ GNU PUBLIC LICENCE (GPL) Version 2 and above.
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::abs;
|
||||
|
||||
const size_t BUFF_SIZE = 20000; //44100; ///TODO for debugging
|
||||
const size_t CHUNK_SIZE = 20000; //44100; ///TODO for debugging
|
||||
const size_t CONTEXT = 100;
|
||||
const size_t CHUNK_SIZE = BUFF_SIZE + 2*CONTEXT;
|
||||
const size_t BUFF_SIZE = CHUNK_SIZE + 2*CONTEXT;
|
||||
|
||||
const float EPSILON = 1.0f / (1 << 23); // one normalised sample step for 24bit samples
|
||||
const float SILENCE_GATE = 1024.0f * EPSILON;// signal below this level (-39dB) is too low to detect jumps
|
||||
const float TRIGGER_FACTOR = 6.0f; // discontinuity detected by local change compared to average change
|
||||
const uint AVERAGE_SAMPLES = 50; // number of past samples to use for average delta
|
||||
|
||||
/* ==== Helpers ==== */
|
||||
|
||||
|
|
@ -74,9 +80,10 @@ class Channel
|
|||
SF_INFO info_in_,
|
||||
info_out_;
|
||||
|
||||
float buff_[CHUNK_SIZE];
|
||||
float buff_[BUFF_SIZE];
|
||||
size_t numSamples_ = 0;
|
||||
size_t workPos_ = 0;
|
||||
float ema_ = 1.0f / TRIGGER_FACTOR;
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -120,9 +127,9 @@ class Channel
|
|||
void
|
||||
fillBuffer()
|
||||
{
|
||||
assert(numSamples_ < CHUNK_SIZE);
|
||||
assert(numSamples_ < BUFF_SIZE);
|
||||
float* startPos = buff_ + numSamples_;
|
||||
size_t samplesToRead = CHUNK_SIZE - numSamples_;
|
||||
size_t samplesToRead = BUFF_SIZE - numSamples_;
|
||||
numSamples_ = sf_read_float(in_, startPos, samplesToRead);
|
||||
if (numSamples_ < samplesToRead)
|
||||
hitEnd = true; // causes the processing to end with this chunk.
|
||||
|
|
@ -170,10 +177,35 @@ class Channel
|
|||
&& workPos_ <= i)
|
||||
{
|
||||
workPos_ = i;
|
||||
float averageDelta = updateMovingAverage();
|
||||
float changeFactor = delta() / (averageDelta + EPSILON);
|
||||
if (event != NO && SILENCE_GATE < abs(sample()))
|
||||
event = (changeFactor > TRIGGER_FACTOR? YES : NO);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
private:
|
||||
float
|
||||
sample()
|
||||
{
|
||||
return buff_[workPos_];
|
||||
}
|
||||
|
||||
float
|
||||
delta()
|
||||
{
|
||||
if (0 < workPos_)
|
||||
return abs(buff_[workPos_] - buff_[workPos_-1]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
updateMovingAverage()
|
||||
{
|
||||
return ema_ = (delta() + ema_*(AVERAGE_SAMPLES - 1)) / AVERAGE_SAMPLES;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -199,7 +231,7 @@ class Patch
|
|||
void
|
||||
apply()
|
||||
{
|
||||
error("TODO");
|
||||
cerr << "TODO\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -239,21 +271,28 @@ closeStreams()
|
|||
void
|
||||
process()
|
||||
{
|
||||
size_t absStartPos = 0; // for diagnostic messages
|
||||
|
||||
while (!Channel::hitEnd)
|
||||
{
|
||||
for (Channel& channel : streams)
|
||||
channel.fillBuffer();
|
||||
for (uint i=0; i < CHUNK_SIZE; ++i)
|
||||
for (uint i=0; i < BUFF_SIZE; ++i)
|
||||
{
|
||||
Event event = MAYBE;
|
||||
for (Channel& channel : streams)
|
||||
event = channel.visit(i, event);
|
||||
if (YES == event)
|
||||
for (Channel& channel : streams)
|
||||
Patch(channel).apply();
|
||||
{
|
||||
cout << "Skip-Event at "<< absStartPos+i <<"\n";
|
||||
for (Channel& channel : streams)
|
||||
Patch(channel).apply();
|
||||
}
|
||||
}
|
||||
for (Channel& channel : streams)
|
||||
channel.writeBuffer();
|
||||
|
||||
absStartPos += CHUNK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue