mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-17 06:59:56 -05:00
* add a new resampler "copy" which is does not change sample rates but copies data unmodified from input to output.
* add a new API pa_resampler_max_block_size() which can be used to determine the maximum input buffer size for the resampler so that the bounce buffers don't grow larger then the mempool tile size git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1830 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
d079b4863b
commit
fce8507179
2 changed files with 67 additions and 3 deletions
|
|
@ -45,6 +45,9 @@
|
|||
|
||||
#include "resampler.h"
|
||||
|
||||
/* Number of samples of extra space we allow the resamplers to return */
|
||||
#define EXTRA_SAMPLES 128
|
||||
|
||||
struct pa_resampler {
|
||||
pa_resample_method_t resample_method;
|
||||
pa_sample_spec i_ss, o_ss;
|
||||
|
|
@ -88,6 +91,7 @@ struct pa_resampler {
|
|||
} ffmpeg;
|
||||
};
|
||||
|
||||
static int copy_init(pa_resampler *r);
|
||||
static int trivial_init(pa_resampler*r);
|
||||
static int speex_init(pa_resampler*r);
|
||||
static int ffmpeg_init(pa_resampler*r);
|
||||
|
|
@ -136,6 +140,7 @@ static int (* const init_table[])(pa_resampler*r) = {
|
|||
[PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init,
|
||||
[PA_RESAMPLER_FFMPEG] = ffmpeg_init,
|
||||
[PA_RESAMPLER_AUTO] = NULL,
|
||||
[PA_RESAMPLER_COPY] = copy_init
|
||||
};
|
||||
|
||||
static inline size_t sample_size(pa_sample_format_t f) {
|
||||
|
|
@ -169,6 +174,11 @@ pa_resampler* pa_resampler_new(
|
|||
|
||||
/* Fix method */
|
||||
|
||||
if (!variable_rate && a->rate == b->rate) {
|
||||
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;
|
||||
|
|
@ -179,6 +189,11 @@ pa_resampler* pa_resampler_new(
|
|||
resample_method = PA_RESAMPLER_AUTO;
|
||||
}
|
||||
|
||||
if (resample_method == PA_RESAMPLER_COPY && (variable_rate || a->rate != b->rate)) {
|
||||
pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
|
||||
resample_method = PA_RESAMPLER_AUTO;
|
||||
}
|
||||
|
||||
if (resample_method == PA_RESAMPLER_AUTO)
|
||||
resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 0;
|
||||
|
||||
|
|
@ -321,6 +336,35 @@ size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
|
|||
return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz;
|
||||
}
|
||||
|
||||
size_t pa_resampler_max_block_size(pa_resampler *r) {
|
||||
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);
|
||||
|
||||
/* We deduce the "largest" sample spec we're using during the
|
||||
* conversion */
|
||||
ss = r->i_ss;
|
||||
if (r->o_ss.channels > ss.channels)
|
||||
ss.channels = r->o_ss.channels;
|
||||
|
||||
/* We silently assume that the format enum is ordered by size */
|
||||
if (r->o_ss.format > ss.format)
|
||||
ss.format = r->o_ss.format;
|
||||
if (r->work_format > ss.format)
|
||||
ss.format = r->work_format;
|
||||
|
||||
if (r->o_ss.rate > ss.rate)
|
||||
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);
|
||||
|
||||
|
|
@ -357,7 +401,8 @@ static const char * const resample_methods[] = {
|
|||
"speex-fixed-9",
|
||||
"speex-fixed-10",
|
||||
"ffmpeg",
|
||||
"auto"
|
||||
"auto",
|
||||
"copy"
|
||||
};
|
||||
|
||||
const char *pa_resample_method_to_string(pa_resample_method_t m) {
|
||||
|
|
@ -568,7 +613,7 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
|
|||
in_n_samples = input->length / r->w_sz;
|
||||
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 = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_SAMPLES;
|
||||
out_n_samples = out_n_frames * r->o_ss.channels;
|
||||
|
||||
r->buf3.index = 0;
|
||||
|
|
@ -875,6 +920,7 @@ static int trivial_init(pa_resampler*r) {
|
|||
|
||||
r->impl_resample = trivial_resample;
|
||||
r->impl_update_rates = trivial_update_rates;
|
||||
r->impl_free = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -994,3 +1040,17 @@ static int ffmpeg_init(pa_resampler *r) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** copy (noop) implementation ***/
|
||||
|
||||
static int copy_init(pa_resampler *r) {
|
||||
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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ typedef enum pa_resample_method {
|
|||
PA_RESAMPLER_SPEEX_FIXED_MAX = PA_RESAMPLER_SPEEX_FIXED_BASE + 10,
|
||||
PA_RESAMPLER_FFMPEG,
|
||||
PA_RESAMPLER_AUTO, /* automatic select based on sample format */
|
||||
PA_RESAMPLER_COPY,
|
||||
PA_RESAMPLER_MAX
|
||||
} pa_resample_method_t;
|
||||
|
||||
|
|
@ -62,6 +63,9 @@ void pa_resampler_free(pa_resampler *r);
|
|||
/* Returns the size of an input memory block which is required to return the specified amount of output data */
|
||||
size_t pa_resampler_request(pa_resampler *r, size_t out_length);
|
||||
|
||||
/* Requires the maximum size of input blocks we can process without needing bounce buffers larger than the mempool tile size. */
|
||||
size_t pa_resampler_max_block_size(pa_resampler *r);
|
||||
|
||||
/* Pass the specified memory chunk to the resampler and return the newly resampled data */
|
||||
void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue