Uses:
1. Look ahead compression & limiting
2. Sample accurate peak hold (not sure why you'd need that)
Interface:
Code: Select all
/*! Allocates instance with zeroed buffers. */
struct PeakHold* PeakHold_Create(size_t max_window_size);
/*! Destroys all memory associated with the instance */
void PeakHold_Destroy(struct PeakHold *self);
/*! Clears all buffers */
void PeakHold_Clear(struct PeakHold *self);
/*! Inserts next sample */
void PeakHold_Insert(struct PeakHold *self, float value);
/*! Returns maximum sample within the given window size */
float PeakHold_CalcMaxPeak(struct PeakHold *self, size_t window_size);
Oh, and you can specify any arbitrary window length and you'll get O(log N) with N being the window size you are searching for. This can only performed at the current position but you can perform as many searches as you like (for whatever reason you would want to do that for).
In terms of speed, each sample is O(log N), with N being window size, and my i5 laptop CPU took 2 seconds to process 100 seconds of data with a 1 second window @ 44.1khz. That means that computationally this is very cheap - mainly because it doesn't use any complex tree structures - it's more like a skip-list and is a modification of a sort of skip list I was designing.
It's not the cleanest code ever (will clean it up at some point), it's not well commented to explain the algorithm either but it does come with some tests to prove it works (which basically compares this algorithm with a brute force O(N^2) sliding window).