mirror of
https://github.com/aicodix/dsp.git
synced 2026-04-27 22:35:45 +00:00
added an resampler for arbitrary rate differences
This commit is contained in:
parent
6780bd4dc1
commit
4ff2e0f148
2 changed files with 65 additions and 0 deletions
|
|
@ -76,3 +76,8 @@ Sometimes we need a sequence of ["random enough"](https://en.wikipedia.org/wiki/
|
|||
Here a [Pseudorandom number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) can help by prodiving a deterministic and thus repeatable sequence of numbers.
|
||||
[George Marsaglia](https://en.wikipedia.org/wiki/George_Marsaglia) discovered a class of simple and fast pseudorandom number generators, which he called [Xorshift](https://en.wikipedia.org/wiki/Xorshift).
|
||||
|
||||
### [resampler.hh](resampler.hh)
|
||||
|
||||
When working with [Analog-to-digital](https://en.wikipedia.org/wiki/Analog-to-digital_converter) and [Digital-to-analog](https://en.wikipedia.org/wiki/Digital-to-analog_converter) converters, we often face the ugly truth, that we can't always have a precise [Sampling](https://en.wikipedia.org/wiki/Sampling_(signal_processing)) rate.
|
||||
But if we can estimate the Sampling frequency offset, we can correct it by [Resampling](https://en.wikipedia.org/wiki/Sample-rate_conversion) the sampled data.
|
||||
|
||||
|
|
|
|||
60
resampler.hh
Normal file
60
resampler.hh
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Resampling by an arbitrary rate difference
|
||||
|
||||
Copyright 2018 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef RESAMPLER_HH
|
||||
#define RESAMPLER_HH
|
||||
|
||||
#include "window.hh"
|
||||
#include "spline.hh"
|
||||
#include "const.hh"
|
||||
|
||||
namespace DSP {
|
||||
|
||||
template <typename TYPE, int RATE, int TAPS, int OVER>
|
||||
class Resampler
|
||||
{
|
||||
typedef DSP::UniformNaturalCubicSpline<TAPS * OVER, TYPE, TYPE> spline_type;
|
||||
spline_type lpf;
|
||||
|
||||
static TYPE sinc(TYPE x)
|
||||
{
|
||||
return TYPE(0) == x ? TYPE(1) : std::sin(DSP::Const<TYPE>::Pi() * x) / (DSP::Const<TYPE>::Pi() * x);
|
||||
}
|
||||
public:
|
||||
Resampler(TYPE cutoff, TYPE alpha)
|
||||
{
|
||||
TYPE tmp[TAPS * OVER];
|
||||
DSP::Kaiser<TYPE> window(alpha);
|
||||
for (int n = 0; n < TAPS * OVER; ++n) {
|
||||
TYPE x = TYPE(n) / TYPE(OVER) - TYPE(TAPS - 1) / TYPE(2);
|
||||
TYPE y = TYPE(2) * cutoff / TYPE(RATE) * sinc(TYPE(2) * cutoff / TYPE(RATE) * x);
|
||||
tmp[n] = y * window(n, TAPS * OVER);
|
||||
}
|
||||
lpf = spline_type(tmp, 0, 1.0 / OVER);
|
||||
}
|
||||
template <typename IO>
|
||||
void operator ()(IO *output, IO *input, TYPE diff, int samples, int stride = 1)
|
||||
{
|
||||
TYPE ratio = (RATE + diff) / RATE;
|
||||
TYPE recip = RATE / (RATE + diff);
|
||||
for (int i = 0; i < samples - TAPS; ++i) {
|
||||
IO sum = 0;
|
||||
int s0 = nearbyint(i * ratio);
|
||||
int s1 = s0 + TAPS;
|
||||
for (int s = s0; s < s1; ++s) {
|
||||
TYPE k = s * recip - i;
|
||||
sum += lpf(k) * input[s * stride];
|
||||
}
|
||||
output[(i + (TAPS - 1) / 2) * stride] = sum;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue