mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
resample-native: optimize equal input and output sample rates
This commit is contained in:
parent
4fafd10a89
commit
eaffb25cc2
3 changed files with 43 additions and 9 deletions
|
|
@ -47,5 +47,6 @@ static void inner_product_ip_c(float *d, const float * SPA_RESTRICT s,
|
||||||
*d = (sum[1] - sum[0]) * x + sum[0];
|
*d = (sum[1] - sum[0]) * x + sum[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MAKE_RESAMPLER_COPY(c);
|
||||||
MAKE_RESAMPLER_FULL(c);
|
MAKE_RESAMPLER_FULL(c);
|
||||||
MAKE_RESAMPLER_INTER(c);
|
MAKE_RESAMPLER_INTER(c);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,35 @@
|
||||||
* DEALINGS IN THE SOFTWARE.
|
* DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define MAKE_RESAMPLER_COPY(arch) \
|
||||||
|
static void do_resample_copy_##arch(struct resample *r, \
|
||||||
|
const void * SPA_RESTRICT src[], uint32_t *in_len, \
|
||||||
|
void * SPA_RESTRICT dst[], uint32_t offs, uint32_t *out_len) \
|
||||||
|
{ \
|
||||||
|
struct native_data *data = r->data; \
|
||||||
|
uint32_t index, n_taps = data->n_taps; \
|
||||||
|
uint32_t c, olen = *out_len, ilen = *in_len; \
|
||||||
|
\
|
||||||
|
if (r->channels == 0) \
|
||||||
|
return; \
|
||||||
|
\
|
||||||
|
index = data->index; \
|
||||||
|
if (offs < olen && index + n_taps <= ilen) { \
|
||||||
|
uint32_t to_copy = SPA_MIN(olen - offs, \
|
||||||
|
ilen - (index + n_taps) + 1); \
|
||||||
|
for (c = 0; c < r->channels; c++) { \
|
||||||
|
const float *s = src[c]; \
|
||||||
|
float *d = dst[c]; \
|
||||||
|
memcpy(&d[offs], &s[index], to_copy * sizeof(float)); \
|
||||||
|
} \
|
||||||
|
index += to_copy; \
|
||||||
|
offs += to_copy; \
|
||||||
|
} \
|
||||||
|
*in_len = index - data->index; \
|
||||||
|
*out_len = offs; \
|
||||||
|
data->index = index; \
|
||||||
|
}
|
||||||
|
|
||||||
#define MAKE_RESAMPLER_FULL(arch) \
|
#define MAKE_RESAMPLER_FULL(arch) \
|
||||||
static void do_resample_full_##arch(struct resample *r, \
|
static void do_resample_full_##arch(struct resample *r, \
|
||||||
const void * SPA_RESTRICT src[], uint32_t *in_len, \
|
const void * SPA_RESTRICT src[], uint32_t *in_len, \
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ struct native_data {
|
||||||
double rate;
|
double rate;
|
||||||
uint32_t n_taps;
|
uint32_t n_taps;
|
||||||
uint32_t n_phases;
|
uint32_t n_phases;
|
||||||
uint32_t oversample;
|
|
||||||
uint32_t in_rate;
|
uint32_t in_rate;
|
||||||
uint32_t out_rate;
|
uint32_t out_rate;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
|
|
@ -101,8 +100,8 @@ static int build_filter(float *taps, uint32_t stride, uint32_t n_taps, uint32_t
|
||||||
for (j = 0; j < n_taps12; j++, t += 1.0) {
|
for (j = 0; j < n_taps12; j++, t += 1.0) {
|
||||||
/* exploit symmetry in filter taps */
|
/* exploit symmetry in filter taps */
|
||||||
taps[(n_phases - i) * stride + n_taps12 + j] =
|
taps[(n_phases - i) * stride + n_taps12 + j] =
|
||||||
taps[i * stride + (n_taps12 - j - 1)] =
|
taps[i * stride + (n_taps12 - j - 1)] =
|
||||||
cutoff * sinc(t * cutoff) * blackman(t, n_taps);
|
cutoff * sinc(t * cutoff) * blackman(t, n_taps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -144,15 +143,21 @@ static void impl_native_update_rate(struct resample *r, double rate)
|
||||||
data->inc = data->in_rate / data->out_rate;
|
data->inc = data->in_rate / data->out_rate;
|
||||||
data->frac = data->in_rate % data->out_rate;
|
data->frac = data->in_rate % data->out_rate;
|
||||||
|
|
||||||
data->func = rate == 1.0 ? do_resample_full_c : do_resample_inter_c;
|
if (data->in_rate == data->out_rate)
|
||||||
|
data->func = do_resample_copy_c;
|
||||||
|
else {
|
||||||
|
bool is_full = r->i_rate == in_rate;
|
||||||
|
|
||||||
|
data->func = is_full ? do_resample_full_c : do_resample_inter_c;
|
||||||
#if defined (__SSE__)
|
#if defined (__SSE__)
|
||||||
if (r->cpu_flags & SPA_CPU_FLAG_SSE)
|
if (r->cpu_flags & SPA_CPU_FLAG_SSE)
|
||||||
data->func = rate == 1.0 ? do_resample_full_sse : do_resample_inter_sse;
|
data->func = is_full ? do_resample_full_sse : do_resample_inter_sse;
|
||||||
#endif
|
#endif
|
||||||
#if defined (__SSSE3__)
|
#if defined (__SSSE3__)
|
||||||
if (r->cpu_flags & SPA_CPU_FLAG_SSSE3)
|
if (r->cpu_flags & SPA_CPU_FLAG_SSSE3)
|
||||||
data->func = rate == 1.0 ? do_resample_full_ssse3 : do_resample_inter_ssse3;
|
data->func = is_full ? do_resample_full_ssse3 : do_resample_inter_ssse3;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void impl_native_process(struct resample *r,
|
static void impl_native_process(struct resample *r,
|
||||||
|
|
@ -300,7 +305,6 @@ static int impl_native_init(struct resample *r)
|
||||||
r->data = d;
|
r->data = d;
|
||||||
d->n_taps = n_taps;
|
d->n_taps = n_taps;
|
||||||
d->n_phases = n_phases;
|
d->n_phases = n_phases;
|
||||||
d->oversample = oversample;
|
|
||||||
d->in_rate = in_rate;
|
d->in_rate = in_rate;
|
||||||
d->out_rate = out_rate;
|
d->out_rate = out_rate;
|
||||||
d->filter = SPA_MEMBER(d, sizeof(struct native_data), float);
|
d->filter = SPA_MEMBER(d, sizeof(struct native_data), float);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue