NOTES¶
Resampling — Three Rate Conversion Modes
Downsampling (keep/skip), upsampling (zero-insertion), arbitrary-factor linear interpolation.
Algorithm¶
Downsampling — tiny_downsample_skip_f32¶
\[ y[n] = x[n \cdot M + \text{offset}], \quad n = 0, \dots, \lfloor (L - \text{offset}) / M \rfloor \]
Keep one sample every \(M\). \(\text{offset}\) controls starting phase.
Aliasing risk
Signal bandwidth must be limited to \(f_s / (2M)\) before downsampling, or high frequencies fold into the baseband.
Upsampling — tiny_upsample_zero_f32¶
Insert \(L-1\) zeros between each original sample. Output length: \(L \cdot N\).
Spectral images
Zero-insertion introduces \(L-1\) spectral copies of the original → requires low-pass post-filtering.
Linear Interpolation — tiny_resample_f32¶
\[ y[m] = x[n] + (x[n+1] - x[n]) \cdot \alpha, \quad n = \lfloor m \cdot R \rfloor,\; \alpha = m \cdot R - n \]
\(R = \text{orig_len} / \text{new_len}\). Works for any rational factor.
High-frequency roll-off
Linear interpolation acts as a time-varying low-pass filter. High frequencies are attenuated, especially during upsampling.
API Reference¶
// Downsample: keep 1 sample every M
int tiny_downsample_skip_f32(const float *input, int len,
int M, int offset, float *output);
// Upsample: insert N-1 zeros between samples
int tiny_upsample_zero_f32(const float *input, int len,
int N, float *output);
// Arbitrary-factor linear interpolation resampling
int tiny_resample_f32(const float *input, int orig_len,
int new_len, float *output);