10f66f451Sopenharmony_ci/* mix.c - A very basic mixer.
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2014 Brad Conroy, dedicated to the Public Domain.
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci
60f66f451Sopenharmony_ciUSE_MIX(NEWTOY(mix, "c:d:l#r#", TOYFLAG_USR|TOYFLAG_BIN))
70f66f451Sopenharmony_ci
80f66f451Sopenharmony_ciconfig MIX
90f66f451Sopenharmony_ci  bool "mix"
100f66f451Sopenharmony_ci  default y
110f66f451Sopenharmony_ci  help
120f66f451Sopenharmony_ci   usage: mix [-d DEV] [-c CHANNEL] [-l VOL] [-r RIGHT]
130f66f451Sopenharmony_ci
140f66f451Sopenharmony_ci   List OSS sound channels (module snd-mixer-oss), or set volume(s).
150f66f451Sopenharmony_ci
160f66f451Sopenharmony_ci   -c CHANNEL	Set/show volume of CHANNEL (default first channel found)
170f66f451Sopenharmony_ci   -d DEV		Device node (default /dev/mixer)
180f66f451Sopenharmony_ci   -l VOL		Volume level
190f66f451Sopenharmony_ci   -r RIGHT	Volume of right stereo channel (with -r, -l sets left volume)
200f66f451Sopenharmony_ci*/
210f66f451Sopenharmony_ci
220f66f451Sopenharmony_ci#define FOR_mix
230f66f451Sopenharmony_ci#include "toys.h"
240f66f451Sopenharmony_ci#include <linux/soundcard.h>
250f66f451Sopenharmony_ci
260f66f451Sopenharmony_ciGLOBALS(
270f66f451Sopenharmony_ci   long r, l;
280f66f451Sopenharmony_ci   char *d, *c;
290f66f451Sopenharmony_ci)
300f66f451Sopenharmony_ci
310f66f451Sopenharmony_civoid mix_main(void)
320f66f451Sopenharmony_ci{
330f66f451Sopenharmony_ci  const char *channels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
340f66f451Sopenharmony_ci  int mask, channel = -1, level, fd;
350f66f451Sopenharmony_ci
360f66f451Sopenharmony_ci  if (!TT.d) TT.d = "/dev/mixer";
370f66f451Sopenharmony_ci  fd = xopen(TT.d, O_RDWR|O_NONBLOCK);
380f66f451Sopenharmony_ci  xioctl(fd, SOUND_MIXER_READ_DEVMASK, &mask);
390f66f451Sopenharmony_ci
400f66f451Sopenharmony_ci  for (channel = 0; channel < SOUND_MIXER_NRDEVICES; channel++) {
410f66f451Sopenharmony_ci    if ((1<<channel) & mask) {
420f66f451Sopenharmony_ci      if (TT.c) {
430f66f451Sopenharmony_ci        if (!strcmp(channels[channel], TT.c)) break;
440f66f451Sopenharmony_ci      } else if (toys.optflags & FLAG_l) break;
450f66f451Sopenharmony_ci      else printf("%s\n", channels[channel]);
460f66f451Sopenharmony_ci    }
470f66f451Sopenharmony_ci  }
480f66f451Sopenharmony_ci
490f66f451Sopenharmony_ci  if (!(toys.optflags & (FLAG_c|FLAG_l))) return;
500f66f451Sopenharmony_ci  else if (channel == SOUND_MIXER_NRDEVICES) error_exit("bad -c '%s'", TT.c);
510f66f451Sopenharmony_ci
520f66f451Sopenharmony_ci  if (!(toys.optflags & FLAG_l)) {
530f66f451Sopenharmony_ci    xioctl(fd, MIXER_READ(channel), &level);
540f66f451Sopenharmony_ci    if (level > 0xFF)
550f66f451Sopenharmony_ci      xprintf("%s:%s = left:%d\t right:%d\n",
560f66f451Sopenharmony_ci              TT.d, channels[channel], level>>8, level & 0xFF);
570f66f451Sopenharmony_ci    else xprintf("%s:%s = %d\n", TT.d, channels[channel], level);
580f66f451Sopenharmony_ci  } else {
590f66f451Sopenharmony_ci    level = TT.l;
600f66f451Sopenharmony_ci    if (!(toys.optflags & FLAG_r)) level = TT.r | (level<<8);
610f66f451Sopenharmony_ci
620f66f451Sopenharmony_ci    xioctl(fd, MIXER_WRITE(channel), &level);
630f66f451Sopenharmony_ci  }
640f66f451Sopenharmony_ci
650f66f451Sopenharmony_ci  if (CFG_TOYBOX_FREE) close(fd);
660f66f451Sopenharmony_ci}
67