From a380edd64faf059ea694301eae03b788b6a7001d Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Sat, 14 Oct 2000 18:34:51 +0000 Subject: [PATCH] Fixed pointers use --- aserver/aserver.c | 48 +++++++++++------- include/aserver.h | 22 +++++++-- src/pcm/pcm.c | 1 + src/pcm/pcm_mmap.c | 38 +++++--------- src/pcm/pcm_route.c | 48 +++++++++--------- src/pcm/pcm_share.c | 22 +++++---- src/pcm/pcm_shm.c | 140 +++++++++++++++++++++++----------------------------- 7 files changed, 161 insertions(+), 158 deletions(-) diff --git a/aserver/aserver.c b/aserver/aserver.c index a35570c4..8cda2b3b 100644 --- a/aserver/aserver.c +++ b/aserver/aserver.c @@ -288,7 +288,7 @@ int pcm_shm_open(client_t *client, int *cookie) } client->transport.shm.ctrl_id = shmid; client->transport.shm.ctrl = shmat(shmid, 0, 0); - if (!client->transport.shm.ctrl) { + if (client->transport.shm.ctrl == (void*) -1) { result = -errno; shmctl(shmid, IPC_RMID, 0); SYSERR("shmat"); @@ -360,7 +360,7 @@ int shm_ack_fd(client_t *client, int fd) int pcm_shm_cmd(client_t *client) { - snd_pcm_shm_ctrl_t *ctrl = client->transport.shm.ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = client->transport.shm.ctrl; char buf[1]; int err; int cmd; @@ -376,34 +376,39 @@ int pcm_shm_cmd(client_t *client) ctrl->result = snd_pcm_async(pcm, ctrl->u.async.sig, ctrl->u.async.pid); break; case SND_PCM_IOCTL_INFO: - ctrl->result = snd_pcm_info(pcm, &ctrl->u.info); + ctrl->result = snd_pcm_info(pcm, (snd_pcm_info_t *) &ctrl->u.info); break; case SND_PCM_IOCTL_PARAMS: - ctrl->result = snd_pcm_params(pcm, &ctrl->u.params); + ctrl->result = snd_pcm_params(pcm, (snd_pcm_params_t *) &ctrl->u.params); break; case SND_PCM_IOCTL_PARAMS_INFO: - ctrl->result = snd_pcm_params_info(pcm, &ctrl->u.params_info); + ctrl->result = snd_pcm_params_info(pcm, (snd_pcm_params_info_t *) &ctrl->u.params_info); break; case SND_PCM_IOCTL_SETUP: - ctrl->result = snd_pcm_setup(pcm, &ctrl->u.setup); + ctrl->result = snd_pcm_setup(pcm, (snd_pcm_setup_t *) &ctrl->u.setup); break; case SND_PCM_IOCTL_STATUS: - ctrl->result = snd_pcm_status(pcm, &ctrl->u.status); + ctrl->result = snd_pcm_status(pcm, (snd_pcm_status_t *) &ctrl->u.status); break; case SND_PCM_IOCTL_STATE: ctrl->result = snd_pcm_state(pcm); break; case SND_PCM_IOCTL_DELAY: - ctrl->result = snd_pcm_delay(pcm, &ctrl->u.delay); + ctrl->result = snd_pcm_delay(pcm, (ssize_t *) &ctrl->u.delay.frames); break; case SND_PCM_IOCTL_AVAIL_UPDATE: ctrl->result = snd_pcm_avail_update(pcm); + ctrl->hw_ptr = *pcm->hw_ptr; break; case SND_PCM_IOCTL_PREPARE: ctrl->result = snd_pcm_prepare(pcm); + ctrl->appl_ptr = *pcm->appl_ptr; + ctrl->hw_ptr = *pcm->hw_ptr; break; case SND_PCM_IOCTL_START: ctrl->result = snd_pcm_start(pcm); + ctrl->appl_ptr = *pcm->appl_ptr; + ctrl->hw_ptr = *pcm->hw_ptr; break; case SND_PCM_IOCTL_DRAIN: ctrl->result = snd_pcm_drain(pcm); @@ -412,19 +417,20 @@ int pcm_shm_cmd(client_t *client) ctrl->result = snd_pcm_drop(pcm); break; case SND_PCM_IOCTL_PAUSE: - ctrl->result = snd_pcm_pause(pcm, ctrl->u.pause); + ctrl->result = snd_pcm_pause(pcm, ctrl->u.pause.enable); break; case SND_PCM_IOCTL_CHANNEL_INFO: - ctrl->result = snd_pcm_channel_info(pcm, &ctrl->u.channel_info); + ctrl->result = snd_pcm_channel_info(pcm, (snd_pcm_channel_info_t *) &ctrl->u.channel_info); break; case SND_PCM_IOCTL_CHANNEL_PARAMS: - ctrl->result = snd_pcm_channel_params(pcm, &ctrl->u.channel_params); + ctrl->result = snd_pcm_channel_params(pcm, (snd_pcm_channel_params_t *) &ctrl->u.channel_params); break; case SND_PCM_IOCTL_CHANNEL_SETUP: - ctrl->result = snd_pcm_channel_setup(pcm, &ctrl->u.channel_setup); + ctrl->result = snd_pcm_channel_setup(pcm, (snd_pcm_channel_setup_t *) &ctrl->u.channel_setup); break; case SND_PCM_IOCTL_REWIND: - ctrl->result = snd_pcm_rewind(pcm, ctrl->u.rewind); + ctrl->result = snd_pcm_rewind(pcm, ctrl->u.rewind.frames); + ctrl->appl_ptr = *pcm->appl_ptr; break; case SND_PCM_IOCTL_LINK: { @@ -454,11 +460,18 @@ int pcm_shm_cmd(client_t *client) } i = &pcm->mmap_info[index]; if (i->type == SND_PCM_MMAP_USER) { - i->u.user.shmid = shmget(IPC_PRIVATE, i->size, 0666); - if (i->u.user.shmid < 0) { + void *ptr; + int shmid = shmget(IPC_PRIVATE, i->size, 0666); + if (shmid < 0) { SYSERR("shmget"); return -EINVAL; } + ptr = shmat(shmid, i->addr, 0); + if (ptr != i->addr) { + SYSERR("shmat"); + return -EINVAL; + } + i->u.user.shmid = shmid; } ctrl->u.mmap_info = *i; ctrl->u.mmap_info.index = index; @@ -483,7 +496,8 @@ int pcm_shm_cmd(client_t *client) break; } case SND_PCM_IOCTL_MMAP_FORWARD: - ctrl->result = snd_pcm_mmap_forward(pcm, ctrl->u.mmap_forward); + ctrl->result = snd_pcm_mmap_forward(pcm, ctrl->u.mmap_forward.frames); + ctrl->appl_ptr = *pcm->appl_ptr; break; case SND_PCM_IOCTL_POLL_DESCRIPTOR: ctrl->result = 0; @@ -895,7 +909,7 @@ int server(char *sockname, int port) struct pollfd pfds[OPEN_MAX]; size_t pfds_count; do { - err = poll(pollfds, pollfds_count, 1000); + err = poll(pollfds, pollfds_count, -1); } while (err == 0); if (err < 0) { SYSERR("poll"); diff --git a/include/aserver.h b/include/aserver.h index 9a68b0d7..643c5684 100644 --- a/include/aserver.h +++ b/include/aserver.h @@ -34,6 +34,8 @@ typedef struct { long result; int cmd; + size_t hw_ptr; + size_t appl_ptr; union { struct { int sig; @@ -45,14 +47,24 @@ typedef struct { snd_pcm_params_info_t params_info; snd_pcm_setup_t setup; snd_pcm_status_t status; - ssize_t delay; - int pause; + struct { + ssize_t frames; + } delay; + struct { + int enable; + } pause; snd_pcm_channel_info_t channel_info; snd_pcm_channel_params_t channel_params; snd_pcm_channel_setup_t channel_setup; - ssize_t rewind; - int link; - size_t mmap_forward; + struct { + ssize_t frames; + } rewind; + struct { + int fd; + } link; + struct { + ssize_t frames; + } mmap_forward; } u; char data[0]; } snd_pcm_shm_ctrl_t; diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 5c85320c..e1a797e0 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -1039,6 +1039,7 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, err = snd_pcm_start(pcm); if (err < 0) break; + state = SND_PCM_STATE_RUNNING; } } if (xfer > 0) diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c index ffdb8455..4eb51d4f 100644 --- a/src/pcm/pcm_mmap.c +++ b/src/pcm/pcm_mmap.c @@ -122,7 +122,6 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, size_t *slave_sizep) { size_t xfer; - ssize_t err = 0; if (slave_sizep && *slave_sizep < size) size = *slave_sizep; xfer = 0; @@ -132,19 +131,13 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm), pcm->setup.format.channels, frames, pcm->setup.format.sfmt); - err = snd_pcm_mmap_forward(pcm, frames); - if (err < 0) - break; - assert((size_t)err == frames); - offset += err; - xfer += err; - } - if (xfer > 0) { - if (slave_sizep) - *slave_sizep = xfer; - return xfer; + snd_pcm_mmap_forward(pcm, frames); + offset += frames; + xfer += frames; } - return err; + if (slave_sizep) + *slave_sizep = xfer; + return xfer; } ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, @@ -154,7 +147,6 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, size_t *slave_sizep) { size_t xfer; - ssize_t err = 0; if (slave_sizep && *slave_sizep < size) size = *slave_sizep; xfer = 0; @@ -164,19 +156,13 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, areas, offset, pcm->setup.format.channels, frames, pcm->setup.format.sfmt); - err = snd_pcm_mmap_forward(pcm, frames); - if (err < 0) - break; - assert((size_t)err == frames); - offset += err; - xfer += err; - } - if (xfer > 0) { - if (slave_sizep) - *slave_sizep = xfer; - return xfer; + snd_pcm_mmap_forward(pcm, frames); + offset += frames; + xfer += frames; } - return err; + if (slave_sizep) + *slave_sizep = xfer; + return xfer; } ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size) diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c index c51be601..7b6883c4 100644 --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -547,6 +547,30 @@ static int snd_pcm_route_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup) return 0; } +static int snd_pcm_route_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup) +{ +#if 0 + snd_pcm_plugin_t *plugin = pcm->private; + int err; + err = snd_pcm_channel_setup(plugin->slave, setup); + if (err < 0) + return err; +#endif + if (!pcm->mmap_info) + return 0; + if (pcm->setup.mmap_shape == SND_PCM_MMAP_INTERLEAVED) { + setup->running_area.addr = pcm->mmap_info->addr; + setup->running_area.first = setup->channel * pcm->bits_per_sample; + setup->running_area.step = pcm->bits_per_frame; + } else { + setup->running_area.addr = pcm->mmap_info->addr + setup->channel * pcm->setup.buffer_size * pcm->bits_per_sample / 8; + setup->running_area.first = 0; + setup->running_area.step = pcm->bits_per_sample; + } + setup->stopped_area = setup->running_area; + return 0; +} + static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, size_t offset, @@ -581,30 +605,6 @@ static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm, return err; } -static int snd_pcm_route_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup) -{ -#if 0 - snd_pcm_plugin_t *plugin = pcm->private; - int err; - err = snd_pcm_channel_setup(plugin->slave, setup); - if (err < 0) - return err; -#endif - if (!pcm->mmap_info) - return 0; - if (pcm->setup.mmap_shape == SND_PCM_MMAP_INTERLEAVED) { - setup->running_area.addr = pcm->mmap_info->addr; - setup->running_area.first = setup->channel * pcm->bits_per_sample; - setup->running_area.step = pcm->bits_per_frame; - } else { - setup->running_area.addr = pcm->mmap_info->addr + setup->channel * pcm->setup.buffer_size * pcm->bits_per_sample / 8; - setup->running_area.first = 0; - setup->running_area.step = pcm->bits_per_sample; - } - setup->stopped_area = setup->running_area; - return 0; -} - static ssize_t snd_pcm_route_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, size_t offset, diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index 9876afa9..98aa2c41 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -152,18 +152,17 @@ static void snd_pcm_share_stop(snd_pcm_t *pcm, int state) gettimeofday(&share->trigger_time, 0); slave->prepared_count--; slave->running_count--; - if (slave->running_count == 0) { - int err = snd_pcm_drop(slave->pcm); - assert(err >= 0); - } if (pcm->stream == SND_PCM_STREAM_CAPTURE) { + snd_pcm_avail_update(slave->pcm); snd_pcm_areas_copy(pcm->running_areas, 0, pcm->stopped_areas, 0, pcm->setup.format.channels, pcm->setup.buffer_size, pcm->setup.format.sfmt); } - share->hw_ptr = *slave->pcm->hw_ptr; - pcm->hw_ptr = &share->hw_ptr; + if (slave->running_count == 0) { + int err = snd_pcm_drop(slave->pcm); + assert(err >= 0); + } } /* Warning: take the mutex before to call this */ @@ -557,6 +556,8 @@ static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm) ssize_t ret = 0; pthread_mutex_lock(&slave->mutex); ret = snd_pcm_avail_update(slave->pcm); + if (share->state == SND_PCM_STATE_RUNNING) + share->hw_ptr = *slave->pcm->hw_ptr; if (ret == -EPIPE) { struct list_head *i; for (i = slave->clients.next; i != &slave->clients; i = i->next) { @@ -570,8 +571,12 @@ static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm) pthread_mutex_unlock(&slave->mutex); if (ret >= 0) { ret = snd_pcm_mmap_avail(pcm); - if ((size_t)ret > pcm->setup.buffer_size) + if ((size_t)ret > pcm->setup.buffer_size) { + if (share->state == SND_PCM_STATE_RUNNING && + pcm->setup.xrun_mode != SND_PCM_XRUN_NONE) + snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN); return -EPIPE; + } } return ret; } @@ -659,8 +664,7 @@ static int snd_pcm_share_start(snd_pcm_t *pcm) goto _end; } assert(share->hw_ptr == 0); - /* Share the same hw_ptr of slave */ - pcm->hw_ptr = slave->pcm->hw_ptr; + share->hw_ptr = *slave->pcm->hw_ptr; share->appl_ptr = *slave->pcm->appl_ptr; snd_pcm_areas_copy(pcm->stopped_areas, 0, pcm->running_areas, snd_pcm_mmap_offset(pcm), diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c index 0541ffec..766e7bad 100644 --- a/src/pcm/pcm_shm.c +++ b/src/pcm/pcm_shm.c @@ -40,9 +40,7 @@ typedef struct { int socket; - void *ctrl; - size_t hw_ptr; - size_t appl_ptr; + volatile snd_pcm_shm_ctrl_t *ctrl; snd_pcm_mmap_info_t *slave_mmap_info; } snd_pcm_shm_t; @@ -85,7 +83,7 @@ static int snd_pcm_shm_action(snd_pcm_t *pcm) snd_pcm_shm_t *shm = pcm->private; int err; char buf[1]; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; err = write(shm->socket, buf, 1); if (err != 1) return -EBADFD; @@ -104,7 +102,7 @@ static int snd_pcm_shm_action_fd(snd_pcm_t *pcm, int *fd) snd_pcm_shm_t *shm = pcm->private; int err; char buf[1]; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; err = write(shm->socket, buf, 1); if (err != 1) return -EBADFD; @@ -118,36 +116,6 @@ static int snd_pcm_shm_action_fd(snd_pcm_t *pcm, int *fd) return ctrl->result; } -static int snd_pcm_shm_drain(snd_pcm_t *pcm) -{ - snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; - int err; - ctrl->cmd = SND_PCM_IOCTL_DRAIN; - err = snd_pcm_shm_action(pcm); - if (err < 0) - return err; - if (!(pcm->mode & SND_PCM_NONBLOCK)) - snd_pcm_wait(pcm, -1); - return err; -} - -static int snd_pcm_shm_close(snd_pcm_t *pcm) -{ - snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; - int result; - if (!(pcm->mode & SND_PCM_NONBLOCK)) - snd_pcm_shm_drain(pcm); - ctrl->cmd = SND_PCM_IOCTL_CLOSE; - result = snd_pcm_shm_action(pcm); - shmdt((void *)ctrl); - close(shm->socket); - close(pcm->poll_fd); - free(shm); - return result; -} - static int snd_pcm_shm_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED) { return 0; @@ -156,7 +124,7 @@ static int snd_pcm_shm_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock AT static int snd_pcm_shm_async(snd_pcm_t *pcm, int sig, pid_t pid) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_ASYNC; ctrl->u.async.sig = sig; if (pid == 0) @@ -168,7 +136,7 @@ static int snd_pcm_shm_async(snd_pcm_t *pcm, int sig, pid_t pid) static int snd_pcm_shm_info(snd_pcm_t *pcm, snd_pcm_info_t * info) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; // ctrl->u.info = *info; ctrl->cmd = SND_PCM_IOCTL_INFO; @@ -182,7 +150,7 @@ static int snd_pcm_shm_info(snd_pcm_t *pcm, snd_pcm_info_t * info) static int snd_pcm_shm_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t * info) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_PARAMS_INFO; ctrl->u.params_info = *info; @@ -196,7 +164,7 @@ static int snd_pcm_shm_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t * info) static int snd_pcm_shm_params(snd_pcm_t *pcm, snd_pcm_params_t * params) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_PARAMS; ctrl->u.params = *params; @@ -210,7 +178,7 @@ static int snd_pcm_shm_params(snd_pcm_t *pcm, snd_pcm_params_t * params) static int snd_pcm_shm_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_SETUP; // ctrl->u.setup = *setup; @@ -224,7 +192,7 @@ static int snd_pcm_shm_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup) static int snd_pcm_shm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_CHANNEL_INFO; ctrl->u.channel_info = *info; @@ -238,7 +206,7 @@ static int snd_pcm_shm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * inf static int snd_pcm_shm_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_CHANNEL_PARAMS; ctrl->u.channel_params = *params; @@ -270,7 +238,7 @@ static void *convert_addr(void *addr, size_t count, snd_pcm_mmap_info_t *old, sn static int snd_pcm_shm_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_CHANNEL_SETUP; ctrl->u.channel_setup = *setup; @@ -288,7 +256,7 @@ static int snd_pcm_shm_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * s static int snd_pcm_shm_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_STATUS; // ctrl->u.status = *status; @@ -302,7 +270,7 @@ static int snd_pcm_shm_status(snd_pcm_t *pcm, snd_pcm_status_t * status) static int snd_pcm_shm_state(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_STATE; return snd_pcm_shm_action(pcm); } @@ -310,37 +278,32 @@ static int snd_pcm_shm_state(snd_pcm_t *pcm) static int snd_pcm_shm_delay(snd_pcm_t *pcm, ssize_t *delayp) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_DELAY; err = snd_pcm_shm_action(pcm); if (err < 0) return err; - *delayp = ctrl->u.delay; + *delayp = ctrl->u.delay.frames; return err; } static ssize_t snd_pcm_shm_avail_update(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; ctrl->cmd = SND_PCM_IOCTL_AVAIL_UPDATE; err = snd_pcm_shm_action(pcm); if (err < 0) return err; - shm->hw_ptr = shm->appl_ptr; - if (pcm->stream == SND_PCM_STREAM_PLAYBACK) - snd_pcm_mmap_hw_backward(pcm, err); - else - snd_pcm_mmap_hw_forward(pcm, err); return err; } static int snd_pcm_shm_prepare(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_PREPARE; return snd_pcm_shm_action(pcm); } @@ -348,7 +311,7 @@ static int snd_pcm_shm_prepare(snd_pcm_t *pcm) static int snd_pcm_shm_start(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_START; return snd_pcm_shm_action(pcm); } @@ -356,37 +319,47 @@ static int snd_pcm_shm_start(snd_pcm_t *pcm) static int snd_pcm_shm_drop(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_DROP; return snd_pcm_shm_action(pcm); } +static int snd_pcm_shm_drain(snd_pcm_t *pcm) +{ + snd_pcm_shm_t *shm = pcm->private; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + int err; + ctrl->cmd = SND_PCM_IOCTL_DRAIN; + err = snd_pcm_shm_action(pcm); + if (err < 0) + return err; + if (!(pcm->mode & SND_PCM_NONBLOCK)) + snd_pcm_wait(pcm, -1); + return err; +} + static int snd_pcm_shm_pause(snd_pcm_t *pcm, int enable) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_PAUSE; - ctrl->u.pause = enable; + ctrl->u.pause.enable = enable; return snd_pcm_shm_action(pcm); } static ssize_t snd_pcm_shm_rewind(snd_pcm_t *pcm, size_t frames) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; - int err; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_REWIND; - ctrl->u.rewind = frames; - err = snd_pcm_shm_action(pcm); - if (err >= 0) - snd_pcm_mmap_appl_backward(pcm, err); - return err; + ctrl->u.rewind.frames = frames; + return snd_pcm_shm_action(pcm); } static int snd_pcm_shm_mmap(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int count, k, err, fd; ctrl->cmd = SND_PCM_IOCTL_MMAP; count = snd_pcm_shm_action(pcm); @@ -432,7 +405,7 @@ static int snd_pcm_shm_mmap(snd_pcm_t *pcm) static int snd_pcm_shm_munmap(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int err; unsigned int k; ctrl->cmd = SND_PCM_IOCTL_MUNMAP; @@ -464,20 +437,16 @@ static int snd_pcm_shm_munmap(snd_pcm_t *pcm) static ssize_t snd_pcm_shm_mmap_forward(snd_pcm_t *pcm, size_t size) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; - int err; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; ctrl->cmd = SND_PCM_IOCTL_MMAP_FORWARD; - ctrl->u.mmap_forward = size; - err = snd_pcm_shm_action(pcm); - if (err >= 0) - snd_pcm_mmap_appl_forward(pcm, err); - return err; + ctrl->u.mmap_forward.frames = size; + return snd_pcm_shm_action(pcm); } static int snd_pcm_shm_poll_descriptor(snd_pcm_t *pcm) { snd_pcm_shm_t *shm = pcm->private; - snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; int fd, err; ctrl->cmd = SND_PCM_IOCTL_POLL_DESCRIPTOR; err = snd_pcm_shm_action_fd(pcm, &fd); @@ -492,6 +461,23 @@ static int snd_pcm_shm_channels_mask(snd_pcm_t *pcm ATTRIBUTE_UNUSED, return 0; } +static int snd_pcm_shm_close(snd_pcm_t *pcm) +{ + snd_pcm_shm_t *shm = pcm->private; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + int result; + if (!(pcm->mode & SND_PCM_NONBLOCK) && + snd_pcm_shm_state(pcm) == SND_PCM_STATE_RUNNING) + snd_pcm_shm_drain(pcm); + ctrl->cmd = SND_PCM_IOCTL_CLOSE; + result = snd_pcm_shm_action(pcm); + shmdt((void *)ctrl); + close(shm->socket); + close(pcm->poll_fd); + free(shm); + return result; +} + static void snd_pcm_shm_dump(snd_pcm_t *pcm, FILE *fp) { fprintf(fp, "Shm PCM\n"); @@ -680,8 +666,8 @@ int snd_pcm_shm_open(snd_pcm_t **pcmp, char *name, char *socket, char *sname, in return err; } pcm->poll_fd = err; - pcm->hw_ptr = &shm->hw_ptr; - pcm->appl_ptr = &shm->appl_ptr; + pcm->hw_ptr = &ctrl->hw_ptr; + pcm->appl_ptr = &ctrl->appl_ptr; *pcmp = pcm; return 0; -- 2.11.0