Skip to content

Instantly share code, notes, and snippets.

@olilarkin
Created March 4, 2019 14:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olilarkin/8d004ee115c042335ae9e0b765a3dad8 to your computer and use it in GitHub Desktop.
Save olilarkin/8d004ee115c042335ae9e0b765a3dad8 to your computer and use it in GitHub Desktop.
Parameter smoother using xsimd library
#pragma once
#include <vector>
#include "xsimd/xsimd.hpp"
#include "ptrlist.h"
#include "heapbuf.h"
namespace xs = xsimd;
using tVec = std::vector<float, XSIMD_DEFAULT_ALLOCATOR(float)>;
using bType = xs::simd_type<float>;
class SIMDSmoother
{
public:
SIMDSmoother(int nSmoothers, int maxBlockSize, double timeMS = 0.5)
: mTimeMS(timeMS)
{
setSampleRate(44100.);
mScratchBuffer.Resize(nSmoothers * maxBlockSize);
for (int i=0;i<nSmoothers; i++)
{
mOut_m1s.push_back(0.);
mInputs.push_back(0.);
mOutputPtrs.Add(mScratchBuffer.GetAligned(16) + (i * maxBlockSize));
}
}
void ProcessBlock(int nFrames)
{
int inc = (int) bType::size;
int size = (int) mOut_m1s.size();
// size for which the vectorization is possible
int vecSize = size - size % inc;
for (int s = 0; s < nFrames; s++)
{
for(int i = 0; i < vecSize; i += inc)
{
bType bInput = xs::load_aligned(&mInputs[i]);
bType output = (bInput * mB) + (xs::load_aligned(&mOut_m1s[i]) * mA);
xs::store_aligned(&mOut_m1s[i], output);
for(int j = 0; j < inc; j++)
{
mOutputPtrs.Get(i + j)[s] = output[j];
}
}
}
}
void setSampleRate(double sr)
{
mA = std::exp(-1.f/((mTimeMS/1000.f) * sr));
mB = 1.f - mA;
}
float getValue(int valueIdx, int sampleIdx) const
{
return mOutputPtrs.Get(valueIdx)[sampleIdx];
}
void setValue(int valueIdx, float value)
{
mInputs[valueIdx] = value;
}
private:
float mA, mB;
double mTimeMS;
tVec mOut_m1s;
tVec mInputs;
WDL_TypedBuf<float> mScratchBuffer;
WDL_PtrList<float> mOutputPtrs;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment