diff options
-rw-r--r-- | src/common/samplerate.c | 50 | ||||
-rw-r--r-- | src/common/samplerate.h | 2 |
2 files changed, 40 insertions, 12 deletions
diff --git a/src/common/samplerate.c b/src/common/samplerate.c index 66b763f..6eb4729 100644 --- a/src/common/samplerate.c +++ b/src/common/samplerate.c @@ -25,8 +25,6 @@ #include "sample.h" #include "samplerate.h" -/* NOTE: This is quick and dirtry. */ - int init_samplerate(samplerate_t *state, double samplerate) { #if 0 @@ -38,8 +36,8 @@ int init_samplerate(samplerate_t *state, double samplerate) memset(state, 0, sizeof(*state)); state->factor = samplerate / 8000.0; - filter_lowpass_init(&state->up.lp, 4000.0, samplerate, 1); - filter_lowpass_init(&state->down.lp, 4000.0, samplerate, 1); + filter_lowpass_init(&state->up.lp, 3300.0, samplerate, 2); + filter_lowpass_init(&state->down.lp, 3300.0, samplerate, 2); return 0; } @@ -48,11 +46,16 @@ int init_samplerate(samplerate_t *state, double samplerate) int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num) { int output_num = 0, i, idx; - double factor = state->factor, in_index; + double factor = state->factor, in_index, diff; + sample_t output[(int)((double)input_num / factor + 0.5) + 10]; /* add some safety */ + sample_t last_sample; /* filter down */ filter_process(&state->down.lp, samples, input_num); + /* get last sample for interpolation */ + last_sample = state->down.last_sample; + /* resample filtered result */ in_index = state->down.in_index; @@ -62,14 +65,22 @@ int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num) /* if index is outside input sample range, we are done */ if (idx >= input_num) break; - /* copy value from input to output */ - samples[i] = samples[idx]; + /* linear interpolation */ + diff = in_index - (double)idx; + if (idx) + output[i] = samples[idx - 1] * (1.0 - diff) + samples[idx] * diff; + else + output[i] = last_sample * (1.0 - diff) + samples[idx] * diff; /* count output number */ output_num++; /* increment input index */ in_index += factor; } + /* store last sample for interpolation */ + if (input_num) + state->down.last_sample = samples[input_num - 1]; + /* remove number of input samples from index */ in_index -= (double)input_num; /* in_index cannot be negative, excpet due to rounding error, so... */ @@ -78,6 +89,10 @@ int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num) state->down.in_index = in_index; + /* copy samples */ + for (i = 0; i < output_num; i++) + *samples++ = output[i]; + return output_num; } @@ -85,9 +100,12 @@ int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num) int samplerate_upsample(samplerate_t *state, sample_t *input, int input_num, sample_t *output) { int output_num = 0, i, idx; - double factor = 1.0 / state->factor, in_index; - sample_t buff[(int)((double)input_num / factor + 0.5) + 10]; /* add some fafety */ - sample_t *samples; + double factor = 1.0 / state->factor, in_index, diff; + sample_t buff[(int)((double)input_num / factor + 0.5) + 10]; /* add some safety */ + sample_t *samples, last_sample; + + /* get last sample for interpolation */ + last_sample = state->up.last_sample; if (input == output) samples = buff; @@ -103,14 +121,22 @@ int samplerate_upsample(samplerate_t *state, sample_t *input, int input_num, sam /* if index is outside input sample range, we are done */ if (idx >= input_num) break; - /* copy value */ - samples[i] = input[idx]; + /* linear interpolation */ + diff = in_index - (double)idx; + if (idx) + samples[i] = input[idx - 1] * (1.0 - diff) + input[idx] * diff; + else + samples[i] = last_sample * (1.0 - diff) + input[idx] * diff; /* count output number */ output_num++; /* increment input index */ in_index += factor; } + /* store last sample for interpolation */ + if (input_num) + state->up.last_sample = input[input_num - 1]; + /* remove number of input samples from index */ in_index -= (double)input_num; /* in_index cannot be negative, excpet due to rounding error, so... */ diff --git a/src/common/samplerate.h b/src/common/samplerate.h index 9efe3b1..5892bd8 100644 --- a/src/common/samplerate.h +++ b/src/common/samplerate.h @@ -4,10 +4,12 @@ typedef struct samplerate { double factor; struct { filter_t lp; + sample_t last_sample; double in_index; } down; struct { filter_t lp; + sample_t last_sample; double in_index; } up; } samplerate_t; |