]> code.delx.au - pulseaudio/blob - src/modules/alsa/alsa-mixer.h
Merge commit 'origin/master' into master-tx
[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/volume.h>
30 #include <pulse/mainloop-api.h>
31 #include <pulse/channelmap.h>
32 #include <pulse/proplist.h>
33 #include <pulse/volume.h>
34
35 #include <pulsecore/llist.h>
36 #include <pulsecore/rtpoll.h>
37 #include <pulsecore/core.h>
38 #include <pulsecore/log.h>
39
40 typedef struct pa_alsa_fdlist pa_alsa_fdlist;
41 typedef struct pa_alsa_setting pa_alsa_setting;
42 typedef struct pa_alsa_option pa_alsa_option;
43 typedef struct pa_alsa_element pa_alsa_element;
44 typedef struct pa_alsa_path pa_alsa_path;
45 typedef struct pa_alsa_path_set pa_alsa_path_set;
46 typedef struct pa_alsa_mapping pa_alsa_mapping;
47 typedef struct pa_alsa_profile pa_alsa_profile;
48 typedef struct pa_alsa_profile_set pa_alsa_profile_set;
49 typedef struct pa_alsa_port_data pa_alsa_port_data;
50
51 #include "alsa-util.h"
52
53 typedef enum pa_alsa_switch_use {
54 PA_ALSA_SWITCH_IGNORE,
55 PA_ALSA_SWITCH_MUTE, /* make this switch follow mute status */
56 PA_ALSA_SWITCH_OFF, /* set this switch to 'off' unconditionally */
57 PA_ALSA_SWITCH_ON, /* set this switch to 'on' unconditionally */
58 PA_ALSA_SWITCH_SELECT /* allow the user to select switch status through a setting */
59 } pa_alsa_switch_use_t;
60
61 typedef enum pa_alsa_volume_use {
62 PA_ALSA_VOLUME_IGNORE,
63 PA_ALSA_VOLUME_MERGE, /* merge this volume slider into the global volume slider */
64 PA_ALSA_VOLUME_OFF, /* set this volume to minimal unconditionally */
65 PA_ALSA_VOLUME_ZERO /* set this volume to 0dB unconditionally */
66 } pa_alsa_volume_use_t;
67
68 typedef enum pa_alsa_enumeration_use {
69 PA_ALSA_ENUMERATION_IGNORE,
70 PA_ALSA_ENUMERATION_SELECT
71 } pa_alsa_enumeration_use_t;
72
73 typedef enum pa_alsa_required {
74 PA_ALSA_REQUIRED_IGNORE,
75 PA_ALSA_REQUIRED_SWITCH,
76 PA_ALSA_REQUIRED_VOLUME,
77 PA_ALSA_REQUIRED_ENUMERATION,
78 PA_ALSA_REQUIRED_ANY
79 } pa_alsa_required_t;
80
81 typedef enum pa_alsa_direction {
82 PA_ALSA_DIRECTION_ANY,
83 PA_ALSA_DIRECTION_OUTPUT,
84 PA_ALSA_DIRECTION_INPUT
85 } pa_alsa_direction_t;
86
87 /* A setting combines a couple of options into a single entity that
88 * may be selected. Only one setting can be active at the same
89 * time. */
90 struct pa_alsa_setting {
91 pa_alsa_path *path;
92 PA_LLIST_FIELDS(pa_alsa_setting);
93
94 pa_idxset *options;
95
96 char *name;
97 char *description;
98 unsigned priority;
99 };
100
101 /* An option belongs to an element and refers to one enumeration item
102 * of the element is an enumeration item, or a switch status if the
103 * element is a switch item. */
104 struct pa_alsa_option {
105 pa_alsa_element *element;
106 PA_LLIST_FIELDS(pa_alsa_option);
107
108 char *alsa_name;
109 int alsa_idx;
110
111 char *name;
112 char *description;
113 unsigned priority;
114 };
115
116 /* And element wraps one specific ALSA element. A series of elements *
117 make up a path (see below). If the element is an enumeration or switch
118 * element it may includes a list of options. */
119 struct pa_alsa_element {
120 pa_alsa_path *path;
121 PA_LLIST_FIELDS(pa_alsa_element);
122
123 char *alsa_name;
124 pa_alsa_direction_t direction;
125
126 pa_alsa_switch_use_t switch_use;
127 pa_alsa_volume_use_t volume_use;
128 pa_alsa_enumeration_use_t enumeration_use;
129
130 pa_alsa_required_t required;
131 pa_alsa_required_t required_absent;
132
133 pa_bool_t override_map:1;
134 pa_bool_t direction_try_other:1;
135
136 pa_bool_t has_dB:1;
137 long min_volume, max_volume;
138 double min_dB, max_dB;
139
140 pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST][2];
141 unsigned n_channels;
142
143 pa_channel_position_mask_t merged_mask;
144
145 PA_LLIST_HEAD(pa_alsa_option, options);
146 };
147
148 /* A path wraps a series of elements into a single entity which can be
149 * used to control it as if it had a single volume slider, a single
150 * mute switch and a single list of selectable options. */
151 struct pa_alsa_path {
152 pa_alsa_path_set *path_set;
153 PA_LLIST_FIELDS(pa_alsa_path);
154
155 pa_alsa_direction_t direction;
156
157 char *name;
158 char *description;
159 unsigned priority;
160
161 pa_bool_t probed:1;
162 pa_bool_t supported:1;
163 pa_bool_t has_mute:1;
164 pa_bool_t has_volume:1;
165 pa_bool_t has_dB:1;
166
167 long min_volume, max_volume;
168 double min_dB, max_dB;
169
170 /* This is used during parsing only, as a shortcut so that we
171 * don't have to iterate the list all the time */
172 pa_alsa_element *last_element;
173 pa_alsa_option *last_option;
174 pa_alsa_setting *last_setting;
175
176 PA_LLIST_HEAD(pa_alsa_element, elements);
177 PA_LLIST_HEAD(pa_alsa_setting, settings);
178 };
179
180 /* A path set is simply a set of paths that are applicable to a
181 * device */
182 struct pa_alsa_path_set {
183 PA_LLIST_HEAD(pa_alsa_path, paths);
184 pa_alsa_direction_t direction;
185 pa_bool_t probed:1;
186
187 /* This is used during parsing only, as a shortcut so that we
188 * don't have to iterate the list all the time */
189 pa_alsa_path *last_path;
190 };
191
192 int pa_alsa_setting_select(pa_alsa_setting *s, snd_mixer_t *m);
193 void pa_alsa_setting_dump(pa_alsa_setting *s);
194
195 void pa_alsa_option_dump(pa_alsa_option *o);
196
197 void pa_alsa_element_dump(pa_alsa_element *e);
198
199 pa_alsa_path *pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction);
200 pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction);
201 int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB);
202 void pa_alsa_path_dump(pa_alsa_path *p);
203 int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
204 int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t *muted);
205 int pa_alsa_path_set_volume(pa_alsa_path *path, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
206 int pa_alsa_path_set_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t muted);
207 int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m);
208 void pa_alsa_path_set_callback(pa_alsa_path *p, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
209 void pa_alsa_path_free(pa_alsa_path *p);
210
211 pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction);
212 void pa_alsa_path_set_probe(pa_alsa_path_set *s, snd_mixer_t *m, pa_bool_t ignore_dB);
213 void pa_alsa_path_set_dump(pa_alsa_path_set *s);
214 void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
215 void pa_alsa_path_set_free(pa_alsa_path_set *s);
216
217 struct pa_alsa_mapping {
218 pa_alsa_profile_set *profile_set;
219
220 char *name;
221 char *description;
222 unsigned priority;
223 pa_alsa_direction_t direction;
224
225 pa_channel_map channel_map;
226
227 char **device_strings;
228
229 char **input_path_names;
230 char **output_path_names;
231 char **input_element; /* list of fallbacks */
232 char **output_element;
233
234 unsigned supported;
235
236 /* Temporarily used during probing */
237 snd_pcm_t *input_pcm;
238 snd_pcm_t *output_pcm;
239
240 pa_sink *sink;
241 pa_source *source;
242 };
243
244 struct pa_alsa_profile {
245 pa_alsa_profile_set *profile_set;
246
247 char *name;
248 char *description;
249 unsigned priority;
250
251 pa_bool_t supported:1;
252
253 char **input_mapping_names;
254 char **output_mapping_names;
255
256 pa_idxset *input_mappings;
257 pa_idxset *output_mappings;
258 };
259
260 struct pa_alsa_profile_set {
261 pa_hashmap *mappings;
262 pa_hashmap *profiles;
263
264 pa_bool_t auto_profiles;
265 pa_bool_t probed:1;
266 };
267
268 void pa_alsa_mapping_dump(pa_alsa_mapping *m);
269 void pa_alsa_profile_dump(pa_alsa_profile *p);
270
271 pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus);
272 void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss);
273 void pa_alsa_profile_set_free(pa_alsa_profile_set *s);
274 void pa_alsa_profile_set_dump(pa_alsa_profile_set *s);
275
276 snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device);
277
278 pa_alsa_fdlist *pa_alsa_fdlist_new(void);
279 void pa_alsa_fdlist_free(pa_alsa_fdlist *fdl);
280 int pa_alsa_fdlist_set_mixer(pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m);
281
282 /* Data structure for inclusion in pa_device_port for alsa
283 * sinks/sources. This contains nothing that needs to be freed
284 * individually */
285 struct pa_alsa_port_data {
286 pa_alsa_path *path;
287 pa_alsa_setting *setting;
288 };
289
290 void pa_alsa_add_ports(pa_hashmap **p, pa_alsa_path_set *ps);
291
292 #endif