]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libmixer/mixer.3
Merge llvm-project release/17.x llvmorg-17.0.2-0-gb2417f51dbbd
[FreeBSD/FreeBSD.git] / lib / libmixer / mixer.3
1 .\"-
2 .\" Copyright (c) 2021-2022 Christos Margiolis <christos@FreeBSD.org>
3 .\"
4 .\" Permission is hereby granted, free of charge, to any person obtaining a copy
5 .\" of this software and associated documentation files (the "Software"), to deal
6 .\" in the Software without restriction, including without limitation the rights
7 .\" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 .\" copies of the Software, and to permit persons to whom the Software is
9 .\" furnished to do so, subject to the following conditions:
10 .\"
11 .\" The above copyright notice and this permission notice shall be included in
12 .\" all copies or substantial portions of the Software.
13 .\"
14 .\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 .\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 .\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 .\" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 .\" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 .\" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 .\" THE SOFTWARE.
21 .\"
22
23 .Dd January 19, 2023
24 .Dt MIXER 3
25 .Os
26 .Sh NAME
27 .Nm mixer_open ,
28 .Nm mixer_close ,
29 .Nm mixer_get_dev ,
30 .Nm mixer_get_dev_byname ,
31 .Nm mixer_add_ctl ,
32 .Nm mixer_add_ctl_s ,
33 .Nm mixer_remove_ctl ,
34 .Nm mixer_get_ctl ,
35 .Nm mixer_get_ctl_byname ,
36 .Nm mixer_set_vol ,
37 .Nm mixer_set_mute ,
38 .Nm mixer_mod_recsrc ,
39 .Nm mixer_get_dunit ,
40 .Nm mixer_set_dunit ,
41 .Nm mixer_get_mode ,
42 .Nm mixer_get_nmixers ,
43 .Nm MIX_ISDEV ,
44 .Nm MIX_ISMUTE ,
45 .Nm MIX_ISREC ,
46 .Nm MIX_ISRECSRC ,
47 .Nm MIX_VOLNORM ,
48 .Nm MIX_VOLDENORM
49 .Nd interface to OSS mixers
50 .Sh LIBRARY
51 Mixer library (libmixer, -lmixer)
52 .Sh SYNOPSIS
53 .In mixer.h
54 .Ft struct mixer *
55 .Fn mixer_open "const char *name"
56 .Ft int
57 .Fn mixer_close "struct mixer *m"
58 .Ft struct mix_dev *
59 .Fn mixer_get_dev "struct mixer *m" "int devno"
60 .Ft struct mix_dev *
61 .Fn mixer_get_dev_byname "struct mixer *m" "name"
62 .Ft int
63 .Fn mixer_add_ctl "struct mix_dev *parent" "int id" "const char *name" \
64     "int (*mod)(struct mix_dev *d, void *p)" \
65     "int (*print)(struct mix_dev *d, void *p)"
66 .Ft int
67 .Fn mixer_add_ctl_s "mix_ctl_t *ctl"
68 .Ft int
69 .Fn mixer_remove_ctl "mix_ctl_t *ctl"
70 .Ft mix_ctl_t *
71 .Fn mixer_get_ctl "struct mix_dev *d" "int id"
72 .Ft mix_ctl_t *
73 .Fn mixer_get_ctl_byname "struct mix_dev *d" "const char *name"
74 .Ft int
75 .Fn mixer_set_vol "struct mixer *m" "mix_volume_t vol"
76 .Ft int
77 .Fn mixer_set_mute "struct mixer *m" "int opt"
78 .Ft int
79 .Fn mixer_mod_recsrc "struct mixer *m" "int opt"
80 .Ft int
81 .Fn mixer_get_dunit "void"
82 .Ft int
83 .Fn mixer_set_dunit "struct mixer *m" "int unit"
84 .Ft int
85 .Fn mixer_get_mode "int unit"
86 .Ft int
87 .Fn mixer_get_nmixers "void"
88 .Ft int
89 .Fn MIX_ISDEV "struct mixer *m" "int devno"
90 .Ft int
91 .Fn MIX_ISMUTE "struct mixer *m" "int devno"
92 .Ft int
93 .Fn MIX_ISREC "struct mixer *m" "int devno"
94 .Ft int
95 .Fn MIX_ISRECSRC "struct mixer *m" "int devno"
96 .Ft float
97 .Fn MIX_VOLNORM "int v"
98 .Ft int
99 .Fn MIX_VOLDENORM "float v"
100 .Sh DESCRIPTION
101 The
102 .Nm mixer
103 library allows userspace programs to access and manipulate OSS sound mixers in
104 a simple way.
105 .Ss Mixer
106 A mixer is described by the following structure:
107 .Bd -literal
108 struct mixer {
109         TAILQ_HEAD(mix_devhead, mix_dev) devs;  /* device list */
110         struct mix_dev *dev;                    /* selected device */
111         oss_mixerinfo mi;                       /* mixer info */
112         oss_card_info ci;                       /* audio card info */
113         char name[NAME_MAX];                    /* mixer name (e.g /dev/mixer0) */
114         int fd;                                 /* file descriptor */
115         int unit;                               /* audio card unit */
116         int ndev;                               /* number of devices */
117         int devmask;                            /* supported devices */
118 #define MIX_MUTE                0x01
119 #define MIX_UNMUTE              0x02
120 #define MIX_TOGGLEMUTE          0x04
121         int mutemask;                           /* muted devices */
122         int recmask;                            /* recording devices */
123 #define MIX_ADDRECSRC           0x01
124 #define MIX_REMOVERECSRC        0x02
125 #define MIX_SETRECSRC           0x04
126 #define MIX_TOGGLERECSRC        0x08
127         int recsrc;                             /* recording sources */
128 #define MIX_MODE_MIXER          0x01
129 #define MIX_MODE_PLAY           0x02
130 #define MIX_MODE_REC            0x04
131         int mode;                               /* dev.pcm.X.mode sysctl */
132         int f_default;                          /* default mixer flag */
133 };
134 .Ed
135 .Pp
136 The fields are follows:
137 .Bl -tag -width "f_default"
138 .It Fa devs
139 A tail queue structure containing all supported mixer devices.
140 .It Fa dev
141 A pointer to the currently selected device.
142 The device is one of the elements in
143 .Ar devs .
144 .It Fa mi
145 OSS information about the mixer.
146 Look at the definition of the
147 .Ft oss_mixerinfo
148 structure in
149 .In sys/soundcard.h
150 to see its fields.
151 .It Fa ci
152 OSS audio card information.
153 This structure is also defined in
154 .In sys/soundcard.h .
155 .It Fa name
156 Path to the mixer (e.g /dev/mixer0).
157 .It Fa fd
158 File descriptor returned when the mixer is opened in
159 .Fn mixer_open .
160 .It Fa unit
161 Audio card unit.
162 Since each mixer device maps to a pcmX device,
163 .Ar unit
164 is always equal to the number of that pcmX device.
165 For example, if the audio device's number is 0 (i.e pcm0), then
166 .Ar unit
167 is 0 as well.
168 This number is useful when checking if the mixer's audio card is the default one.
169 .It Fa ndev
170 Number of devices in
171 .Ar devs .
172 .It Fa devmask
173 Bit mask containing all supported devices for the mixer.
174 For example, if device 10 is supported, then the 10th bit in the mask will be set.
175 By default,
176 .Fn mixer_open
177 stores only the supported devices in devs, so it is very unlikely this mask will
178 be needed.
179 .It Fa mutemask
180 Bit mask containing all muted devices.
181 The logic is the same as with
182 .Ar devmask .
183 .It Fa recmask
184 Bit mask containing all recording devices.
185 Again, same logic as with the other masks.
186 .It Fa recsrc
187 Bit mask containing all recording sources.
188 Yes, same logic again.
189 .It Fa mode
190 Bit mask containing the supported modes for this audio device.
191 It holds the value of the
192 .Ar dev.pcm.X.mode
193 sysctl.
194 .It Fa f_default
195 Flag which tells whether the mixer's audio card is the default one.
196 .El
197 .Ss Mixer device
198 Each mixer device stored in a mixer is described as follows:
199 .Bd -literal
200 struct mix_dev {
201         struct mixer *parent_mixer;             /* parent mixer */
202         char name[NAME_MAX];                    /* device name (e.g "vol") */
203         int devno;                              /* device number */
204         struct mix_volume {
205 #define MIX_VOLMIN              0.0f
206 #define MIX_VOLMAX              1.0f
207 #define MIX_VOLNORM(v)          ((v) / 100.0f)
208 #define MIX_VOLDENORM(v)        ((int)((v) * 100.0f + 0.5f))
209                 float left;                     /* left volume */
210                 float right;                    /* right volume */
211         } vol;
212         int nctl;                               /* number of controls */
213         TAILQ_HEAD(mix_ctlhead, mix_ctl) ctls;  /* control list */
214         TAILQ_ENTRY(mix_dev) devs;
215 };
216 .Ed
217 .Pp
218 The fields are follows:
219 .Bl -tag -width "parent_mixer"
220 .It Fa parent_mixer
221 Pointer to the mixer the device is attached to.
222 .It Fa name
223 Device name given by the OSS API.
224 Devices can have one of the following names:
225 .Bd -ragged
226 vol, bass, treble, synth, pcm, speaker, line, mic, cd, mix,
227 pcm2, rec, igain, ogain, line1, line2, line3, dig1, dig2, dig3,
228 phin, phout, video, radio, and monitor.
229 .Ed
230 .It Fa devno
231 Device's index in the SOUND_MIXER_NRDEVICES macro defined in
232 .In sys/soundcard.h .
233 This number is used to check against the masks defined in the
234 .Ar mixer
235 structure.
236 .It Fa left right
237 Left and right-ear volumes.
238 Although the OSS API stores volumes in integers from 0-100, \
239 we normalize them to 32-bit floating point numbers.
240 However, the volumes can be denormalized using the
241 .Ar MIX_VOLDENORM
242 macro if needed.
243 .It Fa nctl
244 Number of user-defined mixer controls associated with the device.
245 .It Fa ctls
246 A tail queue containing user-defined mixer controls.
247 .El
248 .Ss User-defined mixer controls
249 Each mixer device can have user-defined controls.
250 The control structure is defined as follows:
251 .Bd -literal
252 struct mix_ctl {
253         struct mix_dev *parent_dev;             /* parent device */
254         int id;                                 /* control id */
255         char name[NAME_MAX];                    /* control name */
256         int (*mod)(struct mix_dev *, void *);   /* modify control values */
257         int (*print)(struct mix_dev *, void *); /* print control */
258         TAILQ_ENTRY(mix_ctl) ctls;
259 };
260 .Ed
261 .Pp
262 The fields are follows:
263 .Bl -tag -width "parent_dev"
264 .It Fa parent_dev
265 Pointer to the device the control is attached to.
266 .It Fa id
267 Control ID assigned by the caller.
268 Even though the library will report it, care has to be taken to not give \
269 a control the same ID in case the caller has to choose controls using their ID.
270 .It Fa name
271 Control name.
272 As with
273 .Ar id ,
274 the caller has to make sure the same name is not used more than once.
275 .It Fa mod
276 Function pointer to a control modification function.
277 As in
278 .Xr mixer 8 ,
279 each mixer control's values can be modified.
280 For example, if we have a volume control, the
281 .Ar mod
282 function will be responsible for handling volume changes.
283 .It Fa print
284 Function pointer to a control print function.
285 .El
286 .Ss Opening and closing the mixer
287 The application must first call the
288 .Fn mixer_open
289 function to obtain a handle to the device, which is used as an argument \
290 in most other functions and macros.
291 The parameter
292 .Ar name
293 specifies the path to the mixer.
294 OSS mixers are stored under
295 .Ar /dev/mixerN
296 where
297 .Ar N
298 is the number of the mixer device.
299 Each device maps to an actual
300 .Ar pcm
301 audio card, so
302 .Ar /dev/mixer0
303 is the mixer for
304 .Ar pcm0 ,
305 and so on.
306 If
307 .Ar name
308 is
309 .Ar NULL
310 or
311 .Ar /dev/mixer ,
312 .Fn mixer_open
313 opens the default mixer (hw.snd.default_unit).
314 .Pp
315 The
316 .Fn mixer_close
317 function frees resources and closes the mixer device.
318 It is a good practice to always call it when the application is done using the mixer.
319 .Ss Manipulating the mixer
320 The
321 .Fn mixer_get_dev
322 and
323 .Fn mixer_get_dev_byname
324 functions select a mixer device, either by its number or by its name respectively.
325 The mixer structure keeps a list of all the devices, but only \
326 one can be manipulated at a time.
327 Each time a new device is to be manipulated, one of the two functions has to be called.
328 .Pp
329 The
330 .Fn mixer_set_vol
331 function changes the volume of the selected mixer device.
332 The
333 .Ar vol
334 parameter is a structure that stores the left and right volumes of a given device.
335 The allowed volume values are between MIX_VOLMIN (0.0) and MIX_VOLMAX (1.0).
336 .Pp
337 The
338 .Fn mixer_set_mute
339 function modifies the mute of a selected device.
340 The
341 .Ar opt
342 parameter has to be one of the following options:
343 .Bl -tag -width MIX_TOGGLEMUTE -offset indent
344 .It Dv MIX_MUTE
345 Mute the device.
346 .It Dv MIX_UNMUTE
347 Unmute the device.
348 .It Dv MIX_TOGGLEMUTE
349 Toggle the device's mute (e.g mute if unmuted and unmute if muted).
350 .El
351 .Pp
352 The
353 .Fn mixer_mod_recsrc
354 function modifies a recording device.
355 The selected device has to be a recording device, otherwise the function will fail.
356 The
357 .Ar opt
358 parameter has to be one of the following options:
359 .Bl -tag -width MIX_REMOVERECSRC -offset indent
360 .It Dv MIX_ADDRECSRC
361 Add device to the recording sources.
362 .It Dv MIX_REMOVERECSRC
363 Remove device from the recording sources.
364 .It Dv MIX_SETRECSRC
365 Set device as the only recording source.
366 .It Dv MIX_TOGGLERECSRC
367 Toggle device from the recording sources.
368 .El
369 .Pp
370 The
371 .Fn mixer_get_dunit
372 and
373 .Fn mixer_set_dunit
374 functions get and set the default audio card in the system.
375 Although this is not really a mixer feature, it is useful to have instead of \
376 having to use the
377 .Xr sysctl 3
378 controls.
379 .Pp
380 The
381 .Fn mixer_get_mode
382 function returns the playback/recording mode of the audio device the mixer \
383 belongs to.
384 The available values are the following:
385 .Bl -tag -width "MIX_STATUS_PLAY | MIX_STATUS_REC" -offset indent
386 .It Dv MIX_STATUS_NONE
387 Neither playback nor recording.
388 .It Dv MIX_STATUS_PLAY
389 Playback.
390 .It Dv MIX_STATUS_REC
391 Recording.
392 .It Dv MIX_STATUS_PLAY | MIX_STATUS_REC
393 Playback and recording.
394 .El
395 .Pp
396 The
397 .Fn mixer_get_nmixers
398 function returns the total number of mixer devices in the system.
399 .Pp
400 The
401 .Fn MIX_ISDEV
402 macro checks if a device is actually a valid device for a given mixer.
403 It is very unlikely that this macro will ever be needed since the library \
404 stores only valid devices by default.
405 .Pp
406 The
407 .Fn MIX_ISMUTE
408 macro checks if a device is muted.
409 .Pp
410 The
411 .Fn MIX_ISREC
412 macro checks if a device is a recording device.
413 .Pp
414 The
415 .Fn MIX_ISRECSRC
416 macro checks if a device is a recording source.
417 .Pp
418 The
419 .Fn MIX_VOLNORM
420 macro normalizes a value to 32-bit floating point number.
421 It is used to normalize the volumes read from the OSS API.
422 .Pp
423 The
424 .Fn MIX_VOLDENORM
425 macro denormalizes the left and right volumes stores in the
426 .Ft mix_dev
427 structure.
428 .Ss Defining and using mixer controls
429 The
430 .Fn mix_add_ctl
431 function creates a control and attaches it to the device specified in the
432 .Ar parent
433 argument.
434 .Pp
435 The
436 .Fn mix_add_ctl_s
437 function does the same thing as with
438 .Fn mix_add_ctl
439 but the caller passes a
440 .Ft mix_ctl_t *
441 structure instead of each field as a separate argument.
442 .Pp
443 The
444 .Fn mixer_remove_ctl
445 functions removes a control from the device its attached to.
446 .Pp
447 The
448 .Fn mixer_get_ctl
449 function searches for a control in the device specified in the
450 .Ar d
451 argument and returns a pointer to it.
452 The search is done using the control's ID.
453 .Pp
454 The
455 .Fn mixer_get_ctl_byname
456 function is the same as with
457 .Fn mixer_get_ctl
458 but the search is done using the control's name.
459 .Sh RETURN VALUES
460 The
461 .Fn mixer_open
462 function returns the newly created handle on success and NULL on failure.
463 .Pp
464 The
465 .Fn mixer_close ,
466 .Fn mixer_set_vol ,
467 .Fn mixer_set_mute ,
468 .Fn mixer_mod_recsrc ,
469 .Fn mixer_get_dunut ,
470 .Fn mixer_set_dunit
471 and
472 .Fn mixer_get_nmixers
473 functions return 0 or positive values on success and -1 on failure.
474 .Pp
475 The
476 .Fn mixer_get_dev
477 and
478 .Fn mixer_get_dev_byname
479 functions return the selected device on success and NULL on failure.
480 .Pp
481 All functions set the value of
482 .Ar errno
483 on failure.
484 .Sh EXAMPLES
485 .Ss Change the volume of a device
486 .Bd -literal
487 struct mixer *m;
488 mix_volume_t vol;
489 char *mix_name, *dev_name;
490
491 mix_name = ...;
492 if ((m = mixer_open(mix_name)) == NULL)
493         err(1, "mixer_open: %s", mix_name);
494
495 dev_name = ...;
496 if ((m->dev = mixer_get_dev_byname(m, dev_name)) < 0)
497         err(1, "unknown device: %s", dev_name);
498
499 vol.left = ...;
500 vol.right = ....;
501 if (mixer_set_vol(m, vol) < 0)
502         warn("cannot change volume");
503
504 (void)mixer_close(m);
505 .Ed
506 .Ss Mute all unmuted devices
507 .Bd -literal
508 struct mixer *m;
509 struct mix_dev *dp;
510
511 if ((m = mixer_open(NULL)) == NULL)     /* Open the default mixer. */
512         err(1, "mixer_open");
513 TAILQ_FOREACH(dp, &m->devs, devs) {
514         m->dev = dp;                    /* Select device. */
515         if (M_ISMUTE(m, dp->devno))
516                 continue;
517         if (mixer_set_mute(m, MIX_MUTE) < 0)
518                 warn("cannot mute device: %s", dp->name);
519 }
520
521 (void)mixer_close(m);
522 .Ed
523 .Ss Print all recording sources' names and volumes
524 .Bd -literal
525 struct mixer *m;
526 struct mix_dev *dp;
527
528 char *mix_name, *dev_name;
529
530 mix_name = ...;
531 if ((m = mixer_open(mix_name)) == NULL)
532         err(1, "mixer_open: %s", mix_name);
533
534 TAILQ_FOREACH(dp, &m->devs, devs) {
535         if (M_ISRECSRC(m, dp->devno))
536                 printf("%s\\t%.2f:%.2f\\n",
537                     dp->name, dp->vol.left, dp->vol.right);
538 }
539
540 (void)mixer_close(m);
541 .Ed
542 .Sh SEE ALSO
543 .Xr queue 3 ,
544 .Xr sysctl 3 ,
545 .Xr sound 4 ,
546 .Xr mixer 8
547 and
548 .Xr errno 2
549 .Sh AUTHORS
550 .An Christos Margiolis Aq Mt christos@FreeBSD.org