mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
audioconvert: interchange the resampler loops
Iterate the channels in the inner loop instead of the outer loop. This makes it handle with 0 channels better but also does the more complicated phase increment code only once for all channels. Also the filters might stay in the cache for each channel now.
This commit is contained in:
parent
3f41b93aa5
commit
fb2b314660
1 changed files with 32 additions and 44 deletions
|
|
@ -52,16 +52,13 @@ DEFINE_RESAMPLER(copy,arch) \
|
||||||
{ \
|
{ \
|
||||||
struct native_data *data = r->data; \
|
struct native_data *data = r->data; \
|
||||||
uint32_t index, n_taps = data->n_taps, n_taps2 = n_taps/2; \
|
uint32_t index, n_taps = data->n_taps, n_taps2 = n_taps/2; \
|
||||||
uint32_t c, olen = *out_len, ilen = *in_len; \
|
uint32_t c, olen = *out_len, ilen = *in_len, ch = r->channels; \
|
||||||
\
|
|
||||||
if (r->channels == 0) \
|
|
||||||
return; \
|
|
||||||
\
|
\
|
||||||
index = ioffs; \
|
index = ioffs; \
|
||||||
if (ooffs < olen && index + n_taps <= ilen) { \
|
if (ooffs < olen && index + n_taps <= ilen) { \
|
||||||
uint32_t to_copy = SPA_MIN(olen - ooffs, \
|
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 < ch; c++) { \
|
||||||
const float *s = src[c]; \
|
const float *s = src[c]; \
|
||||||
float *d = dst[c]; \
|
float *d = dst[c]; \
|
||||||
spa_memcpy(&d[ooffs], &s[index + n_taps2], \
|
spa_memcpy(&d[ooffs], &s[index + n_taps2], \
|
||||||
|
|
@ -74,12 +71,12 @@ DEFINE_RESAMPLER(copy,arch) \
|
||||||
*out_len = ooffs; \
|
*out_len = ooffs; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INC(index,phase,n_phases) \
|
#define INC(index,phase,n_phases) \
|
||||||
index += inc; \
|
index += inc; \
|
||||||
phase += frac; \
|
phase += frac; \
|
||||||
if (phase >= n_phases) { \
|
if (phase >= n_phases) { \
|
||||||
phase -= n_phases; \
|
phase -= n_phases; \
|
||||||
index += 1; \
|
index += 1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_RESAMPLER_FULL(arch) \
|
#define MAKE_RESAMPLER_FULL(arch) \
|
||||||
|
|
@ -89,24 +86,19 @@ DEFINE_RESAMPLER(full,arch) \
|
||||||
uint32_t n_taps = data->n_taps, stride = data->filter_stride_os; \
|
uint32_t n_taps = data->n_taps, stride = data->filter_stride_os; \
|
||||||
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, ch = r->channels; \
|
||||||
\
|
\
|
||||||
if (r->channels == 0) \
|
index = ioffs; \
|
||||||
return; \
|
phase = (uint32_t)data->phase; \
|
||||||
\
|
for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
|
||||||
for (c = 0; c < r->channels; c++) { \
|
float *filter = &data->filter[phase * stride]; \
|
||||||
const float *s = src[c]; \
|
for (c = 0; c < ch; c++) { \
|
||||||
float *d = dst[c]; \
|
const float *s = src[c]; \
|
||||||
\
|
float *d = dst[c]; \
|
||||||
index = ioffs; \
|
|
||||||
phase = (uint32_t)data->phase; \
|
|
||||||
\
|
|
||||||
for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
|
|
||||||
inner_product_##arch(&d[o], &s[index], \
|
inner_product_##arch(&d[o], &s[index], \
|
||||||
&data->filter[phase * stride], \
|
filter, n_taps); \
|
||||||
n_taps); \
|
|
||||||
INC(index, phase, n_phases); \
|
|
||||||
} \
|
} \
|
||||||
|
INC(index, phase, n_phases); \
|
||||||
} \
|
} \
|
||||||
*in_len = index; \
|
*in_len = index; \
|
||||||
*out_len = o; \
|
*out_len = o; \
|
||||||
|
|
@ -121,28 +113,24 @@ DEFINE_RESAMPLER(inter,arch) \
|
||||||
uint32_t n_phases = data->n_phases, out_rate = data->out_rate; \
|
uint32_t n_phases = data->n_phases, out_rate = data->out_rate; \
|
||||||
uint32_t n_taps = data->n_taps; \
|
uint32_t n_taps = data->n_taps; \
|
||||||
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, ch = r->channels; \
|
||||||
float phase; \
|
float phase; \
|
||||||
\
|
\
|
||||||
if (r->channels == 0) \
|
index = ioffs; \
|
||||||
return; \
|
phase = data->phase; \
|
||||||
\
|
for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
|
||||||
for (c = 0; c < r->channels; c++) { \
|
float ph = phase * n_phases / out_rate; \
|
||||||
const float *s = src[c]; \
|
uint32_t offset = (uint32_t)floorf(ph); \
|
||||||
float *d = dst[c]; \
|
float *filter0 = &data->filter[(offset+0) * stride]; \
|
||||||
\
|
float *filter1 = &data->filter[(offset+1) * stride]; \
|
||||||
index = ioffs; \
|
float pho = ph - offset; \
|
||||||
phase = data->phase; \
|
for (c = 0; c < ch; c++) { \
|
||||||
\
|
const float *s = src[c]; \
|
||||||
for (o = ooffs; o < olen && index + n_taps <= ilen; o++) { \
|
float *d = dst[c]; \
|
||||||
float ph = phase * n_phases / out_rate; \
|
|
||||||
uint32_t offset = (uint32_t)floorf(ph); \
|
|
||||||
inner_product_ip_##arch(&d[o], &s[index], \
|
inner_product_ip_##arch(&d[o], &s[index], \
|
||||||
&data->filter[(offset + 0) * stride], \
|
filter0, filter1, pho, n_taps); \
|
||||||
&data->filter[(offset + 1) * stride], \
|
|
||||||
ph - offset, n_taps); \
|
|
||||||
INC(index, phase, out_rate); \
|
|
||||||
} \
|
} \
|
||||||
|
INC(index, phase, out_rate); \
|
||||||
} \
|
} \
|
||||||
*in_len = index; \
|
*in_len = index; \
|
||||||
*out_len = o; \
|
*out_len = o; \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue