#include <asoundlib.h>
#include <pulse/sample.h>
-#include <pulse/volume.h>
#include <pulse/mainloop-api.h>
#include <pulse/channelmap.h>
-#include <pulse/proplist.h>
#include <pulse/volume.h>
#include <pulsecore/llist.h>
#include <pulsecore/rtpoll.h>
-#include <pulsecore/core.h>
-#include <pulsecore/log.h>
typedef struct pa_alsa_fdlist pa_alsa_fdlist;
+typedef struct pa_alsa_mixer_pdata pa_alsa_mixer_pdata;
typedef struct pa_alsa_setting pa_alsa_setting;
typedef struct pa_alsa_option pa_alsa_option;
typedef struct pa_alsa_element pa_alsa_element;
typedef struct pa_alsa_path_set pa_alsa_path_set;
typedef struct pa_alsa_mapping pa_alsa_mapping;
typedef struct pa_alsa_profile pa_alsa_profile;
+typedef struct pa_alsa_decibel_fix pa_alsa_decibel_fix;
typedef struct pa_alsa_profile_set pa_alsa_profile_set;
typedef struct pa_alsa_port_data pa_alsa_port_data;
typedef enum pa_alsa_volume_use {
PA_ALSA_VOLUME_IGNORE,
- PA_ALSA_VOLUME_MERGE, /* merge this volume slider into the global volume slider */
- PA_ALSA_VOLUME_OFF, /* set this volume to minimal unconditionally */
- PA_ALSA_VOLUME_ZERO /* set this volume to 0dB unconditionally */
+ PA_ALSA_VOLUME_MERGE, /* merge this volume slider into the global volume slider */
+ PA_ALSA_VOLUME_OFF, /* set this volume to minimal unconditionally */
+ PA_ALSA_VOLUME_ZERO, /* set this volume to 0dB unconditionally */
+ PA_ALSA_VOLUME_CONSTANT /* set this volume to a constant value unconditionally */
} pa_alsa_volume_use_t;
typedef enum pa_alsa_enumeration_use {
char *name;
char *description;
unsigned priority;
+
+ pa_alsa_required_t required;
+ pa_alsa_required_t required_any;
+ pa_alsa_required_t required_absent;
};
-/* And element wraps one specific ALSA element. A series of elements *
-make up a path (see below). If the element is an enumeration or switch
-* element it may includes a list of options. */
+/* An element wraps one specific ALSA element. A series of elements
+ * make up a path (see below). If the element is an enumeration or switch
+ * element it may include a list of options. */
struct pa_alsa_element {
pa_alsa_path *path;
PA_LLIST_FIELDS(pa_alsa_element);
pa_alsa_enumeration_use_t enumeration_use;
pa_alsa_required_t required;
+ pa_alsa_required_t required_any;
pa_alsa_required_t required_absent;
+ long constant_volume;
+
pa_bool_t override_map:1;
pa_bool_t direction_try_other:1;
pa_bool_t has_dB:1;
long min_volume, max_volume;
+ long volume_limit; /* -1 for no configured limit */
double min_dB, max_dB;
pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST][2];
pa_channel_position_mask_t merged_mask;
PA_LLIST_HEAD(pa_alsa_option, options);
+
+ pa_alsa_decibel_fix *db_fix;
};
/* A path wraps a series of elements into a single entity which can be
pa_bool_t has_mute:1;
pa_bool_t has_volume:1;
pa_bool_t has_dB:1;
+ /* These two are used during probing only */
+ pa_bool_t has_req_any:1;
+ pa_bool_t req_any_present:1;
long min_volume, max_volume;
double min_dB, max_dB;
void pa_alsa_element_dump(pa_alsa_element *e);
-pa_alsa_path *pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction);
+pa_alsa_path *pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction);
pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction);
int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB);
void pa_alsa_path_dump(pa_alsa_path *p);
int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t *muted);
-int pa_alsa_path_set_volume(pa_alsa_path *path, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
+int pa_alsa_path_set_volume(pa_alsa_path *path, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v, pa_bool_t deferred_volume, pa_bool_t write_to_hw);
int pa_alsa_path_set_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t muted);
int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m);
void pa_alsa_path_set_callback(pa_alsa_path *p, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
void pa_alsa_path_free(pa_alsa_path *p);
-pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction);
+pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction, const char *paths_dir);
void pa_alsa_path_set_probe(pa_alsa_path_set *s, snd_mixer_t *m, pa_bool_t ignore_dB);
void pa_alsa_path_set_dump(pa_alsa_path_set *s);
void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
pa_idxset *output_mappings;
};
+struct pa_alsa_decibel_fix {
+ pa_alsa_profile_set *profile_set;
+
+ char *name; /* Alsa volume element name. */
+ long min_step;
+ long max_step;
+
+ /* An array that maps alsa volume element steps to decibels. The steps can
+ * be used as indices to this array, after subtracting min_step from the
+ * real value.
+ *
+ * The values are actually stored as integers representing millibels,
+ * because that's the format the alsa API uses. */
+ long *db_values;
+};
+
struct pa_alsa_profile_set {
pa_hashmap *mappings;
pa_hashmap *profiles;
+ pa_hashmap *decibel_fixes;
pa_bool_t auto_profiles;
pa_bool_t probed:1;
void pa_alsa_mapping_dump(pa_alsa_mapping *m);
void pa_alsa_profile_dump(pa_alsa_profile *p);
+void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix);
pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus);
-void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss);
+void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec);
void pa_alsa_profile_set_free(pa_alsa_profile_set *s);
void pa_alsa_profile_set_dump(pa_alsa_profile_set *s);
void pa_alsa_fdlist_free(pa_alsa_fdlist *fdl);
int pa_alsa_fdlist_set_mixer(pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m);
+/* Alternative for handling alsa mixer events in io-thread. */
+
+pa_alsa_mixer_pdata *pa_alsa_mixer_pdata_new(void);
+void pa_alsa_mixer_pdata_free(pa_alsa_mixer_pdata *pd);
+int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer, pa_rtpoll *rtp);
+
/* Data structure for inclusion in pa_device_port for alsa
* sinks/sources. This contains nothing that needs to be freed
* individually */