|
|
|
@ -21,21 +21,21 @@ |
|
|
|
|
#include <stdint.h> |
|
|
|
|
#include <errno.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include "samplerate.h" |
|
|
|
|
|
|
|
|
|
/* generally use filter, but disable for test using quick and dirty replacement */ |
|
|
|
|
#define USE_FILTER |
|
|
|
|
|
|
|
|
|
/* NOTE: This is quick and dirtry. */ |
|
|
|
|
|
|
|
|
|
int init_samplerate(samplerate_t *state, int samplerate) |
|
|
|
|
int init_samplerate(samplerate_t *state, double samplerate) |
|
|
|
|
{ |
|
|
|
|
#if 0 |
|
|
|
|
if ((samplerate % 8000)) { |
|
|
|
|
fprintf(stderr, "Sample rate must be a muliple of 8000 to support MNCC socket interface, aborting!\n"); |
|
|
|
|
return -EINVAL; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
memset(state, 0, sizeof(*state)); |
|
|
|
|
state->factor = samplerate / 8000; |
|
|
|
|
state->factor = samplerate / 8000.0; |
|
|
|
|
|
|
|
|
|
biquad_init(&state->up.bq, 4000.0, samplerate); |
|
|
|
|
biquad_init(&state->down.bq, 4000.0, samplerate); |
|
|
|
@ -46,10 +46,9 @@ int init_samplerate(samplerate_t *state, int samplerate) |
|
|
|
|
/* convert input sample rate to 8000 Hz */ |
|
|
|
|
int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output) |
|
|
|
|
{ |
|
|
|
|
#ifdef USE_FILTER |
|
|
|
|
int output_num, i, j; |
|
|
|
|
int factor = state->factor; |
|
|
|
|
double spl[input_num]; |
|
|
|
|
int output_num, i; |
|
|
|
|
double factor = state->factor, step; |
|
|
|
|
double spl[input_num + 10]; /* add some safety */ |
|
|
|
|
int32_t value; |
|
|
|
|
|
|
|
|
|
/* convert samples to double */ |
|
|
|
@ -58,62 +57,42 @@ int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, in |
|
|
|
|
|
|
|
|
|
/* filter down */ |
|
|
|
|
biquad_process(&state->down.bq, spl, input_num, 1); |
|
|
|
|
output_num = input_num / factor; |
|
|
|
|
output_num = (int)((double)input_num / factor); |
|
|
|
|
|
|
|
|
|
/* resample filtered result */ |
|
|
|
|
for (i = 0, j = 0; i < output_num; i++, j += factor) { |
|
|
|
|
value = spl[j] * 32768.0; |
|
|
|
|
for (i = 0, step = 0.5 / (double)output_num; i < output_num; i++, step += factor) { |
|
|
|
|
value = spl[(int)step] * 32768.0; |
|
|
|
|
if (value < -32768) |
|
|
|
|
value = -32768; |
|
|
|
|
else if (value > 32767) |
|
|
|
|
value = 32767; |
|
|
|
|
*output++ = value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return output_num; |
|
|
|
|
#else |
|
|
|
|
int output_num = 0, i; |
|
|
|
|
double sum; |
|
|
|
|
int factor, sum_count; |
|
|
|
|
|
|
|
|
|
//memcpy(output, input, input_num*2);
|
|
|
|
|
//return input_num;
|
|
|
|
|
sum = state->down.sum; |
|
|
|
|
sum_count = state->down.sum_count; |
|
|
|
|
factor = state->factor; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < input_num; i++) { |
|
|
|
|
sum += *input++; |
|
|
|
|
sum_count++; |
|
|
|
|
if (sum_count == factor) { |
|
|
|
|
*output++ = sum / (double)sum_count; |
|
|
|
|
output_num++; |
|
|
|
|
sum = 0; |
|
|
|
|
sum_count = 0; |
|
|
|
|
} |
|
|
|
|
if ((int)(step - factor) >= input_num) { |
|
|
|
|
fprintf(stderr, "Error: input_num is %d, so step should be close to 0.5 below that, but it is %.4f. Please fix!\n", input_num, step); |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
state->down.sum = sum; |
|
|
|
|
state->down.sum_count = sum_count; |
|
|
|
|
|
|
|
|
|
return output_num; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* convert 8000 Hz sample rate to output sample rate */ |
|
|
|
|
int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output) |
|
|
|
|
{ |
|
|
|
|
#ifdef USE_FILTER |
|
|
|
|
int output_num, i; |
|
|
|
|
int factor = state->factor; |
|
|
|
|
double spl[input_num * factor]; |
|
|
|
|
double factor = 1.0 / state->factor, step; |
|
|
|
|
double spl[(int)((double)input_num / factor + 0.5) + 10]; /* add some fafety */ |
|
|
|
|
int32_t value; |
|
|
|
|
|
|
|
|
|
output_num = input_num * factor; |
|
|
|
|
output_num = (int)((double)input_num / factor + 0.5); |
|
|
|
|
|
|
|
|
|
/* resample input */ |
|
|
|
|
for (i = 0; i < output_num; i++) |
|
|
|
|
spl[i] = input[i / factor] / 32768.0; |
|
|
|
|
for (i = 0, step = 0.5 / (double)output_num; i < output_num; i++, step += factor) |
|
|
|
|
spl[i] = input[(int)step] / 32768.0; |
|
|
|
|
if ((int)(step - factor) >= input_num) { |
|
|
|
|
fprintf(stderr, "Error: input_num is %d, so step should be close to 0.5 below that, but it is %.4f. Please fix!\n", input_num, step); |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* filter up */ |
|
|
|
|
biquad_process(&state->up.bq, spl, output_num, 1); |
|
|
|
@ -129,31 +108,5 @@ int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return output_num; |
|
|
|
|
#else |
|
|
|
|
int output_num = 0, i, j; |
|
|
|
|
double last_sample, sample, slope; |
|
|
|
|
int factor; |
|
|
|
|
|
|
|
|
|
last_sample = state->up.last_sample; |
|
|
|
|
factor = state->factor; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < input_num; i++) { |
|
|
|
|
sample = *input++; |
|
|
|
|
slope = (double)(sample - last_sample) / (double)factor; |
|
|
|
|
//int jolly = (int)last_sample;
|
|
|
|
|
for (j = 0; j < factor; j++) { |
|
|
|
|
// if (last_sample > 32767 || last_sample < -32767)
|
|
|
|
|
// printf("%.5f sample=%.0f, last_sample=%d, slope=%.5f\n", last_sample, sample, jolly, slope);
|
|
|
|
|
*output++ = last_sample; |
|
|
|
|
output_num++; |
|
|
|
|
last_sample += slope; |
|
|
|
|
} |
|
|
|
|
last_sample = sample; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
state->up.last_sample = last_sample; |
|
|
|
|
|
|
|
|
|
return output_num; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|