diff --git a/examples/Audio/order.json b/examples/Audio/order.json index 9769c0d49..d2d9551e6 100644 --- a/examples/Audio/order.json +++ b/examples/Audio/order.json @@ -9,5 +9,6 @@ "filterbanks", "FFT-phase-vocoder", "sample-streamer", - "sample-streamer-multi" + "sample-streamer-multi", + "resample" ] diff --git a/examples/Audio/resample/render.cpp b/examples/Audio/resample/render.cpp new file mode 100644 index 000000000..5aceb9590 --- /dev/null +++ b/examples/Audio/resample/render.cpp @@ -0,0 +1,100 @@ +/* + ____ _____ _ _ +| __ )| ____| | / \ +| _ \| _| | | / _ \ +| |_) | |___| |___ / ___ \ +|____/|_____|_____/_/ \_\ +http://bela.io +*/ +/** +\example Audio/resample/render.cpp + +Downsample a signal to process it at a lower sample rate. +========================================================= + +This project downsamples a source signal, does some processing at the a lower +sample rate and then upsamples the processed signal again such that it can be +send to the output channel. +The source signal is a simple sine tone. The original signal and the downsampled +signal are send to the scope and can be compared there. Note that the resampling +introduces a small delay due to the anti-aliasing filter that is applied both +during decimation (downsampling) and interpolation (upsampling). +By changing the global variable gDecimationFactor, you can decide the ratio between +the original samplerate and the samplerate after downsampling. +*/ + +#include +#include +#include +#include + +const float gFrequency = 440.0; +const unsigned int gDecimationFactor = 4; +const unsigned int gOutputChannel = 0; + +Scope scope; +Decimator decimator; +Interpolator interpolator; + +unsigned int gBlockSizeResampled; +float gPhase; +float gInverseSampleRate; + +float sinetone() { + float out = 0.8f * sinf(gPhase); + gPhase += 2.0f * (float)M_PI * gFrequency * gInverseSampleRate; + if (gPhase > M_PI) + gPhase -= 2.0f * (float)M_PI; + return out; +} + +bool setup(BelaContext* context, void* userData) { + gBlockSizeResampled = context->audioFrames / gDecimationFactor; + scope.setup(2, context->audioSampleRate); + + if (decimator.setup(gDecimationFactor, context->audioFrames, ResampleBase::fir_quality::high, ResampleBase::fir_phase::linear)) { + return false; + }; + if (interpolator.setup(gDecimationFactor, gBlockSizeResampled, ResampleBase::fir_quality::high, ResampleBase::fir_phase::linear)) { + return false; + }; + + gInverseSampleRate = 1.0 / context->audioSampleRate; + gPhase = 0.0; + + return true; +} + +void render(BelaContext* context, void* userData) { + + // source is a sine tone + float inOutBuf[context->audioFrames]; + for (unsigned int n = 0; n < context->audioFrames; ++n) { + inOutBuf[n] = sinetone(); + } + + // downsample + float downsampledBuf[gBlockSizeResampled]; + decimator.process(downsampledBuf, inOutBuf); + + // do some processing at a lower sampling rate + for (unsigned int n = 0; n < gBlockSizeResampled; n++) { + downsampledBuf[n] *= 1; // obviously this doen't do anything + } + + // inspect source and resampled signal in scope + for (unsigned int n = 0; n < context->audioFrames; n++) { + scope.log(inOutBuf[n], downsampledBuf[n / gDecimationFactor]); + } + + // upsample before output + interpolator.process(inOutBuf, downsampledBuf); + + // play at output channel + for (unsigned int n = 0; n < context->audioFrames; ++n) { + audioWrite(context, n, gOutputChannel, inOutBuf[n]); + } +} + +void cleanup(BelaContext* context, void* userData) { +} \ No newline at end of file diff --git a/libraries/Resample/Resample.cpp b/libraries/Resample/Resample.cpp new file mode 100644 index 000000000..99c91bf5a --- /dev/null +++ b/libraries/Resample/Resample.cpp @@ -0,0 +1,205 @@ +#include +#include // ceil +#include // memcpy + +#define ENABLE_NE10_FIR_DECIMATE_FLOAT_NEON // Defines needed for Ne10 library +#define ENABLE_NE10_FIR_INTERPOLATE_FLOAT_NEON +#include // neon library, must be included before `Resample.h` (or anything else that #includes NE10.h) + +#include "Resample.h" +#include "aa_fir.h" + +std::vector ResampleBase::get_fir(unsigned int factor, fir_quality quality, fir_phase phase) { + if (factor == 2 && quality == high && phase == minimum) + return fir_2_high_minphase; + else if (factor == 2 && quality == high && phase == linear) + return fir_2_high_linear; + else if (factor == 2 && quality == low && phase == minimum) + return fir_2_low_minphase; + else if (factor == 2 && quality == low && phase == linear) + return fir_2_low_linear; + else if (factor == 4 && quality == high && phase == minimum) + return fir_4_high_minphase; + else if (factor == 4 && quality == high && phase == linear) + return fir_4_high_linear; + else if (factor == 4 && quality == low && phase == minimum) + return fir_4_low_minphase; + else if (factor == 4 && quality == low && phase == linear) + return fir_4_low_linear; + else if (factor == 8 && quality == high && phase == minimum) + return fir_8_high_minphase; + else if (factor == 8 && quality == high && phase == linear) + return fir_8_high_linear; + else if (factor == 8 && quality == low && phase == minimum) + return fir_8_low_minphase; + else if (factor == 8 && quality == low && phase == linear) + return fir_8_low_linear; + else if (factor == 16 && quality == high && phase == minimum) + return fir_16_high_minphase; + else if (factor == 16 && quality == high && phase == linear) + return fir_16_high_linear; + else if (factor == 16 && quality == low && phase == minimum) + return fir_16_low_minphase; + else if (factor == 16 && quality == low && phase == linear) + return fir_16_low_linear; + else { + std::cerr << "get_fir: invalid combination " << factor << quality << phase << std::endl; + return std::vector(); + } +} + +void ResampleBase::cleanup() { + NE10_FREE(pCoeff); + NE10_FREE(pState); + pCoeff = nullptr; + pState = nullptr; +} + +int Decimator::setup(unsigned int decimationFactor, unsigned int blockSize, fir_quality quality, fir_phase phase) { + cleanup(); + this->blockSizeIn = blockSize; + this->factor = decimationFactor; + if (decimationFactor == 1) { + // Don't do anything + return 0; + } + std::vector fir = get_fir(decimationFactor, quality, phase); + uint numTaps = fir.size(); + + pCoeff = (ne10_float32_t*)NE10_MALLOC(numTaps * sizeof(ne10_float32_t)); + pState = (ne10_float32_t*)NE10_MALLOC( + (numTaps + blockSize - 1) * sizeof(ne10_float32_t)); + if (!pState || !pCoeff) + return -1; + + for (unsigned int n = 0; n < numTaps; ++n) { + // reverse filter coefficients + pCoeff[n] = fir[numTaps - 1 - n]; + } + int err = ne10_fir_decimate_init_float(&decimator, numTaps, decimationFactor, pCoeff, pState, blockSize); + if (err) { + std::cerr << "ERR: blockSize must be whole multiple of decimationFactor" << std::endl; + return -1; + } + + return 0; +} + +void Decimator::process(ne10_float32_t* outBlock, const ne10_float32_t* inBlock) { + if (factor == 1 && outBlock != inBlock) { + memcpy(outBlock, inBlock, blockSizeIn * sizeof(*outBlock)); + return; + } + ne10_fir_decimate_float_neon(&decimator, (float*)inBlock, outBlock, blockSizeIn); +} + +int Interpolator::setup(unsigned int L, unsigned int blockSize, fir_quality quality, fir_phase phase) { + cleanup(); + this->blockSizeIn = blockSize / L; + this->factor = L; + if (L == 1) { + // Don't do anything + return 0; + } + std::vector fir = get_fir(L, quality, phase); + uint filtSize = fir.size(); + // numTaps must be a multiple of the interpolation factor + uint numTaps = ceil((float)filtSize / L) * L; + uint phaseLength = numTaps / L; + pCoeff = (ne10_float32_t*)NE10_MALLOC(numTaps * sizeof(ne10_float32_t)); + pState = (ne10_float32_t*)NE10_MALLOC( + (blockSizeIn + phaseLength - 1) * sizeof(ne10_float32_t)); + if (!pState || !pCoeff) { + return -1; + } + + for (unsigned int n = 0; n < filtSize; ++n) { + // reverse fir coefficients + pCoeff[numTaps - filtSize + n] = fir[filtSize - 1 - n]; + } + for (uint n = 0; n < numTaps - filtSize; ++n) { + // rest are are zeros + pCoeff[n] = 0; + } + + int err = ne10_fir_interpolate_init_float(&interpolator, L, numTaps, pCoeff, pState, blockSizeIn); + if (err) { + std::cerr << "Error: couldn't init interpolator" << std::endl; + return -1; + } + + return 0; +} + +void Interpolator::process(ne10_float32_t* outBlock, const ne10_float32_t* inBlock) { + if (factor == 1 && outBlock != inBlock) { + memcpy(outBlock, inBlock, blockSizeIn * sizeof(*outBlock)); + return; + } + ne10_fir_interpolate_float_neon(&interpolator, (float*)inBlock, outBlock, blockSizeIn); +} + +#if 0 +#undef NDEBUG +#include +bool DecimatorTest() +{ + std::vector> irs(2); + const unsigned int len = 1000; + for(unsigned int n = 0; n < len; ++n) { + float val = (len - n) / (float)len; + irs[0].push_back(val); + irs[1].push_back(-val); + } + Decimator c; + Decimator d; + const unsigned int blockSize = 16; + c.setup(irs, blockSize); + d.setup(irs, blockSize); + const unsigned int outChannels = 3; + for(int inChannels = 1; inChannels < 5; ++inChannels) + { + const unsigned int numFrames = 3 * len; + // interleaved buffers + std::vector outs(numFrames * outChannels); + std::vector douts(numFrames * outChannels); + std::vector ins(numFrames * inChannels); + // ins contains impulses + for(unsigned int n = 0; n < inChannels; ++n) + ins[n] = n + 1; + for(unsigned int n = 0; n < numFrames - blockSize; n += blockSize) { + unsigned int outOffset = n * outChannels; + unsigned int inOffset = n * inChannels; + c.processInterleaved(outs.data() + outOffset, ins.data() + inOffset, + blockSize, outChannels, inChannels); + for(unsigned int i = 0; i < inChannels && i < d.getChannels(); ++i) + { + float out[blockSize]; + float in[blockSize]; + for(unsigned int k = 0; k < blockSize; ++k) + in[k] = ins[numFrames + k * inChannels + i]; + d.process(out, in, blockSize, i); + for(unsigned int k = 0; k < blockSize; ++k) + outs[numFrames + k * inChannels + i] = out[k]; + } + } + for(unsigned int n = 0; n < numFrames; ++n) + { + for(unsigned int i = 0; i < outChannels; ++i) { + float expected; + if(i < irs.size() && n < irs[i].size() && i < inChannels) + expected = irs[i][n] * (i + 1); + else + expected = 0; + float out = outs[n * outChannels + i]; + float dout = outs[n * outChannels + i]; + if(out != expected || dout != expected) { + fprintf(stderr, "error at n: %d, ch: %d. inChannels: %d, inVal: %f, expected: %f, got: %f, dgot: %f\n", n, i, inChannels, ins[n * inChannels +i], expected, out, dout); + assert(false); + } + } + } + } + return true; +} +#endif diff --git a/libraries/Resample/Resample.h b/libraries/Resample/Resample.h new file mode 100644 index 000000000..ff1e3510d --- /dev/null +++ b/libraries/Resample/Resample.h @@ -0,0 +1,48 @@ +#include +#include + +// Abstract base class for decimator and intepolator +class ResampleBase { +public: + enum fir_quality { high, + low }; + enum fir_phase { minimum, + linear }; + ~ResampleBase() { cleanup(); }; + virtual int setup(unsigned int factor, unsigned int blockSize, fir_quality quality, fir_phase phase) = 0; + virtual void process(float* outBlock, const float* inBlock) = 0; + +protected: + std::vector get_fir(unsigned int factor, fir_quality quality, fir_phase phase); + void cleanup(); + unsigned int blockSizeIn; + unsigned int factor; + ne10_float32_t* pCoeff = nullptr; + ne10_float32_t* pState = nullptr; +}; + +class Decimator : public ResampleBase { +public: + Decimator(){}; + Decimator(unsigned int factor, unsigned int blockSize, fir_quality quality, fir_phase phase) { + setup(factor, blockSize, quality, phase); + }; + int setup(unsigned int decimationFactor, unsigned int blockSize, fir_quality quality = high, fir_phase phase = linear); + void process(float* outBlock, const float* inBlock); + +private: + ne10_fir_decimate_instance_f32_t decimator; +}; + +class Interpolator : public ResampleBase { +public: + Interpolator(){}; + Interpolator(unsigned int factor, unsigned int blockSize, fir_quality quality, fir_phase phase) { + setup(factor, blockSize, quality, phase); + }; + int setup(unsigned int interpolationFactor, unsigned int blockSize, fir_quality quality = high, fir_phase phase = linear); + void process(float* outBlock, const float* inBlock); + +private: + ne10_fir_interpolate_instance_f32_t interpolator; +}; \ No newline at end of file diff --git a/libraries/Resample/aa_fir.h b/libraries/Resample/aa_fir.h new file mode 100644 index 000000000..bbf4eafaa --- /dev/null +++ b/libraries/Resample/aa_fir.h @@ -0,0 +1,2935 @@ +#include + +// cutoff: 0.225 * sr +// numTaps: 51 +// ripple: 80 +// phase: minimum +std::vector fir_2_high_minphase = { + 4.3722142749386392e-02, + 1.7614320524524416e-01, + 3.4648387984545992e-01, + 3.9759902073619241e-01, + 2.2607800950842674e-01, + -5.0718657757082203e-02, + -1.8251005786751157e-01, + -7.4695834695210558e-02, + 9.3220592475834141e-02, + 1.0257410827999744e-01, + -2.5731547193203363e-02, + -9.2282866933618993e-02, + -1.6281697284818267e-02, + 6.8998723382982838e-02, + 3.8436741192205387e-02, + -4.3769511882573726e-02, + -4.6691937920674553e-02, + 2.1474024694138283e-02, + 4.5900285475941209e-02, + -4.0331297015319687e-03, + -3.9794464543789161e-02, + -8.1383625817098276e-03, + 3.1137855590174932e-02, + 1.5447158830833746e-02, + -2.1902560779260685e-02, + -1.8715369459070413e-02, + 1.3387712476163978e-02, + 1.8947943222262870e-02, + -6.3489941741575349e-03, + -1.7153413387194821e-02, + 1.0996742137334100e-03, + 1.4241168577628586e-02, + 2.3672423569476801e-03, + -1.0941598859276747e-02, + -4.2816755582750620e-03, + 7.7885751606447482e-03, + 4.9800271722939956e-03, + -5.0994976060557149e-03, + -4.8467126455053206e-03, + 3.0283955966671642e-03, + 4.2229471694928307e-03, + -1.5763390773546517e-03, + -3.3999733048867297e-03, + 6.7137938272539537e-04, + 2.5692115889008570e-03, + -1.8062132247890570e-04, + -1.8554325822914457e-03, + -2.2272843521294697e-05, + 1.2999022748010696e-03, + 6.2208675917562749e-05, + -9.0960591394420012e-04 +}; + +// cutoff: 0.225 * sr +// numTaps: 102 +// ripple: 80 +// phase: linear +std::vector fir_2_high_linear = { + 1.2809588808484075e-05, + 2.2257572396190976e-05, + -2.3909482985913329e-05, + -6.1981617882020439e-05, + 2.1970937541873283e-05, + 1.2739671389496251e-04, + 1.3271521943359044e-05, + -2.1327446396811805e-04, + -1.0698695253503209e-04, + 2.9944015664806441e-04, + 2.8292217699696473e-04, + -3.4709267831123885e-04, + -5.5359210642144923e-04, + 2.9921222955062561e-04, + 9.0835190356575819e-04, + -8.6943026005468162e-05, + -1.3019066604756638e-03, + -3.5713734432907376e-04, + 1.6466699039334057e-03, + 1.0794905552958265e-03, + -1.8125694339519989e-03, + -2.0822840462476322e-03, + 1.6371950950831412e-03, + 3.3003790763007396e-03, + -9.4756535312468795e-04, + -4.5838052979045819e-03, + -4.0751506592246774e-04, + 5.6908510487912109e-03, + 2.5180561004644682e-03, + -6.2955262668019487e-03, + -5.3720827854385729e-03, + 6.0104239738092043e-03, + 8.8200084515865657e-03, + -4.4221124139289438e-03, + -1.2549786578044869e-02, + 1.1313555622793892e-03, + 1.6074724561412179e-02, + 4.2156088798689538e-03, + -1.8727731920182154e-02, + -1.1928162907840722e-02, + 1.9638266498467817e-02, + 2.2351180888065977e-02, + -1.7622290074269350e-02, + -3.6146568257888832e-02, + 1.0755051545235594e-02, + 5.5231322813222940e-02, + 5.3901070844156549e-03, + -8.6884820903499374e-02, + -4.8287604644234032e-02, + 1.8034826714279470e-01, + 4.1329665829981999e-01, + 4.1329665829981999e-01, + 1.8034826714279470e-01, + -4.8287604644234032e-02, + -8.6884820903499374e-02, + 5.3901070844156549e-03, + 5.5231322813222940e-02, + 1.0755051545235594e-02, + -3.6146568257888832e-02, + -1.7622290074269350e-02, + 2.2351180888065977e-02, + 1.9638266498467817e-02, + -1.1928162907840722e-02, + -1.8727731920182154e-02, + 4.2156088798689538e-03, + 1.6074724561412179e-02, + 1.1313555622793892e-03, + -1.2549786578044869e-02, + -4.4221124139289438e-03, + 8.8200084515865657e-03, + 6.0104239738092043e-03, + -5.3720827854385729e-03, + -6.2955262668019487e-03, + 2.5180561004644682e-03, + 5.6908510487912109e-03, + -4.0751506592246774e-04, + -4.5838052979045819e-03, + -9.4756535312468795e-04, + 3.3003790763007396e-03, + 1.6371950950831412e-03, + -2.0822840462476322e-03, + -1.8125694339519989e-03, + 1.0794905552958265e-03, + 1.6466699039334057e-03, + -3.5713734432907376e-04, + -1.3019066604756638e-03, + -8.6943026005468162e-05, + 9.0835190356575819e-04, + 2.9921222955062561e-04, + -5.5359210642144923e-04, + -3.4709267831123885e-04, + 2.8292217699696473e-04, + 2.9944015664806441e-04, + -1.0698695253503209e-04, + -2.1327446396811805e-04, + 1.3271521943359044e-05, + 1.2739671389496251e-04, + 2.1970937541873283e-05, + -6.1981617882020439e-05, + -2.3909482985913329e-05, + 2.2257572396190976e-05, + 1.2809588808484075e-05 +}; + +// cutoff: 0.175 * sr +// numTaps: 13 +// ripple: 60 +// phase: minimum +std::vector fir_2_low_minphase = { + 8.4390544654505170e-02, + 2.4373943363061573e-01, + 3.6877359643824864e-01, + 3.3145123638284485e-01, + 1.3707382445706798e-01, + -6.0491832954826984e-02, + -1.1779270976544816e-01, + -4.4523644218519884e-02, + 3.6291275262370165e-02, + 4.2903820791367391e-02, + 3.2651097045362509e-03, + -1.7899919414406294e-02, + -7.1807349683548419e-03 +}; + +// cutoff: 0.175 * sr +// numTaps: 26 +// ripple: 60 +// phase: linear +std::vector fir_2_low_linear = { + 4.7991244665945653e-04, + 1.1780432466133806e-04, + -2.7183058989479099e-03, + -4.9820510898411965e-03, + 7.6806349668853647e-04, + 1.4263565931065036e-02, + 1.7763579590002347e-02, + -8.0396926438541030e-03, + -4.8869782894521228e-02, + -4.8164275209873215e-02, + 4.3960274433956469e-02, + 2.0397260444006071e-01, + 3.3144830307394380e-01, + 3.3144830307394380e-01, + 2.0397260444006071e-01, + 4.3960274433956469e-02, + -4.8164275209873215e-02, + -4.8869782894521228e-02, + -8.0396926438541030e-03, + 1.7763579590002347e-02, + 1.4263565931065036e-02, + 7.6806349668853647e-04, + -4.9820510898411965e-03, + -2.7183058989479099e-03, + 1.1780432466133806e-04, + 4.7991244665945653e-04 +}; + +// cutoff: 0.1125 * sr +// numTaps: 101 +// ripple: 80 +// phase: minimum +std::vector fir_4_high_minphase = { + 9.4146347568241414e-03, + 2.7631743252567433e-02, + 5.7963730917694217e-02, + 9.8548902819215661e-02, + 1.4300029168976994e-01, + 1.8104809531243046e-01, + 2.0111553898724810e-01, + 1.9417340234259997e-01, + 1.5747513239781802e-01, + 9.6687729324891933e-02, + 2.5204489889306153e-02, + -3.9444167471994168e-02, + -8.1120085174977263e-02, + -9.0539398630824330e-02, + -6.8612255214088078e-02, + -2.6188681406779362e-02, + 1.9814798735803843e-02, + 5.2588311549106787e-02, + 6.1470400761966255e-02, + 4.5581300547282273e-02, + 1.3556670814781650e-02, + -2.0393957939373892e-02, + -4.2477153863752441e-02, + -4.4811039973066916e-02, + -2.8245543153148287e-02, + -1.3902567027075808e-03, + 2.3509219658311636e-02, + 3.6016419964768599e-02, + 3.1813950872072901e-02, + 1.4135322471311551e-02, + -8.1832566265574256e-03, + -2.4948927205962944e-02, + -2.9211279742712232e-02, + -2.0089568704237785e-02, + -2.7426442224237815e-03, + 1.4386032386446986e-02, + 2.3589070421094312e-02, + 2.1336814649335473e-02, + 9.5632762243212568e-03, + -5.6015666152606442e-03, + -1.6953040412417499e-02, + -1.9583248446769667e-02, + -1.2985388569744750e-02, + -9.3974843531304843e-04, + 1.0540327380812732e-02, + 1.6177847256016210e-02, + 1.3827360261295959e-02, + 5.2423763130924833e-03, + -5.0622890363717669e-03, + -1.2122230846918675e-02, + -1.2905714583611226e-02, + -7.5715759014261782e-03, + 8.4891702703880666e-04, + 8.1291919413426800e-03, + 1.0934786243333300e-02, + 8.3357319880097442e-03, + 2.0354707983631227e-03, + -4.6452510005771776e-03, + -8.5088247296733130e-03, + -7.9773933983391283e-03, + -3.7141258628221757e-03, + 1.9031329201664045e-03, + 6.0664184839960235e-03, + 6.9327077795369790e-03, + 4.4062012930448100e-03, + 3.6486287318080456e-05, + -3.9025158943356343e-03, + -5.5622282961796015e-03, + -4.3837382360184468e-03, + -1.2298364657625212e-03, + 2.1689938567281404e-03, + 4.1501916380643020e-03, + 3.9080930082837301e-03, + 1.8131477406364044e-03, + -9.1568407203421350e-04, + -2.8789511451343956e-03, + -3.2130281887326464e-03, + -1.9466781236980866e-03, + 1.0699943400360493e-04, + 1.8516378493742664e-03, + 2.4678116703205971e-03, + 1.7994632816234807e-03, + 3.3422798809372596e-04, + -1.0967375513573174e-03, + -1.7920582678372194e-03, + -1.5034788115082442e-03, + -5.1067321066005983e-04, + 5.9501175819037008e-04, + 1.2401426472734656e-03, + 1.1700593605806402e-03, + 5.1733742093117185e-04, + -2.9630987764522648e-04, + -8.3514100282304450e-04, + -8.5954101283996836e-04, + -4.3845089606023611e-04, + 1.4627540679283996e-04, + 5.5923422235784745e-04, + 6.1149587200614360e-04, + 3.2616648704088442e-04, + -8.6973064461923899e-05, + -3.8788837369780238e-04 +}; + +// cutoff: 0.1125 * sr +// numTaps: 202 +// ripple: 80 +// phase: linear +std::vector fir_4_high_linear = { + 7.9416495800456900e-06, + 1.0666766545226998e-05, + 7.2043011730087529e-06, + -3.6353664766193822e-06, + -1.8131391471034215e-05, + -2.8134351689016358e-05, + -2.4887624384282820e-05, + -4.7428612547107379e-06, + 2.6442414095542892e-05, + 5.3592770552911081e-05, + 5.8740290262321974e-05, + 3.1256326086672218e-05, + -2.3257904565985966e-05, + -8.1343812457310938e-05, + -1.1040887967718026e-04, + -8.5398600772487677e-05, + -5.5670617836611257e-06, + 9.8586815867607015e-05, + 1.7480320197427071e-04, + 1.7349259963575056e-04, + 7.6559756139410237e-05, + -8.4929420906533178e-05, + -2.3687835176609777e-04, + -2.9389784313998328e-04, + -2.0428288023314009e-04, + 1.4233853594376735e-05, + 2.6984238239051065e-04, + 4.3199666080693730e-04, + 3.9505914423178712e-04, + 1.4061264603465703e-04, + -2.3604796053600688e-04, + -5.5637930898261528e-04, + -6.3972621854085584e-04, + -4.0003500421072663e-04, + 9.1549571827174940e-05, + 6.1785976422930387e-04, + 9.0702020296232623e-04, + 7.6805955548933918e-04, + 2.0533118218913414e-04, + -5.5278091561035956e-04, + -1.1395832354814592e-03, + -1.2222266750105998e-03, + -6.8200695126052399e-04, + 2.9145850209503810e-04, + 1.2545743334046535e-03, + 1.7054138794833074e-03, + 1.3377789216588673e-03, + 2.2837156006606774e-04, + -1.1503367269864427e-03, + -2.1220420255502665e-03, + -2.1305812828337246e-03, + -1.0444164629097202e-03, + 7.1956430442878883e-04, + 2.3407401451983594e-03, + 2.9671708290431903e-03, + 2.1514073199152810e-03, + 1.3192340633685231e-04, + -2.2045293234960683e-03, + -3.6993714627636762e-03, + -3.4844804860618621e-03, + -1.4630580034124315e-03, + 1.5480569866722458e-03, + 4.1279367399737589e-03, + 4.9073727064080398e-03, + 3.2753494991289516e-03, + -2.1959249487605548e-04, + -4.0136991192702802e-03, + -6.2073249672770182e-03, + -5.4942707099394292e-03, + -1.8963572401940302e-03, + 3.0928749384859394e-03, + 7.0960608191115672e-03, + 7.9569591464229671e-03, + 4.8617166866750270e-03, + -1.0892659592132167e-03, + -7.2114400264895852e-03, + -1.0406382683836852e-02, + -8.6808018962932932e-03, + -2.2912721880321389e-03, + 6.1046275078176200e-03, + 1.2486130793072070e-02, + 1.3322245076032895e-02, + 7.4168360446536692e-03, + -3.1723577287840463e-03, + -1.3714581391458458e-02, + -1.8795945611914184e-02, + -1.4929067095466811e-02, + -2.5930698273800273e-03, + 1.3363964028249846e-02, + 2.5386393197767847e-02, + 2.6446846437606395e-02, + 1.3574274180177055e-02, + -9.9011422479110371e-03, + -3.4573765816708180e-02, + -4.7889608513087600e-02, + -3.8855415727835983e-02, + -2.7566859028321155e-03, + 5.6053562183530706e-02, + 1.2459358958227368e-01, + 1.8499721427349611e-01, + 2.2032387965817074e-01, + 2.2032387965817074e-01, + 1.8499721427349611e-01, + 1.2459358958227368e-01, + 5.6053562183530706e-02, + -2.7566859028321155e-03, + -3.8855415727835983e-02, + -4.7889608513087600e-02, + -3.4573765816708180e-02, + -9.9011422479110371e-03, + 1.3574274180177055e-02, + 2.6446846437606395e-02, + 2.5386393197767847e-02, + 1.3363964028249846e-02, + -2.5930698273800273e-03, + -1.4929067095466811e-02, + -1.8795945611914184e-02, + -1.3714581391458458e-02, + -3.1723577287840463e-03, + 7.4168360446536692e-03, + 1.3322245076032895e-02, + 1.2486130793072070e-02, + 6.1046275078176200e-03, + -2.2912721880321389e-03, + -8.6808018962932932e-03, + -1.0406382683836852e-02, + -7.2114400264895852e-03, + -1.0892659592132167e-03, + 4.8617166866750270e-03, + 7.9569591464229671e-03, + 7.0960608191115672e-03, + 3.0928749384859394e-03, + -1.8963572401940302e-03, + -5.4942707099394292e-03, + -6.2073249672770182e-03, + -4.0136991192702802e-03, + -2.1959249487605548e-04, + 3.2753494991289516e-03, + 4.9073727064080398e-03, + 4.1279367399737589e-03, + 1.5480569866722458e-03, + -1.4630580034124315e-03, + -3.4844804860618621e-03, + -3.6993714627636762e-03, + -2.2045293234960683e-03, + 1.3192340633685231e-04, + 2.1514073199152810e-03, + 2.9671708290431903e-03, + 2.3407401451983594e-03, + 7.1956430442878883e-04, + -1.0444164629097202e-03, + -2.1305812828337246e-03, + -2.1220420255502665e-03, + -1.1503367269864427e-03, + 2.2837156006606774e-04, + 1.3377789216588673e-03, + 1.7054138794833074e-03, + 1.2545743334046535e-03, + 2.9145850209503810e-04, + -6.8200695126052399e-04, + -1.2222266750105998e-03, + -1.1395832354814592e-03, + -5.5278091561035956e-04, + 2.0533118218913414e-04, + 7.6805955548933918e-04, + 9.0702020296232623e-04, + 6.1785976422930387e-04, + 9.1549571827174940e-05, + -4.0003500421072663e-04, + -6.3972621854085584e-04, + -5.5637930898261528e-04, + -2.3604796053600688e-04, + 1.4061264603465703e-04, + 3.9505914423178712e-04, + 4.3199666080693730e-04, + 2.6984238239051065e-04, + 1.4233853594376735e-05, + -2.0428288023314009e-04, + -2.9389784313998328e-04, + -2.3687835176609777e-04, + -8.4929420906533178e-05, + 7.6559756139410237e-05, + 1.7349259963575056e-04, + 1.7480320197427071e-04, + 9.8586815867607015e-05, + -5.5670617836611257e-06, + -8.5398600772487677e-05, + -1.1040887967718026e-04, + -8.1343812457310938e-05, + -2.3257904565985966e-05, + 3.1256326086672218e-05, + 5.8740290262321974e-05, + 5.3592770552911081e-05, + 2.6442414095542892e-05, + -4.7428612547107379e-06, + -2.4887624384282820e-05, + -2.8134351689016358e-05, + -1.8131391471034215e-05, + -3.6353664766193822e-06, + 7.2043011730087529e-06, + 1.0666766545226998e-05, + 7.9416495800456900e-06 +}; + +// cutoff: 0.0875 * sr +// numTaps: 25 +// ripple: 60 +// phase: minimum +std::vector fir_4_low_minphase = { + 3.1670077015177489e-02, + 6.4078884098873176e-02, + 1.0525572327624977e-01, + 1.4628451017055941e-01, + 1.7718083452750621e-01, + 1.8909565396061614e-01, + 1.7692802094548540e-01, + 1.4165754363418190e-01, + 9.0180609151926328e-02, + 3.3811181098111001e-02, + -1.5367051527900022e-02, + -4.7713289093428243e-02, + -5.9014280346163302e-02, + -5.1007107279381660e-02, + -3.0522262917791511e-02, + -6.4710688116802117e-03, + 1.2922636098171288e-02, + 2.2826913300019867e-02, + 2.2491466127815989e-02, + 1.4894199167336660e-02, + 4.6264235689559615e-03, + -3.8416340829394162e-03, + -8.0238260929062135e-03, + -7.6163367691943415e-03, + -4.3278192196016009e-03 +}; + +// cutoff: 0.0875 * sr +// numTaps: 50 +// ripple: 60 +// phase: linear +std::vector fir_4_low_linear = { + 2.0816110347548678e-04, + 1.6724218604766616e-04, + -1.5211715489392351e-04, + -7.9428042634456194e-04, + -1.6086883863679446e-03, + -2.2160471678977149e-03, + -2.0934825806087601e-03, + -7.8805644566280156e-04, + 1.7980034884823510e-03, + 5.1676154826178948e-03, + 8.1744721446680244e-03, + 9.2554265518639406e-03, + 6.9526525885758124e-03, + 5.9949954979067704e-04, + -9.0652188423634081e-03, + -1.9626128484325867e-02, + -2.7266738670884003e-02, + -2.7628930096201064e-02, + -1.7080052817462894e-02, + 5.9734912720489476e-03, + 4.0165916292933167e-02, + 8.1012528592306343e-02, + 1.2166472458036415e-01, + 1.5444233622790327e-01, + 1.7273767101193518e-01, + 1.7273767101193518e-01, + 1.5444233622790327e-01, + 1.2166472458036415e-01, + 8.1012528592306343e-02, + 4.0165916292933167e-02, + 5.9734912720489476e-03, + -1.7080052817462894e-02, + -2.7628930096201064e-02, + -2.7266738670884003e-02, + -1.9626128484325867e-02, + -9.0652188423634081e-03, + 5.9949954979067704e-04, + 6.9526525885758124e-03, + 9.2554265518639406e-03, + 8.1744721446680244e-03, + 5.1676154826178948e-03, + 1.7980034884823510e-03, + -7.8805644566280156e-04, + -2.0934825806087601e-03, + -2.2160471678977149e-03, + -1.6086883863679446e-03, + -7.9428042634456194e-04, + -1.5211715489392351e-04, + 1.6724218604766616e-04, + 2.0816110347548678e-04 +}; + +// cutoff: 0.05625 * sr +// numTaps: 202 +// ripple: 80 +// phase: minimum +std::vector fir_8_high_minphase = { + 3.6674063715924957e-03, + 6.6841391935982463e-03, + 1.1343636845442933e-02, + 1.7540574160531661e-02, + 2.5274468425067979e-02, + 3.4425652245686438e-02, + 4.4726461938632778e-02, + 5.5760380269724533e-02, + 6.6971562077471222e-02, + 7.7690484202984772e-02, + 8.7181592543083747e-02, + 9.4699056948484572e-02, + 9.9547180667864152e-02, + 1.0115019107469396e-01, + 9.9113757779814196e-02, + 9.3274178162219917e-02, + 8.3736481807840740e-02, + 7.0883703515108795e-02, + 5.5364747555029389e-02, + 3.8061145164462795e-02, + 2.0018695297559033e-02, + 2.3708574223599847e-03, + -1.3748361408470086e-02, + -2.7310027955355060e-02, + -3.7474843357921971e-02, + -4.3666438656948185e-02, + -4.5631525345461478e-02, + -4.3460002778949763e-02, + -3.7581413101563169e-02, + -2.8722804784920397e-02, + -1.7844431155819102e-02, + -6.0535947150919664e-03, + 5.5080423080247753e-03, + 1.5759373341060919e-02, + 2.3792133834364525e-02, + 2.8942437906573207e-02, + 3.0856245641309687e-02, + 2.9511929785428204e-02, + 2.5213356909712121e-02, + 1.8548641317239788e-02, + 1.0324986004428528e-02, + 1.4744499934859071e-03, + -7.0441179179898082e-03, + -1.4345625272360999e-02, + -1.9710963740274583e-02, + -2.2655687506373201e-02, + -2.2974639162839178e-02, + -2.0755244147000199e-02, + -1.6357385570425636e-02, + -1.0364224357746482e-02, + -3.5093903011773780e-03, + 3.4056856382648185e-03, + 9.6050182157991805e-03, + 1.4425281299322457e-02, + 1.7382544238884499e-02, + 1.8223362215815695e-02, + 1.6943214882626019e-02, + 1.3778623179249288e-02, + 9.1736598618081221e-03, + 3.7169889576464999e-03, + -1.9260536796803708e-03, + -7.0943161619390471e-03, + -1.1208232306187593e-02, + -1.3832599161452021e-02, + -1.4723893583696716e-02, + -1.3848351694610961e-02, + -1.1382124349705302e-02, + -7.6797028471671915e-03, + -3.2288311275514500e-03, + 1.4139871756116938e-03, + 5.6906166230092274e-03, + 9.1093850277342934e-03, + 1.1297359505608629e-02, + 1.2044156381222935e-02, + 1.1319556529298275e-02, + 9.2695889509368749e-03, + 6.1939367651660899e-03, + 2.5030276440629598e-03, + -1.3340860859600370e-03, + -4.8484230766274459e-03, + -7.6297556093725787e-03, + -9.3714466247787620e-03, + -9.9051091690353504e-03, + -9.2153455674640217e-03, + -7.4353742543314854e-03, + -4.8264423428191934e-03, + -1.7397853836535907e-03, + 1.4277805665837422e-03, + 4.2863723066978174e-03, + 6.5004462129480628e-03, + 7.8249050071997929e-03, + 8.1345560905129854e-03, + 7.4333569609401195e-03, + 5.8498068179428601e-03, + 3.6163142197262067e-03, + 1.0348003204641147e-03, + -1.5624541886018878e-03, + -3.8546396243244142e-03, + -5.5712565039582624e-03, + -6.5246806317374537e-03, + -6.6294334082499257e-03, + -5.9100241266609012e-03, + -4.4905229895554127e-03, + -2.5779352037651709e-03, + -4.3096266684663999e-04, + 1.6728443031453050e-03, + 3.4736733168925747e-03, + 4.7611054507394109e-03, + 5.3968673483458605e-03, + 5.3310562060206318e-03, + 4.6040012160378958e-03, + 3.3358329215128083e-03, + 1.7104344212339709e-03, + -5.2402108975598142e-05, + -1.7254541148714331e-03, + -3.1030322966678057e-03, + -4.0265083927193464e-03, + -4.4007117752082039e-03, + -4.2045468455720984e-03, + -3.4899687491552300e-03, + -2.3719041788027961e-03, + -1.0109347673667353e-03, + 4.1010020407662755e-04, + 1.7088615386008903e-03, + 2.7269408223894592e-03, + 3.3492855955816439e-03, + 3.5168304393002636e-03, + 3.2315587529258174e-03, + 2.5528331260492193e-03, + 1.5859704762712715e-03, + 4.6865532378179413e-04, + -6.4898718744657200e-04, + -1.6251466116142207e-03, + -2.3422343260381968e-03, + -2.7231944904314107e-03, + -2.7371567056505143e-03, + -2.4022251558117394e-03, + -1.7796696815772716e-03, + -9.6415455310017574e-04, + -7.1080188540450210e-05, + 7.8050267005168815e-04, + 1.4836173374574448e-03, + 1.9562451277666819e-03, + 2.1512909651706059e-03, + 2.0589744798281177e-03, + 1.7077068671145594e-03, + 1.1578318454424647e-03, + 4.9159253978107965e-04, + -1.9770717221279430e-04, + -8.1953143669906273e-04, + -1.2976586903485157e-03, + -1.5785787734251791e-03, + -1.6380329756975069e-03, + -1.4817857045441533e-03, + -1.1430522784320553e-03, + -6.7733441916864611e-04, + -1.5339428215539307e-04, + 3.5637167489736935e-04, + 7.8626771707273301e-04, + 1.0855269813781364e-03, + 1.2227181364936122e-03, + 1.1906532689474132e-03, + 1.0045483063630969e-03, + 6.9909245173630538e-04, + 3.2285158927610423e-04, + -7.0222918098621114e-05, + -4.2624813822299496e-04, + -7.0059913170565603e-04, + -8.6278393640592751e-04, + -8.9878637924881415e-04, + -8.1264155415144491e-04, + -6.2432516572690367e-04, + -3.6625836274978892e-04, + -7.8484656161099701e-05, + 1.9824908975918306e-04, + 4.2737343995581303e-04, + 5.8165800210268823e-04, + 6.4567659885003681e-04, + 6.1699265206659215e-04, + 5.0647062839461756e-04, + 3.3543464974006190e-04, + 1.3192951059699370e-04, + -7.3071180877944979e-05, + -2.5167285105228836e-04, + -3.8138992110844217e-04, + -4.4785761802825728e-04, + -4.4668502957034151e-04, + -3.8263553539496056e-04, + -2.7021129109190207e-04, + -1.2955260845811333e-04, + 1.7723363549247147e-05, + 1.5027592531572265e-04, + 2.5079753396558212e-04, + 3.0696726227516567e-04, + 3.1412297730389538e-04, + 2.7519815558596294e-04, + 1.9926299782224073e-04, + 1.0070505242935733e-04, + -4.3454921803117430e-06, + -1.0007657436517130e-04, + -1.7290610685406652e-04, + -2.1411764725316949e-04 +}; + +// cutoff: 0.05625 * sr +// numTaps: 403 +// ripple: 80 +// phase: linear +std::vector fir_8_high_linear = { + 3.9708382327681750e-06, + 4.9306016374296919e-06, + 5.3334013281351790e-06, + 4.9408643426257770e-06, + 3.6021627811479419e-06, + 1.3001177496299045e-06, + -1.8176893918556559e-06, + -5.4307575226784832e-06, + -9.0657264263295850e-06, + -1.2145962120363102e-05, + -1.4067223467224462e-05, + -1.4291114685124852e-05, + -1.2443854319157100e-05, + -8.4051647165787538e-06, + -2.3714386555459034e-06, + 5.1208525240791278e-06, + 1.3221251806563059e-05, + 2.0844234918745317e-05, + 2.6796475992365232e-05, + 2.9939841848874766e-05, + 2.9370244560222251e-05, + 2.4587353504621511e-05, + 1.5628215950585078e-05, + 3.1397475812872881e-06, + -1.1628991651399364e-05, + -2.6924243741446360e-05, + -4.0672043918457073e-05, + -5.0733813933478508e-05, + -5.5204626726520245e-05, + -5.2715954447661238e-05, + -4.2699444939542274e-05, + -2.5568781745821922e-05, + -2.7835403151365200e-06, + 2.3228145759602534e-05, + 4.9293574810652612e-05, + 7.1851111640564876e-05, + 8.7401896874646299e-05, + 9.3004391984475904e-05, + 8.6746593486943644e-05, + 6.8126877953641527e-05, + 3.8280007661585741e-05, + -2.5686612601772112e-19, + -4.2464854212389271e-05, + -8.3840063878614675e-05, + -1.1843957684450216e-04, + -1.4090067591924620e-04, + -1.4694941904772830e-04, + -1.3409379777089983e-04, + -1.0214178590401718e-04, + -5.3455792592077604e-05, + 7.1169508906801549e-06, + 7.2659504969045972e-05, + 1.3492164795457078e-04, + 1.8530696851413160e-04, + 2.1599906163959740e-04, + 2.2108605306906141e-04, + 1.9753024082828295e-04, + 1.4583716256235578e-04, + 7.0306561030850995e-05, + -2.1205581421381138e-05, + -1.1802437982386235e-04, + -2.0783625008714723e-04, + -2.7819059626861504e-04, + -3.1814783282676894e-04, + -3.1986419212815800e-04, + -2.7989499533718565e-04, + -2.0001817924033768e-04, + -8.7428442628870192e-05, + 4.5774940878568828e-05, + 1.8379476725659645e-04, + 3.0893092795926857e-04, + 4.0377050164848210e-04, + 4.5351163678456255e-04, + 4.4812190716126901e-04, + 3.8403107783086687e-04, + 2.6509766030464354e-04, + 1.0266593865646372e-04, + -8.5362287201251524e-05, + -2.7639139349152519e-04, + -4.4575310424577365e-04, + -5.6979354670108758e-04, + -6.2905165508392053e-04, + -6.1111540635532446e-04, + -5.1275564221873397e-04, + -3.4100463005613623e-04, + -1.1296281070105764e-04, + 1.4572974439620921e-04, + 4.0364863528921104e-04, + 6.2728929030688677e-04, + 7.8529799492923103e-04, + 8.5270982647749278e-04, + 8.1463768240473190e-04, + 6.6889172527351054e-04, + 4.2711468634862358e-04, + 1.1418616659513179e-04, + -2.3413981449502423e-04, + -5.7517031065589951e-04, + -8.6436953761502133e-04, + -1.0610246047329805e-03, + -1.1337776756542245e-03, + -1.0652942478290191e-03, + -8.5540416980910334e-04, + -5.2220999932743963e-04, + -1.0089121726420446e-04, + 3.5978337021319877e-04, + 8.0292313245214093e-04, + 1.1703740347449958e-03, + 1.4101620167436650e-03, + 1.4835904370199317e-03, + 1.3710495993280668e-03, + 1.0757073016218076e-03, + 6.2447500597426621e-04, + 6.5961926473765504e-05, + -5.3449693532160649e-04, + -1.1022683933312486e-03, + -1.5624882313090410e-03, + -1.8496919932683585e-03, + -1.9167981482004670e-03, + -1.7422461411737932e-03, + -1.3342613951700247e-03, + -7.3153147820885478e-04, + 2.3963058050109641e-18, + 7.7403111371563207e-04, + 1.4938136285833580e-03, + 2.0639753573012624e-03, + 2.4028408067177987e-03, + 2.4536946598613294e-03, + 2.1934814756143528e-03, + 1.6376802937135523e-03, + 8.4051376002913846e-04, + -1.0979661913989589e-04, + -1.1003982097410234e-03, + -2.0068563535807237e-03, + -2.7084197951279900e-03, + -3.1036729907111113e-03, + -3.1245956658136312e-03, + -2.7471446550629990e-03, + -1.9968135695645644e-03, + -9.4818183004063928e-04, + 2.8182334485003753e-04, + 1.5464427045193082e-03, + 2.6861059111575034e-03, + 3.5480424209820595e-03, + 4.0061329855621032e-03, + 3.9784930418711529e-03, + 3.4404291901591858e-03, + 2.4308665727133666e-03, + 1.0510667184604674e-03, + -5.4463482339545078e-04, + -2.1653487466505479e-03, + -3.6057322199722188e-03, + -4.6711950010231082e-03, + -5.2032089566911282e-03, + -5.1015381946655980e-03, + -4.3404156420471995e-03, + -2.9762839034441191e-03, + -1.1456399724280033e-03, + 9.4732248234365949e-04, + 3.0523240871465204e-03, + 4.9017083490193345e-03, + 6.2430865316761243e-03, + 6.8720872974490652e-03, + 6.6611450884382431e-03, + 5.5805141901092261e-03, + 3.7084305767259049e-03, + 1.2284965848522998e-03, + -1.5861842342080313e-03, + -4.4010036746948682e-03, + -6.8573139102545118e-03, + -8.6153887752712620e-03, + -9.3980046216532581e-03, + -9.0293937429823425e-03, + -7.4645588180056533e-03, + -4.8047811101062585e-03, + -1.2965393029515848e-03, + 2.6871560147420448e-03, + 6.6820046351639441e-03, + 1.0181234375649526e-02, + 1.2693239570160253e-02, + 1.3801987624179201e-02, + 1.3223467985097388e-02, + 1.0851516072436361e-02, + 6.7871600671172939e-03, + 1.3471516713416181e-03, + -4.9505878835131370e-03, + -1.1424457354367572e-02, + -1.7286941430997817e-02, + -2.1717667219693839e-02, + -2.3944885318772084e-02, + -2.3327298483040017e-02, + -1.9427773634064744e-02, + -1.2070977817728557e-02, + -1.3783476176288103e-03, + 1.2224088932697995e-02, + 2.8026875973030725e-02, + 4.5086210529879781e-02, + 6.2297005689373748e-02, + 7.8483480759227175e-02, + 9.2498920279554614e-02, + 1.0332516955488472e-01, + 1.1016231276896073e-01, + 1.1249983417715828e-01, + 1.1016231276896073e-01, + 1.0332516955488472e-01, + 9.2498920279554614e-02, + 7.8483480759227175e-02, + 6.2297005689373748e-02, + 4.5086210529879781e-02, + 2.8026875973030725e-02, + 1.2224088932697995e-02, + -1.3783476176288103e-03, + -1.2070977817728557e-02, + -1.9427773634064744e-02, + -2.3327298483040017e-02, + -2.3944885318772084e-02, + -2.1717667219693839e-02, + -1.7286941430997817e-02, + -1.1424457354367572e-02, + -4.9505878835131370e-03, + 1.3471516713416181e-03, + 6.7871600671172939e-03, + 1.0851516072436361e-02, + 1.3223467985097388e-02, + 1.3801987624179201e-02, + 1.2693239570160253e-02, + 1.0181234375649526e-02, + 6.6820046351639441e-03, + 2.6871560147420448e-03, + -1.2965393029515848e-03, + -4.8047811101062585e-03, + -7.4645588180056533e-03, + -9.0293937429823425e-03, + -9.3980046216532581e-03, + -8.6153887752712620e-03, + -6.8573139102545118e-03, + -4.4010036746948682e-03, + -1.5861842342080313e-03, + 1.2284965848522998e-03, + 3.7084305767259049e-03, + 5.5805141901092261e-03, + 6.6611450884382431e-03, + 6.8720872974490652e-03, + 6.2430865316761243e-03, + 4.9017083490193345e-03, + 3.0523240871465204e-03, + 9.4732248234365949e-04, + -1.1456399724280033e-03, + -2.9762839034441191e-03, + -4.3404156420471995e-03, + -5.1015381946655980e-03, + -5.2032089566911282e-03, + -4.6711950010231082e-03, + -3.6057322199722188e-03, + -2.1653487466505479e-03, + -5.4463482339545078e-04, + 1.0510667184604674e-03, + 2.4308665727133666e-03, + 3.4404291901591858e-03, + 3.9784930418711529e-03, + 4.0061329855621032e-03, + 3.5480424209820595e-03, + 2.6861059111575034e-03, + 1.5464427045193082e-03, + 2.8182334485003753e-04, + -9.4818183004063928e-04, + -1.9968135695645644e-03, + -2.7471446550629990e-03, + -3.1245956658136312e-03, + -3.1036729907111113e-03, + -2.7084197951279900e-03, + -2.0068563535807237e-03, + -1.1003982097410234e-03, + -1.0979661913989589e-04, + 8.4051376002913846e-04, + 1.6376802937135523e-03, + 2.1934814756143528e-03, + 2.4536946598613294e-03, + 2.4028408067177987e-03, + 2.0639753573012624e-03, + 1.4938136285833580e-03, + 7.7403111371563207e-04, + 2.3963058050109641e-18, + -7.3153147820885478e-04, + -1.3342613951700247e-03, + -1.7422461411737932e-03, + -1.9167981482004670e-03, + -1.8496919932683585e-03, + -1.5624882313090410e-03, + -1.1022683933312486e-03, + -5.3449693532160649e-04, + 6.5961926473765504e-05, + 6.2447500597426621e-04, + 1.0757073016218076e-03, + 1.3710495993280668e-03, + 1.4835904370199317e-03, + 1.4101620167436650e-03, + 1.1703740347449958e-03, + 8.0292313245214093e-04, + 3.5978337021319877e-04, + -1.0089121726420446e-04, + -5.2220999932743963e-04, + -8.5540416980910334e-04, + -1.0652942478290191e-03, + -1.1337776756542245e-03, + -1.0610246047329805e-03, + -8.6436953761502133e-04, + -5.7517031065589951e-04, + -2.3413981449502423e-04, + 1.1418616659513179e-04, + 4.2711468634862358e-04, + 6.6889172527351054e-04, + 8.1463768240473190e-04, + 8.5270982647749278e-04, + 7.8529799492923103e-04, + 6.2728929030688677e-04, + 4.0364863528921104e-04, + 1.4572974439620921e-04, + -1.1296281070105764e-04, + -3.4100463005613623e-04, + -5.1275564221873397e-04, + -6.1111540635532446e-04, + -6.2905165508392053e-04, + -5.6979354670108758e-04, + -4.4575310424577365e-04, + -2.7639139349152519e-04, + -8.5362287201251524e-05, + 1.0266593865646372e-04, + 2.6509766030464354e-04, + 3.8403107783086687e-04, + 4.4812190716126901e-04, + 4.5351163678456255e-04, + 4.0377050164848210e-04, + 3.0893092795926857e-04, + 1.8379476725659645e-04, + 4.5774940878568828e-05, + -8.7428442628870192e-05, + -2.0001817924033768e-04, + -2.7989499533718565e-04, + -3.1986419212815800e-04, + -3.1814783282676894e-04, + -2.7819059626861504e-04, + -2.0783625008714723e-04, + -1.1802437982386235e-04, + -2.1205581421381138e-05, + 7.0306561030850995e-05, + 1.4583716256235578e-04, + 1.9753024082828295e-04, + 2.2108605306906141e-04, + 2.1599906163959740e-04, + 1.8530696851413160e-04, + 1.3492164795457078e-04, + 7.2659504969045972e-05, + 7.1169508906801549e-06, + -5.3455792592077604e-05, + -1.0214178590401718e-04, + -1.3409379777089983e-04, + -1.4694941904772830e-04, + -1.4090067591924620e-04, + -1.1843957684450216e-04, + -8.3840063878614675e-05, + -4.2464854212389271e-05, + -2.5686612601772112e-19, + 3.8280007661585741e-05, + 6.8126877953641527e-05, + 8.6746593486943644e-05, + 9.3004391984475904e-05, + 8.7401896874646299e-05, + 7.1851111640564876e-05, + 4.9293574810652612e-05, + 2.3228145759602534e-05, + -2.7835403151365200e-06, + -2.5568781745821922e-05, + -4.2699444939542274e-05, + -5.2715954447661238e-05, + -5.5204626726520245e-05, + -5.0733813933478508e-05, + -4.0672043918457073e-05, + -2.6924243741446360e-05, + -1.1628991651399364e-05, + 3.1397475812872881e-06, + 1.5628215950585078e-05, + 2.4587353504621511e-05, + 2.9370244560222251e-05, + 2.9939841848874766e-05, + 2.6796475992365232e-05, + 2.0844234918745317e-05, + 1.3221251806563059e-05, + 5.1208525240791278e-06, + -2.3714386555459034e-06, + -8.4051647165787538e-06, + -1.2443854319157100e-05, + -1.4291114685124852e-05, + -1.4067223467224462e-05, + -1.2145962120363102e-05, + -9.0657264263295850e-06, + -5.4307575226784832e-06, + -1.8176893918556559e-06, + 1.3001177496299045e-06, + 3.6021627811479419e-06, + 4.9408643426257770e-06, + 5.3334013281351790e-06, + 4.9306016374296919e-06, + 3.9708382327681750e-06 +}; + +// cutoff: 0.04375 * sr +// numTaps: 49 +// ripple: 60 +// phase: minimum +std::vector fir_8_low_minphase = { + 1.4972333662230951e-02, + 2.0408347389030690e-02, + 2.8896117921156622e-02, + 3.8670782204353396e-02, + 4.9154796978336544e-02, + 5.9838606864369759e-02, + 7.0061453190943299e-02, + 7.9232284464463024e-02, + 8.6686416710804806e-02, + 9.1893080540255481e-02, + 9.4375382940993610e-02, + 9.3869583647002028e-02, + 9.0230935829711839e-02, + 8.3595304631422049e-02, + 7.4222440775503440e-02, + 6.2622529052864112e-02, + 4.9411113195344747e-02, + 3.5355074996647931e-02, + 2.1202041581551905e-02, + 7.7713195620686048e-03, + -4.2564656310397101e-03, + -1.4275764273363776e-02, + -2.1886389993093999e-02, + -2.6820584584527539e-02, + -2.9087217810541782e-02, + -2.8817913775292758e-02, + -2.6365608489085545e-02, + -2.2170151973123362e-02, + -1.6813375912102559e-02, + -1.0848308495390672e-02, + -4.8730268681772704e-03, + 6.3611057691807468e-04, + 5.2436938956798018e-03, + 8.6955476503759455e-03, + 1.0827641481444826e-02, + 1.1665151097794594e-02, + 1.1288654765984273e-02, + 9.9434765241279890e-03, + 7.8845028922494946e-03, + 5.4391058570751605e-03, + 2.8836721642183159e-03, + 5.2577303403507835e-04, + -1.4557382263480853e-03, + -2.8968253205693940e-03, + -3.7544117764944760e-03, + -4.0117409145339544e-03, + -3.7756580097916968e-03, + -3.1343133502732641e-03, + -2.2597806752086232e-03 +}; + +// cutoff: 0.04375 * sr +// numTaps: 98 +// ripple: 60 +// phase: linear +std::vector fir_8_low_linear = { + 9.2808465594181614e-05, + 8.7244796533660895e-05, + 5.2597799690312659e-05, + -1.8597078602776281e-05, + -1.3022014347139710e-04, + -2.8083702220097184e-04, + -4.6231245848384240e-04, + -6.5904698744977217e-04, + -8.4808486021882643e-04, + -1.0002722898191827e-03, + -1.0825397533973879e-03, + -1.0612487961927145e-03, + -9.0639535410694965e-04, + -5.9631453951652176e-04, + -1.2240466929737786e-04, + 5.0670040615706220e-04, + 1.2621156486434396e-03, + 2.0934184829339178e-03, + 2.9295604356247614e-03, + 3.6822724848965447e-03, + 4.2520288084196226e-03, + 4.5363633887980908e-03, + 4.4400499704838683e-03, + 3.8863879181294005e-03, + 2.8286157011671391e-03, + 1.2603290823998488e-03, + -7.7626378580604200e-04, + -3.1853482133773229e-03, + -5.8166787543823808e-03, + -8.4695342366732564e-03, + -1.0901671386308546e-02, + -1.2843047675337329e-02, + -1.4013616634014901e-02, + -1.4144057768965469e-02, + -1.2997933864928594e-02, + -1.0393512061545269e-02, + -6.2233742139874053e-03, + -4.6999664901310528e-04, + 6.7842957470155259e-03, + 1.5354212868689631e-02, + 2.4955917943335591e-02, + 3.5219076186040220e-02, + 4.5705988752162523e-02, + 5.5936648323454206e-02, + 6.5418012311827617e-02, + 7.3675379820393155e-02, + 8.0283520242066628e-02, + 8.4895160576045209e-02, + 8.7264603036595181e-02, + 8.7264603036595181e-02, + 8.4895160576045209e-02, + 8.0283520242066628e-02, + 7.3675379820393155e-02, + 6.5418012311827617e-02, + 5.5936648323454206e-02, + 4.5705988752162523e-02, + 3.5219076186040220e-02, + 2.4955917943335591e-02, + 1.5354212868689631e-02, + 6.7842957470155259e-03, + -4.6999664901310528e-04, + -6.2233742139874053e-03, + -1.0393512061545269e-02, + -1.2997933864928594e-02, + -1.4144057768965469e-02, + -1.4013616634014901e-02, + -1.2843047675337329e-02, + -1.0901671386308546e-02, + -8.4695342366732564e-03, + -5.8166787543823808e-03, + -3.1853482133773229e-03, + -7.7626378580604200e-04, + 1.2603290823998488e-03, + 2.8286157011671391e-03, + 3.8863879181294005e-03, + 4.4400499704838683e-03, + 4.5363633887980908e-03, + 4.2520288084196226e-03, + 3.6822724848965447e-03, + 2.9295604356247614e-03, + 2.0934184829339178e-03, + 1.2621156486434396e-03, + 5.0670040615706220e-04, + -1.2240466929737786e-04, + -5.9631453951652176e-04, + -9.0639535410694965e-04, + -1.0612487961927145e-03, + -1.0825397533973879e-03, + -1.0002722898191827e-03, + -8.4808486021882643e-04, + -6.5904698744977217e-04, + -4.6231245848384240e-04, + -2.8083702220097184e-04, + -1.3022014347139710e-04, + -1.8597078602776281e-05, + 5.2597799690312659e-05, + 8.7244796533660895e-05, + 9.2808465594181614e-05 +}; + +// cutoff: 0.028125 * sr +// numTaps: 402 +// ripple: 80 +// phase: minimum +std::vector fir_16_high_minphase = { + 1.9496396889996060e-03, + 2.2929941072578506e-03, + 3.1051533031482294e-03, + 4.1284445901596141e-03, + 5.3447096239652419e-03, + 6.7543357884588227e-03, + 8.3592312193953300e-03, + 1.0159703962870206e-02, + 1.2149063739995148e-02, + 1.4319880600473405e-02, + 1.6659601426165373e-02, + 1.9148779274749211e-02, + 2.1764764004198165e-02, + 2.4481236233006652e-02, + 2.7263601763062903e-02, + 3.0079543882537408e-02, + 3.2884973843070153e-02, + 3.5639755119576164e-02, + 3.8297454782075330e-02, + 4.0812428075436495e-02, + 4.3135862109776192e-02, + 4.5221949605918660e-02, + 4.7024085006233479e-02, + 4.8500504464474424e-02, + 4.9611150791461736e-02, + 5.0320247816290818e-02, + 5.0598771833152340e-02, + 5.0424364570080246e-02, + 4.9780067271139157e-02, + 4.8659276176677556e-02, + 4.7060127564651361e-02, + 4.4993667681501787e-02, + 4.2476764435947466e-02, + 3.9536933141850215e-02, + 3.6207831939622473e-02, + 3.2534085853997766e-02, + 2.8565216782279901e-02, + 2.4359721415030434e-02, + 1.9979561689745559e-02, + 1.5491819114319108e-02, + 1.0966867724549408e-02, + 6.4768367165030111e-03, + 2.0932177095157730e-03, + -2.1121497622534130e-03, + -6.0725859301679237e-03, + -9.7234314721794946e-03, + -1.3008013121566618e-02, + -1.5874631165347493e-02, + -1.8281510104921114e-02, + -2.0193822856441768e-02, + -2.1589785638075218e-02, + -2.2455542885748109e-02, + -2.2789916874183153e-02, + -2.2601071118026755e-02, + -2.1908798725169470e-02, + -2.0743219484602497e-02, + -1.9144771063212777e-02, + -1.7161043653026967e-02, + -1.4848699120222757e-02, + -1.2269194740178339e-02, + -9.4906373943699045e-03, + -6.5829191964238464e-03, + -3.6189557809424002e-03, + -6.6954802023743039e-04, + 2.1938143476300312e-03, + 4.9057008228881299e-03, + 7.4033378406863559e-03, + 9.6320025386679824e-03, + 1.1543417772242496e-02, + 1.3098984640994803e-02, + 1.4268988215072503e-02, + 1.5035027798861102e-02, + 1.5387640326708803e-02, + 1.5329250799656116e-02, + 1.4871552589754786e-02, + 1.4037341982850001e-02, + 1.2857361328397853e-02, + 1.1372141609389468e-02, + 9.6273186318543806e-03, + 7.6766672310449955e-03, + 5.5758053530938411e-03, + 3.3849086969862554e-03, + 1.1639680769787439e-03, + -1.0260369370977405e-03, + -3.1273262943805683e-03, + -5.0847004958731665e-03, + -6.8495425161140397e-03, + -8.3780252933187190e-03, + -9.6344841510052851e-03, + -1.0590441116167181e-02, + -1.1227249167465529e-02, + -1.1534257580396277e-02, + -1.1511715270398135e-02, + -1.1166941960807128e-02, + -1.0518085943303801e-02, + -9.5894207855986100e-03, + -8.4140448908104418e-03, + -7.0299010095017586e-03, + -5.4814356901053962e-03, + -3.8153685665510591e-03, + -2.0821992913920193e-03, + -3.3190049213498976e-04, + 1.3848436628436179e-03, + 3.0201829906695322e-03, + 4.5288748015875849e-03, + 5.8712847633808005e-03, + 7.0118907608999765e-03, + 7.9231055994982164e-03, + 8.5826551974154432e-03, + 8.9778965085102868e-03, + 9.1026109193766275e-03, + 8.9598810948235130e-03, + 8.5588409788164045e-03, + 7.9174609097523631e-03, + 7.0587583483377962e-03, + 6.0131769527488645e-03, + 4.8147036367346564e-03, + 3.5021643497054923e-03, + 2.1161722421120179e-03, + 6.9953461889608100e-04, + -7.0611966525790254e-04, + -2.0589383659047511e-03, + -3.3209105463820822e-03, + -4.4558244005732149e-03, + -5.4334068565406379e-03, + -6.2272704649374054e-03, + -6.8184397471794797e-03, + -7.1927408858735685e-03, + -7.3444897914910620e-03, + -7.2730906991259449e-03, + -6.9859877203787488e-03, + -6.4956512752936913e-03, + -5.8213783336929798e-03, + -4.9867529985117807e-03, + -4.0207368818732546e-03, + -2.9543182298664419e-03, + -1.8222535204480111e-03, + -6.5935723223954916e-04, + 4.9792233223742760e-04, + 1.6154014877892966e-03, + 2.6595735122552058e-03, + 3.6013273502927454e-03, + 4.4133738394782759e-03, + 5.0744920448927752e-03, + 5.5668966297025288e-03, + 5.8797043281147467e-03, + 6.0066199040440908e-03, + 5.9481670037523256e-03, + 5.7093919577793665e-03, + 5.3018912505646432e-03, + 4.7408502130627389e-03, + 4.0471198640450031e-03, + 3.2440991507151585e-03, + 2.3592375829510474e-03, + 1.4206502135210035e-03, + 4.5886064189752012e-04, + -4.9704078988216892e-04, + -1.4169273448661145e-03, + -2.2739923349226572e-03, + -3.0425250888604918e-03, + -3.7013625183957869e-03, + -4.2319137188148379e-03, + -4.6210479049588471e-03, + -4.8590431855510662e-03, + -4.9423475298802323e-03, + -4.8709740889967884e-03, + -4.6507695030673282e-03, + -4.2910522105648790e-03, + -3.8064691441108958e-03, + -3.2140289374575351e-03, + -2.5351198367575762e-03, + -1.7917346308768012e-03, + -1.0090233072642216e-03, + -2.1139651800745855e-04, + 5.7541050109702883e-04, + 1.3277849182099495e-03, + 2.0223443656848957e-03, + 2.6392871531186516e-03, + 3.1603364572384369e-03, + 3.5719063539961910e-03, + 3.8629755923451233e-03, + 4.0275145577967682e-03, + 4.0625484353849590e-03, + 3.9703379287805039e-03, + 3.7557229743489470e-03, + 3.4286754095292356e-03, + 3.0010307595475195e-03, + 2.4890893128204647e-03, + 1.9101236566027571e-03, + 1.2843606368224158e-03, + 6.3164193465658309e-04, + -2.6307622208727291e-05, + -6.6933563649124238e-04, + -1.2768050225840082e-03, + -1.8309382636318623e-03, + -2.3150359986174197e-03, + -2.7159512223539940e-03, + -3.0222900396985304e-03, + -3.2270338417084011e-03, + -3.3251867456670970e-03, + -3.3166349459378772e-03, + -3.2033199266537369e-03, + -2.9918229918515856e-03, + -2.6903940074111347e-03, + -2.3112283285053889e-03, + -1.8672346708212910e-03, + -1.3745787009257805e-03, + -8.4925527748830863e-04, + -3.0925561984175738e-04, + 2.2852860225072160e-04, + 7.4657475750987792e-04, + 1.2293868651056042e-03, + 1.6617686434171742e-03, + 2.0317779816530854e-03, + 2.3284754791173009e-03, + 2.5447476009751733e-03, + 2.6749041680341995e-03, + 2.7173751353729903e-03, + 2.6721610934556917e-03, + 2.5434488859029662e-03, + 2.3364697824466065e-03, + 2.0602969346264358e-03, + 1.7247032423891556e-03, + 1.3424091423529794e-03, + 9.2615895172927574e-04, + 4.9054729598636089e-04, + 4.9309116464183991e-05, + -3.8267063914210100e-04, + -7.9236230889229468e-04, + -1.1665536042738383e-03, + -1.4946890108359118e-03, + -1.7667884374219268e-03, + -1.9761432710043636e-03, + -2.1168566031464584e-03, + -2.1867570452239584e-03, + -2.1845053277964582e-03, + -2.1125692683827448e-03, + -1.9743910836815814e-03, + -1.7766891438240609e-03, + -1.5266843968440909e-03, + -1.2342417504169069e-03, + -9.0914544165974175e-04, + -5.6329901538799574e-04, + -2.0778182405346520e-04, + 1.4519853065353427e-04, + 4.8492979430734173e-04, + 8.0015929298618180e-04, + 1.0819202532231823e-03, + 1.3212157636430144e-03, + 1.5121253210169030e-03, + 1.6490455714079219e-03, + 1.7295526021694021e-03, + 1.7518388663583491e-03, + 1.7172741274491545e-03, + 1.6278091959249742e-03, + 1.4884238369919768e-03, + 1.3043453872676573e-03, + 1.0833294367010101e-03, + 8.3293744196504004e-04, + 5.6252229309410788e-04, + 2.8074556921892552e-04, + -2.3145014654026199e-06, + -2.7804156164102186e-04, + -5.3693790501385826e-04, + -7.7170159339716665e-04, + -9.7470147629459298e-04, + -1.1408144798418685e-03, + -1.2650188016250948e-03, + -1.3450815893206697e-03, + -1.3789096049119189e-03, + -1.3672402633432687e-03, + -1.3110532299575005e-03, + -1.2140019288181003e-03, + -1.0798943266521483e-03, + -9.1467624312044186e-04, + -7.2394213977236132e-04, + -5.1524455084511430e-04, + -2.9530822753914918e-04, + -7.2381414649586948e-05, + 1.4674698325602394e-04, + 3.5440987845426341e-04, + 5.4480836270734921e-04, + 7.1156591245852589e-04, + 8.5056552432118571e-04, + 9.5733617241911299e-04, + 1.0298738553906619e-03, + 1.0661762749292851e-03, + 1.0666731671772932e-03, + 1.0318554425819732e-03, + 9.6446894219968818e-04, + 8.6704678088659899e-04, + 7.4433522760463462e-04, + 6.0054719864312484e-04, + 4.4166940106772320e-04, + 2.7274284036711913e-04, + 1.0024161970846838e-04, + -7.0638903550365750e-05, + -2.3355205390792689e-04, + -3.8401281483278266e-04, + -5.1680710696627697e-04, + -6.2870168230250417e-04, + -7.1602512278171829e-04, + -7.7715320738109216e-04, + -8.1024020903023967e-04, + -8.1563587836070621e-04, + -7.9338831526916691e-04, + -7.4573038719807406e-04, + -6.7450891025076635e-04, + -5.8347787966573175e-04, + -4.7570598338080743e-04, + -3.5594937060085452e-04, + -2.2791999836153351e-04, + -9.6851765033152589e-05, + 3.3429127155130393e-05, + 1.5796726838501236e-04, + 2.7336078188830735e-04, + 3.7544332467574553e-04, + 4.6182734429479151e-04, + 5.2952684328816900e-04, + 5.7747565870206700e-04, + 6.0406664033601869e-04, + 6.0968391213095212e-04, + 5.9430958845757976e-04, + 5.5979443484597397e-04, + 5.0731234501604958e-04, + 4.3985446883332589e-04, + 3.5954297989527996e-04, + 2.7024273084536428e-04, + 1.7468977916235839e-04, + 7.6926315953907543e-05, + -2.0280286194313977e-05, + -1.1302619459467170e-04, + -1.9889229854487921e-04, + -2.7455745557599043e-04, + -3.3842787249802135e-04, + -3.8820070125752265e-04, + -4.2325941176954603e-04, + -4.4233685456236850e-04, + -4.4589489367119766e-04, + -4.3367214905217784e-04, + -4.0730637021278845e-04, + -3.6763936729788309e-04, + -3.1723467344164447e-04, + -2.5761866735738841e-04, + -1.9172063520433064e-04, + -1.2136067484376434e-04, + -4.9764625974440448e-05, + 2.1133772384435045e-05, + 8.8269002916167312e-05, + 1.5003424162293261e-04, + 2.0391927732344681e-04, + 2.4891062153593592e-04, + 2.8320935242100848e-04, + 3.0667182850379108e-04, + 3.1824392929713833e-04, + 3.1856281483111067e-04, + 3.0739003662093767e-04, + 2.8617993951766485e-04, + 2.5548352533300071e-04, + 2.1736923023385886e-04, + 1.7280127527129251e-04, + 1.2422217601928804e-04, + 7.2889018672522851e-05, + 2.1333598428178394e-05, + -2.9154488647396908e-05, + -7.6232770815117069e-05, + -1.1892695794224634e-04, + -1.5529113214100547e-04, + -1.8492632997480442e-04, + -2.0642362940371956e-04, + -2.1994278302421683e-04, + -2.2472235374535008e-04, + -2.2156722226606253e-04, + -2.1028140258702105e-04, + -1.9219906970007088e-04, + -1.6757599626103070e-04, + -1.3822503106060015e-04, + -1.0484164894589609e-04, + -6.9358145261984267e-05, + -3.2508088742459881e-05, + 3.7682231284911502e-06, + 3.8724043162012820e-05, + 7.0429841003524768e-05, + 9.8422348598423809e-05, + 1.2124004274457540e-04, + 1.3889167867069913e-04, + 1.5036796014804990e-04, + 1.5611809938593000e-04, + 1.5549797731150895e-04, + 1.4940465726086041e-04, + 1.3763655040697719e-04, + 1.2149061996134092e-04, + 1.0118462629525292e-04, + 7.8214319598124367e-05, + 5.2937533634380897e-05, + 2.7000838217629200e-05, + 8.3369852590532533e-07, + -2.3930871185306945e-05, + -4.7013348472934724e-05, + -6.7034486821511253e-05, + -8.3930891947562377e-05, + -9.6544417464509782e-05 +}; + +// cutoff: 0.028125 * sr +// numTaps: 804 +// ripple: 80 +// phase: linear +std::vector fir_16_high_linear = { + 2.0448593524251475e-06, + 2.2814837129352344e-06, + 2.4592021640530758e-06, + 2.5615701251905669e-06, + 2.5735779063382329e-06, + 2.4824723094014294e-06, + 2.2785540324870408e-06, + 1.9559144461931424e-06, + 1.5130751648724072e-06, + 9.5349521342800803e-07, + 2.8591353256442564e-07, + -4.7550094802556064e-07, + -1.3112134932730510e-06, + -2.1966165724873288e-06, + -3.1025579114867454e-06, + -3.9961006217458017e-06, + -4.8415027501264580e-06, + -5.6013937510599201e-06, + -6.2381157773600148e-06, + -6.7151887167471117e-06, + -6.9988499680464824e-06, + -7.0596134361718361e-06, + -6.8737874774895210e-06, + -6.4248888471624118e-06, + -5.7048893242793972e-06, + -4.7152337792682985e-06, + -3.4675730745089580e-06, + -1.9841623316357794e-06, + -2.9788463677789838e-07, + 1.5481280332827121e-06, + 3.5012913139677931e-06, + 5.5007820213736303e-06, + 7.4791524523146086e-06, + 9.3643127083812472e-06, + 1.1081832162283956e-05, + 1.2557495839648532e-05, + 1.3720037607930856e-05, + 1.4503960261781407e-05, + 1.4852343443027233e-05, + 1.4719534337841937e-05, + 1.4073613667609428e-05, + 1.2898530936358429e-05, + 1.1195808390863422e-05, + 8.9857227219025398e-06, + 6.3078870680988770e-06, + 3.2211731039406624e-06, + -1.9706652511553799e-07, + -3.8524919862074531e-06, + -7.6359776683441505e-06, + -1.1426486293368867e-05, + -1.5094554204279836e-05, + -1.8506300399446324e-05, + -2.1527847656492401e-05, + -2.4030022528210561e-05, + -2.5893183030854454e-05, + -2.7012009337079675e-05, + -2.7300084468930802e-05, + -2.6694089447667943e-05, + -2.5157441004505104e-05, + -2.2683209993595208e-05, + -1.9296175058655712e-05, + -1.5053888638366139e-05, + -1.0046660569442744e-05, + -4.3963976475755195e-06, + 1.7457253916907992e-06, + 8.2027480261938975e-06, + 1.4776502202044712e-05, + 2.1253187870439957e-05, + 2.7409806478739149e-05, + 3.3021275368266602e-05, + 3.7868012584319150e-05, + 4.1743753836027187e-05, + 4.4463342528813389e-05, + 4.5870221019459712e-05, + 4.5843347370138332e-05, + 4.4303267486262211e-05, + 4.1217087888909199e-05, + 3.6602119439076914e-05, + 3.0527996695509004e-05, + 2.3117120500019392e-05, + 1.4543321756339811e-05, + 5.0287007982021541e-06, + -5.1613424523850064e-06, + -1.5724809070176612e-05, + -2.6331390354200945e-05, + -3.6632141796209158e-05, + -4.6270280162060261e-05, + -5.4892790607863596e-05, + -6.2162487663035203e-05, + -6.7770141071380309e-05, + -7.1446256505991571e-05, + -7.2972093341404327e-05, + -7.2189507854895219e-05, + -6.9009230868040969e-05, + -6.3417223877030798e-05, + -5.5478806601291977e-05, + -4.5340310545686811e-05, + -3.3228086073273726e-05, + -1.9444772617655118e-05, + -4.3628306135770352e-06, + 1.1584573262061898e-05, + 2.7915141882968156e-05, + 4.4111206910801404e-05, + 5.9635307329388339e-05, + 7.3947145142951886e-05, + 8.6521409734815826e-05, + 9.6865910398047654e-05, + 1.0453942134534828e-04, + 1.0916862700301668e-04, + 1.1046355895363467e-04, + 1.0823094024502612e-04, + 1.0238489797893359e-04, + 9.2954570471183562e-05, + 8.0088219458687479e-05, + 6.4053558741821533e-05, + 4.5234125562244746e-05, + 2.4121646606318014e-05, + 1.3044829748798140e-06, + -2.2547626435127793e-05, + -4.6702170398297802e-05, + -7.0385340040376632e-05, + -9.2805777138246594e-05, + -1.1317989979738287e-04, + -1.3075802792822193e-04, + -1.4485047243924706e-04, + -1.5485271927416711e-04, + -1.6026883446734684e-04, + -1.6073224054063945e-04, + -1.5602306814666128e-04, + -1.4608136922756847e-04, + -1.3101558745713828e-04, + -1.1110581574154505e-04, + -8.6801525518092433e-05, + -5.8713624117681186e-05, + -2.7600879427983252e-05, + 5.6490601859328117e-06, + 4.0043634382013096e-05, + 7.4513729751671441e-05, + 1.0794566244652888e-04, + 1.3921586828195644e-04, + 1.6722725938379416e-04, + 1.9094611169424020e-04, + 2.0943828712131918e-04, + 2.2190357108901719e-04, + 2.2770692287127378e-04, + 2.2640549327288990e-04, + 2.1777036153063624e-04, + 2.0180207896818147e-04, + 1.7873927782354761e-04, + 1.4905980536426825e-04, + 1.1347407031437511e-04, + 7.2910534100152985e-05, + 2.8493535985629604e-05, + -1.8486099311561781e-05, + -6.6606968967607247e-05, + -1.1435857201667477e-04, + -1.6018720242129707e-04, + -2.0254490919183532e-04, + -2.3994002881809164e-04, + -2.7098769070468343e-04, + -2.9445864082867397e-04, + -3.0932472599470026e-04, + -3.1479943275445092e-04, + -3.1037198144499346e-04, + -2.9583363523744946e-04, + -2.7129509311377587e-04, + -2.3719408908604725e-04, + -1.9429261087710887e-04, + -1.4366347136090559e-04, + -8.6666305740287539e-05, + -2.4913416179292600e-05, + 3.9773767782013673e-05, + 1.0541651170484826e-04, + 1.6993747232550214e-04, + 2.3122458594640273e-04, + 2.8719824199828714e-04, + 3.3587966381479846e-04, + 3.7545831031486003e-04, + 4.0435607200174010e-04, + 4.2128606599168070e-04, + 4.2530393896642618e-04, + 4.1584976293255885e-04, + 3.9277885299955048e-04, + 3.5638014323390157e-04, + 3.0738111794532421e-04, + 2.4693870140621050e-04, + 1.7661594711657790e-04, + 9.8344824984600930e-05, + 1.4375866834553487e-05, + -7.2784117487994200e-05, + -1.6044461456661934e-04, + -2.4581224701327939e-04, + -3.2607752014576010e-04, + -3.9850485144574132e-04, + -4.6052306945913420e-04, + -5.0981346549712036e-04, + -5.4439246993775699e-04, + -5.6268610830294394e-04, + -5.6359357077537329e-04, + -5.4653749950380761e-04, + -5.1149895490128412e-04, + -4.5903545615386300e-04, + -3.9028099052279720e-04, + -3.0692743645115833e-04, + -2.1118743059680306e-04, + -1.0573931071016062e-04, + 6.3446343160917681e-06, + 1.2168479843577799e-04, + 2.3669343158937839e-04, + 3.4768353101823215e-04, + 4.5098423092594571e-04, + 5.4305916427597155e-04, + 6.2062406925431080e-04, + 6.8075982640013297e-04, + 7.2101714677286785e-04, + 7.3950928919052316e-04, + 7.3498946401449048e-04, + 7.0690997664714296e-04, + 6.5546066639585285e-04, + 5.8158479245183517e-04, + 4.8697119183414888e-04, + 3.7402226469009190e-04, + 2.4579810833879706e-04, + 1.0593789914069862e-04, + -4.1439614131538925e-05, + -1.9185391533214880e-04, + -3.4059557061571019e-04, + -4.8287029121143993e-04, + -6.1394990701075841e-04, + -7.2932560313283183e-04, + -8.2485856595491090e-04, + -8.9692312983970799e-04, + -9.4253761694940521e-04, + -9.5947832121163459e-04, + -9.4637249975269226e-04, + -9.0276679193140473e-04, + -8.2916817358132978e-04, + -7.2705535369536347e-04, + -5.9885940994431925e-04, + -4.4791341198838664e-04, + -2.7837176864636533e-04, + -9.5101025864726725e-05, + 9.6455194643981729e-05, + 2.9043352292640502e-04, + 4.8072602826168759e-04, + 6.6116816611092673e-04, + 8.2573383410370564e-04, + 9.6873150249392724e-04, + 1.0849951830318037e-03, + 1.1700639927543623e-03, + 1.2203442612732304e-03, + 1.2332485209694153e-03, + 1.2073063019364784e-03, + 1.1422424140689266e-03, + 1.0390193178366305e-03, + 8.9984123789469989e-04, + 7.2811882969659478e-04, + 5.2839443455472875e-04, + 3.0622921586499091e-04, + 6.8054719216530579e-05, + -1.7900739821394003e-04, + -4.2735260783253949e-04, + -6.6912186724906429e-04, + -8.9644441193134053e-04, + -1.1016876565290907e-03, + -1.2777064563431534e-03, + -1.4180837892679282e-03, + -1.5173549756447753e-03, + -1.5712078625344293e-03, + -1.5766519567626046e-03, + -1.5321502865455990e-03, + -1.4377087855604578e-03, + -1.2949191995584219e-03, + -1.1069528808266256e-03, + -8.7850432088356397e-04, + -6.1568483284839043e-04, + -3.2586838452009945e-04, + -1.7493151788670608e-05, + 3.0017614058020864e-04, + 6.1731864667995790e-04, + 9.2385294154423360e-04, + 1.2097490228933591e-03, + 1.4653473639491745e-03, + 1.6816751315973312e-03, + 1.8507495060865293e-03, + 1.9658581727908520e-03, + 2.0218075072189717e-03, + 2.0151297354759940e-03, + 1.9442414079061103e-03, + 1.8095468481466746e-03, + 1.6134817986977372e-03, + 1.3604942345157686e-03, + 1.0569612081502431e-03, + 7.1104256793199999e-04, + 3.3247439497329764e-04, + -6.7693026796287117e-05, + -4.7740602315044173e-04, + -8.8395872932796207e-04, + -1.2743747876510514e-03, + -1.6358084286288049e-03, + -1.9559529104454113e-03, + -2.2234437317846787e-03, + -2.4282438503041323e-03, + -2.5619983492091072e-03, + -2.6183466009465661e-03, + -2.5931809714877982e-03, + -2.4848424702094882e-03, + -2.2942454463367621e-03, + -2.0249254194396877e-03, + -1.6830063546605688e-03, + -1.2770860906257211e-03, + -8.1804112986477208e-04, + -3.1875453357312788e-04, + 2.0622685252224377e-04, + 7.4109725429724377e-04, + 1.2692481609197911e-03, + 1.7737632182101145e-03, + 2.2379376394176813e-03, + 2.6458067921058931e-03, + 2.9826679017099216e-03, + 3.2355785664758014e-03, + 3.3938160246578288e-03, + 3.4492818583073950e-03, + 3.3968380489958630e-03, + 3.2345619945953383e-03, + 2.9639102133716829e-03, + 2.5897829489151996e-03, + 2.1204846811479099e-03, + 1.5675785683119529e-03, + 9.4563600724469944e-04, + 2.7188571280761391e-04, + -4.3423011326273867e-04, + -1.1515819248544177e-03, + -1.8579478919700495e-03, + -2.5306620161427771e-03, + -3.1472973744865848e-03, + -3.6863649812029923e-03, + -4.1280077081407756e-03, + -4.4546682411725274e-03, + -4.6517101952107797e-03, + -4.7079722787055746e-03, + -4.6162367813829680e-03, + -4.3735956314303144e-03, + -3.9816997869961523e-03, + -3.4468807313927318e-03, + -2.7801362557929518e-03, + -1.9969764478174820e-03, + -1.1171297581730772e-03, + -1.6411308076762660e-04, + 8.3532616076101068e-04, + 1.8518839929939524e-03, + 2.8544743177553586e-03, + 3.8110848184719141e-03, + 4.6896924980201248e-03, + 5.4592146616349677e-03, + 6.0904694508147218e-03, + 6.5571190184318586e-03, + 6.8365681558626426e-03, + 6.9107916641187751e-03, + 6.7670650057095102e-03, + 6.3985747635966457e-03, + 5.8048881279081531e-03, + 4.9922639690768928e-03, + 3.9737919574406805e-03, + 2.7693505563609212e-03, + 1.4053794359845950e-03, + -8.5533196640784665e-05, + -1.6652428113951340e-03, + -3.2908097717928150e-03, + -4.9154141939305399e-03, + -6.4894045855957514e-03, + -7.9614563497952175e-03, + -9.2798127503034098e-03, + -1.0393578122452106e-02, + -1.1254031058496998e-02, + -1.1815924071941679e-02, + -1.2038735895678358e-02, + -1.1887843117710266e-02, + -1.1335579304115799e-02, + -1.0362152075683986e-02, + -8.9563917419499695e-03, + -7.1163089807522832e-03, + -4.8494435881849965e-03, + -2.1729913993043769e-03, + 8.8629803537573814e-04, + 4.2924546807429093e-03, + 8.0008479501908376e-03, + 1.1958963306492853e-02, + 1.6107379861145951e-02, + 2.0380928014341302e-02, + 2.4710001379038161e-02, + 2.9021993055253981e-02, + 3.3242822880253424e-02, + 3.7298519673337339e-02, + 4.1116820795062278e-02, + 4.4628750600597469e-02, + 4.7770139610673244e-02, + 5.0483047449980896e-02, + 5.2717054784347302e-02, + 5.4430392571180361e-02, + 5.5590880844853814e-02, + 5.6176653889838633e-02, + 5.6176653889838633e-02, + 5.5590880844853814e-02, + 5.4430392571180361e-02, + 5.2717054784347302e-02, + 5.0483047449980896e-02, + 4.7770139610673244e-02, + 4.4628750600597469e-02, + 4.1116820795062278e-02, + 3.7298519673337339e-02, + 3.3242822880253424e-02, + 2.9021993055253981e-02, + 2.4710001379038161e-02, + 2.0380928014341302e-02, + 1.6107379861145951e-02, + 1.1958963306492853e-02, + 8.0008479501908376e-03, + 4.2924546807429093e-03, + 8.8629803537573814e-04, + -2.1729913993043769e-03, + -4.8494435881849965e-03, + -7.1163089807522832e-03, + -8.9563917419499695e-03, + -1.0362152075683986e-02, + -1.1335579304115799e-02, + -1.1887843117710266e-02, + -1.2038735895678358e-02, + -1.1815924071941679e-02, + -1.1254031058496998e-02, + -1.0393578122452106e-02, + -9.2798127503034098e-03, + -7.9614563497952175e-03, + -6.4894045855957514e-03, + -4.9154141939305399e-03, + -3.2908097717928150e-03, + -1.6652428113951340e-03, + -8.5533196640784665e-05, + 1.4053794359845950e-03, + 2.7693505563609212e-03, + 3.9737919574406805e-03, + 4.9922639690768928e-03, + 5.8048881279081531e-03, + 6.3985747635966457e-03, + 6.7670650057095102e-03, + 6.9107916641187751e-03, + 6.8365681558626426e-03, + 6.5571190184318586e-03, + 6.0904694508147218e-03, + 5.4592146616349677e-03, + 4.6896924980201248e-03, + 3.8110848184719141e-03, + 2.8544743177553586e-03, + 1.8518839929939524e-03, + 8.3532616076101068e-04, + -1.6411308076762660e-04, + -1.1171297581730772e-03, + -1.9969764478174820e-03, + -2.7801362557929518e-03, + -3.4468807313927318e-03, + -3.9816997869961523e-03, + -4.3735956314303144e-03, + -4.6162367813829680e-03, + -4.7079722787055746e-03, + -4.6517101952107797e-03, + -4.4546682411725274e-03, + -4.1280077081407756e-03, + -3.6863649812029923e-03, + -3.1472973744865848e-03, + -2.5306620161427771e-03, + -1.8579478919700495e-03, + -1.1515819248544177e-03, + -4.3423011326273867e-04, + 2.7188571280761391e-04, + 9.4563600724469944e-04, + 1.5675785683119529e-03, + 2.1204846811479099e-03, + 2.5897829489151996e-03, + 2.9639102133716829e-03, + 3.2345619945953383e-03, + 3.3968380489958630e-03, + 3.4492818583073950e-03, + 3.3938160246578288e-03, + 3.2355785664758014e-03, + 2.9826679017099216e-03, + 2.6458067921058931e-03, + 2.2379376394176813e-03, + 1.7737632182101145e-03, + 1.2692481609197911e-03, + 7.4109725429724377e-04, + 2.0622685252224377e-04, + -3.1875453357312788e-04, + -8.1804112986477208e-04, + -1.2770860906257211e-03, + -1.6830063546605688e-03, + -2.0249254194396877e-03, + -2.2942454463367621e-03, + -2.4848424702094882e-03, + -2.5931809714877982e-03, + -2.6183466009465661e-03, + -2.5619983492091072e-03, + -2.4282438503041323e-03, + -2.2234437317846787e-03, + -1.9559529104454113e-03, + -1.6358084286288049e-03, + -1.2743747876510514e-03, + -8.8395872932796207e-04, + -4.7740602315044173e-04, + -6.7693026796287117e-05, + 3.3247439497329764e-04, + 7.1104256793199999e-04, + 1.0569612081502431e-03, + 1.3604942345157686e-03, + 1.6134817986977372e-03, + 1.8095468481466746e-03, + 1.9442414079061103e-03, + 2.0151297354759940e-03, + 2.0218075072189717e-03, + 1.9658581727908520e-03, + 1.8507495060865293e-03, + 1.6816751315973312e-03, + 1.4653473639491745e-03, + 1.2097490228933591e-03, + 9.2385294154423360e-04, + 6.1731864667995790e-04, + 3.0017614058020864e-04, + -1.7493151788670608e-05, + -3.2586838452009945e-04, + -6.1568483284839043e-04, + -8.7850432088356397e-04, + -1.1069528808266256e-03, + -1.2949191995584219e-03, + -1.4377087855604578e-03, + -1.5321502865455990e-03, + -1.5766519567626046e-03, + -1.5712078625344293e-03, + -1.5173549756447753e-03, + -1.4180837892679282e-03, + -1.2777064563431534e-03, + -1.1016876565290907e-03, + -8.9644441193134053e-04, + -6.6912186724906429e-04, + -4.2735260783253949e-04, + -1.7900739821394003e-04, + 6.8054719216530579e-05, + 3.0622921586499091e-04, + 5.2839443455472875e-04, + 7.2811882969659478e-04, + 8.9984123789469989e-04, + 1.0390193178366305e-03, + 1.1422424140689266e-03, + 1.2073063019364784e-03, + 1.2332485209694153e-03, + 1.2203442612732304e-03, + 1.1700639927543623e-03, + 1.0849951830318037e-03, + 9.6873150249392724e-04, + 8.2573383410370564e-04, + 6.6116816611092673e-04, + 4.8072602826168759e-04, + 2.9043352292640502e-04, + 9.6455194643981729e-05, + -9.5101025864726725e-05, + -2.7837176864636533e-04, + -4.4791341198838664e-04, + -5.9885940994431925e-04, + -7.2705535369536347e-04, + -8.2916817358132978e-04, + -9.0276679193140473e-04, + -9.4637249975269226e-04, + -9.5947832121163459e-04, + -9.4253761694940521e-04, + -8.9692312983970799e-04, + -8.2485856595491090e-04, + -7.2932560313283183e-04, + -6.1394990701075841e-04, + -4.8287029121143993e-04, + -3.4059557061571019e-04, + -1.9185391533214880e-04, + -4.1439614131538925e-05, + 1.0593789914069862e-04, + 2.4579810833879706e-04, + 3.7402226469009190e-04, + 4.8697119183414888e-04, + 5.8158479245183517e-04, + 6.5546066639585285e-04, + 7.0690997664714296e-04, + 7.3498946401449048e-04, + 7.3950928919052316e-04, + 7.2101714677286785e-04, + 6.8075982640013297e-04, + 6.2062406925431080e-04, + 5.4305916427597155e-04, + 4.5098423092594571e-04, + 3.4768353101823215e-04, + 2.3669343158937839e-04, + 1.2168479843577799e-04, + 6.3446343160917681e-06, + -1.0573931071016062e-04, + -2.1118743059680306e-04, + -3.0692743645115833e-04, + -3.9028099052279720e-04, + -4.5903545615386300e-04, + -5.1149895490128412e-04, + -5.4653749950380761e-04, + -5.6359357077537329e-04, + -5.6268610830294394e-04, + -5.4439246993775699e-04, + -5.0981346549712036e-04, + -4.6052306945913420e-04, + -3.9850485144574132e-04, + -3.2607752014576010e-04, + -2.4581224701327939e-04, + -1.6044461456661934e-04, + -7.2784117487994200e-05, + 1.4375866834553487e-05, + 9.8344824984600930e-05, + 1.7661594711657790e-04, + 2.4693870140621050e-04, + 3.0738111794532421e-04, + 3.5638014323390157e-04, + 3.9277885299955048e-04, + 4.1584976293255885e-04, + 4.2530393896642618e-04, + 4.2128606599168070e-04, + 4.0435607200174010e-04, + 3.7545831031486003e-04, + 3.3587966381479846e-04, + 2.8719824199828714e-04, + 2.3122458594640273e-04, + 1.6993747232550214e-04, + 1.0541651170484826e-04, + 3.9773767782013673e-05, + -2.4913416179292600e-05, + -8.6666305740287539e-05, + -1.4366347136090559e-04, + -1.9429261087710887e-04, + -2.3719408908604725e-04, + -2.7129509311377587e-04, + -2.9583363523744946e-04, + -3.1037198144499346e-04, + -3.1479943275445092e-04, + -3.0932472599470026e-04, + -2.9445864082867397e-04, + -2.7098769070468343e-04, + -2.3994002881809164e-04, + -2.0254490919183532e-04, + -1.6018720242129707e-04, + -1.1435857201667477e-04, + -6.6606968967607247e-05, + -1.8486099311561781e-05, + 2.8493535985629604e-05, + 7.2910534100152985e-05, + 1.1347407031437511e-04, + 1.4905980536426825e-04, + 1.7873927782354761e-04, + 2.0180207896818147e-04, + 2.1777036153063624e-04, + 2.2640549327288990e-04, + 2.2770692287127378e-04, + 2.2190357108901719e-04, + 2.0943828712131918e-04, + 1.9094611169424020e-04, + 1.6722725938379416e-04, + 1.3921586828195644e-04, + 1.0794566244652888e-04, + 7.4513729751671441e-05, + 4.0043634382013096e-05, + 5.6490601859328117e-06, + -2.7600879427983252e-05, + -5.8713624117681186e-05, + -8.6801525518092433e-05, + -1.1110581574154505e-04, + -1.3101558745713828e-04, + -1.4608136922756847e-04, + -1.5602306814666128e-04, + -1.6073224054063945e-04, + -1.6026883446734684e-04, + -1.5485271927416711e-04, + -1.4485047243924706e-04, + -1.3075802792822193e-04, + -1.1317989979738287e-04, + -9.2805777138246594e-05, + -7.0385340040376632e-05, + -4.6702170398297802e-05, + -2.2547626435127793e-05, + 1.3044829748798140e-06, + 2.4121646606318014e-05, + 4.5234125562244746e-05, + 6.4053558741821533e-05, + 8.0088219458687479e-05, + 9.2954570471183562e-05, + 1.0238489797893359e-04, + 1.0823094024502612e-04, + 1.1046355895363467e-04, + 1.0916862700301668e-04, + 1.0453942134534828e-04, + 9.6865910398047654e-05, + 8.6521409734815826e-05, + 7.3947145142951886e-05, + 5.9635307329388339e-05, + 4.4111206910801404e-05, + 2.7915141882968156e-05, + 1.1584573262061898e-05, + -4.3628306135770352e-06, + -1.9444772617655118e-05, + -3.3228086073273726e-05, + -4.5340310545686811e-05, + -5.5478806601291977e-05, + -6.3417223877030798e-05, + -6.9009230868040969e-05, + -7.2189507854895219e-05, + -7.2972093341404327e-05, + -7.1446256505991571e-05, + -6.7770141071380309e-05, + -6.2162487663035203e-05, + -5.4892790607863596e-05, + -4.6270280162060261e-05, + -3.6632141796209158e-05, + -2.6331390354200945e-05, + -1.5724809070176612e-05, + -5.1613424523850064e-06, + 5.0287007982021541e-06, + 1.4543321756339811e-05, + 2.3117120500019392e-05, + 3.0527996695509004e-05, + 3.6602119439076914e-05, + 4.1217087888909199e-05, + 4.4303267486262211e-05, + 4.5843347370138332e-05, + 4.5870221019459712e-05, + 4.4463342528813389e-05, + 4.1743753836027187e-05, + 3.7868012584319150e-05, + 3.3021275368266602e-05, + 2.7409806478739149e-05, + 2.1253187870439957e-05, + 1.4776502202044712e-05, + 8.2027480261938975e-06, + 1.7457253916907992e-06, + -4.3963976475755195e-06, + -1.0046660569442744e-05, + -1.5053888638366139e-05, + -1.9296175058655712e-05, + -2.2683209993595208e-05, + -2.5157441004505104e-05, + -2.6694089447667943e-05, + -2.7300084468930802e-05, + -2.7012009337079675e-05, + -2.5893183030854454e-05, + -2.4030022528210561e-05, + -2.1527847656492401e-05, + -1.8506300399446324e-05, + -1.5094554204279836e-05, + -1.1426486293368867e-05, + -7.6359776683441505e-06, + -3.8524919862074531e-06, + -1.9706652511553799e-07, + 3.2211731039406624e-06, + 6.3078870680988770e-06, + 8.9857227219025398e-06, + 1.1195808390863422e-05, + 1.2898530936358429e-05, + 1.4073613667609428e-05, + 1.4719534337841937e-05, + 1.4852343443027233e-05, + 1.4503960261781407e-05, + 1.3720037607930856e-05, + 1.2557495839648532e-05, + 1.1081832162283956e-05, + 9.3643127083812472e-06, + 7.4791524523146086e-06, + 5.5007820213736303e-06, + 3.5012913139677931e-06, + 1.5481280332827121e-06, + -2.9788463677789838e-07, + -1.9841623316357794e-06, + -3.4675730745089580e-06, + -4.7152337792682985e-06, + -5.7048893242793972e-06, + -6.4248888471624118e-06, + -6.8737874774895210e-06, + -7.0596134361718361e-06, + -6.9988499680464824e-06, + -6.7151887167471117e-06, + -6.2381157773600148e-06, + -5.6013937510599201e-06, + -4.8415027501264580e-06, + -3.9961006217458017e-06, + -3.1025579114867454e-06, + -2.1966165724873288e-06, + -1.3112134932730510e-06, + -4.7550094802556064e-07, + 2.8591353256442564e-07, + 9.5349521342800803e-07, + 1.5130751648724072e-06, + 1.9559144461931424e-06, + 2.2785540324870408e-06, + 2.4824723094014294e-06, + 2.5735779063382329e-06, + 2.5615701251905669e-06, + 2.4592021640530758e-06, + 2.2814837129352344e-06, + 2.0448593524251475e-06 +}; + +// cutoff: 0.021875 * sr +// numTaps: 98 +// ripple: 60 +// phase: minimum +std::vector fir_16_low_minphase = { + 8.5636219964374451e-03, + 8.1838311193531427e-03, + 9.7270794406542956e-03, + 1.1676424721356099e-02, + 1.3848497181183873e-02, + 1.6194564266139487e-02, + 1.8666430805607273e-02, + 2.1243968025130320e-02, + 2.3884901319978946e-02, + 2.6559547580695075e-02, + 2.9226087191469789e-02, + 3.1852840389332990e-02, + 3.4394506223971666e-02, + 3.6813355920749628e-02, + 3.9064695226215036e-02, + 4.1114370019527925e-02, + 4.2922894771096523e-02, + 4.4458461348461993e-02, + 4.5685663548239143e-02, + 4.6579876172586659e-02, + 4.7116969648918615e-02, + 4.7282799735356061e-02, + 4.7062868476397721e-02, + 4.6453001332482514e-02, + 4.5452385929941025e-02, + 4.4071869387674489e-02, + 4.2324261699960307e-02, + 4.0230581616024913e-02, + 3.7813628575245235e-02, + 3.5106196139267881e-02, + 3.2144348031575426e-02, + 2.8971526578880392e-02, + 2.5630537237511380e-02, + 2.2168816768320873e-02, + 1.8633455232218831e-02, + 1.5076021689722234e-02, + 1.1545702554387126e-02, + 8.0922293278927002e-03, + 4.7605007310295286e-03, + 1.5951508157736312e-03, + -1.3641498107298308e-03, + -4.0798743092924153e-03, + -6.5220373893848651e-03, + -8.6649090278308628e-03, + -1.0490593262546751e-02, + -1.1985367801648333e-02, + -1.3143361906778764e-02, + -1.3963327705361569e-02, + -1.4451570011195123e-02, + -1.4618499014773249e-02, + -1.4481569664171294e-02, + -1.4062298090901145e-02, + -1.3388322894417333e-02, + -1.2489366479739484e-02, + -1.1398690025996448e-02, + -1.0150197146788746e-02, + -8.7808070161144343e-03, + -7.3274440942774190e-03, + -5.8278030496305847e-03, + -4.3166653366115615e-03, + -2.8273862240471076e-03, + -1.3900201370477901e-03, + -3.3311284810244704e-05, + 1.2178772699450902e-03, + 2.3418009813401496e-03, + 3.3222749926971338e-03, + 4.1470310377197403e-03, + 4.8090608870810722e-03, + 5.3048106177270467e-03, + 5.6354621830032002e-03, + 5.8051630376269349e-03, + 5.8220380068448631e-03, + 5.6966650327518577e-03, + 5.4432608330343751e-03, + 5.0781623509947070e-03, + 4.6202069461306937e-03, + 4.0885807322124761e-03, + 3.5029995619525280e-03, + 2.8822659999497282e-03, + 2.2450623612050922e-03, + 1.6089138569418196e-03, + 9.9077365971315381e-04, + 4.0583779952200799e-04, + -1.3220693735031737e-04, + -6.1246352821553028e-04, + -1.0266285818238557e-03, + -1.3696565927830522e-03, + -1.6387732815107677e-03, + -1.8333847946472089e-03, + -1.9542720129300281e-03, + -2.0041262515392098e-03, + -1.9874640471446384e-03, + -1.9110092318325525e-03, + -1.7830097823484082e-03, + -1.6128165457348520e-03, + -1.4100495340530637e-03, + -1.1843343650808236e-03, + -9.4494975407220230e-04 +}; + +// cutoff: 0.021875 * sr +// numTaps: 195 +// ripple: 60 +// phase: linear +std::vector fir_16_low_linear = { + 4.6406350512302725e-05, + 4.6554827062602420e-05, + 4.3624389029543715e-05, + 3.7044618200778362e-05, + 2.6300100028348718e-05, + 1.0958820312583623e-05, + -9.2989636518609359e-06, + -3.4652359343132310e-05, + -6.5113043115270046e-05, + -1.0050114198018762e-04, + -1.4042491927489305e-04, + -1.8426537060876191e-04, + -2.3116677834560183e-04, + -2.8003417534844081e-04, + -3.2953853194173148e-04, + -3.7813030543505844e-04, + -4.2406178181615662e-04, + -4.6541839836751497e-04, + -5.0015896924819722e-04, + -5.2616444992933183e-04, + -5.4129457822660516e-04, + -5.4345142784508534e-04, + -5.3064861380453584e-04, + -5.0108460722860339e-04, + -4.5321835929638358e-04, + -3.8584521008158109e-04, + -2.9817087653823875e-04, + -1.8988118331660482e-04, + -6.1205127693790174e-05, + 8.7031138304048973e-05, + 2.5336176503197079e-04, + 4.3565232612359544e-04, + 6.3108662343493887e-04, + 8.3617092095002600e-04, + 1.0467570093525482e-03, + 1.2580850973105821e-03, + 1.4648470648899511e-03, + 1.6612701083396427e-03, + 1.8412202650038201e-03, + 1.9983247450917371e-03, + 2.1261114275366324e-03, + 2.2181633151920170e-03, + 2.2682852057079946e-03, + 2.2706793343151041e-03, + 2.2201262988592210e-03, + 2.1121672005066598e-03, + 1.9432826391518124e-03, + 1.7110640027185389e-03, + 1.4143723942915242e-03, + 1.0534805580650589e-03, + 6.3019329954705071e-04, + 1.4794214952948385e-04, + -3.8814960578747759e-04, + -9.7123491841188112e-04, + -1.5927467903638364e-03, + -2.2424400051362101e-03, + -2.9084721028967836e-03, + -3.5775240775331690e-03, + -4.2349603772314504e-03, + -4.8650268635811534e-03, + -5.4510844488597178e-03, + -5.9758752098080931e-03, + -6.4218168919418428e-03, + -6.7713208941768445e-03, + -7.0071280814699901e-03, + -7.1126561341291264e-03, + -7.0723516253674576e-03, + -6.8720396400502159e-03, + -6.4992635209499810e-03, + -5.9436072643748354e-03, + -5.1969931912348522e-03, + -4.2539477949767946e-03, + -3.1118291127273183e-03, + -1.7710095746438211e-03, + -2.3500904894905683e-04, + 1.4894262974820404e-03, + 3.3923026784192937e-03, + 5.4604171368528584e-03, + 7.6774567887004331e-03, + 1.0024158632651404e-02, + 1.2478528418934461e-02, + 1.5016115797219065e-02, + 1.7610341726319201e-02, + 2.0232872954908707e-02, + 2.2854037301067002e-02, + 2.5443272495368190e-02, + 2.7969600531186505e-02, + 3.0402118807646105e-02, + 3.2710498872326250e-02, + 3.4865483285526050e-02, + 3.6839371044256823e-02, + 3.8606482126164195e-02, + 4.0143592040470771e-02, + 4.1430327799141770e-02, + 4.2449517436447801e-02, + 4.3187486094082572e-02, + 4.3634292732958123e-02, + 4.3783902709019495e-02, + 4.3634292732958123e-02, + 4.3187486094082572e-02, + 4.2449517436447801e-02, + 4.1430327799141770e-02, + 4.0143592040470771e-02, + 3.8606482126164195e-02, + 3.6839371044256823e-02, + 3.4865483285526050e-02, + 3.2710498872326250e-02, + 3.0402118807646105e-02, + 2.7969600531186505e-02, + 2.5443272495368190e-02, + 2.2854037301067002e-02, + 2.0232872954908707e-02, + 1.7610341726319201e-02, + 1.5016115797219065e-02, + 1.2478528418934461e-02, + 1.0024158632651404e-02, + 7.6774567887004331e-03, + 5.4604171368528584e-03, + 3.3923026784192937e-03, + 1.4894262974820404e-03, + -2.3500904894905683e-04, + -1.7710095746438211e-03, + -3.1118291127273183e-03, + -4.2539477949767946e-03, + -5.1969931912348522e-03, + -5.9436072643748354e-03, + -6.4992635209499810e-03, + -6.8720396400502159e-03, + -7.0723516253674576e-03, + -7.1126561341291264e-03, + -7.0071280814699901e-03, + -6.7713208941768445e-03, + -6.4218168919418428e-03, + -5.9758752098080931e-03, + -5.4510844488597178e-03, + -4.8650268635811534e-03, + -4.2349603772314504e-03, + -3.5775240775331690e-03, + -2.9084721028967836e-03, + -2.2424400051362101e-03, + -1.5927467903638364e-03, + -9.7123491841188112e-04, + -3.8814960578747759e-04, + 1.4794214952948385e-04, + 6.3019329954705071e-04, + 1.0534805580650589e-03, + 1.4143723942915242e-03, + 1.7110640027185389e-03, + 1.9432826391518124e-03, + 2.1121672005066598e-03, + 2.2201262988592210e-03, + 2.2706793343151041e-03, + 2.2682852057079946e-03, + 2.2181633151920170e-03, + 2.1261114275366324e-03, + 1.9983247450917371e-03, + 1.8412202650038201e-03, + 1.6612701083396427e-03, + 1.4648470648899511e-03, + 1.2580850973105821e-03, + 1.0467570093525482e-03, + 8.3617092095002600e-04, + 6.3108662343493887e-04, + 4.3565232612359544e-04, + 2.5336176503197079e-04, + 8.7031138304048973e-05, + -6.1205127693790174e-05, + -1.8988118331660482e-04, + -2.9817087653823875e-04, + -3.8584521008158109e-04, + -4.5321835929638358e-04, + -5.0108460722860339e-04, + -5.3064861380453584e-04, + -5.4345142784508534e-04, + -5.4129457822660516e-04, + -5.2616444992933183e-04, + -5.0015896924819722e-04, + -4.6541839836751497e-04, + -4.2406178181615662e-04, + -3.7813030543505844e-04, + -3.2953853194173148e-04, + -2.8003417534844081e-04, + -2.3116677834560183e-04, + -1.8426537060876191e-04, + -1.4042491927489305e-04, + -1.0050114198018762e-04, + -6.5113043115270046e-05, + -3.4652359343132310e-05, + -9.2989636518609359e-06, + 1.0958820312583623e-05, + 2.6300100028348718e-05, + 3.7044618200778362e-05, + 4.3624389029543715e-05, + 4.6554827062602420e-05, + 4.6406350512302725e-05 +}; + diff --git a/libraries/Resample/design_fir.py b/libraries/Resample/design_fir.py new file mode 100644 index 000000000..ceaba58cb --- /dev/null +++ b/libraries/Resample/design_fir.py @@ -0,0 +1,76 @@ +import matplotlib.pyplot as plt +import numpy as np +import scipy.signal as sig +import os + +sr = 1 # samplerate +ripple = {"high": 80, "low": 60} # stopband attenuation and passband ripple +cutoff_ny = {"high": 0.9, "low": 0.7} # cutoff relative to nyquist + +fname = "aa_fir.h" +try: + os.remove(fname) +except FileNotFoundError: + pass +file = open(fname, "a") + +file.write("#include \n\n") + +for down in [2, 4, 8, 16]: + for quality in ripple: + nyquist_resampled = sr/down/2 # new nyquist + cutoff = 0.5 * sr/down * cutoff_ny[quality] # filter cutoff + width = (nyquist_resampled - cutoff)*2 # filter transition bandwidth + + # design kaiser such that stopband starts at nyquist + numtaps, beta = sig.kaiserord(ripple[quality], width/(0.5*sr)) + taps = sig.firwin(numtaps, cutoff, window=('kaiser', beta), fs=sr) + tapsmin = sig.minimum_phase(taps) + + taps = taps/np.sum(taps) + tapsmin = tapsmin/np.sum(tapsmin) + + w, h = sig.freqz(taps, worN=8000) + w, hmin = sig.freqz(taps, worN=8000) + + f = w * 0.5*sr/np.pi # Convert w to Hz. + + plt.figure(1) + plt.plot(f, 20*np.log10(np.abs(h))) + plt.plot(f, 20*np.log10(np.abs(hmin))) + + plt.vlines(cutoff, -129, 0) + plt.vlines(cutoff+width/2, -129, 0) + plt.vlines(cutoff-width/2, -129, 0) + plt.vlines(nyquist_resampled, -129, 0) + + plt.figure(2) + plt.plot(taps) + plt.plot(tapsmin) + + plt.figure(3) + plt.plot(f, 20*np.log10(np.abs(h))) + plt.plot(f, 20*np.log10(np.abs(hmin))) + plt.ylim(-10, 2) + + print("fac", down, "\tQ", quality, "\tcut", cutoff) + file.write(f"// cutoff: {cutoff} * sr\n") + file.write(f"// numTaps: {len(tapsmin)}\n") + file.write(f"// ripple: {ripple[quality]}\n") + file.write(f"// phase: minimum\n") + file.write(f"std::vector fir_{down}_{quality}_minphase = "+"{\n") + for tap in tapsmin[:-1]: + file.write(f"\t{tap:.16e},\n") + file.write(f"\t{tapsmin[-1]:.16e}" + '\n};\n\n') + + file.write(f"// cutoff: {cutoff} * sr\n") + file.write(f"// numTaps: {numtaps}\n") + file.write(f"// ripple: {ripple[quality]}\n") + file.write(f"// phase: linear\n") + file.write(f"std::vector fir_{down}_{quality}_linear = "+"{\n") + for tap in taps[:-1]: + file.write(f"\t{tap:.16e},\n") + file.write(f"\t{taps[-1]:.16e}" + '\n};\n\n') + +file.close() +plt.show() \ No newline at end of file diff --git a/libraries/Resample/lib.metadata b/libraries/Resample/lib.metadata new file mode 100644 index 000000000..8ed4bf5bd --- /dev/null +++ b/libraries/Resample/lib.metadata @@ -0,0 +1,17 @@ +name=Resampling +version=1.0.0 +author=Franz Heuchel +maintainer=Giulio Moro +description=Decimation and interpolation filters. This is a wrapper for the libne10 FIR filter. +examples=Audio/resampling +license=LGPL 3.0 +url= +board=* +dependencies= +LDFLAGS= +LDLIBS= +CXXFLAGS= +CC= +CXX= +CFLAGS= +CPPFLAGS=