85 lines
2.2 KiB
C++
85 lines
2.2 KiB
C++
/**
|
|
* @file sampling.h
|
|
* @author 9exa
|
|
* @brief Objects that resamples signal frames
|
|
* @version 0.1
|
|
* @date 2023-05-08
|
|
*
|
|
* @copyright Copyright (c) 2023
|
|
*
|
|
*/
|
|
#ifndef MENGA_SAMPLING
|
|
#define MENGA_SAMPLING
|
|
|
|
#include "miniaudio.h"
|
|
#include "mengumath.h"
|
|
#include "common.h"
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
namespace Mengu {
|
|
namespace dsp {
|
|
|
|
// Performs linear resampling without any filtering. Useful for resampling frequency domain directly
|
|
template<class T>
|
|
inline void linear_resample_no_filter(const T *input,
|
|
T *output,
|
|
uint32_t size,
|
|
float shift_factor,
|
|
T interp(T a, T b, float w) = &lerp,
|
|
T def_val = T()) {
|
|
float shift_rep = 1 / shift_factor;
|
|
// interpelate the positiobs in the input
|
|
if (shift_factor > 1.0f) {
|
|
// iterate from the back of the array to make the resample work in-place
|
|
for (uint32_t j = 0; j < size; j++) {
|
|
float inp_index = j * shift_rep;
|
|
uint32_t lower = uint32_t(inp_index);
|
|
float remainder = inp_index - lower;
|
|
|
|
output[j] = interp(input[lower], input[lower + 1], remainder);
|
|
}
|
|
}
|
|
else {
|
|
int j = size - 1;
|
|
int resample_start = (int) (size * shift_factor);
|
|
while (j >= resample_start) {
|
|
output[j] = def_val;
|
|
j -= 1;
|
|
}
|
|
while (j >= 0) {
|
|
int inp_index = j * shift_rep;
|
|
int lower = int(inp_index);
|
|
float remainder = inp_index - lower;
|
|
|
|
output[j] = interp(input[lower], input[lower + 1], remainder);
|
|
j -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Just a wrapper around miniaudios resampler API, which uses linear resampling
|
|
// with a 4th order lowpass filter by default
|
|
class LinearResampler {
|
|
public:
|
|
LinearResampler(uint32_t nchannels, float stretch_factor);
|
|
~LinearResampler();
|
|
|
|
void set_stretch_factor(float stretch_factor);
|
|
|
|
std::vector<Complex> resample(const std::vector<Complex> &samples);
|
|
|
|
private:
|
|
ma_linear_resampler _resampler;
|
|
|
|
float _stretch_factor;
|
|
uint32_t _nchannels;
|
|
|
|
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|