]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/source.h
sink, source: Add a latency offset which is inherited from the port
[pulseaudio] / src / pulsecore / source.h
index 902cc0366d025b7a788cd05e7e40189a0b6bd424..da024e654f6f0fc3db5da6291799a2e97cded4ba 100644 (file)
@@ -28,23 +28,25 @@ typedef struct pa_source_volume_change pa_source_volume_change;
 
 #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/device-port.h>
 #include <pulsecore/queue.h>
 #include <pulsecore/thread-mq.h>
+#include <pulsecore/source-output.h>
 
 #define PA_MAX_OUTPUTS_PER_SOURCE 32
 
@@ -53,6 +55,9 @@ static inline pa_bool_t PA_SOURCE_IS_LINKED(pa_source_state_t x) {
     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;
 
@@ -72,6 +77,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;
@@ -94,12 +101,20 @@ struct pa_source {
     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;
 
     pa_hashmap *ports;
     pa_device_port *active_port;
+    pa_atomic_t mixer_dirty;
+
+    /* The latency offset is inherited from the currently active port */
+    pa_usec_t latency_offset;
 
     unsigned priority;
 
@@ -108,20 +123,26 @@ struct pa_source {
      * 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.
@@ -129,32 +150,45 @@ struct pa_source {
      * 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. */
+    /* Called whenever the port shall be changed. Called from IO
+     * thread if deferred volumes are enabled, and main thread otherwise. */
     int (*set_port)(pa_source *s, pa_device_port *port); /*ditto */
 
     /* Called to get the list of formats supported by the source, sorted
      * 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 {
@@ -178,13 +212,16 @@ struct pa_source {
 
         pa_usec_t fixed_latency; /* for sources with PA_SOURCE_DYNAMIC_LATENCY this is 0 */
 
+        /* This latency offset is a direct copy from s->latency_offset */
+        pa_usec_t latency_offset;
+
         /* Delayed volume change events are queued here. The events
          * are stored in expiration order. The one expiring next is in
          * the head of the list. */
         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
@@ -223,6 +260,7 @@ typedef enum pa_source_message {
     PA_SOURCE_MESSAGE_SET_MAX_REWIND,
     PA_SOURCE_MESSAGE_SET_PORT,
     PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE,
+    PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET,
     PA_SOURCE_MESSAGE_MAX
 } pa_source_message_t;
 
@@ -239,6 +277,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;
 
@@ -246,6 +285,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;
 
@@ -258,6 +298,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);
@@ -270,6 +311,13 @@ pa_source* pa_source_new(
         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);
 
@@ -294,6 +342,8 @@ void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flag
 
 /*** May be called by everyone, from main context */
 
+void pa_source_set_latency_offset(pa_source *s, pa_usec_t offset);
+
 /* The returned value is supposed to be in the time domain of the sound card! */
 pa_usec_t pa_source_get_latency(pa_source *s);
 pa_usec_t pa_source_get_requested_latency(pa_source *s);
@@ -309,9 +359,15 @@ int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t caus
 /* 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);
@@ -322,6 +378,9 @@ 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);
+void pa_source_set_mixer_dirty(pa_source *s, pa_bool_t is_dirty);
+
+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 */