mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
sink, source: Add an avoid-processing mode
This generalises the avoid-resampling concept (don't resample for any rate above the default/alternate sample rate) to include channel count and sample format as well. The rationale for this is that users who wish to send out their data untouched by processing in PulseAudio can do so. In addition to this, there are opportunities for certain hardware (such as systems with a DSP connected to a codec) to offload processing to the DSP (providing potential cost savings). Finally, this also enables modules that might be able to perform transformations of (ANY -> sink format), and this allows us to implement such transformations.
This commit is contained in:
parent
cbaf278f1e
commit
01c26546fa
14 changed files with 121 additions and 14 deletions
|
|
@ -121,6 +121,13 @@ void pa_sink_new_data_set_avoid_resampling(pa_sink_new_data *data, bool avoid_re
|
|||
data->avoid_resampling = avoid_resampling;
|
||||
}
|
||||
|
||||
void pa_sink_new_data_set_avoid_processing(pa_sink_new_data *data, bool avoid_processing) {
|
||||
pa_assert(data);
|
||||
|
||||
data->avoid_processing_is_set = true;
|
||||
data->avoid_processing = avoid_processing;
|
||||
}
|
||||
|
||||
void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {
|
||||
pa_assert(data);
|
||||
|
||||
|
|
@ -272,7 +279,7 @@ pa_sink* pa_sink_new(
|
|||
|
||||
s->sample_spec = data->sample_spec;
|
||||
s->channel_map = data->channel_map;
|
||||
s->default_sample_rate = s->sample_spec.rate;
|
||||
s->default_sample_spec = s->sample_spec;
|
||||
pa_sample_spec_init(&s->saved_spec);
|
||||
pa_channel_map_init(&s->saved_map);
|
||||
|
||||
|
|
@ -286,6 +293,11 @@ pa_sink* pa_sink_new(
|
|||
else
|
||||
s->avoid_resampling = s->core->avoid_resampling;
|
||||
|
||||
if (data->avoid_processing_is_set)
|
||||
s->avoid_processing = data->avoid_processing;
|
||||
else
|
||||
s->avoid_processing = s->core->avoid_processing;
|
||||
|
||||
s->inputs = pa_idxset_new(NULL, NULL);
|
||||
s->n_corked = 0;
|
||||
s->input_to_master = NULL;
|
||||
|
|
@ -378,6 +390,7 @@ pa_sink* pa_sink_new(
|
|||
pa_source_new_data_set_channel_map(&source_data, &s->channel_map);
|
||||
pa_source_new_data_set_alternate_sample_rate(&source_data, s->alternate_sample_rate);
|
||||
pa_source_new_data_set_avoid_resampling(&source_data, s->avoid_resampling);
|
||||
pa_source_new_data_set_avoid_processing(&source_data, s->avoid_processing);
|
||||
source_data.name = pa_sprintf_malloc("%s.monitor", name);
|
||||
source_data.driver = data->driver;
|
||||
source_data.module = data->module;
|
||||
|
|
@ -1484,13 +1497,16 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
|
|||
int pa_sink_reconfigure(pa_sink *s, pa_sample_spec *spec, pa_channel_map *map, bool passthrough, bool restore) {
|
||||
int ret = -1;
|
||||
pa_sample_spec desired_spec;
|
||||
uint32_t default_rate = s->default_sample_rate;
|
||||
pa_sample_format_t default_format = s->default_sample_spec.format;
|
||||
uint32_t default_rate = s->default_sample_spec.rate;
|
||||
uint32_t alternate_rate = s->alternate_sample_rate;
|
||||
uint8_t default_channels = s->default_sample_spec.channels;
|
||||
uint32_t idx;
|
||||
pa_sink_input *i;
|
||||
bool default_rate_is_usable = false;
|
||||
bool alternate_rate_is_usable = false;
|
||||
bool avoid_resampling = s->avoid_resampling;
|
||||
bool avoid_processing = s->avoid_processing;
|
||||
pa_channel_map old_map, *new_map;
|
||||
|
||||
pa_assert(restore || (spec != NULL));
|
||||
|
|
@ -1502,7 +1518,7 @@ int pa_sink_reconfigure(pa_sink *s, pa_sample_spec *spec, pa_channel_map *map, b
|
|||
if (!s->reconfigure)
|
||||
return -1;
|
||||
|
||||
if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough && !restore && !avoid_resampling)) {
|
||||
if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough && !restore && !avoid_resampling && !avoid_processing)) {
|
||||
pa_log_debug("Default and alternate sample rates are the same, so there is no point in switching.");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1541,13 +1557,22 @@ int pa_sink_reconfigure(pa_sink *s, pa_sample_spec *spec, pa_channel_map *map, b
|
|||
/* We have to try to use the sink input spec */
|
||||
desired_spec = *spec;
|
||||
|
||||
} else if (avoid_processing) {
|
||||
desired_spec = s->sample_spec;
|
||||
|
||||
if (spec->rate >= default_rate || spec->rate >= alternate_rate)
|
||||
desired_spec.rate = spec->rate;
|
||||
if (spec->channels >= default_channels)
|
||||
desired_spec.channels = spec->channels;
|
||||
if (pa_sample_size_of_format(spec->format) >= pa_sample_size_of_format(default_format))
|
||||
desired_spec.format = spec->format;
|
||||
|
||||
} else if (avoid_resampling) {
|
||||
/* We just try to set the sink input's sample rate if it's not too low */
|
||||
desired_spec = s->sample_spec;
|
||||
|
||||
if (spec->rate >= default_rate || spec->rate >= alternate_rate)
|
||||
desired_spec.rate = spec->rate;
|
||||
/* FIXME: don't set this if it's too low */
|
||||
desired_spec.format = spec->format;
|
||||
|
||||
} else if (default_rate == spec->rate || alternate_rate == spec->rate) {
|
||||
/* We can directly try to use this rate */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue