static int dspctl (int fd, request_t request, void *argp) { static esd_format_t fmt = ESD_STREAM | ESD_PLAY | ESD_MONO; static int speed; int *arg = (int *) argp; DPRINTF ("hijacking /dev/dsp ioctl, and sending it to esd " "(%d : %x - %p)\n", fd, request, argp); switch (request) { case SNDCTL_DSP_RESET: case SNDCTL_DSP_POST: break; case SNDCTL_DSP_SETFMT: fmt |= (*arg & 0x30) ? ESD_BITS16 : ESD_BITS8; settings |= 1; break; case SNDCTL_DSP_SPEED: speed = *arg; settings |= 2; break; case SNDCTL_DSP_STEREO: fmt &= ~ESD_MONO; fmt |= (*arg) ? ESD_STEREO : ESD_MONO; break; case SNDCTL_DSP_GETBLKSIZE: *arg = ESD_BUF_SIZE; break; case SNDCTL_DSP_GETFMTS: *arg = 0x38; break; case SNDCTL_DSP_GETCAPS: *arg = 0; break; case SNDCTL_DSP_GETOSPACE: { audio_buf_info *bufinfo = (audio_buf_info *) argp; bufinfo->bytes = ESD_BUF_SIZE; } break; default: DPRINTF ("unhandled /dev/dsp ioctl (%x - %p)\n", request, argp); break; } if (settings == 3 && !done) { int proto = ESD_PROTO_STREAM_PLAY; done = 1; if (write (sndfd, &proto, sizeof (proto)) != sizeof (proto)) return -1; if (write (sndfd, &fmt, sizeof (fmt)) != sizeof (fmt)) return -1; if (write (sndfd, &speed, sizeof (speed)) != sizeof (speed)) return -1; if (write (sndfd, ident, ESD_NAME_MAX) != ESD_NAME_MAX) return -1; fmt = ESD_STREAM | ESD_PLAY | ESD_MONO; speed = 0; if (use_mixer) { int esd = -1, player = -1; int left, right; while (player < 0) mix_init (&esd, &player); get_volume (&left, &right); DPRINTF ("panning %d - %d %d\n", player, left, right); esd_set_stream_pan (esd, player, left, right); } } return 0; }
int mixctl (int fd, request_t request, void *argp) { static int esd = -1, player = -1; static int left, right; int *arg = (int *) argp; DPRINTF ("hijacking /dev/mixer ioctl, and sending it to esd " "(%d : %x - %p)\n", fd, request, argp); switch (request) { case SOUND_MIXER_READ_DEVMASK: *arg = 5113; break; case SOUND_MIXER_READ_PCM: mix_init (&esd, &player); if (player > 0) { esd_info_t *all_info; all_info = esd_get_all_info (esd); if (all_info) { esd_player_info_t *player_info; for (player_info = all_info->player_list; player_info; player_info = player_info->next) if (player_info->source_id == player) { *arg = ESD_VOL_TO_OSS (player_info->left_vol_scale, player_info->right_vol_scale); } esd_free_all_info (all_info); } else return -1; } else { get_volume (&left, &right); *arg = ESD_VOL_TO_OSS (left, right); } break; case SOUND_MIXER_WRITE_PCM: mix_init (&esd, &player); left = OSS_VOL_TO_ESD_LEFT (*arg); right = OSS_VOL_TO_ESD_RIGHT (*arg); set_volume (left, right); if (player > 0) { DPRINTF ("panning %d - %d %d\n", player, left, right); esd_set_stream_pan (esd, player, left, right); } break; default: DPRINTF ("unhandled /dev/mixer ioctl (%x - %p)\n", request, argp); break; } return 0; }
/* * to set/get/query special features/parameters */ static int control(int cmd, void *arg) { esd_player_info_t *esd_pi; esd_info_t *esd_i; time_t now; static time_t vol_cache_time; static ao_control_vol_t vol_cache; switch (cmd) { case AOCONTROL_GET_VOLUME: time(&now); if (now == vol_cache_time) { *(ao_control_vol_t *)arg = vol_cache; return CONTROL_OK; } dprintf("esd: get vol\n"); if ((esd_i = esd_get_all_info(esd_fd)) == NULL) return CONTROL_ERROR; for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0) break; if (esd_pi != NULL) { ao_control_vol_t *vol = (ao_control_vol_t *)arg; vol->left = esd_pi->left_vol_scale * 100 / ESD_VOLUME_BASE; vol->right = esd_pi->right_vol_scale * 100 / ESD_VOLUME_BASE; vol_cache = *vol; vol_cache_time = now; } esd_free_all_info(esd_i); return CONTROL_OK; case AOCONTROL_SET_VOLUME: dprintf("esd: set vol\n"); if ((esd_i = esd_get_all_info(esd_fd)) == NULL) return CONTROL_ERROR; for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0) break; if (esd_pi != NULL) { ao_control_vol_t *vol = (ao_control_vol_t *)arg; esd_set_stream_pan(esd_fd, esd_pi->source_id, vol->left * ESD_VOLUME_BASE / 100, vol->right * ESD_VOLUME_BASE / 100); vol_cache = *vol; time(&vol_cache_time); } esd_free_all_info(esd_i); return CONTROL_OK; default: return CONTROL_UNKNOWN; } }