#pragma once #include #include #include #include #include namespace dsp { template class FrequencyXlator : public generic_block> { public: FrequencyXlator() {} FrequencyXlator(stream* in, float sampleRate, float freq) { init(in, sampleRate, freq); } ~FrequencyXlator() { generic_block>::stop(); } void init(stream* in, float sampleRate, float freq) { _in = in; _sampleRate = sampleRate; _freq = freq; phase = lv_cmake(1.0f, 0.0f); phaseDelta = lv_cmake(std::cos((_freq / _sampleRate) * 2.0f * FL_M_PI), std::sin((_freq / _sampleRate) * 2.0f * FL_M_PI)); generic_block>::registerInput(_in); generic_block>::registerOutput(&out); } void setInputSize(stream* in) { std::lock_guard lck(generic_block>::ctrlMtx); generic_block>::tempStop(); generic_block>::unregisterInput(_in); _in = in; generic_block>::registerInput(_in); generic_block>::tempStart(); } void setSampleRate(float sampleRate) { // No need to restart _sampleRate = sampleRate; phaseDelta = lv_cmake(std::cos((_freq / _sampleRate) * 2.0f * FL_M_PI), std::sin((_freq / _sampleRate) * 2.0f * FL_M_PI)); } float getSampleRate() { return _sampleRate; } void setFrequency(float freq) { // No need to restart _freq = freq; phaseDelta = lv_cmake(std::cos((_freq / _sampleRate) * 2.0f * FL_M_PI), std::sin((_freq / _sampleRate) * 2.0f * FL_M_PI)); } float getFrequency() { return _freq; } int run() { count = _in->read(); if (count < 0) { return -1; } // TODO: Do float xlation if constexpr (std::is_same_v) { spdlog::error("XLATOR NOT IMPLEMENTED FOR FLOAT"); } if constexpr (std::is_same_v) { volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)out.writeBuf, (lv_32fc_t*)_in->readBuf, phaseDelta, &phase, count); } _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; float _sampleRate; float _freq; lv_32fc_t phaseDelta; lv_32fc_t phase; stream* _in; }; class AGC : public generic_block { public: AGC() {} AGC(stream* in, float fallRate, float sampleRate) { init(in, fallRate, sampleRate); } ~AGC() { generic_block::stop(); } void init(stream* in, float fallRate, float sampleRate) { _in = in; _sampleRate = sampleRate; _fallRate = fallRate; _CorrectedFallRate = _fallRate / _sampleRate; generic_block::registerInput(_in); generic_block::registerOutput(&out); } void setInput(stream* in) { std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in); _in = in; generic_block::registerInput(_in); generic_block::tempStart(); } void setSampleRate(float sampleRate) { std::lock_guard lck(generic_block::ctrlMtx); _sampleRate = sampleRate; _CorrectedFallRate = _fallRate / _sampleRate; } void setFallRate(float fallRate) { std::lock_guard lck(generic_block::ctrlMtx); _fallRate = fallRate; _CorrectedFallRate = _fallRate / _sampleRate; } int run() { count = _in->read(); if (count < 0) { return -1; } level = pow(10, ((10.0f * log10f(level)) - (_CorrectedFallRate * count)) / 10.0f); for (int i = 0; i < count; i++) { if (_in->readBuf[i] > level) { level = _in->readBuf[i]; } } volk_32f_s32f_multiply_32f(out.writeBuf, _in->readBuf, 1.0f / level, count); _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; float level = 0.0f; float _fallRate; float _CorrectedFallRate; float _sampleRate; stream* _in; }; class FeedForwardAGC : public generic_block { public: FeedForwardAGC() {} FeedForwardAGC(stream* in) { init(in); } ~FeedForwardAGC() { generic_block::stop(); } void init(stream* in) { _in = in; generic_block::registerInput(_in); generic_block::registerOutput(&out); } void setInput(stream* in) { std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in); _in = in; generic_block::registerInput(_in); generic_block::tempStart(); } int run() { count = _in->read(); if (count < 0) { return -1; } float level = 0; for (int i = 0; i < count; i++) { if (fabs(_in->readBuf[i]) > level) { level = fabs(_in->readBuf[i]); } } volk_32f_s32f_multiply_32f(out.writeBuf, _in->readBuf, 1.0f / level, count); _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; stream* _in; }; template class Volume : public generic_block> { public: Volume() {} Volume(stream* in, float volume) { init(in, volume); } ~Volume() { generic_block>::stop(); } void init(stream* in, float volume) { _in = in; _volume = volume; generic_block>::registerInput(_in); generic_block>::registerOutput(&out); } void setInputSize(stream* in) { std::lock_guard lck(generic_block>::ctrlMtx); generic_block>::tempStop(); generic_block>::unregisterInput(_in); _in = in; generic_block>::registerInput(_in); generic_block>::tempStart(); } void setVolume(float volume) { _volume = volume; level = powf(_volume, 2); } float getVolume() { return _volume; } void setMuted(bool muted) { _muted = muted; } bool getMuted() { return _muted; } int run() { count = _in->read(); if (count < 0) { return -1; } if (_muted) { if constexpr (std::is_same_v) { memset(out.writeBuf, 0, sizeof(stereo_t) * count); } else { memset(out.writeBuf, 0, sizeof(float) * count); } } else { if constexpr (std::is_same_v) { volk_32f_s32f_multiply_32f((float*)out.writeBuf, (float*)_in->readBuf, level, count * 2); } else { volk_32f_s32f_multiply_32f((float*)out.writeBuf, (float*)_in->readBuf, level, count); } } _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; float level = 1.0f; float _volume = 1.0f; bool _muted = false; stream* _in; }; class Squelch : public generic_block { public: Squelch() {} Squelch(stream* in, float level) { init(in, level); } ~Squelch() { generic_block::stop(); delete[] normBuffer; } void init(stream* in, float level) { _in = in; _level = level; normBuffer = new float[STREAM_BUFFER_SIZE]; generic_block::registerInput(_in); generic_block::registerOutput(&out); } void setInput(stream* in) { std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in); _in = in; generic_block::registerInput(_in); generic_block::tempStart(); } void setLevel(float level) { _level = level; } float getLevel() { return _level; } int run() { count = _in->read(); if (count < 0) { return -1; } float sum = 0.0f; volk_32fc_magnitude_32f(normBuffer, (lv_32fc_t*)_in->readBuf, count); volk_32f_accumulator_s32f(&sum, normBuffer, count); sum /= (float)count; if (10.0f * log10f(sum) >= _level) { memcpy(out.writeBuf, _in->readBuf, count * sizeof(complex_t)); } else { memset(out.writeBuf, 0, count * sizeof(complex_t)); } _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; float* normBuffer; float _level = -50.0f; stream* _in; }; template class Packer : public generic_block> { public: Packer() {} Packer(stream* in, int count) { init(in, count); } ~Packer() { generic_block>::stop(); } void init(stream* in, int count) { _in = in; samples = count; generic_block>::registerInput(_in); generic_block>::registerOutput(&out); } void setInput(stream* in) { std::lock_guard lck(generic_block>::ctrlMtx); generic_block>::tempStop(); generic_block>::unregisterInput(_in); _in = in; generic_block>::registerInput(_in); generic_block>::tempStart(); } void setSampleCount(int count) { std::lock_guard lck(generic_block>::ctrlMtx); generic_block>::tempStop(); samples = count; generic_block>::tempStart(); } int run() { count = _in->read(); if (count < 0) { read = 0; return -1; } for (int i = 0; i < count; i++) { out.writeBuf[read++] = _in->readBuf[i]; if (read >= samples) { read = 0; if (!out.swap(samples)) { _in->flush(); read = 0; return -1; } } } _in->flush(); return count; } stream out; private: int count; int samples = 1; int read = 0; stream* _in; }; class Threshold : public generic_block { public: Threshold() {} Threshold(stream* in) { init(in); } ~Threshold() { generic_block::stop(); delete[] normBuffer; } void init(stream* in) { _in = in; normBuffer = new float[STREAM_BUFFER_SIZE]; generic_block::registerInput(_in); generic_block::registerOutput(&out); } void setInput(stream* in) { std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in); _in = in; generic_block::registerInput(_in); generic_block::tempStart(); } void setLevel(float level) { _level = level; } float getLevel() { return _level; } int run() { count = _in->read(); if (count < 0) { return -1; } for (int i = 0; i < count; i++) { out.writeBuf[i] = (_in->readBuf[i] > 0.0f); } _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; float* normBuffer; float _level = -50.0f; stream* _in; }; }