summaryrefslogtreecommitdiffstats
path: root/resample.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-05-12 23:38:38 +0000
committerLennart Poettering <lennart@poettering.net>2007-05-12 23:38:38 +0000
commita64e85acf96bc0c55363fe55c9e9116aef2a8584 (patch)
tree69ec57b46bdebe0e7496bf11ea9a54cdf5806904 /resample.c
parent2eb6dec8e9f0114bdbad59cf8f11f197f8fdaaf3 (diff)
resampling works
git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@4 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce
Diffstat (limited to 'resample.c')
-rw-r--r--resample.c172
1 files changed, 25 insertions, 147 deletions
diff --git a/resample.c b/resample.c
index f69e6d6..292f891 100644
--- a/resample.c
+++ b/resample.c
@@ -1,164 +1,42 @@
-#include "sydney.h"
+#include "macro.h"
+#include "resample.h"
-#define MAX_OPERATIONS 10
+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) {
-typedef struct buffer_spec buffer_spec_t;
-
-struct buffer_spec {
- void *data;
- size_t size;
- size_t max_size;
-};
-
-typedef struct operation operation_t;
-
-typedef void (*operation_execute_t)(operation_t *o, buffer_spec_t *source);
-
-struct operation {
- operation_execute_t execute;
-
- struct buffer_spec result;
-
- size_t sample
- unsigned nchannels;
-};
-
-typedef struct pipeline pipeline_t;
-
-struct pipeline {
- operation_t operations[MAX_OPERATIONS];
-};
-
-static int native_pcm_format(pcm_format_t f) {
-
- /* Sample formats we know to handle natively */
-
- return
- f == SA_PCM_FORMAT_S16_NE ||
- f == SA_PCM_FORMAT_S32_NE ||
- f == SA_PCM_FORMAT_FLOAT32_NE;
+ spx_uint32_t in_samples = in_bytes/sizeof(int16_t), out_samples = *out_bytes/sizeof(int16_t);
-}
-
-/* Steps: prefmt -> volume -> remap -> resample -> postfmt */
+ speex_resampler_set_input_stride(speex, sstr/sizeof(int16_t));
+ speex_resampler_set_input_stride(speex, dstr/sizeof(int16_t));
-int build_pipeline_output(
- sa_device_t *dev,
- sa_pipeline_t *pipeline,
- sa_pcm_format format,
- unsigned rate,
- unsigned nchannels,
- const sa_channel_t map[]) {
+ speex_resampler_process_int(speex, channel, src, &in_samples, dst, &out_samples);
- int *channel_map_table;
- unsigned u, t;
- int prefmt_required;
- int sum_required = 0;
- int o = 0;
- pcm_format_t work_format;
- operation_execute_t func;
-
- sa_assert(dev);
- sa_assert(pipeline);
+ sa_assert(in_samples == in_bytes/sizeof(int16_t));
- if (!(channel_map_table = sa_new(int, nchannels * dev->nchannels)))
- return SA_ERROR_OOM;
-
- for (u = 0; u < nchannels; u++) {
- unsigned k = 0;
-
- for (t = 0; t < dev->nchannels; t++) {
+ *out_bytes = out_samples * sizeof(int16_t);
+}
- if (map[u] == map[t])
- channel_map_table[u * dev->nchannels + k++] += 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) {
- if (k > 1)
- sum_required = 1;
-
- channel_map_table[k] = (unsigned) -1;
- }
+ spx_uint32_t in_samples = in_bytes/sizeof(float), out_samples = *out_bytes/sizeof(float);
- prefmt_required =
- sum_required ||
- dev->output_volume != 0 ||
- dev->rate != rate ||
- dev->dsr_enabled;
-
- if (native_pcm_format(dev->pcm_format))
- prefmt_required = 0;
-
- if (prefmt_required) {
-
- switch (dev->pcm_format) {
- case SA_PCM_FORMAT_U8:
- case SA_PCM_FORMAT_ULAW:
- case SA_PCM_FORMAT_ALAW:
- case SA_PCM_FORMAT_S16_LE:
- case SA_PCM_FORMAT_S16_BE:
- work_format = SA_PCM_FORMAT_S16_NE;
- break;
+ speex_resampler_set_input_stride(speex, sstr/sizeof(float));
+ speex_resampler_set_input_stride(speex, dstr/sizeof(float));
- case SA_PCM_FORMAT_S24_LE:
- case SA_PCM_FORMAT_S24_BE:
- case SA_PCM_FORMAT_S32_LE:
- case SA_PCM_FORMAT_S32_BE:
- work_format = SA_PCM_FORMAT_S32_NE;
- break;
+ speex_resampler_process_float(speex, channel, src, &in_samples, dst, &out_samples);
- case SA_PCM_FORMAT_FLOAT32_LE:
- case SA_PCM_FORMAT_FLOAT32_BE:
- work_format = SA_PCM_FORMAT_FLOAT32_NE;
- break;
- }
-
- sa_assert(native_pcm_format(work_format));
+ sa_assert(in_samples == in_bytes/sizeof(float));
- func = get_format_converter(dev->pcm_format, work_format);
- pipeline.operations[o].execute = func;
- pipeline.operations[o].buffer.data = NULL;
- pipeline.operations[o].buffer.stride = dev->nchannels * get_sample_size(dev->work_format);
- pipeline.operations[o].
- o++;
-
- } else
- work_format = dev->pcm_format;
-
- if (dev->output_volume != 0) {
- pipeline.operations[o].execute = get_scaler(work_format);
- pipeline.operations[o].buffer.data = NULL;
- o++;
- }
-
- if (dev->rate != rate || dev->dsr_enabled) {
- pipeline.operations[o].execute = get_resampler(work_format);
- pipeline.operations[o].buffer.data = NULL;
- o++;
- }
-
- if (work_format != pcm_format) {
- pipeline.operations[o].execute = get_format_converter(work_format, pcm_format);
- pipeline.operations[o].buffer.data = NULL;
- o++;
- }
-
- pipeline.operations[o].execute = NULL;
-
-
-
+ *out_bytes = out_samples * sizeof(float);
}
-void execute_pipeline(sa_device_t *dev, pipeline_t *pipeline, const buffer_spec_t *buffer, buffer_spec_t *output) {
- sa_operation_t *o;
-
- sa_assert(dev);
- sa_assert(pipeline);
- sa_assert(buffer);
+resample_func_t get_resample_func(sa_pcm_format_t f) {
+
+ static const resample_func_t funcs[SA_PCM_FORMAT_MAX] = {
+ [SA_PCM_FORMAT_S16_NE] = resample_s16,
+ [SA_PCM_FORMAT_FLOAT32_NE] = resample_f32
+ };
- for (o = pipeline->operations; o->execute; o++) {
- o->execute(o, buffer);
- buffer = &o->buffer;
- }
+ sa_assert(f < SA_PCM_FORMAT_MAX);
- *output = *buffer;
+ return funcs[f];
}