From fe92855cbb76a7730bf325b08b92332f21542985 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Tue, 26 Sep 2000 09:46:05 +0000 Subject: [PATCH] Added rewind to API in place of appl_ptr(). Moved aserver to a better place --- Makefile.am | 2 +- acinclude.m4 | 2 +- {src/aserver => aserver}/Makefile.am | 6 ++--- {src/aserver => aserver}/aserver.c | 4 +-- configure.in | 4 +-- include/aserver.h | 5 ++-- include/pcm.h | 3 +-- src/Makefile.am | 2 +- src/pcm/pcm.c | 14 +++------- src/pcm/pcm_client.c | 8 +++--- src/pcm/pcm_file.c | 13 ++++++--- src/pcm/pcm_hw.c | 27 +++++++++++-------- src/pcm/pcm_local.h | 3 ++- src/pcm/pcm_mmap.c | 9 +++++++ src/pcm/pcm_multi.c | 40 +++++++++++++--------------- src/pcm/pcm_plugin.c | 26 +++++++++++++++--- src/pcm/pcm_plugin.h | 2 +- 17 files changed, 98 insertions(+), 72 deletions(-) rename {src/aserver => aserver}/Makefile.am (63%) rename {src/aserver => aserver}/aserver.c (99%) diff --git a/Makefile.am b/Makefile.am index 48fcacec..7bff906b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=doc include src test utils +SUBDIRS=doc include src aserver test utils EXTRA_DIST=ChangeLog INSTALL TODO configure cvscompile libtool version INCLUDES=-I$(top_srcdir)/include diff --git a/acinclude.m4 b/acinclude.m4 index 1bf50ad9..6857c8b8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -10,7 +10,7 @@ void main(void) #if !defined(SND_PROTOCOL_VERSION) || !defined(SND_PROTOCOL_INCOMPATIBLE) #error not found #else -#if !defined(SND_PCM_IOCTL_APPL_PTR) +#if !defined(SND_PCM_IOCTL_REWIND) #error wrong version #endif exit(0); diff --git a/src/aserver/Makefile.am b/aserver/Makefile.am similarity index 63% rename from src/aserver/Makefile.am rename to aserver/Makefile.am index 4568805d..5b88a747 100644 --- a/src/aserver/Makefile.am +++ b/aserver/Makefile.am @@ -2,12 +2,12 @@ bin_PROGRAMS = aserver aserver_SOURCES = aserver.c # aserver_LDADD = -lasound -aserver_LDADD = ../libasound.la +aserver_LDADD = ../src/libasound.la all: aserver INCLUDES=-I$(top_srcdir)/include -I$(top_srcdir)/src/pcm -../libasound.la: - $(MAKE) -C .. libasound.la +../src/libasound.la: + $(MAKE) -C ../src libasound.la diff --git a/src/aserver/aserver.c b/aserver/aserver.c similarity index 99% rename from src/aserver/aserver.c rename to aserver/aserver.c index 4a77a952..6c637f25 100644 --- a/src/aserver/aserver.c +++ b/aserver/aserver.c @@ -401,8 +401,8 @@ int pcm_shm_cmd(client_t *client) case SND_PCM_IOCTL_CHANNEL_SETUP: ctrl->result = snd_pcm_channel_setup(pcm, &ctrl->u.channel_setup); break; - case SND_PCM_IOCTL_APPL_PTR: - ctrl->result = snd_pcm_appl_ptr(pcm, ctrl->u.appl_ptr); + case SND_PCM_IOCTL_REWIND: + ctrl->result = snd_pcm_rewind(pcm, ctrl->u.rewind); break; case SND_PCM_IOCTL_LINK: { diff --git a/configure.in b/configure.in index d7fdedcb..e4509775 100644 --- a/configure.in +++ b/configure.in @@ -51,8 +51,8 @@ AC_SUBST(LIBTOOL_VERSION_INFO) AC_OUTPUT(Makefile doc/Makefile include/Makefile src/Makefile \ src/control/Makefile src/mixer/Makefile src/pcm/Makefile \ - src/pcm/plugin/Makefile src/rawmidi/Makefile src/timer/Makefile \ + src/rawmidi/Makefile src/timer/Makefile \ src/hwdep/Makefile src/seq/Makefile src/instr/Makefile \ - src/compat/Makefile src/conf/Makefile src/aserver/Makefile \ + src/compat/Makefile src/conf/Makefile aserver/Makefile \ test/Makefile utils/Makefile \ utils/alsa-lib.spec) diff --git a/include/aserver.h b/include/aserver.h index aef553a8..138534f5 100644 --- a/include/aserver.h +++ b/include/aserver.h @@ -31,7 +31,7 @@ #define SND_PCM_IOCTL_CLOSE _IO ('A', 0xf9) typedef struct { - int result; + long result; int cmd; union { snd_pcm_info_t info; @@ -44,8 +44,7 @@ typedef struct { snd_pcm_channel_info_t channel_info; snd_pcm_channel_params_t channel_params; snd_pcm_channel_setup_t channel_setup; - off_t appl_ptr; - int hw_ptr; + ssize_t rewind; int link; size_t mmap_forward; } u; diff --git a/include/pcm.h b/include/pcm.h index a559176e..3d2c9b9a 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -150,8 +150,7 @@ int snd_pcm_flush(snd_pcm_t *handle); int snd_pcm_pause(snd_pcm_t *handle, int enable); int snd_pcm_state(snd_pcm_t *handle); int snd_pcm_delay(snd_pcm_t *handle, ssize_t *delayp); -size_t snd_pcm_hw_ptr(snd_pcm_t *handle); -ssize_t snd_pcm_appl_ptr(snd_pcm_t *handle, off_t offset); +ssize_t snd_pcm_rewind(snd_pcm_t *handle, size_t frames); ssize_t snd_pcm_writei(snd_pcm_t *handle, const void *buffer, size_t size); ssize_t snd_pcm_readi(snd_pcm_t *handle, void *buffer, size_t size); ssize_t snd_pcm_writen(snd_pcm_t *handle, void **bufs, size_t size); diff --git a/src/Makefile.am b/src/Makefile.am index c6985ed6..b5c29a3f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat conf aserver +SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat conf COMPATNUM=@LIBTOOL_VERSION_INFO@ lib_LTLIBRARIES = libasound.la diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index fbf8bff7..2f1c001d 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -204,15 +204,12 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable) } -ssize_t snd_pcm_appl_ptr(snd_pcm_t *pcm, off_t offset) +ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames) { assert(pcm); assert(pcm->valid_setup); - if (pcm->mmap_control) { - if (offset == 0) - return pcm->mmap_control->appl_ptr; - } - return pcm->fast_ops->appl_ptr(pcm->fast_op_arg, offset); + assert(frames > 0); + return pcm->fast_ops->rewind(pcm->fast_op_arg, frames); } ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size) @@ -659,11 +656,6 @@ ssize_t snd_pcm_mmap_forward(snd_pcm_t *pcm, size_t size) return pcm->fast_ops->mmap_forward(pcm->fast_op_arg, size); } -size_t snd_pcm_hw_ptr(snd_pcm_t *pcm) -{ - return pcm->mmap_status->hw_ptr; -} - int snd_pcm_area_silence(snd_pcm_channel_area_t *dst_area, size_t dst_offset, size_t samples, int format) { diff --git a/src/pcm/pcm_client.c b/src/pcm/pcm_client.c index 7e7799ab..dbf4c338 100644 --- a/src/pcm/pcm_client.c +++ b/src/pcm/pcm_client.c @@ -387,13 +387,13 @@ static int snd_pcm_client_shm_pause(snd_pcm_t *pcm, int enable) return ctrl->result; } -static ssize_t snd_pcm_client_shm_appl_ptr(snd_pcm_t *pcm, off_t offset) +static ssize_t snd_pcm_client_shm_rewind(snd_pcm_t *pcm, size_t frames) { snd_pcm_client_t *client = pcm->private; snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl; int err; - ctrl->cmd = SND_PCM_IOCTL_APPL_PTR; - ctrl->u.appl_ptr = offset; + ctrl->cmd = SND_PCM_IOCTL_REWIND; + ctrl->u.rewind = frames; err = snd_pcm_client_shm_action(pcm); if (err < 0) return err; @@ -569,7 +569,7 @@ struct snd_pcm_fast_ops snd_pcm_client_fast_ops = { stop: snd_pcm_client_shm_stop, flush: snd_pcm_client_shm_flush, pause: snd_pcm_client_shm_pause, - appl_ptr: snd_pcm_client_shm_appl_ptr, + rewind: snd_pcm_client_shm_rewind, writei: snd_pcm_mmap_writei, writen: snd_pcm_mmap_writen, readi: snd_pcm_mmap_readi, diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index 644aae34..316ccd39 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -122,10 +122,17 @@ static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable) return snd_pcm_pause(file->slave, enable); } -static ssize_t snd_pcm_file_appl_ptr(snd_pcm_t *pcm, off_t offset) +static ssize_t snd_pcm_file_rewind(snd_pcm_t *pcm, size_t frames) { snd_pcm_file_t *file = pcm->private; - return snd_pcm_appl_ptr(file->slave, offset); + ssize_t f = snd_pcm_rewind(file->slave, frames); + off_t err; + if (f > 0) { + err = lseek(file->fd, -snd_pcm_frames_to_bytes(pcm, f), SEEK_CUR); + if (err < 0) + return err; + } + return f; } static void snd_pcm_file_write_areas(snd_pcm_t *pcm, @@ -336,7 +343,7 @@ struct snd_pcm_fast_ops snd_pcm_file_fast_ops = { stop: snd_pcm_file_stop, flush: snd_pcm_file_flush, pause: snd_pcm_file_pause, - appl_ptr: snd_pcm_file_appl_ptr, + rewind: snd_pcm_file_rewind, writei: snd_pcm_file_writei, writen: snd_pcm_file_writen, readi: snd_pcm_file_readi, diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index b4f06b40..bdfb3b65 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -225,17 +225,22 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable) return 0; } -static ssize_t snd_pcm_hw_appl_ptr(snd_pcm_t *pcm, off_t offset) +static ssize_t snd_pcm_hw_rewind(snd_pcm_t *pcm, size_t frames) { - ssize_t result; - snd_pcm_hw_t *hw = pcm->private; - int fd = hw->fd; - if (pcm->mmap_status && pcm->mmap_control) - return snd_pcm_mmap_appl_ptr(pcm, offset); - result = ioctl(fd, SND_PCM_IOCTL_APPL_PTR, offset); - if (result < 0) - return -errno; - return result; + ssize_t used; + if (pcm->setup.xrun_mode == SND_PCM_XRUN_ASAP) { + ssize_t d; + int err = snd_pcm_hw_delay(pcm, &d); + if (err < 0) + return 0; + } + used = pcm->setup.buffer_size - snd_pcm_mmap_avail(pcm); + if (used <= 0) + return 0; + if (frames > (size_t)used) + frames = used; + snd_pcm_mmap_appl_backward(pcm, frames); + return frames; } static ssize_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, size_t size) @@ -451,7 +456,7 @@ struct snd_pcm_fast_ops snd_pcm_hw_fast_ops = { stop: snd_pcm_hw_stop, flush: snd_pcm_hw_flush, pause: snd_pcm_hw_pause, - appl_ptr: snd_pcm_hw_appl_ptr, + rewind: snd_pcm_hw_rewind, writei: snd_pcm_hw_writei, writen: snd_pcm_hw_writen, readi: snd_pcm_hw_readi, diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 35154c7a..7f49e42c 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -54,7 +54,7 @@ struct snd_pcm_fast_ops { int (*pause)(snd_pcm_t *pcm, int enable); int (*state)(snd_pcm_t *pcm); int (*delay)(snd_pcm_t *pcm, ssize_t *delayp); - ssize_t (*appl_ptr)(snd_pcm_t *pcm, off_t offset); + ssize_t (*rewind)(snd_pcm_t *pcm, size_t frames); ssize_t (*writei)(snd_pcm_t *pcm, const void *buffer, size_t size); ssize_t (*writen)(snd_pcm_t *pcm, void **bufs, size_t size); ssize_t (*readi)(snd_pcm_t *pcm, void *buffer, size_t size); @@ -96,6 +96,7 @@ int snd_pcm_munmap_control(snd_pcm_t *pcm); int snd_pcm_munmap_data(snd_pcm_t *pcm); int snd_pcm_mmap_ready(snd_pcm_t *pcm); ssize_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset); +void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, size_t frames); void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, size_t frames); void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, size_t frames); size_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm); diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c index 2be47c53..4f05e93e 100644 --- a/src/pcm/pcm_mmap.c +++ b/src/pcm/pcm_mmap.c @@ -173,6 +173,15 @@ ssize_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset) return appl_ptr; } +void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, size_t frames) +{ + ssize_t appl_ptr = pcm->mmap_control->appl_ptr; + appl_ptr -= frames; + if (appl_ptr < 0) + appl_ptr += pcm->setup.boundary; + pcm->mmap_control->appl_ptr = appl_ptr; +} + void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, size_t frames) { size_t appl_ptr = pcm->mmap_control->appl_ptr; diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index f697bd95..daadc52a 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -196,7 +196,6 @@ static int snd_pcm_multi_setup(snd_pcm_t *pcm, snd_pcm_setup_t *setup) return err; if (setup->format.rate != s.format.rate) return -EINVAL; - /* mmap is not feasible */ if (setup->buffer_size != s.buffer_size) return -EINVAL; if (setup->mmap_shape != SND_PCM_MMAP_NONINTERLEAVED || @@ -327,31 +326,28 @@ static int snd_pcm_multi_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * return 0; } -static ssize_t snd_pcm_multi_appl_ptr(snd_pcm_t *pcm, off_t offset) +static ssize_t snd_pcm_multi_rewind(snd_pcm_t *pcm, size_t frames) { snd_pcm_multi_t *multi = pcm->private; - ssize_t pos, newpos; unsigned int i; - snd_pcm_t *handle_0 = multi->slaves[0].handle; - - pos = snd_pcm_appl_ptr(handle_0, 0); - newpos = snd_pcm_appl_ptr(handle_0, offset); - if (newpos < 0) - return newpos; - offset = newpos - pos; - if (offset < 0) - offset += handle_0->setup.boundary; - - for (i = 1; i < multi->slaves_count; ++i) { + size_t pos[multi->slaves_count]; + memset(pos, 0, sizeof(pos)); + for (i = 0; i < multi->slaves_count; ++i) { snd_pcm_t *handle_i = multi->slaves[i].handle; - ssize_t newpos_i; - newpos_i = snd_pcm_appl_ptr(handle_i, offset); - if (newpos_i < 0) - return newpos_i; - if (newpos_i != newpos) - return -EBADFD; + ssize_t f = snd_pcm_rewind(handle_i, frames); + if (f < 0) + return f; + pos[i] = f; + frames = f; + } + /* Realign the pointers */ + for (i = 0; i < multi->slaves_count; ++i) { + snd_pcm_t *handle_i = multi->slaves[i].handle; + size_t f = pos[i] - frames; + if (f > 0) + snd_pcm_mmap_appl_forward(handle_i, f); } - return newpos; + return frames; } static int snd_pcm_multi_mmap_status(snd_pcm_t *pcm) @@ -531,7 +527,7 @@ struct snd_pcm_fast_ops snd_pcm_multi_fast_ops = { writen: snd_pcm_mmap_writen, readi: snd_pcm_mmap_readi, readn: snd_pcm_mmap_readn, - appl_ptr: snd_pcm_multi_appl_ptr, + rewind: snd_pcm_multi_rewind, poll_descriptor: snd_pcm_multi_poll_descriptor, channels_mask: snd_pcm_multi_channels_mask, avail_update: snd_pcm_multi_avail_update, diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index 28257038..1c05ddee 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -154,10 +154,28 @@ int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable) return snd_pcm_pause(plugin->slave, enable); } -ssize_t snd_pcm_plugin_appl_ptr(snd_pcm_t *pcm, off_t offset) +ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames) { - /* FIXME */ - return -ENOSYS; + snd_pcm_plugin_t *plugin = pcm->private; + ssize_t n = pcm->setup.buffer_size - snd_pcm_mmap_avail(pcm); + if (n > 0) { + if ((size_t)n > frames) + n = frames; + snd_pcm_mmap_appl_backward(pcm, n); + frames -= n; + } + if (frames > 0) { + ssize_t err = snd_pcm_rewind(plugin->slave, frames); + if (err < 0) { + if (n > 0) + return n; + return err; + } + if (plugin->client_frames) + err = plugin->client_frames(pcm, err); + n += err; + } + return n; } ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size) @@ -381,7 +399,7 @@ struct snd_pcm_fast_ops snd_pcm_plugin_fast_ops = { stop: snd_pcm_plugin_stop, flush: snd_pcm_plugin_flush, pause: snd_pcm_plugin_pause, - appl_ptr: snd_pcm_plugin_appl_ptr, + rewind: snd_pcm_plugin_rewind, writei: snd_pcm_plugin_writei, writen: snd_pcm_plugin_writen, readi: snd_pcm_plugin_readi, diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h index e76993ca..3f566158 100644 --- a/src/pcm/pcm_plugin.h +++ b/src/pcm/pcm_plugin.h @@ -44,7 +44,7 @@ int snd_pcm_plugin_start(snd_pcm_t *pcm); int snd_pcm_plugin_stop(snd_pcm_t *pcm); int snd_pcm_plugin_flush(snd_pcm_t *pcm); int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable); -ssize_t snd_pcm_plugin_appl_ptr(snd_pcm_t *pcm, off_t offset); +ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames); ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size); ssize_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, size_t size); ssize_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, size_t size); -- 2.47.1