Fixed pointers use

This commit is contained in:
Abramo Bagnara 2000-10-14 18:34:51 +00:00
parent e39bf6e72e
commit a380edd64f
7 changed files with 161 additions and 158 deletions

View file

@ -288,7 +288,7 @@ int pcm_shm_open(client_t *client, int *cookie)
} }
client->transport.shm.ctrl_id = shmid; client->transport.shm.ctrl_id = shmid;
client->transport.shm.ctrl = shmat(shmid, 0, 0); client->transport.shm.ctrl = shmat(shmid, 0, 0);
if (!client->transport.shm.ctrl) { if (client->transport.shm.ctrl == (void*) -1) {
result = -errno; result = -errno;
shmctl(shmid, IPC_RMID, 0); shmctl(shmid, IPC_RMID, 0);
SYSERR("shmat"); SYSERR("shmat");
@ -360,7 +360,7 @@ int shm_ack_fd(client_t *client, int fd)
int pcm_shm_cmd(client_t *client) 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]; char buf[1];
int err; int err;
int cmd; 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); ctrl->result = snd_pcm_async(pcm, ctrl->u.async.sig, ctrl->u.async.pid);
break; break;
case SND_PCM_IOCTL_INFO: 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; break;
case SND_PCM_IOCTL_PARAMS: 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; break;
case SND_PCM_IOCTL_PARAMS_INFO: 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; break;
case SND_PCM_IOCTL_SETUP: 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; break;
case SND_PCM_IOCTL_STATUS: 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; break;
case SND_PCM_IOCTL_STATE: case SND_PCM_IOCTL_STATE:
ctrl->result = snd_pcm_state(pcm); ctrl->result = snd_pcm_state(pcm);
break; break;
case SND_PCM_IOCTL_DELAY: 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; break;
case SND_PCM_IOCTL_AVAIL_UPDATE: case SND_PCM_IOCTL_AVAIL_UPDATE:
ctrl->result = snd_pcm_avail_update(pcm); ctrl->result = snd_pcm_avail_update(pcm);
ctrl->hw_ptr = *pcm->hw_ptr;
break; break;
case SND_PCM_IOCTL_PREPARE: case SND_PCM_IOCTL_PREPARE:
ctrl->result = snd_pcm_prepare(pcm); ctrl->result = snd_pcm_prepare(pcm);
ctrl->appl_ptr = *pcm->appl_ptr;
ctrl->hw_ptr = *pcm->hw_ptr;
break; break;
case SND_PCM_IOCTL_START: case SND_PCM_IOCTL_START:
ctrl->result = snd_pcm_start(pcm); ctrl->result = snd_pcm_start(pcm);
ctrl->appl_ptr = *pcm->appl_ptr;
ctrl->hw_ptr = *pcm->hw_ptr;
break; break;
case SND_PCM_IOCTL_DRAIN: case SND_PCM_IOCTL_DRAIN:
ctrl->result = snd_pcm_drain(pcm); ctrl->result = snd_pcm_drain(pcm);
@ -412,19 +417,20 @@ int pcm_shm_cmd(client_t *client)
ctrl->result = snd_pcm_drop(pcm); ctrl->result = snd_pcm_drop(pcm);
break; break;
case SND_PCM_IOCTL_PAUSE: 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; break;
case SND_PCM_IOCTL_CHANNEL_INFO: 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; break;
case SND_PCM_IOCTL_CHANNEL_PARAMS: 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; break;
case SND_PCM_IOCTL_CHANNEL_SETUP: 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; break;
case SND_PCM_IOCTL_REWIND: 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; break;
case SND_PCM_IOCTL_LINK: case SND_PCM_IOCTL_LINK:
{ {
@ -454,11 +460,18 @@ int pcm_shm_cmd(client_t *client)
} }
i = &pcm->mmap_info[index]; i = &pcm->mmap_info[index];
if (i->type == SND_PCM_MMAP_USER) { if (i->type == SND_PCM_MMAP_USER) {
i->u.user.shmid = shmget(IPC_PRIVATE, i->size, 0666); void *ptr;
if (i->u.user.shmid < 0) { int shmid = shmget(IPC_PRIVATE, i->size, 0666);
if (shmid < 0) {
SYSERR("shmget"); SYSERR("shmget");
return -EINVAL; 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 = *i;
ctrl->u.mmap_info.index = index; ctrl->u.mmap_info.index = index;
@ -483,7 +496,8 @@ int pcm_shm_cmd(client_t *client)
break; break;
} }
case SND_PCM_IOCTL_MMAP_FORWARD: 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; break;
case SND_PCM_IOCTL_POLL_DESCRIPTOR: case SND_PCM_IOCTL_POLL_DESCRIPTOR:
ctrl->result = 0; ctrl->result = 0;
@ -895,7 +909,7 @@ int server(char *sockname, int port)
struct pollfd pfds[OPEN_MAX]; struct pollfd pfds[OPEN_MAX];
size_t pfds_count; size_t pfds_count;
do { do {
err = poll(pollfds, pollfds_count, 1000); err = poll(pollfds, pollfds_count, -1);
} while (err == 0); } while (err == 0);
if (err < 0) { if (err < 0) {
SYSERR("poll"); SYSERR("poll");

View file

@ -34,6 +34,8 @@
typedef struct { typedef struct {
long result; long result;
int cmd; int cmd;
size_t hw_ptr;
size_t appl_ptr;
union { union {
struct { struct {
int sig; int sig;
@ -45,14 +47,24 @@ typedef struct {
snd_pcm_params_info_t params_info; snd_pcm_params_info_t params_info;
snd_pcm_setup_t setup; snd_pcm_setup_t setup;
snd_pcm_status_t status; snd_pcm_status_t status;
ssize_t delay; struct {
int pause; ssize_t frames;
} delay;
struct {
int enable;
} pause;
snd_pcm_channel_info_t channel_info; snd_pcm_channel_info_t channel_info;
snd_pcm_channel_params_t channel_params; snd_pcm_channel_params_t channel_params;
snd_pcm_channel_setup_t channel_setup; snd_pcm_channel_setup_t channel_setup;
ssize_t rewind; struct {
int link; ssize_t frames;
size_t mmap_forward; } rewind;
struct {
int fd;
} link;
struct {
ssize_t frames;
} mmap_forward;
} u; } u;
char data[0]; char data[0];
} snd_pcm_shm_ctrl_t; } snd_pcm_shm_ctrl_t;

View file

@ -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); err = snd_pcm_start(pcm);
if (err < 0) if (err < 0)
break; break;
state = SND_PCM_STATE_RUNNING;
} }
} }
if (xfer > 0) if (xfer > 0)

View file

@ -122,7 +122,6 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
size_t *slave_sizep) size_t *slave_sizep)
{ {
size_t xfer; size_t xfer;
ssize_t err = 0;
if (slave_sizep && *slave_sizep < size) if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
xfer = 0; 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), snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm),
pcm->setup.format.channels, pcm->setup.format.channels,
frames, pcm->setup.format.sfmt); frames, pcm->setup.format.sfmt);
err = snd_pcm_mmap_forward(pcm, frames); snd_pcm_mmap_forward(pcm, frames);
if (err < 0) offset += frames;
break; xfer += frames;
assert((size_t)err == frames);
offset += err;
xfer += err;
} }
if (xfer > 0) { if (slave_sizep)
if (slave_sizep) *slave_sizep = xfer;
*slave_sizep = xfer; return xfer;
return xfer;
}
return err;
} }
ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, 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 *slave_sizep)
{ {
size_t xfer; size_t xfer;
ssize_t err = 0;
if (slave_sizep && *slave_sizep < size) if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
xfer = 0; xfer = 0;
@ -164,19 +156,13 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
areas, offset, areas, offset,
pcm->setup.format.channels, pcm->setup.format.channels,
frames, pcm->setup.format.sfmt); frames, pcm->setup.format.sfmt);
err = snd_pcm_mmap_forward(pcm, frames); snd_pcm_mmap_forward(pcm, frames);
if (err < 0) offset += frames;
break; xfer += frames;
assert((size_t)err == frames);
offset += err;
xfer += err;
} }
if (xfer > 0) { if (slave_sizep)
if (slave_sizep) *slave_sizep = xfer;
*slave_sizep = xfer; return xfer;
return xfer;
}
return err;
} }
ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size) ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size)

View file

@ -547,6 +547,30 @@ static int snd_pcm_route_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup)
return 0; 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, static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
snd_pcm_channel_area_t *areas, snd_pcm_channel_area_t *areas,
size_t offset, size_t offset,
@ -581,30 +605,6 @@ static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
return err; 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, static ssize_t snd_pcm_route_read_areas(snd_pcm_t *pcm,
snd_pcm_channel_area_t *areas, snd_pcm_channel_area_t *areas,
size_t offset, size_t offset,

View file

@ -152,18 +152,17 @@ static void snd_pcm_share_stop(snd_pcm_t *pcm, int state)
gettimeofday(&share->trigger_time, 0); gettimeofday(&share->trigger_time, 0);
slave->prepared_count--; slave->prepared_count--;
slave->running_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) { if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
snd_pcm_avail_update(slave->pcm);
snd_pcm_areas_copy(pcm->running_areas, 0, snd_pcm_areas_copy(pcm->running_areas, 0,
pcm->stopped_areas, 0, pcm->stopped_areas, 0,
pcm->setup.format.channels, pcm->setup.buffer_size, pcm->setup.format.channels, pcm->setup.buffer_size,
pcm->setup.format.sfmt); pcm->setup.format.sfmt);
} }
share->hw_ptr = *slave->pcm->hw_ptr; if (slave->running_count == 0) {
pcm->hw_ptr = &share->hw_ptr; int err = snd_pcm_drop(slave->pcm);
assert(err >= 0);
}
} }
/* Warning: take the mutex before to call this */ /* 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; ssize_t ret = 0;
pthread_mutex_lock(&slave->mutex); pthread_mutex_lock(&slave->mutex);
ret = snd_pcm_avail_update(slave->pcm); ret = snd_pcm_avail_update(slave->pcm);
if (share->state == SND_PCM_STATE_RUNNING)
share->hw_ptr = *slave->pcm->hw_ptr;
if (ret == -EPIPE) { if (ret == -EPIPE) {
struct list_head *i; struct list_head *i;
for (i = slave->clients.next; i != &slave->clients; i = i->next) { 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); pthread_mutex_unlock(&slave->mutex);
if (ret >= 0) { if (ret >= 0) {
ret = snd_pcm_mmap_avail(pcm); 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 -EPIPE;
}
} }
return ret; return ret;
} }
@ -659,8 +664,7 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
goto _end; goto _end;
} }
assert(share->hw_ptr == 0); assert(share->hw_ptr == 0);
/* Share the same hw_ptr of slave */ share->hw_ptr = *slave->pcm->hw_ptr;
pcm->hw_ptr = slave->pcm->hw_ptr;
share->appl_ptr = *slave->pcm->appl_ptr; share->appl_ptr = *slave->pcm->appl_ptr;
snd_pcm_areas_copy(pcm->stopped_areas, 0, snd_pcm_areas_copy(pcm->stopped_areas, 0,
pcm->running_areas, snd_pcm_mmap_offset(pcm), pcm->running_areas, snd_pcm_mmap_offset(pcm),

View file

@ -40,9 +40,7 @@
typedef struct { typedef struct {
int socket; int socket;
void *ctrl; volatile snd_pcm_shm_ctrl_t *ctrl;
size_t hw_ptr;
size_t appl_ptr;
snd_pcm_mmap_info_t *slave_mmap_info; snd_pcm_mmap_info_t *slave_mmap_info;
} snd_pcm_shm_t; } 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; snd_pcm_shm_t *shm = pcm->private;
int err; int err;
char buf[1]; 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); err = write(shm->socket, buf, 1);
if (err != 1) if (err != 1)
return -EBADFD; 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; snd_pcm_shm_t *shm = pcm->private;
int err; int err;
char buf[1]; 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); err = write(shm->socket, buf, 1);
if (err != 1) if (err != 1)
return -EBADFD; return -EBADFD;
@ -118,36 +116,6 @@ static int snd_pcm_shm_action_fd(snd_pcm_t *pcm, int *fd)
return ctrl->result; 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) static int snd_pcm_shm_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
{ {
return 0; 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) 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_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->cmd = SND_PCM_IOCTL_ASYNC;
ctrl->u.async.sig = sig; ctrl->u.async.sig = sig;
if (pid == 0) 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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
// ctrl->u.info = *info; // ctrl->u.info = *info;
ctrl->cmd = SND_PCM_IOCTL_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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
ctrl->cmd = SND_PCM_IOCTL_PARAMS_INFO; ctrl->cmd = SND_PCM_IOCTL_PARAMS_INFO;
ctrl->u.params_info = *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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
ctrl->cmd = SND_PCM_IOCTL_PARAMS; ctrl->cmd = SND_PCM_IOCTL_PARAMS;
ctrl->u.params = *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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
ctrl->cmd = SND_PCM_IOCTL_SETUP; ctrl->cmd = SND_PCM_IOCTL_SETUP;
// ctrl->u.setup = *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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
ctrl->cmd = SND_PCM_IOCTL_CHANNEL_INFO; ctrl->cmd = SND_PCM_IOCTL_CHANNEL_INFO;
ctrl->u.channel_info = *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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
ctrl->cmd = SND_PCM_IOCTL_CHANNEL_PARAMS; ctrl->cmd = SND_PCM_IOCTL_CHANNEL_PARAMS;
ctrl->u.channel_params = *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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
ctrl->cmd = SND_PCM_IOCTL_CHANNEL_SETUP; ctrl->cmd = SND_PCM_IOCTL_CHANNEL_SETUP;
ctrl->u.channel_setup = *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) 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_t *shm = pcm->private;
snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
int err; int err;
ctrl->cmd = SND_PCM_IOCTL_STATUS; ctrl->cmd = SND_PCM_IOCTL_STATUS;
// ctrl->u.status = *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) static int snd_pcm_shm_state(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; ctrl->cmd = SND_PCM_IOCTL_STATE;
return snd_pcm_shm_action(pcm); 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) static int snd_pcm_shm_delay(snd_pcm_t *pcm, ssize_t *delayp)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; int err;
ctrl->cmd = SND_PCM_IOCTL_DELAY; ctrl->cmd = SND_PCM_IOCTL_DELAY;
err = snd_pcm_shm_action(pcm); err = snd_pcm_shm_action(pcm);
if (err < 0) if (err < 0)
return err; return err;
*delayp = ctrl->u.delay; *delayp = ctrl->u.delay.frames;
return err; return err;
} }
static ssize_t snd_pcm_shm_avail_update(snd_pcm_t *pcm) static ssize_t snd_pcm_shm_avail_update(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; int err;
ctrl->cmd = SND_PCM_IOCTL_AVAIL_UPDATE; ctrl->cmd = SND_PCM_IOCTL_AVAIL_UPDATE;
err = snd_pcm_shm_action(pcm); err = snd_pcm_shm_action(pcm);
if (err < 0) if (err < 0)
return err; 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; return err;
} }
static int snd_pcm_shm_prepare(snd_pcm_t *pcm) static int snd_pcm_shm_prepare(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; ctrl->cmd = SND_PCM_IOCTL_PREPARE;
return snd_pcm_shm_action(pcm); 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) static int snd_pcm_shm_start(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; ctrl->cmd = SND_PCM_IOCTL_START;
return snd_pcm_shm_action(pcm); 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) static int snd_pcm_shm_drop(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; ctrl->cmd = SND_PCM_IOCTL_DROP;
return snd_pcm_shm_action(pcm); 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) static int snd_pcm_shm_pause(snd_pcm_t *pcm, int enable)
{ {
snd_pcm_shm_t *shm = pcm->private; 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->cmd = SND_PCM_IOCTL_PAUSE;
ctrl->u.pause = enable; ctrl->u.pause.enable = enable;
return snd_pcm_shm_action(pcm); return snd_pcm_shm_action(pcm);
} }
static ssize_t snd_pcm_shm_rewind(snd_pcm_t *pcm, size_t frames) static ssize_t snd_pcm_shm_rewind(snd_pcm_t *pcm, size_t frames)
{ {
snd_pcm_shm_t *shm = pcm->private; 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_REWIND; ctrl->cmd = SND_PCM_IOCTL_REWIND;
ctrl->u.rewind = frames; ctrl->u.rewind.frames = frames;
err = snd_pcm_shm_action(pcm); return snd_pcm_shm_action(pcm);
if (err >= 0)
snd_pcm_mmap_appl_backward(pcm, err);
return err;
} }
static int snd_pcm_shm_mmap(snd_pcm_t *pcm) static int snd_pcm_shm_mmap(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; int count, k, err, fd;
ctrl->cmd = SND_PCM_IOCTL_MMAP; ctrl->cmd = SND_PCM_IOCTL_MMAP;
count = snd_pcm_shm_action(pcm); 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) static int snd_pcm_shm_munmap(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; int err;
unsigned int k; unsigned int k;
ctrl->cmd = SND_PCM_IOCTL_MUNMAP; 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) 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_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_MMAP_FORWARD; ctrl->cmd = SND_PCM_IOCTL_MMAP_FORWARD;
ctrl->u.mmap_forward = size; ctrl->u.mmap_forward.frames = size;
err = snd_pcm_shm_action(pcm); return snd_pcm_shm_action(pcm);
if (err >= 0)
snd_pcm_mmap_appl_forward(pcm, err);
return err;
} }
static int snd_pcm_shm_poll_descriptor(snd_pcm_t *pcm) static int snd_pcm_shm_poll_descriptor(snd_pcm_t *pcm)
{ {
snd_pcm_shm_t *shm = pcm->private; 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; int fd, err;
ctrl->cmd = SND_PCM_IOCTL_POLL_DESCRIPTOR; ctrl->cmd = SND_PCM_IOCTL_POLL_DESCRIPTOR;
err = snd_pcm_shm_action_fd(pcm, &fd); 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; 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) static void snd_pcm_shm_dump(snd_pcm_t *pcm, FILE *fp)
{ {
fprintf(fp, "Shm PCM\n"); 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; return err;
} }
pcm->poll_fd = err; pcm->poll_fd = err;
pcm->hw_ptr = &shm->hw_ptr; pcm->hw_ptr = &ctrl->hw_ptr;
pcm->appl_ptr = &shm->appl_ptr; pcm->appl_ptr = &ctrl->appl_ptr;
*pcmp = pcm; *pcmp = pcm;
return 0; return 0;