From 8dc62142765249addf131b058c27f931ede1776b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 6 Nov 2006 13:06:01 +0000 Subject: Revert r1404 and keep it on a development branch until it is fully tested. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1409 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 247 ++++++++++++++++++++++------------------------ 1 file changed, 119 insertions(+), 128 deletions(-) (limited to 'src/pulsecore/resampler.c') diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index c28c2fb3..b0142049 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -51,7 +51,8 @@ struct pa_resampler { }; struct impl_libsamplerate { - pa_memchunk buf1, buf2, buf3, buf4; + pa_memblock *buf1_block, *buf2_block, *buf3_block, *buf4_block; + float* buf1, *buf2, *buf3, *buf4; unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples; pa_convert_to_float32ne_func_t to_float32ne_func; @@ -223,14 +224,14 @@ static void libsamplerate_free(pa_resampler *r) { if (u->src_state) src_delete(u->src_state); - if (u->buf1.memblock) - pa_memblock_unref(u->buf1.memblock); - if (u->buf2.memblock) - pa_memblock_unref(u->buf2.memblock); - if (u->buf3.memblock) - pa_memblock_unref(u->buf3.memblock); - if (u->buf4.memblock) - pa_memblock_unref(u->buf4.memblock); + if (u->buf1_block) + pa_memblock_unref(u->buf1_block); + if (u->buf2_block) + pa_memblock_unref(u->buf2_block); + if (u->buf3_block) + pa_memblock_unref(u->buf3_block); + if (u->buf4_block) + pa_memblock_unref(u->buf4_block); pa_xfree(u); } @@ -269,80 +270,64 @@ static void calc_map_table(pa_resampler *r) { } } -static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { +static float * convert_to_float(pa_resampler *r, void *input, unsigned n_frames) { struct impl_libsamplerate *u; unsigned n_samples; - void *src, *dst; assert(r); assert(input); - assert(input->memblock); - assert(r->impl_data); u = r->impl_data; /* Convert the incoming sample into floats and place them in buf1 */ - if (!u->to_float32ne_func || !input->length) + if (!u->to_float32ne_func) return input; - n_samples = (input->length / r->i_fz) * r->i_ss.channels; + n_samples = n_frames * r->i_ss.channels; - if (!u->buf1.memblock || u->buf1_samples < n_samples) { - if (u->buf1.memblock) - pa_memblock_unref(u->buf1.memblock); + if (u->buf1_samples < n_samples) { + if (u->buf1_block) + pa_memblock_unref(u->buf1_block); u->buf1_samples = n_samples; - u->buf1.memblock = pa_memblock_new(r->mempool, u->buf1.length = sizeof(float) * n_samples); - u->buf1.index = 0; + u->buf1_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); + u->buf1 = u->buf1_block->data; } + + u->to_float32ne_func(n_samples, input, u->buf1); - src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; - dst = (uint8_t*) pa_memblock_acquire(u->buf1.memblock); - u->to_float32ne_func(n_samples, src, dst); - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf1.memblock); - - u->buf1.length = sizeof(float) * n_samples; - - return &u->buf1; + return u->buf1; } -static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { +static float *remap_channels(pa_resampler *r, float *input, unsigned n_frames) { struct impl_libsamplerate *u; - unsigned n_samples, n_frames; + unsigned n_samples; int i_skip, o_skip; unsigned oc; - float *src, *dst; assert(r); assert(input); - assert(input->memblock); - assert(r->impl_data); u = r->impl_data; /* Remap channels and place the result int buf2 */ - if (!u->map_required || !input->length) + if (!u->map_required) return input; - n_samples = input->length / sizeof(float); - n_frames = n_samples / r->o_ss.channels; + n_samples = n_frames * r->o_ss.channels; - if (!u->buf2.memblock || u->buf2_samples < n_samples) { - if (u->buf2.memblock) - pa_memblock_unref(u->buf2.memblock); + if (u->buf2_samples < n_samples) { + if (u->buf2_block) + pa_memblock_unref(u->buf2_block); u->buf2_samples = n_samples; - u->buf2.memblock = pa_memblock_new(r->mempool, u->buf2.length = sizeof(float) * n_samples); - u->buf2.index = 0; + u->buf2_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); + u->buf2 = u->buf2_block->data; } - src = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - dst = (float*) pa_memblock_acquire(u->buf2.memblock); - - memset(dst, 0, n_samples * sizeof(float)); + memset(u->buf2, 0, n_samples * sizeof(float)); o_skip = sizeof(float) * r->o_ss.channels; i_skip = sizeof(float) * r->i_ss.channels; @@ -353,57 +338,49 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { for (i = 0; i < PA_CHANNELS_MAX && u->map_table[oc][i] >= 0; i++) oil_vectoradd_f32( - dst + oc, o_skip, - dst + oc, o_skip, - src + u->map_table[oc][i], i_skip, + u->buf2 + oc, o_skip, + u->buf2 + oc, o_skip, + input + u->map_table[oc][i], i_skip, n_frames, &one, &one); } - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf2.memblock); - - u->buf2.length = n_frames * sizeof(float) * r->o_ss.channels; - - return &u->buf2; + return u->buf2; } -static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { +static float *resample(pa_resampler *r, float *input, unsigned *n_frames) { struct impl_libsamplerate *u; SRC_DATA data; - unsigned in_n_frames, in_n_samples; unsigned out_n_frames, out_n_samples; int ret; assert(r); assert(input); + assert(n_frames); assert(r->impl_data); u = r->impl_data; /* Resample the data and place the result in buf3 */ - if (!u->src_state || !input->length) + if (!u->src_state) return input; - in_n_samples = input->length / sizeof(float); - in_n_frames = in_n_samples * r->o_ss.channels; - - out_n_frames = (in_n_frames*r->o_ss.rate/r->i_ss.rate)+1024; + out_n_frames = (*n_frames*r->o_ss.rate/r->i_ss.rate)+1024; out_n_samples = out_n_frames * r->o_ss.channels; - if (!u->buf3.memblock || u->buf3_samples < out_n_samples) { - if (u->buf3.memblock) - pa_memblock_unref(u->buf3.memblock); + if (u->buf3_samples < out_n_samples) { + if (u->buf3_block) + pa_memblock_unref(u->buf3_block); u->buf3_samples = out_n_samples; - u->buf3.memblock = pa_memblock_new(r->mempool, u->buf3.length = sizeof(float) * out_n_samples); - u->buf3.index = 0; + u->buf3_block = pa_memblock_new(r->mempool, sizeof(float) * out_n_samples); + u->buf3 = u->buf3_block->data; } - data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - data.input_frames = in_n_frames; + data.data_in = input; + data.input_frames = *n_frames; - data.data_out = (float*) pa_memblock_acquire(u->buf3.memblock); + data.data_out = u->buf3; data.output_frames = out_n_frames; data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate; @@ -411,20 +388,16 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { ret = src_process(u->src_state, &data); assert(ret == 0); - assert((unsigned) data.input_frames_used == in_n_frames); + assert((unsigned) data.input_frames_used == *n_frames); - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf3.memblock); - - u->buf3.length = data.output_frames_gen * sizeof(float) * r->o_ss.channels; + *n_frames = data.output_frames_gen; - return &u->buf3; + return u->buf3; } -static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { +static void *convert_from_float(pa_resampler *r, float *input, unsigned n_frames) { struct impl_libsamplerate *u; - unsigned n_samples, n_frames; - void *src, *dst; + unsigned n_samples; assert(r); assert(input); @@ -433,35 +406,30 @@ static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { /* Convert the data into the correct sample type and place the result in buf4 */ - if (!u->from_float32ne_func || !input->length) + if (!u->from_float32ne_func) return input; - - n_frames = input->length / sizeof(float) / r->o_ss.channels; + n_samples = n_frames * r->o_ss.channels; if (u->buf4_samples < n_samples) { - if (u->buf4.memblock) - pa_memblock_unref(u->buf4.memblock); + if (u->buf4_block) + pa_memblock_unref(u->buf4_block); u->buf4_samples = n_samples; - u->buf4.memblock = pa_memblock_new(r->mempool, u->buf4.length = r->o_fz * n_frames); - u->buf4.index = 0; + u->buf4_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); + u->buf4 = u->buf4_block->data; } + + u->from_float32ne_func(n_samples, input, u->buf4); - src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->length; - dst = pa_memblock_acquire(u->buf4.memblock); - u->from_float32ne_func(n_samples, src, dst); - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf4.memblock); - - u->buf4.length = r->o_fz * n_frames; - - return &u->buf4; + return u->buf4; } static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { struct impl_libsamplerate *u; - pa_memchunk *buf; + float *buf; + void *input, *output; + unsigned n_frames; assert(r); assert(in); @@ -473,23 +441,55 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun u = r->impl_data; - buf = convert_to_float(r, (pa_memchunk*) in); - buf = remap_channels(r, buf); - buf = resample(r, buf); - - if (buf->length) { - buf = convert_from_float(r, buf); - *out = *buf; - - if (buf == in) - pa_memblock_ref(buf->memblock); - else - pa_memchunk_reset(buf); - } else - pa_memchunk_reset(out); - - pa_memblock_release(in->memblock); - + input = ((uint8_t*) in->memblock->data + in->index); + n_frames = in->length / r->i_fz; + assert(n_frames > 0); + + buf = convert_to_float(r, input, n_frames); + buf = remap_channels(r, buf, n_frames); + buf = resample(r, buf, &n_frames); + + if (n_frames) { + output = convert_from_float(r, buf, n_frames); + + if (output == input) { + /* Mm, no adjustment has been necessary, so let's return the original block */ + out->memblock = pa_memblock_ref(in->memblock); + out->index = in->index; + out->length = in->length; + } else { + out->length = n_frames * r->o_fz; + out->index = 0; + out->memblock = NULL; + + if (output == u->buf1) { + u->buf1 = NULL; + u->buf1_samples = 0; + out->memblock = u->buf1_block; + u->buf1_block = NULL; + } else if (output == u->buf2) { + u->buf2 = NULL; + u->buf2_samples = 0; + out->memblock = u->buf2_block; + u->buf2_block = NULL; + } else if (output == u->buf3) { + u->buf3 = NULL; + u->buf3_samples = 0; + out->memblock = u->buf3_block; + u->buf3_block = NULL; + } else if (output == u->buf4) { + u->buf4 = NULL; + u->buf4_samples = 0; + out->memblock = u->buf4_block; + u->buf4_block = NULL; + } + + assert(out->memblock); + } + } else { + out->memblock = NULL; + out->index = out->length = 0; + } } static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { @@ -516,10 +516,8 @@ static int libsamplerate_init(pa_resampler *r) { r->impl_data = u = pa_xnew(struct impl_libsamplerate, 1); - pa_memchunk_reset(&u->buf1); - pa_memchunk_reset(&u->buf2); - pa_memchunk_reset(&u->buf3); - pa_memchunk_reset(&u->buf4); + u->buf1 = u->buf2 = u->buf3 = u->buf4 = NULL; + u->buf1_block = u->buf2_block = u->buf3_block = u->buf4_block = NULL; u->buf1_samples = u->buf2_samples = u->buf3_samples = u->buf4_samples = 0; if (r->i_ss.format == PA_SAMPLE_FLOAT32NE) @@ -580,16 +578,12 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out /* Do real resampling */ size_t l; unsigned o_index; - void *src, *dst; /* The length of the new memory block rounded up */ l = ((((n_frames+1) * r->o_ss.rate) / r->i_ss.rate) + 1) * fz; out->index = 0; out->memblock = pa_memblock_new(r->mempool, l); - - src = (uint8_t*) pa_memblock_acquire(in->memblock) + in->index; - dst = pa_memblock_acquire(out->memblock); for (o_index = 0;; o_index++, u->o_counter++) { unsigned j; @@ -600,16 +594,13 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out if (j >= n_frames) break; - assert(o_index*fz < pa_memblock_get_length(out->memblock)); + assert(o_index*fz < out->memblock->length); - memcpy((uint8_t*) dst + fz*o_index, - (uint8_t*) src + fz*j, fz); + memcpy((uint8_t*) out->memblock->data + fz*o_index, + (uint8_t*) in->memblock->data + in->index + fz*j, fz); } - - pa_memblock_release(in->memblock); - pa_memblock_release(out->memblock); - + out->length = o_index*fz; } -- cgit