summaryrefslogtreecommitdiffstats
path: root/src/resample.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/resample.c')
-rw-r--r--src/resample.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/resample.c b/src/resample.c
new file mode 100644
index 0000000..23c63a5
--- /dev/null
+++ b/src/resample.c
@@ -0,0 +1,42 @@
+#include "macro.h"
+#include "resample.h"
+
+static void resample_s16(SpeexResamplerState *speex, unsigned channel, void *dst, size_t dstr, const void *src, size_t sstr, size_t in_bytes, size_t *out_bytes) {
+
+ spx_uint32_t in_samples = in_bytes/sizeof(int16_t), out_samples = *out_bytes/sizeof(int16_t);
+
+ speex_resampler_set_input_stride(speex, sstr/sizeof(int16_t));
+ speex_resampler_set_input_stride(speex, dstr/sizeof(int16_t));
+
+ speex_resampler_process_int(speex, channel, src, &in_samples, dst, &out_samples);
+
+ sa_assert(in_samples == in_bytes/sizeof(int16_t));
+
+ *out_bytes = out_samples * sizeof(int16_t);
+}
+
+static void resample_f32(SpeexResamplerState *speex, unsigned channel, void *dst, size_t dstr, const void *src, size_t sstr, size_t in_bytes, size_t *out_bytes) {
+
+ spx_uint32_t in_samples = in_bytes/sizeof(float), out_samples = *out_bytes/sizeof(float);
+
+ speex_resampler_set_input_stride(speex, sstr/sizeof(float));
+ speex_resampler_set_input_stride(speex, dstr/sizeof(float));
+
+ speex_resampler_process_float(speex, channel, src, &in_samples, dst, &out_samples);
+
+ sa_assert(in_samples == in_bytes/sizeof(float));
+
+ *out_bytes = out_samples * sizeof(float);
+}
+
+sa_resample_func_t sa_get_resample_func(sa_pcm_format_t f) {
+
+ static const sa_resample_func_t funcs[_SA_PCM_FORMAT_MAX] = {
+ [SA_PCM_FORMAT_S16_NE] = resample_s16,
+ [SA_PCM_FORMAT_FLOAT32_NE] = resample_f32
+ };
+
+ sa_assert(f < _SA_PCM_FORMAT_MAX);
+
+ return funcs[f];
+}