mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-10-29 05:40:25 -04:00 
			
		
		
		
	- splitted mmap in logical steps
- optimized mmap transfer - completed mmap helpers - renamed pcm_plugin_build.c to pcm_common.c
This commit is contained in:
		
							parent
							
								
									5b42e338bb
								
							
						
					
					
						commit
						7b054f4dce
					
				
					 17 changed files with 658 additions and 781 deletions
				
			
		
							
								
								
									
										1
									
								
								TODO
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO
									
										
									
									
									
								
							|  | @ -1,6 +1,5 @@ | |||
| M plug sync and pos problems | ||||
| M Loopback implementation? | ||||
| L break up snd_pcm_mmap_* in logical steps | ||||
| L complete mmap emulation (after plug sync and pos thought) | ||||
| L add hsearch_r code from glibc (for compatibility with older distributions) | ||||
| L move OSS emulation to user space (LD_PRELOAD) | ||||
|  |  | |||
|  | @ -97,7 +97,6 @@ int snd_pcm_channel_info(snd_pcm_t *handle, snd_pcm_channel_info_t *info); | |||
| int snd_pcm_channel_params(snd_pcm_t *handle, snd_pcm_channel_params_t *params); | ||||
| int snd_pcm_channel_setup(snd_pcm_t *handle, snd_pcm_channel_setup_t *setup); | ||||
| int snd_pcm_voice_setup(snd_pcm_t *handle, int channel, snd_pcm_voice_setup_t *setup); | ||||
| int snd_pcm_all_voices_setup(snd_pcm_t *handle, int channel, snd_pcm_voice_setup_t *setup); | ||||
| int snd_pcm_channel_status(snd_pcm_t *handle, snd_pcm_channel_status_t *status); | ||||
| int snd_pcm_channel_update(snd_pcm_t *handle, int channel); | ||||
| int snd_pcm_playback_prepare(snd_pcm_t *handle); | ||||
|  | @ -126,17 +125,36 @@ int snd_pcm_mmap_data(snd_pcm_t *handle, int channel, void **buffer); | |||
| int snd_pcm_munmap_control(snd_pcm_t *handle, int channel); | ||||
| int snd_pcm_munmap_data(snd_pcm_t *handle, int channel); | ||||
| int snd_pcm_voices_mask(snd_pcm_t *pcm, int channel, bitset_t *client_vmask); | ||||
| int snd_pcm_mmap_frags_used(snd_pcm_t *pcm, int channel, ssize_t *frags); | ||||
| int snd_pcm_mmap_frags_free(snd_pcm_t *pcm, int channel, ssize_t *frags); | ||||
| int snd_pcm_mmap_bytes_used(snd_pcm_t *pcm, int channel, ssize_t *bytes); | ||||
| int snd_pcm_mmap_bytes_free(snd_pcm_t *pcm, int channel, ssize_t *bytes); | ||||
| int snd_pcm_mmap_ready(snd_pcm_t *pcm, int channel); | ||||
| ssize_t snd_pcm_mmap_write(snd_pcm_t *handle, const void *buffer, size_t size); | ||||
| ssize_t snd_pcm_mmap_read(snd_pcm_t *handle, void *buffer, size_t size); | ||||
| ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long  count); | ||||
| ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count); | ||||
| int snd_pcm_mmap_samples_used(snd_pcm_t *pcm, int channel, ssize_t *samples); | ||||
| int snd_pcm_mmap_samples_free(snd_pcm_t *pcm, int channel, ssize_t *samples); | ||||
| ssize_t snd_pcm_mmap_samples_xfer(snd_pcm_t *pcm, int channel, size_t samples); | ||||
| ssize_t snd_pcm_mmap_samples_offset(snd_pcm_t *pcm, int channel); | ||||
| int snd_pcm_mmap_commit_samples(snd_pcm_t *pcm, int channel, int samples); | ||||
| ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_voice_area_t *voices, size_t samples); | ||||
| ssize_t snd_pcm_mmap_write_samples(snd_pcm_t *pcm, const void *buffer, size_t samples); | ||||
| ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_voice_area_t *voices, size_t samples); | ||||
| ssize_t snd_pcm_mmap_read_samples(snd_pcm_t *pcm, const void *buffer, size_t samples); | ||||
| int snd_pcm_mmap_get_areas(snd_pcm_t *pcm, int channel, snd_pcm_voice_area_t *areas); | ||||
| 
 | ||||
| 
 | ||||
| ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int channel); | ||||
| 
 | ||||
| int snd_pcm_area_silence(const snd_pcm_voice_area_t *dst_voice, size_t dst_offset, | ||||
| 			 size_t samples, int format); | ||||
| int snd_pcm_areas_silence(const snd_pcm_voice_area_t *dst_voices, size_t dst_offset, | ||||
| 			  size_t vcount, size_t samples, int format); | ||||
| int snd_pcm_area_copy(const snd_pcm_voice_area_t *src_voice, size_t src_offset, | ||||
| 		      const snd_pcm_voice_area_t *dst_voice, size_t dst_offset, | ||||
| 		      size_t samples, int format); | ||||
| int snd_pcm_areas_copy(const snd_pcm_voice_area_t *src_voices, size_t src_offset, | ||||
| 		       const snd_pcm_voice_area_t *dst_voices, size_t dst_offset, | ||||
| 		       size_t vcount, size_t samples, int format); | ||||
| 
 | ||||
| /* misc */ | ||||
| 
 | ||||
| int snd_pcm_format_signed(int format); | ||||
|  | @ -181,9 +199,7 @@ typedef enum { | |||
| 
 | ||||
| typedef struct snd_stru_pcm_plugin_voice { | ||||
| 	void *aptr;			/* pointer to the allocated area */ | ||||
| 	void *addr;			/* address to voice samples */ | ||||
| 	unsigned int first;		/* offset to first sample in bits */ | ||||
| 	unsigned int step;		/* samples distance in bits */ | ||||
| 	snd_pcm_voice_area_t area; | ||||
| 	unsigned int enabled:1;		/* voice need to be processed */ | ||||
| 	unsigned int wanted:1;		/* voice is wanted */ | ||||
| } snd_pcm_plugin_voice_t; | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ SUBDIRS = plugin | |||
| 
 | ||||
| EXTRA_LTLIBRARIES = libpcm.la | ||||
| 
 | ||||
| libpcm_la_SOURCES = pcm.c pcm_hw.c pcm_plug.c pcm_plugin_build.c pcm_misc.c \ | ||||
| libpcm_la_SOURCES = pcm.c pcm_hw.c pcm_plug.c pcm_common.c pcm_misc.c \ | ||||
| 		    pcm_mmap.c | ||||
| libpcm_la_LIBADD = plugin/libpcmplugin.la | ||||
| noinst_HEADERS = pcm_local.h | ||||
|  |  | |||
|  | @ -83,10 +83,6 @@ int snd_pcm_channel_close(snd_pcm_t *pcm, int channel) | |||
| 		ret = err; | ||||
| 	chan->open = 0; | ||||
| 	chan->valid_setup = 0; | ||||
| 	if (chan->valid_voices_setup) { | ||||
| 		chan->valid_voices_setup = 0; | ||||
| 		free(chan->voices_setup); | ||||
| 	} | ||||
| 	return ret; | ||||
| }	 | ||||
| 
 | ||||
|  | @ -182,6 +178,9 @@ int snd_pcm_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t *setup) | |||
| 	if ((err = pcm->ops->channel_setup(pcm, setup)) < 0) | ||||
| 		return err; | ||||
| 	memcpy(&chan->setup, setup, sizeof(*setup)); | ||||
| 	chan->sample_width = snd_pcm_format_physical_width(setup->format.format); | ||||
| 	chan->bits_per_sample = chan->sample_width * setup->format.voices; | ||||
| 	chan->samples_per_frag = setup->frag_size * 8 / chan->bits_per_sample; | ||||
| 	chan->valid_setup = 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -209,61 +208,9 @@ int snd_pcm_voice_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_setup_t *setu | |||
| 	chan = &pcm->chan[channel]; | ||||
| 	if (!chan->open || !chan->valid_setup) | ||||
| 		return -EBADFD; | ||||
| 	if (chan->valid_voices_setup) { | ||||
| 		if (setup->voice >= chan->setup.format.voices) | ||||
| 			return -EINVAL; | ||||
| 		memcpy(setup, &chan->voices_setup[setup->voice], sizeof(*setup)); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return pcm->ops->voice_setup(pcm, channel, setup); | ||||
| } | ||||
| 
 | ||||
| const snd_pcm_voice_setup_t* snd_pcm_channel_cached_voice_setup(snd_pcm_t *pcm, int channel, unsigned int voice) | ||||
| { | ||||
| 	struct snd_pcm_chan *chan; | ||||
| 	if (!pcm) | ||||
| 		return 0; | ||||
| 	if (channel < 0 || channel > 1) | ||||
| 		return 0; | ||||
| 	chan = &pcm->chan[channel]; | ||||
| 	if (!chan->open || !chan->valid_setup) | ||||
| 		return 0; | ||||
| 	if (voice >= chan->setup.format.voices) | ||||
| 		return 0; | ||||
| 	return &chan->voices_setup[voice]; | ||||
| } | ||||
| 
 | ||||
| int snd_pcm_all_voices_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_setup_t *setup) | ||||
| { | ||||
| 	struct snd_pcm_chan *chan; | ||||
| 	snd_pcm_voice_setup_t *vs, *v; | ||||
| 	unsigned int voice; | ||||
| 	int err; | ||||
| 	if (!pcm) | ||||
| 		return -EFAULT; | ||||
| 	if (channel < 0 || channel > 1) | ||||
| 		return -EINVAL; | ||||
| 	chan = &pcm->chan[channel]; | ||||
| 	if (!chan->open || !chan->valid_setup) | ||||
| 		return -EBADFD; | ||||
| 	vs = calloc(chan->setup.format.voices, sizeof(*setup)); | ||||
| 	for (voice = 0, v = vs; voice < chan->setup.format.voices; ++voice, ++v) { | ||||
| 		v->voice = voice; | ||||
| 		err = snd_pcm_voice_setup(pcm, channel, v); | ||||
| 		if (err < 0) { | ||||
| 			free(vs); | ||||
| 			return err; | ||||
| 		} | ||||
| 		if (setup) { | ||||
| 			memcpy(setup, v, sizeof(*setup)); | ||||
| 			setup++; | ||||
| 		} | ||||
| 	} | ||||
| 	chan->voices_setup = vs; | ||||
| 	chan->valid_voices_setup = 1; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int snd_pcm_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t *status) | ||||
| { | ||||
| 	if (!pcm || !status) | ||||
|  |  | |||
|  | @ -82,8 +82,10 @@ struct snd_pcm_chan { | |||
| 	int mode; | ||||
| 	int valid_setup; | ||||
| 	snd_pcm_channel_setup_t setup; | ||||
| 	int valid_voices_setup; | ||||
| 	snd_pcm_voice_setup_t *voices_setup; | ||||
| 	snd_pcm_voice_area_t *voices; | ||||
| 	size_t sample_width; | ||||
| 	size_t bits_per_sample; | ||||
| 	size_t samples_per_frag; | ||||
| 	snd_pcm_mmap_control_t *mmap_control; | ||||
| 	size_t mmap_control_size; | ||||
| 	int mmap_control_emulation; | ||||
|  | @ -141,13 +143,8 @@ void snd_pcm_plug_buf_unlock(snd_pcm_t *pcm, int channel, void *ptr); | |||
| #define ROUTE_PLUGIN_RESOLUTION 16 | ||||
| 
 | ||||
| int getput_index(int format); | ||||
| int copy_index(int format); | ||||
| int conv_index(int src_format, int dst_format); | ||||
| 
 | ||||
| void snd_pcm_plugin_silence_voice(snd_pcm_plugin_t *plugin, | ||||
| 				  const snd_pcm_plugin_voice_t *dst_voice, | ||||
| 				  size_t samples); | ||||
| 
 | ||||
| #ifdef PLUGIN_DEBUG | ||||
| #define pdprintf( args... ) fprintf(stderr, "plugin: " ##args) | ||||
| #else | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -438,6 +438,7 @@ static int snd_pcm_plug_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t | |||
| 	} | ||||
| 
 | ||||
| 	/* compute right sizes */ | ||||
| 	slave_params.buffer_size = snd_pcm_plug_slave_size(pcm, channel, slave_params.buffer_size); | ||||
| 	slave_params.frag_size = snd_pcm_plug_slave_size(pcm, channel, slave_params.frag_size); | ||||
| 	if (params->mode == SND_PCM_MODE_STREAM) { | ||||
| 		slave_params.buf.stream.bytes_fill_max = snd_pcm_plug_slave_size(pcm, channel, slave_params.buf.stream.bytes_fill_max); | ||||
|  | @ -471,7 +472,7 @@ static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t *s | |||
| 	setup->buffer_size = snd_pcm_plug_client_size(pcm, setup->channel, setup->buffer_size); | ||||
| 	setup->frag_size = snd_pcm_plug_client_size(pcm, setup->channel, setup->frag_size); | ||||
| 	/* FIXME: it may overflow */ | ||||
| 	setup->pos_boundary = snd_pcm_plug_client_size(pcm, setup->channel, setup->pos_boundary); | ||||
| 	setup->byte_boundary = snd_pcm_plug_client_size(pcm, setup->channel, setup->byte_boundary); | ||||
| 	if (setup->mode == SND_PCM_MODE_STREAM) { | ||||
| 		setup->buf.stream.bytes_min = snd_pcm_plug_client_size(pcm, setup->channel, setup->buf.stream.bytes_min); | ||||
| 		setup->buf.stream.bytes_align = snd_pcm_plug_client_size(pcm, setup->channel, setup->buf.stream.bytes_align); | ||||
|  | @ -500,8 +501,8 @@ static int snd_pcm_plug_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t | |||
| 		return 0; | ||||
| 
 | ||||
| 	/* FIXME: may overflow */ | ||||
| 	status->pos_io = snd_pcm_plug_client_size(pcm, status->channel, status->pos_io); | ||||
| 	status->pos_data = snd_pcm_plug_client_size(pcm, status->channel, status->pos_data); | ||||
| 	status->byte_io = snd_pcm_plug_client_size(pcm, status->channel, status->byte_io); | ||||
| 	status->byte_data = snd_pcm_plug_client_size(pcm, status->channel, status->byte_data); | ||||
| 	status->bytes_used = snd_pcm_plug_client_size(pcm, status->channel, status->bytes_used); | ||||
| 	status->bytes_free = snd_pcm_plug_client_size(pcm, status->channel, status->bytes_free); | ||||
| 	return 0;	 | ||||
|  | @ -605,8 +606,8 @@ static int snd_pcm_plug_voice_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_s | |||
|         memset(setup, 0, sizeof(*setup)); | ||||
|         setup->voice = voice; | ||||
| 	chan = &pcm->chan[channel]; | ||||
| 	if (!chan->mmap_control) { | ||||
| 		setup->addr = -1; | ||||
| 	if (!chan->mmap_data) { | ||||
| 		setup->area.addr = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (voice >= chan->setup.format.voices) | ||||
|  | @ -617,14 +618,14 @@ static int snd_pcm_plug_voice_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_s | |||
|                 return width; | ||||
| 	size = chan->mmap_data_size; | ||||
| 	if (chan->setup.format.interleave) { | ||||
|                 setup->addr = 0; | ||||
|                 setup->first = voice * width; | ||||
|                 setup->step = chan->setup.format.voices * width; | ||||
|                 setup->area.addr = chan->mmap_data; | ||||
|                 setup->area.first = chan->sample_width; | ||||
|                 setup->area.step = chan->bits_per_sample; | ||||
|         } else { | ||||
|                 size /= chan->setup.format.voices; | ||||
|                 setup->addr = setup->voice * size; | ||||
|                 setup->first = 0; | ||||
|                 setup->step = width; | ||||
|                 setup->area.addr = chan->mmap_data + setup->voice * size; | ||||
|                 setup->area.first = 0; | ||||
|                 setup->area.step = width; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -231,17 +231,17 @@ static void adpcm_decode(snd_pcm_plugin_t *plugin, | |||
| 		adpcm_voice_t *state; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		srcbit = src_voices[voice].first % 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		srcbit_step = src_voices[voice].step % 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		srcbit = src_voices[voice].area.first % 8; | ||||
| 		dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		srcbit_step = src_voices[voice].area.step % 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		state = &data->voices[voice]; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
|  | @ -290,17 +290,17 @@ static void adpcm_encode(snd_pcm_plugin_t *plugin, | |||
| 		adpcm_voice_t *state; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		dstbit = dst_voices[voice].first % 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		dstbit_step = dst_voices[voice].step % 8; | ||||
| 		src = src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		dstbit = dst_voices[voice].area.first % 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		dstbit_step = dst_voices[voice].area.step % 8; | ||||
| 		state = &data->voices[voice]; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
|  | @ -340,16 +340,16 @@ static ssize_t adpcm_transfer(snd_pcm_plugin_t *plugin, | |||
| 		return 0; | ||||
| 	for (voice = 0; voice < plugin->src_format.voices; voice++) { | ||||
| 		if (plugin->src_format.format == SND_PCM_SFMT_IMA_ADPCM) { | ||||
| 			if (src_voices[voice].first % 4 != 0 || | ||||
| 			    src_voices[voice].step % 4 != 0 || | ||||
| 			    dst_voices[voice].first % 8 != 0 || | ||||
| 			    dst_voices[voice].step % 8 != 0) | ||||
| 			if (src_voices[voice].area.first % 4 != 0 || | ||||
| 			    src_voices[voice].area.step % 4 != 0 || | ||||
| 			    dst_voices[voice].area.first % 8 != 0 || | ||||
| 			    dst_voices[voice].area.step % 8 != 0) | ||||
| 				return -EINVAL; | ||||
| 		} else { | ||||
| 			if (src_voices[voice].first % 8 != 0 || | ||||
| 			    src_voices[voice].step % 8 != 0 || | ||||
| 			    dst_voices[voice].first % 4 != 0 || | ||||
| 			    dst_voices[voice].step % 4 != 0) | ||||
| 			if (src_voices[voice].area.first % 8 != 0 || | ||||
| 			    src_voices[voice].area.step % 8 != 0 || | ||||
| 			    dst_voices[voice].area.first % 4 != 0 || | ||||
| 			    dst_voices[voice].area.step % 4 != 0) | ||||
| 				return -EINVAL; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -161,15 +161,15 @@ static void alaw_decode(snd_pcm_plugin_t *plugin, | |||
| 		size_t samples1; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
| 			signed short sample = alaw2linear(*src); | ||||
|  | @ -204,15 +204,15 @@ static void alaw_encode(snd_pcm_plugin_t *plugin, | |||
| 		size_t samples1; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
| 			goto *get; | ||||
|  | @ -240,11 +240,11 @@ static ssize_t alaw_transfer(snd_pcm_plugin_t *plugin, | |||
| 	if (samples == 0) | ||||
| 		return 0; | ||||
| 	for (voice = 0; voice < plugin->src_format.voices; voice++) { | ||||
| 		if (src_voices[voice].first % 8 != 0 ||  | ||||
| 		    src_voices[voice].step % 8 != 0) | ||||
| 		if (src_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    src_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 		if (dst_voices[voice].first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].step % 8 != 0) | ||||
| 		if (dst_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 	} | ||||
| 	data = (alaw_t *)plugin->extra_data; | ||||
|  |  | |||
|  | @ -68,12 +68,12 @@ static ssize_t block_transfer(snd_pcm_plugin_t *plugin, | |||
| 			return result; | ||||
| 		count = plugin->src_format.voices; | ||||
| 		if (plugin->src_format.interleave) { | ||||
| 			result = snd_pcm_write(data->slave, src_voices->addr, result); | ||||
| 			result = snd_pcm_write(data->slave, src_voices->area.addr, result); | ||||
| 		} else { | ||||
| 			result /= count; | ||||
| 			for (voice = 0; voice < count; voice++) { | ||||
| 				if (src_voices[voice].enabled) | ||||
| 					vec[voice].iov_base = src_voices[voice].addr; | ||||
| 					vec[voice].iov_base = src_voices[voice].area.addr; | ||||
| 				else | ||||
| 					vec[voice].iov_base = 0; | ||||
| 				vec[voice].iov_len = result; | ||||
|  | @ -90,7 +90,7 @@ static ssize_t block_transfer(snd_pcm_plugin_t *plugin, | |||
| 			return result; | ||||
| 		count = plugin->dst_format.voices; | ||||
| 		if (plugin->dst_format.interleave) { | ||||
| 			result = snd_pcm_read(data->slave, dst_voices->addr, result); | ||||
| 			result = snd_pcm_read(data->slave, dst_voices->area.addr, result); | ||||
| 			for (voice = 0; voice < count; voice++) { | ||||
| 				dst_voices[voice].enabled = src_voices[voice].enabled; | ||||
| 			} | ||||
|  | @ -99,7 +99,7 @@ static ssize_t block_transfer(snd_pcm_plugin_t *plugin, | |||
| 			for (voice = 0; voice < count; voice++) { | ||||
| 				dst_voices[voice].enabled = src_voices[voice].enabled; | ||||
| 				if (dst_voices[voice].enabled) | ||||
| 					vec[voice].iov_base = dst_voices[voice].addr; | ||||
| 					vec[voice].iov_base = dst_voices[voice].area.addr; | ||||
| 				else | ||||
| 					vec[voice].iov_base = 0; | ||||
| 				vec[voice].iov_len = result; | ||||
|  |  | |||
|  | @ -35,121 +35,63 @@ | |||
| #include "../pcm_local.h" | ||||
| #endif | ||||
| 
 | ||||
| typedef struct copy_private_data { | ||||
| 	int copy; | ||||
| } copy_t; | ||||
| 
 | ||||
| static void copy(snd_pcm_plugin_t *plugin, | ||||
| 		 const snd_pcm_plugin_voice_t *src_voices, | ||||
| 		 snd_pcm_plugin_voice_t *dst_voices, | ||||
| 		 size_t samples) | ||||
| { | ||||
| #define COPY_LABELS | ||||
| #include "plugin_ops.h" | ||||
| #undef COPY_LABELS | ||||
| 	copy_t *data = (copy_t *)plugin->extra_data; | ||||
| 	void *copy = copy_labels[data->copy]; | ||||
| 	int voice; | ||||
| 	int nvoices = plugin->src_format.voices; | ||||
| 	for (voice = 0; voice < nvoices; ++voice) { | ||||
| 		char *src; | ||||
| 		char *dst; | ||||
| 		int src_step, dst_step; | ||||
| 		size_t samples1; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
| 			goto *copy; | ||||
| #define COPY_END after | ||||
| #include "plugin_ops.h" | ||||
| #undef COPY_END | ||||
| 		after: | ||||
| 			src += src_step; | ||||
| 			dst += dst_step; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static ssize_t copy_transfer(snd_pcm_plugin_t *plugin, | ||||
| 			     const snd_pcm_plugin_voice_t *src_voices, | ||||
| 			     snd_pcm_plugin_voice_t *dst_voices, | ||||
| 			     size_t samples) | ||||
| { | ||||
| 	copy_t *data; | ||||
| 	unsigned int voice; | ||||
| 	unsigned int nvoices; | ||||
| 
 | ||||
| 	if (plugin == NULL || src_voices == NULL || dst_voices == NULL) | ||||
| 		return -EFAULT; | ||||
| 	data = (copy_t *)plugin->extra_data; | ||||
| 	if (samples == 0) | ||||
| 		return 0; | ||||
| 	for (voice = 0; voice < plugin->src_format.voices; voice++) { | ||||
| 		if (src_voices[voice].first % 8 != 0 ||  | ||||
| 		    src_voices[voice].step % 8 != 0) | ||||
| 	nvoices = plugin->src_format.voices; | ||||
| 	for (voice = 0; voice < nvoices; voice++) { | ||||
| 		if (src_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    src_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 		if (dst_voices[voice].first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].step % 8 != 0) | ||||
| 		if (dst_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 		if (!src_voices->enabled) { | ||||
| 			if (dst_voices->wanted) | ||||
| 				snd_pcm_area_silence(&dst_voices->area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices->enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		snd_pcm_area_copy(&src_voices->area, 0, &dst_voices->area, 0, samples, plugin->src_format.format); | ||||
| 	} | ||||
| 	copy(plugin, src_voices, dst_voices, samples); | ||||
| 	return samples; | ||||
| } | ||||
| 
 | ||||
| int copy_index(int format) | ||||
| { | ||||
| 	int size = snd_pcm_format_physical_width(format); | ||||
| 	switch (size) { | ||||
| 	case 8: | ||||
| 		return 0; | ||||
| 	case 16: | ||||
| 		return 1; | ||||
| 	case 32: | ||||
| 		return 2; | ||||
| 	case 64: | ||||
| 		return 3; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
| 	 | ||||
| int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle, | ||||
| 			      int channel, | ||||
| 			      snd_pcm_format_t *format, | ||||
| 			      snd_pcm_plugin_t **r_plugin) | ||||
| { | ||||
| 	int err; | ||||
| 	struct copy_private_data *data; | ||||
| 	snd_pcm_plugin_t *plugin; | ||||
| 	int copy; | ||||
| 	int width; | ||||
| 
 | ||||
| 	if (r_plugin == NULL) | ||||
| 		return -EFAULT; | ||||
| 	*r_plugin = NULL; | ||||
| 
 | ||||
| 	copy = copy_index(format->format); | ||||
| 	if (copy < 0) | ||||
| 	width = snd_pcm_format_physical_width(format->format); | ||||
| 	if (width < 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	err = snd_pcm_plugin_build(handle, channel, | ||||
| 				   "copy", | ||||
| 				   format, | ||||
| 				   format, | ||||
| 				   sizeof(copy_t), | ||||
| 				   0, | ||||
| 				   &plugin); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	data = (copy_t *)plugin->extra_data; | ||||
| 	data->copy = copy; | ||||
| 	plugin->transfer = copy_transfer; | ||||
| 	*r_plugin = plugin; | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -63,15 +63,15 @@ static void convert(snd_pcm_plugin_t *plugin, | |||
| 		size_t samples1; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
| 			goto *conv; | ||||
|  | @ -99,11 +99,11 @@ static ssize_t linear_transfer(snd_pcm_plugin_t *plugin, | |||
| 	if (samples == 0) | ||||
| 		return 0; | ||||
| 	for (voice = 0; voice < plugin->src_format.voices; voice++) { | ||||
| 		if (src_voices[voice].first % 8 != 0 ||  | ||||
| 		    src_voices[voice].step % 8 != 0) | ||||
| 		if (src_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    src_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 		if (dst_voices[voice].first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].step % 8 != 0) | ||||
| 		if (dst_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 	} | ||||
| 	convert(plugin, src_voices, dst_voices, samples); | ||||
|  |  | |||
|  | @ -38,9 +38,7 @@ typedef struct mmap_private_data { | |||
| 	snd_pcm_mmap_control_t *control; | ||||
| 	void *buffer; | ||||
| 	unsigned int frag; | ||||
| 	size_t samples_frag_size; | ||||
| 	char *silence; | ||||
| 	snd_pcm_plugin_voice_t voices[0]; | ||||
| } mmap_t; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -50,22 +48,22 @@ static int mmap_src_voices(snd_pcm_plugin_t *plugin, | |||
| { | ||||
| 	mmap_t *data; | ||||
| 	unsigned int voice; | ||||
|         snd_pcm_plugin_voice_t *dv, *sv; | ||||
|         snd_pcm_plugin_voice_t *sv; | ||||
| 	snd_pcm_voice_area_t *dv; | ||||
| 	struct snd_pcm_chan *chan; | ||||
| 	snd_pcm_channel_setup_t *setup; | ||||
| 	snd_pcm_mmap_control_t *ctrl; | ||||
| 	int frag, f; | ||||
| 	struct pollfd pfd; | ||||
| 	int ready; | ||||
| 
 | ||||
| 	if (plugin == NULL || voices == NULL) | ||||
| 		return -EINVAL; | ||||
| 	data = (mmap_t *)plugin->extra_data; | ||||
| 	if (samples != data->samples_frag_size) | ||||
| 	ctrl = data->control; | ||||
| 	chan = &data->slave->chan[plugin->channel]; | ||||
| 	if (samples != chan->samples_per_frag) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	ctrl = data->control; | ||||
| 	chan = &plugin->handle->chan[plugin->channel]; | ||||
| 	setup = &chan->setup; | ||||
| 	if (ctrl->status < SND_PCM_STATUS_PREPARED) | ||||
| 		return -EBADFD; | ||||
|  | @ -74,11 +72,12 @@ static int mmap_src_voices(snd_pcm_plugin_t *plugin, | |||
| 	if (ready < 0) | ||||
| 		return ready; | ||||
| 	if (!ready) { | ||||
| 		struct pollfd pfd; | ||||
| 		if (ctrl->status != SND_PCM_STATUS_RUNNING) | ||||
| 			return -EPIPE; | ||||
| 		if (chan->mode & SND_PCM_NONBLOCK) | ||||
| 			return -EAGAIN; | ||||
| 		pfd.fd = snd_pcm_file_descriptor(plugin->handle, plugin->channel); | ||||
| 		pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->channel); | ||||
| 		pfd.events = POLLOUT | POLLERR; | ||||
| 		ready = poll(&pfd, 1, 10000); | ||||
| 		if (ready < 0) | ||||
|  | @ -90,16 +89,16 @@ static int mmap_src_voices(snd_pcm_plugin_t *plugin, | |||
| 	frag = ctrl->frag_data; | ||||
| 	f = frag % setup->frags; | ||||
| 
 | ||||
| 	dv = data->voices; | ||||
| 	sv = plugin->src_voices; | ||||
| 	dv = chan->voices; | ||||
| 	*voices = sv; | ||||
| 	for (voice = 0; voice < plugin->src_format.voices; ++voice) { | ||||
| 		sv->enabled = 1; | ||||
| 		sv->wanted = !data->silence[voice * setup->frags + f]; | ||||
| 		sv->aptr = 0; | ||||
| 		sv->addr = dv->addr + (dv->step * data->samples_frag_size * f) / 8; | ||||
| 		sv->first = dv->first; | ||||
| 		sv->step = dv->step; | ||||
| 		sv->area.addr = dv->addr + (dv->step * chan->samples_per_frag * f) / 8; | ||||
| 		sv->area.first = dv->first; | ||||
| 		sv->area.step = dv->step; | ||||
| 		++sv; | ||||
| 		++dv; | ||||
| 	} | ||||
|  | @ -114,21 +113,21 @@ static int mmap_dst_voices(snd_pcm_plugin_t *plugin, | |||
| 	mmap_t *data; | ||||
| 	int err; | ||||
| 	unsigned int voice; | ||||
|         snd_pcm_plugin_voice_t *dv, *sv; | ||||
|         snd_pcm_plugin_voice_t *dv; | ||||
| 	snd_pcm_voice_area_t *sv; | ||||
| 	struct snd_pcm_chan *chan; | ||||
| 	snd_pcm_channel_setup_t *setup; | ||||
| 	snd_pcm_mmap_control_t *ctrl; | ||||
| 	int frag, f; | ||||
| 	struct pollfd pfd; | ||||
| 	int ready; | ||||
| 
 | ||||
| 	if (plugin == NULL || voices == NULL) | ||||
| 		return -EINVAL; | ||||
| 	data = (mmap_t *)plugin->extra_data; | ||||
| 	if (samples != data->samples_frag_size) | ||||
| 	chan = &data->slave->chan[plugin->channel]; | ||||
| 	if (samples != chan->samples_per_frag) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	chan = &plugin->handle->chan[plugin->channel]; | ||||
| 	setup = &chan->setup; | ||||
| 	ctrl = data->control; | ||||
| 	if (ctrl->status < SND_PCM_STATUS_PREPARED) | ||||
|  | @ -143,17 +142,12 @@ static int mmap_dst_voices(snd_pcm_plugin_t *plugin, | |||
| 	if (ready < 0) | ||||
| 		return ready; | ||||
| 	if (!ready) { | ||||
| 		if (ctrl->status == SND_PCM_STATUS_PREPARED && | ||||
| 		    chan->setup.start_mode == SND_PCM_START_FULL) { | ||||
| 			err = snd_pcm_channel_go(data->slave, plugin->channel); | ||||
| 			if (err < 0) | ||||
| 				return err; | ||||
| 		} | ||||
| 		struct pollfd pfd; | ||||
| 		if (ctrl->status != SND_PCM_STATUS_RUNNING) | ||||
| 			return -EPIPE; | ||||
| 		if (chan->mode & SND_PCM_NONBLOCK) | ||||
| 			return -EAGAIN; | ||||
| 		pfd.fd = snd_pcm_file_descriptor(plugin->handle, plugin->channel); | ||||
| 		pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->channel); | ||||
| 		pfd.events = POLLIN | POLLERR; | ||||
| 		ready = poll(&pfd, 1, 10000); | ||||
| 		if (ready < 0) | ||||
|  | @ -166,16 +160,16 @@ static int mmap_dst_voices(snd_pcm_plugin_t *plugin, | |||
| 	frag = ctrl->frag_data; | ||||
| 	f = frag % setup->frags; | ||||
| 
 | ||||
| 	sv = data->voices; | ||||
| 	sv = chan->voices; | ||||
| 	dv = plugin->dst_voices; | ||||
| 	*voices = dv; | ||||
| 	for (voice = 0; voice < plugin->dst_format.voices; ++voice) { | ||||
| 		dv->enabled = 1; | ||||
| 		dv->wanted = 0; | ||||
| 		dv->aptr = 0; | ||||
| 		dv->addr = sv->addr + (sv->step * data->samples_frag_size * f) / 8; | ||||
| 		dv->first = sv->first; | ||||
| 		dv->step = sv->step; | ||||
| 		dv->area.addr = sv->addr + (sv->step * chan->samples_per_frag * f) / 8; | ||||
| 		dv->area.first = sv->first; | ||||
| 		dv->area.step = sv->step; | ||||
| 		++sv; | ||||
| 		++dv; | ||||
| 	} | ||||
|  | @ -218,14 +212,7 @@ static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin, | |||
| 			data->silence[voice * setup->frags + f] = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	frag++; | ||||
| 	if (frag == setup->frag_boundary) { | ||||
| 		ctrl->frag_data = 0; | ||||
| 		ctrl->pos_data = 0; | ||||
| 	} else { | ||||
| 		ctrl->frag_data = frag; | ||||
| 		ctrl->pos_data += setup->frag_size; | ||||
| 	} | ||||
| 	snd_pcm_mmap_commit_samples(data->slave, SND_PCM_CHANNEL_PLAYBACK, samples); | ||||
| 	if (ctrl->status == SND_PCM_STATUS_PREPARED && | ||||
| 	    (chan->setup.start_mode == SND_PCM_START_DATA || | ||||
| 	     (chan->setup.start_mode == SND_PCM_START_FULL && | ||||
|  | @ -262,14 +249,7 @@ static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin, | |||
| 	setup = &data->slave->chan[SND_PCM_CHANNEL_CAPTURE].setup; | ||||
| 
 | ||||
| 	/* FIXME: not here the increment */ | ||||
| 	frag++; | ||||
| 	if (frag == setup->frag_boundary) { | ||||
| 		ctrl->frag_data = 0; | ||||
| 		ctrl->pos_data = 0; | ||||
| 	} else { | ||||
| 		ctrl->frag_data = frag; | ||||
| 		ctrl->pos_data += setup->frag_size; | ||||
| 	} | ||||
| 	snd_pcm_mmap_commit_samples(data->slave, SND_PCM_CHANNEL_CAPTURE, samples); | ||||
| 	return samples; | ||||
| } | ||||
|   | ||||
|  | @ -285,8 +265,6 @@ static int mmap_action(snd_pcm_plugin_t *plugin, | |||
| 	if (action == INIT) { | ||||
| 		snd_pcm_channel_setup_t *setup; | ||||
| 		int result; | ||||
| 		unsigned int voice; | ||||
| 		snd_pcm_plugin_voice_t *v; | ||||
| 
 | ||||
| 		if (data->control) | ||||
| 			snd_pcm_munmap(data->slave, plugin->channel); | ||||
|  | @ -294,22 +272,7 @@ static int mmap_action(snd_pcm_plugin_t *plugin, | |||
| 		if (result < 0) | ||||
| 			return result; | ||||
| 		setup = &data->slave->chan[plugin->channel].setup; | ||||
| 		data->samples_frag_size = setup->frag_size / snd_pcm_format_size(setup->format.format, setup->format.voices); | ||||
| 
 | ||||
| 		v = data->voices; | ||||
| 		for (voice = 0; voice < setup->format.voices; ++voice) { | ||||
| 			snd_pcm_voice_setup_t vsetup; | ||||
| 			 | ||||
| 			vsetup.voice = voice; | ||||
| 			if ((result = snd_pcm_voice_setup(data->slave, plugin->channel, &vsetup)) < 0) | ||||
| 				return result; | ||||
| 			if (vsetup.addr < 0) | ||||
| 				return -EBADFD; | ||||
| 			v->addr = data->buffer + vsetup.addr; | ||||
| 			v->first = vsetup.first; | ||||
| 			v->step = vsetup.step; | ||||
| 			v++; | ||||
| 		} | ||||
| 		if (plugin->channel == SND_PCM_CHANNEL_PLAYBACK) { | ||||
| 			data->silence = malloc(setup->frags * setup->format.voices); | ||||
| 			memset(data->silence, 0, setup->frags * setup->format.voices); | ||||
|  |  | |||
|  | @ -177,15 +177,15 @@ static void mulaw_decode(snd_pcm_plugin_t *plugin, | |||
| 		size_t samples1; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
| 			signed short sample = ulaw2linear(*src); | ||||
|  | @ -220,15 +220,15 @@ static void mulaw_encode(snd_pcm_plugin_t *plugin, | |||
| 		size_t samples1; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		samples1 = samples; | ||||
| 		while (samples1-- > 0) { | ||||
| 			goto *get; | ||||
|  | @ -256,11 +256,11 @@ static ssize_t mulaw_transfer(snd_pcm_plugin_t *plugin, | |||
| 	if (samples == 0) | ||||
| 		return 0; | ||||
| 	for (voice = 0; voice < plugin->src_format.voices; voice++) { | ||||
| 		if (src_voices[voice].first % 8 != 0 ||  | ||||
| 		    src_voices[voice].step % 8 != 0) | ||||
| 		if (src_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    src_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 		if (dst_voices[voice].first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].step % 8 != 0) | ||||
| 		if (dst_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 	} | ||||
| 	data = (mulaw_t *)plugin->extra_data; | ||||
|  |  | |||
|  | @ -106,15 +106,15 @@ static void resample_expand(snd_pcm_plugin_t *plugin, | |||
| 		S2 = rvoices->last_S2; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], dst_samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, dst_samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = (char *)src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = (char *)dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = (char *)src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = (char *)dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		src_samples1 = src_samples; | ||||
| 		dst_samples1 = dst_samples; | ||||
| 		if (pos & ~MASK) { | ||||
|  | @ -190,15 +190,15 @@ static void resample_shrink(snd_pcm_plugin_t *plugin, | |||
| 		S2 = rvoices->last_S2; | ||||
| 		if (!src_voices[voice].enabled) { | ||||
| 			if (dst_voices[voice].wanted) | ||||
| 				snd_pcm_plugin_silence_voice(plugin, &dst_voices[voice], dst_samples); | ||||
| 				snd_pcm_area_silence(&dst_voices[voice].area, 0, dst_samples, plugin->dst_format.format); | ||||
| 			dst_voices[voice].enabled = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		dst_voices[voice].enabled = 1; | ||||
| 		src = (char *)src_voices[voice].addr + src_voices[voice].first / 8; | ||||
| 		dst = (char *)dst_voices[voice].addr + dst_voices[voice].first / 8; | ||||
| 		src_step = src_voices[voice].step / 8; | ||||
| 		dst_step = dst_voices[voice].step / 8; | ||||
| 		src = (char *)src_voices[voice].area.addr + src_voices[voice].area.first / 8; | ||||
| 		dst = (char *)dst_voices[voice].area.addr + dst_voices[voice].area.first / 8; | ||||
| 		src_step = src_voices[voice].area.step / 8; | ||||
| 		dst_step = dst_voices[voice].area.step / 8; | ||||
| 		src_samples1 = src_samples; | ||||
| 		dst_samples1 = dst_samples; | ||||
| 		while (dst_samples1 > 0) { | ||||
|  | @ -313,11 +313,11 @@ static ssize_t rate_transfer(snd_pcm_plugin_t *plugin, | |||
| 	if (samples == 0) | ||||
| 		return 0; | ||||
| 	for (voice = 0; voice < plugin->src_format.voices; voice++) { | ||||
| 		if (src_voices[voice].first % 8 != 0 ||  | ||||
| 		    src_voices[voice].step % 8 != 0) | ||||
| 		if (src_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    src_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 		if (dst_voices[voice].first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].step % 8 != 0) | ||||
| 		if (dst_voices[voice].area.first % 8 != 0 ||  | ||||
| 		    dst_voices[voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -81,7 +81,7 @@ static void route_to_voice_zero(snd_pcm_plugin_t *plugin, | |||
| 				ttable_dst_t* ttable UNUSED, size_t samples) | ||||
| { | ||||
| 	if (dst_voice->wanted) | ||||
| 		snd_pcm_plugin_silence_voice(plugin, dst_voice, samples); | ||||
| 		snd_pcm_area_silence(&dst_voice->area, 0, samples, plugin->dst_format.format); | ||||
| 	dst_voice->enabled = 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -101,7 +101,7 @@ static void route_to_voice_one(snd_pcm_plugin_t *plugin, | |||
| 	int src_step, dst_step; | ||||
| 	for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) { | ||||
| 		src_voice = &src_voices[ttable->srcs[srcidx].voice]; | ||||
| 		if (src_voice->addr != NULL) | ||||
| 		if (src_voice->area.addr != NULL) | ||||
| 			break; | ||||
| 	} | ||||
| 	if (srcidx == ttable->nsrcs) { | ||||
|  | @ -111,10 +111,10 @@ static void route_to_voice_one(snd_pcm_plugin_t *plugin, | |||
| 
 | ||||
| 	dst_voice->enabled = 1; | ||||
| 	conv = conv_labels[data->conv]; | ||||
| 	src = src_voice->addr + src_voice->first / 8; | ||||
| 	src_step = src_voice->step / 8; | ||||
| 	dst = dst_voice->addr + dst_voice->first / 8; | ||||
| 	dst_step = dst_voice->step / 8; | ||||
| 	src = src_voice->area.addr + src_voice->area.first / 8; | ||||
| 	src_step = src_voice->area.step / 8; | ||||
| 	dst = dst_voice->area.addr + dst_voice->area.first / 8; | ||||
| 	dst_step = dst_voice->area.step / 8; | ||||
| 	while (samples-- > 0) { | ||||
| 		goto *conv; | ||||
| #define CONV_END after | ||||
|  | @ -190,8 +190,8 @@ static void route_to_voice(snd_pcm_plugin_t *plugin, | |||
| 		const snd_pcm_plugin_voice_t *src_voice = &src_voices[ttable->srcs[srcidx].voice]; | ||||
| 		if (!src_voice->enabled) | ||||
| 			continue; | ||||
| 		srcs[srcidx1] = src_voice->addr + src_voices->first / 8; | ||||
| 		src_steps[srcidx1] = src_voice->step / 8; | ||||
| 		srcs[srcidx1] = src_voice->area.addr + src_voices->area.first / 8; | ||||
| 		src_steps[srcidx1] = src_voice->area.step / 8; | ||||
| 		src_tt[srcidx1] = ttable->srcs[srcidx]; | ||||
| 		srcidx1++; | ||||
| 	} | ||||
|  | @ -210,8 +210,8 @@ static void route_to_voice(snd_pcm_plugin_t *plugin, | |||
| 	add = add_labels[data->sum_type * 2 + ttable->att]; | ||||
| 	norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size]; | ||||
| 	put32 = put32_labels[data->put]; | ||||
| 	dst = dst_voice->addr + dst_voice->first / 8; | ||||
| 	dst_step = dst_voice->step / 8; | ||||
| 	dst = dst_voice->area.addr + dst_voice->area.first / 8; | ||||
| 	dst_step = dst_voice->area.step / 8; | ||||
| 
 | ||||
| 	while (samples-- > 0) { | ||||
| 		ttable_src_t *ttp = src_tt; | ||||
|  | @ -513,15 +513,15 @@ static ssize_t route_transfer(snd_pcm_plugin_t *plugin, | |||
| 
 | ||||
| 	src_nvoices = plugin->src_format.voices; | ||||
| 	for (src_voice = 0; src_voice < src_nvoices; ++src_voice) { | ||||
| 		if (src_voices[src_voice].first % 8 != 0 ||  | ||||
| 		    src_voices[src_voice].step % 8 != 0) | ||||
| 		if (src_voices[src_voice].area.first % 8 != 0 ||  | ||||
| 		    src_voices[src_voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	dst_nvoices = plugin->dst_format.voices; | ||||
| 	for (dst_voice = 0; dst_voice < dst_nvoices; ++dst_voice) { | ||||
| 		if (dst_voices[dst_voice].first % 8 != 0 ||  | ||||
| 		    dst_voices[dst_voice].step % 8 != 0) | ||||
| 		if (dst_voices[dst_voice].area.first % 8 != 0 ||  | ||||
| 		    dst_voices[dst_voice].area.step % 8 != 0) | ||||
| 			return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -58,12 +58,12 @@ static ssize_t stream_transfer(snd_pcm_plugin_t *plugin, | |||
| 			return result; | ||||
| 		count = plugin->src_format.voices; | ||||
| 		if (plugin->src_format.interleave) { | ||||
| 			result = snd_pcm_write(data->slave, src_voices->addr, result); | ||||
| 			result = snd_pcm_write(data->slave, src_voices->area.addr, result); | ||||
| 		} else { | ||||
| 			result /= count; | ||||
| 			for (voice = 0; voice < count; voice++) { | ||||
| 				if (src_voices[voice].enabled) | ||||
| 					vec[voice].iov_base = src_voices[voice].addr; | ||||
| 					vec[voice].iov_base = src_voices[voice].area.addr; | ||||
| 				else | ||||
| 					vec[voice].iov_base = 0; | ||||
| 				vec[voice].iov_len = result; | ||||
|  | @ -80,7 +80,7 @@ static ssize_t stream_transfer(snd_pcm_plugin_t *plugin, | |||
| 			return result; | ||||
| 		count = plugin->dst_format.voices; | ||||
| 		if (plugin->dst_format.interleave) { | ||||
| 			result = snd_pcm_read(data->slave, dst_voices->addr, result); | ||||
| 			result = snd_pcm_read(data->slave, dst_voices->area.addr, result); | ||||
| 			for (voice = 0; voice < count; voice++) | ||||
| 				dst_voices[voice].enabled = src_voices[voice].enabled; | ||||
| 		} else { | ||||
|  | @ -88,7 +88,7 @@ static ssize_t stream_transfer(snd_pcm_plugin_t *plugin, | |||
| 			for (voice = 0; voice < count; voice++) { | ||||
| 				dst_voices[voice].enabled = src_voices[voice].enabled; | ||||
| 				if (dst_voices[voice].enabled) | ||||
| 					vec[voice].iov_base = dst_voices[voice].addr; | ||||
| 					vec[voice].iov_base = dst_voices[voice].area.addr; | ||||
| 				else | ||||
| 					vec[voice].iov_base = 0; | ||||
| 				vec[voice].iov_len = result; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Abramo Bagnara
						Abramo Bagnara