On Sun, Aug 30, 2009 at 09:35:08PM -0400, Ryan Flannery wrote: > On Sun, Aug 30, 2009 at 8:55 PM, Brynet<bry...@gmail.com> wrote: > > Edd wrote: > >> Upon invocation I get: > >> xstatbar: ioctl AUDIO_MIXER_READ: Invalid argument > > > > The system I was using had no sound card.. I assumed this error was > > related to that, so perhaps the author can tell us why it doesn't > > work? > > > > Here is the cosmetic changes anyway, sorry for not properly testing. > > > > Off-hand I have no idea why this fails, but I can dig into it further > if it is still an open issue.
couple issues here ... /* find the "master" device */ v->master_idx = -1; devinfo.index = 0; while (ioctl(v->dev_fd, AUDIO_MIXER_DEVINFO, &devinfo) >= 0) { if (strncmp(devinfo.label.name, "master", 7) == 0) v->master_idx = devinfo.index; devinfo.index++; } if (v->master_idx == -1) errx(1, "failed to find \"master\" mixer device for volume init"); you should make sure you get outputs.master as opposed to possibly record.master, or some other "master". technically speaking, a device is free to make up whatever class it wants. you have to find the "outputs" class index, and make sure that "master"'s mixer_class equals the "outputs" class index. /* Volume values are stored as 8-bit values, however not all values are * supported (i.e. fewer than 256 different volume levels may be * supported). As such, to accurately determine the percentages shown * in the display, we have to find the maximum settings for this * device. you could use the delta: devinfo.un.v.delta. that is the step size of the hardware. that is, you have to move that many volume units to affect a change in the hardware. you could use this to determine the largest value ... So, we... * 1. read the current volume values * 2. set the volume to the max possible (255) 255 -> AUDIO_MAX_GAIN * 3. read the volume values and see what the max is for this device * 4. reset the volume to what was read in step 1 so we don't muck * with the users' volume. */ /* read current volume */ v->info.dev = v->master_idx; v->info.type = AUDIO_MIXER_VALUE; if (ioctl(v->dev_fd, AUDIO_MIXER_READ, &(v->info)) < 0) err(1, "ioctl AUDIO_MIXER_READ"); that fails because on many devices because num_channels is not set correctly. in sys/dev/ic/ac97.c: ac97_mixer_get_port(struct ac86_codec_if *codec_if, mixer_ctrl_t *cp) { struct ac97_softc *as = (struct ac97_softc *)codec_if; struct ac97_source_info *si = &as->source_info[cp->dev]; ... case AUDIO_MIXER_VALUE: { const struct audio_mixer_value *value = si->info; u_int16_t l, r; if ((cp->un.value.num_channels <= 0) || (cp->un.value.num_channels > value->num_channels)) return (EINVAL); here, value->num_channels == devinfo.un.v.num_channels ... -- jake...@sdf.lonestar.org SDF Public Access UNIX System - http://sdf.lonestar.org