sndlock/dsp_lib.h

61 lines
1.4 KiB
C
Raw Normal View History

2024-12-30 23:45:14 +08:00
#pragma once
#include <cstdint>
2024-12-31 16:57:42 +08:00
#include <complex>
static uint32_t frequency_to_ftw(double f) {
return f*(double)UINT32_MAX;
}
2024-12-30 23:45:14 +08:00
class DDS {
private:
uint32_t phase = 0;
public:
uint32_t ftw = 0;
double get() {
phase += ftw; // wraps on overflow
return sin(phase*2.0*M_PI/(double)UINT32_MAX);
}
};
2024-12-31 16:57:42 +08:00
template<typename T, unsigned int order>
2024-12-30 23:45:14 +08:00
class Lowpass {
private:
double k = 0.0;
2024-12-31 16:57:42 +08:00
T s[order] = {};
2024-12-30 23:45:14 +08:00
public:
void set_bandwidth(double f) {
k = 2.0*M_PI*f;
}
T update(T x) {
T a = x;
2024-12-31 16:57:42 +08:00
for(int i=0;i<order;i++) {
2024-12-30 23:45:14 +08:00
s[i] += (a - s[i])*k;
a = s[i];
}
return a;
}
};
2024-12-31 16:57:42 +08:00
template<unsigned int order>
class Lockin {
private:
double scale;
uint32_t phase = 0;
Lowpass<std::complex<double>, order> lpf;
public:
uint32_t ftw = 0;
void set_scale(double s) {
scale = s;
}
void set_bandwidth(double f) {
lpf.set_bandwidth(f);
}
std::complex<double> update(double x) {
std::complex<double> rotated;
rotated = x*std::polar(scale, phase*2.0*M_PI/(double)UINT32_MAX);
phase -= ftw; // wraps on underflow
return lpf.update(rotated);
}
};