Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,17 @@ RUN mkdir -p Tools \
RUN ln -sf /usr/local/bin/soul /owl/Tools/soul \
&& ln -sf /usr/local/bin/FirmwareSender /owl/Tools/FirmwareSender

# hvcc deps (non-fatal).
RUN pip3 install --no-cache-dir -r Tools/hvcc/requirements.txt || true
# hvcc deps. The pingdynasty hvcc fork runs under python2.7 (heavy.mk invokes
# `python2.7 hvcc.py`), and its requirements (enum==0.4.4, Jinja2==2.7.3) are
# python2 packages. ubuntu 20.04 ships `python2` WITHOUT pip, so bootstrap pip
# for python2 first, then install the fork's requirements into python2 — not
# python3 (a `pip3 install` here left python2.7 without `enum` and silently
# broke every Heavy/PD build).
RUN curl -fsSL https://bootstrap.pypa.io/pip/2.7/get-pip.py -o /tmp/get-pip.py \
&& python2 /tmp/get-pip.py \
&& python2 -m pip install --no-cache-dir -r Tools/hvcc/requirements.txt \
&& rm -f /tmp/get-pip.py \
&& python2 -c "import enum, jinja2; print('hvcc py2 deps OK')"

# Pre-build the patch libraries for the target platform so a later
# `make PATCHNAME=X patch` links immediately (no separate `make libs` needed).
Expand Down
8 changes: 8 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
v23.1
-----

* Fixed missing SmoothValue and StiffValue::normal definitions
* Fixed SmoothValue<int> to use float lambda
* Fixed Dockerfile hvcc build


v23.0
-----

Expand Down
6 changes: 0 additions & 6 deletions LibSource/SimpleValue.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
#include "SimpleValue.h"
#include "math.h"

/**
* The int constants are meant to provide reasonable defaults for use
* with OWL parameters, which are generally 12 bit fixed point, i.e. Q12.
*/
#define Q12_FACTOR ((float)(1<<12))

template<> const float SimpleValue<float>::DEFAULT_LAMBDA = 0.9;
template<> const float SimpleValue<float>::DEFAULT_DELTA = 0.02;
template<> const float SimpleValue<float>::DEFAULT_EXP_C = 1;
template<> const float SimpleValue<float>::DEFAULT_EXP_K = 2*M_LN2;
template<> const float SimpleValue<float>::DEFAULT_LOG_C = 1.6487212707;
template<> const float SimpleValue<float>::DEFAULT_LOG_K = 5.74033482823*M_LN2;
template<> const int SimpleValue<int>::DEFAULT_LAMBDA = (int)(0.9*Q12_FACTOR);
template<> const int SimpleValue<int>::DEFAULT_DELTA = (int)(0.02*Q12_FACTOR);
template<> const int SimpleValue<int>::DEFAULT_EXP_C = (int)(1*Q12_FACTOR);
template<> const int SimpleValue<int>::DEFAULT_EXP_K = (int)(2*M_LN2*Q12_FACTOR);
Expand Down
3 changes: 0 additions & 3 deletions LibSource/SimpleValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class SimpleValue {
operator T(){
return get();
}
static const T DEFAULT_LAMBDA;
static const T DEFAULT_DELTA;
static const T DEFAULT_EXP_C;
static const T DEFAULT_EXP_K;
Expand All @@ -57,13 +56,11 @@ class SimpleValue {
};

// prevent -Wundefined-var-template warnings
template<> const float SimpleValue<float>::DEFAULT_LAMBDA;
template<> const float SimpleValue<float>::DEFAULT_DELTA;
template<> const float SimpleValue<float>::DEFAULT_EXP_C;
template<> const float SimpleValue<float>::DEFAULT_EXP_K;
template<> const float SimpleValue<float>::DEFAULT_LOG_C;
template<> const float SimpleValue<float>::DEFAULT_LOG_K;
template<> const int SimpleValue<int>::DEFAULT_LAMBDA;
template<> const int SimpleValue<int>::DEFAULT_DELTA;
template<> const int SimpleValue<int>::DEFAULT_EXP_C;
template<> const int SimpleValue<int>::DEFAULT_EXP_K;
Expand Down
22 changes: 15 additions & 7 deletions LibSource/SmoothValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@

/**
* Applies exponential smoothing to a scalar value.
* y(n) = lambda*y(n-1) + (1.0-lambda)*y(n) for floats
* y(n) = (lambda*y(n-1) + y(n))/(lambda+1) for ints
* y(n) = lambda*y(n-1) + (1-lambda)*x(n), with 0 <= lambda < 1,
* where x(n) is the new input and y(n) the smoothed output.
* Smoothing is applied when the value is written to, not when it is read.
* todo: adjust for sampling frequency / blocksize (time delay of the response (mean) is 1/α data points)
*
* lambda is a dimensionless coefficient and is always a float, independent of
* the value type T.
* todo: adjust lambda for sample rate / blocksize; for input weight
* alpha = 1-lambda the mean lag of the response is lambda/(1-lambda) samples.
* https://en.wikipedia.org/wiki/Exponential_smoothing
*/
template<typename T, typename Value = SimpleValue<T>>
class SmoothValue : public Value {
public:
T lambda = Value::DEFAULT_LAMBDA;
float lambda = 0.9f;
SmoothValue() {}
SmoothValue(T value) : Value(value) {}
SmoothValue(T lambda, T init) : Value(init), lambda(lambda) {}
SmoothValue(float lambda, T init) : Value(init), lambda(lambda) {}
SmoothValue(const SmoothValue<T, Value>& other) : Value(other), lambda(other.lambda) {}
void update(T x){
Value::update(Value::get()*lambda + x*(1.0f - lambda));
Expand Down Expand Up @@ -45,7 +49,9 @@ class SmoothValue : public Value {
operator T(){
return Value::get();
}
static T normal(float lambda, int blocksize);
static float normal(float lambda, int blocksize){
return powf(lambda, blocksize/128.0f);
}
};

template class SmoothValue<int>;
Expand Down Expand Up @@ -92,7 +98,9 @@ class StiffValue : public Value {
operator T(){
return Value::get();
}
static T normal(float delta);
static float normal(float delta){
return delta;
}
};

template class StiffValue<int>;
Expand Down
2 changes: 1 addition & 1 deletion Source/PatchProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ PatchParameter<T> PatchProcessor::getParameter(const char* name, T min, T max, T
if(parameters[pid] != NULL)
delete parameters[pid];
ParameterUpdater* updater = NULL;
T l = SmoothValue<T>::normal(lambda, blocksize);
float l = SmoothValue<T>::normal(lambda, blocksize);
T d = StiffValue<T>::normal(delta)*abs(max-min);
if(skew == 1.0){
if(lambda == 0.0 && delta == 0.0){
Expand Down
6 changes: 4 additions & 2 deletions TestPatches/PatchRun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ int main(int argc, char** argv){
ASSERT(wav.getBitsPerSample() == 16, "Incorrect number of bits per sample in input file");
ASSERT(wav.isValid(), "Invalid wav");
int16_t* src = (int16_t*)wav.getData();
int16_t* end = src+wav.getNumberOfSamples();
while(src+BLOCKSIZE <= end){
// getNumberOfSamples() is frames per channel; the buffer holds
// frames*channels interleaved int16s.
int16_t* end = src+wav.getNumberOfSamples()*channels;
while(src+BLOCKSIZE*channels <= end){
samples->split16(src, BLOCKSIZE);
processor.patch->processAudio(*samples);
samples->comb16(src);
Expand Down
34 changes: 26 additions & 8 deletions TestPatches/SmoothValueTestPatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,42 @@ class SmoothValueTestPatch : public TestPatch {
CHECK_CLOSE(a, -1, DEFAULT_TOLERANCE); // arrives near target
}
{
// typedef SmoothValue<int> SmoothInt;
TEST("int");
SmoothValue<float, SimpleValue<int>> a = 5;
CHECK_CLOSE(a, 5, DEFAULT_TOLERANCE);
CHECK_CLOSE(a.lambda, 0.9, DEFAULT_TOLERANCE); // default lambda
a = 0;
CHECK_CLOSE(a.lambda, 0.9, DEFAULT_TOLERANCE);
a.lambda = 0.6;
CHECK_CLOSE(a, 5*0.9, DEFAULT_TOLERANCE);
for(int i=0; i<32; ++i)
a = 0;
CHECK_CLOSE(a, 3, DEFAULT_TOLERANCE);
int prev = a;
for(int i=0; i<32; ++i){
a = -10;
CHECK_CLOSE(a, -10, DEFAULT_TOLERANCE);
CHECK((int)a <= prev);
prev = a;
}
CHECK_CLOSE(a, -8, DEFAULT_TOLERANCE);
}
{
TEST("weirdint");
SmoothInt a = 5;
CHECK_CLOSE(a, 5, DEFAULT_TOLERANCE);
CHECK_CLOSE(a.lambda, 0.9, DEFAULT_TOLERANCE); // default lambda
a = 0;
CHECK_CLOSE(a.lambda, 0.9, DEFAULT_TOLERANCE);
a.lambda = 0.6;
int prev = a;
for(int i=0; i<32; ++i){
a = 100;
CHECK((int)a >= prev);
prev = a;
}
CHECK_CLOSE(a, 98, DEFAULT_TOLERANCE);
}
{
TEST("normal");
CHECK_CLOSE(SmoothFloat::normal(0.9, 128), 0.9, DEFAULT_TOLERANCE);
CHECK_CLOSE(SmoothFloat::normal(0.9, 64), sqrtf(0.9), DEFAULT_TOLERANCE);
CHECK_CLOSE(SmoothInt::normal(0.81, 256), 0.81*0.81, DEFAULT_TOLERANCE);
CHECK(SmoothFloat::normal(0.95, 16) < 1);
CHECK_CLOSE(StiffInt::normal(0.5), 0.5, DEFAULT_TOLERANCE);
}
}
};
Expand Down
Loading