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