]> code.delx.au - pulseaudio/blob - src/modules/alsa/alsa-mixer.h
volume: Rename 'sync volume' to 'deferred volume'.
[pulseaudio] / src / modules / alsa / alsa-mixer.h
1 #ifndef fooalsamixerhfoo
2 #define fooalsamixerhfoo
3
4 /***
5 This file is part of PulseAudio.
6
7 Copyright 2004-2006 Lennart Poettering
8 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9
10 PulseAudio is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published
12 by the Free Software Foundation; either version 2.1 of the License,
13 or (at your option) any later version.
14
15 PulseAudio is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with PulseAudio; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 USA.
24 ***/
25
26 #include <asoundlib.h>
27
28 #include <pulse/sample.h>
29 #include <pulse/mainloop-api.h>
30 #include <pulse/channelmap.h>
31 #include <pulse/volume.h>
32
33 #include <pulsecore/llist.h>
34 #include <pulsecore/rtpoll.h>
35
36 typedef struct pa_alsa_fdlist pa_alsa_fdlist;
37 typedef struct pa_alsa_mixer_pdata pa_alsa_mixer_pdata;
38 typedef struct pa_alsa_setting pa_alsa_setting;
39 typedef struct pa_alsa_option pa_alsa_option;
40 typedef struct pa_alsa_element pa_alsa_element;
41 typedef struct pa_alsa_path pa_alsa_path;
42 typedef struct pa_alsa_path_set pa_alsa_path_set;
43 typedef struct pa_alsa_mapping pa_alsa_mapping;
44 typedef struct pa_alsa_profile pa_alsa_profile;
45 typedef struct pa_alsa_decibel_fix pa_alsa_decibel_fix;
46 typedef struct pa_alsa_profile_set pa_alsa_profile_set;
47 typedef struct pa_alsa_port_data pa_alsa_port_data;
48
49 #include "alsa-util.h"
50
51 typedef enum pa_alsa_switch_use {
52 PA_ALSA_SWITCH_IGNORE,
53 PA_ALSA_SWITCH_MUTE, /* make this switch follow mute status */
54 PA_ALSA_SWITCH_OFF, /* set this switch to 'off' unconditionally */
55 PA_ALSA_SWITCH_ON, /* set this switch to 'on' unconditionally */
56 PA_ALSA_SWITCH_SELECT /* allow the user to select switch status through a setting */
57 } pa_alsa_switch_use_t;
58
59 typedef enum pa_alsa_volume_use {
60 PA_ALSA_VOLUME_IGNORE,
61 PA_ALSA_VOLUME_MERGE, /* merge this volume slider into the global volume slider */
62 PA_ALSA_VOLUME_OFF, /* set this volume to minimal unconditionally */
63 PA_ALSA_VOLUME_ZERO, /* set this volume to 0dB unconditionally */
64 PA_ALSA_VOLUME_CONSTANT /* set this volume to a constant value unconditionally */
65 } pa_alsa_volume_use_t;
66
67 typedef enum pa_alsa_enumeration_use {
68 PA_ALSA_ENUMERATION_IGNORE,
69 PA_ALSA_ENUMERATION_SELECT
70 } pa_alsa_enumeration_use_t;
71
72 typedef enum pa_alsa_required {
73 PA_ALSA_REQUIRED_IGNORE,
74 PA_ALSA_REQUIRED_SWITCH,
75 PA_ALSA_REQUIRED_VOLUME,
76 PA_ALSA_REQUIRED_ENUMERATION,
77 PA_ALSA_REQUIRED_ANY
78 } pa_alsa_required_t;
79
80 typedef enum pa_alsa_direction {
81 PA_ALSA_DIRECTION_ANY,
82 PA_ALSA_DIRECTION_OUTPUT,
83 PA_ALSA_DIRECTION_INPUT
84 } pa_alsa_direction_t;
85
86 /* A setting combines a couple of options into a single entity that
87 * may be selected. Only one setting can be active at the same
88 * time. */
89 struct pa_alsa_setting {
90 pa_alsa_path *path;
91 PA_LLIST_FIELDS(pa_alsa_setting);
92
93 pa_idxset *options;
94
95 char *name;
96 char *description;
97 unsigned priority;
98 };
99
100 /* An option belongs to an element and refers to one enumeration item
101 * of the element is an enumeration item, or a switch status if the
102 * element is a switch item. */
103 struct pa_alsa_option {
104 pa_alsa_element *element;
105 PA_LLIST_FIELDS(pa_alsa_option);
106
107 char *alsa_name;
108 int alsa_idx;
109
110 char *name;
111 char *description;
112 unsigned priority;
113
114 pa_alsa_required_t required;
115 pa_alsa_required_t required_any;
116 pa_alsa_required_t required_absent;
117 };
118
119 /* An element wraps one specific ALSA element. A series of elements
120 * make up a path (see below). If the element is an enumeration or switch
121 * element it may include a list of options. */
122 struct pa_alsa_element {
123 pa_alsa_path *path;
124 PA_LLIST_FIELDS(pa_alsa_element);
125
126 char *alsa_name;
127 pa_alsa_direction_t direction;
128
129 pa_alsa_switch_use_t switch_use;
130 pa_alsa_volume_use_t volume_use;
131 pa_alsa_enumeration_use_t enumeration_use;
132
133 pa_alsa_required_t required;
134 pa_alsa_required_t required_any;
135 pa_alsa_required_t required_absent;
136
137 long constant_volume;
138
139 pa_bool_t override_map:1;
140 pa_bool_t direction_try_other:1;
141
142 pa_bool_t has_dB:1;
143 long min_volume, max_volume;
144 long volume_limit; /* -1 for no configured limit */
145 double min_dB, max_dB;
146
147 pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST][2];
148 unsigned n_channels;
149
150 pa_channel_position_mask_t merged_mask;
151
152 PA_LLIST_HEAD(pa_alsa_option, options);
153
154 pa_alsa_decibel_fix *db_fix;
155 };
156
157 /* A path wraps a series of elements into a single entity which can be
158 * used to control it as if it had a single volume slider, a single
159 * mute switch and a single list of selectable options. */
160 struct pa_alsa_path {
161 pa_alsa_path_set *path_set;
162 PA_LLIST_FIELDS(pa_alsa_path);
163
164 pa_alsa_direction_t direction;
165
166 char *name;
167 char *description;
168 unsigned priority;
169
170 pa_bool_t probed:1;
171 pa_bool_t supported:1;
172 pa_bool_t has_mute:1;
173 pa_bool_t has_volume:1;
174 pa_bool_t has_dB:1;
175 /* These two are used during probing only */
176 pa_bool_t has_req_any:1;
177 pa_bool_t req_any_present:1;
178
179 long min_volume, max_volume;
180 double min_dB, max_dB;
181
182 /* This is used during parsing only, as a shortcut so that we
183 * don't have to iterate the list all the time */
184 pa_alsa_element *last_element;
185 pa_alsa_option *last_option;
186 pa_alsa_setting *last_setting;
187
188 PA_LLIST_HEAD(pa_alsa_element, elements);
189 PA_LLIST_HEAD(pa_alsa_setting, settings);
190 };
191
192 /* A path set is simply a set of paths that are applicable to a
193 * device */
194 struct pa_alsa_path_set {
195 PA_LLIST_HEAD(pa_alsa_path, paths);
196 pa_alsa_direction_t direction;
197 pa_bool_t probed:1;
198
199 /* This is used during parsing only, as a shortcut so that we
200 * don't have to iterate the list all the time */
201 pa_alsa_path *last_path;
202 };
203
204 int pa_alsa_setting_select(pa_alsa_setting *s, snd_mixer_t *m);
205 void pa_alsa_setting_dump(pa_alsa_setting *s);
206
207 void pa_alsa_option_dump(pa_alsa_option *o);
208
209 void pa_alsa_element_dump(pa_alsa_element *e);
210
211 pa_alsa_path *pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction);
212 pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction);
213 int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB);
214 void pa_alsa_path_dump(pa_alsa_path *p);
215 int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
216 int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t *muted);
217 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);
218 int pa_alsa_path_set_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t muted);
219 int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m);
220 void pa_alsa_path_set_callback(pa_alsa_path *p, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
221 void pa_alsa_path_free(pa_alsa_path *p);
222
223 pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction);
224 void pa_alsa_path_set_probe(pa_alsa_path_set *s, snd_mixer_t *m, pa_bool_t ignore_dB);
225 void pa_alsa_path_set_dump(pa_alsa_path_set *s);
226 void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
227 void pa_alsa_path_set_free(pa_alsa_path_set *s);
228
229 struct pa_alsa_mapping {
230 pa_alsa_profile_set *profile_set;
231
232 char *name;
233 char *description;
234 unsigned priority;
235 pa_alsa_direction_t direction;
236
237 pa_channel_map channel_map;
238
239 char **device_strings;
240
241 char **input_path_names;
242 char **output_path_names;
243 char **input_element; /* list of fallbacks */
244 char **output_element;
245
246 unsigned supported;
247
248 /* Temporarily used during probing */
249 snd_pcm_t *input_pcm;
250 snd_pcm_t *output_pcm;
251
252 pa_sink *sink;
253 pa_source *source;
254 };
255
256 struct pa_alsa_profile {
257 pa_alsa_profile_set *profile_set;
258
259 char *name;
260 char *description;
261 unsigned priority;
262
263 pa_bool_t supported:1;
264
265 char **input_mapping_names;
266 char **output_mapping_names;
267
268 pa_idxset *input_mappings;
269 pa_idxset *output_mappings;
270 };
271
272 struct pa_alsa_decibel_fix {
273 pa_alsa_profile_set *profile_set;
274
275 char *name; /* Alsa volume element name. */
276 long min_step;
277 long max_step;
278
279 /* An array that maps alsa volume element steps to decibels. The steps can
280 * be used as indices to this array, after subtracting min_step from the
281 * real value.
282 *
283 * The values are actually stored as integers representing millibels,
284 * because that's the format the alsa API uses. */
285 long *db_values;
286 };
287
288 struct pa_alsa_profile_set {
289 pa_hashmap *mappings;
290 pa_hashmap *profiles;
291 pa_hashmap *decibel_fixes;
292
293 pa_bool_t auto_profiles;
294 pa_bool_t probed:1;
295 };
296
297 void pa_alsa_mapping_dump(pa_alsa_mapping *m);
298 void pa_alsa_profile_dump(pa_alsa_profile *p);
299 void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix);
300
301 pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus);
302 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);
303 void pa_alsa_profile_set_free(pa_alsa_profile_set *s);
304 void pa_alsa_profile_set_dump(pa_alsa_profile_set *s);
305
306 snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device);
307
308 pa_alsa_fdlist *pa_alsa_fdlist_new(void);
309 void pa_alsa_fdlist_free(pa_alsa_fdlist *fdl);
310 int pa_alsa_fdlist_set_mixer(pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m);
311
312 /* Alternative for handling alsa mixer events in io-thread. */
313
314 pa_alsa_mixer_pdata *pa_alsa_mixer_pdata_new(void);
315 void pa_alsa_mixer_pdata_free(pa_alsa_mixer_pdata *pd);
316 int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer, pa_rtpoll *rtp);
317
318 /* Data structure for inclusion in pa_device_port for alsa
319 * sinks/sources. This contains nothing that needs to be freed
320 * individually */
321 struct pa_alsa_port_data {
322 pa_alsa_path *path;
323 pa_alsa_setting *setting;
324 };
325
326 void pa_alsa_add_ports(pa_hashmap **p, pa_alsa_path_set *ps);
327
328 #endif