[pulseaudio-commits] r1881 - /branches/lennart/src/pulsecore/resampler.c
svnmailer-noreply at 0pointer.de
svnmailer-noreply at 0pointer.de
Fri Sep 21 17:22:36 PDT 2007
Author: lennart
Date: Sat Sep 22 02:22:36 2007
New Revision: 1881
URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=1881&root=pulseaudio&view=rev
Log:
fix selection of working format
Modified:
branches/lennart/src/pulsecore/resampler.c
Modified: branches/lennart/src/pulsecore/resampler.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/resampler.c?rev=1881&root=pulseaudio&r1=1880&r2=1881&view=diff
==============================================================================
--- branches/lennart/src/pulsecore/resampler.c (original)
+++ branches/lennart/src/pulsecore/resampler.c Sat Sep 22 02:22:36 2007
@@ -29,7 +29,7 @@
#if HAVE_LIBSAMPLERATE
#include <samplerate.h>
-#endif
+#endif
#include <liboil/liboilfuncs.h>
#include <liboil/liboil.h>
@@ -59,7 +59,7 @@
unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;
pa_sample_format_t work_format;
-
+
pa_convert_func_t to_work_format_func;
pa_convert_func_t from_work_format_func;
@@ -69,7 +69,7 @@
void (*impl_free)(pa_resampler *r);
void (*impl_update_rates)(pa_resampler *r);
void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples);
-
+
struct { /* data specific to the trivial resampler */
unsigned o_counter;
unsigned i_counter;
@@ -114,7 +114,7 @@
[PA_RESAMPLER_SRC_SINC_FASTEST] = NULL,
[PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL,
[PA_RESAMPLER_SRC_LINEAR] = NULL,
-#endif
+#endif
[PA_RESAMPLER_TRIVIAL] = trivial_init,
[PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init,
[PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init,
@@ -178,12 +178,12 @@
pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
resample_method = PA_RESAMPLER_COPY;
}
-
+
if (!pa_resample_method_supported(resample_method)) {
pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(resample_method));
resample_method = PA_RESAMPLER_AUTO;
}
-
+
if (resample_method == PA_RESAMPLER_FFMPEG && variable_rate) {
pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
resample_method = PA_RESAMPLER_AUTO;
@@ -232,27 +232,30 @@
calc_map_table(r);
pa_log_info("Using resampler '%s'", pa_resample_method_to_string(resample_method));
-
+
if ((resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) ||
(resample_method == PA_RESAMPLER_FFMPEG))
r->work_format = PA_SAMPLE_S16NE;
- else if (resample_method == PA_RESAMPLER_TRIVIAL) {
+ else if (resample_method == PA_RESAMPLER_TRIVIAL || resample_method == PA_RESAMPLER_COPY) {
if (r->map_required || a->format != b->format) {
- if (a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE)
+ if (a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE ||
+ b->format == PA_SAMPLE_FLOAT32NE || b->format == PA_SAMPLE_FLOAT32RE)
r->work_format = PA_SAMPLE_FLOAT32NE;
else
r->work_format = PA_SAMPLE_S16NE;
-
+
} else
r->work_format = a->format;
-
+
} else
r->work_format = PA_SAMPLE_FLOAT32NE;
+ pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
+
r->w_sz = sample_size(r->work_format);
-
+
if (r->i_ss.format == r->work_format)
r->to_work_format_func = NULL;
else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
@@ -302,7 +305,7 @@
pa_memblock_unref(r->buf3.memblock);
if (r->buf4.memblock)
pa_memblock_unref(r->buf4.memblock);
-
+
pa_xfree(r);
}
@@ -340,7 +343,7 @@
size_t block_size_max;
pa_sample_spec ss;
size_t fs;
-
+
pa_assert(r);
block_size_max = pa_mempool_block_size_max(r->mempool);
@@ -352,7 +355,7 @@
ss.channels = r->o_ss.channels;
/* We silently assume that the format enum is ordered by size */
- if (r->o_ss.format > ss.format)
+ if (r->o_ss.format > ss.format)
ss.format = r->o_ss.format;
if (r->work_format > ss.format)
ss.format = r->work_format;
@@ -361,13 +364,13 @@
ss.rate = r->o_ss.rate;
fs = pa_frame_size(&ss);
-
+
return (((block_size_max/fs + EXTRA_SAMPLES)*r->i_ss.rate)/ss.rate)*r->i_fz;
}
pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
pa_assert(r);
-
+
return r->resample_method;
}
@@ -422,7 +425,7 @@
if (m <= PA_RESAMPLER_SRC_LINEAR)
return 0;
#endif
-
+
return 1;
}
@@ -446,7 +449,7 @@
static void calc_map_table(pa_resampler *r) {
unsigned oc;
-
+
pa_assert(r);
if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || !pa_channel_map_equal(&r->i_cm, &r->o_cm))))
@@ -493,7 +496,7 @@
r->buf1.index = 0;
r->buf1.length = r->w_sz * n_samples;
-
+
if (!r->buf1.memblock || r->buf1_samples < n_samples) {
if (r->buf1.memblock)
pa_memblock_unref(r->buf1.memblock);
@@ -534,7 +537,7 @@
r->buf2.index = 0;
r->buf2.length = r->w_sz * out_n_samples;
-
+
if (!r->buf2.memblock || r->buf2_samples < out_n_samples) {
if (r->buf2.memblock)
pa_memblock_unref(r->buf2.memblock);
@@ -553,11 +556,11 @@
switch (r->work_format) {
case PA_SAMPLE_FLOAT32NE:
-
+
for (oc = 0; oc < r->o_ss.channels; oc++) {
unsigned i;
static const float one = 1.0;
-
+
for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++)
oil_vectoradd_f32(
(float*) dst + oc, o_skip,
@@ -574,7 +577,7 @@
for (oc = 0; oc < r->o_ss.channels; oc++) {
unsigned i;
static const int16_t one = 1;
-
+
for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++)
oil_vectoradd_s16(
(int16_t*) dst + oc, o_skip,
@@ -618,7 +621,7 @@
r->buf3.index = 0;
r->buf3.length = r->w_sz * out_n_samples;
-
+
if (!r->buf3.memblock || r->buf3_samples < out_n_samples) {
if (r->buf3.memblock)
pa_memblock_unref(r->buf3.memblock);
@@ -629,7 +632,7 @@
r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames);
r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels;
-
+
return &r->buf3;
}
@@ -650,7 +653,7 @@
r->buf4.index = 0;
r->buf4.length = r->o_fz * n_frames;
-
+
if (!r->buf4.memblock || r->buf4_samples < n_samples) {
if (r->buf4.memblock)
pa_memblock_unref(r->buf4.memblock);
@@ -688,7 +691,7 @@
if (buf->length) {
buf = convert_from_work_format(r, buf);
*out = *buf;
-
+
if (buf == in)
pa_memblock_ref(buf->memblock);
else
@@ -702,14 +705,14 @@
#ifdef HAVE_LIBSAMPLERATE
static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
SRC_DATA data;
-
+
pa_assert(r);
pa_assert(input);
pa_assert(output);
pa_assert(out_n_frames);
-
+
memset(&data, 0, sizeof(data));
-
+
data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
data.input_frames = in_n_frames;
@@ -736,16 +739,16 @@
static void libsamplerate_free(pa_resampler *r) {
pa_assert(r);
-
+
if (r->src.state)
src_delete(r->src.state);
}
static int libsamplerate_init(pa_resampler *r) {
int err;
-
- pa_assert(r);
-
+
+ pa_assert(r);
+
if (!(r->src.state = src_new(r->resample_method, r->o_ss.channels, &err)))
return -1;
@@ -767,7 +770,7 @@
pa_assert(input);
pa_assert(output);
pa_assert(out_n_frames);
-
+
in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
@@ -788,7 +791,7 @@
pa_assert(input);
pa_assert(output);
pa_assert(out_n_frames);
-
+
in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
@@ -804,7 +807,7 @@
static void speex_update_rates(pa_resampler *r) {
pa_assert(r);
- if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
+ if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
pa_assert_se(paspfx_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
else {
pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
@@ -814,11 +817,11 @@
static void speex_free(pa_resampler *r) {
pa_assert(r);
-
+
if (!r->speex.state)
return;
-
- if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
+
+ if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
paspfx_resampler_destroy(r->speex.state);
else {
pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
@@ -828,17 +831,17 @@
static int speex_init(pa_resampler *r) {
int q, err;
-
+
pa_assert(r);
r->impl_free = speex_free;
r->impl_update_rates = speex_update_rates;
-
+
if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) {
q = r->resample_method - PA_RESAMPLER_SPEEX_FIXED_BASE;
pa_log_info("Choosing speex quality setting %i.", q);
-
+
if (!(r->speex.state = paspfx_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
return -1;
@@ -848,7 +851,7 @@
q = r->resample_method - PA_RESAMPLER_SPEEX_FLOAT_BASE;
pa_log_info("Choosing speex quality setting %i.", q);
-
+
if (!(r->speex.state = paspfl_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
return -1;
@@ -864,35 +867,35 @@
size_t fz;
unsigned o_index;
void *src, *dst;
-
+
pa_assert(r);
pa_assert(input);
pa_assert(output);
pa_assert(out_n_frames);
fz = r->w_sz * r->o_ss.channels;
-
+
src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
-
+
for (o_index = 0;; o_index++, r->trivial.o_counter++) {
unsigned j;
-
+
j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate);
j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0;
-
+
if (j >= in_n_frames)
break;
pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
-
+
oil_memcpy((uint8_t*) dst + fz * o_index,
- (uint8_t*) src + fz * j, fz);
- }
-
+ (uint8_t*) src + fz * j, fz);
+ }
+
pa_memblock_release(input->memblock);
pa_memblock_release(output->memblock);
-
+
*out_n_frames = o_index;
r->trivial.i_counter += in_n_frames;
@@ -929,7 +932,7 @@
static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
unsigned used_frames = 0, c;
-
+
pa_assert(r);
pa_assert(input);
pa_assert(output);
@@ -1008,9 +1011,9 @@
static void ffmpeg_free(pa_resampler *r) {
unsigned c;
-
- pa_assert(r);
-
+
+ pa_assert(r);
+
if (r->ffmpeg.state)
av_resample_close(r->ffmpeg.state);
@@ -1021,21 +1024,21 @@
static int ffmpeg_init(pa_resampler *r) {
unsigned c;
-
+
pa_assert(r);
/* We could probably implement different quality levels by
* adjusting the filter parameters here. However, ffmpeg
* internally only uses these hardcoded values, so let's use them
* here for now as well until ffmpeg makes this configurable. */
-
+
if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8)))
return -1;
r->impl_free = ffmpeg_free;
r->impl_resample = ffmpeg_resample;
- for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
+ for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
pa_memchunk_reset(&r->ffmpeg.buf[c]);
return 0;
@@ -1047,7 +1050,7 @@
pa_assert(r);
pa_assert(r->o_ss.rate == r->i_ss.rate);
-
+
r->impl_free = NULL;
r->impl_resample = NULL;
r->impl_update_rates = NULL;
More information about the pulseaudio-commits
mailing list