]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Better PCM mmap API. Fixed pcm_multi
authorAbramo Bagnara <abramo@alsa-project.org>
Fri, 13 Apr 2001 15:40:53 +0000 (15:40 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Fri, 13 Apr 2001 15:40:53 +0000 (15:40 +0000)
16 files changed:
aserver/aserver.c
include/aserver.h
include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_file.c
src/pcm/pcm_hw.c
src/pcm/pcm_local.h
src/pcm/pcm_meter.c
src/pcm/pcm_mmap.c
src/pcm/pcm_multi.c
src/pcm/pcm_null.c
src/pcm/pcm_plugin.c
src/pcm/pcm_plugin.h
src/pcm/pcm_share.c
src/pcm/pcm_shm.c
src/pcm/pcm_surr.c

index 8f05587b8972d9df5e8d76a3dacfb615d245f636..59050c3df547e18d9bf1693459d6a56068db889d 100644 (file)
@@ -455,8 +455,10 @@ static int pcm_shm_cmd(client_t *client)
                ctrl->result = snd_pcm_munmap(pcm);
                break;
        }
-       case SND_PCM_IOCTL_MMAP_FORWARD:
-               ctrl->result = snd_pcm_mmap_forward(pcm, ctrl->u.mmap_forward.frames);
+       case SND_PCM_IOCTL_MMAP_COMMIT:
+               ctrl->result = snd_pcm_mmap_commit(pcm,
+                                                  ctrl->u.mmap_commit.offset,
+                                                  ctrl->u.mmap_commit.frames);
                ctrl->appl_ptr = *pcm->appl_ptr;
                break;
        case SND_PCM_IOCTL_POLL_DESCRIPTOR:
@@ -610,7 +612,7 @@ static int ctl_shm_cmd(client_t *client)
                ctrl->result = snd_ctl_pcm_next_device(ctl, &ctrl->u.device);
                break;
        case SND_CTL_IOCTL_PCM_SURROUND_NEXT_DEVICE:
-               ctrl->result = snd_ctl_pcm_surround_next_device(ctl, &ctrl->u.surround.type, &ctrl->u.surround.device);
+               ctrl->result = snd_ctl_pcm_surround_next_device(ctl, ctrl->u.surround.type, &ctrl->u.surround.device);
                break;
        case SNDRV_CTL_IOCTL_PCM_INFO:
                ctrl->result = snd_ctl_pcm_info(ctl, &ctrl->u.pcm_info);
index 9b97d15085829384c01e0ed987929edf0f90e54e..4d52d337ed196cd9701576fc8f848fa7d7de7a2b 100644 (file)
@@ -42,7 +42,7 @@ typedef enum _snd_transport_type {
 #define SND_PCM_IOCTL_STATE            _IO ('A', 0xf1)
 #define SND_PCM_IOCTL_MMAP             _IO ('A', 0xf2)
 #define SND_PCM_IOCTL_MUNMAP           _IO ('A', 0xf3)
-#define SND_PCM_IOCTL_MMAP_FORWARD     _IO ('A', 0xf4)
+#define SND_PCM_IOCTL_MMAP_COMMIT      _IO ('A', 0xf4)
 #define SND_PCM_IOCTL_AVAIL_UPDATE     _IO ('A', 0xf5)
 #define SND_PCM_IOCTL_ASYNC            _IO ('A', 0xf6)
 #define SND_PCM_IOCTL_CLOSE            _IO ('A', 0xf7)
@@ -77,8 +77,9 @@ typedef struct {
                        int fd;
                } link;
                struct {
+                       snd_pcm_uframes_t offset;
                        snd_pcm_uframes_t frames;
-               } mmap_forward;
+               } mmap_commit;
        } u;
        char data[0];
 } snd_pcm_shm_ctrl_t;
@@ -101,7 +102,7 @@ typedef struct {
                } async;
                int device;
                struct {
-                       int type;
+                       snd_pcm_surround_type_t type;
                        int device;
                } surround;
                int subscribe_events;
index 241d2093c214aff7bab54146d3f969660b9f602d..a8e0dcb511777a15d2745fcbe7b71b99a46d9d37 100644 (file)
@@ -381,16 +381,12 @@ int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out);
 int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out);
 
 /* mmap */
-const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm);
-const snd_pcm_channel_area_t *snd_pcm_mmap_running_areas(snd_pcm_t *pcm);
-const snd_pcm_channel_area_t *snd_pcm_mmap_stopped_areas(snd_pcm_t *pcm);
-snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
-snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
-snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t size);
-snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
-snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
-snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
-snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+int snd_pcm_mmap_begin(snd_pcm_t *pcm,
+                      const snd_pcm_channel_area_t **areas,
+                      snd_pcm_uframes_t *offset,
+                      snd_pcm_uframes_t *frames);
+int snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset,
+                       snd_pcm_uframes_t frames);
 
 const char *snd_pcm_stream_name(snd_pcm_stream_t stream);
 const char *snd_pcm_access_name(snd_pcm_access_t _access);
index 38c4ed5b9dcc415d9f7a47107a655bb8985a96ba..d032603bfa3e5a49babc41dce03e84bcd06c645e 100644 (file)
@@ -1098,23 +1098,6 @@ snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
        return pcm->fast_ops->avail_update(pcm->fast_op_arg);
 }
 
-/**
- * \brief Advance PCM frame position in mmap buffer
- * \param pcm PCM handle
- * \param size movement size
- * \return a positive number of actual movement size otherwise a negative
- * error code
- *
- * On playback does all the actions needed to transport the frames across
- * underlying layers. 
- */
-snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
-{
-       assert(size > 0);
-       assert(size <= snd_pcm_mmap_avail(pcm));
-       return pcm->fast_ops->mmap_forward(pcm->fast_op_arg, size);
-}
-
 /**
  * \brief Silence an area
  * \param dst_area area specification
@@ -3932,64 +3915,57 @@ void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
        obj->stream = snd_enum_to_int(val);
 }
 
-
-/**
- * \brief Get channel areas for a given PCM when running
- * \param pcm PCM handle
- * \return pointer to channel areas (one for each channel)
- */
-const snd_pcm_channel_area_t *snd_pcm_mmap_running_areas(snd_pcm_t *pcm)
-{
-       return pcm->running_areas;
-}
-
-/**
- * \brief Get channel areas for a given PCM when stopped
- * \param pcm PCM handle
- * \return pointer to channel areas (one for each channel)
- */
-const snd_pcm_channel_area_t *snd_pcm_mmap_stopped_areas(snd_pcm_t *pcm)
-{
-       return pcm->stopped_areas;
-}
-
 /**
- * \brief Get appropriate channel areas for a given PCM according to its state (running or stopped)
+ * \brief Application request to access a portion of mmap area
  * \param pcm PCM handle
- * \return pointer to channel areas (one for each channel)
+ * \param areas Returned mmap channel areas
+ * \param offset Returned mmap area offset
+ * \param size mmap area portion size (wanted on entry, contiguous
+available on exit)
+ * \return 0 on success otherwise a negative error code
  */
-const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
+int snd_pcm_mmap_begin(snd_pcm_t *pcm,
+                      const snd_pcm_channel_area_t **areas,
+                      snd_pcm_uframes_t *offset,
+                      snd_pcm_uframes_t *frames)
 {
+       snd_pcm_uframes_t cont;
+       snd_pcm_uframes_t avail;
+       snd_pcm_uframes_t f;
+       assert(pcm && areas && offset && frames);
        if (pcm->stopped_areas &&
            snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING) 
-               return pcm->stopped_areas;
-       return pcm->running_areas;
-}
-
-/**
- * \brief Correct frames count according to contiguity consideration inside PCM ring buffer
- * \param pcm PCM handle
- * \param frames Frames to transfer
- * \return Number of contiguous frames transferrable
- */
-snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
-{
-        assert(pcm);
-       if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
-               return snd_pcm_mmap_playback_xfer(pcm, frames);
+               *areas = pcm->stopped_areas;
        else
-               return snd_pcm_mmap_capture_xfer(pcm, frames);
+               *areas = pcm->running_areas;
+       *offset = *pcm->appl_ptr % pcm->buffer_size;
+       avail = snd_pcm_mmap_avail(pcm);
+       f = *frames;
+       if (f > avail)
+               f = avail;
+       cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
+       if (f > cont)
+               f = cont;
+       *frames = f;
+       return 0;
 }
 
 /**
- * \brief Return application offset inside ring buffer
+ * \brief Application has completed the access to area requested with
+#snd_pcm_mmap_begin
  * \param pcm PCM handle
- * \return Offset for frames transfer
+ * \return 0 on success otherwise a negative error code
+ *
+ * To call this with offset/frames values different from that returned
+ * by snd_pcm_mmap_begin has undefined effects and it has to be avoided.
  */
-snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
+int snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset,
+                       snd_pcm_uframes_t frames)
 {
-        assert(pcm);
-       return *pcm->appl_ptr % pcm->buffer_size;
+       assert(pcm);
+       assert(offset == *pcm->appl_ptr % pcm->buffer_size);
+       assert(frames <= snd_pcm_mmap_avail(pcm));
+       return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
 }
 
 #ifndef DOC_HIDDEN
index 48a34279230fb2c1b24c1116a05ca43c0841f31d..a979914c86991cb93bd9c6048a2b9a0b799d7103 100644 (file)
@@ -268,26 +268,19 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
        return n;
 }
 
-static snd_pcm_sframes_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm,
+                                                 snd_pcm_uframes_t offset,
+                                                 snd_pcm_uframes_t size)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       snd_pcm_uframes_t ofs = snd_pcm_mmap_offset(pcm);
-       snd_pcm_sframes_t n = snd_pcm_mmap_forward(file->slave, size);
-       snd_pcm_uframes_t xfer = 0;
-       if (n <= 0)
-               return n;
-       while (xfer < (snd_pcm_uframes_t)n) {
-               snd_pcm_uframes_t frames = n - xfer;
-               snd_pcm_uframes_t cont = pcm->buffer_size - ofs;
-               if (frames > cont)
-                       frames = cont;
-               snd_pcm_file_add_frames(pcm, snd_pcm_mmap_areas(file->slave), ofs, frames);
-               ofs += frames;
-               if (ofs == pcm->buffer_size)
-                       ofs = 0;
-               xfer += frames;
-       }
-       return n;
+       snd_pcm_uframes_t ofs;
+       snd_pcm_uframes_t siz = size;
+       const snd_pcm_channel_area_t *areas;
+       snd_pcm_mmap_begin(file->slave, &areas, &ofs, &siz);
+       assert(ofs == offset && siz == size);
+       snd_pcm_mmap_commit(file->slave, ofs, siz);
+       snd_pcm_file_add_frames(pcm, areas, ofs, siz);
+       return 0;
 }
 
 static snd_pcm_sframes_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
@@ -400,7 +393,7 @@ snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
        readi: snd_pcm_file_readi,
        readn: snd_pcm_file_readn,
        avail_update: snd_pcm_file_avail_update,
-       mmap_forward: snd_pcm_file_mmap_forward,
+       mmap_commit: snd_pcm_file_mmap_commit,
 };
 
 int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int fd, const char *fmt, snd_pcm_t *slave, int close_slave)
index f38470e0448070e70221339f4accc9282f973998..0adf5ca6414f1d0e4f5580d27b3dd78f60a2a11b 100644 (file)
@@ -449,7 +449,9 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm)
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
+                                               snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
+                                               snd_pcm_uframes_t size)
 {
        if (!(pcm->info & SND_PCM_INFO_MMAP) && 
            pcm->stream == SND_PCM_STREAM_PLAYBACK)
@@ -526,7 +528,7 @@ snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
        readi: snd_pcm_hw_readi,
        readn: snd_pcm_hw_readn,
        avail_update: snd_pcm_hw_avail_update,
-       mmap_forward: snd_pcm_hw_mmap_forward,
+       mmap_commit: snd_pcm_hw_mmap_commit,
 };
 
 static int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode)
index 49a3df3f8c19d270c7b6677e9eb2caf68bc9fb67..0d68bc2b3394bec671e5f8cfeb8bdbd0d7468e7e 100644 (file)
@@ -114,7 +114,7 @@ typedef struct {
        snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
        snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
        snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm);
-       snd_pcm_sframes_t (*mmap_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+       snd_pcm_sframes_t (*mmap_commit)(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
 } snd_pcm_fast_ops_t;
 
 struct _snd_pcm {
@@ -209,9 +209,11 @@ void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
-snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm);
-snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
-snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+
+snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
 
 typedef snd_pcm_uframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm, 
                                                       const snd_pcm_channel_area_t *areas,
@@ -279,6 +281,26 @@ static inline snd_pcm_sframes_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
        return pcm->buffer_size - avail;
 }
 
+static inline const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
+{
+       if (pcm->stopped_areas &&
+           snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING) 
+               return pcm->stopped_areas;
+       return pcm->running_areas;
+}
+
+static inline snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
+{
+        assert(pcm);
+       return *pcm->appl_ptr % pcm->buffer_size;
+}
+
+static inline snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
+{
+        assert(pcm);
+       return *pcm->hw_ptr % pcm->buffer_size;
+}
+
 #define snd_pcm_mmap_playback_delay snd_pcm_mmap_playback_hw_avail
 #define snd_pcm_mmap_capture_delay snd_pcm_mmap_capture_avail
 
index 3a7c737f97d859d9b7cc2d22bf4c7b5e385bd3df..01aefcf1a472ba9be2fcdbea5fd3d3e01c21ccb0 100644 (file)
@@ -385,11 +385,13 @@ 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_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_meter_mmap_commit(snd_pcm_t *pcm,
+                                                  snd_pcm_uframes_t offset,
+                                                  snd_pcm_uframes_t size)
 {
        snd_pcm_meter_t *meter = pcm->private_data;
        snd_pcm_uframes_t old_rptr = *pcm->appl_ptr;
-       snd_pcm_sframes_t result = snd_pcm_mmap_forward(meter->slave, size);
+       snd_pcm_sframes_t result = snd_pcm_mmap_commit(meter->slave, offset, size);
        if (result <= 0)
                return result;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
@@ -594,7 +596,7 @@ snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
        readi: snd_pcm_mmap_readi,
        readn: snd_pcm_mmap_readn,
        avail_update: snd_pcm_meter_avail_update,
-       mmap_forward: snd_pcm_meter_mmap_forward,
+       mmap_commit: snd_pcm_meter_mmap_commit,
 };
 
 int snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, unsigned int frequency,
index 376c9837519ee8eb363216ac07bec066531f1819..c8d588d93d445c596d5a136f517fb49de36bf8f2 100644 (file)
@@ -44,36 +44,6 @@ size_t page_align(size_t size)
        return size;
 }
 
-snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
-{
-       snd_pcm_uframes_t cont;
-       snd_pcm_uframes_t avail = snd_pcm_mmap_playback_avail(pcm);
-       if (avail < frames)
-               frames = avail;
-       cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
-       if (cont < frames)
-               frames = cont;
-       return frames;
-}
-
-snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
-{
-       snd_pcm_uframes_t cont;
-       snd_pcm_uframes_t avail = snd_pcm_mmap_capture_avail(pcm);
-       if (avail < frames)
-               frames = avail;
-       cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
-       if (cont < frames)
-               frames = cont;
-       return frames;
-}
-
-snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
-{
-        assert(pcm);
-       return *pcm->hw_ptr % pcm->buffer_size;
-}
-
 void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_sframes_t appl_ptr = *pcm->appl_ptr;
@@ -115,28 +85,18 @@ static snd_pcm_uframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
                                                  snd_pcm_uframes_t offset,
                                                  snd_pcm_uframes_t size)
 {
-       const snd_pcm_channel_area_t *pcm_areas;
-       snd_pcm_uframes_t pcm_offset;
        snd_pcm_uframes_t xfer = size;
        assert(snd_pcm_mmap_playback_avail(pcm) >= size);
-       pcm_areas = snd_pcm_mmap_areas(pcm);
-       pcm_offset = snd_pcm_mmap_offset(pcm);
        while (size > 0) {
+               const snd_pcm_channel_area_t *pcm_areas;
+               snd_pcm_uframes_t pcm_offset;
                snd_pcm_uframes_t frames = size;
-               snd_pcm_uframes_t cont = pcm->buffer_size - pcm_offset;
-               int err;
-               if (frames > cont)
-                       frames = cont;
+               snd_pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
                snd_pcm_areas_copy(pcm_areas, pcm_offset,
                                   areas, offset, 
                                   pcm->channels, 
                                   frames, pcm->format);
-               err = snd_pcm_mmap_forward(pcm, frames);
-               assert(err == (snd_pcm_sframes_t)frames);
-               if (frames == cont)
-                       pcm_offset = 0;
-               else
-                       pcm_offset += frames;
+               snd_pcm_mmap_commit(pcm, pcm_offset, frames);
                offset += frames;
                size -= frames;
        }
@@ -148,28 +108,18 @@ static snd_pcm_uframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
                                                 snd_pcm_uframes_t offset,
                                                 snd_pcm_uframes_t size)
 {
-       const snd_pcm_channel_area_t *pcm_areas;
-       snd_pcm_uframes_t pcm_offset;
        snd_pcm_uframes_t xfer = size;
        assert(snd_pcm_mmap_capture_avail(pcm) >= size);
-       pcm_areas = snd_pcm_mmap_areas(pcm);
-       pcm_offset = snd_pcm_mmap_offset(pcm);
        while (size > 0) {
+               const snd_pcm_channel_area_t *pcm_areas;
+               snd_pcm_uframes_t pcm_offset;
                snd_pcm_uframes_t frames = size;
-               snd_pcm_uframes_t cont = pcm->buffer_size - pcm_offset;
-               int err;
-               if (frames > cont)
-                       frames = cont;
+               snd_pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
                snd_pcm_areas_copy(areas, offset, 
                                   pcm_areas, pcm_offset,
                                   pcm->channels, 
                                   frames, pcm->format);
-               err = snd_pcm_mmap_forward(pcm, frames);
-               assert(err == (snd_pcm_sframes_t)frames);
-               if (frames == cont)
-                       pcm_offset = 0;
-               else
-                       pcm_offset += frames;
+               snd_pcm_mmap_commit(pcm, pcm_offset, frames);
                offset += frames;
                size -= frames;
        }
index 193e0a1c1fe421f3238386da0da6b9148eadcd72..04c23a8635eb34c535f2a4bed9a25d34a8844b4d 100644 (file)
@@ -30,6 +30,7 @@ typedef struct {
        snd_pcm_t *pcm;
        unsigned int channels_count;
        int close_slave;
+       int linked;
 } snd_pcm_multi_slave_t;
 
 typedef struct {
@@ -50,14 +51,12 @@ static int snd_pcm_multi_close(snd_pcm_t *pcm)
        unsigned int i;
        int ret = 0;
        for (i = 0; i < multi->slaves_count; ++i) {
-               int err;
                snd_pcm_multi_slave_t *slave = &multi->slaves[i];
-               if (slave->close_slave)
-                       err = snd_pcm_close(slave->pcm);
-               else
-                       err = snd_pcm_unlink(slave->pcm);
-               if (err < 0)
-                       ret = err;
+               if (slave->close_slave) {
+                       int err = snd_pcm_close(slave->pcm);
+                       if (err < 0)
+                               ret = err;
+               }
        }
        free(multi->slaves);
        free(multi->channels);
@@ -249,7 +248,7 @@ static int snd_pcm_multi_hw_params_slave(snd_pcm_t *pcm,
 {
        snd_pcm_multi_t *multi = pcm->private_data;
        snd_pcm_t *slave = multi->slaves[slave_idx].pcm;
-       int err = snd_pcm_hw_refine(slave, sparams);
+       int err = snd_pcm_hw_params(slave, sparams);
        if (err < 0)
                return err;
        err = snd_pcm_areas_silence(slave->running_areas, 0, slave->channels, slave->buffer_size, slave->format);
@@ -266,20 +265,25 @@ static int snd_pcm_multi_hw_params_slave(snd_pcm_t *pcm,
 static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       unsigned int k;
+       unsigned int i;
        snd_pcm_hw_params_t sparams[multi->slaves_count];
        int err;
-       for (k = 0; k < multi->slaves_count; ++k) {
-               err = snd_pcm_multi_hw_refine_sprepare(pcm, k, &sparams[k]);
+       for (i = 0; i < multi->slaves_count; ++i) {
+               err = snd_pcm_multi_hw_refine_sprepare(pcm, i, &sparams[i]);
                assert(err >= 0);
-               err = snd_pcm_multi_hw_refine_schange(pcm, k, params, &sparams[k]);
+               err = snd_pcm_multi_hw_refine_schange(pcm, i, params, &sparams[i]);
                assert(err >= 0);
-               err = snd_pcm_multi_hw_params_slave(pcm, k, &sparams[k]);
+               err = snd_pcm_multi_hw_params_slave(pcm, i, &sparams[i]);
                if (err < 0) {
-                       snd_pcm_multi_hw_refine_cchange(pcm, k, params, &sparams[k]);
+                       snd_pcm_multi_hw_refine_cchange(pcm, i, params, &sparams[i]);
                        return err;
                }
        }
+       multi->slaves[0].linked = 0;
+       for (i = 1; i < multi->slaves_count; ++i) {
+               err = snd_pcm_link(multi->slaves[0].pcm, multi->slaves[i].pcm);
+               multi->slaves[i].linked = (err >= 0);
+       }
        return 0;
 }
 
@@ -293,6 +297,11 @@ static int snd_pcm_multi_hw_free(snd_pcm_t *pcm)
                int e = snd_pcm_hw_free(slave);
                if (e < 0)
                        err = e;
+               if (!multi->slaves[i].linked)
+                       continue;
+               e = snd_pcm_unlink(slave);
+               if (e < 0)
+                       err = e;
        }
        return err;
 }
@@ -335,44 +344,107 @@ static int snd_pcm_multi_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 static snd_pcm_sframes_t snd_pcm_multi_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       snd_pcm_t *slave = multi->slaves[0].pcm;
-       return snd_pcm_avail_update(slave);
+       snd_pcm_sframes_t ret = LONG_MAX;
+       unsigned int i;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               snd_pcm_sframes_t avail;
+               avail = snd_pcm_avail_update(multi->slaves[i].pcm);
+               if (avail < 0)
+                       return avail;
+               if (ret > avail)
+                       ret = avail;
+       }
+       return ret;
 }
 
 static int snd_pcm_multi_prepare(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       return snd_pcm_prepare(multi->slaves[0].pcm);
+       int err = 0;
+       unsigned int i;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               if (multi->slaves[i].linked)
+                       continue;
+               err = snd_pcm_prepare(multi->slaves[i].pcm);
+               if (err < 0)
+                       return err;
+       }
+       return err;
 }
 
 static int snd_pcm_multi_reset(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       return snd_pcm_reset(multi->slaves[0].pcm);
+       int err = 0;
+       unsigned int i;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               if (multi->slaves[i].linked)
+                       continue;
+               err = snd_pcm_reset(multi->slaves[i].pcm);
+               if (err < 0)
+                       return err;
+       }
+       return err;
 }
 
 static int snd_pcm_multi_start(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       return snd_pcm_start(multi->slaves[0].pcm);
+       int err = 0;
+       unsigned int i;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               if (multi->slaves[i].linked)
+                       continue;
+               err = snd_pcm_start(multi->slaves[i].pcm);
+               if (err < 0)
+                       return err;
+       }
+       return err;
 }
 
 static int snd_pcm_multi_drop(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       return snd_pcm_drop(multi->slaves[0].pcm);
+       int err = 0;
+       unsigned int i;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               if (multi->slaves[i].linked)
+                       continue;
+               err = snd_pcm_drop(multi->slaves[i].pcm);
+               if (err < 0)
+                       return err;
+       }
+       return err;
 }
 
 static int snd_pcm_multi_drain(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       return snd_pcm_drain(multi->slaves[0].pcm);
+       int err = 0;
+       unsigned int i;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               if (multi->slaves[i].linked)
+                       continue;
+               err = snd_pcm_drain(multi->slaves[i].pcm);
+               if (err < 0)
+                       return err;
+       }
+       return err;
 }
 
 static int snd_pcm_multi_pause(snd_pcm_t *pcm, int enable)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
-       return snd_pcm_pause(multi->slaves[0].pcm, enable);
+       int err = 0;
+       unsigned int i;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               if (multi->slaves[i].linked)
+                       continue;
+               err = snd_pcm_pause(multi->slaves[i].pcm, enable);
+               if (err < 0)
+                       return err;
+       }
+       return err;
 }
 
 static int snd_pcm_multi_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
@@ -408,19 +480,21 @@ static snd_pcm_sframes_t snd_pcm_multi_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
                snd_pcm_t *slave_i = multi->slaves[i].pcm;
                snd_pcm_uframes_t f = pos[i] - frames;
                if (f > 0)
-                       snd_pcm_mmap_forward(slave_i, f);
+                       snd_pcm_mmap_commit(slave_i, snd_pcm_mmap_offset(slave_i), f);
        }
        return frames;
 }
 
-static snd_pcm_sframes_t snd_pcm_multi_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_multi_mmap_commit(snd_pcm_t *pcm,
+                                                  snd_pcm_uframes_t offset,
+                                                  snd_pcm_uframes_t size)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
        unsigned int i;
 
        for (i = 0; i < multi->slaves_count; ++i) {
                snd_pcm_t *slave = multi->slaves[i].pcm;
-               snd_pcm_sframes_t frames = snd_pcm_mmap_forward(slave, size);
+               snd_pcm_sframes_t frames = snd_pcm_mmap_commit(slave, offset, size);
                if (frames < 0)
                        return frames;
                if (i == 0) {
@@ -497,7 +571,7 @@ snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
        readn: snd_pcm_mmap_readn,
        rewind: snd_pcm_multi_rewind,
        avail_update: snd_pcm_multi_avail_update,
-       mmap_forward: snd_pcm_multi_mmap_forward,
+       mmap_commit: snd_pcm_multi_mmap_commit,
 };
 
 int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
@@ -534,8 +608,6 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
                slave->pcm = slaves_pcm[i];
                slave->channels_count = schannels_count[i];
                slave->close_slave = close_slaves;
-               if (i != 0)
-                       snd_pcm_link(slaves_pcm[i-1], slaves_pcm[i]);
        }
        for (i = 0; i < channels_count; ++i) {
                snd_pcm_multi_channel_t *bind = &multi->channels[i];
index 6f244e363e60c2fcf5afcdd9e8a8a4f5cf22c5cc..bd3f6a16e4858e5d72287e3eb70bf0efed15197a 100644 (file)
@@ -219,7 +219,9 @@ static snd_pcm_sframes_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUT
        return snd_pcm_null_fwd(pcm, size);
 }
 
-static snd_pcm_sframes_t snd_pcm_null_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_null_mmap_commit(snd_pcm_t *pcm,
+                                                 snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
+                                                 snd_pcm_uframes_t size)
 {
        return snd_pcm_null_fwd(pcm, size);
 }
@@ -316,7 +318,7 @@ snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
        readi: snd_pcm_null_readi,
        readn: snd_pcm_null_readn,
        avail_update: snd_pcm_null_avail_update,
-       mmap_forward: snd_pcm_null_mmap_forward,
+       mmap_commit: snd_pcm_null_mmap_commit,
 };
 
 int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode)
index f1b6a2291e1626b351fa9892d35e5725cd5f6e2e..a6674abbf14a04fb29b42df6cdd8e77a7293ed70 100644 (file)
@@ -198,29 +198,22 @@ static snd_pcm_uframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_t *slave = plugin->slave;
-       const snd_pcm_channel_area_t *slave_areas;
-       snd_pcm_uframes_t slave_offset;
        snd_pcm_uframes_t xfer = size;
-       slave_areas = snd_pcm_mmap_areas(slave);
-       slave_offset = snd_pcm_mmap_offset(slave);
        while (size > 0) {
                snd_pcm_uframes_t frames = size;
-               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
-               snd_pcm_uframes_t slave_frames = slave_cont;
+               const snd_pcm_channel_area_t *slave_areas;
+               snd_pcm_uframes_t slave_offset, slave_frames;
+               snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
                frames = plugin->write(pcm, areas, offset, frames,
                                       slave_areas, slave_offset, &slave_frames);
                assert(slave_frames <= snd_pcm_mmap_playback_avail(slave));
                snd_atomic_write_begin(&plugin->watom);
                snd_pcm_mmap_appl_forward(pcm, frames);
                snd_pcm_mmap_hw_forward(pcm, frames);
-               snd_pcm_mmap_forward(slave, slave_frames);
+               snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
                snd_atomic_write_end(&plugin->watom);
                offset += frames;
                size -= frames;
-               if (slave_frames == slave_cont)
-                       slave_offset = 0;
-               else
-                       slave_offset += slave_frames;
        }
        return xfer;
 }
@@ -232,29 +225,22 @@ static snd_pcm_uframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_t *slave = plugin->slave;
-       const snd_pcm_channel_area_t *slave_areas;
-       snd_pcm_uframes_t slave_offset;
        snd_pcm_uframes_t xfer = size;
-       slave_areas = snd_pcm_mmap_areas(slave);
-       slave_offset = snd_pcm_mmap_offset(slave);
        while (size > 0) {
                snd_pcm_uframes_t frames = size;
-               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
-               snd_pcm_uframes_t slave_frames = slave_cont;
+               const snd_pcm_channel_area_t *slave_areas;
+               snd_pcm_uframes_t slave_offset, slave_frames;
+               snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
                frames = plugin->read(pcm, areas, offset, frames,
                                      slave_areas, slave_offset, &slave_frames);
                assert(slave_frames <= snd_pcm_mmap_capture_avail(slave));
                snd_atomic_write_begin(&plugin->watom);
                snd_pcm_mmap_appl_forward(pcm, frames);
                snd_pcm_mmap_hw_forward(pcm, frames);
-               snd_pcm_mmap_forward(slave, slave_frames);
+               snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
                snd_atomic_write_end(&plugin->watom);
                offset += frames;
                size -= frames;
-               if (slave_frames == slave_cont)
-                       slave_offset = 0;
-               else
-                       slave_offset += slave_frames;
        }
        return xfer;
 }
@@ -292,13 +278,15 @@ snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_ufra
                                  snd_pcm_plugin_read_areas);
 }
 
-snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
+                                            snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
+                                            snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_t *slave = plugin->slave;
-       const snd_pcm_channel_area_t *areas, *slave_areas;
-       snd_pcm_uframes_t xfer, offset;
-       snd_pcm_uframes_t slave_offset, slave_size;
+       const snd_pcm_channel_area_t *areas;
+       snd_pcm_uframes_t xfer, hw_offset;
+       snd_pcm_uframes_t slave_size;
        if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
                snd_atomic_write_begin(&plugin->watom);
                snd_pcm_mmap_appl_forward(pcm, size);
@@ -309,36 +297,29 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
        if (slave_size <= 0)
                return slave_size;
        areas = snd_pcm_mmap_areas(pcm);
-       offset = snd_pcm_mmap_hw_offset(pcm);
-       slave_areas = snd_pcm_mmap_areas(slave);
-       slave_offset = snd_pcm_mmap_offset(slave);
+       hw_offset = snd_pcm_mmap_hw_offset(pcm);
        xfer = 0;
        while (size && slave_size) {
                snd_pcm_uframes_t frames = size;
-               snd_pcm_uframes_t cont = pcm->buffer_size - offset;
-               snd_pcm_uframes_t slave_frames = slave_size;
-               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
+               snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset;
+               const snd_pcm_channel_area_t *slave_areas;
+               snd_pcm_uframes_t slave_offset, slave_frames;
+               snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
                if (frames > cont)
                        frames = cont;
-               if (slave_frames > slave_cont)
-                       slave_frames = slave_cont;
-               frames = plugin->write(pcm, areas, offset, frames,
+               frames = plugin->write(pcm, areas, hw_offset, frames,
                                       slave_areas, slave_offset, &slave_frames);
                snd_atomic_write_begin(&plugin->watom);
                snd_pcm_mmap_appl_forward(pcm, frames);
                snd_pcm_mmap_hw_forward(pcm, frames);
-               snd_pcm_mmap_forward(slave, slave_frames);
+               snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
                snd_atomic_write_end(&plugin->watom);
                xfer += frames;
                if (frames == cont)
-                       offset = 0;
+                       hw_offset = 0;
                else
-                       offset += frames;
+                       hw_offset += frames;
                size -= frames;
-               if (slave_frames == slave_cont)
-                       slave_offset = 0;
-               else
-                       slave_offset += slave_frames;
                slave_size -= slave_frames;
        }
        return xfer;
@@ -348,9 +329,8 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_t *slave = plugin->slave;
-       const snd_pcm_channel_area_t *areas, *slave_areas;
-       snd_pcm_uframes_t xfer, offset, size;
-       snd_pcm_uframes_t slave_offset;
+       const snd_pcm_channel_area_t *areas;
+       snd_pcm_uframes_t xfer, hw_offset, size;
        snd_pcm_sframes_t slave_size;
        slave_size = snd_pcm_avail_update(slave);
        if (slave_size <= 0)
@@ -364,34 +344,27 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
        xfer = snd_pcm_mmap_capture_avail(pcm);
        size = pcm->buffer_size - xfer;
        areas = snd_pcm_mmap_areas(pcm);
-       offset = snd_pcm_mmap_hw_offset(pcm);
-       slave_areas = snd_pcm_mmap_areas(slave);
-       slave_offset = snd_pcm_mmap_offset(slave);
+       hw_offset = snd_pcm_mmap_hw_offset(pcm);
        while (size && slave_size) {
                snd_pcm_uframes_t frames = size;
-               snd_pcm_uframes_t cont = pcm->buffer_size - offset;
-               snd_pcm_uframes_t slave_frames = slave_size;
-               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
+               snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset;
+               const snd_pcm_channel_area_t *slave_areas;
+               snd_pcm_uframes_t slave_offset, slave_frames;
+               snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
                if (frames > cont)
                        frames = cont;
-               if (slave_frames > slave_cont)
-                       slave_frames = slave_cont;
-               frames = plugin->read(pcm, areas, offset, frames,
+               frames = plugin->read(pcm, areas, hw_offset, frames,
                                      slave_areas, slave_offset, &slave_frames);
                snd_atomic_write_begin(&plugin->watom);
                snd_pcm_mmap_hw_forward(pcm, frames);
-               snd_pcm_mmap_forward(slave, slave_frames);
+               snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
                snd_atomic_write_end(&plugin->watom);
                xfer += frames;
                if (frames == cont)
-                       offset = 0;
+                       hw_offset = 0;
                else
-                       offset += frames;
+                       hw_offset += frames;
                size -= frames;
-               if (slave_frames == slave_cont)
-                       slave_offset = 0;
-               else
-                       slave_offset += slave_frames;
                slave_size -= slave_frames;
        }
        return xfer;
@@ -474,6 +447,6 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
        readi: snd_pcm_plugin_readi,
        readn: snd_pcm_plugin_readn,
        avail_update: snd_pcm_plugin_avail_update,
-       mmap_forward: snd_pcm_plugin_mmap_forward,
+       mmap_commit: snd_pcm_plugin_mmap_commit,
 };
 
index d8aeb607ede692576821c6db8060b3b815dd2ddd..3abe7d34fe4b7ca039c4181fe2768ac7aa5309c4 100644 (file)
@@ -65,7 +65,7 @@ snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_
 snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
-snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm);
 int snd_pcm_plugin_mmap_status(snd_pcm_t *pcm);
 int snd_pcm_plugin_mmap_control(snd_pcm_t *pcm);
index e597b19ec4c44826b25137c79ebc8517833e6f58..873d18103eb3545d682291a65c2d2aea4eb1f502 100644 (file)
@@ -118,7 +118,7 @@ static snd_pcm_uframes_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
 }
 
 /* Warning: take the mutex before to call this */
-/* Return number of frames to mmap_forward the slave */
+/* Return number of frames to mmap_commit the slave */
 static snd_pcm_uframes_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
 {
        struct list_head *i;
@@ -223,7 +223,7 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
                                frames = -safety_missing;
                                missing = 1;
                        }
-                       err = snd_pcm_mmap_forward(spcm, frames);
+                       err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
                        assert(err == frames);
                        slave_avail -= frames;
                } else {
@@ -756,22 +756,25 @@ static snd_pcm_sframes_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
 }
 
 /* Call it with mutex held */
-static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t _snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
+                                                   snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
+                                                   snd_pcm_uframes_t size)
 {
        snd_pcm_share_t *share = pcm->private_data;
        snd_pcm_share_slave_t *slave = share->slave;
+       snd_pcm_t *spcm = slave->pcm;
        snd_pcm_sframes_t ret = 0;
        snd_pcm_sframes_t frames;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
            share->state == SND_PCM_STATE_RUNNING) {
-               frames = *slave->pcm->appl_ptr - share->appl_ptr;
+               frames = *spcm->appl_ptr - share->appl_ptr;
                if (frames > (snd_pcm_sframes_t)pcm->buffer_size)
                        frames -= pcm->boundary;
                else if (frames < -(snd_pcm_sframes_t)pcm->buffer_size)
                        frames += pcm->boundary;
                if (frames > 0) {
                        /* Latecomer PCM */
-                       ret = snd_pcm_rewind(slave->pcm, frames);
+                       ret = snd_pcm_rewind(spcm, frames);
                        if (ret < 0)
                                return ret;
                }
@@ -781,7 +784,7 @@ static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_ufr
                frames = _snd_pcm_share_slave_forward(slave);
                if (frames > 0) {
                        snd_pcm_sframes_t err;
-                       err = snd_pcm_mmap_forward(slave->pcm, frames);
+                       err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
                        assert(err == frames);
                }
                _snd_pcm_share_update(pcm);
@@ -789,13 +792,15 @@ static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_ufr
        return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
+                                                  snd_pcm_uframes_t offset,
+                                                  snd_pcm_uframes_t size)
 {
        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_mmap_forward(pcm, size);
+       ret = _snd_pcm_share_mmap_commit(pcm, offset, size);
        Pthread_mutex_unlock(&slave->mutex);
        return ret;
 }
@@ -838,6 +843,7 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
 {
        snd_pcm_share_t *share = pcm->private_data;
        snd_pcm_share_slave_t *slave = share->slave;
+       snd_pcm_t *spcm = slave->pcm;
        int err = 0;
        if (share->state != SND_PCM_STATE_PREPARED)
                return -EBADFD;
@@ -852,16 +858,16 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
                }
                if (slave->running_count) {
                        snd_pcm_sframes_t sd;
-                       err = snd_pcm_delay(slave->pcm, &sd);
+                       err = snd_pcm_delay(spcm, &sd);
                        if (err < 0)
                                goto _end;
-                       err = snd_pcm_rewind(slave->pcm, sd);
+                       err = snd_pcm_rewind(spcm, sd);
                        if (err < 0)
                                goto _end;
                }
                assert(share->hw_ptr == 0);
-               share->hw_ptr = *slave->pcm->hw_ptr;
-               share->appl_ptr = *slave->pcm->appl_ptr;
+               share->hw_ptr = *spcm->hw_ptr;
+               share->appl_ptr = *spcm->appl_ptr;
                while (xfer < hw_avail) {
                        snd_pcm_uframes_t frames = hw_avail - xfer;
                        snd_pcm_uframes_t offset = snd_pcm_mmap_offset(pcm);
@@ -877,10 +883,10 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
                }
                snd_pcm_mmap_appl_forward(pcm, hw_avail);
                if (slave->running_count == 0)
-                       snd_pcm_mmap_forward(slave->pcm, hw_avail);
+                       snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), hw_avail);
        }
        if (slave->running_count == 0) {
-               err = snd_pcm_start(slave->pcm);
+               err = snd_pcm_start(spcm);
                if (err < 0)
                        goto _end;
        }
@@ -1181,7 +1187,7 @@ snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
        readn: snd_pcm_mmap_readn,
        rewind: snd_pcm_share_rewind,
        avail_update: snd_pcm_share_avail_update,
-       mmap_forward: snd_pcm_share_mmap_forward,
+       mmap_commit: snd_pcm_share_mmap_commit,
 };
 
 int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
index ed2e0847a2356156353c7be1ab277d026a3919d1..4b87ed228f4c14ef7465a03e7f67e95b7a2267b4 100644 (file)
@@ -435,12 +435,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_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_shm_mmap_commit(snd_pcm_t *pcm,
+                                                snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
+                                                snd_pcm_uframes_t size)
 {
        snd_pcm_shm_t *shm = pcm->private_data;
        volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
-       ctrl->cmd = SND_PCM_IOCTL_MMAP_FORWARD;
-       ctrl->u.mmap_forward.frames = size;
+       ctrl->cmd = SND_PCM_IOCTL_MMAP_COMMIT;
+       ctrl->u.mmap_commit.offset = offset;
+       ctrl->u.mmap_commit.frames = size;
        return snd_pcm_shm_action(pcm);
 }
 
@@ -510,7 +513,7 @@ snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
        readi: snd_pcm_mmap_readi,
        readn: snd_pcm_mmap_readn,
        avail_update: snd_pcm_shm_avail_update,
-       mmap_forward: snd_pcm_shm_mmap_forward,
+       mmap_commit: snd_pcm_shm_mmap_commit,
 };
 
 static int make_local_socket(const char *filename)
index b70b74c6a4fa90d909d4fa864433dd248678cece..66231bd66876352dffecbf890089e8df31cb6daf 100644 (file)
@@ -207,13 +207,13 @@ static snd_pcm_sframes_t snd_pcm_surround_readn(snd_pcm_t *pcm, void **bufs, snd
        return res;
 }
 
-static snd_pcm_sframes_t snd_pcm_surround_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
+static snd_pcm_sframes_t snd_pcm_surround_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size)
 {
        int i;
        snd_pcm_sframes_t res = -1, res1;
        snd_pcm_surround_t *surr = pcm->private_data;
        for (i = 0; i < surr->pcms; i++) {
-               res1 = snd_pcm_mmap_forward(surr->pcm[i], size);
+               res1 = snd_pcm_mmap_commit(surr->pcm[i], offset, size);
                if (res1 < 0)
                        return res1;
                if (res < 0) {
@@ -367,7 +367,7 @@ snd_pcm_fast_ops_t snd_pcm_surround_fast_ops = {
        readi: snd_pcm_surround_readi,
        readn: snd_pcm_surround_readn,
        avail_update: snd_pcm_surround_avail_update,
-       mmap_forward: snd_pcm_surround_mmap_forward,
+       mmap_commit: snd_pcm_surround_mmap_commit,
 };
 
 int snd_pcm_surround_open(snd_pcm_t **pcmp, const char *name, int card, int dev,