SDRPlusPlus/core/src/dsp/vfo.h

112 lines
3.9 KiB
C
Raw Normal View History

2020-06-22 16:45:57 +02:00
#pragma once
2020-09-18 00:23:03 +02:00
#include <dsp/block.h>
2020-11-02 03:57:44 +01:00
#include <dsp/window.h>
#include <dsp/resampling.h>
#include <dsp/processing.h>
#include <algorithm>
2020-06-22 16:45:57 +02:00
namespace dsp {
class VFO {
public:
2020-11-02 03:57:44 +01:00
VFO() {}
2020-06-22 16:45:57 +02:00
2020-11-02 03:57:44 +01:00
~VFO() { stop(); }
VFO(stream<complex_t>* in, float offset, float inSampleRate, float outSampleRate, float bandWidth) {
init(in, offset, inSampleRate, outSampleRate, bandWidth);
};
2020-06-22 16:45:57 +02:00
2020-11-02 03:57:44 +01:00
void init(stream<complex_t>* in, float offset, float inSampleRate, float outSampleRate, float bandWidth) {
_in = in;
_offset = offset;
_inSampleRate = inSampleRate;
_outSampleRate = outSampleRate;
2020-06-22 16:45:57 +02:00
_bandWidth = bandWidth;
2020-11-02 03:57:44 +01:00
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
xlator.init(_in, _inSampleRate, -_offset);
win.init(realCutoff, realCutoff, inSampleRate);
resamp.init(&xlator.out, &win, _inSampleRate, _outSampleRate);
win.setSampleRate(_inSampleRate * resamp.getInterpolation());
resamp.updateWindow(&win);
out = &resamp.out;
2020-06-22 16:45:57 +02:00
}
void start() {
2020-11-02 03:57:44 +01:00
if (running) { return; }
xlator.start();
2020-07-19 15:59:44 +02:00
resamp.start();
2020-06-22 16:45:57 +02:00
}
2020-11-02 03:57:44 +01:00
void stop() {
if (!running) { return; }
xlator.stop();
resamp.stop();
2020-06-22 16:45:57 +02:00
}
2020-11-02 03:57:44 +01:00
void setInSampleRate(float inSampleRate) {
_inSampleRate = inSampleRate;
if (running) { xlator.stop(); resamp.stop(); }
xlator.setSampleRate(_inSampleRate);
resamp.setInSampleRate(_inSampleRate);
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
win.setSampleRate(_inSampleRate * resamp.getInterpolation());
win.setCutoff(realCutoff);
win.setTransWidth(realCutoff);
resamp.updateWindow(&win);
if (running) { xlator.start(); resamp.start(); }
2020-06-22 16:45:57 +02:00
}
2020-11-02 03:57:44 +01:00
void setOutSampleRate(float outSampleRate) {
_outSampleRate = outSampleRate;
if (running) { resamp.stop(); }
resamp.setOutSampleRate(_outSampleRate);
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
win.setSampleRate(_inSampleRate * resamp.getInterpolation());
win.setCutoff(realCutoff);
win.setTransWidth(realCutoff);
resamp.updateWindow(&win);
if (running) { resamp.start(); }
2020-06-22 16:45:57 +02:00
}
2020-11-02 03:57:44 +01:00
void setOutSampleRate(float outSampleRate, float bandWidth) {
_outSampleRate = outSampleRate;
2020-07-19 15:59:44 +02:00
_bandWidth = bandWidth;
2020-11-02 03:57:44 +01:00
if (running) { resamp.stop(); }
resamp.setOutSampleRate(_outSampleRate);
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
win.setSampleRate(_inSampleRate * resamp.getInterpolation());
win.setCutoff(realCutoff);
win.setTransWidth(realCutoff);
resamp.updateWindow(&win);
if (running) { resamp.start(); }
2020-06-22 16:45:57 +02:00
}
void setOffset(float offset) {
2020-11-02 03:57:44 +01:00
_offset = offset;
xlator.setFrequency(-_offset);
2020-06-22 16:45:57 +02:00
}
2020-11-02 03:57:44 +01:00
void setBandwidth(float bandWidth) {
_bandWidth = bandWidth;
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
win.setCutoff(realCutoff);
win.setTransWidth(realCutoff);
resamp.updateWindow(&win);
2020-07-19 15:59:44 +02:00
}
2020-11-02 03:57:44 +01:00
stream<complex_t>* out;
2020-06-22 16:45:57 +02:00
private:
2020-11-02 03:57:44 +01:00
bool running = false;
float _offset, _inSampleRate, _outSampleRate, _bandWidth;
filter_window::BlackmanWindow win;
stream<complex_t>* _in;
2020-12-06 16:13:47 +01:00
FrequencyXlator<complex_t> xlator;
2020-11-02 03:57:44 +01:00
PolyphaseResampler<complex_t> resamp;
2020-06-22 16:45:57 +02:00
};
2020-11-02 03:57:44 +01:00
}