]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Removed snd_pcm_hwptr().
authorJaroslav Kysela <perex@perex.cz>
Sat, 22 Feb 2003 17:19:02 +0000 (17:19 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sat, 22 Feb 2003 17:19:02 +0000 (17:19 +0000)
Added snd_pcm_hwdiff() and snd_pcm_forward().
Returned the behaviour for snd_pcm_mmap_begin().

17 files changed:
aserver/aserver.c
include/aserver.h
include/pcm.h
src/Versions
src/pcm/pcm.c
src/pcm/pcm_dmix.c
src/pcm/pcm_file.c
src/pcm/pcm_hooks.c
src/pcm/pcm_hw.c
src/pcm/pcm_jack.c
src/pcm/pcm_local.h
src/pcm/pcm_meter.c
src/pcm/pcm_multi.c
src/pcm/pcm_null.c
src/pcm/pcm_plugin.c
src/pcm/pcm_share.c
src/pcm/pcm_shm.c

index a6b4a4e2ba6a16e2b9202c2f93e1d936690dbdd8..cef3641c6cfc9f0382bcc117be13c75539b3c657 100644 (file)
@@ -471,9 +471,6 @@ static int pcm_shm_cmd(client_t *client)
        case SND_PCM_IOCTL_HWSYNC:
                ctrl->result = snd_pcm_hwsync(pcm);
                break;
-       case SND_PCM_IOCTL_HWPTR:
-               ctrl->result = snd_pcm_hwptr(pcm, (snd_pcm_uframes_t *) &ctrl->u.hwptr.frames);
-               break;
        case SNDRV_PCM_IOCTL_DELAY:
                ctrl->result = snd_pcm_delay(pcm, (snd_pcm_sframes_t *) &ctrl->u.delay.frames);
                break;
@@ -507,6 +504,9 @@ static int pcm_shm_cmd(client_t *client)
        case SNDRV_PCM_IOCTL_REWIND:
                ctrl->result = snd_pcm_rewind(pcm, ctrl->u.rewind.frames);
                break;
+       case SND_PCM_IOCTL_FORWARD:
+               ctrl->result = snd_pcm_forward(pcm, ctrl->u.forward.frames);
+               break;
        case SNDRV_PCM_IOCTL_LINK:
        {
                /* FIXME */
index c6e9f957cb8d47eb174dd3a3bfc5a4ff57912021..2586832460d7a0f33e6c2235298030531a7467a7 100644 (file)
@@ -50,7 +50,7 @@ typedef enum _snd_transport_type {
 #define SND_PCM_IOCTL_POLL_DESCRIPTOR  _IO ('A', 0xf8)
 #define SND_PCM_IOCTL_HW_PTR_FD                _IO ('A', 0xf9)
 #define SND_PCM_IOCTL_APPL_PTR_FD      _IO ('A', 0xfa)
-#define SND_PCM_IOCTL_HWPTR            _IO ('A', 0xfb)
+#define SND_PCM_IOCTL_FORWARD          _IO ('A', 0xfb)
 
 typedef struct {
        snd_pcm_uframes_t ptr;
@@ -74,9 +74,6 @@ typedef struct {
                snd_pcm_hw_params_t hw_params;
                snd_pcm_sw_params_t sw_params;
                snd_pcm_status_t status;
-               struct {
-                       snd_pcm_uframes_t frames;
-               } hwptr;
                struct {
                        snd_pcm_uframes_t frames;
                } avail;
@@ -90,6 +87,9 @@ typedef struct {
                struct {
                        snd_pcm_uframes_t frames;
                } rewind;
+               struct {
+                       snd_pcm_uframes_t frames;
+               } forward;
                struct {
                        int fd;
                } link;
index 0ea5012c1d75cffa9927634a8443c151daeeda3f..e2121886225f6aabe4589f80a24531da07402998 100644 (file)
@@ -410,11 +410,12 @@ int snd_pcm_drain(snd_pcm_t *pcm);
 int snd_pcm_pause(snd_pcm_t *pcm, int enable);
 snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm);
 int snd_pcm_hwsync(snd_pcm_t *pcm);
-int snd_pcm_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *uframes);
+int snd_pcm_hwdiff(snd_pcm_t *pcm, snd_pcm_uframes_t *diff, snd_pcm_uframes_t *old_pos);
 int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
 int snd_pcm_resume(snd_pcm_t *pcm);
 snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
 snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
index 6abc98e4db27b9a99bbfe253dee312e85ba1794f..ea45321ae48d546ddb7d33e214deee47d570e192 100644 (file)
@@ -83,6 +83,7 @@ ALSA_0.9.0rc4 {
 ALSA_0.9.0rc8 {
   global:
 
-    snd_pcm_hwptr;
+    snd_pcm_hwdiff;
+    snd_pcm_forward;
 
 } ALSA_0.9.0rc4;
index 9383346efeddec04f1d41e919f45a64c0e5eae92..b53c43c76dd6e7fc3e5a249256938214047ec620 100644 (file)
@@ -400,6 +400,12 @@ only when the stream is in the running or draining (playback only) state.
 Note that this function does not update the current r/w pointer for applications,
 so the function \link ::snd_pcm_avail_update \endlink must be called afterwards
 before any read/write begin+commit operations.
+<p>
+To determine the processed frames by hardware, the function \link ::snd_pcm_hwdiff \endlink
+might be used. Note that this function returns cached value which is synchronized with
+hardware using the \link ::snd_pcm_hwsync \endlink function. The application may
+manage the right r/w pointer via \link ::snd_pcm_rewind \endlink and
+\link ::snd_pcm_forward \endlink functions.
 
 \section pcm_action Managing the stream state
 
@@ -869,28 +875,42 @@ int snd_pcm_hwsync(snd_pcm_t *pcm)
 }
 
 /**
- * \brief Return hardware pointer
+ * \brief Return count of processed frames by hardware from last call
  * \param pcm PCM handle
+ * \param diff Difference between last position and current
+ * \param old_pos Old position on entry, actual position on exit
  * \return 0 on success otherwise a negative error code
  *
- * The hardware pointer is in range 0 ... (boundary - 1). It contains
+ * The old_ptr parameter is in range 0 ... (boundary - 1). It contains
  * count_of_ring_buffer_crosses * buffer_size + offset in the ring buffer.
+ * Using this value is not intented 
  *
- * Note this function does not return the real hardware pointer.
+ * Note this function does not obtain the real position from hardware.
  * The function \link ::snd_pcm_hwsync \endlink have to be called
  * before to obtain the real hardware position.
  */
 #ifndef DOXYGEN
-int INTERNAL(snd_pcm_hwptr)(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
+int INTERNAL(snd_pcm_hwdiff)(snd_pcm_t *pcm, snd_pcm_uframes_t *diff, snd_pcm_uframes_t *old_pos)
 #else
-int snd_pcm_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
+int snd_pcm_hwdiff(snd_pcm_t *pcm, snd_pcm_uframes_t *diff, snd_pcm_uframes_t *old_pos)
 #endif
 {
-       assert(pcm);
+       snd_pcm_uframes_t d, hw_ptr;
+
+       assert(pcm && diff && old_pos);
        assert(pcm->setup);
-       return pcm->fast_ops->hwptr(pcm->fast_op_arg, hwptr);
+       assert(*old_pos < pcm->boundary);
+       hw_ptr = *pcm->hw.ptr;
+       if (hw_ptr < *old_pos) {
+               d = (pcm->boundary - *old_pos) + hw_ptr;
+       } else {
+               d = hw_ptr - *old_pos;
+       }
+       *diff = d;
+       *old_pos = hw_ptr;
+       return 0;
 }
-default_symbol_version(__snd_pcm_hwptr, snd_pcm_hwptr, ALSA_0.9.0rc8);
+default_symbol_version(__snd_pcm_hwdiff, snd_pcm_hwdiff, ALSA_0.9.0rc8);
 
 /**
  * \brief Obtain delay for a running PCM handle
@@ -1029,6 +1049,25 @@ snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
        return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
 }
 
+/**
+ * \brief Move application frame position forward
+ * \param pcm PCM handle
+ * \param frames wanted skip in frames
+ * \return a positive number for actual skip otherwise a negative error code
+ */
+#ifndef DOXYGEN
+snd_pcm_sframes_t INTERNAL(snd_pcm_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+#else
+snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+#endif
+{
+       assert(pcm);
+       assert(pcm->setup);
+       assert(frames > 0);
+       return pcm->fast_ops->forward(pcm->fast_op_arg, frames);
+}
+default_symbol_version(__snd_pcm_forward, snd_pcm_forward, ALSA_0.9.0rc8);
+
 /**
  * \brief Write interleaved frames to a PCM
  * \param pcm PCM handle
@@ -5816,7 +5855,7 @@ void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
  * \brief Application request to access a portion of direct (mmap) area
  * \param pcm PCM handle 
  * \param areas Returned mmap channel areas
- * \param offset mmap area offset in area steps (== frames) (wanted on entry (see note), returned on exit)
+ * \param offset Returned mmap area offset in area steps (== frames)
  * \param frames mmap area portion size in frames (wanted on entry, contiguous available on exit)
  * \return 0 on success otherwise a negative error code
  *
@@ -5829,10 +5868,6 @@ void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
  *
  * See the snd_pcm_mmap_commit() function to finish the frame processing in
  * the direct areas.
- *
- * Note: The offset value is always overriden when stop_threshold < boundary.
- *       Otherwise, the application must specify it's own offset value.
- * 
  */
 int snd_pcm_mmap_begin(snd_pcm_t *pcm,
                       const snd_pcm_channel_area_t **areas,
@@ -5844,16 +5879,10 @@ int snd_pcm_mmap_begin(snd_pcm_t *pcm,
        snd_pcm_uframes_t avail;
        assert(pcm && areas && offset && frames);
        *areas = snd_pcm_mmap_areas(pcm);
-       if (pcm->stop_threshold < pcm->boundary) {
-               *offset = *pcm->appl.ptr % pcm->buffer_size;
-               avail = snd_pcm_mmap_avail(pcm);
-               if (avail > pcm->buffer_size)
-                       avail = pcm->buffer_size;
-       } else {
-               if (*offset >= pcm->buffer_size)
-                       return -EINVAL;
+       *offset = *pcm->appl.ptr % pcm->buffer_size;
+       avail = snd_pcm_mmap_avail(pcm);
+       if (avail > pcm->buffer_size)
                avail = pcm->buffer_size;
-       }
        cont = pcm->buffer_size - *offset;
        f = *frames;
        if (f > avail)
index ca322b894dc588aa1a890a339bfbbf63cffe5258..588b30204bfc3d0707c6b7ae78872ee9bfd888bf 100644 (file)
@@ -989,25 +989,6 @@ static int snd_pcm_dmix_hwsync(snd_pcm_t *pcm)
        }
 }
 
-static int snd_pcm_dmix_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_dmix_t *dmix = pcm->private_data;
-
-       switch(dmix->state) {
-       case SNDRV_PCM_STATE_DRAINING:
-       case SNDRV_PCM_STATE_RUNNING:
-       case SNDRV_PCM_STATE_PREPARED:
-       case SNDRV_PCM_STATE_PAUSED:
-       case SNDRV_PCM_STATE_SUSPENDED:
-               *hwptr = *pcm->hw.ptr;
-               return 0;
-       case SNDRV_PCM_STATE_XRUN:
-               return -EPIPE;
-       default:
-               return -EBADFD;
-       }
-}
-
 static int snd_pcm_dmix_prepare(snd_pcm_t *pcm)
 {
        snd_pcm_dmix_t *dmix = pcm->private_data;
@@ -1108,6 +1089,19 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
        return frames;
 }
 
+static snd_pcm_sframes_t snd_pcm_dmix_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_sframes_t avail;
+
+       avail = snd_pcm_mmap_avail(pcm);
+       if (avail < 0)
+               return 0;
+       if (frames > avail)
+               frames = avail;
+       snd_pcm_mmap_appl_forward(pcm, frames);
+       return frames;
+}
+
 static int snd_pcm_dmix_resume(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
        // snd_pcm_dmix_t *dmix = pcm->private_data;
@@ -1224,7 +1218,6 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
        status: snd_pcm_dmix_status,
        state: snd_pcm_dmix_state,
        hwsync: snd_pcm_dmix_hwsync,
-       hwptr: snd_pcm_dmix_hwptr,
        delay: snd_pcm_dmix_delay,
        prepare: snd_pcm_dmix_prepare,
        reset: snd_pcm_dmix_reset,
@@ -1233,6 +1226,7 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
        drain: snd_pcm_dmix_drain,
        pause: snd_pcm_dmix_pause,
        rewind: snd_pcm_dmix_rewind,
+       forward: snd_pcm_dmix_forward,
        resume: snd_pcm_dmix_resume,
        writei: snd_pcm_mmap_writei,
        writen: snd_pcm_mmap_writen,
index 4ecb44aaefea6e964a4f40ffe64e440430905ecf..bcedc0e2c4605cef7c52caebf57e3369b33ad594 100644 (file)
@@ -168,12 +168,6 @@ static int snd_pcm_file_hwsync(snd_pcm_t *pcm)
        return snd_pcm_hwsync(file->slave);
 }
 
-static int snd_pcm_file_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return INTERNAL(snd_pcm_hwptr)(file->slave, hwptr);
-}
-
 static int snd_pcm_file_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_file_t *file = pcm->private_data;
@@ -236,19 +230,37 @@ static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
 static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       snd_pcm_sframes_t err = snd_pcm_rewind(file->slave, frames);
+       snd_pcm_sframes_t err;
+       snd_pcm_uframes_t n;
+       
+       n = snd_pcm_frames_to_bytes(pcm, frames);
+       if (n > file->wbuf_used_bytes)
+               frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+       err = snd_pcm_rewind(file->slave, frames);
        if (err > 0) {
-               snd_pcm_uframes_t n = snd_pcm_frames_to_bytes(pcm, frames);
-               snd_pcm_sframes_t ptr;
-               assert(n >= file->wbuf_used_bytes);
-               ptr = file->appl_ptr - err;
-               if (ptr < 0)
-                       ptr += file->wbuf_size;
+               n = snd_pcm_frames_to_bytes(pcm, err);
                file->wbuf_used_bytes -= n;
        }
        return err;
 }
 
+static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_file_t *file = pcm->private_data;
+       snd_pcm_sframes_t err;
+       snd_pcm_uframes_t n;
+       
+       n = snd_pcm_frames_to_bytes(pcm, frames);
+       if (file->wbuf_used_bytes + n > file->wbuf_size_bytes)
+               frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
+       err = snd_pcm_forward(file->slave, frames);
+       if (err > 0) {
+               snd_pcm_uframes_t n = snd_pcm_frames_to_bytes(pcm, err);
+               file->wbuf_used_bytes += n;
+       }
+       return err;
+}
+
 static int snd_pcm_file_resume(snd_pcm_t *pcm)
 {
        snd_pcm_file_t *file = pcm->private_data;
@@ -372,9 +384,6 @@ static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
 static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       /* we don't support mode without xrun detection */
-       if (params->stop_threshold >= params->boundary)
-               return -EINVAL;
        return snd_pcm_sw_params(file->slave, params);
 }
 
@@ -422,7 +431,6 @@ static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
        status: snd_pcm_file_status,
        state: snd_pcm_file_state,
        hwsync: snd_pcm_file_hwsync,
-       hwptr: snd_pcm_file_hwptr,
        delay: snd_pcm_file_delay,
        prepare: snd_pcm_file_prepare,
        reset: snd_pcm_file_reset,
@@ -431,6 +439,7 @@ static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
        drain: snd_pcm_file_drain,
        pause: snd_pcm_file_pause,
        rewind: snd_pcm_file_rewind,
+       forward: snd_pcm_file_forward,
        resume: snd_pcm_file_resume,
        writei: snd_pcm_file_writei,
        writen: snd_pcm_file_writen,
index c4cbd0a903ebe4e0a02498dab829365bf6de2642..dd88a564d76630ca9d5ce1f56a00fafba637254a 100644 (file)
@@ -122,12 +122,6 @@ static int snd_pcm_hooks_hwsync(snd_pcm_t *pcm)
        return snd_pcm_hwsync(h->slave);
 }
 
-static int snd_pcm_hooks_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return INTERNAL(snd_pcm_hwptr)(h->slave, hwptr);
-}
-
 static int snd_pcm_hooks_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_hooks_t *h = pcm->private_data;
@@ -176,6 +170,12 @@ static snd_pcm_sframes_t snd_pcm_hooks_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
        return snd_pcm_rewind(h->slave, frames);
 }
 
+static snd_pcm_sframes_t snd_pcm_hooks_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_hooks_t *h = pcm->private_data;
+       return snd_pcm_forward(h->slave, frames);
+}
+
 static int snd_pcm_hooks_resume(snd_pcm_t *pcm)
 {
        snd_pcm_hooks_t *h = pcm->private_data;
@@ -305,7 +305,6 @@ static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
        status: snd_pcm_hooks_status,
        state: snd_pcm_hooks_state,
        hwsync: snd_pcm_hooks_hwsync,
-       hwptr: snd_pcm_hooks_hwptr,
        delay: snd_pcm_hooks_delay,
        prepare: snd_pcm_hooks_prepare,
        reset: snd_pcm_hooks_reset,
@@ -314,6 +313,7 @@ static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
        drain: snd_pcm_hooks_drain,
        pause: snd_pcm_hooks_pause,
        rewind: snd_pcm_hooks_rewind,
+       forward: snd_pcm_hooks_forward,
        resume: snd_pcm_hooks_resume,
        writei: snd_pcm_hooks_writei,
        writen: snd_pcm_hooks_writen,
index b04bc55a16857a3d79ca826a58d8a23828631b34..ef27ea843e13474e87ad44508a841af92d9ee55c 100644 (file)
@@ -345,9 +345,6 @@ static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
                hw->mmap_control->avail_min = params->avail_min;
                return 0;
        }
-       /* FIXME */
-       if (hw->mmap_shm && params->stop_threshold >= params->boundary)
-               return -EINVAL;
        if (ioctl(fd, SNDRV_PCM_IOCTL_SW_PARAMS, params) < 0) {
                SYSERR("SNDRV_PCM_IOCTL_SW_PARAMS failed");
                return -errno;
@@ -431,23 +428,6 @@ static int snd_pcm_hw_hwsync(snd_pcm_t *pcm)
        return 0;
 }
 
-static int snd_pcm_hw_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       switch (snd_pcm_state(pcm)) {
-       case SND_PCM_STATE_RUNNING:
-       case SND_PCM_STATE_DRAINING:
-       case SND_PCM_STATE_PREPARED:
-       case SND_PCM_STATE_PAUSED:
-       case SND_PCM_STATE_SUSPENDED:
-               *hwptr = *pcm->hw.ptr;
-               return 0;
-       case SND_PCM_STATE_XRUN:
-               return -EPIPE;
-       default:
-               return -EBADFD;
-       }
-}
-
 static int snd_pcm_hw_prepare(snd_pcm_t *pcm)
 {
        snd_pcm_hw_t *hw = pcm->private_data;
@@ -534,6 +514,31 @@ static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fra
        return frames;
 }
 
+static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_hw_t *hw = pcm->private_data;
+       snd_pcm_sframes_t avail;
+
+       switch (FAST_PCM_STATE(hw)) {
+       case SNDRV_PCM_STATE_RUNNING:
+       case SNDRV_PCM_STATE_DRAINING:
+       case SNDRV_PCM_STATE_PAUSED:
+       case SNDRV_PCM_STATE_PREPARED:
+               break;
+       case SNDRV_PCM_STATE_XRUN:
+               return -EPIPE;
+       default:
+               return -EBADFD;
+       }
+       avail = snd_pcm_mmap_avail(pcm);
+       if (avail < 0)
+               return 0;
+       if (frames > avail)
+               frames = avail;
+       snd_pcm_mmap_appl_forward(pcm, frames);
+       return frames;
+}
+
 static int snd_pcm_hw_resume(snd_pcm_t *pcm)
 {
        snd_pcm_hw_t *hw = pcm->private_data;
@@ -718,12 +723,6 @@ static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
        if (hw->mmap_shm) {
                if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                        snd_pcm_sframes_t result = 0, res;
-                       snd_pcm_uframes_t last_offset;
-
-                       /* FIXME */
-                       last_offset = *pcm->appl.ptr - offset;
-                       if (last_offset != offset)
-                               return -EINVAL;
 
                        do {
                                res = snd_pcm_write_mmap(pcm, size);
@@ -819,7 +818,6 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
        status: snd_pcm_hw_status,
        state: snd_pcm_hw_state,
        hwsync: snd_pcm_hw_hwsync,
-       hwptr: snd_pcm_hw_hwptr,
        delay: snd_pcm_hw_delay,
        prepare: snd_pcm_hw_prepare,
        reset: snd_pcm_hw_reset,
@@ -828,6 +826,7 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
        drain: snd_pcm_hw_drain,
        pause: snd_pcm_hw_pause,
        rewind: snd_pcm_hw_rewind,
+       forward: snd_pcm_hw_forward,
        resume: snd_pcm_hw_resume,
        writei: snd_pcm_hw_writei,
        writen: snd_pcm_hw_writen,
index 69625901d45122b50d20e536809e5bb67c4cf81c..eebb496c16c962748f64015206be73e82d2e9a2f 100644 (file)
@@ -185,24 +185,6 @@ static int snd_pcm_jack_hwsync(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
        return 0;
 }
 
-static int snd_pcm_jack_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-#ifdef PCM_JACK_DEBUG
-       printf("snd_pcm_jack_hwptr\n"); fflush(stdout);
-#endif
-       switch (snd_pcm_state(pcm)) {
-       case SND_PCM_STATE_RUNNING:
-       case SND_PCM_STATE_DRAINING:
-       case SND_PCM_STATE_PREPARED:
-       case SND_PCM_STATE_PAUSED:
-       case SND_PCM_STATE_SUSPENDED:
-               *hwptr = *pcm->hw.ptr;
-               return 0;
-       default:
-               return -EBADFD;
-       }
-}
-
 static int snd_pcm_jack_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sframes_t *delayp)
 {
 #ifdef PCM_JACK_DEBUG
@@ -460,6 +442,22 @@ static snd_pcm_sframes_t snd_pcm_jack_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
        return frames;
 }
 
+static snd_pcm_sframes_t snd_pcm_jack_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_sframes_t avail;
+
+#ifdef PCM_JACK_DEBUG
+       printf("snd_pcm_jack_forward\n"); fflush(stdout);
+#endif
+       avail = snd_pcm_mmap_avail(pcm);
+       if (avail < 0)
+               return 0;
+       if (frames > (snd_pcm_uframes_t) avail)
+               frames = (snd_pcm_uframes_t) avail;
+       snd_pcm_mmap_appl_forward(pcm, frames);
+       return frames;
+}
+
 static int snd_pcm_jack_resume(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
        return 0;
@@ -611,7 +609,6 @@ static snd_pcm_fast_ops_t snd_pcm_jack_fast_ops = {
        status: snd_pcm_jack_status,
        state: snd_pcm_jack_state,
        hwsync: snd_pcm_jack_hwsync,
-       hwptr: snd_pcm_jack_hwptr,
        delay: snd_pcm_jack_delay,
        prepare: snd_pcm_jack_prepare,
        reset: snd_pcm_jack_reset,
@@ -620,6 +617,7 @@ static snd_pcm_fast_ops_t snd_pcm_jack_fast_ops = {
        drain: snd_pcm_jack_drain,
        pause: snd_pcm_jack_pause,
        rewind: snd_pcm_jack_rewind,
+       forward: snd_pcm_jack_forward,
        resume: snd_pcm_jack_resume,
        writei: snd_pcm_mmap_writei,
        writen: snd_pcm_mmap_writen,
index 0866ca7b7d3b734ef2b3ede5499276e78d60640c..bc85ebc45fe5025f52e7513d0bf78f93fdc11c27 100644 (file)
@@ -147,10 +147,10 @@ typedef struct {
        int (*pause)(snd_pcm_t *pcm, int enable);
        snd_pcm_state_t (*state)(snd_pcm_t *pcm);
        int (*hwsync)(snd_pcm_t *pcm);
-       int (*hwptr)(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr);
        int (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
        int (*resume)(snd_pcm_t *pcm);
        snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+       snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
        snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
        snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
        snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
@@ -550,7 +550,8 @@ int snd_pcm_hw_param_get_max(const snd_pcm_hw_params_t *params,
                             unsigned int *val, int *dir);
 
 #ifdef INTERNAL
-int INTERNAL(snd_pcm_hwptr)(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr);
+int INTERNAL(snd_pcm_hwdiff)(snd_pcm_t *pcm, snd_pcm_uframes_t *diff, snd_pcm_uframes_t *old_pos);
+snd_pcm_sframes_t INTERNAL(snd_pcm_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 
 int INTERNAL(snd_pcm_hw_params_get_access)(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access);
 int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access);
index 8d163b192202e5be649a34f51943cdf3441c9a29..0858382ca4cf7c56028154d378a61c8b131987f4 100644 (file)
@@ -325,12 +325,6 @@ static int snd_pcm_meter_hwsync(snd_pcm_t *pcm)
        return snd_pcm_hwsync(meter->slave);
 }
 
-static int snd_pcm_meter_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_meter_t *meter = pcm->private_data;
-       return INTERNAL(snd_pcm_hwptr)(meter->slave, hwptr);
-}
-
 static int snd_pcm_meter_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_meter_t *meter = pcm->private_data;
@@ -402,6 +396,15 @@ static snd_pcm_sframes_t snd_pcm_meter_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
        return err;
 }
 
+static snd_pcm_sframes_t snd_pcm_meter_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_meter_t *meter = pcm->private_data;
+       snd_pcm_sframes_t err = snd_pcm_forward(meter->slave, frames);
+       if (err > 0 && pcm->stream == SND_PCM_STREAM_PLAYBACK)
+               meter->rptr = *pcm->appl.ptr;
+       return err;
+}
+
 static int snd_pcm_meter_resume(snd_pcm_t *pcm)
 {
        snd_pcm_meter_t *meter = pcm->private_data;
@@ -614,6 +617,7 @@ static snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
        drain: snd_pcm_meter_drain,
        pause: snd_pcm_meter_pause,
        rewind: snd_pcm_meter_rewind,
+       forward: snd_pcm_meter_forward,
        resume: snd_pcm_meter_resume,
        writei: snd_pcm_mmap_writei,
        writen: snd_pcm_mmap_writen,
index 9373cdf1b9c7d8fc0bcb59fdc3bcff68732ddea0..8416331341a8e40e40a0c367347313dff5801421 100644 (file)
@@ -358,13 +358,6 @@ static int snd_pcm_multi_hwsync(snd_pcm_t *pcm)
        return snd_pcm_hwsync(slave);
 }
 
-static int snd_pcm_multi_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_multi_t *multi = pcm->private_data;
-       snd_pcm_t *slave = multi->slaves[multi->master_slave].pcm;
-       return INTERNAL(snd_pcm_hwptr)(slave, hwptr);
-}
-
 static int snd_pcm_multi_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
@@ -512,7 +505,37 @@ static snd_pcm_sframes_t snd_pcm_multi_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
                snd_pcm_uframes_t f = pos[i] - frames;
                snd_pcm_sframes_t result;
                if (f > 0) {
-                       result = snd_pcm_mmap_commit(slave_i, snd_pcm_mmap_offset(slave_i), f);
+                       result = snd_pcm_forward(slave_i, f);
+                       if (result < 0)
+                               return result;
+                       if ((snd_pcm_uframes_t)result != f)
+                               return -EIO;
+               }
+       }
+       return frames;
+}
+
+static snd_pcm_sframes_t snd_pcm_multi_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_multi_t *multi = pcm->private_data;
+       unsigned int i;
+       snd_pcm_uframes_t pos[multi->slaves_count];
+       memset(pos, 0, sizeof(pos));
+       for (i = 0; i < multi->slaves_count; ++i) {
+               snd_pcm_t *slave_i = multi->slaves[i].pcm;
+               snd_pcm_sframes_t f = snd_pcm_forward(slave_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 *slave_i = multi->slaves[i].pcm;
+               snd_pcm_uframes_t f = pos[i] - frames;
+               snd_pcm_sframes_t result;
+               if (f > 0) {
+                       result = snd_pcm_rewind(slave_i, f);
                        if (result < 0)
                                return result;
                        if ((snd_pcm_uframes_t)result != f)
@@ -609,7 +632,6 @@ static snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
        status: snd_pcm_multi_status,
        state: snd_pcm_multi_state,
        hwsync: snd_pcm_multi_hwsync,
-       hwptr: snd_pcm_multi_hwptr,
        delay: snd_pcm_multi_delay,
        prepare: snd_pcm_multi_prepare,
        reset: snd_pcm_multi_reset,
@@ -622,6 +644,7 @@ static snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
        readi: snd_pcm_mmap_readi,
        readn: snd_pcm_mmap_readn,
        rewind: snd_pcm_multi_rewind,
+       forward: snd_pcm_multi_forward,
        resume: snd_pcm_multi_resume,
        avail_update: snd_pcm_multi_avail_update,
        mmap_commit: snd_pcm_multi_mmap_commit,
index 239e91660fa62523155104750099fc433f713c8b..79e21b0856405a411c6545ec9ac0429a899107cc 100644 (file)
@@ -105,23 +105,6 @@ static int snd_pcm_null_hwsync(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
        return 0;
 }
 
-static int snd_pcm_null_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       switch (snd_pcm_state(pcm)) {
-       case SND_PCM_STATE_RUNNING:
-       case SND_PCM_STATE_DRAINING:
-       case SND_PCM_STATE_PREPARED:
-       case SND_PCM_STATE_PAUSED:
-       case SND_PCM_STATE_SUSPENDED:
-               *hwptr = *pcm->hw.ptr;
-               return 0;
-       case SND_PCM_STATE_XRUN:
-               return -EPIPE;
-       default:
-               return -EBADFD;
-       }
-}
-
 static int snd_pcm_null_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sframes_t *delayp)
 {
        *delayp = 0;
@@ -202,6 +185,21 @@ static snd_pcm_sframes_t snd_pcm_null_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
        }
 }
 
+static snd_pcm_sframes_t snd_pcm_null_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_null_t *null = pcm->private_data;
+       switch (null->state) {
+       case SND_PCM_STATE_RUNNING:
+               snd_pcm_mmap_hw_forward(pcm, frames);
+               /* Fall through */
+       case SND_PCM_STATE_PREPARED:
+               snd_pcm_mmap_appl_forward(pcm, frames);
+               return frames;
+       default:
+               return -EBADFD;
+       }
+}
+
 static int snd_pcm_null_resume(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
        return 0;
@@ -329,7 +327,6 @@ static snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
        status: snd_pcm_null_status,
        state: snd_pcm_null_state,
        hwsync: snd_pcm_null_hwsync,
-       hwptr: snd_pcm_null_hwptr,
        delay: snd_pcm_null_delay,
        prepare: snd_pcm_null_prepare,
        reset: snd_pcm_null_reset,
@@ -338,6 +335,7 @@ static snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
        drain: snd_pcm_null_drain,
        pause: snd_pcm_null_pause,
        rewind: snd_pcm_null_rewind,
+       forward: snd_pcm_null_forward,
        resume: snd_pcm_null_resume,
        writei: snd_pcm_null_writei,
        writen: snd_pcm_null_writen,
index 9be8ffbb7a8e99daa2ba3597c15f469841c14c15..51e56475f1defb42247a9ba589f9c56fa19d4eb0 100644 (file)
@@ -199,12 +199,6 @@ int snd_pcm_plugin_hwsync(snd_pcm_t *pcm)
        return snd_pcm_hwsync(plugin->slave);
 }
 
-int snd_pcm_plugin_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return INTERNAL(snd_pcm_hwptr)(plugin->slave, hwptr);
-}
-
 int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
@@ -288,34 +282,56 @@ snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_sframes_t n = snd_pcm_mmap_hw_avail(pcm);
-       assert(n >= 0);
-       if (n > 0) {
-               if ((snd_pcm_uframes_t)n > frames)
-                       n = frames;
-               frames -= n;
+       snd_pcm_sframes_t sframes;
+
+       if ((snd_pcm_uframes_t)n > frames)
+               frames = n;
+       if (frames == 0)
+               return 0;
+       
+       /* FIXME: rate plugin */
+       if (plugin->slave_frames)
+               sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
+       else
+               sframes = frames;
+       snd_atomic_write_begin(&plugin->watom);
+       sframes = snd_pcm_rewind(plugin->slave, sframes);
+       if (sframes < 0) {
+               snd_atomic_write_end(&plugin->watom);
+               return sframes;
        }
-       if (frames > 0) {
-               snd_pcm_sframes_t err;
-               /* FIXME: rate plugin */
-               if (plugin->slave_frames)
-                       frames = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
-               snd_atomic_write_begin(&plugin->watom);
-               err = snd_pcm_rewind(plugin->slave, frames);
-               if (err < 0) {
-                       if (n <= 0) {
-                               snd_atomic_write_end(&plugin->watom);
-                               return err;
-                       }
-                       goto _end;
-               }
-               if (plugin->client_frames)
-                       err = plugin->client_frames(pcm, err);
-               snd_pcm_mmap_hw_backward(pcm, (snd_pcm_uframes_t) err);
-               n += err;
-       } else
-               snd_atomic_write_begin(&plugin->watom);
- _end:
-       snd_pcm_mmap_appl_backward(pcm, (snd_pcm_uframes_t) n);
+       if (plugin->client_frames)
+               frames = plugin->client_frames(pcm, sframes);
+       snd_pcm_mmap_appl_backward(pcm, (snd_pcm_uframes_t) frames);
+       snd_atomic_write_end(&plugin->watom);
+       return n;
+}
+
+snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_plugin_t *plugin = pcm->private_data;
+       snd_pcm_sframes_t n = snd_pcm_mmap_avail(pcm);
+       snd_pcm_uframes_t sframes;
+
+       if ((snd_pcm_uframes_t)n > frames)
+               frames = n;
+       if (frames == 0)
+               return 0;
+       
+       /* FIXME: rate plugin */
+       if (plugin->slave_frames)
+               sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
+       else
+               sframes = frames;
+       snd_atomic_write_begin(&plugin->watom);
+       sframes = snd_pcm_forward(plugin->slave, (snd_pcm_uframes_t) sframes);
+       if (sframes < 0) {
+               snd_atomic_write_end(&plugin->watom);
+               return sframes;
+       }
+       if (plugin->client_frames)
+               frames = plugin->client_frames(pcm, sframes);
+       snd_pcm_mmap_appl_forward(pcm, (snd_pcm_uframes_t) frames);
        snd_atomic_write_end(&plugin->watom);
        return n;
 }
@@ -632,7 +648,6 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
        status: snd_pcm_plugin_status,
        state: snd_pcm_plugin_state,
        hwsync: snd_pcm_plugin_hwsync,
-       hwptr: snd_pcm_plugin_hwptr,
        delay: snd_pcm_plugin_delay,
        prepare: snd_pcm_plugin_prepare,
        reset: snd_pcm_plugin_reset,
@@ -641,6 +656,7 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
        drain: snd_pcm_plugin_drain,
        pause: snd_pcm_plugin_pause,
        rewind: snd_pcm_plugin_rewind,
+       forward: snd_pcm_plugin_forward,
        resume: snd_pcm_plugin_resume,
        writei: snd_pcm_plugin_writei,
        writen: snd_pcm_plugin_writen,
index 02290df760c30b335c93787bb3e65b4374a42e8a..eaa6402bb33df1154a635d2cf8a3d13eabe4aa94 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * \file pcm/pcm_share.c
  * \ingroup PCM_Plugins
  * \brief PCM Share Plugin Interface
@@ -737,36 +737,6 @@ static int snd_pcm_share_hwsync(snd_pcm_t *pcm)
        return err;
 }
 
-static int _snd_pcm_share_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_share_t *share = pcm->private_data;
-       snd_pcm_share_slave_t *slave = share->slave;
-       switch (share->state) {
-       case SND_PCM_STATE_RUNNING:
-       case SND_PCM_STATE_DRAINING:
-       case SND_PCM_STATE_PREPARED:
-       case SND_PCM_STATE_PAUSED:
-       case SND_PCM_STATE_SUSPENDED:
-               *hwptr = *pcm->hw.ptr;
-               return 0;
-       case SND_PCM_STATE_XRUN:
-               return -EPIPE;
-       default:
-               return -EBADFD;
-       }
-}
-
-static int snd_pcm_share_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *hwptr)
-{
-       snd_pcm_share_t *share = pcm->private_data;
-       snd_pcm_share_slave_t *slave = share->slave;
-       int err;
-       Pthread_mutex_lock(&slave->mutex);
-       err = _snd_pcm_share_hwptr(pcm, hwptr);
-       Pthread_mutex_unlock(&slave->mutex);
-       return err;
-}
-
 static int _snd_pcm_share_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_share_t *share = pcm->private_data;
@@ -1027,19 +997,15 @@ static snd_pcm_sframes_t _snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
        }
        n = snd_pcm_mmap_hw_avail(pcm);
        assert(n >= 0);
-       if (n > 0) {
-               if ((snd_pcm_uframes_t)n > frames)
-                       n = frames;
-               frames -= n;
-       }
-       if (share->state == SND_PCM_STATE_RUNNING &&
-           frames > 0) {
-               int ret = snd_pcm_rewind(slave->pcm, frames);
+       if ((snd_pcm_uframes_t)n > frames)
+               frames = n;
+       if (share->state == SND_PCM_STATE_RUNNING && frames > 0) {
+               snd_pcm_sframes_t ret = snd_pcm_rewind(slave->pcm, frames);
                if (ret < 0)
                        return ret;
-               n += ret;
+               frames = ret;
        }
-       snd_pcm_mmap_appl_backward(pcm, n);
+       snd_pcm_mmap_appl_backward(pcm, frames);
        _snd_pcm_share_update(pcm);
        return n;
 }
@@ -1055,6 +1021,52 @@ static snd_pcm_sframes_t snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
        return ret;
 }
 
+static snd_pcm_sframes_t _snd_pcm_share_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_share_t *share = pcm->private_data;
+       snd_pcm_share_slave_t *slave = share->slave;
+       snd_pcm_sframes_t n;
+       switch (share->state) {
+       case SND_PCM_STATE_RUNNING:
+               break;
+       case SND_PCM_STATE_PREPARED:
+               if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
+                       return -EBADFD;
+               break;
+       case SND_PCM_STATE_DRAINING:
+               if (pcm->stream != SND_PCM_STREAM_CAPTURE)
+                       return -EBADFD;
+               break;
+       case SND_PCM_STATE_XRUN:
+               return -EPIPE;
+       default:
+               return -EBADFD;
+       }
+       n = snd_pcm_mmap_avail(pcm);
+       if ((snd_pcm_uframes_t)n > frames)
+               frames = n;
+       if (share->state == SND_PCM_STATE_RUNNING && frames > 0) {
+               snd_pcm_sframes_t ret = snd_pcm_forward(slave->pcm, frames);
+               if (ret < 0)
+                       return ret;
+               frames = ret;
+       }
+       snd_pcm_mmap_appl_forward(pcm, frames);
+       _snd_pcm_share_update(pcm);
+       return n;
+}
+
+static snd_pcm_sframes_t snd_pcm_share_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_share_t *share = pcm->private_data;
+       snd_pcm_share_slave_t *slave = share->slave;
+       snd_pcm_sframes_t ret;
+       Pthread_mutex_lock(&slave->mutex);
+       ret = _snd_pcm_share_forward(pcm, frames);
+       Pthread_mutex_unlock(&slave->mutex);
+       return ret;
+}
+
 /* Warning: take the mutex before to call this */
 static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state)
 {
@@ -1264,7 +1276,6 @@ static snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
        status: snd_pcm_share_status,
        state: snd_pcm_share_state,
        hwsync: snd_pcm_share_hwsync,
-       hwptr: snd_pcm_share_hwptr,
        delay: snd_pcm_share_delay,
        prepare: snd_pcm_share_prepare,
        reset: snd_pcm_share_reset,
@@ -1277,6 +1288,7 @@ static snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
        readi: snd_pcm_mmap_readi,
        readn: snd_pcm_mmap_readn,
        rewind: snd_pcm_share_rewind,
+       forward: snd_pcm_share_forward,
        resume: snd_pcm_share_resume,
        avail_update: snd_pcm_share_avail_update,
        mmap_commit: snd_pcm_share_mmap_commit,
index 65194d14230488d341be64f9c6f3097a131c041b..619cdc5272221b2716be3e1df88b3e206891808a 100644 (file)
@@ -451,19 +451,6 @@ static int snd_pcm_shm_hwsync(snd_pcm_t *pcm)
        return snd_pcm_shm_action(pcm);
 }
 
-static int snd_pcm_shm_hwptr(snd_pcm_t *pcm, snd_pcm_uframes_t *uframes)
-{
-       snd_pcm_shm_t *shm = pcm->private_data;
-       volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
-       int err;
-       ctrl->cmd = SND_PCM_IOCTL_HWPTR;
-       return snd_pcm_shm_action(pcm);
-       if (err < 0)
-               return err;
-       *uframes = ctrl->u.hwptr.frames;
-       return err;
-}
-
 static int snd_pcm_shm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_shm_t *shm = pcm->private_data;
@@ -558,6 +545,15 @@ static snd_pcm_sframes_t snd_pcm_shm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fr
        return snd_pcm_shm_action(pcm);
 }
 
+static snd_pcm_sframes_t snd_pcm_shm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_shm_t *shm = pcm->private_data;
+       volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
+       ctrl->cmd = SND_PCM_IOCTL_FORWARD;
+       ctrl->u.forward.frames = frames;
+       return snd_pcm_shm_action(pcm);
+}
+
 static int snd_pcm_shm_resume(snd_pcm_t *pcm)
 {
        snd_pcm_shm_t *shm = pcm->private_data;
@@ -632,7 +628,6 @@ static snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
        status: snd_pcm_shm_status,
        state: snd_pcm_shm_state,
        hwsync: snd_pcm_shm_hwsync,
-       hwptr: snd_pcm_shm_hwptr,
        delay: snd_pcm_shm_delay,
        prepare: snd_pcm_shm_prepare,
        reset: snd_pcm_shm_reset,
@@ -641,6 +636,7 @@ static snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
        drain: snd_pcm_shm_drain,
        pause: snd_pcm_shm_pause,
        rewind: snd_pcm_shm_rewind,
+       forward: snd_pcm_shm_forward,
        resume: snd_pcm_shm_resume,
        writei: snd_pcm_mmap_writei,
        writen: snd_pcm_mmap_writen,