}
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");
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;
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);
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:
{
}
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;
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;
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");
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;
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;
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;
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;
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)
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;
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;
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;
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;
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;
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;
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;
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;
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);
}
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);
}
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);
}
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);
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;
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);
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");
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;