ref: 3d29bd8ccc57b5059130828c74dd32d6519b05f6
parent: 386e144a520324e83dd92262913b8d1a86a1fbde
author: Matthew Wang <mjw7@princeton.edu>
date: Tue Jul 21 09:37:48 EDT 2020
improve error reporting structure, use function pointer that can be set by the user instead of weak attribute
--- a/TestPlugin/Source/PluginProcessor.cpp
+++ b/TestPlugin/Source/PluginProcessor.cpp
@@ -94,7 +94,7 @@
for (int samp = 0; samp < buffer.getNumSamples(); ++samp)
{
- outPointerL[samp] = LEAFTest_tick( (inPointerL[samp] ));
+ outPointerL[samp] = LEAFTest_tick( (inPointerL[samp] + inPointerR[samp]) * 0.5f );
outPointerR[samp] = outPointerL[samp];
}
}
--- a/leaf/Inc/leaf-analysis.h
+++ b/leaf/Inc/leaf-analysis.h
@@ -536,7 +536,7 @@
// Maybe keep these up to PeriodDetector internal?
- typedef struct _tZeroCrossing2
+ typedef struct _tZeroCrossingInfo
{
tMempool mempool;
@@ -547,21 +547,21 @@
int _leading_edge;// = undefined_edge; int_min
int _trailing_edge;// = undefined_edge;
float _width;// = 0.0f;
- } _tZeroCrossing2;
+ } _tZeroCrossingInfo;
- typedef _tZeroCrossing2* tZeroCrossing2;
+ typedef _tZeroCrossingInfo* tZeroCrossingInfo;
- void tZeroCrossing2_init (tZeroCrossing2* const);
- void tZeroCrossing2_initToPool (tZeroCrossing2* const, tMempool* const);
- void tZeroCrossing2_free (tZeroCrossing2* const);
+ void tZeroCrossingInfo_init (tZeroCrossingInfo* const);
+ void tZeroCrossingInfo_initToPool (tZeroCrossingInfo* const, tMempool* const);
+ void tZeroCrossingInfo_free (tZeroCrossingInfo* const);
- int tZeroCrossing2_tick(tZeroCrossing2* const, float s);
- int tZeroCrossing2_getState(tZeroCrossing2* const);
- void tZeroCrossing2_updatePeak(tZeroCrossing2* const, float s, int pos);
- int tZeroCrossing2_period(tZeroCrossing2* const, tZeroCrossing2* const next);
- float tZeroCrossing2_fractionalPeriod(tZeroCrossing2* const, tZeroCrossing2* const next);
- int tZeroCrossing2_getWidth(tZeroCrossing2* const);
- int tZeroCrossing2_isSimilar(tZeroCrossing2* const, tZeroCrossing2* const next);
+ int tZeroCrossingInfo_tick(tZeroCrossingInfo* const, float s);
+ int tZeroCrossingInfo_getState(tZeroCrossingInfo* const);
+ void tZeroCrossingInfo_updatePeak(tZeroCrossingInfo* const, float s, int pos);
+ int tZeroCrossingInfo_period(tZeroCrossingInfo* const, tZeroCrossingInfo* const next);
+ float tZeroCrossingInfo_fractionalPeriod(tZeroCrossingInfo* const, tZeroCrossingInfo* const next);
+ int tZeroCrossingInfo_getWidth(tZeroCrossingInfo* const);
+ int tZeroCrossingInfo_isSimilar(tZeroCrossingInfo* const, tZeroCrossingInfo* const next);
//==============================================================================
@@ -568,11 +568,11 @@
#define PULSE_HEIGHT_DIFF 0.8
#define PULSE_WIDTH_DIFF 0.85
- typedef struct _tZeroCrossings
+ typedef struct _tZeroCrossingCollector
{
tMempool mempool;
- tZeroCrossing2* _info;
+ tZeroCrossingInfo* _info;
unsigned int _size;
unsigned int _pos;
unsigned int _mask;
@@ -586,27 +586,27 @@
int _ready;// = false;
float _peak_update;// = 0.0f;
float _peak;// = 0.0f;
- } _tZeroCrossings;
+ } _tZeroCrossingCollector;
- typedef _tZeroCrossings* tZeroCrossings;
+ typedef _tZeroCrossingCollector* tZeroCrossingCollector;
- void tZeroCrossings_init (tZeroCrossings* const, int windowSize, float hysteresis);
- void tZeroCrossings_initToPool (tZeroCrossings* const, int windowSize, float hysteresis, tMempool* const);
- void tZeroCrossings_free (tZeroCrossings* const);
+ void tZeroCrossingCollector_init (tZeroCrossingCollector* const, int windowSize, float hysteresis);
+ void tZeroCrossingCollector_initToPool (tZeroCrossingCollector* const, int windowSize, float hysteresis, tMempool* const);
+ void tZeroCrossingCollector_free (tZeroCrossingCollector* const);
- int tZeroCrossings_tick(tZeroCrossings* const, float s);
- int tZeroCrossings_getState(tZeroCrossings* const);
+ int tZeroCrossingCollector_tick(tZeroCrossingCollector* const, float s);
+ int tZeroCrossingCollector_getState(tZeroCrossingCollector* const);
- int tZeroCrossings_getNumEdges(tZeroCrossings* const zc);
- int tZeroCrossings_getCapacity(tZeroCrossings* const zc);
- int tZeroCrossings_getFrame(tZeroCrossings* const zc);
- int tZeroCrossings_getWindowSize(tZeroCrossings* const zc);
+ int tZeroCrossingCollector_getNumEdges(tZeroCrossingCollector* const zc);
+ int tZeroCrossingCollector_getCapacity(tZeroCrossingCollector* const zc);
+ int tZeroCrossingCollector_getFrame(tZeroCrossingCollector* const zc);
+ int tZeroCrossingCollector_getWindowSize(tZeroCrossingCollector* const zc);
- int tZeroCrossings_isReady(tZeroCrossings* const zc);
- float tZeroCrossings_getPeak(tZeroCrossings* const zc);
- int tZeroCrossings_isReset(tZeroCrossings* const zc);
+ int tZeroCrossingCollector_isReady(tZeroCrossingCollector* const zc);
+ float tZeroCrossingCollector_getPeak(tZeroCrossingCollector* const zc);
+ int tZeroCrossingCollector_isReset(tZeroCrossingCollector* const zc);
- tZeroCrossing2 const tZeroCrossings_getCrossing(tZeroCrossings* const zc, int index);
+ tZeroCrossingInfo const tZeroCrossingCollector_getCrossing(tZeroCrossingCollector* const zc, int index);
//==============================================================================
@@ -723,7 +723,7 @@
_auto_correlation_info _fundamental;
// passed in, not initialized
- tZeroCrossings _zc;
+ tZeroCrossingCollector _zc;
float _harmonic_threshold;
float _periodicity_diff_threshold;
@@ -734,7 +734,7 @@
{
tMempool mempool;
- tZeroCrossings _zc;
+ tZeroCrossingCollector _zc;
float _period_info[2]; // i0 is period, i1 is periodicity
unsigned int _min_period;
int _range;
--- a/leaf/Inc/leaf-global.h
+++ b/leaf/Inc/leaf-global.h
@@ -31,8 +31,11 @@
float (*random)(void); //!< A pointer to the random() function provided on initialization.
int clearOnAllocation; //!< A flag that determines whether memory allocated from the LEAF memory pool will be cleared.
tMempool mempool; //!< The default LEAF mempool object.
- _tMempool _mempool;
+ _tMempool _internal_mempool;
size_t header_size; //!< The size in bytes of memory region headers within mempools.
+ void (*errorCallback)(LEAFErrorType); //!< A pointer to the callback function for LEAF errors. Can be set by the user.
+ int errorState[LEAFErrorNil]; //!< An array of flags that indicate which errors have occurred.
+
///@}
};
typedef struct LEAF LEAF;
--- a/leaf/Inc/leaf-mempool.h
+++ b/leaf/Inc/leaf-mempool.h
@@ -54,6 +54,14 @@
//#define size_t unsigned long
+ typedef enum LEAFErrorType
+ {
+ LEAFMempoolOverrun = 0,
+ LEAFMempoolFragmentation,
+ LEAFInvalidFree,
+ LEAFErrorNil
+ } LEAFErrorType;
+
/*!
* @defgroup tmempool tMempool
* @ingroup mempool
@@ -145,8 +153,6 @@
size_t leaf_pool_get_used(void);
char* leaf_pool_get_pool(void);
-
- void leaf_mempool_overrun(void);
#ifdef __cplusplus
}
--- a/leaf/Src/leaf-analysis.c
+++ b/leaf/Src/leaf-analysis.c
@@ -952,15 +952,15 @@
}
-void tZeroCrossing2_init (tZeroCrossing2* const zc)
+void tZeroCrossingInfo_init (tZeroCrossingInfo* const zc)
{
- tZeroCrossing2_initToPool(zc, &leaf.mempool);
+ tZeroCrossingInfo_initToPool(zc, &leaf.mempool);
}
-void tZeroCrossing2_initToPool (tZeroCrossing2* const zc, tMempool* const mp)
+void tZeroCrossingInfo_initToPool (tZeroCrossingInfo* const zc, tMempool* const mp)
{
_tMempool* m = *mp;
- _tZeroCrossing2* z = *zc = (_tZeroCrossing2*) mpool_alloc(sizeof(_tZeroCrossing2), m);
+ _tZeroCrossingInfo* z = *zc = (_tZeroCrossingInfo*) mpool_alloc(sizeof(_tZeroCrossingInfo), m);
z->mempool = m;
z->_leading_edge = INT_MIN;
@@ -968,16 +968,16 @@
z->_width = 0.0f;
}
-void tZeroCrossing2_free (tZeroCrossing2* const zc)
+void tZeroCrossingInfo_free (tZeroCrossingInfo* const zc)
{
- _tZeroCrossing2* z = *zc;
+ _tZeroCrossingInfo* z = *zc;
mpool_free((char*)z, z->mempool);
}
-void tZeroCrossing2_updatePeak(tZeroCrossing2* const zc, float s, int pos)
+void tZeroCrossingInfo_updatePeak(tZeroCrossingInfo* const zc, float s, int pos)
{
- _tZeroCrossing2* z = *zc;
+ _tZeroCrossingInfo* z = *zc;
z->_peak = fmax(s, z->_peak);
if ((z->_width == 0.0f) && (s < (z->_peak * 0.3f)))
@@ -984,18 +984,18 @@
z->_width = pos - z->_leading_edge;
}
-int tZeroCrossing2_period(tZeroCrossing2* const zc, tZeroCrossing2* const next)
+int tZeroCrossingInfo_period(tZeroCrossingInfo* const zc, tZeroCrossingInfo* const next)
{
- _tZeroCrossing2* z = *zc;
- _tZeroCrossing2* n = *next;
+ _tZeroCrossingInfo* z = *zc;
+ _tZeroCrossingInfo* n = *next;
return n->_leading_edge - z->_leading_edge;
}
-float tZeroCrossing2_fractionalPeriod(tZeroCrossing2* const zc, tZeroCrossing2* const next)
+float tZeroCrossingInfo_fractionalPeriod(tZeroCrossingInfo* const zc, tZeroCrossingInfo* const next)
{
- _tZeroCrossing2* z = *zc;
- _tZeroCrossing2* n = *next;
+ _tZeroCrossingInfo* z = *zc;
+ _tZeroCrossingInfo* n = *next;
// Get the start edge
float prev1 = z->_before_crossing;
@@ -1014,17 +1014,17 @@
return result + (dx2 - dx1);
}
-int tZeroCrossing2_getWidth(tZeroCrossing2* const zc)
+int tZeroCrossingInfo_getWidth(tZeroCrossingInfo* const zc)
{
- _tZeroCrossing2* z = *zc;
+ _tZeroCrossingInfo* z = *zc;
return z->_width;
}
-int tZeroCrossing2_isSimilar(tZeroCrossing2* const zc, tZeroCrossing2* const next)
+int tZeroCrossingInfo_isSimilar(tZeroCrossingInfo* const zc, tZeroCrossingInfo* const next)
{
- _tZeroCrossing2* z = *zc;
- _tZeroCrossing2* n = *next;
+ _tZeroCrossingInfo* z = *zc;
+ _tZeroCrossingInfo* n = *next;
int similarPeak = fabs(z->_peak - n->_peak) <= ((1.0f - PULSE_HEIGHT_DIFF) * fmax(fabs(z->_peak), fabs(n->_peak)));
@@ -1034,19 +1034,19 @@
}
-static inline void update_state(tZeroCrossings* const zc, float s);
-static inline void shift(tZeroCrossings* const zc, int n);
-static inline void reset(tZeroCrossings* const zc);
+static inline void update_state(tZeroCrossingCollector* const zc, float s);
+static inline void shift(tZeroCrossingCollector* const zc, int n);
+static inline void reset(tZeroCrossingCollector* const zc);
-void tZeroCrossings_init (tZeroCrossings* const zc, int windowSize, float hysteresis)
+void tZeroCrossingCollector_init (tZeroCrossingCollector* const zc, int windowSize, float hysteresis)
{
- tZeroCrossings_initToPool(zc, windowSize, hysteresis, &leaf.mempool);
+ tZeroCrossingCollector_initToPool(zc, windowSize, hysteresis, &leaf.mempool);
}
-void tZeroCrossings_initToPool (tZeroCrossings* const zc, int windowSize, float hysteresis, tMempool* const mp)
+void tZeroCrossingCollector_initToPool (tZeroCrossingCollector* const zc, int windowSize, float hysteresis, tMempool* const mp)
{
_tMempool* m = *mp;
- _tZeroCrossings* z = *zc = (_tZeroCrossings*) mpool_alloc(sizeof(_tZeroCrossings), m);
+ _tZeroCrossingCollector* z = *zc = (_tZeroCrossingCollector*) mpool_alloc(sizeof(_tZeroCrossingCollector), m);
z->mempool = m;
z->_hysteresis = -hysteresis;
@@ -1059,9 +1059,9 @@
z->_size = pow(2, ceil(log2(size)));
z->_mask = z->_size - 1;
- z->_info = (tZeroCrossing2*) mpool_alloc(sizeof(tZeroCrossing2) * z->_size, m);
+ z->_info = (tZeroCrossingInfo*) mpool_alloc(sizeof(tZeroCrossingInfo) * z->_size, m);
for (int i = 0; i < z->_size; i++)
- tZeroCrossing2_initToPool(&z->_info[i], mp);
+ tZeroCrossingInfo_initToPool(&z->_info[i], mp);
z->_pos = 0;
z->_prev = 0.0f;
@@ -1073,16 +1073,16 @@
z->_peak = 0.0f;
}
-void tZeroCrossings_free (tZeroCrossings* const zc)
+void tZeroCrossingCollector_free (tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
mpool_free((char*)z, z->mempool);
}
-int tZeroCrossings_tick(tZeroCrossings* const zc, float s)
+int tZeroCrossingCollector_tick(tZeroCrossingCollector* const zc, float s)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
// Offset s by half of hysteresis, so that zero cross detection is
// centered on the actual zero.
@@ -1111,73 +1111,73 @@
return z->_state;
}
-int tZeroCrossings_getState(tZeroCrossings* const zc)
+int tZeroCrossingCollector_getState(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return z->_state;
}
-tZeroCrossing2 const tZeroCrossings_getCrossing(tZeroCrossings* const zc, int index)
+tZeroCrossingInfo const tZeroCrossingCollector_getCrossing(tZeroCrossingCollector* const zc, int index)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
int i = (z->_num_edges - 1) - index;
return z->_info[(z->_pos + i) & z->_mask];
}
-int tZeroCrossings_getNumEdges(tZeroCrossings* const zc)
+int tZeroCrossingCollector_getNumEdges(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return z->_num_edges;
}
-int tZeroCrossings_getCapacity(tZeroCrossings* const zc)
+int tZeroCrossingCollector_getCapacity(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return z->_size;
}
-int tZeroCrossings_getFrame(tZeroCrossings* const zc)
+int tZeroCrossingCollector_getFrame(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return z->_frame;
}
-int tZeroCrossings_getWindowSize(tZeroCrossings* const zc)
+int tZeroCrossingCollector_getWindowSize(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return z->_window_size;
}
-int tZeroCrossings_isReady(tZeroCrossings* const zc)
+int tZeroCrossingCollector_isReady(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return z->_ready;
}
-float tZeroCrossings_getPeak(tZeroCrossings* const zc)
+float tZeroCrossingCollector_getPeak(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return fmax(z->_peak, z->_peak_update);
}
-int tZeroCrossings_isReset(tZeroCrossings* const zc)
+int tZeroCrossingCollector_isReset(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
return z->_frame == 0;
}
-static inline void update_state(tZeroCrossings* const zc, float s)
+static inline void update_state(tZeroCrossingCollector* const zc, float s)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
if (z->_ready)
{
@@ -1196,7 +1196,7 @@
{
--z->_pos;
z->_pos &= z->_mask;
- tZeroCrossing2 crossing = z->_info[z->_pos];
+ tZeroCrossingInfo crossing = z->_info[z->_pos];
crossing->_before_crossing = z->_prev;
crossing->_after_crossing = s;
crossing->_peak = s;
@@ -1208,7 +1208,7 @@
}
else
{
- tZeroCrossing2_updatePeak(&z->_info[z->_pos], s, z->_frame);
+ tZeroCrossingInfo_updatePeak(&z->_info[z->_pos], s, z->_frame);
}
if (s > z->_peak_update)
{
@@ -1226,11 +1226,11 @@
z->_prev = s;
}
-static inline void shift(tZeroCrossings* const zc, int n)
+static inline void shift(tZeroCrossingCollector* const zc, int n)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
- tZeroCrossing2 crossing = z->_info[z->_pos];
+ tZeroCrossingInfo crossing = z->_info[z->_pos];
crossing->_leading_edge -= n;
if (!z->_state)
@@ -1247,9 +1247,9 @@
z->_num_edges = i;
}
-static inline void reset(tZeroCrossings* const zc)
+static inline void reset(tZeroCrossingCollector* const zc)
{
- _tZeroCrossings* z = *zc;
+ _tZeroCrossingCollector* z = *zc;
z->_num_edges = 0;
z->_state = 0;
@@ -1475,7 +1475,7 @@
static inline void set_bitstream(tPeriodDetector* const detector);
static inline void autocorrelate(tPeriodDetector* const detector);
-static inline void sub_collector_init(_sub_collector* collector, tZeroCrossings* const crossings, float pdt, int range);
+static inline void sub_collector_init(_sub_collector* collector, tZeroCrossingCollector* const crossings, float pdt, int range);
static inline float sub_collector_period_of(_sub_collector* collector, _auto_correlation_info info);
static inline void sub_collector_save(_sub_collector* collector, _auto_correlation_info info);
static inline int sub_collector_try_sub_harmonic(_sub_collector* collector, int harmonic, _auto_correlation_info info);
@@ -1494,11 +1494,11 @@
_tPeriodDetector* p = *detector = (_tPeriodDetector*) mpool_alloc(sizeof(_tPeriodDetector), m);
p->mempool = m;
- tZeroCrossings_initToPool(&p->_zc, (1.0f / lowestFreq) * leaf.sampleRate * 2.0f, hysteresis, mempool);
+ tZeroCrossingCollector_initToPool(&p->_zc, (1.0f / lowestFreq) * leaf.sampleRate * 2.0f, hysteresis, mempool);
p->_min_period = (1.0f / highestFreq) * leaf.sampleRate;
p->_range = highestFreq / lowestFreq;
- int windowSize = tZeroCrossings_getWindowSize(&p->_zc);
+ int windowSize = tZeroCrossingCollector_getWindowSize(&p->_zc);
tBitset_initToPool(&p->_bits, windowSize, mempool);
p->_weight = 2.0f / windowSize;
p->_mid_point = windowSize / 2;
@@ -1515,7 +1515,7 @@
{
_tPeriodDetector* p = *detector;
- tZeroCrossings_free(&p->_zc);
+ tZeroCrossingCollector_free(&p->_zc);
tBitset_free(&p->_bits);
tBACF_free(&p->_bacf);
@@ -1527,8 +1527,8 @@
_tPeriodDetector* p = *detector;
// Zero crossing
- int prev = tZeroCrossings_getState(&p->_zc);
- int zc = tZeroCrossings_tick(&p->_zc, s);
+ int prev = tZeroCrossingCollector_getState(&p->_zc);
+ int zc = tZeroCrossingCollector_tick(&p->_zc, s);
if (!zc && prev != zc)
{
@@ -1536,13 +1536,13 @@
p->_predicted_period = -1.0f;
}
- if (tZeroCrossings_isReset(&p->_zc))
+ if (tZeroCrossingCollector_isReset(&p->_zc))
{
p->_period_info[0] = -1.0f;
p->_period_info[1] = 0.0f;
}
- if (tZeroCrossings_isReady(&p->_zc))
+ if (tZeroCrossingCollector_isReady(&p->_zc))
{
set_bitstream(detector);
autocorrelate(detector);
@@ -1592,21 +1592,21 @@
if (p->_predicted_period == -1.0f && p->_edge_mark != p->_predict_edge)
{
p->_predict_edge = p->_edge_mark;
- int n = tZeroCrossings_getNumEdges(&p->_zc);
+ int n = tZeroCrossingCollector_getNumEdges(&p->_zc);
if (n > 1)
{
- float threshold = tZeroCrossings_getPeak(&p->_zc) * PULSE_THRESHOLD;
+ float threshold = tZeroCrossingCollector_getPeak(&p->_zc) * PULSE_THRESHOLD;
for (int i = n - 1; i > 0; --i)
{
- tZeroCrossing2 edge2 = tZeroCrossings_getCrossing(&p->_zc, i);
+ tZeroCrossingInfo edge2 = tZeroCrossingCollector_getCrossing(&p->_zc, i);
if (edge2->_peak >= threshold)
{
for (int j = i-1; j >= 0; --j)
{
- tZeroCrossing2 edge1 = tZeroCrossings_getCrossing(&p->_zc, j);
- if (tZeroCrossing2_isSimilar(&edge1, &edge2))
+ tZeroCrossingInfo edge1 = tZeroCrossingCollector_getCrossing(&p->_zc, j);
+ if (tZeroCrossingInfo_isSimilar(&edge1, &edge2))
{
- p->_predicted_period = tZeroCrossing2_fractionalPeriod(&edge1, &edge2);
+ p->_predicted_period = tZeroCrossingInfo_fractionalPeriod(&edge1, &edge2);
return p->_predicted_period;
}
}
@@ -1621,7 +1621,7 @@
{
_tPeriodDetector* p = *detector;
- return tZeroCrossings_isReady(&p->_zc);
+ return tZeroCrossingCollector_isReady(&p->_zc);
}
static inline void set_bitstream(tPeriodDetector* const detector)
@@ -1628,13 +1628,13 @@
{
_tPeriodDetector* p = *detector;
- float threshold = tZeroCrossings_getPeak(&p->_zc) * PULSE_THRESHOLD;
+ float threshold = tZeroCrossingCollector_getPeak(&p->_zc) * PULSE_THRESHOLD;
tBitset_clear(&p->_bits);
- for (int i = 0; i != tZeroCrossings_getNumEdges(&p->_zc); ++i)
+ for (int i = 0; i != tZeroCrossingCollector_getNumEdges(&p->_zc); ++i)
{
- tZeroCrossing2 info = tZeroCrossings_getCrossing(&p->_zc, i);
+ tZeroCrossingInfo info = tZeroCrossingCollector_getCrossing(&p->_zc, i);
if (info->_peak >= threshold)
{
int pos = fmax(info->_leading_edge, 0);
@@ -1648,24 +1648,24 @@
{
_tPeriodDetector* p = *detector;
- float threshold = tZeroCrossings_getPeak(&p->_zc) * PULSE_THRESHOLD;
+ float threshold = tZeroCrossingCollector_getPeak(&p->_zc) * PULSE_THRESHOLD;
_sub_collector collect;
sub_collector_init(&collect, &p->_zc, p->_periodicity_diff_threshold, p->_range);
int shouldBreak = 0;
- int n = tZeroCrossings_getNumEdges(&p->_zc);
+ int n = tZeroCrossingCollector_getNumEdges(&p->_zc);
for (int i = 0; i != n - 1; ++i)
{
- tZeroCrossing2 first = tZeroCrossings_getCrossing(&p->_zc, i);
+ tZeroCrossingInfo first = tZeroCrossingCollector_getCrossing(&p->_zc, i);
if (first->_peak >= threshold)
{
for (int j = i + 1; j != n; ++j)
{
- tZeroCrossing2 next = tZeroCrossings_getCrossing(&p->_zc, j);
+ tZeroCrossingInfo next = tZeroCrossingCollector_getCrossing(&p->_zc, j);
if (next->_peak >= threshold)
{
- int period = tZeroCrossing2_period(&first, &next);
+ int period = tZeroCrossingInfo_period(&first, &next);
if (period > p->_mid_point)
break;
if (period >= p->_min_period)
@@ -1718,7 +1718,7 @@
sub_collector_get(&collect, collect._fundamental, p->_period_info);
}
-static inline void sub_collector_init(_sub_collector* collector, tZeroCrossings* const crossings, float pdt, int range)
+static inline void sub_collector_init(_sub_collector* collector, tZeroCrossingCollector* const crossings, float pdt, int range)
{
collector->_zc = *crossings;
collector->_harmonic_threshold = HARMONIC_PERIODICITY_FACTOR * 2.0f / collector->_zc->_window_size;
@@ -1733,9 +1733,9 @@
static inline float sub_collector_period_of(_sub_collector* collector, _auto_correlation_info info)
{
- tZeroCrossing2 first = tZeroCrossings_getCrossing(&collector->_zc, info._i1);
- tZeroCrossing2 next = tZeroCrossings_getCrossing(&collector->_zc, info._i2);
- return tZeroCrossing2_fractionalPeriod(&first, &next);
+ tZeroCrossingInfo first = tZeroCrossingCollector_getCrossing(&collector->_zc, info._i1);
+ tZeroCrossingInfo next = tZeroCrossingCollector_getCrossing(&collector->_zc, info._i2);
+ return tZeroCrossingInfo_fractionalPeriod(&first, &next);
}
static inline void sub_collector_save(_sub_collector* collector, _auto_correlation_info info)
--- a/leaf/Src/leaf-mempool.c
+++ b/leaf/Src/leaf-mempool.c
@@ -79,9 +79,9 @@
void leaf_pool_init(char* memory, size_t size)
{
- mpool_create(memory, size, &leaf._mempool);
+ mpool_create(memory, size, &leaf._internal_mempool);
- leaf.mempool = &leaf._mempool;
+ leaf.mempool = &leaf._internal_mempool;
}
/**
@@ -92,7 +92,14 @@
// If the head is NULL, the mempool is full
if (pool->head == NULL)
{
- leaf_mempool_overrun();
+ if ((pool->msize - pool->usize) > asize)
+ {
+ LEAF_internalErrorCallback(LEAFMempoolFragmentation);
+ }
+ else
+ {
+ LEAF_internalErrorCallback(LEAFMempoolOverrun);
+ }
return NULL;
}
@@ -109,7 +116,14 @@
// are no blocks large enough, return NULL
if (node_to_alloc == NULL)
{
- leaf_mempool_overrun();
+ if ((pool->msize - pool->usize) > asize)
+ {
+ LEAF_internalErrorCallback(LEAFMempoolFragmentation);
+ }
+ else
+ {
+ LEAF_internalErrorCallback(LEAFMempoolOverrun);
+ }
return NULL;
}
}
@@ -166,7 +180,14 @@
// If the head is NULL, the mempool is full
if (pool->head == NULL)
{
- leaf_mempool_overrun();
+ if ((pool->msize - pool->usize) > asize)
+ {
+ LEAF_internalErrorCallback(LEAFMempoolFragmentation);
+ }
+ else
+ {
+ LEAF_internalErrorCallback(LEAFMempoolOverrun);
+ }
return NULL;
}
@@ -183,7 +204,14 @@
// are no blocks large enough, return NULL
if (node_to_alloc == NULL)
{
- leaf_mempool_overrun();
+ if ((pool->msize - pool->usize) > asize)
+ {
+ LEAF_internalErrorCallback(LEAFMempoolFragmentation);
+ }
+ else
+ {
+ LEAF_internalErrorCallback(LEAFMempoolOverrun);
+ }
return NULL;
}
}
@@ -230,10 +258,8 @@
char* leaf_alloc(size_t size)
{
//printf("alloc %i\n", size);
- char* block = mpool_alloc(size, &leaf._mempool);
+ char* block = mpool_alloc(size, &leaf._internal_mempool);
- if (block == NULL) leaf_mempool_overrun();
-
return block;
}
@@ -240,11 +266,8 @@
char* leaf_calloc(size_t size)
{
//printf("alloc %i\n", size);
- char* block = mpool_calloc(size, &leaf._mempool);
-
- if (block == NULL) leaf_mempool_overrun();
-
-
+ char* block = mpool_calloc(size, &leaf._internal_mempool);
+
return block;
}
@@ -264,7 +287,7 @@
if ((long) other_node < (long) pool->mpool ||
(long) other_node >= (((long) pool->mpool) + pool->msize))
{
- LEAF_error(2);
+ LEAF_internalErrorCallback(LEAFInvalidFree);
return;
}
next_node = other_node->next;
@@ -318,7 +341,7 @@
void leaf_free(char* ptr)
{
- mpool_free(ptr, &leaf._mempool);
+ mpool_free(ptr, &leaf._internal_mempool);
}
size_t mpool_get_size(_tMempool* pool)
@@ -333,17 +356,17 @@
size_t leaf_pool_get_size(void)
{
- return mpool_get_size(&leaf._mempool);
+ return mpool_get_size(&leaf._internal_mempool);
}
size_t leaf_pool_get_used(void)
{
- return mpool_get_used(&leaf._mempool);
+ return mpool_get_used(&leaf._internal_mempool);
}
char* leaf_pool_get_pool(void)
{
- char* buff = leaf._mempool.mpool;
+ char* buff = leaf._internal_mempool.mpool;
return buff;
}
@@ -383,12 +406,6 @@
node->next = NULL;
node->prev = NULL;
-}
-
-void leaf_mempool_overrun(void)
-{
- LEAF_error(1);
- //TODO: we should make a set of real error codes that are in an enum type
}
void tMempool_init(tMempool* const mp, char* memory, size_t size)
--- a/leaf/Src/leaf.c
+++ b/leaf/Src/leaf.c
@@ -36,6 +36,11 @@
leaf.random = random;
leaf.clearOnAllocation = 0;
+
+ leaf.errorCallback = &LEAF_defaultErrorCallback;
+
+ for (int i = 0; i < LEAFErrorNil; ++i)
+ leaf.errorState[i] = 0;
}
@@ -52,10 +57,19 @@
return leaf.sampleRate;
}
+void LEAF_defaultErrorCallback(LEAFErrorType whichone)
+{
+ // Not sure what this should do if anything
+ // Maybe fine as a placeholder
+}
-//implement a function called this in your user code to catch errors
-//__attribute__((weak))
-uint8_t LEAF_error(uint8_t whichone)
+void LEAF_internalErrorCallback(LEAFErrorType whichone)
{
- return whichone;
+ leaf.errorState[whichone] = 1;
+ leaf.errorCallback(whichone);
+}
+
+void LEAF_setErrorCallback(void (*callback)(LEAFErrorType))
+{
+ leaf.errorCallback = callback;
}
--- a/leaf/leaf.h
+++ b/leaf/leaf.h
@@ -140,9 +140,19 @@
*/
float LEAF_getSampleRate (void);
-
-// __attribute__((weak))
- uint8_t LEAF_error(uint8_t whichone);
+ //! The default callback function for LEAF errors.
+ /*!
+ @param errorType The type of the error that has occurred.
+ */
+ void LEAF_defaultErrorCallback(LEAFErrorType errorType);
+
+ void LEAF_internalErrorCallback(LEAFErrorType whichone);
+
+ //! Set the callback function for LEAF errors.
+ /*!
+ @param callback A pointer to the callback function.
+ */
+ void LEAF_setErrorCallback(void (*callback)(LEAFErrorType))
/*! @} */