mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2026-03-15 05:33:56 -04:00
sink,source: support for rate update
Avoid resampling or use integer resampling when supported by the sinks/sources Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
This commit is contained in:
parent
5bcfd2b630
commit
f0ec495938
7 changed files with 219 additions and 0 deletions
|
|
@ -106,6 +106,13 @@ void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_m
|
|||
data->channel_map = *map;
|
||||
}
|
||||
|
||||
void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const uint32_t alternate_sample_rate) {
|
||||
pa_assert(data);
|
||||
|
||||
data->alternate_sample_rate_is_set = TRUE;
|
||||
data->alternate_sample_rate = alternate_sample_rate;
|
||||
}
|
||||
|
||||
void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {
|
||||
pa_assert(data);
|
||||
|
||||
|
|
@ -182,6 +189,7 @@ static void reset_callbacks(pa_sink *s) {
|
|||
s->set_port = NULL;
|
||||
s->get_formats = NULL;
|
||||
s->set_formats = NULL;
|
||||
s->update_rate = NULL;
|
||||
}
|
||||
|
||||
/* Called from main context */
|
||||
|
|
@ -277,6 +285,11 @@ pa_sink* pa_sink_new(
|
|||
|
||||
s->sample_spec = data->sample_spec;
|
||||
s->channel_map = data->channel_map;
|
||||
if (data->alternate_sample_rate_is_set)
|
||||
s->alternate_sample_rate = data->alternate_sample_rate;
|
||||
else
|
||||
s->alternate_sample_rate = s->core->alternate_sample_rate;
|
||||
s->default_sample_rate = s->sample_spec.rate;
|
||||
|
||||
s->inputs = pa_idxset_new(NULL, NULL);
|
||||
s->n_corked = 0;
|
||||
|
|
@ -364,6 +377,7 @@ pa_sink* pa_sink_new(
|
|||
pa_source_new_data_init(&source_data);
|
||||
pa_source_new_data_set_sample_spec(&source_data, &s->sample_spec);
|
||||
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);
|
||||
source_data.name = pa_sprintf_malloc("%s.monitor", name);
|
||||
source_data.driver = data->driver;
|
||||
source_data.module = data->module;
|
||||
|
|
@ -1312,6 +1326,69 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
|
|||
pa_sink_unref(s);
|
||||
}
|
||||
|
||||
/* Called from main thread */
|
||||
pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough)
|
||||
{
|
||||
if (s->update_rate) {
|
||||
uint32_t desired_rate = rate;
|
||||
uint32_t default_rate = s->default_sample_rate;
|
||||
uint32_t alternate_rate = s->alternate_sample_rate;
|
||||
pa_bool_t use_alternate = FALSE;
|
||||
|
||||
if (PA_SINK_IS_RUNNING(s->state)) {
|
||||
pa_log_info("Cannot update rate, SINK_IS_RUNNING, will keep using %u kHz",
|
||||
s->sample_spec.rate);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (s->monitor_source) {
|
||||
if (PA_SOURCE_IS_RUNNING(s->monitor_source->state) == TRUE) {
|
||||
pa_log_info("Cannot update rate, monitor source is RUNNING");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (PA_UNLIKELY (desired_rate < 8000 ||
|
||||
desired_rate > PA_RATE_MAX))
|
||||
return FALSE;
|
||||
|
||||
if (!passthrough) {
|
||||
pa_assert(default_rate % 4000 || default_rate % 11025);
|
||||
pa_assert(alternate_rate % 4000 || alternate_rate % 11025);
|
||||
|
||||
if (default_rate % 4000) {
|
||||
/* default is a 11025 multiple */
|
||||
if ((alternate_rate % 4000 == 0) && (desired_rate % 4000 == 0))
|
||||
use_alternate=TRUE;
|
||||
} else {
|
||||
/* default is 4000 multiple */
|
||||
if ((alternate_rate % 11025 == 0) && (desired_rate % 11025 == 0))
|
||||
use_alternate=TRUE;
|
||||
}
|
||||
|
||||
if (use_alternate)
|
||||
desired_rate = alternate_rate;
|
||||
else
|
||||
desired_rate = default_rate;
|
||||
} else {
|
||||
desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
|
||||
}
|
||||
|
||||
if (passthrough || pa_sink_used_by(s) == 0) {
|
||||
pa_sink_suspend(s, TRUE, PA_SUSPEND_IDLE); /* needed before rate update, will be resumed automatically */
|
||||
}
|
||||
|
||||
if (s->update_rate(s, desired_rate) == TRUE) {
|
||||
/* update monitor source as well */
|
||||
if (s->monitor_source)
|
||||
pa_source_update_rate(s->monitor_source, desired_rate);
|
||||
pa_log_info("Changed sampling rate successfully");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Called from main thread */
|
||||
pa_usec_t pa_sink_get_latency(pa_sink *s) {
|
||||
pa_usec_t usec = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue