From 3260b1d7d87e15454d1db7c3130d832855abdd6c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 31 Aug 2014 18:44:30 +0200 Subject: [PATCH] Patch-Operation wie geplant implementiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...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 --- sauSynKlick/Makefile | 2 +- sauSynKlick/SynKlick.cc | 115 ++++++++++++++++++++++++++++++++-------- 2 files changed, 94 insertions(+), 23 deletions(-) diff --git a/sauSynKlick/Makefile b/sauSynKlick/Makefile index 586b376..353428c 100644 --- a/sauSynKlick/Makefile +++ b/sauSynKlick/Makefile @@ -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 diff --git a/sauSynKlick/SynKlick.cc b/sauSynKlick/SynKlick.cc index b2f53f5..8f9996d 100644 --- a/sauSynKlick/SynKlick.cc +++ b/sauSynKlick/SynKlick.cc @@ -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 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 <