📄 emumixer.c
字号:
get: snd_emu10k1_send_volume_get, put: snd_emu10k1_send_volume_put};static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * 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(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ emu10k1_pcm_mixer_t *mix = (emu10k1_pcm_mixer_t *)kcontrol->private_value; emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 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(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ unsigned long flags; emu10k1_pcm_mixer_t *mix = (emu10k1_pcm_mixer_t *)kcontrol->private_value; emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 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 snd_kcontrol_new_t snd_emu10k1_attn_control ={ access: SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: "EMU10K1 PCM Volume", info: snd_emu10k1_attn_info, get: snd_emu10k1_attn_get, put: snd_emu10k1_attn_put};static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * 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(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ emu10k1_t *emu = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 0 : 1; return 0;}static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ unsigned long flags; emu10k1_t *emu = snd_kcontrol_chip(kcontrol); unsigned int reg, val; int change; spin_lock_irqsave(&emu->reg_lock, flags); reg = inl(emu->port + HCFG); val = ucontrol->value.integer.value[0] & 1 ? 0 : HCFG_GPOUT0; change = (reg & HCFG_GPOUT0) != val; reg &= ~HCFG_GPOUT0; reg |= val; outl(reg | val, emu->port + HCFG); spin_unlock_irqrestore(&emu->reg_lock, flags); return change;}static snd_kcontrol_new_t snd_emu10k1_shared_spdif ={ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: "SB Live Analog/Digital Output Jack", info: snd_emu10k1_shared_spdif_info, get: snd_emu10k1_shared_spdif_get, put: snd_emu10k1_shared_spdif_put};#if 0 // XXX: not working yet../* * Audigy analog / digital switches */static int audigy_output_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * 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 audigy_output_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ emu10k1_t *emu = snd_kcontrol_chip(kcontrol); unsigned int mask = (unsigned int)kcontrol->private_value; ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & mask ? 0 : 1; return 0;}static int audigy_output_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ unsigned long flags; emu10k1_t *emu = snd_kcontrol_chip(kcontrol); unsigned int mask = (unsigned int)kcontrol->private_value; unsigned int reg, oreg; int change; spin_lock_irqsave(&emu->reg_lock, flags); reg = oreg = inl(emu->port + A_IOCFG); reg &= ~mask; reg |= ucontrol->value.integer.value[0] & 1 ? 0 : mask; change = (reg != oreg); if (change) outl(reg, emu->port + A_IOCFG); spin_unlock_irqrestore(&emu->reg_lock, flags); return change;}static snd_kcontrol_new_t audigy_output_analog ={ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: "Audigy Analog Output Switch", info: audigy_output_info, get: audigy_output_get, put: audigy_output_put, private_value: 0x40,};static snd_kcontrol_new_t audigy_output_digital ={ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: "Audigy Digital Output Switch", info: audigy_output_info, get: audigy_output_get, put: audigy_output_put, private_value: 0x04,};#endif // XXX/* */static void snd_emu10k1_mixer_free_ac97(ac97_t *ac97){ emu10k1_t *emu = snd_magic_cast(emu10k1_t, ac97->private_data, return); emu->ac97 = NULL;}int __devinit snd_emu10k1_mixer(emu10k1_t *emu){ ac97_t ac97; int err, pcm, idx; snd_kcontrol_t *kctl; snd_card_t *card = emu->card; if (!emu->APS) { memset(&ac97, 0, sizeof(ac97)); ac97.write = snd_emu10k1_ac97_write; ac97.read = snd_emu10k1_ac97_read; ac97.private_data = emu; ac97.private_free = snd_emu10k1_mixer_free_ac97; if ((err = snd_ac97_mixer(emu->card, &ac97, &emu->ac97)) < 0) return err; } else { strcpy(emu->card->mixername, "EMU APS"); } for (pcm = 0; pcm < 32; pcm++) { emu10k1_pcm_mixer_t *mix; int v; mix = &emu->pcm_mixer[pcm]; mix->epcm = NULL; if ((kctl = mix->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL) return -ENOMEM; kctl->private_value = (long)mix; kctl->id.index = pcm; if ((err = snd_ctl_add(card, kctl))) return err; for (v = 0; v < 4; v++) mix->send_routing[0][v] = mix->send_routing[1][v] = mix->send_routing[2][v] = v; if ((kctl = mix->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL) return -ENOMEM; kctl->private_value = (long)mix; kctl->id.index = pcm; if ((err = snd_ctl_add(card, kctl))) return err; memset(&mix->send_volume, 0, sizeof(mix->send_volume)); mix->send_volume[0][0] = mix->send_volume[0][1] = mix->send_volume[1][0] = mix->send_volume[2][1] = 255; if ((kctl = mix->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL) return -ENOMEM; kctl->private_value = (long)mix; kctl->id.index = pcm; if ((err = snd_ctl_add(card, kctl))) return err; mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff; } for (idx = 0; idx < 3; idx++) { if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL) return -ENOMEM; kctl->private_value = idx; kctl->id.index = idx; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL) return -ENOMEM; kctl->private_value = idx; kctl->id.index = idx; if ((err = snd_ctl_add(card, kctl))) return err; } if (emu->audigy) {#if 0 // XXX if ((kctl = snd_ctl_new1(&audigy_output_analog, emu)) == NULL) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = snd_ctl_new1(&audigy_output_digital, emu)) == NULL) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err;#endif // XXX } else { if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -