mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-12-20 08:56:54 -05:00
Changed ALSA unit from bytes to frames. Splitted mmap control structs. Better midlevel interrupt handler
This commit is contained in:
parent
bbdff9fce5
commit
e8cac7de4d
13 changed files with 405 additions and 571 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue