#include <inttypes.h>
+#include <pulse/def.h>
+#include <pulse/format.h>
#include <pulse/sample.h>
#include <pulse/channelmap.h>
#include <pulse/volume.h>
#include <pulsecore/core.h>
#include <pulsecore/idxset.h>
-#include <pulsecore/memblock.h>
#include <pulsecore/memchunk.h>
#include <pulsecore/sink.h>
#include <pulsecore/module.h>
#include <pulsecore/asyncmsgq.h>
#include <pulsecore/msgobject.h>
#include <pulsecore/rtpoll.h>
-#include <pulsecore/source-output.h>
#include <pulsecore/card.h>
#include <pulsecore/queue.h>
#include <pulsecore/thread-mq.h>
+#include <pulsecore/source-output.h>
#define PA_MAX_OUTPUTS_PER_SOURCE 32
return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE || x == PA_SOURCE_SUSPENDED;
}
+/* A generic definition for void callback functions */
+typedef void(*pa_source_cb_t)(pa_source *s);
+
struct pa_source {
pa_msgobject parent;
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;
pa_bool_t save_volume:1;
pa_bool_t save_muted:1;
+ /* Saved volume state while we're in passthrough mode */
+ pa_cvolume saved_volume;
+ pa_bool_t saved_save_volume:1;
+
pa_asyncmsgq *asyncmsgq;
pa_memchunk silence;
* inhibited */
int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */
- /* Callled when the volume is queried. Called from main loop
+ /* Called when the volume is queried. Called from main loop
* context. If this is NULL a PA_SOURCE_MESSAGE_GET_VOLUME message
* will be sent to the IO thread instead. If refresh_volume is
- * FALSE neither this function is called nor a message is sent. */
- void (*get_volume)(pa_source *s); /* ditto */
+ * FALSE neither this function is called nor a message is sent.
+ *
+ * You must use the function pa_source_set_get_volume_callback() to
+ * set this callback. */
+ pa_source_cb_t get_volume; /* may be NULL */
/* Called when the volume shall be changed. Called from main loop
* context. If this is NULL a PA_SOURCE_MESSAGE_SET_VOLUME message
- * will be sent to the IO thread instead. */
- void (*set_volume)(pa_source *s); /* ditto */
+ * will be sent to the IO thread instead.
+ *
+ * You must use the function pa_source_set_set_volume_callback() to
+ * set this callback. */
+ pa_source_cb_t set_volume; /* may be NULL */
- /* Source drivers that set PA_SOURCE_SYNC_VOLUME must provide this
+ /* Source drivers that set PA_SOURCE_DEFERRED_VOLUME must provide this
* callback. This callback is not used with source that do not set
- * PA_SOURCE_SYNC_VOLUME. This is called from the IO thread when a
+ * PA_SOURCE_DEFERRED_VOLUME. This is called from the IO thread when a
* pending hardware volume change has to be written to the
* hardware. The requested volume is passed to the callback
* implementation in s->thread_info.current_hw_volume.
* The call is done inside pa_source_volume_change_apply(), which is
* not called automatically - it is the driver's responsibility to
* schedule that function to be called at the right times in the
- * IO thread. */
- void (*write_volume)(pa_source *s); /* ditto */
+ * IO thread.
+ *
+ * You must use the function pa_source_set_write_volume_callback() to
+ * set this callback. */
+ pa_source_cb_t write_volume; /* may be NULL */
/* Called when the mute setting is queried. Called from main loop
* context. If this is NULL a PA_SOURCE_MESSAGE_GET_MUTE message
* will be sent to the IO thread instead. If refresh_mute is
- * FALSE neither this function is called nor a message is sent.*/
- void (*get_mute)(pa_source *s); /* ditto */
+ * FALSE neither this function is called nor a message is sent.
+ *
+ * You must use the function pa_source_set_get_mute_callback() to
+ * set this callback. */
+ pa_source_cb_t get_mute; /* may be NULL */
/* Called when the mute setting shall be changed. Called from main
* loop context. If this is NULL a PA_SOURCE_MESSAGE_SET_MUTE
- * message will be sent to the IO thread instead. */
- void (*set_mute)(pa_source *s); /* ditto */
+ * message will be sent to the IO thread instead.
+ *
+ * You must use the function pa_source_set_set_mute_callback() to
+ * set this callback. */
+ pa_source_cb_t set_mute; /* may be NULL */
/* Called when a the requested latency is changed. Called from IO
* thread context. */
- void (*update_requested_latency)(pa_source *s); /* ditto */
+ pa_source_cb_t update_requested_latency; /* may be NULL */
/* Called whenever the port shall be changed. Called from main
* thread. */
* 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 {
PA_LLIST_HEAD(pa_source_volume_change, volume_changes);
pa_source_volume_change *volume_changes_tail;
/* This value is updated in pa_source_volume_change_apply() and
- * used only by sources with PA_SOURCE_SYNC_VOLUME. */
+ * used only by sources with PA_SOURCE_DEFERRED_VOLUME. */
pa_cvolume current_hw_volume;
/* The amount of usec volume up events are delayed and volume
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 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;
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);
pa_source_new_data *data,
pa_source_flags_t flags);
+void pa_source_set_get_volume_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_set_volume_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_write_volume_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_get_mute_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_set_mute_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_enable_decibel_volume(pa_source *s, pa_bool_t enable);
+
void pa_source_put(pa_source *s);
void pa_source_unlink(pa_source *s);
/* Use this instead of checking s->flags & PA_SOURCE_FLAT_VOLUME directly. */
pa_bool_t pa_source_flat_volume_enabled(pa_source *s);
+/* Get the master source when sharing volumes */
+pa_source *pa_source_get_master(pa_source *s);
+
/* Is the source in passthrough mode? (that is, is this a monitor source for a sink
* that has a passthrough sink input connected to it. */
pa_bool_t pa_source_is_passthrough(pa_source *s);
+/* These should be called when a source enters/leaves passthrough mode */
+void pa_source_enter_passthrough(pa_source *s);
+void pa_source_leave_passthrough(pa_source *s);
void pa_source_set_volume(pa_source *source, const pa_cvolume *volume, pa_bool_t sendmsg, pa_bool_t save);
const pa_cvolume *pa_source_get_volume(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, pa_bool_t passthrough);
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 */