📄 emumixer.c
字号:
static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); struct snd_emu10k1_pcm_mixer *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)]; int change = 0, idx, val; int num_efx = emu->audigy ? 8 : 4; spin_lock_irqsave(&emu->reg_lock, flags); for (idx = 0; idx < 3*num_efx; idx++) { val = ucontrol->value.integer.value[idx] & 255; if (mix->send_volume[idx/num_efx][idx%num_efx] != val) { mix->send_volume[idx/num_efx][idx%num_efx] = val; change = 1; } } if (change && mix->epcm) { if (mix->epcm->voices[0] && mix->epcm->voices[1]) { update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number, &mix->send_volume[1][0]); update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number, &mix->send_volume[2][0]); } else if (mix->epcm->voices[0]) { update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number, &mix->send_volume[0][0]); } } spin_unlock_irqrestore(&emu->reg_lock, flags); return change;}static struct snd_kcontrol_new snd_emu10k1_send_volume_control ={ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "EMU10K1 PCM Send Volume", .count = 32, .info = snd_emu10k1_send_volume_info, .get = snd_emu10k1_send_volume_get, .put = snd_emu10k1_send_volume_put};static int snd_emu10k1_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 3; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0xffff; return 0;}static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); struct snd_emu10k1_pcm_mixer *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)]; unsigned long flags; int idx; spin_lock_irqsave(&emu->reg_lock, flags); for (idx = 0; idx < 3; idx++) ucontrol->value.integer.value[idx] = mix->attn[idx]; spin_unlock_irqrestore(&emu->reg_lock, flags); return 0;}static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); struct snd_emu10k1_pcm_mixer *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)]; int change = 0, idx, val; spin_lock_irqsave(&emu->reg_lock, flags); for (idx = 0; idx < 3; idx++) { val = ucontrol->value.integer.value[idx] & 0xffff; if (mix->attn[idx] != val) { mix->attn[idx] = val; change = 1; } } if (change && mix->epcm) { if (mix->epcm->voices[0] && mix->epcm->voices[1]) { snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]); snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]); } else if (mix->epcm->voices[0]) { snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]); } } spin_unlock_irqrestore(&emu->reg_lock, flags); return change;}static struct snd_kcontrol_new snd_emu10k1_attn_control ={ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "EMU10K1 PCM Volume", .count = 32, .info = snd_emu10k1_attn_info, .get = snd_emu10k1_attn_get, .put = snd_emu10k1_attn_put};/* Mutichannel PCM stream controls */static int snd_emu10k1_efx_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = emu->audigy ? 8 : 4; uinfo->value.integer.min = 0; uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f; return 0;}static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)]; int idx; int num_efx = emu->audigy ? 8 : 4; int mask = emu->audigy ? 0x3f : 0x0f; spin_lock_irqsave(&emu->reg_lock, flags); for (idx = 0; idx < num_efx; idx++) ucontrol->value.integer.value[idx] = mix->send_routing[0][idx] & mask; spin_unlock_irqrestore(&emu->reg_lock, flags); return 0;}static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch]; int change = 0, idx, val; int num_efx = emu->audigy ? 8 : 4; int mask = emu->audigy ? 0x3f : 0x0f; spin_lock_irqsave(&emu->reg_lock, flags); for (idx = 0; idx < num_efx; idx++) { val = ucontrol->value.integer.value[idx] & mask; if (mix->send_routing[0][idx] != val) { mix->send_routing[0][idx] = val; change = 1; } } if (change && mix->epcm) { if (mix->epcm->voices[ch]) { update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number, &mix->send_routing[0][0]); } } spin_unlock_irqrestore(&emu->reg_lock, flags); return change;}static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control ={ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "Multichannel PCM Send Routing", .count = 16, .info = snd_emu10k1_efx_send_routing_info, .get = snd_emu10k1_efx_send_routing_get, .put = snd_emu10k1_efx_send_routing_put};static int snd_emu10k1_efx_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = emu->audigy ? 8 : 4; uinfo->value.integer.min = 0; uinfo->value.integer.max = 255; return 0;}static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)]; int idx; int num_efx = emu->audigy ? 8 : 4; spin_lock_irqsave(&emu->reg_lock, flags); for (idx = 0; idx < num_efx; idx++) ucontrol->value.integer.value[idx] = mix->send_volume[0][idx]; spin_unlock_irqrestore(&emu->reg_lock, flags); return 0;}static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch]; int change = 0, idx, val; int num_efx = emu->audigy ? 8 : 4; spin_lock_irqsave(&emu->reg_lock, flags); for (idx = 0; idx < num_efx; idx++) { val = ucontrol->value.integer.value[idx] & 255; if (mix->send_volume[0][idx] != val) { mix->send_volume[0][idx] = val; change = 1; } } if (change && mix->epcm) { if (mix->epcm->voices[ch]) { update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number, &mix->send_volume[0][0]); } } spin_unlock_irqrestore(&emu->reg_lock, flags); return change;}static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control ={ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "Multichannel PCM Send Volume", .count = 16, .info = snd_emu10k1_efx_send_volume_info, .get = snd_emu10k1_efx_send_volume_get, .put = snd_emu10k1_efx_send_volume_put};static int snd_emu10k1_efx_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0xffff; return 0;}static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)]; unsigned long flags; spin_lock_irqsave(&emu->reg_lock, flags); ucontrol->value.integer.value[0] = mix->attn[0]; spin_unlock_irqrestore(&emu->reg_lock, flags); return 0;}static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch]; int change = 0, val; spin_lock_irqsave(&emu->reg_lock, flags); val = ucontrol->value.integer.value[0] & 0xffff; if (mix->attn[0] != val) { mix->attn[0] = val; change = 1; } if (change && mix->epcm) { if (mix->epcm->voices[ch]) { snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]); } } spin_unlock_irqrestore(&emu->reg_lock, flags); return change;}static struct snd_kcontrol_new snd_emu10k1_efx_attn_control ={ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "Multichannel PCM Volume", .count = 16, .info = snd_emu10k1_efx_attn_info, .get = snd_emu10k1_efx_attn_get, .put = snd_emu10k1_efx_attn_put};static int snd_emu10k1_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0;}static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); if (emu->audigy) ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; else ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; return 0;}static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); unsigned int reg, val; int change = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -