mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Fix buffer size handling of direct plugins
Introduce "max_periods" option to specify the max number of periods per buffer to each plugin. - When max_periods = -1, the fixed buffer size as the slave size is used (old behavior). - When max_periods = 0 (or 1), the number of periods is variable between 2 and the slave buffer size. - When max_periods greater than 2 is given, it specifies the max periods of that pcm explicitly. When no option is given in the PCM defintion, the value "defaults.pcm.dmix_max_periods" is referred as default. The default value is 0, as defined in alsa.conf. You can override this in ~/.asoundrc or /etc/asound.conf as you like.
This commit is contained in:
		
							parent
							
								
									33d69ef33b
								
							
						
					
					
						commit
						1128efc7d4
					
				
					 7 changed files with 41 additions and 56 deletions
				
			
		| 
						 | 
					@ -57,7 +57,7 @@ defaults.pcm.nonblock 1
 | 
				
			||||||
defaults.pcm.ipc_key 5678293
 | 
					defaults.pcm.ipc_key 5678293
 | 
				
			||||||
defaults.pcm.ipc_gid audio
 | 
					defaults.pcm.ipc_gid audio
 | 
				
			||||||
defaults.pcm.ipc_perm 0660
 | 
					defaults.pcm.ipc_perm 0660
 | 
				
			||||||
defaults.pcm.dmix_variable_buffer true
 | 
					defaults.pcm.dmix_max_periods 0
 | 
				
			||||||
defaults.pcm.front.card defaults.pcm.card
 | 
					defaults.pcm.front.card defaults.pcm.card
 | 
				
			||||||
defaults.pcm.front.device defaults.pcm.device
 | 
					defaults.pcm.front.device defaults.pcm.device
 | 
				
			||||||
defaults.pcm.rear.card defaults.pcm.card
 | 
					defaults.pcm.rear.card defaults.pcm.card
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,9 +92,4 @@ pcm.!dmix {
 | 
				
			||||||
			default 16
 | 
								default 16
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	# Allow apps different buffer sizes
 | 
					 | 
				
			||||||
	variable_buffer_size {
 | 
					 | 
				
			||||||
		@func refer
 | 
					 | 
				
			||||||
		name defaults.pcm.dmix_variable_buffer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -697,7 +697,7 @@ int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 | 
				
			||||||
					   &dshare->shmptr->hw.period_time);
 | 
										   &dshare->shmptr->hw.period_time);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	if (! dshare->variable_buffer_size) {
 | 
						if (dshare->max_periods < 0) {
 | 
				
			||||||
		err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
 | 
							err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
 | 
				
			||||||
						   &dshare->shmptr->hw.buffer_size);
 | 
											   &dshare->shmptr->hw.buffer_size);
 | 
				
			||||||
		if (err < 0)
 | 
							if (err < 0)
 | 
				
			||||||
| 
						 | 
					@ -711,13 +711,13 @@ int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 | 
				
			||||||
				    (1<<SND_PCM_HW_PARAM_BUFFER_SIZE)|
 | 
									    (1<<SND_PCM_HW_PARAM_BUFFER_SIZE)|
 | 
				
			||||||
				    (1<<SND_PCM_HW_PARAM_BUFFER_TIME))) {
 | 
									    (1<<SND_PCM_HW_PARAM_BUFFER_TIME))) {
 | 
				
			||||||
		int changed;
 | 
							int changed;
 | 
				
			||||||
 | 
							unsigned int max_periods = dshare->max_periods;
 | 
				
			||||||
 | 
							if (max_periods < 2)
 | 
				
			||||||
 | 
								max_periods = dshare->slave_buffer_size / dshare->slave_period_size;
 | 
				
			||||||
		do {
 | 
							do {
 | 
				
			||||||
			changed = 0;
 | 
								changed = 0;
 | 
				
			||||||
			/* Set min/max size to [2:1024] since INT_MAX as the
 | 
					 | 
				
			||||||
			 * upper-limit results in a too big buffer on some apps.
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			err = hw_param_interval_refine_minmax(params, SND_PCM_HW_PARAM_PERIODS,
 | 
								err = hw_param_interval_refine_minmax(params, SND_PCM_HW_PARAM_PERIODS,
 | 
				
			||||||
							      2, 1024);
 | 
												      2, max_periods);
 | 
				
			||||||
			if (err < 0)
 | 
								if (err < 0)
 | 
				
			||||||
				return err;
 | 
									return err;
 | 
				
			||||||
			changed |= err;
 | 
								changed |= err;
 | 
				
			||||||
| 
						 | 
					@ -1382,17 +1382,19 @@ static int _snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
 | 
				
			||||||
	return (direction << 1) + (device << 2) + (subdevice << 8) + (card << 12);
 | 
						return (direction << 1) + (device << 2) + (subdevice << 8) + (card << 12);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
 | 
					static int snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
 | 
				
			||||||
					snd_config_t *sconf,
 | 
										snd_config_t *sconf,
 | 
				
			||||||
					int direction)
 | 
										int direction)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return _snd_pcm_direct_get_slave_ipc_offset(root, sconf, direction, 0);
 | 
						return _snd_pcm_direct_get_slave_ipc_offset(root, sconf, direction, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_open_conf *rec)
 | 
					int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
 | 
				
			||||||
 | 
									   int stream, struct snd_pcm_direct_open_conf *rec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_config_iterator_t i, next;
 | 
						snd_config_iterator_t i, next;
 | 
				
			||||||
	int ipc_key_add_uid = 0;
 | 
						int ipc_key_add_uid = 0;
 | 
				
			||||||
 | 
						snd_config_t *n;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rec->slave = NULL;
 | 
						rec->slave = NULL;
 | 
				
			||||||
| 
						 | 
					@ -1401,10 +1403,18 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_ope
 | 
				
			||||||
	rec->ipc_perm = 0600;
 | 
						rec->ipc_perm = 0600;
 | 
				
			||||||
	rec->ipc_gid = -1;
 | 
						rec->ipc_gid = -1;
 | 
				
			||||||
	rec->slowptr = 0;
 | 
						rec->slowptr = 0;
 | 
				
			||||||
	rec->variable_buffer_size = 0;
 | 
						rec->max_periods = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* read defaults */
 | 
				
			||||||
 | 
						if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) {
 | 
				
			||||||
 | 
							long val;
 | 
				
			||||||
 | 
							err = snd_config_get_integer(n, &val);
 | 
				
			||||||
 | 
							if (err >= 0)
 | 
				
			||||||
 | 
								rec->max_periods = val;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_config_for_each(i, next, conf) {
 | 
						snd_config_for_each(i, next, conf) {
 | 
				
			||||||
		snd_config_t *n = snd_config_iterator_entry(i);
 | 
							n = snd_config_iterator_entry(i);
 | 
				
			||||||
		const char *id;
 | 
							const char *id;
 | 
				
			||||||
		if (snd_config_get_id(n, &id) < 0)
 | 
							if (snd_config_get_id(n, &id) < 0)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
| 
						 | 
					@ -1488,11 +1498,12 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_ope
 | 
				
			||||||
			rec->slowptr = err;
 | 
								rec->slowptr = err;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (strcmp(id, "variable_buffer_size") == 0) {
 | 
							if (strcmp(id, "max_periods") == 0) {
 | 
				
			||||||
			err = snd_config_get_bool(n);
 | 
								long val;
 | 
				
			||||||
 | 
								err = snd_config_get_integer(n, &val);
 | 
				
			||||||
			if (err < 0)
 | 
								if (err < 0)
 | 
				
			||||||
				return err;
 | 
									return err;
 | 
				
			||||||
			rec->variable_buffer_size = err;
 | 
								rec->max_periods = val;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		SNDERR("Unknown field %s", id);
 | 
							SNDERR("Unknown field %s", id);
 | 
				
			||||||
| 
						 | 
					@ -1502,11 +1513,16 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_ope
 | 
				
			||||||
		SNDERR("slave is not defined");
 | 
							SNDERR("slave is not defined");
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (ipc_key_add_uid)
 | 
					 | 
				
			||||||
		rec->ipc_key += getuid();
 | 
					 | 
				
			||||||
	if (!rec->ipc_key) {
 | 
						if (!rec->ipc_key) {
 | 
				
			||||||
		SNDERR("Unique IPC key is not defined");
 | 
							SNDERR("Unique IPC key is not defined");
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (ipc_key_add_uid)
 | 
				
			||||||
 | 
							rec->ipc_key += getuid();
 | 
				
			||||||
 | 
						err = snd_pcm_direct_get_slave_ipc_offset(root, rec->slave, stream);
 | 
				
			||||||
 | 
						if (err < 0)
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
 | 
						rec->ipc_key += err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ struct snd_pcm_direct {
 | 
				
			||||||
	snd_timer_t *timer; 		/* timer used as poll_fd */
 | 
						snd_timer_t *timer; 		/* timer used as poll_fd */
 | 
				
			||||||
	int interleaved;	 	/* we have interleaved buffer */
 | 
						int interleaved;	 	/* we have interleaved buffer */
 | 
				
			||||||
	int slowptr;			/* use slow but more precise ptr updates */
 | 
						int slowptr;			/* use slow but more precise ptr updates */
 | 
				
			||||||
	int variable_buffer_size;	/* allow the variable buffer size */
 | 
						int max_periods;		/* max periods (-1 = fixed periods, 0 = max buffer size) */
 | 
				
			||||||
	unsigned int channels;		/* client's channels */
 | 
						unsigned int channels;		/* client's channels */
 | 
				
			||||||
	unsigned int *bindings;
 | 
						unsigned int *bindings;
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
| 
						 | 
					@ -187,7 +187,6 @@ int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix);
 | 
				
			||||||
void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix);
 | 
					void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix);
 | 
				
			||||||
int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix);
 | 
					int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix);
 | 
				
			||||||
int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name);
 | 
					int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name);
 | 
				
			||||||
int snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root, snd_config_t *sconf, int direction);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
 | 
					int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
 | 
				
			||||||
struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
 | 
					struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
 | 
				
			||||||
| 
						 | 
					@ -197,9 +196,9 @@ struct snd_pcm_direct_open_conf {
 | 
				
			||||||
	mode_t ipc_perm;
 | 
						mode_t ipc_perm;
 | 
				
			||||||
	int ipc_gid;
 | 
						int ipc_gid;
 | 
				
			||||||
	int slowptr;
 | 
						int slowptr;
 | 
				
			||||||
	int variable_buffer_size;
 | 
						int max_periods;
 | 
				
			||||||
	snd_config_t *slave;
 | 
						snd_config_t *slave;
 | 
				
			||||||
	snd_config_t *bindings;
 | 
						snd_config_t *bindings;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_open_conf *rec);
 | 
					int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf, int stream, struct snd_pcm_direct_open_conf *rec);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -487,8 +487,7 @@ static int snd_pcm_dmix_prepare(snd_pcm_t *pcm)
 | 
				
			||||||
static void reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
 | 
					static void reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
 | 
						dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
 | 
				
			||||||
	if (! dmix->variable_buffer_size ||
 | 
						if (pcm->buffer_size > pcm->period_size * 2)
 | 
				
			||||||
	    pcm->buffer_size > pcm->period_size * 2)
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	/* If we have too litte periods, better to align the start position
 | 
						/* If we have too litte periods, better to align the start position
 | 
				
			||||||
	 * to the period boundary so that the interrupt can be handled properly
 | 
						 * to the period boundary so that the interrupt can be handled properly
 | 
				
			||||||
| 
						 | 
					@ -851,7 +850,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	pcm->private_data = dmix;
 | 
						pcm->private_data = dmix;
 | 
				
			||||||
	dmix->state = SND_PCM_STATE_OPEN;
 | 
						dmix->state = SND_PCM_STATE_OPEN;
 | 
				
			||||||
	dmix->slowptr = opts->slowptr;
 | 
						dmix->slowptr = opts->slowptr;
 | 
				
			||||||
	dmix->variable_buffer_size = opts->variable_buffer_size;
 | 
						dmix->max_periods = opts->max_periods;
 | 
				
			||||||
	dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
 | 
						dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (first_instance) {
 | 
						if (first_instance) {
 | 
				
			||||||
| 
						 | 
					@ -1092,10 +1091,9 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	struct slave_params params;
 | 
						struct slave_params params;
 | 
				
			||||||
	struct snd_pcm_direct_open_conf dopen;
 | 
						struct snd_pcm_direct_open_conf dopen;
 | 
				
			||||||
	int bsize, psize;
 | 
						int bsize, psize;
 | 
				
			||||||
	int ipc_offset;
 | 
					 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = snd_pcm_direct_parse_open_conf(conf, &dopen);
 | 
						err = snd_pcm_direct_parse_open_conf(root, conf, stream, &dopen);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1134,13 +1132,6 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	params.period_size = psize;
 | 
						params.period_size = psize;
 | 
				
			||||||
	params.buffer_size = bsize;
 | 
						params.buffer_size = bsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ipc_offset = snd_pcm_direct_get_slave_ipc_offset(root, sconf, stream);
 | 
					 | 
				
			||||||
	if (ipc_offset < 0) {
 | 
					 | 
				
			||||||
		snd_config_delete(sconf);
 | 
					 | 
				
			||||||
		return ipc_offset;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dopen.ipc_key += ipc_offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = snd_pcm_dmix_open(pcmp, name, &dopen, ¶ms,
 | 
						err = snd_pcm_dmix_open(pcmp, name, &dopen, ¶ms,
 | 
				
			||||||
				root, sconf, stream, mode);
 | 
									root, sconf, stream, mode);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -662,7 +662,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	pcm->private_data = dshare;
 | 
						pcm->private_data = dshare;
 | 
				
			||||||
	dshare->state = SND_PCM_STATE_OPEN;
 | 
						dshare->state = SND_PCM_STATE_OPEN;
 | 
				
			||||||
	dshare->slowptr = opts->slowptr;
 | 
						dshare->slowptr = opts->slowptr;
 | 
				
			||||||
	dshare->variable_buffer_size = opts->variable_buffer_size;
 | 
						dshare->max_periods = opts->max_periods;
 | 
				
			||||||
	dshare->sync_ptr = snd_pcm_dshare_sync_ptr;
 | 
						dshare->sync_ptr = snd_pcm_dshare_sync_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (first_instance) {
 | 
						if (first_instance) {
 | 
				
			||||||
| 
						 | 
					@ -835,10 +835,9 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	struct slave_params params;
 | 
						struct slave_params params;
 | 
				
			||||||
	struct snd_pcm_direct_open_conf dopen;
 | 
						struct snd_pcm_direct_open_conf dopen;
 | 
				
			||||||
	int bsize, psize;
 | 
						int bsize, psize;
 | 
				
			||||||
	int ipc_offset;
 | 
					 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = snd_pcm_direct_parse_open_conf(conf, &dopen);
 | 
						err = snd_pcm_direct_parse_open_conf(root, conf, stream, &dopen);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -869,13 +868,6 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	params.period_size = psize;
 | 
						params.period_size = psize;
 | 
				
			||||||
	params.buffer_size = bsize;
 | 
						params.buffer_size = bsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ipc_offset = snd_pcm_direct_get_slave_ipc_offset(root, sconf, stream);
 | 
					 | 
				
			||||||
	if (ipc_offset < 0) {
 | 
					 | 
				
			||||||
		snd_config_delete(sconf);
 | 
					 | 
				
			||||||
		return ipc_offset;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dopen.ipc_key += ipc_offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = snd_pcm_dshare_open(pcmp, name, &dopen, ¶ms,
 | 
						err = snd_pcm_dshare_open(pcmp, name, &dopen, ¶ms,
 | 
				
			||||||
				  root, sconf, stream, mode);
 | 
									  root, sconf, stream, mode);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -544,7 +544,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	pcm->private_data = dsnoop;
 | 
						pcm->private_data = dsnoop;
 | 
				
			||||||
	dsnoop->state = SND_PCM_STATE_OPEN;
 | 
						dsnoop->state = SND_PCM_STATE_OPEN;
 | 
				
			||||||
	dsnoop->slowptr = opts->slowptr;
 | 
						dsnoop->slowptr = opts->slowptr;
 | 
				
			||||||
	dsnoop->variable_buffer_size = opts->variable_buffer_size;
 | 
						dsnoop->max_periods = opts->max_periods;
 | 
				
			||||||
	dsnoop->sync_ptr = snd_pcm_dsnoop_sync_ptr;
 | 
						dsnoop->sync_ptr = snd_pcm_dsnoop_sync_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (first_instance) {
 | 
						if (first_instance) {
 | 
				
			||||||
| 
						 | 
					@ -707,10 +707,9 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	struct slave_params params;
 | 
						struct slave_params params;
 | 
				
			||||||
	struct snd_pcm_direct_open_conf dopen;
 | 
						struct snd_pcm_direct_open_conf dopen;
 | 
				
			||||||
	int bsize, psize;
 | 
						int bsize, psize;
 | 
				
			||||||
	int ipc_offset;
 | 
					 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = snd_pcm_direct_parse_open_conf(conf, &dopen);
 | 
						err = snd_pcm_direct_parse_open_conf(root, conf, stream, &dopen);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -741,13 +740,6 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	params.period_size = psize;
 | 
						params.period_size = psize;
 | 
				
			||||||
	params.buffer_size = bsize;
 | 
						params.buffer_size = bsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ipc_offset = snd_pcm_direct_get_slave_ipc_offset(root, sconf, stream);
 | 
					 | 
				
			||||||
	if (ipc_offset < 0) {
 | 
					 | 
				
			||||||
		snd_config_delete(sconf);
 | 
					 | 
				
			||||||
		return ipc_offset;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dopen.ipc_key += ipc_offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = snd_pcm_dsnoop_open(pcmp, name, &dopen, ¶ms,
 | 
						err = snd_pcm_dsnoop_open(pcmp, name, &dopen, ¶ms,
 | 
				
			||||||
				  root, sconf, stream, mode);
 | 
									  root, sconf, stream, mode);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue