mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Fix direct plugins running on 32bit emulation with 64bit arch
Fix the problems of dmix/dsnoop/dshare plugins running on 32bit mode with 64bit biarch.
This commit is contained in:
		
							parent
							
								
									99005614ba
								
							
						
					
					
						commit
						e80f80866f
					
				
					 5 changed files with 147 additions and 108 deletions
				
			
		| 
						 | 
					@ -532,7 +532,7 @@ static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int hw_param_interval_refine_one(snd_pcm_hw_params_t *params,
 | 
					static int hw_param_interval_refine_one(snd_pcm_hw_params_t *params,
 | 
				
			||||||
					snd_pcm_hw_param_t var,
 | 
										snd_pcm_hw_param_t var,
 | 
				
			||||||
					snd_pcm_hw_params_t *src)
 | 
										snd_interval_t *src)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_interval_t *i;
 | 
						snd_interval_t *i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -543,7 +543,7 @@ static int hw_param_interval_refine_one(snd_pcm_hw_params_t *params,
 | 
				
			||||||
		SNDERR("dshare interval %i empty?", (int)var);
 | 
							SNDERR("dshare interval %i empty?", (int)var);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (snd_interval_refine(i, hw_param_interval(src, var)))
 | 
						if (snd_interval_refine(i, src))
 | 
				
			||||||
		params->cmask |= 1<<var;
 | 
							params->cmask |= 1<<var;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -553,7 +553,6 @@ static int hw_param_interval_refine_one(snd_pcm_hw_params_t *params,
 | 
				
			||||||
int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 | 
					int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_pcm_direct_t *dshare = pcm->private_data;
 | 
						snd_pcm_direct_t *dshare = pcm->private_data;
 | 
				
			||||||
	snd_pcm_hw_params_t *hw_params = &dshare->shmptr->hw_params;
 | 
					 | 
				
			||||||
	static snd_mask_t access = { .bits = { 
 | 
						static snd_mask_t access = { .bits = { 
 | 
				
			||||||
					(1<<SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) |
 | 
										(1<<SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) |
 | 
				
			||||||
					(1<<SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) |
 | 
										(1<<SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) |
 | 
				
			||||||
| 
						 | 
					@ -582,7 +581,7 @@ int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (snd_mask_refine_set(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT),
 | 
							if (snd_mask_refine_set(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT),
 | 
				
			||||||
				        snd_mask_value(hw_param_mask(hw_params, SND_PCM_HW_PARAM_FORMAT))))
 | 
										dshare->shmptr->hw.format))
 | 
				
			||||||
			params->cmask |= 1<<SND_PCM_HW_PARAM_FORMAT;
 | 
								params->cmask |= 1<<SND_PCM_HW_PARAM_FORMAT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//snd_mask_none(hw_param_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
 | 
						//snd_mask_none(hw_param_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
 | 
				
			||||||
| 
						 | 
					@ -595,22 +594,28 @@ int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 | 
				
			||||||
		if (err < 0)
 | 
							if (err < 0)
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_RATE, hw_params);
 | 
						err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_RATE,
 | 
				
			||||||
 | 
										   &dshare->shmptr->hw.rate);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE, hw_params);
 | 
						err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
 | 
				
			||||||
 | 
										   &dshare->shmptr->hw.buffer_size);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_TIME, hw_params);
 | 
						err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_TIME,
 | 
				
			||||||
 | 
										   &dshare->shmptr->hw.buffer_time);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_SIZE, hw_params);
 | 
						err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_SIZE,
 | 
				
			||||||
 | 
										   &dshare->shmptr->hw.period_size);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_TIME, hw_params);
 | 
						err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_TIME,
 | 
				
			||||||
 | 
										   &dshare->shmptr->hw.period_time);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIODS, hw_params);
 | 
						err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIODS,
 | 
				
			||||||
 | 
										   &dshare->shmptr->hw.periods);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	params->info = dshare->shmptr->s.info;
 | 
						params->info = dshare->shmptr->s.info;
 | 
				
			||||||
| 
						 | 
					@ -675,8 +680,8 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
 | 
				
			||||||
	struct pollfd fd;
 | 
						struct pollfd fd;
 | 
				
			||||||
	int loops = 10;
 | 
						int loops = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hw_params = &dmix->shmptr->hw_params;
 | 
						snd_pcm_hw_params_alloca(&hw_params);
 | 
				
			||||||
	sw_params = &dmix->shmptr->sw_params;
 | 
						snd_pcm_sw_params_alloca(&sw_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      __again:
 | 
					      __again:
 | 
				
			||||||
      	if (loops-- <= 0) {
 | 
					      	if (loops-- <= 0) {
 | 
				
			||||||
| 
						 | 
					@ -800,6 +805,16 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* store some hw_params values to shared info */
 | 
				
			||||||
 | 
						dmix->shmptr->hw.format = snd_mask_value(hw_param_mask(hw_params, SND_PCM_HW_PARAM_FORMAT));
 | 
				
			||||||
 | 
						dmix->shmptr->hw.rate = *hw_param_interval(hw_params, SND_PCM_HW_PARAM_RATE);
 | 
				
			||||||
 | 
						dmix->shmptr->hw.buffer_size = *hw_param_interval(hw_params, SND_PCM_HW_PARAM_BUFFER_SIZE);
 | 
				
			||||||
 | 
						dmix->shmptr->hw.buffer_time = *hw_param_interval(hw_params, SND_PCM_HW_PARAM_BUFFER_TIME);
 | 
				
			||||||
 | 
						dmix->shmptr->hw.period_size = *hw_param_interval(hw_params, SND_PCM_HW_PARAM_PERIOD_SIZE);
 | 
				
			||||||
 | 
						dmix->shmptr->hw.period_time = *hw_param_interval(hw_params, SND_PCM_HW_PARAM_PERIOD_TIME);
 | 
				
			||||||
 | 
						dmix->shmptr->hw.periods = *hw_param_interval(hw_params, SND_PCM_HW_PARAM_PERIODS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = snd_pcm_sw_params_current(spcm, sw_params);
 | 
						ret = snd_pcm_sw_params_current(spcm, sw_params);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		SNDERR("unable to get current sw_params");
 | 
							SNDERR("unable to get current sw_params");
 | 
				
			||||||
| 
						 | 
					@ -865,10 +880,20 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
 | 
				
			||||||
	dmix->shmptr->s.channels = spcm->channels;
 | 
						dmix->shmptr->s.channels = spcm->channels;
 | 
				
			||||||
	dmix->shmptr->s.rate = spcm->rate;
 | 
						dmix->shmptr->s.rate = spcm->rate;
 | 
				
			||||||
	dmix->shmptr->s.format = spcm->format;
 | 
						dmix->shmptr->s.format = spcm->format;
 | 
				
			||||||
	dmix->shmptr->s.boundary = spcm->boundary;
 | 
					 | 
				
			||||||
	dmix->shmptr->s.info = spcm->info & ~SND_PCM_INFO_PAUSE;
 | 
						dmix->shmptr->s.info = spcm->info & ~SND_PCM_INFO_PAUSE;
 | 
				
			||||||
	dmix->shmptr->s.msbits = spcm->msbits;
 | 
						dmix->shmptr->s.msbits = spcm->msbits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Currently, we assume that each dmix client has the same
 | 
				
			||||||
 | 
						 * hw_params setting.
 | 
				
			||||||
 | 
						 * If the arbitrary hw_parmas is supported in future,
 | 
				
			||||||
 | 
						 * boundary has to be taken from the slave config but
 | 
				
			||||||
 | 
						 * recalculated for the native boundary size (for 32bit
 | 
				
			||||||
 | 
						 * emulation on 64bit arch).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						dmix->slave_buffer_size = spcm->buffer_size;
 | 
				
			||||||
 | 
						dmix->slave_period_size = spcm->period_size;
 | 
				
			||||||
 | 
						dmix->slave_boundary = spcm->boundary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spcm->donot_close = 1;
 | 
						spcm->donot_close = 1;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -936,6 +961,54 @@ int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static snd_pcm_uframes_t recalc_boundary_size(unsigned long long bsize, snd_pcm_uframes_t buffer_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (bsize > LONG_MAX) {
 | 
				
			||||||
 | 
							bsize = buffer_size;
 | 
				
			||||||
 | 
							while (bsize * 2 <= LONG_MAX - buffer_size)
 | 
				
			||||||
 | 
								bsize *= 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (snd_pcm_uframes_t)bsize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * open a slave PCM as secondary client (dup'ed fd)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						snd_pcm_t *spcm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = snd_pcm_hw_open_fd(spcmp, client_name, dmix->hw_fd, 0, 0);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							SNDERR("unable to open hardware");
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						spcm = *spcmp;
 | 
				
			||||||
 | 
						spcm->donot_close = 1;
 | 
				
			||||||
 | 
						spcm->setup = 1;
 | 
				
			||||||
 | 
						/* we copy the slave setting */
 | 
				
			||||||
 | 
						spcm->buffer_size = dmix->shmptr->s.buffer_size;
 | 
				
			||||||
 | 
						spcm->sample_bits = dmix->shmptr->s.sample_bits;
 | 
				
			||||||
 | 
						spcm->channels = dmix->shmptr->s.channels;
 | 
				
			||||||
 | 
						spcm->format = dmix->shmptr->s.format;
 | 
				
			||||||
 | 
						spcm->boundary = recalc_boundary_size(dmix->shmptr->s.boundary, spcm->buffer_size);
 | 
				
			||||||
 | 
						spcm->info = dmix->shmptr->s.info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Use the slave setting as SPCM, so far */
 | 
				
			||||||
 | 
						dmix->slave_buffer_size = spcm->buffer_size;
 | 
				
			||||||
 | 
						dmix->slave_period_size = dmix->shmptr->s.period_size;
 | 
				
			||||||
 | 
						dmix->slave_boundary = spcm->boundary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = snd_pcm_mmap(spcm);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							SNDERR("unable to mmap channels");
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix)
 | 
					int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_timer_params_t *params;
 | 
						snd_timer_params_t *params;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,13 +48,20 @@ struct slave_params {
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	char socket_name[256];			/* name of communication socket */
 | 
						char socket_name[256];			/* name of communication socket */
 | 
				
			||||||
	snd_pcm_type_t type;			/* PCM type (currently only hw) */
 | 
						snd_pcm_type_t type;			/* PCM type (currently only hw) */
 | 
				
			||||||
	snd_pcm_hw_params_t hw_params;
 | 
					 | 
				
			||||||
	snd_pcm_sw_params_t sw_params;
 | 
					 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		snd_pcm_uframes_t buffer_size;
 | 
							unsigned int format;
 | 
				
			||||||
		snd_pcm_uframes_t period_size;
 | 
							snd_interval_t rate;
 | 
				
			||||||
		snd_pcm_uframes_t boundary;
 | 
							snd_interval_t buffer_size;
 | 
				
			||||||
		snd_pcm_uframes_t channels;
 | 
							snd_interval_t buffer_time;
 | 
				
			||||||
 | 
							snd_interval_t period_size;
 | 
				
			||||||
 | 
							snd_interval_t period_time;
 | 
				
			||||||
 | 
							snd_interval_t periods;
 | 
				
			||||||
 | 
						} hw;
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							unsigned int buffer_size;
 | 
				
			||||||
 | 
							unsigned int period_size;
 | 
				
			||||||
 | 
							unsigned long long boundary;
 | 
				
			||||||
 | 
							unsigned int channels;
 | 
				
			||||||
		unsigned int sample_bits;
 | 
							unsigned int sample_bits;
 | 
				
			||||||
		unsigned int rate;
 | 
							unsigned int rate;
 | 
				
			||||||
		snd_pcm_format_t format;
 | 
							snd_pcm_format_t format;
 | 
				
			||||||
| 
						 | 
					@ -85,6 +92,9 @@ struct snd_pcm_direct {
 | 
				
			||||||
	snd_pcm_uframes_t avail_max;
 | 
						snd_pcm_uframes_t avail_max;
 | 
				
			||||||
	snd_pcm_uframes_t slave_appl_ptr;
 | 
						snd_pcm_uframes_t slave_appl_ptr;
 | 
				
			||||||
	snd_pcm_uframes_t slave_hw_ptr;
 | 
						snd_pcm_uframes_t slave_hw_ptr;
 | 
				
			||||||
 | 
						snd_pcm_uframes_t slave_period_size;
 | 
				
			||||||
 | 
						snd_pcm_uframes_t slave_buffer_size;
 | 
				
			||||||
 | 
						snd_pcm_uframes_t slave_boundary;
 | 
				
			||||||
	int (*sync_ptr)(snd_pcm_t *pcm);
 | 
						int (*sync_ptr)(snd_pcm_t *pcm);
 | 
				
			||||||
	snd_pcm_state_t state;
 | 
						snd_pcm_state_t state;
 | 
				
			||||||
	snd_htimestamp_t trigger_tstamp;
 | 
						snd_htimestamp_t trigger_tstamp;
 | 
				
			||||||
| 
						 | 
					@ -146,6 +156,7 @@ int snd_pcm_direct_munmap(snd_pcm_t *pcm);
 | 
				
			||||||
int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix);
 | 
					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_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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,8 +238,8 @@ static void mix_areas(snd_pcm_direct_t *dmix,
 | 
				
			||||||
static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
 | 
					static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_pcm_direct_t *dmix = pcm->private_data;
 | 
						snd_pcm_direct_t *dmix = pcm->private_data;
 | 
				
			||||||
	snd_pcm_uframes_t appl_ptr, slave_appl_ptr, slave_bsize;
 | 
						snd_pcm_uframes_t slave_hw_ptr, slave_appl_ptr, slave_size;
 | 
				
			||||||
	snd_pcm_uframes_t size, slave_size, slave_hw_ptr;
 | 
						snd_pcm_uframes_t appl_ptr, size;
 | 
				
			||||||
	const snd_pcm_channel_area_t *src_areas, *dst_areas;
 | 
						const snd_pcm_channel_area_t *src_areas, *dst_areas;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* calculate the size to transfer */
 | 
						/* calculate the size to transfer */
 | 
				
			||||||
| 
						 | 
					@ -253,17 +253,16 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
 | 
				
			||||||
		size = pcm->boundary - size;
 | 
							size = pcm->boundary - size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* check the available size in the slave PCM buffer */
 | 
						/* check the available size in the slave PCM buffer */
 | 
				
			||||||
	slave_bsize = dmix->shmptr->s.buffer_size;
 | 
					 | 
				
			||||||
	slave_hw_ptr = dmix->slave_hw_ptr;
 | 
						slave_hw_ptr = dmix->slave_hw_ptr;
 | 
				
			||||||
	/* don't write on the last active period - this area may be cleared
 | 
						/* don't write on the last active period - this area may be cleared
 | 
				
			||||||
	 * by the driver during mix operation...
 | 
						 * by the driver during mix operation...
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	slave_hw_ptr -= slave_hw_ptr % dmix->shmptr->s.period_size;
 | 
						slave_hw_ptr -= slave_hw_ptr % dmix->slave_period_size;
 | 
				
			||||||
	slave_hw_ptr += slave_bsize;
 | 
						slave_hw_ptr += dmix->slave_buffer_size;
 | 
				
			||||||
	if (slave_hw_ptr >= dmix->shmptr->s.boundary)
 | 
						if (slave_hw_ptr >= dmix->slave_boundary)
 | 
				
			||||||
		slave_hw_ptr -= dmix->shmptr->s.boundary;
 | 
							slave_hw_ptr -= dmix->slave_boundary;
 | 
				
			||||||
	if (slave_hw_ptr < dmix->slave_appl_ptr)
 | 
						if (slave_hw_ptr < dmix->slave_appl_ptr)
 | 
				
			||||||
		slave_size = slave_hw_ptr + (dmix->shmptr->s.boundary - dmix->slave_appl_ptr);
 | 
							slave_size = slave_hw_ptr + (dmix->slave_boundary - dmix->slave_appl_ptr);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		slave_size = slave_hw_ptr - dmix->slave_appl_ptr;
 | 
							slave_size = slave_hw_ptr - dmix->slave_appl_ptr;
 | 
				
			||||||
	if (slave_size < size)
 | 
						if (slave_size < size)
 | 
				
			||||||
| 
						 | 
					@ -277,22 +276,22 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
 | 
				
			||||||
	appl_ptr = dmix->last_appl_ptr % pcm->buffer_size;
 | 
						appl_ptr = dmix->last_appl_ptr % pcm->buffer_size;
 | 
				
			||||||
	dmix->last_appl_ptr += size;
 | 
						dmix->last_appl_ptr += size;
 | 
				
			||||||
	dmix->last_appl_ptr %= pcm->boundary;
 | 
						dmix->last_appl_ptr %= pcm->boundary;
 | 
				
			||||||
	slave_appl_ptr = dmix->slave_appl_ptr % slave_bsize;
 | 
						slave_appl_ptr = dmix->slave_appl_ptr % dmix->slave_buffer_size;
 | 
				
			||||||
	dmix->slave_appl_ptr += size;
 | 
						dmix->slave_appl_ptr += size;
 | 
				
			||||||
	dmix->slave_appl_ptr %= dmix->shmptr->s.boundary;
 | 
						dmix->slave_appl_ptr %= dmix->slave_boundary;
 | 
				
			||||||
	dmix_down_sem(dmix);
 | 
						dmix_down_sem(dmix);
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
		snd_pcm_uframes_t transfer = size;
 | 
							snd_pcm_uframes_t transfer = size;
 | 
				
			||||||
		if (appl_ptr + transfer > pcm->buffer_size)
 | 
							if (appl_ptr + transfer > pcm->buffer_size)
 | 
				
			||||||
			transfer = pcm->buffer_size - appl_ptr;
 | 
								transfer = pcm->buffer_size - appl_ptr;
 | 
				
			||||||
		if (slave_appl_ptr + transfer > slave_bsize)
 | 
							if (slave_appl_ptr + transfer > dmix->slave_buffer_size)
 | 
				
			||||||
			transfer = slave_bsize - slave_appl_ptr;
 | 
								transfer = dmix->slave_buffer_size - slave_appl_ptr;
 | 
				
			||||||
		mix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
 | 
							mix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
 | 
				
			||||||
		size -= transfer;
 | 
							size -= transfer;
 | 
				
			||||||
		if (! size)
 | 
							if (! size)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		slave_appl_ptr += transfer;
 | 
							slave_appl_ptr += transfer;
 | 
				
			||||||
		slave_appl_ptr %= slave_bsize;
 | 
							slave_appl_ptr %= dmix->slave_buffer_size;
 | 
				
			||||||
		appl_ptr += transfer;
 | 
							appl_ptr += transfer;
 | 
				
			||||||
		appl_ptr %= pcm->buffer_size;
 | 
							appl_ptr %= pcm->buffer_size;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -327,7 +326,7 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm)
 | 
				
			||||||
		/* not really started yet - don't update hw_ptr */
 | 
							/* not really started yet - don't update hw_ptr */
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (diff < 0) {
 | 
						if (diff < 0) {
 | 
				
			||||||
		slave_hw_ptr += dmix->shmptr->s.boundary;
 | 
							slave_hw_ptr += dmix->slave_boundary;
 | 
				
			||||||
		diff = slave_hw_ptr - old_slave_hw_ptr;
 | 
							diff = slave_hw_ptr - old_slave_hw_ptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dmix->hw_ptr += diff;
 | 
						dmix->hw_ptr += diff;
 | 
				
			||||||
| 
						 | 
					@ -451,7 +450,6 @@ static int snd_pcm_dmix_prepare(snd_pcm_t *pcm)
 | 
				
			||||||
	snd_pcm_direct_t *dmix = pcm->private_data;
 | 
						snd_pcm_direct_t *dmix = pcm->private_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_pcm_direct_check_interleave(dmix, pcm);
 | 
						snd_pcm_direct_check_interleave(dmix, pcm);
 | 
				
			||||||
	// assert(pcm->boundary == dmix->shmptr->s.boundary);	/* for sure */
 | 
					 | 
				
			||||||
	dmix->state = SND_PCM_STATE_PREPARED;
 | 
						dmix->state = SND_PCM_STATE_PREPARED;
 | 
				
			||||||
	dmix->appl_ptr = dmix->last_appl_ptr = 0;
 | 
						dmix->appl_ptr = dmix->last_appl_ptr = 0;
 | 
				
			||||||
	dmix->hw_ptr = 0;
 | 
						dmix->hw_ptr = 0;
 | 
				
			||||||
| 
						 | 
					@ -861,25 +859,9 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
		snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
 | 
							snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
 | 
				
			||||||
		ret = snd_pcm_hw_open_fd(&spcm, "dmix_client", dmix->hw_fd, 0, 0);
 | 
							ret = snd_pcm_direct_open_secondary_client(&spcm, dmix, "dmix_client");
 | 
				
			||||||
		if (ret < 0) {
 | 
							if (ret < 0)
 | 
				
			||||||
			SNDERR("unable to open hardware");
 | 
					 | 
				
			||||||
			goto _err;
 | 
								goto _err;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		spcm->donot_close = 1;
 | 
					 | 
				
			||||||
		spcm->setup = 1;
 | 
					 | 
				
			||||||
		spcm->buffer_size = dmix->shmptr->s.buffer_size;
 | 
					 | 
				
			||||||
		spcm->sample_bits = dmix->shmptr->s.sample_bits;
 | 
					 | 
				
			||||||
		spcm->channels = dmix->shmptr->s.channels;
 | 
					 | 
				
			||||||
		spcm->format = dmix->shmptr->s.format;
 | 
					 | 
				
			||||||
		spcm->boundary = dmix->shmptr->s.boundary;
 | 
					 | 
				
			||||||
		spcm->info = dmix->shmptr->s.info;
 | 
					 | 
				
			||||||
		ret = snd_pcm_mmap(spcm);
 | 
					 | 
				
			||||||
		if (ret < 0) {
 | 
					 | 
				
			||||||
			SNDERR("unable to mmap channels");
 | 
					 | 
				
			||||||
			goto _err;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		dmix->spcm = spcm;
 | 
							dmix->spcm = spcm;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,48 +103,52 @@ static void share_areas(snd_pcm_direct_t *dshare,
 | 
				
			||||||
static void snd_pcm_dshare_sync_area(snd_pcm_t *pcm)
 | 
					static void snd_pcm_dshare_sync_area(snd_pcm_t *pcm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_pcm_direct_t *dshare = pcm->private_data;
 | 
						snd_pcm_direct_t *dshare = pcm->private_data;
 | 
				
			||||||
	snd_pcm_uframes_t appl_ptr, slave_appl_ptr, slave_bsize;
 | 
						snd_pcm_uframes_t slave_hw_ptr, slave_appl_ptr, slave_size;
 | 
				
			||||||
	snd_pcm_uframes_t size, slave_hw_ptr;
 | 
						snd_pcm_uframes_t appl_ptr, size;
 | 
				
			||||||
	const snd_pcm_channel_area_t *src_areas, *dst_areas;
 | 
						const snd_pcm_channel_area_t *src_areas, *dst_areas;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* calculate the size to transfer */
 | 
						/* calculate the size to transfer */
 | 
				
			||||||
	size = dshare->appl_ptr - dshare->last_appl_ptr;
 | 
						size = dshare->appl_ptr - dshare->last_appl_ptr;
 | 
				
			||||||
	if (! size)
 | 
						if (! size)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	slave_bsize = dshare->shmptr->s.buffer_size;
 | 
					 | 
				
			||||||
	slave_hw_ptr = dshare->slave_hw_ptr;
 | 
						slave_hw_ptr = dshare->slave_hw_ptr;
 | 
				
			||||||
	/* don't write on the last active period - this area may be cleared
 | 
						/* don't write on the last active period - this area may be cleared
 | 
				
			||||||
	 * by the driver during write operation...
 | 
						 * by the driver during write operation...
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	slave_hw_ptr -= slave_hw_ptr % dshare->shmptr->s.period_size;
 | 
						slave_hw_ptr -= slave_hw_ptr % dshare->slave_period_size;
 | 
				
			||||||
	slave_hw_ptr += slave_bsize;
 | 
						slave_hw_ptr += dshare->slave_buffer_size;
 | 
				
			||||||
	if (dshare->slave_hw_ptr > dshare->slave_appl_ptr)
 | 
						if (dshare->slave_hw_ptr > dshare->slave_boundary)
 | 
				
			||||||
		slave_hw_ptr -= dshare->shmptr->s.boundary;
 | 
							slave_hw_ptr -= dshare->slave_boundary;
 | 
				
			||||||
	if (dshare->slave_appl_ptr + size >= slave_hw_ptr)
 | 
						if (slave_hw_ptr < dshare->slave_appl_ptr)
 | 
				
			||||||
		size = slave_hw_ptr - dshare->slave_appl_ptr;
 | 
							slave_size = slave_hw_ptr + (dshare->slave_boundary - dshare->slave_appl_ptr);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							slave_size = slave_hw_ptr - dshare->slave_appl_ptr;
 | 
				
			||||||
 | 
						if (slave_size < size)
 | 
				
			||||||
 | 
							size = slave_size;
 | 
				
			||||||
	if (! size)
 | 
						if (! size)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* add sample areas here */
 | 
						/* add sample areas here */
 | 
				
			||||||
	src_areas = snd_pcm_mmap_areas(pcm);
 | 
						src_areas = snd_pcm_mmap_areas(pcm);
 | 
				
			||||||
	dst_areas = snd_pcm_mmap_areas(dshare->spcm);
 | 
						dst_areas = snd_pcm_mmap_areas(dshare->spcm);
 | 
				
			||||||
	appl_ptr = dshare->last_appl_ptr % pcm->buffer_size;
 | 
						appl_ptr = dshare->last_appl_ptr % pcm->buffer_size;
 | 
				
			||||||
	dshare->last_appl_ptr += size;
 | 
						dshare->last_appl_ptr += size;
 | 
				
			||||||
	dshare->last_appl_ptr %= pcm->boundary;
 | 
						dshare->last_appl_ptr %= pcm->boundary;
 | 
				
			||||||
	slave_appl_ptr = dshare->slave_appl_ptr % slave_bsize;
 | 
						slave_appl_ptr = dshare->slave_appl_ptr % dshare->slave_buffer_size;
 | 
				
			||||||
	dshare->slave_appl_ptr += size;
 | 
						dshare->slave_appl_ptr += size;
 | 
				
			||||||
	dshare->slave_appl_ptr %= dshare->shmptr->s.boundary;
 | 
						dshare->slave_appl_ptr %= dshare->slave_boundary;
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
		snd_pcm_uframes_t transfer = size;
 | 
							snd_pcm_uframes_t transfer = size;
 | 
				
			||||||
		if (appl_ptr + transfer > pcm->buffer_size)
 | 
							if (appl_ptr + transfer > pcm->buffer_size)
 | 
				
			||||||
			transfer = pcm->buffer_size - appl_ptr;
 | 
								transfer = pcm->buffer_size - appl_ptr;
 | 
				
			||||||
		if (slave_appl_ptr + transfer > slave_bsize)
 | 
							if (slave_appl_ptr + transfer > dshare->slave_buffer_size)
 | 
				
			||||||
			transfer = slave_bsize - slave_appl_ptr;
 | 
								transfer = dshare->slave_buffer_size - slave_appl_ptr;
 | 
				
			||||||
		share_areas(dshare, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
 | 
							share_areas(dshare, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
 | 
				
			||||||
		size -= transfer;
 | 
							size -= transfer;
 | 
				
			||||||
		if (! size)
 | 
							if (! size)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		slave_appl_ptr += transfer;
 | 
							slave_appl_ptr += transfer;
 | 
				
			||||||
		slave_appl_ptr %= slave_bsize;
 | 
							slave_appl_ptr %= dshare->slave_buffer_size;
 | 
				
			||||||
		appl_ptr += transfer;
 | 
							appl_ptr += transfer;
 | 
				
			||||||
		appl_ptr %= pcm->buffer_size;
 | 
							appl_ptr %= pcm->buffer_size;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -178,7 +182,7 @@ static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm)
 | 
				
			||||||
		/* not really started yet - don't update hw_ptr */
 | 
							/* not really started yet - don't update hw_ptr */
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (diff < 0) {
 | 
						if (diff < 0) {
 | 
				
			||||||
		slave_hw_ptr += dshare->shmptr->s.boundary;
 | 
							slave_hw_ptr += dshare->slave_boundary;
 | 
				
			||||||
		diff = slave_hw_ptr - old_slave_hw_ptr;
 | 
							diff = slave_hw_ptr - old_slave_hw_ptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dshare->hw_ptr += diff;
 | 
						dshare->hw_ptr += diff;
 | 
				
			||||||
| 
						 | 
					@ -299,7 +303,6 @@ static int snd_pcm_dshare_prepare(snd_pcm_t *pcm)
 | 
				
			||||||
	snd_pcm_direct_t *dshare = pcm->private_data;
 | 
						snd_pcm_direct_t *dshare = pcm->private_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_pcm_direct_check_interleave(dshare, pcm);
 | 
						snd_pcm_direct_check_interleave(dshare, pcm);
 | 
				
			||||||
	// assert(pcm->boundary == dshare->shmptr->s.boundary);	/* for sure */
 | 
					 | 
				
			||||||
	dshare->state = SND_PCM_STATE_PREPARED;
 | 
						dshare->state = SND_PCM_STATE_PREPARED;
 | 
				
			||||||
	dshare->appl_ptr = dshare->last_appl_ptr = 0;
 | 
						dshare->appl_ptr = dshare->last_appl_ptr = 0;
 | 
				
			||||||
	dshare->hw_ptr = 0;
 | 
						dshare->hw_ptr = 0;
 | 
				
			||||||
| 
						 | 
					@ -706,25 +709,10 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
		snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT);
 | 
							snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT);
 | 
				
			||||||
 | 
							ret = snd_pcm_direct_open_secondary_client(&spcm, dshare, "dshare_client");
 | 
				
			||||||
		ret = snd_pcm_hw_open_fd(&spcm, "dshare_client", dshare->hw_fd, 0, 0);
 | 
							ret = snd_pcm_hw_open_fd(&spcm, "dshare_client", dshare->hw_fd, 0, 0);
 | 
				
			||||||
		if (ret < 0) {
 | 
							if (ret < 0)
 | 
				
			||||||
			SNDERR("unable to open hardware");
 | 
					 | 
				
			||||||
			goto _err;
 | 
								goto _err;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		spcm->donot_close = 1;
 | 
					 | 
				
			||||||
		spcm->setup = 1;
 | 
					 | 
				
			||||||
		spcm->buffer_size = dshare->shmptr->s.buffer_size;
 | 
					 | 
				
			||||||
		spcm->sample_bits = dshare->shmptr->s.sample_bits;
 | 
					 | 
				
			||||||
		spcm->channels = dshare->shmptr->s.channels;
 | 
					 | 
				
			||||||
		spcm->format = dshare->shmptr->s.format;
 | 
					 | 
				
			||||||
		spcm->boundary = dshare->shmptr->s.boundary;
 | 
					 | 
				
			||||||
		spcm->info = dshare->shmptr->s.info;
 | 
					 | 
				
			||||||
		ret = snd_pcm_mmap(spcm);
 | 
					 | 
				
			||||||
		if (ret < 0) {
 | 
					 | 
				
			||||||
			SNDERR("unable to mmap channels");
 | 
					 | 
				
			||||||
			goto _err;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		dshare->spcm = spcm;
 | 
							dshare->spcm = spcm;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,14 +93,15 @@ static void snd_pcm_dsnoop_sync_area(snd_pcm_t *pcm, snd_pcm_uframes_t slave_hw_
 | 
				
			||||||
	dst_areas = snd_pcm_mmap_areas(pcm);
 | 
						dst_areas = snd_pcm_mmap_areas(pcm);
 | 
				
			||||||
	src_areas = snd_pcm_mmap_areas(dsnoop->spcm);
 | 
						src_areas = snd_pcm_mmap_areas(dsnoop->spcm);
 | 
				
			||||||
	hw_ptr %= pcm->buffer_size;
 | 
						hw_ptr %= pcm->buffer_size;
 | 
				
			||||||
	slave_hw_ptr %= dsnoop->shmptr->s.buffer_size;
 | 
						slave_hw_ptr %= dsnoop->slave_buffer_size;
 | 
				
			||||||
	while (size > 0) {
 | 
						while (size > 0) {
 | 
				
			||||||
		transfer = hw_ptr + size > pcm->buffer_size ? pcm->buffer_size - hw_ptr : size;
 | 
							transfer = hw_ptr + size > pcm->buffer_size ? pcm->buffer_size - hw_ptr : size;
 | 
				
			||||||
		transfer = slave_hw_ptr + transfer > dsnoop->shmptr->s.buffer_size ? dsnoop->shmptr->s.buffer_size - slave_hw_ptr : transfer;
 | 
							transfer = slave_hw_ptr + transfer > dsnoop->slave_buffer_size ?
 | 
				
			||||||
 | 
								dsnoop->slave_buffer_size - slave_hw_ptr : transfer;
 | 
				
			||||||
		size -= transfer;
 | 
							size -= transfer;
 | 
				
			||||||
		snoop_areas(dsnoop, src_areas, dst_areas, slave_hw_ptr, hw_ptr, transfer);
 | 
							snoop_areas(dsnoop, src_areas, dst_areas, slave_hw_ptr, hw_ptr, transfer);
 | 
				
			||||||
		slave_hw_ptr += transfer;
 | 
							slave_hw_ptr += transfer;
 | 
				
			||||||
	 	slave_hw_ptr %= dsnoop->shmptr->s.buffer_size;
 | 
						 	slave_hw_ptr %= dsnoop->slave_buffer_size;
 | 
				
			||||||
		hw_ptr += transfer;
 | 
							hw_ptr += transfer;
 | 
				
			||||||
		hw_ptr %= pcm->buffer_size;
 | 
							hw_ptr %= pcm->buffer_size;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -130,7 +131,7 @@ static int snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm)
 | 
				
			||||||
	if (diff == 0)		/* fast path */
 | 
						if (diff == 0)		/* fast path */
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (diff < 0) {
 | 
						if (diff < 0) {
 | 
				
			||||||
		slave_hw_ptr += dsnoop->shmptr->s.boundary;
 | 
							slave_hw_ptr += dsnoop->slave_boundary;
 | 
				
			||||||
		diff = slave_hw_ptr - old_slave_hw_ptr;
 | 
							diff = slave_hw_ptr - old_slave_hw_ptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	snd_pcm_dsnoop_sync_area(pcm, old_slave_hw_ptr, diff);
 | 
						snd_pcm_dsnoop_sync_area(pcm, old_slave_hw_ptr, diff);
 | 
				
			||||||
| 
						 | 
					@ -245,7 +246,6 @@ static int snd_pcm_dsnoop_prepare(snd_pcm_t *pcm)
 | 
				
			||||||
	snd_pcm_direct_t *dsnoop = pcm->private_data;
 | 
						snd_pcm_direct_t *dsnoop = pcm->private_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_pcm_direct_check_interleave(dsnoop, pcm);
 | 
						snd_pcm_direct_check_interleave(dsnoop, pcm);
 | 
				
			||||||
	// assert(pcm->boundary == dsnoop->shmptr->s.boundary);	/* for sure */
 | 
					 | 
				
			||||||
	dsnoop->state = SND_PCM_STATE_PREPARED;
 | 
						dsnoop->state = SND_PCM_STATE_PREPARED;
 | 
				
			||||||
	dsnoop->appl_ptr = 0;
 | 
						dsnoop->appl_ptr = 0;
 | 
				
			||||||
	dsnoop->hw_ptr = 0;
 | 
						dsnoop->hw_ptr = 0;
 | 
				
			||||||
| 
						 | 
					@ -597,25 +597,10 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
		snd_pcm_direct_semaphore_down(dsnoop, DIRECT_IPC_SEM_CLIENT);
 | 
							snd_pcm_direct_semaphore_down(dsnoop, DIRECT_IPC_SEM_CLIENT);
 | 
				
			||||||
		ret = snd_pcm_hw_open_fd(&spcm, "dsnoop_client", dsnoop->hw_fd, 0, 0);
 | 
					 | 
				
			||||||
		if (ret < 0) {
 | 
					 | 
				
			||||||
			SNDERR("unable to open hardware");
 | 
					 | 
				
			||||||
			goto _err;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spcm->donot_close = 1;
 | 
							ret = snd_pcm_direct_open_secondary_client(&spcm, dsnoop, "dsnoop_client");
 | 
				
			||||||
		spcm->setup = 1;
 | 
							if (ret < 0)
 | 
				
			||||||
		spcm->buffer_size = dsnoop->shmptr->s.buffer_size;
 | 
					 | 
				
			||||||
		spcm->sample_bits = dsnoop->shmptr->s.sample_bits;
 | 
					 | 
				
			||||||
		spcm->channels = dsnoop->shmptr->s.channels;
 | 
					 | 
				
			||||||
		spcm->format = dsnoop->shmptr->s.format;
 | 
					 | 
				
			||||||
		spcm->boundary = dsnoop->shmptr->s.boundary;
 | 
					 | 
				
			||||||
		spcm->info = dsnoop->shmptr->s.info;
 | 
					 | 
				
			||||||
		ret = snd_pcm_mmap(spcm);
 | 
					 | 
				
			||||||
		if (ret < 0) {
 | 
					 | 
				
			||||||
			SNDERR("unable to mmap channels");
 | 
					 | 
				
			||||||
			goto _err;
 | 
								goto _err;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		dsnoop->spcm = spcm;
 | 
							dsnoop->spcm = spcm;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue