mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-07-01 06:37:51 +02:00
Fixed resampling bug + added waterfall colormap selection + general bugfix
This commit is contained in:
@ -132,4 +132,54 @@ namespace dsp {
|
||||
stream<complex_t>* _in;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class RealToComplex : public generic_block<RealToComplex> {
|
||||
public:
|
||||
RealToComplex() {}
|
||||
|
||||
RealToComplex(stream<float>* in) { init(in); }
|
||||
|
||||
~RealToComplex() {
|
||||
delete[] nullBuffer;
|
||||
generic_block<RealToComplex>::stop();
|
||||
}
|
||||
|
||||
void init(stream<float>* in) {
|
||||
_in = in;
|
||||
nullBuffer = new float[STREAM_BUFFER_SIZE];
|
||||
memset(nullBuffer, 0, STREAM_BUFFER_SIZE * sizeof(float));
|
||||
generic_block<RealToComplex>::registerInput(_in);
|
||||
generic_block<RealToComplex>::registerOutput(&out);
|
||||
}
|
||||
|
||||
void setInput(stream<float>* in) {
|
||||
std::lock_guard<std::mutex> lck(generic_block<RealToComplex>::ctrlMtx);
|
||||
generic_block<RealToComplex>::tempStop();
|
||||
generic_block<RealToComplex>::unregisterInput(_in);
|
||||
_in = in;
|
||||
generic_block<RealToComplex>::registerInput(_in);
|
||||
generic_block<RealToComplex>::tempStart();
|
||||
}
|
||||
|
||||
int run() {
|
||||
count = _in->read();
|
||||
if (count < 0) { return -1; }
|
||||
|
||||
volk_32f_x2_interleave_32fc((lv_32fc_t*)out.writeBuf, _in->readBuf, nullBuffer, count);
|
||||
|
||||
_in->flush();
|
||||
if (!out.swap(count)) { return -1; }
|
||||
return count;
|
||||
}
|
||||
|
||||
stream<complex_t> out;
|
||||
|
||||
private:
|
||||
float avg;
|
||||
int count;
|
||||
float* nullBuffer;
|
||||
stream<float>* _in;
|
||||
|
||||
};
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include <dsp/block.h>
|
||||
#include <fftw3.h>
|
||||
#include <volk/volk.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <string.h>
|
||||
@ -89,13 +88,15 @@ namespace dsp {
|
||||
public:
|
||||
AGC() {}
|
||||
|
||||
AGC(stream<float>* in, float ratio) { init(in, ratio); }
|
||||
AGC(stream<float>* in, float fallRate, float sampleRate) { init(in, fallRate, sampleRate); }
|
||||
|
||||
~AGC() { generic_block<AGC>::stop(); }
|
||||
|
||||
void init(stream<float>* in, float ratio) {
|
||||
void init(stream<float>* in, float fallRate, float sampleRate) {
|
||||
_in = in;
|
||||
_ratio = ratio;
|
||||
_sampleRate = sampleRate;
|
||||
_fallRate = fallRate;
|
||||
_CorrectedFallRate = _fallRate / _sampleRate;
|
||||
generic_block<AGC>::registerInput(_in);
|
||||
generic_block<AGC>::registerOutput(&out);
|
||||
}
|
||||
@ -109,15 +110,30 @@ namespace dsp {
|
||||
generic_block<AGC>::tempStart();
|
||||
}
|
||||
|
||||
void setSampleRate(float sampleRate) {
|
||||
std::lock_guard<std::mutex> lck(generic_block<AGC>::ctrlMtx);
|
||||
_sampleRate = sampleRate;
|
||||
_CorrectedFallRate = _fallRate / _sampleRate;
|
||||
}
|
||||
|
||||
void setFallRate(float fallRate) {
|
||||
std::lock_guard<std::mutex> lck(generic_block<AGC>::ctrlMtx);
|
||||
_fallRate = fallRate;
|
||||
_CorrectedFallRate = _fallRate / _sampleRate;
|
||||
}
|
||||
|
||||
int run() {
|
||||
count = _in->read();
|
||||
if (count < 0) { return -1; }
|
||||
|
||||
level = pow(10, ((10.0f * log10f(level)) - (_CorrectedFallRate * count)) / 10.0f);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
level = (fabsf(_in->readBuf[i]) * _ratio) + (level * (1.0f - _ratio));
|
||||
out.writeBuf[i] = _in->readBuf[i] / level;
|
||||
if (_in->readBuf[i] > level) { level = _in->readBuf[i]; }
|
||||
}
|
||||
|
||||
volk_32f_s32f_multiply_32f(out.writeBuf, _in->readBuf, 1.0f / level, count);
|
||||
|
||||
_in->flush();
|
||||
if (!out.swap(count)) { return -1; }
|
||||
return count;
|
||||
@ -127,8 +143,10 @@ namespace dsp {
|
||||
|
||||
private:
|
||||
int count;
|
||||
float level = 1.0f;
|
||||
float _ratio;
|
||||
float level = 0.0f;
|
||||
float _fallRate;
|
||||
float _CorrectedFallRate;
|
||||
float _sampleRate;
|
||||
stream<float>* _in;
|
||||
|
||||
};
|
||||
|
@ -109,6 +109,7 @@ namespace dsp {
|
||||
|
||||
// Write to output
|
||||
int outIndex = 0;
|
||||
int _interp_m_1 = _interp - 1;
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
for (int i = 0; outIndex < outCount; i += _decim) {
|
||||
int phase = i % _interp;
|
||||
@ -155,10 +156,10 @@ namespace dsp {
|
||||
for(int tap = 0; tap < tapsPerPhase; tap++) {
|
||||
for (int phase = 0; phase < phases; phase++) {
|
||||
if(currentTap < tapCount) {
|
||||
tapPhases[phase][tap] = taps[currentTap++];
|
||||
tapPhases[(_interp - 1) - phase][tap] = taps[currentTap++];
|
||||
}
|
||||
else{
|
||||
tapPhases[phase][tap] = 0;
|
||||
tapPhases[(_interp - 1) - phase][tap] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,4 +188,80 @@ namespace dsp {
|
||||
std::vector<float*> tapPhases;
|
||||
|
||||
};
|
||||
|
||||
class PowerDecimator : public generic_block<PowerDecimator> {
|
||||
public:
|
||||
PowerDecimator() {}
|
||||
|
||||
PowerDecimator(stream<complex_t>* in, unsigned int power) { init(in, power); }
|
||||
|
||||
~PowerDecimator() {
|
||||
generic_block<PowerDecimator>::stop();
|
||||
}
|
||||
|
||||
void init(stream<complex_t>* in, unsigned int power) {
|
||||
_in = in;
|
||||
_power = power;
|
||||
generic_block<PowerDecimator>::registerInput(_in);
|
||||
generic_block<PowerDecimator>::registerOutput(&out);
|
||||
}
|
||||
|
||||
void setInput(stream<complex_t>* in) {
|
||||
std::lock_guard<std::mutex> lck(generic_block<PowerDecimator>::ctrlMtx);
|
||||
generic_block<PowerDecimator>::tempStop();
|
||||
generic_block<PowerDecimator>::unregisterInput(_in);
|
||||
_in = in;
|
||||
generic_block<PowerDecimator>::registerInput(_in);
|
||||
generic_block<PowerDecimator>::tempStart();
|
||||
}
|
||||
|
||||
void setPower(unsigned int power) {
|
||||
std::lock_guard<std::mutex> lck(generic_block<PowerDecimator>::ctrlMtx);
|
||||
generic_block<PowerDecimator>::tempStop();
|
||||
generic_block<PowerDecimator>::unregisterInput(_in);
|
||||
_power = power;
|
||||
generic_block<PowerDecimator>::registerInput(_in);
|
||||
generic_block<PowerDecimator>::tempStart();
|
||||
}
|
||||
|
||||
int run() {
|
||||
count = _in->read();
|
||||
if (count < 0) { return -1; }
|
||||
|
||||
if (_power == 0) {
|
||||
memcpy(out.writeBuf, _in->readBuf, count * sizeof(complex_t));
|
||||
}
|
||||
else if (_power == 1) {
|
||||
for (int j = 0; j < count; j += 2) {
|
||||
out.writeBuf[j / 2].i = (_in->readBuf[j].i + _in->readBuf[j + 1].i) * 0.5f;
|
||||
out.writeBuf[j / 2].q = (_in->readBuf[j].q + _in->readBuf[j + 1].q) * 0.5f;
|
||||
}
|
||||
count /= 2;
|
||||
}
|
||||
|
||||
_in->flush();
|
||||
|
||||
if (_power > 1) {
|
||||
for (int i = 1; i < _power; i++) {
|
||||
for (int j = 0; j < count; j += 2) {
|
||||
out.writeBuf[j / 2].i = (_in->readBuf[j].i + _in->readBuf[j + 1].i) * 0.5f;
|
||||
out.writeBuf[j / 2].q = (_in->readBuf[j].q + _in->readBuf[j + 1].q) * 0.5f;
|
||||
}
|
||||
count /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!out.swap(count)) { return -1; }
|
||||
return count;
|
||||
}
|
||||
|
||||
stream<complex_t> out;
|
||||
|
||||
|
||||
private:
|
||||
int count;
|
||||
unsigned int _power = 0;
|
||||
stream<complex_t>* _in;
|
||||
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user