static void mix_init (int *esd, int *player) { esd_info_t *all_info; esd_player_info_t *player_info; if (*esd < 0 && (*esd = esd_open_sound (NULL)) < 0) return; if (*player < 0) { all_info = esd_get_all_info (*esd); if (all_info) { for (player_info = all_info->player_list; player_info; player_info = player_info->next) if (!strcmp(player_info->name, ident)) { *player = player_info->source_id; break; } esd_free_all_info (all_info); } } }
static int ao_esd_get_property (ao_driver_t *this_gen, int property) { esd_driver_t *this = (esd_driver_t *) this_gen; int mixer_fd; esd_player_info_t *esd_pi; esd_info_t *esd_i; switch(property) { case AO_PROP_MIXER_VOL: if((mixer_fd = esd_open_sound(NULL)) >= 0) { if((esd_i = esd_get_all_info(mixer_fd)) != NULL) { for(esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) { if(!strcmp(this->pname, esd_pi->name)) { this->mixer.source_id = esd_pi->source_id; if(!this->mixer.mute) this->mixer.volume = (((esd_pi->left_vol_scale * 100) / 256) + ((esd_pi->right_vol_scale * 100) / 256)) >> 1; } } esd_free_all_info(esd_i); } esd_close(mixer_fd); } return this->mixer.volume; break; case AO_PROP_MUTE_VOL: return this->mixer.mute; break; }
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; } }