#pragma once #include namespace dsp { 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; } if (out.aquire() < 0) { return -1; } volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)out.data, (lv_32fc_t*)_in->data, phaseDelta, &phase, count); _in->flush(); out.write(count); return count; } stream out; private: int count; float _sampleRate; float _freq; lv_32fc_t phaseDelta; lv_32fc_t phase; stream* _in; }; }