resample: fix start position of new samples

When we finished processing the history it might be possible that we
need to skip some samples from the input. Implement this by adding
a start offset for the samples in the buffer.
This commit is contained in:
Wim Taymans 2020-02-13 16:43:06 +01:00
parent 0a26c478f7
commit 761119f640
2 changed files with 19 additions and 17 deletions

View file

@ -29,8 +29,8 @@
#include "resample.h" #include "resample.h"
typedef void (*resample_func_t)(struct resample *r, typedef void (*resample_func_t)(struct resample *r,
const void * SPA_RESTRICT src[], uint32_t *in_len, const void * SPA_RESTRICT src[], uint32_t ioffs, uint32_t *in_len,
void * SPA_RESTRICT dst[], uint32_t offs, uint32_t *out_len); void * SPA_RESTRICT dst[], uint32_t ooffs, uint32_t *out_len);
struct native_data { struct native_data {
double rate; double rate;
@ -52,8 +52,8 @@ struct native_data {
#define DEFINE_RESAMPLER(type,arch) \ #define DEFINE_RESAMPLER(type,arch) \
void do_resample_##type##_##arch(struct resample *r, \ void do_resample_##type##_##arch(struct resample *r, \
const void * SPA_RESTRICT src[], uint32_t *in_len, \ const void * SPA_RESTRICT src[], uint32_t ioffs, uint32_t *in_len, \
void * SPA_RESTRICT dst[], uint32_t offs, uint32_t *out_len) void * SPA_RESTRICT dst[], uint32_t ooffs, uint32_t *out_len)
#define MAKE_RESAMPLER_COPY(arch) \ #define MAKE_RESAMPLER_COPY(arch) \
DEFINE_RESAMPLER(copy,arch) \ DEFINE_RESAMPLER(copy,arch) \
@ -65,21 +65,21 @@ DEFINE_RESAMPLER(copy,arch) \
if (r->channels == 0) \ if (r->channels == 0) \
return; \ return; \
\ \
index = 0; \ index = ioffs; \
if (offs < olen && index + n_taps <= ilen) { \ if (ooffs < olen && index + n_taps <= ilen) { \
uint32_t to_copy = SPA_MIN(olen - offs, \ uint32_t to_copy = SPA_MIN(olen - ooffs, \
ilen - (index + n_taps) + 1); \ ilen - (index + n_taps) + 1); \
for (c = 0; c < r->channels; c++) { \ for (c = 0; c < r->channels; c++) { \
const float *s = src[c]; \ const float *s = src[c]; \
float *d = dst[c]; \ float *d = dst[c]; \
spa_memcpy(&d[offs], &s[index + n_taps2], \ spa_memcpy(&d[ooffs], &s[index + n_taps2], \
to_copy * sizeof(float)); \ to_copy * sizeof(float)); \
} \ } \
index += to_copy; \ index += to_copy; \
offs += to_copy; \ ooffs += to_copy; \
} \ } \
*in_len = index; \ *in_len = index; \
*out_len = offs; \ *out_len = ooffs; \
} }
#define MAKE_RESAMPLER_FULL(arch) \ #define MAKE_RESAMPLER_FULL(arch) \
@ -90,6 +90,7 @@ DEFINE_RESAMPLER(full,arch) \
uint32_t index, phase, n_phases = data->out_rate; \ uint32_t index, phase, n_phases = data->out_rate; \
uint32_t c, o, olen = *out_len, ilen = *in_len; \ uint32_t c, o, olen = *out_len, ilen = *in_len; \
uint32_t inc = data->inc, frac = data->frac; \ uint32_t inc = data->inc, frac = data->frac; \
static int cnt = 0; \
\ \
if (r->channels == 0) \ if (r->channels == 0) \
return; \ return; \
@ -98,10 +99,10 @@ DEFINE_RESAMPLER(full,arch) \
const float *s = src[c]; \ const float *s = src[c]; \
float *d = dst[c]; \ float *d = dst[c]; \
\ \
index = 0; \ index = ioffs; \
phase = data->phase; \ phase = data->phase; \
\ \
for (o = offs; o < olen && index + n_taps <= ilen; o++) { \ for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
const float *ip, *taps; \ const float *ip, *taps; \
\ \
ip = &s[index]; \ ip = &s[index]; \
@ -137,10 +138,10 @@ DEFINE_RESAMPLER(inter,arch) \
const float *s = src[c]; \ const float *s = src[c]; \
float *d = dst[c]; \ float *d = dst[c]; \
\ \
index = 0; \ index = ioffs; \
phase = data->phase; \ phase = data->phase; \
\ \
for (o = offs; o < olen && index + n_taps <= ilen; o++) { \ for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
const float *ip, *t0, *t1; \ const float *ip, *t0, *t1; \
float ph, x; \ float ph, x; \
uint32_t offset; \ uint32_t offset; \

View file

@ -184,7 +184,7 @@ static void impl_native_process(struct resample *r,
* and we try to process it */ * and we try to process it */
in = hist + refill; in = hist + refill;
out = *out_len; out = *out_len;
data->func(r, (const void**)history, &in, dst, 0, &out); data->func(r, (const void**)history, 0, &in, dst, 0, &out);
spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d hist:%d", spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d hist:%d",
r, hist + refill, in, *out_len, out, hist); r, hist + refill, in, *out_len, out, hist);
} else { } else {
@ -192,10 +192,11 @@ static void impl_native_process(struct resample *r,
} }
if (in >= hist) { if (in >= hist) {
int skip = in - hist;
/* we are past the history and can now work on the new /* we are past the history and can now work on the new
* input data */ * input data */
in = *in_len; in = *in_len - skip;
data->func(r, src, &in, dst, out, out_len); data->func(r, src, skip, &in, dst, out, out_len);
spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d", spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d",
r, *in_len, in, *out_len, out); r, *in_len, in, *out_len, out);