feat: pd_signal: resample, linspace

This commit is contained in:
2026-03-04 16:27:00 +01:00
parent 0fb4c4d6c1
commit fe300dabd3
3 changed files with 51 additions and 3 deletions

View File

@@ -8,11 +8,20 @@
#include <vector>
namespace pd_signal {
/** `num` evenly spaced numbers over interval [start,stop] */
void linspace(std::vector<double>& data, double start, double stop, int num);
/** `num` evenly spaced numbers over interval [start,stop] with endpoint=true or [start,stop) with endpoint=false */
void linspace(std::vector<double>& data, double start, double stop, int num, bool endpoint);
/**
* Evaluate at points x the function given by the samples fp[xp[n]].
* Returned in y.
*/
void interp(std::vector<double>& x, std::vector<double>& xp, std::vector<double>& fp, std::vector<double>& y);
void interp(std::vector<double>& y, std::vector<double>& x, std::vector<double>& xp, std::vector<double>& fp);
/** resample to BEAT_LEN */
void resample(std::vector<double> &out, std::vector<double> x, int beat_len);
}
#endif //PASADASUPERPROJECT_SIGNAL_H

View File

@@ -23,8 +23,28 @@ static int binarySearch(std::vector<double>& data, double x) {
return -(insertion_point) - 1; // no element found directly
}
void linspace(std::vector<double>& data, double start, double stop, int num) {
linspace(data, start, stop, num, true);
}
// `num` evenly spaced numbers over interval [start,stop] with endpoint=true or [start,stop) with endpoint=false
void linspace(std::vector<double>& data, double start, double stop, int num, bool endpoint) {
if(num < 0) throw std::invalid_argument("num must be >= 0");
int end = endpoint ? num : (num-1);
double step = (stop - start) / (double) end;
double d = start;
data.resize(num);
for(int i = 0; i < num; i++) {
data[i] = d;
d += step;
}
}
// Evaluate at points x the function given by the samples fp[xp[n]].
void interp(std::vector<double>& x, std::vector<double>& xp, std::vector<double>& fp, std::vector<double>& y) {
void interp(std::vector<double>& y, std::vector<double>& x, std::vector<double>& xp, std::vector<double>& fp) {
if (xp.size() != fp.size()) throw std::invalid_argument("xp.size() != fp.size()");
size_t N = xp.size();
size_t M = x.size();
@@ -65,4 +85,13 @@ void interp(std::vector<double>& x, std::vector<double>& xp, std::vector<double>
}
}
// resample to BEAT_LEN
void resample(std::vector<double> &out, std::vector<double> x, int beat_len) {
std::vector<double> t;
std::vector<double> i;
linspace(t, 0, (double) x.size(), beat_len, false);
linspace(i, 0, (int) (x.size()-1), (int) x.size(), false);
interp(out, t, i, x);
}
}