Patch-Operation wie geplant implementiert
...funktioniert schön in den sauberen Fällen, jedoch nicht so gut wenn mehrere Sprünge dicht beieinander liegen, oder gar eine Strecke von Null-Werten folgt
This commit is contained in:
parent
be57e53479
commit
3260b1d7d8
2 changed files with 94 additions and 23 deletions
|
|
@ -13,7 +13,7 @@
|
|||
#INCLUDES = -I$(XXX_H)
|
||||
INCLUDES =
|
||||
LIBRARIES = -lm -lsndfile
|
||||
CFLAGS = $(INCLUDES) -O0 -ggdb -fPIC
|
||||
CFLAGS = $(INCLUDES) -O0 -ggdb -DDEBUG -fPIC
|
||||
#-O2 -fPIC
|
||||
CXXFLAGS = $(CFLAGS) -std=gnu++11
|
||||
PROGRAMS = SynKlick
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ using std::string;
|
|||
using std::vector;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::max;
|
||||
using std::abs;
|
||||
|
||||
const size_t CHUNK_SIZE = 20000; //44100; ///TODO for debugging
|
||||
|
|
@ -35,6 +36,8 @@ const float TRIGGER_FACTOR = 5.0f; // discontinuity detected by local
|
|||
const float CONFIRMATION_DEGREE = 0.66f; // degree of confirmation by multiple tracks for an event to be accepted
|
||||
const uint AVERAGE_SAMPLES = 50; // number of past samples to use for average delta
|
||||
|
||||
const bool VERBOSE = true;
|
||||
|
||||
/* ==== Helpers ==== */
|
||||
|
||||
void
|
||||
|
|
@ -75,6 +78,7 @@ class EventScore
|
|||
{
|
||||
uint contributions_ = 0;
|
||||
uint positives_ = 0;
|
||||
float prevDeg_ = 0.0f;
|
||||
|
||||
public:
|
||||
float
|
||||
|
|
@ -92,13 +96,26 @@ class EventScore
|
|||
void
|
||||
recordConfirmation(bool confirmed)
|
||||
{
|
||||
prevDeg_ = confirmationDegree(); // record for diagnostics
|
||||
|
||||
++contributions_;
|
||||
if (confirmed)
|
||||
++positives_;
|
||||
}
|
||||
|
||||
string
|
||||
showLastUpdate()
|
||||
{
|
||||
float deg = confirmationDegree();
|
||||
return deg == prevDeg_? "neutral"
|
||||
: (deg > prevDeg_? "conf "
|
||||
: "rej "
|
||||
) + std::to_string(deg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Channel
|
||||
{
|
||||
SNDFILE *in_ = nullptr,
|
||||
|
|
@ -206,19 +223,20 @@ class Channel
|
|||
workPos_ = i;
|
||||
float averageDelta = updateMovingAverage();
|
||||
float changeFactor = delta() / (averageDelta + EPSILON);
|
||||
if (SILENCE_GATE < abs(sample()))
|
||||
event.recordConfirmation(changeFactor > TRIGGER_FACTOR);
|
||||
if (SILENCE_GATE < sampleLevel())
|
||||
event.recordConfirmation (changeFactor > TRIGGER_FACTOR);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
float
|
||||
sample()
|
||||
sampleLevel()
|
||||
{
|
||||
if (0 < workPos_)
|
||||
return std::max(buff_[workPos_-1], buff_[workPos_]);
|
||||
else
|
||||
return buff_[workPos_];
|
||||
auto curr = abs(buff_[workPos_]);
|
||||
auto prev = abs(buff_[workPos_ - 1]);
|
||||
|
||||
return 0 < workPos_? max(prev, curr)
|
||||
: curr;
|
||||
}
|
||||
|
||||
float
|
||||
|
|
@ -235,11 +253,22 @@ class Channel
|
|||
{
|
||||
return ema_ = (delta() + ema_*(AVERAGE_SAMPLES - 1)) / AVERAGE_SAMPLES;
|
||||
}
|
||||
|
||||
float*
|
||||
accessCurrentContext()
|
||||
{
|
||||
assert(CONTEXT <= workPos_);
|
||||
assert(CONTEXT + workPos_ <= numSamples_);
|
||||
return buff_ + (workPos_ - CONTEXT);
|
||||
}
|
||||
friend class Patch;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* fix a glitch detected in the corresponding channel.
|
||||
* Fix a glitch detected in the corresponding channel.
|
||||
* When the Patch is applied, internal work buffers are used
|
||||
* to create two (partially synthetic) copies of the channel's signal
|
||||
* which are then cross faded. The result is pushed back into the
|
||||
|
|
@ -247,20 +276,45 @@ class Channel
|
|||
*/
|
||||
class Patch
|
||||
{
|
||||
float workBuff[2*CONTEXT];
|
||||
Channel& chan_;
|
||||
static const size_t LEN = 2 * CONTEXT;
|
||||
|
||||
float workBuff[LEN];
|
||||
float* rawBuff;
|
||||
|
||||
|
||||
void
|
||||
reconstructMirroredSignal()
|
||||
{
|
||||
for (uint i=0; i < LEN; ++i)
|
||||
workBuff[i] = rawBuff[LEN-1 - i];
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
Patch(Channel& c)
|
||||
: chan_(c)
|
||||
Patch (Channel& c)
|
||||
: rawBuff{c.accessCurrentContext()}
|
||||
{
|
||||
|
||||
reconstructMirroredSignal();
|
||||
}
|
||||
|
||||
void
|
||||
apply()
|
||||
{
|
||||
cerr << "TODO\n";
|
||||
for (uint i=0; i < LEN; ++i)
|
||||
{
|
||||
float fade = (i<CONTEXT) ? CONTEXT - (i+1)
|
||||
: i - CONTEXT;
|
||||
fade = 1.0 - fade/CONTEXT;
|
||||
// i=-1 -> 0
|
||||
// i=CONTEXT-1 -> 1
|
||||
// i=CONTEXT -> 1
|
||||
// i=2*CONTEXT -> 0
|
||||
|
||||
float p = fade * 0.5f,
|
||||
q = 1.0 - p;
|
||||
|
||||
rawBuff[i] = q*rawBuff[i] + p*workBuff[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -297,6 +351,20 @@ closeStreams()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
eventConfirmationDiagnostic(EventScore& event, string name, size_t absPos)
|
||||
{
|
||||
static size_t trail = 0;
|
||||
if (trail && trail != absPos) trail=0;
|
||||
if (event && !trail) trail = absPos;
|
||||
|
||||
if (trail)
|
||||
cerr <<absPos<<"\t jump? "
|
||||
<<name<<"\t :: "
|
||||
<<event.showLastUpdate()
|
||||
<<"\n";
|
||||
}
|
||||
|
||||
void
|
||||
process()
|
||||
{
|
||||
|
|
@ -306,24 +374,24 @@ process()
|
|||
{
|
||||
for (Channel& channel : streams)
|
||||
channel.fillBuffer();
|
||||
|
||||
for (uint i=0; i < BUFF_SIZE; ++i)
|
||||
{
|
||||
EventScore event;
|
||||
bool yesss = false;
|
||||
for (Channel& channel : streams){
|
||||
channel.visit(i, event);
|
||||
if (event || yesss){
|
||||
cerr << "Event ? "<<i<<" "<<channel.name_<<"\t deg "<<event.confirmationDegree()<<"\n";
|
||||
yesss = true;
|
||||
for (Channel& channel : streams)
|
||||
{
|
||||
channel.visit(i, event);
|
||||
if (VERBOSE)
|
||||
eventConfirmationDiagnostic (event, channel.name_, absStartPos+i);
|
||||
}
|
||||
}
|
||||
if (event)
|
||||
{
|
||||
cout << "Skip-Event at "<< absStartPos+i <<"\n";
|
||||
cout << "PATCH at: "<< absStartPos+i <<"\n";
|
||||
for (Channel& channel : streams)
|
||||
Patch(channel).apply();
|
||||
}
|
||||
}
|
||||
|
||||
for (Channel& channel : streams)
|
||||
channel.writeBuffer();
|
||||
|
||||
|
|
@ -332,6 +400,9 @@ process()
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char* argv[]) {
|
||||
if (argc < 3 || string("-h") == argv[1])
|
||||
|
|
|
|||
Loading…
Reference in a new issue