OSDN Git Service

More seek support
authorAbramo Bagnara <abramo@alsa-project.org>
Mon, 29 May 2000 19:53:30 +0000 (19:53 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Mon, 29 May 2000 19:53:30 +0000 (19:53 +0000)
include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_hw.c
src/pcm/pcm_local.h
src/pcm/pcm_plug.c

index 62d323b..f595f0c 100644 (file)
@@ -114,6 +114,7 @@ int snd_pcm_stream_flush(snd_pcm_t *handle, int stream);
 int snd_pcm_playback_pause(snd_pcm_t *handle, int enable);
 int snd_pcm_stream_pause(snd_pcm_t *handle, int stream, int enable);
 ssize_t snd_pcm_transfer_size(snd_pcm_t *handle, int stream);
+ssize_t snd_pcm_stream_seek(snd_pcm_t *pcm, int stream, off_t offset);
 ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size);
 ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size);
 ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long  count);
index f2168b3..84dba13 100644 (file)
@@ -419,6 +419,25 @@ ssize_t snd_pcm_transfer_size(snd_pcm_t *pcm, int stream)
        return str->setup.frag_size;
 }
 
+ssize_t snd_pcm_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
+{
+       struct snd_pcm_stream *str;
+       size_t bytes_per_frame;
+       if (!pcm)
+               return -EFAULT;
+       if (stream < 0 || stream > 1)
+               return -EINVAL;
+       str = &pcm->stream[stream];
+       if (!str->open)
+               return -EBADFD;
+       if (!str->valid_setup)
+               return -EBADFD;
+       bytes_per_frame = str->bits_per_frame / 8;
+       if (bytes_per_frame > 0)
+               offset -= offset % bytes_per_frame;
+       return pcm->ops->stream_seek(pcm, stream, offset);
+}
+
 ssize_t snd_pcm_write(snd_pcm_t *pcm, const void *buffer, size_t size)
 {
        if (!pcm)
index 88f147f..c8a31c8 100644 (file)
@@ -36,8 +36,9 @@
 static int snd_pcm_hw_stream_close(snd_pcm_t *pcm, int stream)
 {
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       if (hw->stream[stream].fd >= 0)
-               if (close(hw->stream[stream].fd))
+       int fd = hw->stream[stream].fd;
+       if (fd >= 0)
+               if (close(fd))
                        return -errno;
        return 0;
 }
@@ -56,9 +57,8 @@ int snd_pcm_hw_stream_fd(snd_pcm_t *pcm, int stream)
 static int snd_pcm_hw_stream_nonblock(snd_pcm_t *pcm, int stream, int nonblock)
 {
        long flags;
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
 
        if ((flags = fcntl(fd, F_GETFL)) < 0)
                return -errno;
@@ -89,9 +89,8 @@ static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
 
 static int snd_pcm_hw_stream_info(snd_pcm_t *pcm, snd_pcm_stream_info_t * info)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[info->stream].fd;
+       int fd = hw->stream[info->stream].fd;
        if (fd < 0)
                return -EINVAL;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_INFO, info) < 0)
@@ -101,9 +100,8 @@ static int snd_pcm_hw_stream_info(snd_pcm_t *pcm, snd_pcm_stream_info_t * info)
 
 static int snd_pcm_hw_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t * params)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[params->stream].fd;
+       int fd = hw->stream[params->stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_PARAMS, params) < 0)
                return -errno;
        return 0;
@@ -111,9 +109,8 @@ static int snd_pcm_hw_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t * pa
 
 static int snd_pcm_hw_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t * setup)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[setup->stream].fd;
+       int fd = hw->stream[setup->stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_SETUP, setup) < 0)
                return -errno;
        return 0;
@@ -121,9 +118,8 @@ static int snd_pcm_hw_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t * setu
 
 static int snd_pcm_hw_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t * setup)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0)
                return -errno;
        return 0;
@@ -131,9 +127,8 @@ static int snd_pcm_hw_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_
 
 static int snd_pcm_hw_stream_status(snd_pcm_t *pcm, snd_pcm_stream_status_t * status)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[status->stream].fd;
+       int fd = hw->stream[status->stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_STATUS, status) < 0)
                return -errno;
        return 0;
@@ -141,9 +136,8 @@ static int snd_pcm_hw_stream_status(snd_pcm_t *pcm, snd_pcm_stream_status_t * st
 
 static int snd_pcm_hw_stream_update(snd_pcm_t *pcm, int stream)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_UPDATE) < 0)
                return -errno;
        return 0;
@@ -151,9 +145,8 @@ static int snd_pcm_hw_stream_update(snd_pcm_t *pcm, int stream)
 
 static int snd_pcm_hw_stream_prepare(snd_pcm_t *pcm, int stream)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_PREPARE) < 0)
                return -errno;
        return 0;
@@ -161,9 +154,8 @@ static int snd_pcm_hw_stream_prepare(snd_pcm_t *pcm, int stream)
 
 static int snd_pcm_hw_stream_go(snd_pcm_t *pcm, int stream)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_GO) < 0)
                return -errno;
        return 0;
@@ -171,8 +163,8 @@ static int snd_pcm_hw_stream_go(snd_pcm_t *pcm, int stream)
 
 static int snd_pcm_hw_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
+       int fd;
        if (pcm->stream[SND_PCM_STREAM_PLAYBACK].open)
                fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
        else
@@ -184,9 +176,8 @@ static int snd_pcm_hw_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
 
 static int snd_pcm_hw_stream_drain(snd_pcm_t *pcm, int stream)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_DRAIN) < 0)
                return -errno;
        return 0;
@@ -194,9 +185,8 @@ static int snd_pcm_hw_stream_drain(snd_pcm_t *pcm, int stream)
 
 static int snd_pcm_hw_stream_flush(snd_pcm_t *pcm, int stream)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_FLUSH) < 0)
                return -errno;
        return 0;
@@ -204,20 +194,25 @@ static int snd_pcm_hw_stream_flush(snd_pcm_t *pcm, int stream)
 
 static int snd_pcm_hw_stream_pause(snd_pcm_t *pcm, int stream, int enable)
 {
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[stream].fd;
+       int fd = hw->stream[stream].fd;
        if (ioctl(fd, SND_PCM_IOCTL_STREAM_PAUSE, &enable) < 0)
                return -errno;
        return 0;
 }
 
+static ssize_t snd_pcm_hw_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
+{
+       snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
+       int fd = hw->stream[stream].fd;
+       return lseek(fd, offset, SEEK_CUR);
+}
+
 static ssize_t snd_pcm_hw_write(snd_pcm_t *pcm, const void *buffer, size_t size)
 {
        ssize_t result;
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
+       int fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
        result = write(fd, buffer, size);
        if (result < 0)
                return -errno;
@@ -227,9 +222,8 @@ static ssize_t snd_pcm_hw_write(snd_pcm_t *pcm, const void *buffer, size_t size)
 static ssize_t snd_pcm_hw_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
 {
        ssize_t result;
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
+       int fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
 #if 0
        result = writev(fd, vector, count);
 #else
@@ -248,9 +242,8 @@ static ssize_t snd_pcm_hw_writev(snd_pcm_t *pcm, const struct iovec *vector, uns
 static ssize_t snd_pcm_hw_read(snd_pcm_t *pcm, void *buffer, size_t size)
 {
        ssize_t result;
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
+       int fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
        result = read(fd, buffer, size);
        if (result < 0)
                return -errno;
@@ -260,9 +253,8 @@ static ssize_t snd_pcm_hw_read(snd_pcm_t *pcm, void *buffer, size_t size)
 ssize_t snd_pcm_hw_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
 {
        ssize_t result;
-       int fd;
        snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
-       fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
+       int fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
 #if 0
        result = readv(fd, vector, count);
 #else
@@ -346,6 +338,7 @@ struct snd_pcm_ops snd_pcm_hw_ops = {
        stream_drain: snd_pcm_hw_stream_drain,
        stream_flush: snd_pcm_hw_stream_flush,
        stream_pause: snd_pcm_hw_stream_pause,
+       stream_seek: snd_pcm_hw_stream_seek,
        write: snd_pcm_hw_write,
        writev: snd_pcm_hw_writev,
        read: snd_pcm_hw_read,
index 136f6cf..d57268b 100644 (file)
@@ -39,6 +39,7 @@ struct snd_pcm_ops {
        int (*stream_drain)(snd_pcm_t *pcm, int stream);
        int (*stream_flush)(snd_pcm_t *pcm, int stream);
        int (*stream_pause)(snd_pcm_t *pcm, int stream, int enable);
+       ssize_t (*stream_seek)(snd_pcm_t *pcm, int stream, off_t offset);
        ssize_t (*write)(snd_pcm_t *pcm, const void *buffer, size_t size);
        ssize_t (*writev)(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
        ssize_t (*read)(snd_pcm_t *pcm, void *buffer, size_t size);
index 87879e5..c9f6eb1 100644 (file)
@@ -612,6 +612,28 @@ static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channe
        return 0;
 }
 
+static ssize_t snd_pcm_plug_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
+{
+       ssize_t ret;
+       snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+       if (snd_pcm_plug_direct(pcm, stream))
+               return snd_pcm_seek(plug->slave, stream, offset);
+       if (offset < 0) {
+               offset = snd_pcm_plug_slave_size(pcm, stream, -offset);
+               if (offset < 0)
+                       return offset;
+               offset = -offset;
+       } else {
+               offset = snd_pcm_plug_slave_size(pcm, stream, offset);
+               if (offset < 0)
+                       return offset;
+       }
+       ret = snd_pcm_seek(plug->slave, stream, offset);
+       if (ret < 0)
+               return ret;
+       return snd_pcm_plug_client_size(pcm, stream, ret);
+}
+  
 ssize_t snd_pcm_plug_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
 {
        snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
@@ -776,6 +798,7 @@ struct snd_pcm_ops snd_pcm_plug_ops = {
        stream_drain: snd_pcm_plug_stream_drain,
        stream_flush: snd_pcm_plug_stream_flush,
        stream_pause: snd_pcm_plug_stream_pause,
+       stream_seek: snd_pcm_plug_stream_seek,
        write: snd_pcm_plug_write,
        writev: snd_pcm_plug_writev,
        read: snd_pcm_plug_read,