mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2026-04-19 14:52:43 +00:00
bugfix + preparations for stereo FM
This commit is contained in:
@@ -11,6 +11,12 @@ namespace dsp {
|
||||
virtual void createTaps(float* taps, int tapCount, float factor = 1.0f) {}
|
||||
};
|
||||
|
||||
class generic_complex_window {
|
||||
public:
|
||||
virtual int getTapCount() { return -1; }
|
||||
virtual void createTaps(dsp::complex_t* taps, int tapCount, float factor = 1.0f) {}
|
||||
};
|
||||
|
||||
class BlackmanWindow : public filter_window::generic_window {
|
||||
public:
|
||||
BlackmanWindow() {}
|
||||
@@ -76,6 +82,108 @@ namespace dsp {
|
||||
float _cutoff, _transWidth, _sampleRate;
|
||||
|
||||
};
|
||||
|
||||
class BandPassBlackmanWindow : public filter_window::generic_complex_window {
|
||||
public:
|
||||
BandPassBlackmanWindow() {}
|
||||
BandPassBlackmanWindow(float lowCutoff, float highCutoff, float transWidth, float sampleRate) { init(lowCutoff, highCutoff, transWidth, sampleRate); }
|
||||
|
||||
void init(float lowCutoff, float highCutoff, float transWidth, float sampleRate) {
|
||||
assert(lowCutoff <= highCutoff);
|
||||
_lowCutoff = lowCutoff;
|
||||
_highCutoff = highCutoff;
|
||||
_transWidth = transWidth;
|
||||
_sampleRate = sampleRate;
|
||||
|
||||
// Calculate other values
|
||||
_offset = (_lowCutoff + _highCutoff) / 2.0f;
|
||||
_cutoff = fabs((_highCutoff - _lowCutoff) / 2.0f);
|
||||
}
|
||||
|
||||
void setSampleRate(float sampleRate) {
|
||||
_sampleRate = sampleRate;
|
||||
}
|
||||
|
||||
void setCutoffs(float lowCutoff, float highCutoff) {
|
||||
assert(lowCutoff <= highCutoff);
|
||||
_lowCutoff = lowCutoff;
|
||||
_highCutoff = highCutoff;
|
||||
|
||||
// Calculate other values
|
||||
_offset = (_lowCutoff + _highCutoff) / 2.0f;
|
||||
_cutoff = fabs((_highCutoff - _lowCutoff) / 2.0f);
|
||||
}
|
||||
|
||||
void setLowCutoff(float lowCutoff) {
|
||||
assert(lowCutoff <= _highCutoff);
|
||||
_lowCutoff = lowCutoff;
|
||||
|
||||
// Calculate other values
|
||||
_offset = (_lowCutoff + _highCutoff) / 2.0f;
|
||||
_cutoff = fabs((_highCutoff - _lowCutoff) / 2.0f);
|
||||
}
|
||||
|
||||
void setHighCutoff(float highCutoff) {
|
||||
assert(_lowCutoff <= highCutoff);
|
||||
_highCutoff = highCutoff;
|
||||
|
||||
// Calculate other values
|
||||
_offset = (_lowCutoff + _highCutoff) / 2.0f;
|
||||
_cutoff = fabs((_highCutoff - _lowCutoff) / 2.0f);
|
||||
}
|
||||
|
||||
void setTransWidth(float transWidth) {
|
||||
_transWidth = transWidth;
|
||||
}
|
||||
|
||||
int getTapCount() {
|
||||
float fc = _cutoff / _sampleRate;
|
||||
if (fc > 1.0f) {
|
||||
fc = 1.0f;
|
||||
}
|
||||
|
||||
int _M = 4.0f / (_transWidth / _sampleRate);
|
||||
if (_M < 4) {
|
||||
_M = 4;
|
||||
}
|
||||
|
||||
if (_M % 2 == 0) { _M++; }
|
||||
|
||||
return _M;
|
||||
}
|
||||
|
||||
void createTaps(dsp::complex_t* taps, int tapCount, float factor = 1.0f) {
|
||||
// Calculate cuttoff frequency
|
||||
float omega = 2.0f * FL_M_PI * (_cutoff / _sampleRate);
|
||||
if (omega > FL_M_PI) { omega = FL_M_PI; }
|
||||
|
||||
// Generate taps
|
||||
float val;
|
||||
float sum = 0.0f;
|
||||
float tc = tapCount;
|
||||
for (int i = 0; i < tapCount; i++) {
|
||||
val = math::sinc(omega, (float)i - (tc/2), FL_M_PI) * window_function::blackman(i, tc - 1);
|
||||
taps[i].re = val;
|
||||
taps[i].im = 0;
|
||||
sum += val;
|
||||
}
|
||||
|
||||
// Normalize taps and multiply by supplied factor
|
||||
for (int i = 0; i < tapCount; i++) {
|
||||
taps[i] = taps[i] * factor;
|
||||
taps[i] = taps[i] / sum;
|
||||
}
|
||||
|
||||
// Add offset
|
||||
lv_32fc_t phase = lv_cmake(1.0f, 0.0f);
|
||||
lv_32fc_t phaseDelta = lv_cmake(std::cos((-_offset / _sampleRate) * 2.0f * FL_M_PI), std::sin((-_offset / _sampleRate) * 2.0f * FL_M_PI));
|
||||
volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)taps, (lv_32fc_t*)taps, phaseDelta, &phase, tapCount);
|
||||
}
|
||||
|
||||
private:
|
||||
float _lowCutoff, _highCutoff;
|
||||
float _cutoff, _transWidth, _sampleRate, _offset;
|
||||
};
|
||||
}
|
||||
|
||||
class RRCTaps : public filter_window::generic_window {
|
||||
|
||||
Reference in New Issue
Block a user