#include "rational_resampler.h" #include #include "common/dsp/filter/firdes.h" namespace dsp { template RationalResamplerBlock::RationalResamplerBlock(std::shared_ptr> input, unsigned interpolation, unsigned decimation, std::vector custom_taps) : Block(input), d_interpolation(interpolation), d_decimation(decimation), d_ctr(0) { // Buffer buffer = create_volk_buffer(2 * STREAM_BUFFER_SIZE); set_ratio(interpolation, decimation, custom_taps); } template RationalResamplerBlock::~RationalResamplerBlock() { volk_free(buffer); } template void RationalResamplerBlock::set_ratio(unsigned interpolation, unsigned decimation, std::vector custom_taps) { d_interpolation = interpolation; d_decimation = decimation; // Start by reducing the interp and decim by their GCD int gcd = std::gcd(interpolation, decimation); d_interpolation /= gcd; d_decimation /= gcd; // Generate taps std::vector rtaps = custom_taps.size() > 0 ? custom_taps : firdes::design_resampler_filter_float(d_interpolation, d_decimation, 0.4); // 0.4 = Fractional BW pfb.init(rtaps, d_interpolation); } template int RationalResamplerBlock::process(T *input, int nsamples, T *output) { memcpy(&buffer[pfb.ntaps - 1], input, nsamples * sizeof(T)); outc = 0; while (inc < nsamples) { if constexpr (std::is_same_v) volk_32f_x2_dot_prod_32f(&output[outc++], &buffer[inc], pfb.taps[d_ctr], pfb.ntaps); if constexpr (std::is_same_v) volk_32fc_32f_dot_prod_32fc((lv_32fc_t *)&output[outc++], (lv_32fc_t *)&buffer[inc], pfb.taps[d_ctr], pfb.ntaps); d_ctr += this->d_decimation; inc += d_ctr / d_interpolation; d_ctr = d_ctr % d_interpolation; } inc -= nsamples; memmove(&buffer[0], &buffer[nsamples], pfb.ntaps * sizeof(T)); return outc; } template void RationalResamplerBlock::work() { int nsamples = Block::input_stream->read(); if (nsamples <= 0) { Block::input_stream->flush(); return; } int outn = process(Block::input_stream->readBuf, nsamples, Block::output_stream->writeBuf); Block::input_stream->flush(); Block::output_stream->swap(outn); } template class RationalResamplerBlock; template class RationalResamplerBlock; }