From 6a3b962d065fa9bb83209ed77afa414ec4280332 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Fri, 13 Apr 2001 15:40:53 +0000 Subject: [PATCH] Better PCM mmap API. Fixed pcm_multi --- aserver/aserver.c | 8 ++- include/aserver.h | 7 ++- include/pcm.h | 16 ++---- src/pcm/pcm.c | 100 +++++++++++++-------------------- src/pcm/pcm_file.c | 31 ++++------- src/pcm/pcm_hw.c | 6 +- src/pcm/pcm_local.h | 30 ++++++++-- src/pcm/pcm_meter.c | 8 ++- src/pcm/pcm_mmap.c | 66 +++------------------- src/pcm/pcm_multi.c | 128 +++++++++++++++++++++++++++++++++---------- src/pcm/pcm_null.c | 6 +- src/pcm/pcm_plugin.c | 97 ++++++++++++-------------------- src/pcm/pcm_plugin.h | 2 +- src/pcm/pcm_share.c | 36 +++++++----- src/pcm/pcm_shm.c | 11 ++-- src/pcm/pcm_surr.c | 6 +- 16 files changed, 279 insertions(+), 279 deletions(-) diff --git a/aserver/aserver.c b/aserver/aserver.c index 8f05587b..59050c3d 100644 --- a/aserver/aserver.c +++ b/aserver/aserver.c @@ -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); diff --git a/include/aserver.h b/include/aserver.h index 9b97d150..4d52d337 100644 --- a/include/aserver.h +++ b/include/aserver.h @@ -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; diff --git a/include/pcm.h b/include/pcm.h index 241d2093..a8e0dcb5 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -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); diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 38c4ed5b..d032603b 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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 diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index 48a34279..a979914c 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -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) diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index f38470e0..0adf5ca6 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -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) diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 49a3df3f..0d68bc2b 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -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 diff --git a/src/pcm/pcm_meter.c b/src/pcm/pcm_meter.c index 3a7c737f..01aefcf1 100644 --- a/src/pcm/pcm_meter.c +++ b/src/pcm/pcm_meter.c @@ -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, diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c index 376c9837..c8d588d9 100644 --- a/src/pcm/pcm_mmap.c +++ b/src/pcm/pcm_mmap.c @@ -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; } diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index 193e0a1c..04c23a86 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -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]; diff --git a/src/pcm/pcm_null.c b/src/pcm/pcm_null.c index 6f244e36..bd3f6a16 100644 --- a/src/pcm/pcm_null.c +++ b/src/pcm/pcm_null.c @@ -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) diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index f1b6a229..a6674abb 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -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, }; diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h index d8aeb607..3abe7d34 100644 --- a/src/pcm/pcm_plugin.h +++ b/src/pcm/pcm_plugin.h @@ -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); diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index e597b19e..873d1810 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -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, diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c index ed2e0847..4b87ed22 100644 --- a/src/pcm/pcm_shm.c +++ b/src/pcm/pcm_shm.c @@ -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) diff --git a/src/pcm/pcm_surr.c b/src/pcm/pcm_surr.c index b70b74c6..66231bd6 100644 --- a/src/pcm/pcm_surr.c +++ b/src/pcm/pcm_surr.c @@ -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, -- 2.47.1