Changed ALSA unit from bytes to frames. Splitted mmap control structs. Better midlevel interrupt handler

This commit is contained in:
Abramo Bagnara 2000-06-10 12:39:51 +00:00
parent bbdff9fce5
commit e8cac7de4d
13 changed files with 405 additions and 571 deletions

View file

@ -51,7 +51,6 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
size_t frames)
{
io_t *data;
ssize_t result;
struct iovec *vec;
int count, channel;
@ -61,50 +60,38 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
vec = (struct iovec *)((char *)data + sizeof(*data));
if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
assert(src_channels);
if ((result = snd_pcm_plugin_src_frames_to_size(plugin, frames)) < 0)
return result;
count = plugin->src_format.channels;
if (plugin->src_format.interleave) {
result = snd_pcm_write(data->slave, src_channels->area.addr, result);
return snd_pcm_write(data->slave, src_channels->area.addr, frames);
} else {
result /= count;
for (channel = 0; channel < count; channel++) {
if (src_channels[channel].enabled)
vec[channel].iov_base = src_channels[channel].area.addr;
else
vec[channel].iov_base = 0;
vec[channel].iov_len = result;
vec[channel].iov_len = frames;
}
result = snd_pcm_writev(data->slave, vec, count);
return snd_pcm_writev(data->slave, vec, count);
}
if (result < 0)
return result;
return snd_pcm_plugin_src_size_to_frames(plugin, result);
} else if (plugin->stream == SND_PCM_STREAM_CAPTURE) {
assert(dst_channels);
if ((result = snd_pcm_plugin_dst_frames_to_size(plugin, frames)) < 0)
return result;
count = plugin->dst_format.channels;
if (plugin->dst_format.interleave) {
result = snd_pcm_read(data->slave, dst_channels->area.addr, result);
for (channel = 0; channel < count; channel++) {
dst_channels[channel].enabled = src_channels[channel].enabled;
}
return snd_pcm_read(data->slave, dst_channels->area.addr, frames);
} else {
result /= count;
for (channel = 0; channel < count; channel++) {
dst_channels[channel].enabled = src_channels[channel].enabled;
if (dst_channels[channel].enabled)
vec[channel].iov_base = dst_channels[channel].area.addr;
else
vec[channel].iov_base = 0;
vec[channel].iov_len = result;
vec[channel].iov_len = frames;
}
result = snd_pcm_readv(data->slave, vec, count);
return snd_pcm_readv(data->slave, vec, count);
}
if (result < 0)
return result;
return snd_pcm_plugin_dst_size_to_frames(plugin, result);
} else {
assert(0);
}

View file

@ -35,7 +35,6 @@
typedef struct mmap_private_data {
snd_pcm_t *slave;
snd_pcm_mmap_control_t *control;
void *buffer;
#if 0
char *silence;
@ -52,18 +51,16 @@ static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
snd_pcm_channel_area_t *dv;
snd_pcm_stream_t *stream;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
size_t pos;
int ready;
unsigned int channel;
assert(plugin && channels);
data = (mmap_t *)plugin->extra_data;
ctrl = data->control;
stream = &data->slave->stream[plugin->stream];
setup = &stream->setup;
if (ctrl->state < SND_PCM_STATE_PREPARED)
if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) < SND_PCM_STATE_PREPARED)
return -EBADFD;
ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
@ -71,7 +68,7 @@ static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
return ready;
if (!ready) {
struct pollfd pfd;
if (ctrl->state != SND_PCM_STATE_RUNNING)
if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) != SND_PCM_STATE_RUNNING)
return -EPIPE;
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
@ -84,9 +81,8 @@ static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
return -EPIPE;
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
}
pos = ctrl->byte_data % setup->buffer_size;
assert(pos % setup->bytes_align == 0);
pos = (pos * 8) / stream->bits_per_frame;
pos = snd_pcm_mmap_frames_offset(data->slave, plugin->stream);
assert(pos % setup->frames_align == 0);
sv = plugin->src_channels;
dv = stream->channels;
@ -119,7 +115,6 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
snd_pcm_channel_area_t *sv;
snd_pcm_stream_t *stream;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
size_t pos;
int ready;
@ -128,10 +123,9 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
stream = &data->slave->stream[plugin->stream];
setup = &stream->setup;
ctrl = data->control;
if (ctrl->state < SND_PCM_STATE_PREPARED)
if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) < SND_PCM_STATE_PREPARED)
return -EBADFD;
if (ctrl->state == SND_PCM_STATE_PREPARED &&
if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) == SND_PCM_STATE_PREPARED &&
stream->setup.start_mode == SND_PCM_START_DATA) {
err = snd_pcm_stream_go(data->slave, plugin->stream);
if (err < 0)
@ -142,7 +136,7 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
return ready;
if (!ready) {
struct pollfd pfd;
if (ctrl->state != SND_PCM_STATE_RUNNING)
if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) != SND_PCM_STATE_RUNNING)
return -EPIPE;
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
@ -155,9 +149,8 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
return -EPIPE;
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
}
pos = ctrl->byte_data % setup->buffer_size;
assert(pos % setup->bytes_align == 0);
pos = (pos * 8) / stream->bits_per_frame;
pos = snd_pcm_mmap_frames_offset(data->slave, plugin->stream);
assert(pos % setup->frames_align == 0);
sv = stream->channels;
dv = plugin->dst_channels;
@ -182,15 +175,12 @@ static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
{
mmap_t *data;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
snd_pcm_stream_t *str;
int err;
assert(plugin && plugin->prev);
assert(src_channels);
data = (mmap_t *)plugin->extra_data;
ctrl = data->control;
assert(ctrl);
str = &data->slave->stream[SND_PCM_STREAM_PLAYBACK];
setup = &str->setup;
@ -201,8 +191,8 @@ static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
}
#endif
snd_pcm_stream_seek(data->slave, SND_PCM_STREAM_PLAYBACK, frames * str->bits_per_frame / 8);
if (ctrl->state == SND_PCM_STATE_PREPARED &&
snd_pcm_mmap_stream_frame_data(data->slave, SND_PCM_STREAM_PLAYBACK, frames);
if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) == SND_PCM_STATE_PREPARED &&
(str->setup.start_mode == SND_PCM_START_DATA ||
(str->setup.start_mode == SND_PCM_START_FULL &&
!snd_pcm_mmap_ready(data->slave, plugin->stream)))) {
@ -219,17 +209,14 @@ static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin,
size_t frames)
{
mmap_t *data;
snd_pcm_mmap_control_t *ctrl;
snd_pcm_stream_t *str;
assert(plugin && plugin->next);
data = (mmap_t *)plugin->extra_data;
ctrl = data->control;
assert(ctrl);
str = &data->slave->stream[SND_PCM_STREAM_CAPTURE];
/* FIXME: not here the increment */
snd_pcm_stream_seek(data->slave, SND_PCM_STREAM_CAPTURE, frames * str->bits_per_frame / 8);
snd_pcm_mmap_stream_frame_data(data->slave, SND_PCM_STREAM_CAPTURE, frames);
return frames;
}
@ -246,9 +233,11 @@ static int mmap_action(snd_pcm_plugin_t *plugin,
snd_pcm_stream_setup_t *setup;
int result;
if (data->control)
if (data->buffer) {
snd_pcm_munmap(data->slave, plugin->stream);
result = snd_pcm_mmap(data->slave, plugin->stream, &data->control, (void **)&data->buffer);
data->buffer = 0;
}
result = snd_pcm_mmap(data->slave, plugin->stream, NULL, NULL, (void **)&data->buffer);
if (result < 0)
return result;
setup = &data->slave->stream[plugin->stream].setup;
@ -276,7 +265,7 @@ static void mmap_free(snd_pcm_plugin_t *plugin, void *private_data UNUSED)
if (data->silence)
free(data->silence);
#endif
if (data->control)
if (data->buffer)
snd_pcm_munmap(data->slave, plugin->stream);
}

View file

@ -304,8 +304,8 @@ static void *get_s16_labels[4 * 2 * 2] = {
#ifdef GET_S16_END
while(0) {
get_s16_xxx1_xx10: sample = (u_int32_t)as_u8(src) << 8; goto GET_S16_END;
get_s16_xxx1_xx90: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 8; goto GET_S16_END;
get_s16_xxx1_xx10: sample = (u_int16_t)as_u8(src) << 8; goto GET_S16_END;
get_s16_xxx1_xx90: sample = (u_int16_t)(as_u8(src) ^ 0x80) << 8; goto GET_S16_END;
get_s16_xx12_xx12: sample = as_u16(src); goto GET_S16_END;
get_s16_xx12_xx92: sample = as_u16(src) ^ 0x8000; goto GET_S16_END;
get_s16_xx12_xx21: sample = bswap_16(as_u16(src)); goto GET_S16_END;