summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/source.h
diff options
context:
space:
mode:
authorColin Guthrie <colin@mageia.org>2011-05-17 22:31:10 +0100
committerColin Guthrie <colin@mageia.org>2011-06-22 22:45:27 +0100
commitdffc4d18d3a9f608f8b316f1e7057d13978ef44f (patch)
tree2967eec64a3884b1b2ae5b7e5f59fafc92097ebf /src/pulsecore/source.h
parentfdf3a0881445560e962924a02319fc5cd2506231 (diff)
capture: Implement per-stream volume control for capture streams.
This piggy backs onto the previous changes for protocol 22 and thus does not bump the version. This and the previous commits should be seen as mostly atomic. Apologies for any bisecting issues this causes (although I would expect these to be minimal)
Diffstat (limited to 'src/pulsecore/source.h')
-rw-r--r--src/pulsecore/source.h50
1 files changed, 47 insertions, 3 deletions
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index 3cdc77ae..902cc036 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -24,6 +24,7 @@
***/
typedef struct pa_source pa_source;
+typedef struct pa_source_volume_change pa_source_volume_change;
#include <inttypes.h>
@@ -80,12 +81,15 @@ struct pa_source {
pa_volume_t base_volume; /* shall be constant */
unsigned n_volume_steps; /* shall be constant */
- pa_cvolume volume, soft_volume;
+ /* Also see http://pulseaudio.org/wiki/InternalVolumes */
+ pa_cvolume reference_volume; /* The volume exported and taken as reference base for relative source output volumes */
+ pa_cvolume real_volume; /* The volume that the hardware is configured to */
+ pa_cvolume soft_volume; /* The internal software volume we apply to all PCM data while it passes through */
+
pa_bool_t muted:1;
pa_bool_t refresh_volume:1;
pa_bool_t refresh_muted:1;
-
pa_bool_t save_port:1;
pa_bool_t save_volume:1;
pa_bool_t save_muted:1;
@@ -115,6 +119,19 @@ struct pa_source {
* will be sent to the IO thread instead. */
void (*set_volume)(pa_source *s); /* ditto */
+ /* Source drivers that set PA_SOURCE_SYNC_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
+ * 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 */
+
/* 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
@@ -160,6 +177,21 @@ struct pa_source {
pa_usec_t max_latency; /* An upper limit for the latencies */
pa_usec_t fixed_latency; /* for sources with PA_SOURCE_DYNAMIC_LATENCY this is 0 */
+
+ /* 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. */
+ pa_cvolume current_hw_volume;
+
+ /* The amount of usec volume up events are delayed and volume
+ * down events are made earlier. */
+ uint32_t volume_change_safety_margin;
+ /* Usec delay added to all volume change events, may be negative. */
+ int32_t volume_change_extra_delay;
} thread_info;
void *userdata;
@@ -172,7 +204,10 @@ typedef enum pa_source_message {
PA_SOURCE_MESSAGE_ADD_OUTPUT,
PA_SOURCE_MESSAGE_REMOVE_OUTPUT,
PA_SOURCE_MESSAGE_GET_VOLUME,
+ PA_SOURCE_MESSAGE_SET_SHARED_VOLUME,
+ PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED,
PA_SOURCE_MESSAGE_SET_VOLUME,
+ PA_SOURCE_MESSAGE_SYNC_VOLUMES,
PA_SOURCE_MESSAGE_GET_MUTE,
PA_SOURCE_MESSAGE_SET_MUTE,
PA_SOURCE_MESSAGE_GET_LATENCY,
@@ -186,6 +221,8 @@ typedef enum pa_source_message {
PA_SOURCE_MESSAGE_GET_FIXED_LATENCY,
PA_SOURCE_MESSAGE_GET_MAX_REWIND,
PA_SOURCE_MESSAGE_SET_MAX_REWIND,
+ PA_SOURCE_MESSAGE_SET_PORT,
+ PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE,
PA_SOURCE_MESSAGE_MAX
} pa_source_message_t;
@@ -269,11 +306,14 @@ int pa_source_update_status(pa_source*s);
int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause);
int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause);
+/* Use this instead of checking s->flags & PA_SOURCE_FLAT_VOLUME directly. */
+pa_bool_t pa_source_flat_volume_enabled(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);
-void pa_source_set_volume(pa_source *source, const pa_cvolume *volume, pa_bool_t save);
+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);
void pa_source_set_mute(pa_source *source, pa_bool_t mute, pa_bool_t save);
@@ -315,6 +355,10 @@ void pa_source_set_max_rewind_within_thread(pa_source *s, size_t max_rewind);
void pa_source_set_latency_range_within_thread(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency);
void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency);
+void pa_source_update_volume_and_mute(pa_source *s);
+
+pa_bool_t pa_source_volume_change_apply(pa_source *s, pa_usec_t *usec_to_next);
+
/*** To be called exclusively by source output drivers, from IO context */
void pa_source_invalidate_requested_latency(pa_source *s, pa_bool_t dynamic);