]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/source-output.h
sink-input, source-output: Remove redundant get_mute() functions
[pulseaudio] / src / pulsecore / source-output.h
index a27602ecb40561107bad78b734894bed7afa5f71..73170d306f301187e09f72f71ce0c92d3cb8ec41 100644 (file)
@@ -8,7 +8,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
 typedef struct pa_source_output pa_source_output;
 
 #include <pulse/sample.h>
 typedef struct pa_source_output pa_source_output;
 
 #include <pulse/sample.h>
-#include <pulsecore/source.h>
+#include <pulse/format.h>
 #include <pulsecore/memblockq.h>
 #include <pulsecore/resampler.h>
 #include <pulsecore/module.h>
 #include <pulsecore/client.h>
 #include <pulsecore/memblockq.h>
 #include <pulsecore/resampler.h>
 #include <pulsecore/module.h>
 #include <pulsecore/client.h>
+#include <pulsecore/source.h>
+#include <pulsecore/core.h>
+#include <pulsecore/sink-input.h>
 
 typedef enum pa_source_output_state {
     PA_SOURCE_OUTPUT_INIT,
 
 typedef enum pa_source_output_state {
     PA_SOURCE_OUTPUT_INIT,
@@ -40,7 +43,7 @@ typedef enum pa_source_output_state {
     PA_SOURCE_OUTPUT_UNLINKED
 } pa_source_output_state_t;
 
     PA_SOURCE_OUTPUT_UNLINKED
 } pa_source_output_state_t;
 
-static inline pa_bool_t PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_state_t x) {
+static inline bool PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_state_t x) {
     return x == PA_SOURCE_OUTPUT_RUNNING || x == PA_SOURCE_OUTPUT_CORKED;
 }
 
     return x == PA_SOURCE_OUTPUT_RUNNING || x == PA_SOURCE_OUTPUT_CORKED;
 }
 
@@ -53,7 +56,10 @@ typedef enum pa_source_output_flags {
     PA_SOURCE_OUTPUT_FIX_FORMAT = 32,
     PA_SOURCE_OUTPUT_FIX_RATE = 64,
     PA_SOURCE_OUTPUT_FIX_CHANNELS = 128,
     PA_SOURCE_OUTPUT_FIX_FORMAT = 32,
     PA_SOURCE_OUTPUT_FIX_RATE = 64,
     PA_SOURCE_OUTPUT_FIX_CHANNELS = 128,
-    PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND = 256
+    PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
+    PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND = 512,
+    PA_SOURCE_OUTPUT_KILL_ON_SUSPEND = 1024,
+    PA_SOURCE_OUTPUT_PASSTHROUGH = 2048
 } pa_source_output_flags_t;
 
 struct pa_source_output {
 } pa_source_output_flags_t;
 
 struct pa_source_output {
@@ -71,15 +77,36 @@ struct pa_source_output {
     pa_module *module;                    /* may be NULL */
     pa_client *client;                    /* may be NULL */
 
     pa_module *module;                    /* may be NULL */
     pa_client *client;                    /* may be NULL */
 
-    pa_source *source; /* NULL while being moved */
+    pa_source *source;                    /* NULL while being moved */
+    pa_source *destination_source;        /* only set by filter sources */
 
     /* A source output can monitor just a single input of a sink, in which case we find it here */
     pa_sink_input *direct_on_input;       /* may be NULL */
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
 
     /* A source output can monitor just a single input of a sink, in which case we find it here */
     pa_sink_input *direct_on_input;       /* may be NULL */
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    pa_format_info *format;
 
 
-    pa_resample_method_t resample_method;
+    /* Also see http://pulseaudio.org/wiki/InternalVolumes */
+    pa_cvolume volume;             /* The volume clients are informed about */
+    pa_cvolume reference_ratio;    /* The ratio of the stream's volume to the source's reference volume */
+    pa_cvolume real_ratio;         /* The ratio of the stream's volume to the source's real volume */
+    pa_cvolume volume_factor;      /* An internally used volume factor that can be used by modules to apply effects and suchlike without having that visible to the outside */
+    pa_cvolume soft_volume;        /* The internal software volume we apply to all PCM data while it passes through. Usually calculated as real_ratio * volume_factor */
+
+    pa_cvolume volume_factor_source; /* A second volume factor in format of the source this stream is connected to */
+
+    bool volume_writable:1;
+
+    bool muted:1;
+
+    /* if true then the source we are connected to and/or the volume
+     * set is worth remembering, i.e. was explicitly chosen by the
+     * user and not automatically. module-stream-restore looks for
+     * this.*/
+    bool save_source:1, save_volume:1, save_muted:1;
+
+    pa_resample_method_t requested_resample_method, actual_resample_method;
 
     /* Pushes a new memchunk into the output. Called from IO thread
      * context. */
 
     /* Pushes a new memchunk into the output. Called from IO thread
      * context. */
@@ -97,31 +124,46 @@ struct pa_source_output {
      * changes. Called from IO context. */
     void (*update_source_requested_latency) (pa_source_output *o); /* may be NULL */
 
      * changes. Called from IO context. */
     void (*update_source_requested_latency) (pa_source_output *o); /* may be NULL */
 
-    /* Called whenver the latency range of the source changes. Called
+    /* Called whenever the latency range of the source changes. Called
      * from IO context. */
     void (*update_source_latency_range) (pa_source_output *o); /* may be NULL */
 
      * from IO context. */
     void (*update_source_latency_range) (pa_source_output *o); /* may be NULL */
 
+    /* Called whenever the fixed latency of the source changes, if there
+     * is one. Called from IO context. */
+    void (*update_source_fixed_latency) (pa_source_output *i); /* may be NULL */
+
     /* If non-NULL this function is called when the output is first
     /* If non-NULL this function is called when the output is first
-     * connected to a source. Called from IO thread context */
+     * connected to a source or when the rtpoll/asyncmsgq fields
+     * change. You usually don't need to implement this function
+     * unless you rewrite a source that is piggy-backed onto
+     * another. Called from IO thread context */
     void (*attach) (pa_source_output *o);           /* may be NULL */
 
     /* If non-NULL this function is called when the output is
      * disconnected from its source. Called from IO thread context */
     void (*detach) (pa_source_output *o);           /* may be NULL */
 
     void (*attach) (pa_source_output *o);           /* may be NULL */
 
     /* If non-NULL this function is called when the output is
      * disconnected from its source. Called from IO thread context */
     void (*detach) (pa_source_output *o);           /* may be NULL */
 
-    /* If non-NULL called whenever the the source this output is attached
+    /* If non-NULL called whenever the source this output is attached
      * to suspends or resumes. Called from main context */
      * to suspends or resumes. Called from main context */
-    void (*suspend) (pa_source_output *o, pa_bool_t b);   /* may be NULL */
+    void (*suspend) (pa_source_output *o, bool b);   /* may be NULL */
 
 
-    /* If non-NULL called whenever the the source this output is attached
-     * to changes. Called from main context */
-    void (*moved) (pa_source_output *o);   /* may be NULL */
+    /* If non-NULL called whenever the source this output is attached
+     * to suspends or resumes. Called from IO context */
+    void (*suspend_within_thread) (pa_source_output *o, bool b);   /* may be NULL */
+
+    /* If non-NULL called whenever the source output is moved to a new
+     * source. Called from main context after the source output has been
+     * detached from the old source and before it has been attached to
+     * the new source. If dest is NULL the move was executed in two
+     * phases and the second one failed; the stream will be destroyed
+     * after this call. */
+    void (*moving) (pa_source_output *o, pa_source *dest);   /* may be NULL */
 
     /* Supposed to unlink and destroy this stream. Called from main
      * context. */
     void (*kill)(pa_source_output* o);              /* may NOT be NULL */
 
 
     /* Supposed to unlink and destroy this stream. Called from main
      * context. */
     void (*kill)(pa_source_output* o);              /* may NOT be NULL */
 
-    /* Return the current latency (i.e. length of bufferd audio) of
+    /* Return the current latency (i.e. length of buffered audio) of
     this stream. Called from main context. This is added to what the
     PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY message sent to the IO thread
     returns */
     this stream. Called from main context. This is added to what the
     PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY message sent to the IO thread
     returns */
@@ -132,14 +174,29 @@ struct pa_source_output {
     void (*state_change) (pa_source_output *o, pa_source_output_state_t state); /* may be NULL */
 
     /* If non-NULL this function is called before this source output
     void (*state_change) (pa_source_output *o, pa_source_output_state_t state); /* may be NULL */
 
     /* If non-NULL this function is called before this source output
-     * is moved to a source and if it returns FALSE the move
+     * is moved to a source and if it returns false the move
      * will not be allowed */
      * will not be allowed */
-    pa_bool_t (*may_move_to) (pa_source_output *o, pa_source *s); /* may be NULL */
+    bool (*may_move_to) (pa_source_output *o, pa_source *s); /* may be NULL */
+
+    /* If non-NULL this function is used to dispatch asynchronous
+     * control events. */
+    void (*send_event)(pa_source_output *o, const char *event, pa_proplist* data);
+
+    /* If non-NULL this function is called whenever the source output
+     * volume changes. Called from main context */
+    void (*volume_changed)(pa_source_output *o); /* may be NULL */
+
+    /* If non-NULL this function is called whenever the source output
+     * mute status changes. Called from main context */
+    void (*mute_changed)(pa_source_output *o); /* may be NULL */
 
     struct {
         pa_source_output_state_t state;
 
 
     struct {
         pa_source_output_state_t state;
 
-        pa_bool_t attached; /* True only between ->attach() and ->detach() calls */
+        pa_cvolume soft_volume;
+        bool muted:1;
+
+        bool attached:1; /* True only between ->attach() and ->detach() calls */
 
         pa_sample_spec sample_spec;
 
 
         pa_sample_spec sample_spec;
 
@@ -158,7 +215,7 @@ struct pa_source_output {
     void *userdata;
 };
 
     void *userdata;
 };
 
-PA_DECLARE_CLASS(pa_source_output);
+PA_DECLARE_PUBLIC_CLASS(pa_source_output);
 #define PA_SOURCE_OUTPUT(o) pa_source_output_cast(o)
 
 enum {
 #define PA_SOURCE_OUTPUT(o) pa_source_output_cast(o)
 
 enum {
@@ -167,10 +224,20 @@ enum {
     PA_SOURCE_OUTPUT_MESSAGE_SET_STATE,
     PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY,
     PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY,
     PA_SOURCE_OUTPUT_MESSAGE_SET_STATE,
     PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY,
     PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY,
+    PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_VOLUME,
+    PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_MUTE,
     PA_SOURCE_OUTPUT_MESSAGE_MAX
 };
 
     PA_SOURCE_OUTPUT_MESSAGE_MAX
 };
 
+typedef struct pa_source_output_send_event_hook_data {
+    pa_source_output *source_output;
+    const char *event;
+    pa_proplist *data;
+} pa_source_output_send_event_hook_data;
+
 typedef struct pa_source_output_new_data {
 typedef struct pa_source_output_new_data {
+    pa_source_output_flags_t flags;
+
     pa_proplist *proplist;
     pa_sink_input *direct_on_input;
 
     pa_proplist *proplist;
     pa_sink_input *direct_on_input;
 
@@ -179,27 +246,50 @@ typedef struct pa_source_output_new_data {
     pa_client *client;
 
     pa_source *source;
     pa_client *client;
 
     pa_source *source;
+    pa_source *destination_source;
 
     pa_resample_method_t resample_method;
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
 
     pa_resample_method_t resample_method;
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    pa_format_info *format;
+    pa_idxset *req_formats;
+    pa_idxset *nego_formats;
+
+    pa_cvolume volume, volume_factor, volume_factor_source;
+    bool muted:1;
+
+    bool sample_spec_is_set:1;
+    bool channel_map_is_set:1;
+
+    bool volume_is_set:1, volume_factor_is_set:1, volume_factor_source_is_set:1;
+    bool muted_is_set:1;
+
+    bool volume_is_absolute:1;
 
 
-    pa_bool_t sample_spec_is_set:1;
-    pa_bool_t channel_map_is_set:1;
+    bool volume_writable:1;
+
+    bool save_source:1, save_volume:1, save_muted:1;
 } pa_source_output_new_data;
 
 pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);
 void pa_source_output_new_data_set_sample_spec(pa_source_output_new_data *data, const pa_sample_spec *spec);
 void pa_source_output_new_data_set_channel_map(pa_source_output_new_data *data, const pa_channel_map *map);
 } pa_source_output_new_data;
 
 pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);
 void pa_source_output_new_data_set_sample_spec(pa_source_output_new_data *data, const pa_sample_spec *spec);
 void pa_source_output_new_data_set_channel_map(pa_source_output_new_data *data, const pa_channel_map *map);
+bool pa_source_output_new_data_is_passthrough(pa_source_output_new_data *data);
+void pa_source_output_new_data_set_volume(pa_source_output_new_data *data, const pa_cvolume *volume);
+void pa_source_output_new_data_apply_volume_factor(pa_source_output_new_data *data, const pa_cvolume *volume_factor);
+void pa_source_output_new_data_apply_volume_factor_source(pa_source_output_new_data *data, const pa_cvolume *volume_factor);
+void pa_source_output_new_data_set_muted(pa_source_output_new_data *data, bool mute);
+bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, bool save);
+bool pa_source_output_new_data_set_formats(pa_source_output_new_data *data, pa_idxset *formats);
 void pa_source_output_new_data_done(pa_source_output_new_data *data);
 
 /* To be called by the implementing module only */
 
 void pa_source_output_new_data_done(pa_source_output_new_data *data);
 
 /* To be called by the implementing module only */
 
-pa_source_output* pa_source_output_new(
+int pa_source_output_new(
+        pa_source_output**o,
         pa_core *core,
         pa_core *core,
-        pa_source_output_new_data *data,
-        pa_source_output_flags_t flags);
+        pa_source_output_new_data *data);
 
 void pa_source_output_put(pa_source_output *o);
 void pa_source_output_unlink(pa_source_output*o);
 
 void pa_source_output_put(pa_source_output *o);
 void pa_source_output_unlink(pa_source_output*o);
@@ -208,30 +298,43 @@ void pa_source_output_set_name(pa_source_output *o, const char *name);
 
 pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t usec);
 
 
 pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t usec);
 
-void pa_source_output_cork(pa_source_output *o, pa_bool_t b);
+void pa_source_output_cork(pa_source_output *o, bool b);
 
 int pa_source_output_set_rate(pa_source_output *o, uint32_t rate);
 
 int pa_source_output_set_rate(pa_source_output *o, uint32_t rate);
+int pa_source_output_update_rate(pa_source_output *o);
+
+size_t pa_source_output_get_max_rewind(pa_source_output *o);
 
 /* Callable by everyone */
 
 
 /* Callable by everyone */
 
-/* External code may request disconnection with this funcion */
+/* External code may request disconnection with this function */
 void pa_source_output_kill(pa_source_output*o);
 
 pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_latency);
 
 void pa_source_output_kill(pa_source_output*o);
 
 pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_latency);
 
-pa_bool_t pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p);
+bool pa_source_output_is_volume_readable(pa_source_output *o);
+bool pa_source_output_is_passthrough(pa_source_output *o);
+void pa_source_output_set_volume(pa_source_output *o, const pa_cvolume *volume, bool save, bool absolute);
+pa_cvolume *pa_source_output_get_volume(pa_source_output *o, pa_cvolume *volume, bool absolute);
+
+void pa_source_output_set_mute(pa_source_output *o, bool mute, bool save);
+
+void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p);
 
 pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o);
 
 
 pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o);
 
-pa_bool_t pa_source_output_may_move(pa_source_output *o);
-pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest);
-int pa_source_output_move_to(pa_source_output *o, pa_source *dest);
+void pa_source_output_send_event(pa_source_output *o, const char *name, pa_proplist *data);
 
 
-/* The same as pa_source_output_move_to() but in two seperate steps,
+bool pa_source_output_may_move(pa_source_output *o);
+bool pa_source_output_may_move_to(pa_source_output *o, pa_source *dest);
+int pa_source_output_move_to(pa_source_output *o, pa_source *dest, bool save);
+
+/* The same as pa_source_output_move_to() but in two separate steps,
  * first the detaching from the old source, then the attaching to the
  * new source */
 int pa_source_output_start_move(pa_source_output *o);
  * first the detaching from the old source, then the attaching to the
  * new source */
 int pa_source_output_start_move(pa_source_output *o);
-int pa_source_output_finish_move(pa_source_output *o, pa_source *dest);
+int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, bool save);
+void pa_source_output_fail_move(pa_source_output *o);
 
 #define pa_source_output_get_state(o) ((o)->state)
 
 
 #define pa_source_output_get_state(o) ((o)->state)
 
@@ -249,4 +352,14 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int
 
 pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output *o, pa_usec_t usec);
 
 
 pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output *o, pa_usec_t usec);
 
+/* Called from the main thread, from source.c only. The normal way to set the
+ * source output volume is to call pa_source_output_set_volume(), but the flat
+ * volume logic in source.c needs also a function that doesn't do all the extra
+ * stuff that pa_source_output_set_volume() does. This function simply sets
+ * o->volume and fires change notifications. */
+void pa_source_output_set_volume_direct(pa_source_output *o, const pa_cvolume *volume);
+
+#define pa_source_output_assert_io_context(s) \
+    pa_assert(pa_thread_mq_get() || !PA_SOURCE_OUTPUT_IS_LINKED((s)->state))
+
 #endif
 #endif