mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
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:
parent
0a26c478f7
commit
761119f640
2 changed files with 19 additions and 17 deletions
|
|
@ -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; \
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue