2020-06-22 16:45:57 +02:00
|
|
|
#pragma once
|
|
|
|
#include <dsp/source.h>
|
|
|
|
#include <dsp/math.h>
|
|
|
|
#include <dsp/resampling.h>
|
|
|
|
#include <dsp/filter.h>
|
2020-08-11 18:33:42 +02:00
|
|
|
#include <spdlog/spdlog.h>
|
2020-06-22 16:45:57 +02:00
|
|
|
|
|
|
|
namespace dsp {
|
|
|
|
class VFO {
|
|
|
|
public:
|
|
|
|
VFO() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void init(stream<complex_t>* in, float inputSampleRate, float outputSampleRate, float bandWidth, float offset, int blockSize) {
|
|
|
|
_input = in;
|
|
|
|
_outputSampleRate = outputSampleRate;
|
|
|
|
_inputSampleRate = inputSampleRate;
|
|
|
|
_bandWidth = bandWidth;
|
|
|
|
_blockSize = blockSize;
|
2020-07-19 15:59:44 +02:00
|
|
|
output = &resamp.output;
|
2020-06-22 16:45:57 +02:00
|
|
|
|
|
|
|
lo.init(offset, inputSampleRate, blockSize);
|
|
|
|
mixer.init(in, &lo.output, blockSize);
|
2020-07-19 15:59:44 +02:00
|
|
|
resamp.init(&mixer.output, inputSampleRate, outputSampleRate, blockSize, _bandWidth * 0.8f, _bandWidth);
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void start() {
|
|
|
|
lo.start();
|
|
|
|
mixer.start();
|
2020-07-19 15:59:44 +02:00
|
|
|
resamp.start();
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
2020-07-19 15:59:44 +02:00
|
|
|
void stop(bool resampler = true) {
|
2020-06-22 16:45:57 +02:00
|
|
|
lo.stop();
|
|
|
|
mixer.stop();
|
2020-07-19 15:59:44 +02:00
|
|
|
if (resampler) { resamp.stop(); };
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void setInputSampleRate(float inputSampleRate, int blockSize = -1) {
|
2020-07-19 15:59:44 +02:00
|
|
|
lo.stop();
|
|
|
|
lo.setSampleRate(inputSampleRate);
|
2020-06-22 16:45:57 +02:00
|
|
|
|
|
|
|
_inputSampleRate = inputSampleRate;
|
|
|
|
|
|
|
|
if (blockSize > 0) {
|
|
|
|
_blockSize = blockSize;
|
2020-07-19 15:59:44 +02:00
|
|
|
mixer.stop();
|
2020-06-22 16:45:57 +02:00
|
|
|
lo.setBlockSize(_blockSize);
|
|
|
|
mixer.setBlockSize(_blockSize);
|
|
|
|
mixer.start();
|
|
|
|
}
|
2020-07-19 15:59:44 +02:00
|
|
|
resamp.setInputSampleRate(inputSampleRate, _blockSize, _bandWidth * 0.8f, _bandWidth);
|
|
|
|
lo.start();
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void setOutputSampleRate(float outputSampleRate, float bandWidth = -1) {
|
|
|
|
if (bandWidth > 0) {
|
|
|
|
_bandWidth = bandWidth;
|
|
|
|
}
|
2020-07-19 15:59:44 +02:00
|
|
|
resamp.setOutputSampleRate(outputSampleRate, _bandWidth * 0.8f, _bandWidth);
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void setBandwidth(float bandWidth) {
|
2020-07-19 15:59:44 +02:00
|
|
|
_bandWidth = bandWidth;
|
|
|
|
resamp.setFilterParams(_bandWidth * 0.8f, _bandWidth);
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void setOffset(float offset) {
|
|
|
|
lo.setFrequency(-offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setBlockSize(int blockSize) {
|
2020-07-19 15:59:44 +02:00
|
|
|
stop(false);
|
2020-06-22 16:45:57 +02:00
|
|
|
_blockSize = blockSize;
|
|
|
|
lo.setBlockSize(_blockSize);
|
|
|
|
mixer.setBlockSize(_blockSize);
|
2020-07-19 15:59:44 +02:00
|
|
|
resamp.setBlockSize(_blockSize);
|
2020-06-22 16:45:57 +02:00
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
2020-07-19 15:59:44 +02:00
|
|
|
int getOutputBlockSize() {
|
|
|
|
return resamp.getOutputBlockSize();
|
|
|
|
}
|
|
|
|
|
2020-06-22 16:45:57 +02:00
|
|
|
stream<complex_t>* output;
|
|
|
|
|
|
|
|
private:
|
|
|
|
SineSource lo;
|
|
|
|
Multiplier mixer;
|
2020-07-19 15:59:44 +02:00
|
|
|
FIRResampler resamp;
|
2020-06-22 16:45:57 +02:00
|
|
|
stream<complex_t>* _input;
|
|
|
|
|
|
|
|
float _outputSampleRate;
|
|
|
|
float _inputSampleRate;
|
|
|
|
float _bandWidth;
|
|
|
|
float _blockSize;
|
|
|
|
};
|
|
|
|
};
|