Entscheidungslogik beobachtet und optimiert
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.
This commit is contained in:
parent
3260b1d7d8
commit
139225fc5c
2 changed files with 43 additions and 23 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ GNU PUBLIC LICENCE (GPL) Version 2 and above.
|
|||
#include <cmath>
|
||||
|
||||
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<factor? TRIGGER_FACTOR/factor : -10);
|
||||
weights_ += weight;
|
||||
score_ += weight * (confirmed? 1.0 : -1.0);
|
||||
}
|
||||
|
||||
bool
|
||||
possible()
|
||||
{
|
||||
return 0.0 < weights_ && 0.1 < confirmationDegree();
|
||||
}
|
||||
|
||||
string
|
||||
showLastUpdate()
|
||||
{
|
||||
float deg = confirmationDegree();
|
||||
return deg == prevDeg_? "neutral"
|
||||
: (deg > 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 <<absPos<<"\t jump? "
|
||||
|
|
|
|||
Loading…
Reference in a new issue