mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Implemented snd_pcm_rewind() for the dmix plugin
This commit is contained in:
		
							parent
							
								
									8f16428f9c
								
							
						
					
					
						commit
						70b11d614d
					
				
					 7 changed files with 459 additions and 28 deletions
				
			
		| 
						 | 
					@ -162,6 +162,10 @@ struct snd_pcm_direct {
 | 
				
			||||||
			mix_areas_32_t *mix_areas_32;
 | 
								mix_areas_32_t *mix_areas_32;
 | 
				
			||||||
			mix_areas_24_t *mix_areas_24;
 | 
								mix_areas_24_t *mix_areas_24;
 | 
				
			||||||
			mix_areas_u8_t *mix_areas_u8;
 | 
								mix_areas_u8_t *mix_areas_u8;
 | 
				
			||||||
 | 
								mix_areas_16_t *remix_areas_16;
 | 
				
			||||||
 | 
								mix_areas_32_t *remix_areas_32;
 | 
				
			||||||
 | 
								mix_areas_24_t *remix_areas_24;
 | 
				
			||||||
 | 
								mix_areas_u8_t *remix_areas_u8;
 | 
				
			||||||
		} dmix;
 | 
							} dmix;
 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
		} dsnoop;
 | 
							} dsnoop;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,6 +213,70 @@ static void mix_areas(snd_pcm_direct_t *dmix,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void remix_areas(snd_pcm_direct_t *dmix,
 | 
				
			||||||
 | 
								const snd_pcm_channel_area_t *src_areas,
 | 
				
			||||||
 | 
								const snd_pcm_channel_area_t *dst_areas,
 | 
				
			||||||
 | 
								snd_pcm_uframes_t src_ofs,
 | 
				
			||||||
 | 
								snd_pcm_uframes_t dst_ofs,
 | 
				
			||||||
 | 
								snd_pcm_uframes_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int src_step, dst_step;
 | 
				
			||||||
 | 
						unsigned int chn, dchn, channels, sample_size;
 | 
				
			||||||
 | 
						mix_areas_t *do_remix_areas;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						channels = dmix->channels;
 | 
				
			||||||
 | 
						switch (dmix->shmptr->s.format) {
 | 
				
			||||||
 | 
						case SND_PCM_FORMAT_S16_LE:
 | 
				
			||||||
 | 
						case SND_PCM_FORMAT_S16_BE:
 | 
				
			||||||
 | 
							sample_size = 2;
 | 
				
			||||||
 | 
							do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_16;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_PCM_FORMAT_S32_LE:
 | 
				
			||||||
 | 
						case SND_PCM_FORMAT_S32_BE:
 | 
				
			||||||
 | 
							sample_size = 4;
 | 
				
			||||||
 | 
							do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_32;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_PCM_FORMAT_S24_3LE:
 | 
				
			||||||
 | 
							sample_size = 3;
 | 
				
			||||||
 | 
							do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_24;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_PCM_FORMAT_U8:
 | 
				
			||||||
 | 
							sample_size = 1;
 | 
				
			||||||
 | 
							do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_u8;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (dmix->interleaved) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * process all areas in one loop
 | 
				
			||||||
 | 
							 * it optimizes the memory accesses for this case
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							do_remix_areas(size * channels,
 | 
				
			||||||
 | 
								       (unsigned char *)dst_areas[0].addr + sample_size * dst_ofs * channels,
 | 
				
			||||||
 | 
								       (unsigned char *)src_areas[0].addr + sample_size * src_ofs * channels,
 | 
				
			||||||
 | 
								       dmix->u.dmix.sum_buffer + dst_ofs * channels,
 | 
				
			||||||
 | 
								       sample_size,
 | 
				
			||||||
 | 
								       sample_size,
 | 
				
			||||||
 | 
								       sizeof(signed int));
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for (chn = 0; chn < channels; chn++) {
 | 
				
			||||||
 | 
							dchn = dmix->bindings ? dmix->bindings[chn] : chn;
 | 
				
			||||||
 | 
							if (dchn >= dmix->shmptr->s.channels)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							src_step = src_areas[chn].step / 8;
 | 
				
			||||||
 | 
							dst_step = dst_areas[dchn].step / 8;
 | 
				
			||||||
 | 
							do_remix_areas(size,
 | 
				
			||||||
 | 
								       ((unsigned char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + dst_ofs * dst_step,
 | 
				
			||||||
 | 
								       ((unsigned char *)src_areas[chn].addr + src_areas[chn].first / 8) + src_ofs * src_step,
 | 
				
			||||||
 | 
								       dmix->u.dmix.sum_buffer + channels * dst_ofs + chn,
 | 
				
			||||||
 | 
								       dst_step,
 | 
				
			||||||
 | 
								       src_step,
 | 
				
			||||||
 | 
								       channels * sizeof(signed int));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * if no concurrent access is allowed in the mixing routines, we need to protect
 | 
					 * if no concurrent access is allowed in the mixing routines, we need to protect
 | 
				
			||||||
 * the area via semaphore
 | 
					 * the area via semaphore
 | 
				
			||||||
| 
						 | 
					@ -234,7 +298,7 @@ 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 slave_hw_ptr, slave_appl_ptr, slave_size;
 | 
						snd_pcm_uframes_t slave_hw_ptr, slave_appl_ptr, slave_size;
 | 
				
			||||||
	snd_pcm_uframes_t appl_ptr, size;
 | 
						snd_pcm_uframes_t appl_ptr, size, transfer;
 | 
				
			||||||
	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 */
 | 
				
			||||||
| 
						 | 
					@ -247,6 +311,27 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
 | 
				
			||||||
	if (size >= pcm->boundary / 2)
 | 
						if (size >= pcm->boundary / 2)
 | 
				
			||||||
		size = pcm->boundary - size;
 | 
							size = pcm->boundary - size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* the slave_app_ptr can be far behing the slave_hw_ptr */
 | 
				
			||||||
 | 
						/* reduce mixing and errors here - just skip not catched writes */
 | 
				
			||||||
 | 
						if (dmix->slave_hw_ptr < dmix->slave_appl_ptr)
 | 
				
			||||||
 | 
							slave_size = dmix->slave_appl_ptr - dmix->slave_hw_ptr;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							slave_size = dmix->slave_appl_ptr + (dmix->slave_boundary - dmix->slave_hw_ptr);
 | 
				
			||||||
 | 
						if (slave_size > dmix->slave_buffer_size) {
 | 
				
			||||||
 | 
							transfer = dmix->slave_buffer_size - slave_size;
 | 
				
			||||||
 | 
							if (transfer > size)
 | 
				
			||||||
 | 
								transfer = size;
 | 
				
			||||||
 | 
							dmix->last_appl_ptr += transfer;
 | 
				
			||||||
 | 
							dmix->last_appl_ptr %= pcm->boundary;
 | 
				
			||||||
 | 
							dmix->slave_appl_ptr += transfer;
 | 
				
			||||||
 | 
							dmix->slave_appl_ptr %= dmix->slave_boundary;
 | 
				
			||||||
 | 
							size = dmix->appl_ptr - dmix->last_appl_ptr;
 | 
				
			||||||
 | 
							if (! size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							if (size >= pcm->boundary / 2)
 | 
				
			||||||
 | 
								size = pcm->boundary - size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* check the available size in the slave PCM buffer */
 | 
						/* check the available size in the slave PCM buffer */
 | 
				
			||||||
	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
 | 
				
			||||||
| 
						 | 
					@ -276,7 +361,7 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)
 | 
				
			||||||
	dmix->slave_appl_ptr %= dmix->slave_boundary;
 | 
						dmix->slave_appl_ptr %= dmix->slave_boundary;
 | 
				
			||||||
	dmix_down_sem(dmix);
 | 
						dmix_down_sem(dmix);
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
		snd_pcm_uframes_t transfer = size;
 | 
							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 > dmix->slave_buffer_size)
 | 
							if (slave_appl_ptr + transfer > dmix->slave_buffer_size)
 | 
				
			||||||
| 
						 | 
					@ -564,15 +649,78 @@ static int snd_pcm_dmix_pause(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int enable ATTRIB
 | 
				
			||||||
	return -EIO;
 | 
						return -EIO;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_uframes_t frames ATTRIBUTE_UNUSED)
 | 
					static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if 0
 | 
						snd_pcm_direct_t *dmix = pcm->private_data;
 | 
				
			||||||
	/* FIXME: substract samples from the mix ring buffer, too? */
 | 
						snd_pcm_uframes_t slave_appl_ptr, slave_size;
 | 
				
			||||||
 | 
						snd_pcm_uframes_t appl_ptr, size, transfer, result;
 | 
				
			||||||
 | 
						const snd_pcm_channel_area_t *src_areas, *dst_areas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dmix->state == SND_PCM_STATE_RUNNING ||
 | 
				
			||||||
 | 
						    dmix->state == SND_PCM_STATE_DRAINING)
 | 
				
			||||||
 | 
						    	return snd_pcm_dmix_hwsync(pcm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dmix->last_appl_ptr < dmix->appl_ptr)
 | 
				
			||||||
 | 
							size = dmix->appl_ptr - dmix->last_appl_ptr;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							size = dmix->appl_ptr + (pcm->boundary - dmix->last_appl_ptr);
 | 
				
			||||||
 | 
						if (frames < size)
 | 
				
			||||||
 | 
							size = frames;
 | 
				
			||||||
 | 
						snd_pcm_mmap_appl_backward(pcm, size);
 | 
				
			||||||
 | 
						frames -= size;
 | 
				
			||||||
 | 
						if (!frames)
 | 
				
			||||||
 | 
							return size;
 | 
				
			||||||
 | 
						result = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dmix->hw_ptr < dmix->appl_ptr)
 | 
				
			||||||
 | 
							size = dmix->appl_ptr - dmix->hw_ptr;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							size = dmix->appl_ptr + (pcm->boundary - dmix->hw_ptr);
 | 
				
			||||||
 | 
						if (size > frames)
 | 
				
			||||||
 | 
							size = frames;
 | 
				
			||||||
 | 
						if (dmix->slave_hw_ptr < dmix->slave_appl_ptr)
 | 
				
			||||||
 | 
							slave_size = dmix->slave_appl_ptr - dmix->slave_hw_ptr;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							slave_size = dmix->slave_appl_ptr + (pcm->boundary - dmix->slave_hw_ptr);
 | 
				
			||||||
 | 
						if (slave_size < size)
 | 
				
			||||||
 | 
							size = slave_size;
 | 
				
			||||||
 | 
						frames -= size;
 | 
				
			||||||
 | 
						result += size;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						/* add sample areas here */
 | 
				
			||||||
 | 
						src_areas = snd_pcm_mmap_areas(pcm);
 | 
				
			||||||
 | 
						dst_areas = snd_pcm_mmap_areas(dmix->spcm);
 | 
				
			||||||
 | 
						dmix->last_appl_ptr -= size;
 | 
				
			||||||
 | 
						dmix->last_appl_ptr %= pcm->boundary;
 | 
				
			||||||
 | 
						appl_ptr = dmix->last_appl_ptr % pcm->buffer_size;
 | 
				
			||||||
 | 
						dmix->slave_appl_ptr -= size;
 | 
				
			||||||
 | 
						dmix->slave_appl_ptr %= dmix->slave_boundary;
 | 
				
			||||||
 | 
						slave_appl_ptr = dmix->slave_appl_ptr % dmix->slave_buffer_size;
 | 
				
			||||||
 | 
						dmix_down_sem(dmix);
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							transfer = size;
 | 
				
			||||||
 | 
							if (appl_ptr + transfer > pcm->buffer_size)
 | 
				
			||||||
 | 
								transfer = pcm->buffer_size - appl_ptr;
 | 
				
			||||||
 | 
							if (slave_appl_ptr + transfer > dmix->slave_buffer_size)
 | 
				
			||||||
 | 
								transfer = dmix->slave_buffer_size - slave_appl_ptr;
 | 
				
			||||||
 | 
							remix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
 | 
				
			||||||
 | 
							size -= transfer;
 | 
				
			||||||
 | 
							if (! size)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							slave_appl_ptr += transfer;
 | 
				
			||||||
 | 
							slave_appl_ptr %= dmix->slave_buffer_size;
 | 
				
			||||||
 | 
							appl_ptr += transfer;
 | 
				
			||||||
 | 
							appl_ptr %= pcm->buffer_size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dmix->last_appl_ptr -= frames;
 | 
				
			||||||
 | 
						dmix->last_appl_ptr %= pcm->boundary;
 | 
				
			||||||
 | 
						dmix->slave_appl_ptr -= frames;
 | 
				
			||||||
 | 
						dmix->slave_appl_ptr %= dmix->slave_boundary;
 | 
				
			||||||
 | 
						dmix_up_sem(dmix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_pcm_mmap_appl_backward(pcm, frames);
 | 
						snd_pcm_mmap_appl_backward(pcm, frames);
 | 
				
			||||||
	return frames;
 | 
					
 | 
				
			||||||
#else
 | 
						return result + frames;
 | 
				
			||||||
	return -EIO;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static snd_pcm_sframes_t snd_pcm_dmix_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 | 
					static snd_pcm_sframes_t snd_pcm_dmix_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ static void mix_areas_32(unsigned int size,
 | 
				
			||||||
	register signed int sample, old_sample;
 | 
						register signed int sample, old_sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
		sample = *src / 256;
 | 
							sample = *src >> 8;
 | 
				
			||||||
		old_sample = *sum;
 | 
							old_sample = *sum;
 | 
				
			||||||
		if (ARCH_CMPXCHG(dst, 0, 1) == 0)
 | 
							if (ARCH_CMPXCHG(dst, 0, 1) == 0)
 | 
				
			||||||
			sample -= old_sample;
 | 
								sample -= old_sample;
 | 
				
			||||||
| 
						 | 
					@ -159,6 +159,37 @@ static void generic_mix_areas_16_native(unsigned int size,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void generic_remix_areas_16_native(unsigned int size,
 | 
				
			||||||
 | 
										  volatile signed short *dst,
 | 
				
			||||||
 | 
										  signed short *src,
 | 
				
			||||||
 | 
										  volatile signed int *sum,
 | 
				
			||||||
 | 
										  size_t dst_step,
 | 
				
			||||||
 | 
										  size_t src_step,
 | 
				
			||||||
 | 
										  size_t sum_step)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register signed int sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							sample = *src;
 | 
				
			||||||
 | 
							if (! *dst) {
 | 
				
			||||||
 | 
								*sum = -sample;
 | 
				
			||||||
 | 
								*dst = *src;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								*sum = sample = *sum - sample;
 | 
				
			||||||
 | 
								if (sample > 0x7fff)
 | 
				
			||||||
 | 
									sample = 0x7fff;
 | 
				
			||||||
 | 
								else if (sample < -0x8000)
 | 
				
			||||||
 | 
									sample = -0x8000;
 | 
				
			||||||
 | 
								*dst = sample;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!--size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							src = (signed short *) ((char *)src + src_step);
 | 
				
			||||||
 | 
							dst = (signed short *) ((char *)dst + dst_step);
 | 
				
			||||||
 | 
							sum = (signed int *)   ((char *)sum + sum_step);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void generic_mix_areas_32_native(unsigned int size,
 | 
					static void generic_mix_areas_32_native(unsigned int size,
 | 
				
			||||||
					volatile signed int *dst,
 | 
										volatile signed int *dst,
 | 
				
			||||||
					signed int *src,
 | 
										signed int *src,
 | 
				
			||||||
| 
						 | 
					@ -170,7 +201,7 @@ static void generic_mix_areas_32_native(unsigned int size,
 | 
				
			||||||
	register signed int sample;
 | 
						register signed int sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
		sample = *src / 256;
 | 
							sample = *src >> 8;
 | 
				
			||||||
		if (! *dst) {
 | 
							if (! *dst) {
 | 
				
			||||||
			*sum = sample;
 | 
								*sum = sample;
 | 
				
			||||||
			*dst = *src;
 | 
								*dst = *src;
 | 
				
			||||||
| 
						 | 
					@ -193,6 +224,39 @@ static void generic_mix_areas_32_native(unsigned int size,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void generic_remix_areas_32_native(unsigned int size,
 | 
				
			||||||
 | 
										  volatile signed int *dst,
 | 
				
			||||||
 | 
										  signed int *src,
 | 
				
			||||||
 | 
										  volatile signed int *sum,
 | 
				
			||||||
 | 
										  size_t dst_step,
 | 
				
			||||||
 | 
										  size_t src_step,
 | 
				
			||||||
 | 
										  size_t sum_step)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register signed int sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							sample = *src >> 8;
 | 
				
			||||||
 | 
							if (! *dst) {
 | 
				
			||||||
 | 
								*sum = -sample;
 | 
				
			||||||
 | 
								*dst = *src;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								*sum = sample = *sum - sample;
 | 
				
			||||||
 | 
								if (sample > 0x7fffff)
 | 
				
			||||||
 | 
									sample = 0x7fffffff;
 | 
				
			||||||
 | 
								else if (sample < -0x800000)
 | 
				
			||||||
 | 
									sample = -0x80000000;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									sample *= 256;
 | 
				
			||||||
 | 
								*dst = sample;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!--size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							src = (signed int *) ((char *)src + src_step);
 | 
				
			||||||
 | 
							dst = (signed int *) ((char *)dst + dst_step);
 | 
				
			||||||
 | 
							sum = (signed int *) ((char *)sum + sum_step);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void generic_mix_areas_16_swap(unsigned int size,
 | 
					static void generic_mix_areas_16_swap(unsigned int size,
 | 
				
			||||||
				      volatile signed short *dst,
 | 
									      volatile signed short *dst,
 | 
				
			||||||
				      signed short *src,
 | 
									      signed short *src,
 | 
				
			||||||
| 
						 | 
					@ -225,6 +289,37 @@ static void generic_mix_areas_16_swap(unsigned int size,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void generic_remix_areas_16_swap(unsigned int size,
 | 
				
			||||||
 | 
									        volatile signed short *dst,
 | 
				
			||||||
 | 
									        signed short *src,
 | 
				
			||||||
 | 
									        volatile signed int *sum,
 | 
				
			||||||
 | 
									        size_t dst_step,
 | 
				
			||||||
 | 
									        size_t src_step,
 | 
				
			||||||
 | 
									        size_t sum_step)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register signed int sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							sample = (signed short) bswap_16(*src);
 | 
				
			||||||
 | 
							if (! *dst) {
 | 
				
			||||||
 | 
								*sum = -sample;
 | 
				
			||||||
 | 
								*dst = *src;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								*sum = sample = *sum - sample;
 | 
				
			||||||
 | 
								if (sample > 0x7fff)
 | 
				
			||||||
 | 
									sample = 0x7fff;
 | 
				
			||||||
 | 
								else if (sample < -0x8000)
 | 
				
			||||||
 | 
									sample = -0x8000;
 | 
				
			||||||
 | 
								*dst = (signed short) bswap_16((signed short) sample);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!--size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							src = (signed short *) ((char *)src + src_step);
 | 
				
			||||||
 | 
							dst = (signed short *) ((char *)dst + dst_step);
 | 
				
			||||||
 | 
							sum = (signed int *)   ((char *)sum + sum_step);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void generic_mix_areas_32_swap(unsigned int size,
 | 
					static void generic_mix_areas_32_swap(unsigned int size,
 | 
				
			||||||
				      volatile signed int *dst,
 | 
									      volatile signed int *dst,
 | 
				
			||||||
				      signed int *src,
 | 
									      signed int *src,
 | 
				
			||||||
| 
						 | 
					@ -236,7 +331,7 @@ static void generic_mix_areas_32_swap(unsigned int size,
 | 
				
			||||||
	register signed int sample;
 | 
						register signed int sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
		sample = bswap_32(*src) / 256;
 | 
							sample = bswap_32(*src) >> 8;
 | 
				
			||||||
		if (! *dst) {
 | 
							if (! *dst) {
 | 
				
			||||||
			*sum = sample;
 | 
								*sum = sample;
 | 
				
			||||||
			*dst = *src;
 | 
								*dst = *src;
 | 
				
			||||||
| 
						 | 
					@ -259,6 +354,39 @@ static void generic_mix_areas_32_swap(unsigned int size,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void generic_remix_areas_32_swap(unsigned int size,
 | 
				
			||||||
 | 
									        volatile signed int *dst,
 | 
				
			||||||
 | 
									        signed int *src,
 | 
				
			||||||
 | 
									        volatile signed int *sum,
 | 
				
			||||||
 | 
									        size_t dst_step,
 | 
				
			||||||
 | 
									        size_t src_step,
 | 
				
			||||||
 | 
									        size_t sum_step)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register signed int sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							sample = bswap_32(*src) >> 8;
 | 
				
			||||||
 | 
							if (! *dst) {
 | 
				
			||||||
 | 
								*sum = -sample;
 | 
				
			||||||
 | 
								*dst = *src;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								*sum = sample = *sum - sample;
 | 
				
			||||||
 | 
								if (sample > 0x7fffff)
 | 
				
			||||||
 | 
									sample = 0x7fffffff;
 | 
				
			||||||
 | 
								else if (sample < -0x800000)
 | 
				
			||||||
 | 
									sample = -0x80000000;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									sample *= 256;
 | 
				
			||||||
 | 
								*dst = bswap_32(sample);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!--size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							src = (signed int *) ((char *)src + src_step);
 | 
				
			||||||
 | 
							dst = (signed int *) ((char *)dst + dst_step);
 | 
				
			||||||
 | 
							sum = (signed int *) ((char *)sum + sum_step);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* always little endian */
 | 
					/* always little endian */
 | 
				
			||||||
static void generic_mix_areas_24(unsigned int size,
 | 
					static void generic_mix_areas_24(unsigned int size,
 | 
				
			||||||
				 volatile unsigned char *dst,
 | 
									 volatile unsigned char *dst,
 | 
				
			||||||
| 
						 | 
					@ -293,6 +421,38 @@ static void generic_mix_areas_24(unsigned int size,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void generic_remix_areas_24(unsigned int size,
 | 
				
			||||||
 | 
									   volatile unsigned char *dst,
 | 
				
			||||||
 | 
									   unsigned char *src,
 | 
				
			||||||
 | 
									   volatile signed int *sum,
 | 
				
			||||||
 | 
									   size_t dst_step,
 | 
				
			||||||
 | 
									   size_t src_step,
 | 
				
			||||||
 | 
									   size_t sum_step)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register signed int sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							sample = src[0] | (src[1] << 8) | (((signed char *)src)[2] << 16);
 | 
				
			||||||
 | 
							if (!(dst[0] | dst[1] | dst[2])) {
 | 
				
			||||||
 | 
								*sum = -sample;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								*sum = sample = *sum - sample;
 | 
				
			||||||
 | 
								if (sample > 0x7fffff)
 | 
				
			||||||
 | 
									sample = 0x7fffff;
 | 
				
			||||||
 | 
								else if (sample < -0x800000)
 | 
				
			||||||
 | 
									sample = -0x800000;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							dst[0] = sample;
 | 
				
			||||||
 | 
							dst[1] = sample >> 8;
 | 
				
			||||||
 | 
							dst[2] = sample >> 16;
 | 
				
			||||||
 | 
							if (!--size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							dst += dst_step;
 | 
				
			||||||
 | 
							src += src_step;
 | 
				
			||||||
 | 
							sum = (signed int *) ((char *)sum + sum_step);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void generic_mix_areas_u8(unsigned int size,
 | 
					static void generic_mix_areas_u8(unsigned int size,
 | 
				
			||||||
				 volatile unsigned char *dst,
 | 
									 volatile unsigned char *dst,
 | 
				
			||||||
				 unsigned char *src,
 | 
									 unsigned char *src,
 | 
				
			||||||
| 
						 | 
					@ -322,18 +482,52 @@ static void generic_mix_areas_u8(unsigned int size,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void generic_remix_areas_u8(unsigned int size,
 | 
				
			||||||
 | 
									   volatile unsigned char *dst,
 | 
				
			||||||
 | 
									   unsigned char *src,
 | 
				
			||||||
 | 
									   volatile signed int *sum,
 | 
				
			||||||
 | 
									   size_t dst_step,
 | 
				
			||||||
 | 
									   size_t src_step,
 | 
				
			||||||
 | 
									   size_t sum_step)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							register int sample = *src - 0x80;
 | 
				
			||||||
 | 
							if (*dst == 0x80) {
 | 
				
			||||||
 | 
								*sum = -sample;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								*sum = sample = *sum - sample;
 | 
				
			||||||
 | 
								if (sample > 0x7f)
 | 
				
			||||||
 | 
									sample = 0x7f;
 | 
				
			||||||
 | 
								else if (sample < -0x80)
 | 
				
			||||||
 | 
									sample = -0x80;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							*dst = sample + 0x80;
 | 
				
			||||||
 | 
							if (!--size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							dst += dst_step;
 | 
				
			||||||
 | 
							src += src_step;
 | 
				
			||||||
 | 
							sum = (signed int *) ((char *)sum + sum_step);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
 | 
					static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (snd_pcm_format_cpu_endian(dmix->shmptr->s.format)) {
 | 
						if (snd_pcm_format_cpu_endian(dmix->shmptr->s.format)) {
 | 
				
			||||||
		dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_native;
 | 
							dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_native;
 | 
				
			||||||
		dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_native;
 | 
							dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_native;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_16 = generic_remix_areas_16_native;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_32 = generic_remix_areas_32_native;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_swap;
 | 
							dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_swap;
 | 
				
			||||||
		dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_swap;
 | 
							dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_swap;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_16 = generic_remix_areas_16_swap;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_32 = generic_remix_areas_32_swap;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dmix->u.dmix.mix_areas_24 = generic_mix_areas_24;
 | 
						dmix->u.dmix.mix_areas_24 = generic_mix_areas_24;
 | 
				
			||||||
	dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8;
 | 
						dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8;
 | 
				
			||||||
 | 
						dmix->u.dmix.remix_areas_24 = generic_remix_areas_24;
 | 
				
			||||||
 | 
						dmix->u.dmix.remix_areas_u8 = generic_remix_areas_u8;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,8 @@
 | 
				
			||||||
#define MIX_AREAS_24 mix_areas_24
 | 
					#define MIX_AREAS_24 mix_areas_24
 | 
				
			||||||
#define MIX_AREAS_24_CMOV mix_areas_24_cmov
 | 
					#define MIX_AREAS_24_CMOV mix_areas_24_cmov
 | 
				
			||||||
#define LOCK_PREFIX ""
 | 
					#define LOCK_PREFIX ""
 | 
				
			||||||
 | 
					#define XADD "addl"
 | 
				
			||||||
 | 
					#define XSUB "subl"
 | 
				
			||||||
#include "pcm_dmix_i386.h"
 | 
					#include "pcm_dmix_i386.h"
 | 
				
			||||||
#undef MIX_AREAS_16
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
#undef MIX_AREAS_16_MMX
 | 
					#undef MIX_AREAS_16_MMX
 | 
				
			||||||
| 
						 | 
					@ -15,6 +17,26 @@
 | 
				
			||||||
#undef MIX_AREAS_24
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
#undef MIX_AREAS_24_CMOV
 | 
					#undef MIX_AREAS_24_CMOV
 | 
				
			||||||
#undef LOCK_PREFIX
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MIX_AREAS_16 remix_areas_16
 | 
				
			||||||
 | 
					#define MIX_AREAS_16_MMX remix_areas_16_mmx
 | 
				
			||||||
 | 
					#define MIX_AREAS_32 remix_areas_32
 | 
				
			||||||
 | 
					#define MIX_AREAS_24 remix_areas_24
 | 
				
			||||||
 | 
					#define MIX_AREAS_24_CMOV remix_areas_24_cmov
 | 
				
			||||||
 | 
					#define LOCK_PREFIX ""
 | 
				
			||||||
 | 
					#define XADD "subl"
 | 
				
			||||||
 | 
					#define XSUB "addl"
 | 
				
			||||||
 | 
					#include "pcm_dmix_i386.h"
 | 
				
			||||||
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
 | 
					#undef MIX_AREAS_16_MMX
 | 
				
			||||||
 | 
					#undef MIX_AREAS_32
 | 
				
			||||||
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
 | 
					#undef MIX_AREAS_24_CMOV
 | 
				
			||||||
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MIX_AREAS_16 mix_areas_16_smp
 | 
					#define MIX_AREAS_16 mix_areas_16_smp
 | 
				
			||||||
#define MIX_AREAS_16_MMX mix_areas_16_smp_mmx
 | 
					#define MIX_AREAS_16_MMX mix_areas_16_smp_mmx
 | 
				
			||||||
| 
						 | 
					@ -22,6 +44,8 @@
 | 
				
			||||||
#define MIX_AREAS_24 mix_areas_24_smp
 | 
					#define MIX_AREAS_24 mix_areas_24_smp
 | 
				
			||||||
#define MIX_AREAS_24_CMOV mix_areas_24_smp_cmov
 | 
					#define MIX_AREAS_24_CMOV mix_areas_24_smp_cmov
 | 
				
			||||||
#define LOCK_PREFIX "lock ; "
 | 
					#define LOCK_PREFIX "lock ; "
 | 
				
			||||||
 | 
					#define XADD "addl"
 | 
				
			||||||
 | 
					#define XSUB "subl"
 | 
				
			||||||
#include "pcm_dmix_i386.h"
 | 
					#include "pcm_dmix_i386.h"
 | 
				
			||||||
#undef MIX_AREAS_16
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
#undef MIX_AREAS_16_MMX
 | 
					#undef MIX_AREAS_16_MMX
 | 
				
			||||||
| 
						 | 
					@ -29,6 +53,26 @@
 | 
				
			||||||
#undef MIX_AREAS_24
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
#undef MIX_AREAS_24_CMOV
 | 
					#undef MIX_AREAS_24_CMOV
 | 
				
			||||||
#undef LOCK_PREFIX
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					#define MIX_AREAS_16 remix_areas_16_smp
 | 
				
			||||||
 | 
					#define MIX_AREAS_16_MMX remix_areas_16_smp_mmx
 | 
				
			||||||
 | 
					#define MIX_AREAS_32 remix_areas_32_smp
 | 
				
			||||||
 | 
					#define MIX_AREAS_24 remix_areas_24_smp
 | 
				
			||||||
 | 
					#define MIX_AREAS_24_CMOV remix_areas_24_smp_cmov
 | 
				
			||||||
 | 
					#define LOCK_PREFIX "lock ; "
 | 
				
			||||||
 | 
					#define XADD "subl"
 | 
				
			||||||
 | 
					#define XSUB "addl"
 | 
				
			||||||
 | 
					#include "pcm_dmix_i386.h"
 | 
				
			||||||
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
 | 
					#undef MIX_AREAS_16_MMX
 | 
				
			||||||
 | 
					#undef MIX_AREAS_32
 | 
				
			||||||
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
 | 
					#undef MIX_AREAS_24_CMOV
 | 
				
			||||||
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
#define i386_dmix_supported_format \
 | 
					#define i386_dmix_supported_format \
 | 
				
			||||||
	((1ULL << SND_PCM_FORMAT_S16_LE) |\
 | 
						((1ULL << SND_PCM_FORMAT_S16_LE) |\
 | 
				
			||||||
| 
						 | 
					@ -71,13 +115,18 @@ static void mix_select_callbacks(snd_pcm_direct_t *dmix)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (mmx) {
 | 
						if (mmx) {
 | 
				
			||||||
		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp_mmx : mix_areas_16_mmx;
 | 
							dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp_mmx : mix_areas_16_mmx;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp_mmx : remix_areas_16_mmx;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp : mix_areas_16;
 | 
							dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp : mix_areas_16;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp : remix_areas_16;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dmix->u.dmix.mix_areas_32 = smp > 1 ? mix_areas_32_smp : mix_areas_32;
 | 
						dmix->u.dmix.mix_areas_32 = smp > 1 ? mix_areas_32_smp : mix_areas_32;
 | 
				
			||||||
 | 
						dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32;
 | 
				
			||||||
	if (cmov) {
 | 
						if (cmov) {
 | 
				
			||||||
		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp_cmov : mix_areas_24_cmov;
 | 
							dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp_cmov : mix_areas_24_cmov;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp_cmov : remix_areas_24_cmov;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24;
 | 
							dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24;
 | 
				
			||||||
 | 
							dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp: remix_areas_24;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,9 +83,9 @@ static void MIX_AREAS_16(unsigned int size,
 | 
				
			||||||
		"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
 | 
							"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
 | 
				
			||||||
		"\tmovswl (%%esi), %%ecx\n"
 | 
							"\tmovswl (%%esi), %%ecx\n"
 | 
				
			||||||
		"\tjnz 3f\n"
 | 
							"\tjnz 3f\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"3:"
 | 
							"3:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%ebx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					@ -202,9 +202,9 @@ static void MIX_AREAS_16_MMX(unsigned int size,
 | 
				
			||||||
		"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
 | 
							"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
 | 
				
			||||||
		"\tmovswl (%%esi), %%ecx\n"
 | 
							"\tmovswl (%%esi), %%ecx\n"
 | 
				
			||||||
		"\tjnz 3f\n"
 | 
							"\tjnz 3f\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"3:"
 | 
							"3:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%ebx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					@ -291,14 +291,14 @@ static void MIX_AREAS_32(unsigned int size,
 | 
				
			||||||
		"\tmovl (%%esi), %%ecx\n"
 | 
							"\tmovl (%%esi), %%ecx\n"
 | 
				
			||||||
		/* sample >>= 8 */
 | 
							/* sample >>= 8 */
 | 
				
			||||||
		"\tsarl $8, %%ecx\n"
 | 
							"\tsarl $8, %%ecx\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"\tjmp 21f\n"
 | 
							"\tjmp 21f\n"
 | 
				
			||||||
		"2:"
 | 
							"2:"
 | 
				
			||||||
		"\tmovl (%%esi), %%ecx\n"
 | 
							"\tmovl (%%esi), %%ecx\n"
 | 
				
			||||||
		/* sample >>= 8 */
 | 
							/* sample >>= 8 */
 | 
				
			||||||
		"\tsarl $8, %%ecx\n"
 | 
							"\tsarl $8, %%ecx\n"
 | 
				
			||||||
		"21:"
 | 
							"21:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%ebx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					@ -403,9 +403,9 @@ static void MIX_AREAS_24(unsigned int size,
 | 
				
			||||||
		"\t" LOCK_PREFIX "btsl $0, (%%edi)\n"
 | 
							"\t" LOCK_PREFIX "btsl $0, (%%edi)\n"
 | 
				
			||||||
		"\tleal (%%ecx,%%eax,1), %%ecx\n"
 | 
							"\tleal (%%ecx,%%eax,1), %%ecx\n"
 | 
				
			||||||
		"\tjc 2f\n"
 | 
							"\tjc 2f\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"2:"
 | 
							"2:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%ebx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					@ -508,9 +508,9 @@ static void MIX_AREAS_24_CMOV(unsigned int size,
 | 
				
			||||||
		"\t" LOCK_PREFIX "btsl $0, (%%edi)\n"
 | 
							"\t" LOCK_PREFIX "btsl $0, (%%edi)\n"
 | 
				
			||||||
		"\tleal (%%ecx,%%eax,1), %%ecx\n"
 | 
							"\tleal (%%ecx,%%eax,1), %%ecx\n"
 | 
				
			||||||
		"\tjc 2f\n"
 | 
							"\tjc 2f\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"2:"
 | 
							"2:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%ebx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,21 +6,57 @@
 | 
				
			||||||
#define MIX_AREAS_32 mix_areas_32
 | 
					#define MIX_AREAS_32 mix_areas_32
 | 
				
			||||||
#define MIX_AREAS_24 mix_areas_24
 | 
					#define MIX_AREAS_24 mix_areas_24
 | 
				
			||||||
#define LOCK_PREFIX ""
 | 
					#define LOCK_PREFIX ""
 | 
				
			||||||
 | 
					#define XADD "addl"
 | 
				
			||||||
 | 
					#define XSUB "subl"
 | 
				
			||||||
#include "pcm_dmix_x86_64.h"
 | 
					#include "pcm_dmix_x86_64.h"
 | 
				
			||||||
#undef MIX_AREAS_16
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
#undef MIX_AREAS_32
 | 
					#undef MIX_AREAS_32
 | 
				
			||||||
#undef MIX_AREAS_24
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
#undef LOCK_PREFIX
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MIX_AREAS_16 remix_areas_16
 | 
				
			||||||
 | 
					#define MIX_AREAS_32 remix_areas_32
 | 
				
			||||||
 | 
					#define MIX_AREAS_24 remix_areas_24
 | 
				
			||||||
 | 
					#define LOCK_PREFIX ""
 | 
				
			||||||
 | 
					#define XADD "subl"
 | 
				
			||||||
 | 
					#define XSUB "addl"
 | 
				
			||||||
 | 
					#include "pcm_dmix_x86_64.h"
 | 
				
			||||||
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
 | 
					#undef MIX_AREAS_32
 | 
				
			||||||
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MIX_AREAS_16 mix_areas_16_smp
 | 
					#define MIX_AREAS_16 mix_areas_16_smp
 | 
				
			||||||
#define MIX_AREAS_32 mix_areas_32_smp
 | 
					#define MIX_AREAS_32 mix_areas_32_smp
 | 
				
			||||||
#define MIX_AREAS_24 mix_areas_24_smp
 | 
					#define MIX_AREAS_24 mix_areas_24_smp
 | 
				
			||||||
#define LOCK_PREFIX "lock ; "
 | 
					#define LOCK_PREFIX "lock ; "
 | 
				
			||||||
 | 
					#define XADD "addl"
 | 
				
			||||||
 | 
					#define XSUB "subl"
 | 
				
			||||||
#include "pcm_dmix_x86_64.h"
 | 
					#include "pcm_dmix_x86_64.h"
 | 
				
			||||||
#undef MIX_AREAS_16
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
#undef MIX_AREAS_32
 | 
					#undef MIX_AREAS_32
 | 
				
			||||||
#undef MIX_AREAS_24
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
#undef LOCK_PREFIX
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					#define MIX_AREAS_16 remix_areas_16_smp
 | 
				
			||||||
 | 
					#define MIX_AREAS_32 remix_areas_32_smp
 | 
				
			||||||
 | 
					#define MIX_AREAS_24 remix_areas_24_smp
 | 
				
			||||||
 | 
					#define LOCK_PREFIX "lock ; "
 | 
				
			||||||
 | 
					#define XADD "subl"
 | 
				
			||||||
 | 
					#define XSUB "addl"
 | 
				
			||||||
 | 
					#include "pcm_dmix_x86_64.h"
 | 
				
			||||||
 | 
					#undef MIX_AREAS_16
 | 
				
			||||||
 | 
					#undef MIX_AREAS_32
 | 
				
			||||||
 | 
					#undef MIX_AREAS_24
 | 
				
			||||||
 | 
					#undef LOCK_PREFIX
 | 
				
			||||||
 | 
					#undef XADD
 | 
				
			||||||
 | 
					#undef XSUB
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
#define x86_64_dmix_supported_format \
 | 
					#define x86_64_dmix_supported_format \
 | 
				
			||||||
	((1ULL << SND_PCM_FORMAT_S16_LE) |\
 | 
						((1ULL << SND_PCM_FORMAT_S16_LE) |\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,9 +79,9 @@ static void MIX_AREAS_16(unsigned int size,
 | 
				
			||||||
		"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%rdi)\n"
 | 
							"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%rdi)\n"
 | 
				
			||||||
		"\tmovswl (%%rsi), %%ecx\n"
 | 
							"\tmovswl (%%rsi), %%ecx\n"
 | 
				
			||||||
		"\tjnz 2f\n"
 | 
							"\tjnz 2f\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"2:"
 | 
							"2:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%rbx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%rbx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					@ -176,14 +176,14 @@ static void MIX_AREAS_32(unsigned int size,
 | 
				
			||||||
		"\tmovl (%%rsi), %%ecx\n"
 | 
							"\tmovl (%%rsi), %%ecx\n"
 | 
				
			||||||
		/* sample >>= 8 */
 | 
							/* sample >>= 8 */
 | 
				
			||||||
		"\tsarl $8, %%ecx\n"
 | 
							"\tsarl $8, %%ecx\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"\tjmp 21f\n"
 | 
							"\tjmp 21f\n"
 | 
				
			||||||
		"2:"
 | 
							"2:"
 | 
				
			||||||
		"\tmovl (%%rsi), %%ecx\n"
 | 
							"\tmovl (%%rsi), %%ecx\n"
 | 
				
			||||||
		/* sample >>= 8 */
 | 
							/* sample >>= 8 */
 | 
				
			||||||
		"\tsarl $8, %%ecx\n"
 | 
							"\tsarl $8, %%ecx\n"
 | 
				
			||||||
		"21:"
 | 
							"21:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%rbx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%rbx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					@ -290,9 +290,9 @@ static void MIX_AREAS_24(unsigned int size,
 | 
				
			||||||
		"\t" LOCK_PREFIX "btsl $0, (%%rdi)\n"
 | 
							"\t" LOCK_PREFIX "btsl $0, (%%rdi)\n"
 | 
				
			||||||
		"\t.byte 0x67, 0x8d, 0x0c, 0x01\n"
 | 
							"\t.byte 0x67, 0x8d, 0x0c, 0x01\n"
 | 
				
			||||||
		"\tjc 2f\n"
 | 
							"\tjc 2f\n"
 | 
				
			||||||
		"\tsubl %%edx, %%ecx\n"
 | 
							"\t" XSUB " %%edx, %%ecx\n"
 | 
				
			||||||
		"2:"
 | 
							"2:"
 | 
				
			||||||
		"\t" LOCK_PREFIX "addl %%ecx, (%%rbx)\n"
 | 
							"\t" LOCK_PREFIX XADD " %%ecx, (%%rbx)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 *   do {
 | 
							 *   do {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue