#pragma once #include namespace dsp { class SineSource : public generic_block { public: SineSource() {} SineSource(int blockSize, float sampleRate, float freq) { init(blockSize, sampleRate, freq); } ~SineSource() { generic_block::stop(); } void init(int blockSize, float sampleRate, float freq) { _blockSize = blockSize; _sampleRate = sampleRate; _freq = freq; zeroPhase = (lv_32fc_t*)volk_malloc(STREAM_BUFFER_SIZE * sizeof(lv_32fc_t), volk_get_alignment()); for (int i = 0; i < STREAM_BUFFER_SIZE; i++) { zeroPhase[i] = lv_cmake(1.0f, 0.0f); } 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::registerOutput(&out); } void setBlockSize(int blockSize) { std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); _blockSize = blockSize; generic_block::tempStart(); } int getBlockSize() { return _blockSize; } 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() { volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)out.writeBuf, zeroPhase, phaseDelta, &phase, _blockSize); if(!out.swap(_blockSize)) { return -1; } return _blockSize; } stream out; private: int _blockSize; float _sampleRate; float _freq; lv_32fc_t phaseDelta; lv_32fc_t phase; lv_32fc_t* zeroPhase; }; }