From 139225fc5c3c9e4f796783e3614799408b98c1da Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 1 Sep 2014 01:11:16 +0200 Subject: [PATCH] Entscheidungslogik beobachtet und optimiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit verwende nun ein gewichtets Mittel, in das die Stärke des Sprunges mit einfließt. Dies führt zu wesentlich stabileren Entscheidungen. Verbesserte Diagnostik (Konstante VERBOSE im Code setzen!), erlaubt nun, den Entscheidungsprozeß im Detail nachzuvollziehen. --- sauSynKlick/Makefile | 2 +- sauSynKlick/SynKlick.cc | 64 +++++++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/sauSynKlick/Makefile b/sauSynKlick/Makefile index 353428c..dc6c35c 100644 --- a/sauSynKlick/Makefile +++ b/sauSynKlick/Makefile @@ -13,7 +13,7 @@ #INCLUDES = -I$(XXX_H) INCLUDES = LIBRARIES = -lm -lsndfile -CFLAGS = $(INCLUDES) -O0 -ggdb -DDEBUG -fPIC +CFLAGS = $(INCLUDES) -ggdb -DDEBUG -fPIC #-O2 -fPIC CXXFLAGS = $(CFLAGS) -std=gnu++11 PROGRAMS = SynKlick diff --git a/sauSynKlick/SynKlick.cc b/sauSynKlick/SynKlick.cc index 8f9996d..0156ff9 100644 --- a/sauSynKlick/SynKlick.cc +++ b/sauSynKlick/SynKlick.cc @@ -20,6 +20,7 @@ GNU PUBLIC LICENCE (GPL) Version 2 and above. #include using std::string; +using std::to_string; using std::vector; using std::cout; using std::cerr; @@ -32,7 +33,7 @@ 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 = 4096.0f * EPSILON;// signal below this level (-33dB) is too low to detect jumps -const float TRIGGER_FACTOR = 5.0f; // discontinuity detected by local change compared to average change +const float TRIGGER_FACTOR = 6.0f; // discontinuity detected by local change compared to average change 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 @@ -76,16 +77,19 @@ reduceBufferPos (size_t & pos, size_t elementsToRemove) */ class EventScore { - uint contributions_ = 0; - uint positives_ = 0; - float prevDeg_ = 0.0f; + float weights_ = 0.0f; + float score_ = 0.0f; + + uint last_ = 0; + float fac_ = 0.0f; public: float confirmationDegree() { - return contributions_? float(positives_)/contributions_ - : 0.0f; + if (0==weights_) return 0.0; + float avgScore = score_/weights_; + return 0.5 * (avgScore + 1.0); } operator bool() @@ -94,23 +98,31 @@ class EventScore } void - recordConfirmation(bool confirmed) + decide(bool unclear, bool confirmed, float factor) { - prevDeg_ = confirmationDegree(); // record for diagnostics + fac_ = factor; + last_ = unclear? 0 : confirmed? 2 : 1; // record for diagnostics + if (unclear) return; - ++contributions_; - if (confirmed) - ++positives_; + float weight = confirmed? (factor/TRIGGER_FACTOR) + : (0.0 prevDeg_? "conf " - : "rej " - ) + std::to_string(deg); + return 0==last_? "neutral" + : (2==last_? "conf\t" + : "rej \t" + ) + to_string(fac_) +'\t'+ to_string(confirmationDegree()); } }; @@ -145,7 +157,7 @@ class Channel error ("could not open "+name+" -- " + sf_strerror (NULL)); if (1 != info_in_.channels) error ("only Mono streams supported -- but '"+name_ - +"' was found to have "+std::to_string(info_in_.channels)+" channels."); + +"' was found to have "+to_string(info_in_.channels)+" channels."); info_out_.format = info_in_.format; info_out_.channels = info_in_.channels; @@ -223,8 +235,9 @@ class Channel workPos_ = i; float averageDelta = updateMovingAverage(); float changeFactor = delta() / (averageDelta + EPSILON); - if (SILENCE_GATE < sampleLevel()) - event.recordConfirmation (changeFactor > TRIGGER_FACTOR); + bool unclear = (sampleLevel() < SILENCE_GATE ); + bool trigger = (changeFactor > TRIGGER_FACTOR); + event.decide (unclear, trigger, changeFactor); } } @@ -251,7 +264,10 @@ class Channel float updateMovingAverage() { - return ema_ = (delta() + ema_*(AVERAGE_SAMPLES - 1)) / AVERAGE_SAMPLES; + float old_ema = ema_; // avoid poisoning EMA used for detection + + ema_ = (delta() + ema_*(AVERAGE_SAMPLES - 1)) / AVERAGE_SAMPLES; + return old_ema; } float* @@ -355,8 +371,12 @@ 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 && trail != absPos) trail = 0; + if (!trail && event.possible()) + { + trail = absPos; + cerr << "...\n"; + } if (trail) cerr <