mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Added possibility to disable also channel and format conversions + softvol.
Unified disable option using mode bits in snd_pcm_open().
This commit is contained in:
		
							parent
							
								
									6814d23d29
								
							
						
					
					
						commit
						ab8331c882
					
				
					 3 changed files with 55 additions and 38 deletions
				
			
		| 
						 | 
				
			
			@ -707,7 +707,9 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
 | 
			
		|||
	snd_interval_t t, buffer_size;
 | 
			
		||||
	const snd_interval_t *srate, *crate;
 | 
			
		||||
 | 
			
		||||
	if (plug->srate == -2)
 | 
			
		||||
	if (plug->srate == -2 ||
 | 
			
		||||
	    (pcm->mode & pcm->mode & SND_PCM_NO_AUTO_RESAMPLE) ||
 | 
			
		||||
	    (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE))
 | 
			
		||||
		links |= SND_PCM_HW_PARBIT_RATE;
 | 
			
		||||
	else {
 | 
			
		||||
		err = snd_pcm_hw_param_refine_multiple(slave, sparams, SND_PCM_HW_PARAM_RATE, params);
 | 
			
		||||
| 
						 | 
				
			
			@ -715,14 +717,14 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
 | 
			
		|||
			return err;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (plug->schannels == -2)
 | 
			
		||||
	if (plug->schannels == -2 || (pcm->mode & SND_PCM_NO_AUTO_CHANNELS))
 | 
			
		||||
		links |= SND_PCM_HW_PARBIT_CHANNELS;
 | 
			
		||||
	else {
 | 
			
		||||
		err = snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS, params);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
	}
 | 
			
		||||
	if (plug->sformat == -2)
 | 
			
		||||
	if (plug->sformat == -2 || (pcm->mode & SND_PCM_NO_AUTO_FORMAT))
 | 
			
		||||
		links |= SND_PCM_HW_PARBIT_FORMAT;
 | 
			
		||||
	else {
 | 
			
		||||
		format_mask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT);
 | 
			
		||||
| 
						 | 
				
			
			@ -791,8 +793,6 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
 | 
			
		|||
	err = _snd_pcm_hw_params_refine(sparams, links, params);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
	if (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE)
 | 
			
		||||
		snd_interval_copy((snd_interval_t *)snd_pcm_hw_param_get_interval(params, SND_PCM_HW_PARAM_RATE), snd_pcm_hw_param_get_interval(sparams, SND_PCM_HW_PARAM_RATE));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -811,10 +811,10 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
 | 
			
		|||
	const snd_interval_t *sbuffer_size;
 | 
			
		||||
	const snd_interval_t *srate, *crate;
 | 
			
		||||
 | 
			
		||||
	if (plug->schannels == -2)
 | 
			
		||||
	if (plug->schannels == -2 || (pcm->mode & SND_PCM_NO_AUTO_CHANNELS))
 | 
			
		||||
		links |= SND_PCM_HW_PARBIT_CHANNELS;
 | 
			
		||||
 | 
			
		||||
	if (plug->sformat == -2)
 | 
			
		||||
	if (plug->sformat == -2 || (pcm->mode & SND_PCM_NO_AUTO_FORMAT))
 | 
			
		||||
		links |= SND_PCM_HW_PARBIT_FORMAT;
 | 
			
		||||
	else {
 | 
			
		||||
		format_mask = snd_pcm_hw_param_get_mask(params,
 | 
			
		||||
| 
						 | 
				
			
			@ -857,7 +857,9 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
 | 
			
		|||
			return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (plug->srate == -2)
 | 
			
		||||
	if (plug->srate == -2 ||
 | 
			
		||||
	    (pcm->mode & SND_PCM_NO_AUTO_RESAMPLE) ||
 | 
			
		||||
	    (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE))
 | 
			
		||||
		links |= SND_PCM_HW_PARBIT_RATE;
 | 
			
		||||
	else {
 | 
			
		||||
		unsigned int rate_min, srate_min;
 | 
			
		||||
| 
						 | 
				
			
			@ -895,8 +897,6 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
 | 
			
		|||
	err = _snd_pcm_hw_params_refine(params, links, sparams);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
	if (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE)
 | 
			
		||||
		snd_interval_copy((snd_interval_t *)snd_pcm_hw_param_get_interval(params, SND_PCM_HW_PARAM_RATE), snd_pcm_hw_param_get_interval(sparams, SND_PCM_HW_PARAM_RATE));
 | 
			
		||||
	/* FIXME */
 | 
			
		||||
	params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -969,34 +969,43 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
 | 
			
		|||
		SNDERR("Invalid resolution value %d", resolution);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	err = snd_pcm_slave_conf(root, slave, &sconf, 1,
 | 
			
		||||
				 SND_PCM_HW_PARAM_FORMAT, 0, &sformat);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
	if (sformat != SND_PCM_FORMAT_UNKNOWN &&
 | 
			
		||||
	    sformat != SND_PCM_FORMAT_S16_LE &&
 | 
			
		||||
	    sformat != SND_PCM_FORMAT_S16_BE &&
 | 
			
		||||
	    sformat != SND_PCM_FORMAT_S24_3LE && 
 | 
			
		||||
	    sformat != SND_PCM_FORMAT_S32_LE &&
 | 
			
		||||
	    sformat != SND_PCM_FORMAT_S32_BE) {
 | 
			
		||||
		SNDERR("only S16_LE, S16_BE, S24_3LE, S32_LE or S32_BE format "
 | 
			
		||||
		       "is supported");
 | 
			
		||||
	if (mode & SND_PCM_NO_SOFTVOL) {
 | 
			
		||||
		err = snd_pcm_slave_conf(root, slave, &sconf, 0);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
		err = snd_pcm_open_named_slave(pcmp, name, root, sconf, stream,
 | 
			
		||||
					       mode, conf);
 | 
			
		||||
		snd_config_delete(sconf);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	} else {
 | 
			
		||||
		snd_ctl_elem_id_alloca(&ctl_id);
 | 
			
		||||
		err = snd_pcm_slave_conf(root, slave, &sconf, 1,
 | 
			
		||||
					 SND_PCM_HW_PARAM_FORMAT, 0, &sformat);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
		if (sformat != SND_PCM_FORMAT_UNKNOWN &&
 | 
			
		||||
		    sformat != SND_PCM_FORMAT_S16_LE &&
 | 
			
		||||
		    sformat != SND_PCM_FORMAT_S16_BE &&
 | 
			
		||||
		    sformat != SND_PCM_FORMAT_S24_3LE && 
 | 
			
		||||
		    sformat != SND_PCM_FORMAT_S32_LE &&
 | 
			
		||||
		    sformat != SND_PCM_FORMAT_S32_BE) {
 | 
			
		||||
			SNDERR("only S16_LE, S16_BE, S24_3LE, S32_LE or S32_BE format "
 | 
			
		||||
			       "is supported");
 | 
			
		||||
			snd_config_delete(sconf);
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		}
 | 
			
		||||
		err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf);
 | 
			
		||||
		snd_config_delete(sconf);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
		if ((err = snd_pcm_parse_control_id(control, ctl_id, &card, &cchannels, NULL)) < 0) {
 | 
			
		||||
			snd_pcm_close(spcm);
 | 
			
		||||
			return err;
 | 
			
		||||
		}
 | 
			
		||||
		err = snd_pcm_softvol_open(pcmp, name, sformat, card, ctl_id, cchannels,
 | 
			
		||||
					   min_dB, max_dB, resolution, spcm, 1);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			snd_pcm_close(spcm);
 | 
			
		||||
	}
 | 
			
		||||
	err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf);
 | 
			
		||||
	snd_config_delete(sconf);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
	snd_ctl_elem_id_alloca(&ctl_id);
 | 
			
		||||
	if ((err = snd_pcm_parse_control_id(control, ctl_id, &card, &cchannels, NULL)) < 0) {
 | 
			
		||||
		snd_pcm_close(spcm);
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
	err = snd_pcm_softvol_open(pcmp, name, sformat, card, ctl_id, cchannels,
 | 
			
		||||
				   min_dB, max_dB, resolution, spcm, 1);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		snd_pcm_close(spcm);
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
#ifndef DOC_HIDDEN
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue