mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05: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
				
			
		| 
						 | 
				
			
			@ -826,6 +826,11 @@ static inline int PA_SINK_IS_OPENED(pa_sink_state_t x) {
 | 
			
		|||
    return x == PA_SINK_RUNNING || x == PA_SINK_IDLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Returns non-zero if sink is running. \since 1.0 */
 | 
			
		||||
static inline int PA_SINK_IS_RUNNING(pa_sink_state_t x) {
 | 
			
		||||
    return x == PA_SINK_RUNNING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** \cond fulldocs */
 | 
			
		||||
#define PA_SINK_INVALID_STATE PA_SINK_INVALID_STATE
 | 
			
		||||
#define PA_SINK_RUNNING PA_SINK_RUNNING
 | 
			
		||||
| 
						 | 
				
			
			@ -937,6 +942,11 @@ static inline int PA_SOURCE_IS_OPENED(pa_source_state_t x) {
 | 
			
		|||
    return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Returns non-zero if source is running \since 1.0 */
 | 
			
		||||
static inline int PA_SOURCE_IS_RUNNING(pa_source_state_t x) {
 | 
			
		||||
    return x == PA_SOURCE_RUNNING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** \cond fulldocs */
 | 
			
		||||
#define PA_SOURCE_INVALID_STATE PA_SOURCE_INVALID_STATE
 | 
			
		||||
#define PA_SOURCE_RUNNING PA_SOURCE_RUNNING
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -367,6 +367,19 @@ int pa_sink_input_new(
 | 
			
		|||
    pa_assert(pa_sample_spec_valid(&data->sample_spec));
 | 
			
		||||
    pa_assert(pa_channel_map_valid(&data->channel_map));
 | 
			
		||||
 | 
			
		||||
    if (!(data->flags & PA_SINK_INPUT_VARIABLE_RATE) &&
 | 
			
		||||
        !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec)) {
 | 
			
		||||
        /* try to change sink rate. This is done before the FIXATE hook since
 | 
			
		||||
           module-suspend-on-idle can resume a sink */
 | 
			
		||||
 | 
			
		||||
        pa_log_info("Trying to change sample rate");
 | 
			
		||||
        if (pa_sink_update_rate(data->sink, data->sample_spec.rate, pa_sink_input_new_data_is_passthrough(data)) == TRUE)
 | 
			
		||||
            pa_log_info("Rate changed to %u kHz",
 | 
			
		||||
                        data->sink->sample_spec.rate);
 | 
			
		||||
        else
 | 
			
		||||
            pa_log_info("Resampling enabled to %u kHz", data->sink->sample_spec.rate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Due to the fixing of the sample spec the volume might not match anymore */
 | 
			
		||||
    pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1605,6 +1618,21 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
 | 
			
		|||
        return -PA_ERR_NOTSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(i->flags & PA_SINK_INPUT_VARIABLE_RATE) &&
 | 
			
		||||
        !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec)) {
 | 
			
		||||
        /* try to change dest sink rate if possible without glitches.
 | 
			
		||||
           module-suspend-on-idle resumes destination sink with
 | 
			
		||||
           SINK_INPUT_MOVE_FINISH hook */
 | 
			
		||||
 | 
			
		||||
        pa_log_info("Trying to change sample rate");
 | 
			
		||||
        if (pa_sink_update_rate(dest, i->sample_spec.rate, pa_sink_input_is_passthrough(i)) == TRUE)
 | 
			
		||||
            pa_log_info("Rate changed to %u kHz",
 | 
			
		||||
                        dest->sample_spec.rate);
 | 
			
		||||
        else
 | 
			
		||||
            pa_log_info("Resampling enabled to %u kHz",
 | 
			
		||||
                        dest->sample_spec.rate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (i->thread_info.resampler &&
 | 
			
		||||
        pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
 | 
			
		||||
        pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,6 +88,8 @@ struct pa_sink {
 | 
			
		|||
 | 
			
		||||
    pa_sample_spec sample_spec;
 | 
			
		||||
    pa_channel_map channel_map;
 | 
			
		||||
    uint32_t default_sample_rate;
 | 
			
		||||
    uint32_t alternate_sample_rate;
 | 
			
		||||
 | 
			
		||||
    pa_idxset *inputs;
 | 
			
		||||
    unsigned n_corked;
 | 
			
		||||
| 
						 | 
				
			
			@ -233,6 +235,10 @@ struct pa_sink {
 | 
			
		|||
     * set). Makes a copy of the formats passed in. */
 | 
			
		||||
    pa_bool_t (*set_formats)(pa_sink *s, pa_idxset *formats); /* may be NULL */
 | 
			
		||||
 | 
			
		||||
    /* Called whenever the sampling frequency shall be changed. Called from
 | 
			
		||||
     * main thread. */
 | 
			
		||||
    pa_bool_t (*update_rate)(pa_sink *s, uint32_t rate);
 | 
			
		||||
 | 
			
		||||
    /* Contains copies of the above data so that the real-time worker
 | 
			
		||||
     * thread can work without access locking */
 | 
			
		||||
    struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -337,11 +343,13 @@ typedef struct pa_sink_new_data {
 | 
			
		|||
 | 
			
		||||
    pa_sample_spec sample_spec;
 | 
			
		||||
    pa_channel_map channel_map;
 | 
			
		||||
    uint32_t alternate_sample_rate;
 | 
			
		||||
    pa_cvolume volume;
 | 
			
		||||
    pa_bool_t muted :1;
 | 
			
		||||
 | 
			
		||||
    pa_bool_t sample_spec_is_set:1;
 | 
			
		||||
    pa_bool_t channel_map_is_set:1;
 | 
			
		||||
    pa_bool_t alternate_sample_rate_is_set:1;
 | 
			
		||||
    pa_bool_t volume_is_set:1;
 | 
			
		||||
    pa_bool_t muted_is_set:1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -356,6 +364,7 @@ pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data);
 | 
			
		|||
void pa_sink_new_data_set_name(pa_sink_new_data *data, const char *name);
 | 
			
		||||
void pa_sink_new_data_set_sample_spec(pa_sink_new_data *data, const pa_sample_spec *spec);
 | 
			
		||||
void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_map *map);
 | 
			
		||||
void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const uint32_t alternate_sample_rate);
 | 
			
		||||
void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume);
 | 
			
		||||
void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute);
 | 
			
		||||
void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port);
 | 
			
		||||
| 
						 | 
				
			
			@ -403,6 +412,8 @@ unsigned pa_device_init_priority(pa_proplist *p);
 | 
			
		|||
 | 
			
		||||
/**** May be called by everyone, from main context */
 | 
			
		||||
 | 
			
		||||
pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough);
 | 
			
		||||
 | 
			
		||||
/* The returned value is supposed to be in the time domain of the sound card! */
 | 
			
		||||
pa_usec_t pa_sink_get_latency(pa_sink *s);
 | 
			
		||||
pa_usec_t pa_sink_get_requested_latency(pa_sink *s);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -348,6 +348,15 @@ int pa_source_output_new(
 | 
			
		|||
    /* Due to the fixing of the sample spec the volume might not match anymore */
 | 
			
		||||
    pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
 | 
			
		||||
 | 
			
		||||
    if (!(data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) &&
 | 
			
		||||
        !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec)){
 | 
			
		||||
        /* try to change source rate. This is done before the FIXATE hook since
 | 
			
		||||
           module-suspend-on-idle can resume a source */
 | 
			
		||||
 | 
			
		||||
        pa_log_info("Trying to change sample rate");
 | 
			
		||||
        pa_source_update_rate(data->source, data->sample_spec.rate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (data->resample_method == PA_RESAMPLER_INVALID)
 | 
			
		||||
        data->resample_method = core->resample_method;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1385,6 +1394,21 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t
 | 
			
		|||
        return -PA_ERR_NOTSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) &&
 | 
			
		||||
        !pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec)){
 | 
			
		||||
        /* try to change dest sink rate if possible without glitches.
 | 
			
		||||
           module-suspend-on-idle resumes destination source with
 | 
			
		||||
           SOURCE_OUTPUT_MOVE_FINISH hook */
 | 
			
		||||
 | 
			
		||||
        pa_log_info("Trying to change sample rate");
 | 
			
		||||
        if (pa_source_update_rate(dest, o->sample_spec.rate) == TRUE)
 | 
			
		||||
            pa_log_info("Rate changed to %u kHz",
 | 
			
		||||
                        dest->sample_spec.rate);
 | 
			
		||||
        else
 | 
			
		||||
            pa_log_info("Resampling enabled to %u kHz",
 | 
			
		||||
                        dest->sample_spec.rate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (o->thread_info.resampler &&
 | 
			
		||||
        pa_sample_spec_equal(pa_resampler_input_sample_spec(o->thread_info.resampler), &dest->sample_spec) &&
 | 
			
		||||
        pa_channel_map_equal(pa_resampler_input_channel_map(o->thread_info.resampler), &dest->channel_map))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,6 +98,13 @@ void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_chann
 | 
			
		|||
        data->channel_map = *map;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pa_source_new_data_set_alternate_sample_rate(pa_source_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_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume) {
 | 
			
		||||
    pa_assert(data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +157,7 @@ static void reset_callbacks(pa_source *s) {
 | 
			
		|||
    s->update_requested_latency = NULL;
 | 
			
		||||
    s->set_port = NULL;
 | 
			
		||||
    s->get_formats = NULL;
 | 
			
		||||
    s->update_rate = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called from main context */
 | 
			
		||||
| 
						 | 
				
			
			@ -243,6 +251,11 @@ pa_source* pa_source_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->outputs = pa_idxset_new(NULL, NULL);
 | 
			
		||||
    s->n_corked = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -907,6 +920,52 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *
 | 
			
		|||
        pa_source_output_push(o, chunk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called from main thread */
 | 
			
		||||
pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    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_SOURCE_IS_RUNNING(s->state)) {
 | 
			
		||||
            pa_log_info("Cannot update rate, SOURCE_IS_RUNNING, will keep using %u kHz",
 | 
			
		||||
                        s->sample_spec.rate);
 | 
			
		||||
            return FALSE; /* cannot reconfigure a RUNNING source without glitches */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (PA_UNLIKELY (desired_rate < 8000 ||
 | 
			
		||||
                         desired_rate > PA_RATE_MAX))
 | 
			
		||||
            return FALSE;
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
        if (s->update_rate(s, desired_rate) == TRUE) {
 | 
			
		||||
            pa_log_info("Changed sampling rate successfully ");
 | 
			
		||||
            return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called from main thread */
 | 
			
		||||
pa_usec_t pa_source_get_latency(pa_source *s) {
 | 
			
		||||
    pa_usec_t usec;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,8 @@ struct pa_source {
 | 
			
		|||
 | 
			
		||||
    pa_sample_spec sample_spec;
 | 
			
		||||
    pa_channel_map channel_map;
 | 
			
		||||
    uint32_t default_sample_rate;
 | 
			
		||||
    uint32_t alternate_sample_rate;
 | 
			
		||||
 | 
			
		||||
    pa_idxset *outputs;
 | 
			
		||||
    unsigned n_corked;
 | 
			
		||||
| 
						 | 
				
			
			@ -178,6 +180,10 @@ struct pa_source {
 | 
			
		|||
     * in descending order of preference. */
 | 
			
		||||
    pa_idxset* (*get_formats)(pa_source *s); /* ditto */
 | 
			
		||||
 | 
			
		||||
    /* Called whenever the sampling frequency shall be changed. Called from
 | 
			
		||||
     * main thread. */
 | 
			
		||||
    pa_bool_t (*update_rate)(pa_source *s, uint32_t rate);
 | 
			
		||||
 | 
			
		||||
    /* Contains copies of the above data so that the real-time worker
 | 
			
		||||
     * thread can work without access locking */
 | 
			
		||||
    struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -262,6 +268,7 @@ typedef struct pa_source_new_data {
 | 
			
		|||
 | 
			
		||||
    pa_sample_spec sample_spec;
 | 
			
		||||
    pa_channel_map channel_map;
 | 
			
		||||
    uint32_t alternate_sample_rate;
 | 
			
		||||
    pa_cvolume volume;
 | 
			
		||||
    pa_bool_t muted:1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -269,6 +276,7 @@ typedef struct pa_source_new_data {
 | 
			
		|||
    pa_bool_t muted_is_set:1;
 | 
			
		||||
    pa_bool_t sample_spec_is_set:1;
 | 
			
		||||
    pa_bool_t channel_map_is_set:1;
 | 
			
		||||
    pa_bool_t alternate_sample_rate_is_set:1;
 | 
			
		||||
 | 
			
		||||
    pa_bool_t namereg_fail:1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -281,6 +289,7 @@ pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data);
 | 
			
		|||
void pa_source_new_data_set_name(pa_source_new_data *data, const char *name);
 | 
			
		||||
void pa_source_new_data_set_sample_spec(pa_source_new_data *data, const pa_sample_spec *spec);
 | 
			
		||||
void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_channel_map *map);
 | 
			
		||||
void pa_source_new_data_set_alternate_sample_rate(pa_source_new_data *data, const uint32_t alternate_sample_rate);
 | 
			
		||||
void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume);
 | 
			
		||||
void pa_source_new_data_set_muted(pa_source_new_data *data, pa_bool_t mute);
 | 
			
		||||
void pa_source_new_data_set_port(pa_source_new_data *data, const char *port);
 | 
			
		||||
| 
						 | 
				
			
			@ -358,6 +367,7 @@ pa_bool_t pa_source_get_mute(pa_source *source, pa_bool_t force_refresh);
 | 
			
		|||
pa_bool_t pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist *p);
 | 
			
		||||
 | 
			
		||||
int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save);
 | 
			
		||||
pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate);
 | 
			
		||||
 | 
			
		||||
unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */
 | 
			
		||||
unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue