📄 mixart_mixer.c
字号:
changed = 1; } } if(changed) { if(is_capture) mixart_update_capture_stream_level(chip, is_aes); else mixart_update_playback_stream_level(chip, is_aes, idx); } up(&chip->mgr->mixer_mutex); return changed;}static snd_kcontrol_new_t snd_mixart_pcm_vol ={ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* name will be filled later */ /* count will be filled later */ .info = mixart_digital_vol_info, /* shared */ .get = mixart_pcm_vol_get, .put = mixart_pcm_vol_put,};static int mixart_pcm_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ mixart_t *chip = snd_kcontrol_chip(kcontrol); int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); down(&chip->mgr->mixer_mutex); if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */ idx += MIXART_PLAYBACK_STREAMS; ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0]; ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1]; up(&chip->mgr->mixer_mutex); return 0;}static int mixart_pcm_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ mixart_t *chip = snd_kcontrol_chip(kcontrol); int changed = 0; int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ int i, j; snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); down(&chip->mgr->mixer_mutex); j = idx; if(is_aes) j += MIXART_PLAYBACK_STREAMS; for(i=0; i<2; i++) { if(chip->digital_playback_active[j][i] != ucontrol->value.integer.value[i]) { chip->digital_playback_active[j][i] = ucontrol->value.integer.value[i]; changed = 1; } } if(changed) mixart_update_playback_stream_level(chip, is_aes, idx); up(&chip->mgr->mixer_mutex); return changed;}static snd_kcontrol_new_t mixart_control_pcm_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* name will be filled later */ .count = MIXART_PLAYBACK_STREAMS, .info = mixart_sw_info, /* shared */ .get = mixart_pcm_sw_get, .put = mixart_pcm_sw_put};static int mixart_update_monitoring(mixart_t* chip, int channel){ int err; mixart_msg_t request; mixart_set_out_audio_level_t audio_level; u32 resp; if(chip->pipe_out_ana.status == PIPE_UNDEFINED) return -EINVAL; /* no pipe defined */ if(!channel) request.uid = chip->pipe_out_ana.uid_left_connector; else request.uid = chip->pipe_out_ana.uid_right_connector; request.message_id = MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL; request.data = &audio_level; request.size = sizeof(audio_level); memset(&audio_level, 0, sizeof(audio_level)); audio_level.valid_mask1 = MIXART_AUDIO_LEVEL_MONITOR_MASK | MIXART_AUDIO_LEVEL_MUTE_M1_MASK; audio_level.monitor_level = mixart_digital_level[chip->monitoring_volume[channel!=0]]; audio_level.monitor_mute1 = !chip->monitoring_active[channel!=0]; err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp); if((err<0) || resp) { snd_printk(KERN_DEBUG "error MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL card(%d) resp(%x)\n", chip->chip_idx, resp); return -EINVAL; } return 0;}/* * monitoring level control */static int mixart_monitor_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ mixart_t *chip = snd_kcontrol_chip(kcontrol); down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->monitoring_volume[0]; ucontrol->value.integer.value[1] = chip->monitoring_volume[1]; up(&chip->mgr->mixer_mutex); return 0;}static int mixart_monitor_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ mixart_t *chip = snd_kcontrol_chip(kcontrol); int changed = 0; int i; down(&chip->mgr->mixer_mutex); for(i=0; i<2; i++) { if(chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) { chip->monitoring_volume[i] = ucontrol->value.integer.value[i]; mixart_update_monitoring(chip, i); changed = 1; } } up(&chip->mgr->mixer_mutex); return changed;}static snd_kcontrol_new_t mixart_control_monitor_vol = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Monitoring Volume", .info = mixart_digital_vol_info, /* shared */ .get = mixart_monitor_vol_get, .put = mixart_monitor_vol_put,};/* * monitoring switch control */static int mixart_monitor_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ mixart_t *chip = snd_kcontrol_chip(kcontrol); down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->monitoring_active[0]; ucontrol->value.integer.value[1] = chip->monitoring_active[1]; up(&chip->mgr->mixer_mutex); return 0;}static int mixart_monitor_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ mixart_t *chip = snd_kcontrol_chip(kcontrol); int changed = 0; int i; down(&chip->mgr->mixer_mutex); for(i=0; i<2; i++) { if(chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { chip->monitoring_active[i] = ucontrol->value.integer.value[i]; changed |= (1<<i); /* mask 0x01 ans 0x02 */ } } if(changed) { /* allocate or release resources for monitoring */ int allocate = chip->monitoring_active[0] || chip->monitoring_active[1]; if(allocate) { snd_mixart_add_ref_pipe( chip, MIXART_PCM_ANALOG, 0, 1); /* allocate the playback pipe for monitoring */ snd_mixart_add_ref_pipe( chip, MIXART_PCM_ANALOG, 1, 1); /* allocate the capture pipe for monitoring */ } if(changed & 0x01) mixart_update_monitoring(chip, 0); if(changed & 0x02) mixart_update_monitoring(chip, 1); if(!allocate) { snd_mixart_kill_ref_pipe( chip->mgr, &chip->pipe_in_ana, 1); /* release the capture pipe for monitoring */ snd_mixart_kill_ref_pipe( chip->mgr, &chip->pipe_out_ana, 1); /* release the playback pipe for monitoring */ } } up(&chip->mgr->mixer_mutex); return (changed != 0);}static snd_kcontrol_new_t mixart_control_monitor_sw = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Monitoring Switch", .info = mixart_sw_info, /* shared */ .get = mixart_monitor_sw_get, .put = mixart_monitor_sw_put};static void mixart_reset_audio_levels(mixart_t *chip){ /* analog volumes can be set even if there is no pipe */ mixart_update_analog_audio_level(chip, 0); /* analog levels for capture only on the first two chips */ if(chip->chip_idx < 2) { mixart_update_analog_audio_level(chip, 1); } return;}int snd_mixart_create_mixer(mixart_mgr_t *mgr){ mixart_t *chip; int err, i; init_MUTEX(&mgr->mixer_mutex); /* can be in another place */ for(i=0; i<mgr->num_cards; i++) { snd_kcontrol_new_t temp; chip = mgr->chip[i]; /* analog output level control */ temp = mixart_control_analog_level; temp.name = "Master Playback Volume"; temp.private_value = 0; /* playback */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; /* output mute controls */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip))) < 0) return err; /* analog input level control only on first two chips !*/ if(i<2) { temp = mixart_control_analog_level; temp.name = "Master Capture Volume"; temp.private_value = 1; /* capture */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; } temp = snd_mixart_pcm_vol; temp.name = "PCM Playback Volume"; temp.count = MIXART_PLAYBACK_STREAMS; temp.private_value = 0; /* playback analog */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; temp.name = "PCM Capture Volume"; temp.count = 1; temp.private_value = MIXART_VOL_REC_MASK; /* capture analog */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) { temp.name = "AES Playback Volume"; temp.count = MIXART_PLAYBACK_STREAMS; temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; temp.name = "AES Capture Volume"; temp.count = 0; temp.private_value = MIXART_VOL_REC_MASK | MIXART_VOL_AES_MASK; /* capture AES/EBU */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; } temp = mixart_control_pcm_switch; temp.name = "PCM Playback Switch"; temp.private_value = 0; /* playback analog */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) { temp.name = "AES Playback Switch"; temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) return err; } /* monitoring */ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip))) < 0) return err; if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip))) < 0) return err; /* init all mixer data and program the master volumes/switches */ mixart_reset_audio_levels(chip); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -