Lines Matching +full:mixer +full:- +full:mode

1 /*-
34 #include "mixer.h"
36 #define BASEPATH "/dev/mixer"
48 if (ioctl(dev->parent_mixer->fd, MIXER_READ(dev->devno), &v) < 0) in _mixer_readvol()
49 return (-1); in _mixer_readvol()
50 dev->vol.left = MIX_VOLNORM(v & 0x00ff); in _mixer_readvol()
51 dev->vol.right = MIX_VOLNORM((v >> 8) & 0x00ff); in _mixer_readvol()
57 * Open a mixer device in `/dev/mixerN`, where N is the number of the mixer.
59 * mixer for pcm0, and so on.
61 * @param name path to mixer device. NULL or "/dev/mixer" for the
62 * the default mixer (i.e `hw.snd.default_unit`).
64 struct mixer *
67 struct mixer *m = NULL; in mixer_open()
72 if ((m = calloc(1, sizeof(struct mixer))) == NULL) in mixer_open()
76 /* `name` does not start with "/dev/mixer". */ in mixer_open()
78 m->unit = -1; in mixer_open()
80 /* `name` is "/dev/mixer" so, we'll use the default unit. */ in mixer_open()
83 m->unit = strtol(name + strlen(BASEPATH), NULL, 10); in mixer_open()
85 (void)strlcpy(m->name, name, sizeof(m->name)); in mixer_open()
88 if ((m->unit = mixer_get_dunit()) < 0) in mixer_open()
90 (void)snprintf(m->name, sizeof(m->name), BASEPATH "%d", m->unit); in mixer_open()
93 if ((m->fd = open(m->name, O_RDWR)) < 0) in mixer_open()
96 m->devmask = m->recmask = m->recsrc = 0; in mixer_open()
97 m->f_default = m->unit == mixer_get_dunit(); in mixer_open()
98 m->mode = mixer_get_mode(m->unit); in mixer_open()
100 m->mi.dev = m->unit; in mixer_open()
101 m->ci.card = m->unit; in mixer_open()
102 if (ioctl(m->fd, SNDCTL_MIXERINFO, &m->mi) < 0) { in mixer_open()
103 memset(&m->mi, 0, sizeof(m->mi)); in mixer_open()
104 strlcpy(m->mi.name, m->name, sizeof(m->mi.name)); in mixer_open()
106 if (ioctl(m->fd, SNDCTL_CARDINFO, &m->ci) < 0) in mixer_open()
107 memset(&m->ci, 0, sizeof(m->ci)); in mixer_open()
108 if (ioctl(m->fd, SOUND_MIXER_READ_DEVMASK, &m->devmask) < 0 || in mixer_open()
109 ioctl(m->fd, SOUND_MIXER_READ_MUTE, &m->mutemask) < 0 || in mixer_open()
110 ioctl(m->fd, SOUND_MIXER_READ_RECMASK, &m->recmask) < 0 || in mixer_open()
111 ioctl(m->fd, SOUND_MIXER_READ_RECSRC, &m->recsrc) < 0) in mixer_open()
114 TAILQ_INIT(&m->devs); in mixer_open()
120 dp->parent_mixer = m; in mixer_open()
121 dp->devno = i; in mixer_open()
122 dp->nctl = 0; in mixer_open()
125 (void)strlcpy(dp->name, names[i], sizeof(dp->name)); in mixer_open()
126 TAILQ_INIT(&dp->ctls); in mixer_open()
127 TAILQ_INSERT_TAIL(&m->devs, dp, devs); in mixer_open()
128 m->ndev++; in mixer_open()
132 m->dev = TAILQ_FIRST(&m->devs); in mixer_open()
143 * Free resources and close the mixer.
146 mixer_close(struct mixer *m) in mixer_close()
151 r = close(m->fd); in mixer_close()
152 while (!TAILQ_EMPTY(&m->devs)) { in mixer_close()
153 dp = TAILQ_FIRST(&m->devs); in mixer_close()
154 TAILQ_REMOVE(&m->devs, dp, devs); in mixer_close()
155 while (!TAILQ_EMPTY(&dp->ctls)) in mixer_close()
156 (void)mixer_remove_ctl(TAILQ_FIRST(&dp->ctls)); in mixer_close()
165 * Select a mixer device. The mixer structure keeps a list of all the devices
166 * the mixer has, but only one can be manipulated at a time -- this is what
167 * the `dev` in the mixer structure field is for. Each time a device is to be
170 * The caller must manually assign the return value to `m->dev`.
173 mixer_get_dev(struct mixer *m, int dev) in mixer_get_dev()
177 if (dev < 0 || dev >= m->ndev) { in mixer_get_dev()
181 TAILQ_FOREACH(dp, &m->devs, devs) { in mixer_get_dev()
182 if (dp->devno == dev) in mixer_get_dev()
196 mixer_get_dev_byname(struct mixer *m, const char *name) in mixer_get_dev_byname()
200 TAILQ_FOREACH(dp, &m->devs, devs) { in mixer_get_dev_byname()
201 if (!strncmp(dp->name, name, sizeof(dp->name))) in mixer_get_dev_byname()
210 * Add a mixer control to a device.
223 return (-1); in mixer_add_ctl()
226 return (-1); in mixer_add_ctl()
227 ctl->parent_dev = parent_dev; in mixer_add_ctl()
228 ctl->id = id; in mixer_add_ctl()
230 (void)strlcpy(ctl->name, name, sizeof(ctl->name)); in mixer_add_ctl()
231 ctl->mod = mod; in mixer_add_ctl()
232 ctl->print = print; in mixer_add_ctl()
233 dp = ctl->parent_dev; in mixer_add_ctl()
235 TAILQ_FOREACH(cp, &dp->ctls, ctls) { in mixer_add_ctl()
236 if (!strncmp(cp->name, name, sizeof(cp->name)) || cp->id == id) { in mixer_add_ctl()
238 return (-1); in mixer_add_ctl()
241 TAILQ_INSERT_TAIL(&dp->ctls, ctl, ctls); in mixer_add_ctl()
242 dp->nctl++; in mixer_add_ctl()
254 return (-1); in mixer_add_ctl_s()
256 return (mixer_add_ctl(ctl->parent_dev, ctl->id, ctl->name, in mixer_add_ctl_s()
257 ctl->mod, ctl->print)); in mixer_add_ctl_s()
261 * Remove a mixer control from a device.
270 return (-1); in mixer_remove_ctl()
272 p = ctl->parent_dev; in mixer_remove_ctl()
273 if (!TAILQ_EMPTY(&p->ctls)) { in mixer_remove_ctl()
274 TAILQ_REMOVE(&p->ctls, ctl, ctls); in mixer_remove_ctl()
282 * Get a mixer control by id.
289 TAILQ_FOREACH(cp, &d->ctls, ctls) { in mixer_get_ctl()
290 if (cp->id == id) in mixer_get_ctl()
299 * Get a mixer control by name.
306 TAILQ_FOREACH(cp, &d->ctls, ctls) { in mixer_get_ctl_byname()
307 if (!strncmp(cp->name, name, sizeof(cp->name))) in mixer_get_ctl_byname()
316 * Change the mixer's left and right volume. The allowed volume values are
318 * an integer value between 0 and 100 stored as `lvol | rvol << 8` -- for
319 * that reason, we de-normalize the 32-bit float volume value, before
325 mixer_set_vol(struct mixer *m, mix_volume_t vol) in mixer_set_vol()
332 return (-1); in mixer_set_vol()
335 if (ioctl(m->fd, MIXER_WRITE(m->dev->devno), &v) < 0) in mixer_set_vol()
336 return (-1); in mixer_set_vol()
337 if (_mixer_readvol(m->dev) < 0) in mixer_set_vol()
338 return (-1); in mixer_set_vol()
351 mixer_set_mute(struct mixer *m, int opt) in mixer_set_mute()
355 m->mutemask |= (1 << m->dev->devno); in mixer_set_mute()
358 m->mutemask &= ~(1 << m->dev->devno); in mixer_set_mute()
361 m->mutemask ^= (1 << m->dev->devno); in mixer_set_mute()
365 return (-1); in mixer_set_mute()
367 if (ioctl(m->fd, SOUND_MIXER_WRITE_MUTE, &m->mutemask) < 0) in mixer_set_mute()
368 return (-1); in mixer_set_mute()
369 if (ioctl(m->fd, SOUND_MIXER_READ_MUTE, &m->mutemask) < 0) in mixer_set_mute()
370 return (-1); in mixer_set_mute()
385 mixer_mod_recsrc(struct mixer *m, int opt) in mixer_mod_recsrc()
387 if (!m->recmask || !MIX_ISREC(m, m->dev->devno)) { in mixer_mod_recsrc()
389 return (-1); in mixer_mod_recsrc()
393 m->recsrc |= (1 << m->dev->devno); in mixer_mod_recsrc()
396 m->recsrc &= ~(1 << m->dev->devno); in mixer_mod_recsrc()
399 m->recsrc = (1 << m->dev->devno); in mixer_mod_recsrc()
402 m->recsrc ^= (1 << m->dev->devno); in mixer_mod_recsrc()
406 return (-1); in mixer_mod_recsrc()
408 if (ioctl(m->fd, SOUND_MIXER_WRITE_RECSRC, &m->recsrc) < 0) in mixer_mod_recsrc()
409 return (-1); in mixer_mod_recsrc()
410 if (ioctl(m->fd, SOUND_MIXER_READ_RECSRC, &m->recsrc) < 0) in mixer_mod_recsrc()
411 return (-1); in mixer_mod_recsrc()
417 * Get default audio card's number. This is used to open the default mixer
418 * and set the mixer structure's `f_default` flag.
428 return (-1); in mixer_get_dunit()
434 * Change the default audio card. This is normally _not_ a mixer feature, but
441 mixer_set_dunit(struct mixer *m, int unit) in mixer_set_dunit()
447 return (-1); in mixer_set_dunit()
449 m->f_default = m->unit == unit; in mixer_set_dunit()
455 * Get sound device mode (none, play, rec, play+rec). Userland programs can
456 * use the MIX_MODE_* flags to determine the mode of the device.
463 unsigned int mode; in mixer_get_mode() local
465 (void)snprintf(buf, sizeof(buf), "dev.pcm.%d.mode", unit); in mixer_get_mode()
467 if (sysctlbyname(buf, &mode, &size, NULL, 0) < 0) in mixer_get_mode()
470 return (mode); in mixer_get_mode()
479 struct mixer *m; in mixer_get_nmixers()
483 * Open a dummy mixer because we need the `fd` field for the in mixer_get_nmixers()
487 return (-1); in mixer_get_nmixers()
488 if (ioctl(m->fd, OSS_SYSINFO, &si) < 0) { in mixer_get_nmixers()
490 return (-1); in mixer_get_nmixers()
498 * Get the full path to a mixer device.
505 if (!(unit == -1 || (unit >= 0 && unit < mixer_get_nmixers()))) { in mixer_get_path()
507 return (-1); in mixer_get_path()
509 if (unit == -1) in mixer_get_path()
516 return (-1); in mixer_get_path()