-M add abstraction layer to control, timer, rawmidi, hwdep, seq
+M add abstraction layer to timer, rawmidi, hwdep, seq
M plug sync and pos problems
M Loopback implementation?
-M change callback argument to be snd_pcm_t instead of void *
L move OSS emulation to user space? (pseudo device driver and daemon)
#define PCM_SHM_SIZE 65536
#define PCM_SHM_DATA_MAXLEN (PCM_SHM_SIZE - offsetof(snd_pcm_client_shm_t, data))
+#define SND_CTL_IOCTL_READ _IOR('U', 0xf0, snd_ctl_event_t)
+#define SND_CTL_IOCTL_CLOSE _IO ('U', 0xf1)
+
+typedef struct {
+ int result;
+ int cmd;
+ union {
+ snd_ctl_hw_info_t hw_info;
+ snd_control_list_t clist;
+ snd_control_info_t cinfo;
+ snd_control_t cread;
+ snd_control_t cwrite;
+ snd_hwdep_info_t hwdep_info;
+ snd_pcm_info_t pcm_info;
+ int pcm_prefer_subdevice;
+ snd_rawmidi_info_t rawmidi_info;
+ snd_ctl_event_t read;
+ } u;
+ char data[0];
+} snd_ctl_client_shm_t;
+
+#define CTL_SHM_SIZE 65536
+#define CTL_SHM_DATA_MAXLEN (CTL_SHM_SIZE - offsetof(snd_ctl_client_shm_t, data))
+
typedef struct {
unsigned char dev_type;
unsigned char transport_type;
int cookie;
} snd_client_open_answer_t;
-struct cmsg_fd
-{
- int len; /* sizeof structure */
- int level; /* SOL_SOCKET */
- int type; /* SCM_RIGHTS */
- int fd; /* fd to pass */
-};
typedef struct snd_ctl snd_ctl_t;
+typedef enum { SND_CTL_TYPE_HW, SND_CTL_TYPE_CLIENT } snd_ctl_type_t;
+
typedef struct snd_ctl_callbacks {
void *private_data; /* may be used by an application */
void (*rebuild) (snd_ctl_t *handle, void *private_data);
int snd_defaults_rawmidi_card(void);
int snd_defaults_rawmidi_device(void);
-int snd_ctl_open(snd_ctl_t **handle, int card);
+int snd_ctl_hw_open(snd_ctl_t **handle, int card);
+int snd_ctl_client_open(snd_ctl_t **handlep, char *host, int port, int transport, char *name);
+snd_ctl_type_t snd_ctl_type(snd_ctl_t *handle);
+int snd_ctl_open(snd_ctl_t **handle, char *name);
int snd_ctl_close(snd_ctl_t *handle);
int snd_ctl_file_descriptor(snd_ctl_t *handle);
int snd_ctl_hw_info(snd_ctl_t *handle, snd_ctl_hw_info_t *info);
extern "C" {
#endif
-int snd_mixer_open(snd_mixer_t **handle, int card);
+int snd_mixer_open(snd_mixer_t **handle, char *name);
int snd_mixer_close(snd_mixer_t *handle);
int snd_mixer_file_descriptor(snd_mixer_t *handle);
#include "asoundlib.h"
#include "pcm_local.h"
#include "aserver.h"
+#include "list.h"
char *command;
return ret;
}
+struct pollfd pollfds[OPEN_MAX];
+unsigned int pollfds_count = 0;
+typedef struct waiter waiter_t;
+typedef int (*waiter_handler_t)(waiter_t *waiter, unsigned short events);
+struct waiter {
+ int fd;
+ void *private_data;
+ waiter_handler_t handler;
+};
+waiter_t waiters[OPEN_MAX];
+
+void add_waiter(int fd, unsigned short events, waiter_handler_t handler,
+ void *data)
+{
+ waiter_t *w = &waiters[fd];
+ struct pollfd *pfd = &pollfds[pollfds_count];
+ assert(!w->handler);
+ pfd->fd = fd;
+ pfd->events = events;
+ pfd->revents = 0;
+ w->fd = fd;
+ w->private_data = data;
+ w->handler = handler;
+ pollfds_count++;
+}
+
+void del_waiter(int fd)
+{
+ waiter_t *w = &waiters[fd];
+ unsigned int k;
+ assert(w->handler);
+ w->handler = 0;
+ for (k = 0; k < pollfds_count; ++k) {
+ if (pollfds[k].fd == fd)
+ break;
+ }
+ assert(k < pollfds_count);
+ pollfds_count--;
+ memmove(&pollfds[k], &pollfds[k + 1], pollfds_count - k);
+}
+
+typedef struct {
+ struct list_head list;
+ int fd;
+ int local;
+} master_t;
+LIST_HEAD(masters);
+
typedef struct client client_t;
typedef struct {
int (*open)(client_t *client, int *cookie);
int (*cmd)(client_t *client);
int (*close)(client_t *client);
- int (*poll_prepare)(client_t *client, struct pollfd *pfds, int pindex);
- void (*poll_events)(client_t *client, struct pollfd *pfds);
} transport_ops_t;
struct client {
+ struct list_head list;
struct socket {
int fd;
- int pindex;
int local;
} data, ctrl;
int transport_type;
struct {
snd_pcm_t *handle;
int fd;
- int pindex;
} pcm;
-#if 0
struct {
snd_ctl_t *handle;
+ int fd;
} control;
+#if 0
struct {
snd_rawmidi_t *handle;
} rawmidi;
} seq;
#endif
} device;
- enum { CLOSED = 0, STOPPED, NORMAL, UNKNOWN } state;
+ int polling;
+ int open;
int cookie;
union {
struct {
} transport;
};
-#define PENDINGS_MAX 4
-#define CLIENTS_MAX 2
+LIST_HEAD(clients);
-client_t clients[CLIENTS_MAX];
-int clients_count = 0;
+typedef struct {
+ struct list_head list;
+ int fd;
+ uint32_t cookie;
+ int local;
+} pending_t;
+LIST_HEAD(pendings);
+
+int pcm_handler(waiter_t *waiter, unsigned short events)
+{
+ client_t *client = waiter->private_data;
+ char buf[1];
+ ssize_t n;
+ if (events & POLLIN) {
+ n = write(client->data.fd, buf, 1);
+ if (n != 1) {
+ perrno("write");
+ return -errno;
+ }
+ } else if (events & POLLOUT) {
+ n = read(client->data.fd, buf, 1);
+ if (n != 1) {
+ perrno("read");
+ return -errno;
+ }
+ }
+ del_waiter(waiter->fd);
+ client->polling = 0;
+ return 0;
+}
int pcm_shm_open(client_t *client, int *cookie)
{
{
int err;
snd_pcm_client_shm_t *ctrl = client->transport.shm.ctrl;
+ if (client->polling) {
+ del_waiter(client->device.pcm.fd);
+ client->polling = 0;
+ }
/* FIXME: blocking */
err = snd_pcm_close(client->device.pcm.handle);
ctrl->result = err;
perrno("shmctl");
client->transport.shm.ctrl = 0;
}
- client->state = CLOSED;
+ client->open = 0;
return 0;
}
-int pcm_poll_prepare(client_t *client, struct pollfd *pfds, int pindex)
-{
- struct pollfd *pfd = &pfds[pindex];
- pfd->events = 0;
- switch (client->state) {
- case UNKNOWN:
- pfd->events = client->stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
- case NORMAL:
- pfd->fd = client->device.pcm.fd;
- client->device.pcm.pindex = pindex;
- return 1;
- break;
- default:
- client->device.pcm.pindex = -1;
- return 0;
- }
-}
-
-void pcm_poll_events(client_t *client, struct pollfd *pfds)
-{
- int n;
- char zero = 0;
- struct pollfd *pfd;
- if (client->device.pcm.pindex < 0)
- return;
- pfd = &pfds[client->device.pcm.pindex];
- if (pfd->revents & POLLIN) {
- client->state = NORMAL;
- n = write(client->data.fd, &zero, 1);
- if (n != 1) {
- perrno("write");
- exit(1);
- }
- } else if (pfd->revents & POLLOUT) {
- client->state = NORMAL;
- n = read(client->data.fd, &zero, 1);
- if (n != 1) {
- perrno("read");
- exit(1);
- }
- }
-}
-
int pcm_shm_cmd(client_t *client)
{
snd_pcm_client_shm_t *ctrl = client->transport.shm.ctrl;
case SND_PCM_IOCTL_WRITE_FRAMES:
{
size_t maxsize = PCM_SHM_DATA_MAXLEN;
- client->state = UNKNOWN;
maxsize = snd_pcm_bytes_to_frames(pcm, maxsize);
if (ctrl->u.write.count > maxsize) {
ctrl->result = -EFAULT;
case SND_PCM_IOCTL_READ_FRAMES:
{
size_t maxsize = PCM_SHM_DATA_MAXLEN;
- client->state = UNKNOWN;
maxsize = snd_pcm_bytes_to_frames(pcm, maxsize);
if (ctrl->u.read.count > maxsize) {
ctrl->result = -EFAULT;
size_t vecsize;
char *base;
int bits_per_sample = snd_pcm_samples_to_bytes(pcm, 8);
- client->state = UNKNOWN;
vecsize = ctrl->u.writev.count * sizeof(struct iovec);
if (vecsize > maxsize) {
ctrl->result = -EFAULT;
size_t vecsize;
char *base;
int bits_per_sample = snd_pcm_samples_to_bytes(pcm, 8);
- client->state = UNKNOWN;
vecsize = ctrl->u.readv.count * sizeof(struct iovec);
if (vecsize > maxsize) {
ctrl->result = -EFAULT;
break;
}
case SND_PCM_IOCTL_FRAME_DATA:
- client->state = UNKNOWN;
ctrl->result = snd_pcm_frame_data(pcm, ctrl->u.frame_data);
break;
case SND_PCM_IOCTL_LINK:
{
- int k;
- for (k = 0; k < clients_count; ++k) {
- if (clients[k].state == CLOSED)
+ struct list_head *item;
+ list_for_each(item, &clients) {
+ client_t *client = list_entry(item, client_t, list);
+ if (!client->open)
continue;
- if (clients[k].data.fd == ctrl->u.link) {
- ctrl->result = snd_pcm_link(pcm, clients[k].device.pcm.handle);
+ if (client->data.fd == ctrl->u.link) {
+ ctrl->result = snd_pcm_link(pcm, client->device.pcm.handle);
break;
}
}
case SND_PCM_IOCTL_MUNMAP_STATUS:
ctrl->result = 0;
break;
- }
#endif
case SND_PCM_IOCTL_CLOSE:
client->ops->close(client);
err = write(client->ctrl.fd, buf, 1);
if (err != 1)
return -EBADFD;
+ if (!client->polling) {
+ add_waiter(client->device.pcm.fd, POLLIN | POLLOUT, pcm_handler, client);
+ client->polling = 1;
+ }
return 0;
}
open: pcm_shm_open,
cmd: pcm_shm_cmd,
close: pcm_shm_close,
- poll_prepare: pcm_poll_prepare,
- poll_events: pcm_poll_events,
};
-void snd_client_open(client_t *client)
+int ctl_handler(waiter_t *waiter, unsigned short events)
+{
+ client_t *client = waiter->private_data;
+ char buf[1];
+ ssize_t n;
+ if (events & POLLIN) {
+ n = write(client->data.fd, buf, 1);
+ if (n != 1) {
+ perrno("write");
+ return -errno;
+ }
+ }
+ del_waiter(waiter->fd);
+ client->polling = 0;
+ return 0;
+}
+
+int ctl_shm_open(client_t *client, int *cookie)
+{
+ int shmid;
+ snd_ctl_t *ctl;
+ int err;
+ int result;
+ err = snd_ctl_open(&ctl, client->name);
+ if (err < 0)
+ return err;
+ client->device.control.handle = ctl;
+ client->device.control.fd = snd_ctl_file_descriptor(ctl);
+
+ shmid = shmget(IPC_PRIVATE, CTL_SHM_SIZE, 0666);
+ if (shmid < 0) {
+ result = -errno;
+ perrno("shmget");
+ goto _err;
+ }
+ client->transport.shm.ctrl_id = shmid;
+ client->transport.shm.ctrl = shmat(shmid, 0, 0);
+ if (!client->transport.shm.ctrl) {
+ result = -errno;
+ shmctl(shmid, IPC_RMID, 0);
+ perrno("shmat");
+ goto _err;
+ }
+ *cookie = shmid;
+ add_waiter(client->device.control.fd, POLLIN, ctl_handler, client);
+ client->polling = 1;
+ return 0;
+
+ _err:
+ snd_ctl_close(ctl);
+ return result;
+
+}
+
+int ctl_shm_close(client_t *client)
+{
+ int err;
+ snd_ctl_client_shm_t *ctrl = client->transport.shm.ctrl;
+ if (client->polling) {
+ del_waiter(client->device.control.fd);
+ client->polling = 0;
+ }
+ /* FIXME: blocking */
+ err = snd_ctl_close(client->device.control.handle);
+ ctrl->result = err;
+ if (err < 0)
+ perrno("snd_ctl_close");
+ if (client->transport.shm.ctrl) {
+ err = shmdt((void *)client->transport.shm.ctrl);
+ if (err < 0)
+ perrno("shmdt");
+ err = shmctl(client->transport.shm.ctrl_id, IPC_RMID, 0);
+ if (err < 0)
+ perrno("shmctl");
+ client->transport.shm.ctrl = 0;
+ }
+ client->open = 0;
+ return 0;
+}
+
+extern int snd_ctl_read1(snd_ctl_t *ctl, snd_ctl_event_t *event);
+
+int ctl_shm_cmd(client_t *client)
+{
+ snd_ctl_client_shm_t *ctrl = client->transport.shm.ctrl;
+ struct pollfd pfd;
+ char buf[1];
+ int err;
+ int cmd;
+ snd_ctl_t *ctl;
+ err = read(client->ctrl.fd, buf, 1);
+ if (err != 1)
+ return -EBADFD;
+ cmd = ctrl->cmd;
+ ctrl->cmd = 0;
+ ctl = client->device.control.handle;
+ switch (cmd) {
+ case SND_CTL_IOCTL_HW_INFO:
+ ctrl->result = snd_ctl_hw_info(ctl, &ctrl->u.hw_info);
+ break;
+ case SND_CTL_IOCTL_CONTROL_LIST:
+ {
+ size_t maxsize = CTL_SHM_DATA_MAXLEN;
+ if (ctrl->u.clist.controls_request * sizeof(*ctrl->u.clist.pids) > maxsize) {
+ ctrl->result = -EFAULT;
+ break;
+ }
+ ctrl->u.clist.pids = (snd_control_id_t*) ctrl->data;
+ ctrl->result = snd_ctl_clist(ctl, &ctrl->u.clist);
+ break;
+ }
+ case SND_CTL_IOCTL_CONTROL_INFO:
+ ctrl->result = snd_ctl_cinfo(ctl, &ctrl->u.cinfo);
+ break;
+ case SND_CTL_IOCTL_CONTROL_READ:
+ ctrl->result = snd_ctl_cread(ctl, &ctrl->u.cread);
+ break;
+ case SND_CTL_IOCTL_CONTROL_WRITE:
+ ctrl->result = snd_ctl_cwrite(ctl, &ctrl->u.cwrite);
+ break;
+ case SND_CTL_IOCTL_HWDEP_INFO:
+ ctrl->result = snd_ctl_hwdep_info(ctl, &ctrl->u.hwdep_info);
+ break;
+ case SND_CTL_IOCTL_PCM_INFO:
+ ctrl->result = snd_ctl_pcm_info(ctl, &ctrl->u.pcm_info);
+ break;
+ case SND_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
+ ctrl->result = snd_ctl_pcm_prefer_subdevice(ctl, ctrl->u.pcm_prefer_subdevice);
+ break;
+ case SND_CTL_IOCTL_RAWMIDI_INFO:
+ ctrl->result = snd_ctl_rawmidi_info(ctl, &ctrl->u.rawmidi_info);
+ break;
+ case SND_CTL_IOCTL_READ:
+ ctrl->result = snd_ctl_read1(ctl, &ctrl->u.read);
+ break;
+ case SND_CTL_IOCTL_CLOSE:
+ client->ops->close(client);
+ break;
+ default:
+ fprintf(stderr, "Bogus cmd: %x\n", ctrl->cmd);
+ ctrl->result = -ENOSYS;
+ }
+ pfd.fd = client->ctrl.fd;
+ pfd.events = POLLHUP;
+ if (poll(&pfd, 1, 0) == 1)
+ return -EBADFD;
+ err = write(client->ctrl.fd, buf, 1);
+ if (err != 1)
+ return -EBADFD;
+ if (!client->polling) {
+ add_waiter(client->device.control.fd, POLLIN, ctl_handler, client);
+ client->polling = 1;
+ }
+ return 0;
+}
+
+transport_ops_t ctl_shm_ops = {
+ open: ctl_shm_open,
+ cmd: ctl_shm_cmd,
+ close: ctl_shm_close,
+};
+
+int snd_client_open(client_t *client)
{
int err;
snd_client_open_request_t req;
goto _answer;
}
break;
+ case SND_DEV_TYPE_CONTROL:
+ switch (req.transport_type) {
+ case SND_TRANSPORT_TYPE_SHM:
+ client->ops = &ctl_shm_ops;
+ break;
+ default:
+ ans.result = -EINVAL;
+ goto _answer;
+ }
+ break;
default:
ans.result = -EINVAL;
goto _answer;
if (err < 0) {
ans.result = err;
} else {
- client->state = STOPPED;
+ client->open = 1;
ans.result = client->data.fd;
}
perrno("write");
exit(1);
}
- return;
+ return 0;
+}
+
+int client_data_handler(waiter_t *waiter, unsigned short events ATTRIBUTE_UNUSED)
+{
+ client_t *client = waiter->private_data;
+ if (client->open)
+ client->ops->close(client);
+ close(client->data.fd);
+ close(client->ctrl.fd);
+ del_waiter(client->data.fd);
+ del_waiter(client->ctrl.fd);
+ list_del(&client->list);
+ free(client);
+ return 0;
+}
+
+int client_ctrl_handler(waiter_t *waiter, unsigned short events)
+{
+ client_t *client = waiter->private_data;
+ if (events & POLLHUP)
+ return client_data_handler(waiter, events);
+ if (client->open)
+ return client->ops->cmd(client);
+ else
+ return snd_client_open(client);
+}
+
+int pending_handler(waiter_t *waiter, unsigned short events)
+{
+ pending_t *pending = waiter->private_data;
+ pending_t *pdata;
+ client_t *client;
+ uint32_t cookie;
+ struct list_head *item;
+ int remove = 0;
+ if (events & POLLHUP)
+ remove = 1;
+ else {
+ int err = read(waiter->fd, &cookie, sizeof(cookie));
+ if (err != sizeof(cookie))
+ remove = 1;
+ else {
+ err = write(waiter->fd, &cookie, sizeof(cookie));
+ if (err != sizeof(cookie))
+ remove = 1;
+ }
+ }
+ del_waiter(waiter->fd);
+ if (remove) {
+ close(waiter->fd);
+ list_del(&pending->list);
+ free(pending);
+ return 0;
+ }
+
+ list_for_each(item, &pendings) {
+ pdata = list_entry(item, pending_t, list);
+ if (pdata->cookie == cookie)
+ goto found;
+ }
+ pending->cookie = cookie;
+ return 0;
+
+ found:
+ client = calloc(sizeof(*client), 1);
+ client->data.fd = pdata->fd;
+ client->data.local = pdata->local;
+ client->ctrl.fd = waiter->fd;
+ client->ctrl.local = pending->local;
+ add_waiter(client->ctrl.fd, POLLIN | POLLHUP, client_ctrl_handler, client);
+ add_waiter(client->data.fd, POLLHUP, client_data_handler, client);
+ client->open = 0;
+ list_add_tail(&client->list, &clients);
+ list_del(&pending->list);
+ list_del(&pdata->list);
+ free(pending);
+ free(pdata);
+ return 0;
+}
+
+int master_handler(waiter_t *waiter, unsigned short events ATTRIBUTE_UNUSED)
+{
+ master_t *master = waiter->private_data;
+ int sock;
+ sock = accept(waiter->fd, 0, 0);
+ if (sock < 0) {
+ int result = -errno;
+ perrno("accept");
+ return result;
+ } else {
+ pending_t *pending = calloc(sizeof(*pending), 1);
+ pending->fd = sock;
+ pending->local = master->local;
+ pending->cookie = 0;
+ add_waiter(sock, POLLIN, pending_handler, pending);
+ list_add_tail(&pending->list, &pendings);
+ }
+ return 0;
}
int server(char *sockname, int port)
{
- typedef struct {
- int fd;
- int pindex;
- int local;
- } master_t;
- master_t masters[2];
- int masters_count = 0;
- typedef struct {
- int fd;
- int pindex;
- uint32_t cookie;
- int local;
- } pending_t;
- pending_t pendings[PENDINGS_MAX];
- int pendings_count = 0;
- struct pollfd pfds[CLIENTS_MAX * 3 + 16];
- int pfds_count;
+ struct list_head *item;
int err;
- int k;
+ unsigned int k;
if (sockname) {
- int master = make_local_socket(sockname);
- if (master < 0)
- return master;
- masters[masters_count].fd = master;
- masters[masters_count].local = 1;
- masters_count++;
+ int sock = make_local_socket(sockname);
+ master_t *master;
+ if (sock < 0)
+ return sock;
+ master = calloc(sizeof(*master), 1);
+ master->fd = sock;
+ master->local = 1;
+ add_waiter(sock, POLLIN, master_handler, master);
+ list_add_tail(&master->list, &masters);
}
if (port >= 0) {
- int master = make_inet_socket(port);
- if (master < 0)
- return master;
- masters[masters_count].fd = master;
- masters[masters_count].local = 0;
- masters_count++;
+ int sock = make_inet_socket(port);
+ master_t *master;
+ if (sock < 0)
+ return sock;
+ master = calloc(sizeof(*master), 1);
+ master->fd = sock;
+ master->local = 0;
+ add_waiter(sock, POLLIN, master_handler, master);
+ list_add_tail(&master->list, &masters);
}
- if (masters_count == 0)
+ if (list_empty(&masters))
return -EINVAL;
- for (k = 0; k < masters_count; ++k) {
- master_t *master = &masters[k];
+ list_for_each(item, &masters) {
+ master_t *master = list_entry(item, master_t, list);
if (fcntl(master->fd, F_SETFL, O_NONBLOCK) < 0) {
int result = -errno;
perrno("fcntl");
}
}
- for (k = 0; k < PENDINGS_MAX; ++k) {
- pendings[k].fd = -1;
- }
-
while (1) {
- pfds_count = 0;
-
- /* Prepare to poll masters */
- if (pendings_count < PENDINGS_MAX) {
- for (k = 0; k < masters_count; ++k) {
- master_t *master = &masters[k];
- master->pindex = pfds_count;
- pfds[pfds_count].fd = master->fd;
- pfds[pfds_count].events = POLLIN;
- pfds_count++;
- }
- } else {
- for (k = 0; k < masters_count; ++k) {
- master_t *master = &masters[k];
- master->pindex = -1;
- }
- }
-
- /* Prepare to poll pendings */
- for (k = 0; k < PENDINGS_MAX; ++k) {
- pending_t *pending = &pendings[k];
- if (pending->fd < 0 ||
- pending->cookie != 0) {
- pending->pindex = -1;
- continue;
- }
- pending->pindex = pfds_count;
- pfds[pfds_count].fd = pending->fd;
- pfds[pfds_count].events = POLLHUP;
- if (pendings_count < PENDINGS_MAX &&
- clients_count < CLIENTS_MAX)
- pfds[pfds_count].events |= POLLIN;
- pfds_count++;
- }
-
- /* Prepare to poll clients */
- for (k = 0; k < clients_count; ++k) {
- client_t *client = &clients[k];
- client->data.pindex = pfds_count;
- pfds[pfds_count].fd = client->data.fd;
- pfds[pfds_count].events = POLLHUP;
- pfds_count++;
-
- client->ctrl.pindex = pfds_count;
- pfds[pfds_count].fd = client->ctrl.fd;
- pfds[pfds_count].events = POLLIN | POLLHUP;
- pfds_count++;
- }
-
- /* Prepare to poll devices */
- for (k = 0; k < clients_count; ++k) {
- client_t *client = &clients[k];
- int n;
- if (client->state == CLOSED)
- continue;
- n = client->ops->poll_prepare(client, pfds, pfds_count);
- pfds_count += n;
- }
-
-
- /* Poll */
+ struct pollfd pfds[OPEN_MAX];
+ size_t pfds_count;
do {
- err = poll(pfds, pfds_count, 1000);
+ err = poll(pollfds, pollfds_count, 1000);
} while (err == 0);
if (err < 0) {
- int result = -errno;
perrno("poll");
- return result;
+ continue;
}
- /* Handle clients events */
- for (k = clients_count - 1; k >= 0; --k) {
- client_t *client;
- struct pollfd *data_pfd = &pfds[clients[k].data.pindex];
- struct pollfd *ctrl_pfd = &pfds[clients[k].ctrl.pindex];
- if (!data_pfd->revents && !ctrl_pfd->revents)
- continue;
- client = &clients[k];
- if ((data_pfd->revents & POLLHUP) ||
- (ctrl_pfd->revents & POLLHUP)) {
- if (client->state != CLOSED) {
- client->ops->close(client);
- }
- close(client->data.fd);
- if (client->ctrl.fd >= 0)
- close(client->ctrl.fd);
- memmove(client, client + 1,
- (clients_count - k) * sizeof(client_t));
- clients_count--;
- continue;
- }
- if (ctrl_pfd->revents & POLLIN) {
- if (client->state == CLOSED)
- snd_client_open(client);
- else
- client->ops->cmd(client);
- }
- }
-
- /* Handle device events */
- for (k = 0; k < clients_count; ++k) {
- client_t *client = &clients[k];
- client->ops->poll_events(client, pfds);
- }
-
- /* Handle pending events */
- for (k = 0; k < PENDINGS_MAX; ++k) {
- struct pollfd *pfd;
- uint32_t cookie;
- int j;
- pending_t *pending = &pendings[k];
- client_t *client;
- int remove = 0;
- if (pending->pindex < 0)
- continue;
- pfd = &pfds[pending->pindex];
- if (!pfd->revents)
- continue;
- if (pfd->revents & POLLHUP)
- remove = 1;
- else {
- if (clients_count >= CLIENTS_MAX)
+ pfds_count = pollfds_count;
+ memcpy(pfds, pollfds, sizeof(*pfds) * pfds_count);
+ for (k = 0; k < pfds_count; k++) {
+ struct pollfd *pfd = &pfds[k];
+ if (pfd->revents) {
+ waiter_t *w = &waiters[pfd->fd];
+ if (!w->handler)
continue;
- err = read(pfd->fd, &cookie, sizeof(cookie));
- if (err != sizeof(cookie))
- remove = 1;
- else {
- err = write(pfd->fd, &cookie, sizeof(cookie));
- if (err != sizeof(cookie))
- remove = 1;
- }
- }
- if (remove) {
- close(pending->fd);
- pending->fd = -1;
- pendings_count--;
- continue;
- }
-
- for (j = 0; j < PENDINGS_MAX; ++j) {
- if (pendings[j].cookie == cookie)
- break;
- }
- if (j == PENDINGS_MAX) {
- pendings[k].cookie = cookie;
- continue;
- }
-
- client = &clients[clients_count];
- memset(client, 0, sizeof(*client));
- client->data.fd = pendings[j].fd;
- client->data.local = pendings[j].local;
- client->ctrl.fd = pendings[k].fd;
- client->ctrl.local = pendings[k].local;
- client->state = CLOSED;
- clients_count++;
- pendings[j].fd = -1;
- pendings[k].fd = -1;
- pendings_count -= 2;
- }
-
- /* Handle master events */
- for (k = 0; k < masters_count; ++k) {
- struct pollfd *pfd;
- master_t *master;
- int sock;
- if (pendings_count >= PENDINGS_MAX)
- break;
- master = &masters[k];
- if (master->pindex < 0)
- continue;
- pfd = &pfds[master->pindex];
- if (!pfd->revents)
- continue;
-
- sock = accept(master->fd, 0, 0);
- if (sock < 0) {
- int result = -errno;
- perrno("accept");
- return result;
- } else {
- int j;
- for (j = 0; j < PENDINGS_MAX; ++j) {
- if (pendings[j].fd < 0)
- break;
- }
- assert(j < PENDINGS_MAX);
- pendings[j].fd = sock;
- pendings[j].local = master->local;
- pendings[j].cookie = 0;
- pendings_count++;
+ err = w->handler(w, pfd->revents);
+ if (err < 0)
+ perrno("handler");
}
}
-
}
return 0;
}
EXTRA_LTLIBRARIES = libcontrol.la
-libcontrol_la_SOURCES = cards.c control.c controls.c bag.c defaults.c
+libcontrol_la_SOURCES = cards.c controls.c bag.c defaults.c \
+ control.c control_hw.c control_client.c
all: libcontrol.la
for (card = 0; card < 32; card++) {
if (snd_card_load(card) < 0)
continue;
- if (snd_ctl_open(&handle, card) < 0)
+ if (snd_ctl_hw_open(&handle, card) < 0)
continue;
if (snd_ctl_hw_info(handle, &info) < 0) {
snd_ctl_close(handle);
if (name == NULL)
return -EINVAL;
- if ((err = snd_ctl_open(&handle, card)) < 0)
+ if ((err = snd_ctl_hw_open(&handle, card)) < 0)
return err;
if ((err = snd_ctl_hw_info(handle, &info)) < 0) {
snd_ctl_close(handle);
if (name == NULL)
return -EINVAL;
- if ((err = snd_ctl_open(&handle, card)) < 0)
+ if ((err = snd_ctl_hw_open(&handle, card)) < 0)
return err;
if ((err = snd_ctl_hw_info(handle, &info)) < 0) {
snd_ctl_close(handle);
/*
* Control Interface - main file
- * Copyright (c) 1998,1999,2000 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
*
*
* This library is free software; you can redistribute it and/or modify
#include <string.h>
#include <errno.h>
#include <fcntl.h>
-#include <sys/ioctl.h>
#include <assert.h>
#include "asoundlib.h"
#include "control_local.h"
-#define SND_FILE_CONTROL "/dev/snd/controlC%i"
-#define SND_CTL_VERSION_MAX SND_PROTOCOL_VERSION(2, 0, 0)
-
-int snd_ctl_open(snd_ctl_t **handle, int card)
+snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl)
{
- int fd, ver;
- char filename[32];
- snd_ctl_t *ctl;
-
- *handle = NULL;
-
- assert(card >= 0 && card < SND_CARDS);
- sprintf(filename, SND_FILE_CONTROL, card);
- if ((fd = open(filename, O_RDWR)) < 0) {
- snd_card_load(card);
- if ((fd = open(filename, O_RDWR)) < 0)
- return -errno;
- }
-
- if (ioctl(fd, SND_CTL_IOCTL_PVERSION, &ver) < 0) {
- close(fd);
- return -errno;
- }
- if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_CTL_VERSION_MAX)) {
- close(fd);
- return -SND_ERROR_INCOMPATIBLE_VERSION;
- }
- ctl = (snd_ctl_t *) calloc(1, sizeof(snd_ctl_t));
- if (ctl == NULL) {
- close(fd);
- return -ENOMEM;
- }
- ctl->card = card;
- ctl->fd = fd;
- INIT_LIST_HEAD(&ctl->hlist);
- *handle = ctl;
- return 0;
+ return ctl->type;
}
-int snd_ctl_close(snd_ctl_t *handle)
+int snd_ctl_close(snd_ctl_t *ctl)
{
int res;
- assert(handle);
- res = close(handle->fd) < 0 ? -errno : 0;
- free(handle);
+ assert(ctl);
+ res = ctl->ops->close(ctl);
+ free(ctl);
return res;
}
-int snd_ctl_file_descriptor(snd_ctl_t *handle)
+int snd_ctl_file_descriptor(snd_ctl_t *ctl)
+{
+ assert(ctl);
+ return ctl->ops->file_descriptor(ctl);
+}
+
+int snd_ctl_hw_info(snd_ctl_t *ctl, snd_ctl_hw_info_t *info)
{
- assert(handle);
- return handle->fd;
+ assert(ctl && info);
+ return ctl->ops->hw_info(ctl, info);
}
-int snd_ctl_hw_info(snd_ctl_t *handle, snd_ctl_hw_info_t *info)
+int snd_ctl_clist(snd_ctl_t *ctl, snd_control_list_t *list)
{
- assert(handle && info);
- if (ioctl(handle->fd, SND_CTL_IOCTL_HW_INFO, info) < 0)
- return -errno;
- return 0;
+ assert(ctl && list);
+ return ctl->ops->clist(ctl, list);
}
-int snd_ctl_clist(snd_ctl_t *handle, snd_control_list_t *list)
+int snd_ctl_cinfo(snd_ctl_t *ctl, snd_control_info_t *info)
{
- assert(handle && list);
- if (ioctl(handle->fd, SND_CTL_IOCTL_CONTROL_LIST, list) < 0)
- return -errno;
- return 0;
+ assert(ctl && info && (info->id.name[0] || info->id.numid));
+ return ctl->ops->cinfo(ctl, info);
}
-int snd_ctl_cinfo(snd_ctl_t *handle, snd_control_info_t *info)
+int snd_ctl_cread(snd_ctl_t *ctl, snd_control_t *control)
{
- assert(handle && info && (info->id.name[0] || info->id.numid));
- if (ioctl(handle->fd, SND_CTL_IOCTL_CONTROL_INFO, info) < 0)
- return -errno;
- return 0;
+ assert(ctl && control && (control->id.name[0] || control->id.numid));
+ return ctl->ops->cread(ctl, control);
}
-int snd_ctl_cread(snd_ctl_t *handle, snd_control_t *control)
+int snd_ctl_cwrite(snd_ctl_t *ctl, snd_control_t *control)
{
- assert(handle && control && (control->id.name[0] || control->id.numid));
- if (ioctl(handle->fd, SND_CTL_IOCTL_CONTROL_READ, control) < 0)
- return -errno;
- return 0;
+ assert(ctl && control && (control->id.name[0] || control->id.numid));
+ return ctl->ops->cwrite(ctl, control);
}
-int snd_ctl_cwrite(snd_ctl_t *handle, snd_control_t *control)
+int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
{
- assert(handle && control && (control->id.name[0] || control->id.numid));
- if (ioctl(handle->fd, SND_CTL_IOCTL_CONTROL_WRITE, control) < 0)
- return -errno;
- return 0;
+ assert(ctl && info);
+ return ctl->ops->hwdep_info(ctl, info);
}
-int snd_ctl_hwdep_info(snd_ctl_t *handle, snd_hwdep_info_t * info)
+int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
{
- assert(handle && info);
- if (ioctl(handle->fd, SND_CTL_IOCTL_HWDEP_INFO, info) < 0)
- return -errno;
- return 0;
+ assert(ctl && info);
+ return ctl->ops->pcm_info(ctl, info);
}
-int snd_ctl_pcm_info(snd_ctl_t *handle, snd_pcm_info_t * info)
+int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev)
{
- assert(handle && info);
- if (ioctl(handle->fd, SND_CTL_IOCTL_PCM_INFO, info) < 0)
- return -errno;
- return 0;
+ assert(ctl);
+ return ctl->ops->pcm_prefer_subdevice(ctl, subdev);
}
-int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *handle, int subdev)
+int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
{
- assert(handle);
- if (ioctl(handle->fd, SND_CTL_IOCTL_PCM_PREFER_SUBDEVICE, &subdev) < 0)
- return -errno;
- return 0;
+ assert(ctl && info);
+ return ctl->ops->rawmidi_info(ctl, info);
}
-int snd_ctl_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info)
+int snd_ctl_read1(snd_ctl_t *ctl, snd_ctl_event_t *event)
{
- assert(handle && info);
- if (ioctl(handle->fd, SND_CTL_IOCTL_RAWMIDI_INFO, info) < 0)
- return -errno;
- return 0;
+ assert(ctl && event);
+ return ctl->ops->read(ctl, event);
}
-int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks)
+int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_callbacks_t * callbacks)
{
int result, count;
snd_ctl_event_t r;
- assert(handle);
+ assert(ctl);
count = 0;
- while ((result = read(handle->fd, &r, sizeof(r))) > 0) {
+ while ((result = snd_ctl_read1(ctl, &r)) > 0) {
if (result != sizeof(r))
return -EIO;
if (!callbacks)
switch (r.type) {
case SND_CTL_EVENT_REBUILD:
if (callbacks->rebuild)
- callbacks->rebuild(handle, callbacks->private_data);
+ callbacks->rebuild(ctl, callbacks->private_data);
break;
case SND_CTL_EVENT_VALUE:
if (callbacks->value)
- callbacks->value(handle, callbacks->private_data, &r.data.id);
+ callbacks->value(ctl, callbacks->private_data, &r.data.id);
break;
case SND_CTL_EVENT_CHANGE:
if (callbacks->change)
- callbacks->change(handle, callbacks->private_data, &r.data.id);
+ callbacks->change(ctl, callbacks->private_data, &r.data.id);
break;
case SND_CTL_EVENT_ADD:
if (callbacks->add)
- callbacks->add(handle, callbacks->private_data, &r.data.id);
+ callbacks->add(ctl, callbacks->private_data, &r.data.id);
break;
case SND_CTL_EVENT_REMOVE:
if (callbacks->remove)
- callbacks->remove(handle, callbacks->private_data, &r.data.id);
+ callbacks->remove(ctl, callbacks->private_data, &r.data.id);
break;
}
count++;
}
return result >= 0 ? count : -errno;
}
+
+static int _snd_ctl_open_hw(snd_ctl_t **handlep, snd_config_t *conf)
+{
+ snd_config_iterator_t i;
+ long card = -1;
+ char *str;
+ int err;
+ snd_config_foreach(i, conf) {
+ snd_config_t *n = snd_config_entry(i);
+ if (strcmp(n->id, "comment") == 0)
+ continue;
+ if (strcmp(n->id, "type") == 0)
+ continue;
+ if (strcmp(n->id, "card") == 0) {
+ err = snd_config_integer_get(n, &card);
+ if (err < 0) {
+ err = snd_config_string_get(n, &str);
+ if (err < 0)
+ return -EINVAL;
+ card = snd_card_get_index(str);
+ if (card < 0)
+ return card;
+ }
+ continue;
+ }
+ return -EINVAL;
+ }
+ if (card < 0)
+ return -EINVAL;
+ return snd_ctl_hw_open(handlep, card);
+}
+
+static int _snd_ctl_open_client(snd_ctl_t **handlep, snd_config_t *conf)
+{
+ snd_config_iterator_t i;
+ char *socket = NULL;
+ char *name = NULL;
+ char *host = NULL;
+ long port = -1;
+ int err;
+ snd_config_foreach(i, conf) {
+ snd_config_t *n = snd_config_entry(i);
+ if (strcmp(n->id, "comment") == 0)
+ continue;
+ if (strcmp(n->id, "type") == 0)
+ continue;
+ if (strcmp(n->id, "socket") == 0) {
+ err = snd_config_string_get(n, &socket);
+ if (err < 0)
+ return -EINVAL;
+ continue;
+ }
+ if (strcmp(n->id, "host") == 0) {
+ err = snd_config_string_get(n, &host);
+ if (err < 0)
+ return -EINVAL;
+ continue;
+ }
+ if (strcmp(n->id, "port") == 0) {
+ err = snd_config_integer_get(n, &port);
+ if (err < 0)
+ return -EINVAL;
+ continue;
+ }
+ if (strcmp(n->id, "name") == 0) {
+ err = snd_config_string_get(n, &name);
+ if (err < 0)
+ return -EINVAL;
+ continue;
+ }
+ return -EINVAL;
+ }
+ if (!name)
+ return -EINVAL;
+ if (socket) {
+ if (port >= 0 || host)
+ return -EINVAL;
+ return snd_ctl_client_open(handlep, socket, -1, SND_TRANSPORT_TYPE_SHM, name);
+ } else {
+ if (port < 0 || !name)
+ return -EINVAL;
+ return snd_ctl_client_open(handlep, host, port, SND_TRANSPORT_TYPE_TCP, name);
+ }
+}
+
+int snd_ctl_open(snd_ctl_t **handlep, char *name)
+{
+ char *str;
+ int err;
+ snd_config_t *ctl_conf, *conf;
+ assert(handlep && name);
+ err = snd_config_update();
+ if (err < 0)
+ return err;
+ err = snd_config_searchv(snd_config, &ctl_conf, "ctl", name, 0);
+ if (err < 0) {
+ int idx = snd_card_get_index(name);
+ if (idx < 0)
+ return idx;
+ return snd_ctl_hw_open(handlep, idx);
+ }
+ if (snd_config_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND)
+ return -EINVAL;
+ err = snd_config_search(ctl_conf, "type", &conf);
+ if (err < 0)
+ return err;
+ err = snd_config_string_get(conf, &str);
+ if (err < 0)
+ return err;
+ if (strcmp(str, "hw") == 0)
+ return _snd_ctl_open_hw(handlep, ctl_conf);
+ else if (strcmp(str, "client") == 0)
+ return _snd_ctl_open_client(handlep, ctl_conf);
+ else
+ return -EINVAL;
+}
--- /dev/null
+/*
+ * Control - Client
+ * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/shm.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/un.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include "control_local.h"
+#include "aserver.h"
+
+typedef struct {
+ int data_fd;
+ int ctrl_fd;
+ union {
+ struct {
+ void *ctrl;
+ } shm;
+ } u;
+} snd_ctl_client_t;
+
+static void clean_poll(snd_ctl_t *ctl)
+{
+ snd_ctl_client_t *client = ctl->private;
+ struct pollfd pfd;
+ int err;
+ char buf[1];
+ pfd.fd = client->data_fd;
+ pfd.events = POLLIN;
+ while (1) {
+ err = poll(&pfd, 1, 0);
+ if (err == 0)
+ break;
+ assert(err > 0);
+ err = read(client->data_fd, buf, 1);
+ assert(err == 1);
+ }
+}
+
+static int snd_ctl_client_shm_action(snd_ctl_t *ctl)
+{
+ snd_ctl_client_t *client = ctl->private;
+ int err;
+ char buf[1];
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ clean_poll(ctl);
+ err = write(client->ctrl_fd, buf, 1);
+ if (err != 1)
+ return -EBADFD;
+ err = read(client->ctrl_fd, buf, 1);
+ if (err != 1)
+ return -EBADFD;
+ if (ctrl->cmd) {
+ fprintf(stderr, "Server has not done the cmd\n");
+ return -EBADFD;
+ }
+ return 0;
+}
+
+static int snd_ctl_client_shm_close(snd_ctl_t *ctl)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int result;
+ ctrl->cmd = SND_CTL_IOCTL_CLOSE;
+ result = snd_ctl_client_shm_action(ctl);
+ if (result >= 0)
+ result = ctrl->result;
+ shmdt((void *)ctrl);
+ close(client->data_fd);
+ close(client->ctrl_fd);
+ free(client);
+ return result;
+}
+
+static int snd_ctl_client_file_descriptor(snd_ctl_t *ctl)
+{
+ snd_ctl_client_t *client = ctl->private;
+ return client->data_fd;
+}
+
+static int snd_ctl_client_shm_hw_info(snd_ctl_t *ctl, snd_ctl_hw_info_t *info)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+// ctrl->u.hw_info = *info;
+ ctrl->cmd = SND_CTL_IOCTL_HW_INFO;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *info = ctrl->u.hw_info;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_clist(snd_ctl_t *ctl, snd_control_list_t *list)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ size_t maxsize = CTL_SHM_DATA_MAXLEN;
+ size_t bytes = list->controls_request * sizeof(*list->pids);
+ int err;
+ snd_control_id_t *pids = list->pids;
+ if (bytes > maxsize)
+ return -EINVAL;
+ ctrl->u.clist = *list;
+ ctrl->cmd = SND_CTL_IOCTL_CONTROL_LIST;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *list = ctrl->u.clist;
+ list->pids = pids;
+ memcpy(pids, ctrl->data, bytes);
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_cinfo(snd_ctl_t *ctl, snd_control_info_t *info)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.cinfo = *info;
+ ctrl->cmd = SND_CTL_IOCTL_CONTROL_INFO;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *info = ctrl->u.cinfo;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_cread(snd_ctl_t *ctl, snd_control_t *control)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.cread = *control;
+ ctrl->cmd = SND_CTL_IOCTL_CONTROL_READ;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *control = ctrl->u.cread;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_cwrite(snd_ctl_t *ctl, snd_control_t *control)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.cwrite = *control;
+ ctrl->cmd = SND_CTL_IOCTL_CONTROL_WRITE;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *control = ctrl->u.cwrite;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.hwdep_info = *info;
+ ctrl->cmd = SND_CTL_IOCTL_HWDEP_INFO;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *info = ctrl->u.hwdep_info;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.pcm_info = *info;
+ ctrl->cmd = SND_CTL_IOCTL_PCM_INFO;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *info = ctrl->u.pcm_info;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.pcm_prefer_subdevice = subdev;
+ ctrl->cmd = SND_CTL_IOCTL_PCM_PREFER_SUBDEVICE;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.rawmidi_info = *info;
+ ctrl->cmd = SND_CTL_IOCTL_RAWMIDI_INFO;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *info = ctrl->u.rawmidi_info;
+ return ctrl->result;
+}
+
+static int snd_ctl_client_shm_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
+{
+ snd_ctl_client_t *client = ctl->private;
+ snd_ctl_client_shm_t *ctrl = client->u.shm.ctrl;
+ int err;
+ ctrl->u.read = *event;
+ ctrl->cmd = SND_CTL_IOCTL_READ;
+ err = snd_ctl_client_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *event = ctrl->u.read;
+ return ctrl->result;
+}
+
+struct snd_ctl_ops snd_ctl_client_ops = {
+ close: snd_ctl_client_shm_close,
+ file_descriptor: snd_ctl_client_file_descriptor,
+ hw_info: snd_ctl_client_shm_hw_info,
+ clist: snd_ctl_client_shm_clist,
+ cinfo: snd_ctl_client_shm_cinfo,
+ cread: snd_ctl_client_shm_cread,
+ cwrite: snd_ctl_client_shm_cwrite,
+ hwdep_info: snd_ctl_client_shm_hwdep_info,
+ pcm_info: snd_ctl_client_shm_pcm_info,
+ pcm_prefer_subdevice: snd_ctl_client_shm_pcm_prefer_subdevice,
+ rawmidi_info: snd_ctl_client_shm_rawmidi_info,
+ read: snd_ctl_client_shm_read,
+};
+
+static int make_local_socket(const char *filename)
+{
+ size_t l = strlen(filename);
+ size_t size = offsetof(struct sockaddr_un, sun_path) + l;
+ struct sockaddr_un *addr = alloca(size);
+ int sock;
+
+ sock = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (sock < 0)
+ return -errno;
+
+ addr->sun_family = AF_LOCAL;
+ memcpy(addr->sun_path, filename, l);
+
+ if (connect(sock, (struct sockaddr *) addr, size) < 0)
+ return -errno;
+ return sock;
+}
+
+static int make_inet_socket(const char *host, int port)
+{
+ struct sockaddr_in addr;
+ int sock;
+ struct hostent *h = gethostbyname(host);
+ if (!h)
+ return -ENOENT;
+
+ sock = socket(PF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ return -errno;
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ memcpy(&addr.sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
+
+ if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+ return -errno;
+ return sock;
+}
+
+/* port == -1 -> PF_LOCAL and host is the socket name */
+int snd_ctl_client_open(snd_ctl_t **handlep, char *host, int port, int transport, char *name)
+{
+ snd_ctl_t *ctl;
+ snd_ctl_client_t *client;
+ snd_client_open_request_t *req;
+ snd_client_open_answer_t ans;
+ size_t namelen, reqlen;
+ int err;
+ int result;
+ int fds[2] = {-1, -1};
+ int k;
+ snd_ctl_client_shm_t *ctrl = NULL;
+ uint32_t rcookie, scookie = getpid();
+ namelen = strlen(name);
+ if (namelen > 255)
+ return -EINVAL;
+
+ for (k = 0; k < 2; ++k) {
+ if (port == -1)
+ fds[k] = make_local_socket(host);
+ else
+ fds[k] = make_inet_socket(host, port);
+ if (fds[k] < 0) {
+ result = fds[k];
+ goto _err;
+ }
+ err = write(fds[k], &scookie, sizeof(scookie));
+ if (err != sizeof(scookie)) {
+ result = -EBADFD;
+ goto _err;
+ }
+ err = read(fds[k], &rcookie, sizeof(rcookie));
+ if (err != sizeof(rcookie) ||
+ rcookie != scookie) {
+ result = -EBADFD;
+ goto _err;
+ }
+ }
+
+ reqlen = sizeof(*req) + namelen;
+ req = alloca(reqlen);
+ memcpy(req->name, name, namelen);
+ req->dev_type = SND_DEV_TYPE_CONTROL;
+ req->transport_type = transport;
+ req->stream = 0;
+ req->mode = 0;
+ req->namelen = namelen;
+ err = write(fds[1], req, reqlen);
+ if (err < 0) {
+ result = -errno;
+ goto _err;
+ }
+ if ((size_t) err != reqlen) {
+ result = -EINVAL;
+ goto _err;
+ }
+ err = read(fds[1], &ans, sizeof(ans));
+ if (err < 0) {
+ result = -errno;
+ goto _err;
+ }
+ if (err != sizeof(ans)) {
+ result = -EINVAL;
+ goto _err;
+ }
+ result = ans.result;
+ if (result < 0)
+ goto _err;
+
+ switch (transport) {
+ case SND_TRANSPORT_TYPE_SHM:
+ ctrl = shmat(ans.cookie, 0, 0);
+ if (!ctrl) {
+ result = -errno;
+ goto _err;
+ }
+ break;
+ default:
+ result = -ENOSYS;
+ goto _err;
+ }
+
+ ctl = calloc(1, sizeof(snd_ctl_t));
+ if (!ctl) {
+ result = -ENOMEM;
+ goto _err;
+ }
+ client = calloc(1, sizeof(snd_ctl_client_t));
+ if (!ctl) {
+ free(ctl);
+ result = -ENOMEM;
+ goto _err;
+ }
+
+ client->data_fd = fds[0];
+ client->ctrl_fd = fds[1];
+ switch (transport) {
+ case SND_TRANSPORT_TYPE_SHM:
+ client->u.shm.ctrl = ctrl;
+ break;
+ }
+ ctl->type = SND_CTL_TYPE_CLIENT;
+ ctl->ops = &snd_ctl_client_ops;
+ ctl->private = client;
+ INIT_LIST_HEAD(&ctl->hlist);
+ *handlep = ctl;
+ return 0;
+
+ _err:
+ if (fds[0] >= 0)
+ close(fds[0]);
+ if (fds[1] >= 0)
+ close(fds[1]);
+ switch (transport) {
+ case SND_TRANSPORT_TYPE_SHM:
+ if (ctrl)
+ shmdt(ctrl);
+ break;
+ }
+ return result;
+}
+
--- /dev/null
+/*
+ * Control Interface - Hardware
+ * Copyright (c) 1998,1999,2000 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#include "asoundlib.h"
+#include "control_local.h"
+
+#define SND_FILE_CONTROL "/dev/snd/controlC%i"
+#define SND_CTL_VERSION_MAX SND_PROTOCOL_VERSION(2, 0, 0)
+
+typedef struct {
+ int card;
+ int fd;
+} snd_ctl_hw_t;
+
+static int snd_ctl_hw_close(snd_ctl_t *handle)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ int res;
+ res = close(hw->fd) < 0 ? -errno : 0;
+ free(hw);
+ return res;
+}
+
+static int snd_ctl_hw_file_descriptor(snd_ctl_t *handle)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ return hw->fd;
+}
+
+static int snd_ctl_hw_hw_info(snd_ctl_t *handle, snd_ctl_hw_info_t *info)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_HW_INFO, info) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_clist(snd_ctl_t *handle, snd_control_list_t *list)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_CONTROL_LIST, list) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_cinfo(snd_ctl_t *handle, snd_control_info_t *info)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_CONTROL_INFO, info) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_cread(snd_ctl_t *handle, snd_control_t *control)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_CONTROL_READ, control) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_cwrite(snd_ctl_t *handle, snd_control_t *control)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_CONTROL_WRITE, control) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_hwdep_info(snd_ctl_t *handle, snd_hwdep_info_t * info)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_HWDEP_INFO, info) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_pcm_info(snd_ctl_t *handle, snd_pcm_info_t * info)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_PCM_INFO, info) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_pcm_prefer_subdevice(snd_ctl_t *handle, int subdev)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_PCM_PREFER_SUBDEVICE, &subdev) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_RAWMIDI_INFO, info) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_ctl_hw_read(snd_ctl_t *handle, snd_ctl_event_t *event)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ return read(hw->fd, event, sizeof(*event));
+}
+
+struct snd_ctl_ops snd_ctl_hw_ops = {
+ close: snd_ctl_hw_close,
+ file_descriptor: snd_ctl_hw_file_descriptor,
+ hw_info: snd_ctl_hw_hw_info,
+ clist: snd_ctl_hw_clist,
+ cinfo: snd_ctl_hw_cinfo,
+ cread: snd_ctl_hw_cread,
+ cwrite: snd_ctl_hw_cwrite,
+ hwdep_info: snd_ctl_hw_hwdep_info,
+ pcm_info: snd_ctl_hw_pcm_info,
+ pcm_prefer_subdevice: snd_ctl_hw_pcm_prefer_subdevice,
+ rawmidi_info: snd_ctl_hw_rawmidi_info,
+ read: snd_ctl_hw_read,
+};
+
+int snd_ctl_hw_open(snd_ctl_t **handle, int card)
+{
+ int fd, ver;
+ char filename[32];
+ snd_ctl_t *ctl;
+ snd_ctl_hw_t *hw;
+
+ *handle = NULL;
+
+ assert(card >= 0 && card < SND_CARDS);
+ sprintf(filename, SND_FILE_CONTROL, card);
+ if ((fd = open(filename, O_RDWR)) < 0) {
+ snd_card_load(card);
+ if ((fd = open(filename, O_RDWR)) < 0)
+ return -errno;
+ }
+
+ if (ioctl(fd, SND_CTL_IOCTL_PVERSION, &ver) < 0) {
+ close(fd);
+ return -errno;
+ }
+ if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_CTL_VERSION_MAX)) {
+ close(fd);
+ return -SND_ERROR_INCOMPATIBLE_VERSION;
+ }
+ ctl = calloc(1, sizeof(snd_ctl_t));
+ if (ctl == NULL) {
+ close(fd);
+ return -ENOMEM;
+ }
+ hw = calloc(1, sizeof(snd_ctl_hw_t));
+ if (hw == NULL) {
+ close(fd);
+ free(ctl);
+ return -ENOMEM;
+ }
+ hw->card = card;
+ hw->fd = fd;
+ ctl->ops = &snd_ctl_hw_ops;
+ ctl->private = hw;
+ INIT_LIST_HEAD(&ctl->hlist);
+ *handle = ctl;
+ return 0;
+}
+
*
*/
+#include <assert.h>
+#include "asoundlib.h"
#include "list.h"
+struct snd_ctl_ops {
+ int (*close)(snd_ctl_t *handle);
+ int (*file_descriptor)(snd_ctl_t *handle);
+ int (*hw_info)(snd_ctl_t *handle, snd_ctl_hw_info_t *info);
+ int (*clist)(snd_ctl_t *handle, snd_control_list_t *list);
+ int (*cinfo)(snd_ctl_t *handle, snd_control_info_t *info);
+ int (*cread)(snd_ctl_t *handle, snd_control_t *control);
+ int (*cwrite)(snd_ctl_t *handle, snd_control_t *control);
+ int (*hwdep_info)(snd_ctl_t *handle, snd_hwdep_info_t * info);
+ int (*pcm_info)(snd_ctl_t *handle, snd_pcm_info_t * info);
+ int (*pcm_prefer_subdevice)(snd_ctl_t *handle, int subdev);
+ int (*rawmidi_info)(snd_ctl_t *handle, snd_rawmidi_info_t * info);
+ int (*read)(snd_ctl_t *handle, snd_ctl_event_t *event);
+};
+
+
struct snd_ctl {
- int card;
- int fd;
+ snd_ctl_type_t type;
+ struct snd_ctl_ops *ops;
+ void *private;
int hcount;
int herr;
struct list_head hlist; /* list of all controls */
static void snd_mixer_simple_read_rebuild(snd_ctl_t *ctl_handle, void *private_data);
static void snd_mixer_simple_read_add(snd_ctl_t *ctl_handle, void *private_data, snd_hcontrol_t *hcontrol);
-int snd_mixer_open(snd_mixer_t **r_handle, int card)
+int snd_mixer_open(snd_mixer_t **r_handle, char *name)
{
snd_mixer_t *handle;
snd_ctl_t *ctl_handle;
if (r_handle == NULL)
return -EINVAL;
*r_handle = NULL;
- if ((err = snd_ctl_open(&ctl_handle, card)) < 0)
+ if ((err = snd_ctl_open(&ctl_handle, name)) < 0)
return err;
handle = (snd_mixer_t *) calloc(1, sizeof(snd_mixer_t));
if (handle == NULL) {
} else {
if (port < 0 || !name)
return -EINVAL;
- return snd_pcm_client_create(handlep, host, port, SND_TRANSPORT_TYPE_SHM, name, stream, mode);
+ return snd_pcm_client_create(handlep, host, port, SND_TRANSPORT_TYPE_TCP, name, stream, mode);
}
}
#include "aserver.h"
typedef struct {
- snd_pcm_t *handle;
int data_fd;
int ctrl_fd;
union {
return ret;
}
-static void clean_state(snd_pcm_client_t *client)
+static void clean_poll(snd_pcm_t *pcm)
{
+ snd_pcm_client_t *client = pcm->private;
struct pollfd pfd;
int err;
char buf[1];
pfd.fd = client->data_fd;
- switch (client->handle->stream) {
+ switch (pcm->stream) {
case SND_PCM_STREAM_PLAYBACK:
pfd.events = POLLOUT;
while (1) {
}
}
-static int snd_pcm_client_shm_action(snd_pcm_client_t *client)
+static int snd_pcm_client_shm_action(snd_pcm_t *pcm)
{
+ snd_pcm_client_t *client = pcm->private;
int err;
char buf[1];
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
+ clean_poll(pcm);
err = write(client->ctrl_fd, buf, 1);
if (err != 1)
return -EBADFD;
return 0;
}
-static int snd_pcm_client_shm_action_fd(snd_pcm_client_t *client)
+static int snd_pcm_client_shm_action_fd(snd_pcm_t *pcm)
{
+ snd_pcm_client_t *client = pcm->private;
int err;
char buf[1];
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int fd;
+ clean_poll(pcm);
err = write(client->ctrl_fd, buf, 1);
if (err != 1)
return -EBADFD;
return fd;
}
-static int snd_pcm_client_shm_close(void *private)
+static int snd_pcm_client_shm_close(snd_pcm_t *pcm)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int result;
ctrl->cmd = SND_PCM_IOCTL_CLOSE;
- result = snd_pcm_client_shm_action(client);
+ result = snd_pcm_client_shm_action(pcm);
if (result >= 0)
result = ctrl->result;
shmdt((void *)ctrl);
close(client->data_fd);
close(client->ctrl_fd);
+ free(client);
return result;
}
-static int snd_pcm_client_shm_nonblock(void *private, int nonblock)
+static int snd_pcm_client_shm_nonblock(snd_pcm_t *pcm, int nonblock)
{
/* FIXME */
return 0;
}
-static int snd_pcm_client_shm_info(void *private, snd_pcm_info_t * info)
+static int snd_pcm_client_shm_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
// ctrl->u.info = *info;
ctrl->cmd = SND_PCM_IOCTL_INFO;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
- memcpy(info, &ctrl->u.info, sizeof(*info));
+ *info = ctrl->u.info;
return ctrl->result;
}
-static int snd_pcm_client_shm_params_info(void *private, snd_pcm_params_info_t * info)
+static int snd_pcm_client_shm_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t * info)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_PARAMS_INFO;
ctrl->u.params_info = *info;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
*info = ctrl->u.params_info;
return ctrl->result;
}
-static int snd_pcm_client_shm_params(void *private, snd_pcm_params_t * params)
+static int snd_pcm_client_shm_params(snd_pcm_t *pcm, snd_pcm_params_t * params)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_PARAMS;
ctrl->u.params = *params;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
*params = ctrl->u.params;
return ctrl->result;
}
-static int snd_pcm_client_shm_setup(void *private, snd_pcm_setup_t * setup)
+static int snd_pcm_client_shm_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_SETUP;
// ctrl->u.setup = *setup;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
*setup = ctrl->u.setup;
return ctrl->result;
}
-static int snd_pcm_client_shm_channel_info(void *private, snd_pcm_channel_info_t * info)
+static int snd_pcm_client_shm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_CHANNEL_INFO;
ctrl->u.channel_info = *info;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
*info = ctrl->u.channel_info;
return ctrl->result;
}
-static int snd_pcm_client_shm_channel_params(void *private, snd_pcm_channel_params_t * params)
+static int snd_pcm_client_shm_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_CHANNEL_PARAMS;
ctrl->u.channel_params = *params;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
*params = ctrl->u.channel_params;
return ctrl->result;
}
-static int snd_pcm_client_shm_channel_setup(void *private, snd_pcm_channel_setup_t * setup)
+static int snd_pcm_client_shm_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_CHANNEL_SETUP;
ctrl->u.channel_setup = *setup;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
*setup = ctrl->u.channel_setup;
return ctrl->result;
}
-static int snd_pcm_client_shm_status(void *private, snd_pcm_status_t * status)
+static int snd_pcm_client_shm_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_STATUS;
// ctrl->u.status = *status;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
*status = ctrl->u.status;
return ctrl->result;
}
-static int snd_pcm_client_shm_state(void *private)
+static int snd_pcm_client_shm_state(snd_pcm_t *pcm)
{
snd_pcm_status_t status;
- int err = snd_pcm_client_shm_status(private, &status);
+ int err = snd_pcm_client_shm_status(pcm, &status);
if (err < 0)
return err;
return status.state;
}
-static ssize_t snd_pcm_client_shm_frame_io(void *private, int update)
+static ssize_t snd_pcm_client_shm_frame_io(snd_pcm_t *pcm, int update)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_FRAME_IO;
ctrl->u.frame_io = update;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static int snd_pcm_client_shm_prepare(void *private)
+static int snd_pcm_client_shm_prepare(snd_pcm_t *pcm)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_PREPARE;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static int snd_pcm_client_shm_go(void *private)
+static int snd_pcm_client_shm_go(snd_pcm_t *pcm)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_GO;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static int snd_pcm_client_shm_drain(void *private)
+static int snd_pcm_client_shm_drain(snd_pcm_t *pcm)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_DRAIN;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static int snd_pcm_client_shm_flush(void *private)
+static int snd_pcm_client_shm_flush(snd_pcm_t *pcm)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_FLUSH;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static int snd_pcm_client_shm_pause(void *private, int enable)
+static int snd_pcm_client_shm_pause(snd_pcm_t *pcm, int enable)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_PAUSE;
ctrl->u.pause = enable;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static ssize_t snd_pcm_client_shm_frame_data(void *private, off_t offset)
+static ssize_t snd_pcm_client_shm_frame_data(snd_pcm_t *pcm, off_t offset)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_FRAME_DATA;
ctrl->u.frame_data = offset;
- clean_state(client);
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static ssize_t snd_pcm_client_shm_write(void *private, snd_timestamp_t *tstamp, const void *buffer, size_t size)
+static ssize_t snd_pcm_client_shm_write(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const void *buffer, size_t size)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
size_t maxsize = PCM_SHM_DATA_MAXLEN;
- size_t bytes = snd_pcm_frames_to_bytes(client->handle, size);
+ size_t bytes = snd_pcm_frames_to_bytes(pcm, size);
int err;
if (bytes > maxsize)
return -EINVAL;
// ctrl->u.write.tstamp = *tstamp;
ctrl->u.write.count = size;
memcpy(ctrl->data, buffer, bytes);
- clean_state(client);
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static ssize_t snd_pcm_client_shm_writev(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
+static ssize_t snd_pcm_client_shm_writev(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
{
/* FIXME: interleaved */
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
size_t vecsize = count * sizeof(struct iovec);
size_t maxsize = PCM_SHM_DATA_MAXLEN;
- int bits_per_sample = client->handle->bits_per_sample;
+ int bits_per_sample = pcm->bits_per_sample;
char *base;
struct iovec *vec;
unsigned long k;
vec[k].iov_base = (void *) ofs;
ofs += len;
}
- clean_state(client);
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
}
-static ssize_t snd_pcm_client_shm_read(void *private, snd_timestamp_t *tstamp, void *buffer, size_t size)
+static ssize_t snd_pcm_client_shm_read(snd_pcm_t *pcm, snd_timestamp_t *tstamp, void *buffer, size_t size)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
size_t maxsize = PCM_SHM_DATA_MAXLEN;
- size_t bytes = snd_pcm_frames_to_bytes(client->handle, size);
+ size_t bytes = snd_pcm_frames_to_bytes(pcm, size);
int err;
if (bytes > maxsize)
return -EINVAL;
ctrl->cmd = SND_PCM_IOCTL_READ_FRAMES;
// ctrl->u.read.tstamp = *tstamp;
ctrl->u.read.count = size;
- clean_state(client);
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
if (ctrl->result <= 0)
return ctrl->result;
- bytes = snd_pcm_frames_to_bytes(client->handle, ctrl->result);
+ bytes = snd_pcm_frames_to_bytes(pcm, ctrl->result);
memcpy(buffer, ctrl->data, bytes);
return ctrl->result;
}
-ssize_t snd_pcm_client_shm_readv(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
+ssize_t snd_pcm_client_shm_readv(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
{
/* FIXME: interleaved */
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
size_t vecsize = count * sizeof(struct iovec);
size_t maxsize = PCM_SHM_DATA_MAXLEN;
- int bits_per_sample = client->handle->bits_per_sample;
+ int bits_per_sample = pcm->bits_per_sample;
char *base;
struct iovec *vec;
unsigned long k;
vec[k].iov_base = (void *) ofs;
ofs += len;
}
- clean_state(client);
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
if (ctrl->result <= 0)
return ctrl->result;
- bytes = snd_pcm_frames_to_bytes(client->handle, ctrl->result);
+ bytes = snd_pcm_frames_to_bytes(pcm, ctrl->result);
ofs = 0;
for (k = 0; k < count; ++k) {
/* FIXME: optimize partial read */
return ctrl->result;
}
-static int snd_pcm_client_shm_mmap_status(void *private, snd_pcm_mmap_status_t **status)
+static int snd_pcm_client_shm_mmap_status(snd_pcm_t *pcm, snd_pcm_mmap_status_t **status)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
void *ptr;
int fd;
ctrl->cmd = SND_PCM_IOCTL_MMAP_STATUS;
- fd = snd_pcm_client_shm_action_fd(client);
+ fd = snd_pcm_client_shm_action_fd(pcm);
if (fd < 0)
return fd;
ptr = mmap(NULL, sizeof(snd_pcm_mmap_status_t), PROT_READ, MAP_FILE|MAP_SHARED,
return 0;
}
-static int snd_pcm_client_shm_mmap_control(void *private, snd_pcm_mmap_control_t **control)
+static int snd_pcm_client_shm_mmap_control(snd_pcm_t *pcm, snd_pcm_mmap_control_t **control)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
void *ptr;
int fd;
ctrl->cmd = SND_PCM_IOCTL_MMAP_CONTROL;
- fd = snd_pcm_client_shm_action_fd(client);
+ fd = snd_pcm_client_shm_action_fd(pcm);
if (fd < 0)
return fd;
ptr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
return 0;
}
-static int snd_pcm_client_shm_mmap_data(void *private, void **buffer, size_t bsize ATTRIBUTE_UNUSED)
+static int snd_pcm_client_shm_mmap_data(snd_pcm_t *pcm, void **buffer, size_t bsize ATTRIBUTE_UNUSED)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
void *ptr;
int prot;
int fd;
ctrl->cmd = SND_PCM_IOCTL_MMAP_DATA;
- fd = snd_pcm_client_shm_action_fd(client);
+ fd = snd_pcm_client_shm_action_fd(pcm);
if (fd < 0)
return fd;
- prot = client->handle->stream == SND_PCM_STREAM_PLAYBACK ? PROT_WRITE : PROT_READ;
+ prot = pcm->stream == SND_PCM_STREAM_PLAYBACK ? PROT_WRITE : PROT_READ;
ptr = mmap(NULL, bsize, prot, MAP_FILE|MAP_SHARED,
fd, SND_PCM_MMAP_OFFSET_DATA);
close(fd);
return 0;
}
-static int snd_pcm_client_shm_munmap_status(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t *status ATTRIBUTE_UNUSED)
+static int snd_pcm_client_shm_munmap_status(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t *status ATTRIBUTE_UNUSED)
{
#if 0
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_MUNMAP_STATUS;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
#endif
}
-static int snd_pcm_client_shm_munmap_control(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t *control ATTRIBUTE_UNUSED)
+static int snd_pcm_client_shm_munmap_control(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t *control ATTRIBUTE_UNUSED)
{
#if 0
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_MUNMAP_CONTROL;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
#endif
}
-static int snd_pcm_client_shm_munmap_data(void *private ATTRIBUTE_UNUSED, void *buffer, size_t bsize)
+static int snd_pcm_client_shm_munmap_data(snd_pcm_t *pcm ATTRIBUTE_UNUSED, void *buffer, size_t bsize)
{
#if 0
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
int err;
ctrl->cmd = SND_PCM_IOCTL_MUNMAP_DATA;
- err = snd_pcm_client_shm_action(client);
+ err = snd_pcm_client_shm_action(pcm);
if (err < 0)
return err;
return ctrl->result;
#endif
}
-static int snd_pcm_client_file_descriptor(void *private)
+static int snd_pcm_client_file_descriptor(snd_pcm_t *pcm)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
+ snd_pcm_client_t *client = pcm->private;
return client->data_fd;
}
-static int snd_pcm_client_channels_mask(void *private ATTRIBUTE_UNUSED,
+static int snd_pcm_client_channels_mask(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
bitset_t *client_vmask ATTRIBUTE_UNUSED)
{
return 0;
}
-static void snd_pcm_client_dump(void *private, FILE *fp)
+static void snd_pcm_client_dump(snd_pcm_t *pcm, FILE *fp)
{
- snd_pcm_client_t *client = (snd_pcm_client_t*) private;
- snd_pcm_t *handle = client->handle;
fprintf(fp, "Client PCM\n");
- if (handle->valid_setup) {
+ if (pcm->valid_setup) {
fprintf(fp, "\nIts setup is:\n");
- snd_pcm_dump_setup(handle, fp);
+ snd_pcm_dump_setup(pcm, fp);
}
}
goto _err;
}
- client->handle = handle;
client->data_fd = fds[0];
client->ctrl_fd = fds[1];
switch (transport) {
handle->type = SND_PCM_TYPE_CLIENT;
handle->stream = stream;
handle->ops = &snd_pcm_client_ops;
- handle->op_arg = client;
+ handle->op_arg = handle;
handle->fast_ops = &snd_pcm_client_fast_ops;
- handle->fast_op_arg = client;
+ handle->fast_op_arg = handle;
handle->mode = mode;
handle->private = client;
*handlep = handle;
#include "pcm_local.h"
typedef struct {
- snd_pcm_t *handle;
int fd;
int card, device, subdevice;
void *mmap_data_ptr;
#define SND_FILE_PCM_STREAM_CAPTURE "/dev/snd/pcmC%iD%ic"
#define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION(2, 0, 0)
-static int snd_pcm_hw_close(void *private)
+static int snd_pcm_hw_close(snd_pcm_t *pcm)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
- free(private);
+ free(hw);
if (fd >= 0)
if (close(fd))
return -errno;
return 0;
}
-static int snd_pcm_hw_nonblock(void *private, int nonblock)
+static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
{
long flags;
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if ((flags = fcntl(fd, F_GETFL)) < 0)
return 0;
}
-static int snd_pcm_hw_info(void *private, snd_pcm_info_t * info)
+static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_INFO, info) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_params_info(void *private, snd_pcm_params_info_t * info)
+static int snd_pcm_hw_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t * info)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_PARAMS_INFO, info) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_params(void *private, snd_pcm_params_t * params)
+static int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_params_t * params)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_PARAMS, params) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_setup(void *private, snd_pcm_setup_t * setup)
+static int snd_pcm_hw_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_SETUP, setup) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_channel_info(void *private, snd_pcm_channel_info_t * info)
+static int snd_pcm_hw_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, info) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_channel_params(void *private, snd_pcm_channel_params_t * params)
+static int snd_pcm_hw_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PARAMS, params) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_channel_setup(void *private, snd_pcm_channel_setup_t * setup)
+static int snd_pcm_hw_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_status(void *private, snd_pcm_status_t * status)
+static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_STATUS, status) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_state(void *private)
+static int snd_pcm_hw_state(snd_pcm_t *pcm)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_pcm_status_t status;
if (ioctl(fd, SND_PCM_IOCTL_STATUS, status) < 0)
return status.state;
}
-static ssize_t snd_pcm_hw_frame_io(void *private, int update ATTRIBUTE_UNUSED)
+static ssize_t snd_pcm_hw_frame_io(snd_pcm_t *pcm, int update ATTRIBUTE_UNUSED)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
ssize_t pos = ioctl(fd, SND_PCM_IOCTL_FRAME_IO);
if (pos < 0)
return pos;
}
-static int snd_pcm_hw_prepare(void *private)
+static int snd_pcm_hw_prepare(snd_pcm_t *pcm)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_PREPARE) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_go(void *private)
+static int snd_pcm_hw_go(snd_pcm_t *pcm)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_GO) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_drain(void *private)
+static int snd_pcm_hw_drain(snd_pcm_t *pcm)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_DRAIN) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_flush(void *private)
+static int snd_pcm_hw_flush(snd_pcm_t *pcm)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_FLUSH) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_pause(void *private, int enable)
+static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
if (ioctl(fd, SND_PCM_IOCTL_PAUSE, enable) < 0)
return -errno;
return 0;
}
-static ssize_t snd_pcm_hw_frame_data(void *private, off_t offset)
+static ssize_t snd_pcm_hw_frame_data(snd_pcm_t *pcm, off_t offset)
{
ssize_t result;
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
- snd_pcm_t *handle = hw->handle;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
- if (handle->mmap_status && handle->mmap_control)
- return snd_pcm_mmap_frame_data(handle, offset);
+ if (pcm->mmap_status && pcm->mmap_control)
+ return snd_pcm_mmap_frame_data(pcm, offset);
result = ioctl(fd, SND_PCM_IOCTL_FRAME_DATA, offset);
if (result < 0)
return -errno;
return result;
}
-static ssize_t snd_pcm_hw_write(void *private, snd_timestamp_t *tstamp, const void *buffer, size_t size)
+static ssize_t snd_pcm_hw_write(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const void *buffer, size_t size)
{
ssize_t result;
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xfer_t xfer;
if (tstamp)
return result;
}
-static ssize_t snd_pcm_hw_writev(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
+static ssize_t snd_pcm_hw_writev(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
{
ssize_t result;
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xferv_t xferv;
if (tstamp)
return result;
}
-static ssize_t snd_pcm_hw_read(void *private, snd_timestamp_t *tstamp, void *buffer, size_t size)
+static ssize_t snd_pcm_hw_read(snd_pcm_t *pcm, snd_timestamp_t *tstamp, void *buffer, size_t size)
{
ssize_t result;
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xfer_t xfer;
if (tstamp)
return result;
}
-ssize_t snd_pcm_hw_readv(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
+ssize_t snd_pcm_hw_readv(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
{
ssize_t result;
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xferv_t xferv;
if (tstamp)
return result;
}
-static int snd_pcm_hw_mmap_status(void *private, snd_pcm_mmap_status_t **status)
+static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm, snd_pcm_mmap_status_t **status)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
void *ptr;
ptr = mmap(NULL, sizeof(snd_pcm_mmap_status_t), PROT_READ, MAP_FILE|MAP_SHARED,
hw->fd, SND_PCM_MMAP_OFFSET_STATUS);
return 0;
}
-static int snd_pcm_hw_mmap_control(void *private, snd_pcm_mmap_control_t **control)
+static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm, snd_pcm_mmap_control_t **control)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
void *ptr;
ptr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
hw->fd, SND_PCM_MMAP_OFFSET_CONTROL);
return 0;
}
-static int snd_pcm_hw_mmap_data(void *private, void **buffer, size_t bsize)
+static int snd_pcm_hw_mmap_data(snd_pcm_t *pcm, void **buffer, size_t bsize)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
void *ptr;
int prot;
- prot = hw->handle->stream == SND_PCM_STREAM_PLAYBACK ? PROT_WRITE : PROT_READ;
+ prot = pcm->stream == SND_PCM_STREAM_PLAYBACK ? PROT_WRITE : PROT_READ;
ptr = mmap(NULL, bsize, prot, MAP_FILE|MAP_SHARED,
hw->fd, SND_PCM_MMAP_OFFSET_DATA);
if (ptr == MAP_FAILED || ptr == NULL)
return 0;
}
-static int snd_pcm_hw_munmap_status(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t *status)
+static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t *status)
{
if (munmap(status, sizeof(*status)) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_munmap_control(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t *control)
+static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t *control)
{
if (munmap(control, sizeof(*control)) < 0)
return -errno;
return 0;
}
-static int snd_pcm_hw_munmap_data(void *private, void *buffer, size_t bsize)
+static int snd_pcm_hw_munmap_data(snd_pcm_t *pcm, void *buffer, size_t bsize)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
if (munmap(buffer, bsize) < 0)
return -errno;
hw->mmap_data_ptr = NULL;
return 0;
}
-static int snd_pcm_hw_file_descriptor(void *private)
+static int snd_pcm_hw_file_descriptor(snd_pcm_t *pcm)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
+ snd_pcm_hw_t *hw = pcm->private;
return hw->fd;
}
-static int snd_pcm_hw_channels_mask(void *private ATTRIBUTE_UNUSED,
+static int snd_pcm_hw_channels_mask(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
bitset_t *client_vmask ATTRIBUTE_UNUSED)
{
return 0;
}
-static void snd_pcm_hw_dump(void *private, FILE *fp)
+static void snd_pcm_hw_dump(snd_pcm_t *pcm, FILE *fp)
{
- snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
- snd_pcm_t *handle = hw->handle;
+ snd_pcm_hw_t *hw = pcm->private;
char *name = "Unknown";
snd_card_get_name(hw->card, &name);
fprintf(fp, "Hardware PCM card %d '%s' device %d subdevice %d\n",
hw->card, name, hw->device, hw->subdevice);
free(name);
- if (handle->valid_setup) {
+ if (pcm->valid_setup) {
fprintf(fp, "\nIts setup is:\n");
- snd_pcm_dump_setup(handle, fp);
+ snd_pcm_dump_setup(pcm, fp);
}
}
assert(handlep);
*handlep = 0;
- if ((ret = snd_ctl_open(&ctl, card)) < 0)
+ if ((ret = snd_ctl_hw_open(&ctl, card)) < 0)
return ret;
switch (stream) {
ret = -ENOMEM;
goto __end;
}
- hw->handle = handle;
hw->card = card;
hw->device = device;
hw->subdevice = subdevice;
handle->type = SND_PCM_TYPE_HW;
handle->stream = stream;
handle->ops = &snd_pcm_hw_ops;
- handle->op_arg = hw;
+ handle->op_arg = handle;
handle->fast_ops = &snd_pcm_hw_fast_ops;
- handle->fast_op_arg = hw;
+ handle->fast_op_arg = handle;
handle->mode = mode;
handle->private = hw;
*handlep = handle;
#include "asoundlib.h"
struct snd_pcm_ops {
- int (*close)(void *private);
- int (*info)(void *private, snd_pcm_info_t *info);
- int (*params_info)(void *private, snd_pcm_params_info_t *info);
- int (*params)(void *private, snd_pcm_params_t *params);
- int (*setup)(void *private, snd_pcm_setup_t *setup);
- void (*dump)(void *private, FILE *fp);
+ int (*close)(snd_pcm_t *pcm);
+ int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
+ int (*params_info)(snd_pcm_t *pcm, snd_pcm_params_info_t *info);
+ int (*params)(snd_pcm_t *pcm, snd_pcm_params_t *params);
+ int (*setup)(snd_pcm_t *pcm, snd_pcm_setup_t *setup);
+ void (*dump)(snd_pcm_t *pcm, FILE *fp);
};
struct snd_pcm_fast_ops {
- int (*nonblock)(void *private, int nonblock);
- int (*status)(void *private, snd_pcm_status_t *status);
- int (*channel_info)(void *private, snd_pcm_channel_info_t *info);
- int (*channel_params)(void *private, snd_pcm_channel_params_t *params);
- int (*channel_setup)(void *private, snd_pcm_channel_setup_t *setup);
- int (*prepare)(void *private);
- int (*go)(void *private);
- int (*drain)(void *private);
- int (*flush)(void *private);
- int (*pause)(void *private, int enable);
- int (*state)(void *private);
- ssize_t (*frame_io)(void *private, int update);
- ssize_t (*frame_data)(void *private, off_t offset);
- ssize_t (*write)(void *private, snd_timestamp_t *tstamp, const void *buffer, size_t size);
- ssize_t (*writev)(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count);
- ssize_t (*read)(void *private, snd_timestamp_t *tstamp, void *buffer, size_t size);
- ssize_t (*readv)(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count);
- int (*file_descriptor)(void *private);
- int (*channels_mask)(void *private, bitset_t *client_vmask);
- int (*mmap_status)(void *private, snd_pcm_mmap_status_t **status);
- int (*mmap_control)(void *private, snd_pcm_mmap_control_t **control);
- int (*mmap_data)(void *private, void **buffer, size_t bsize);
- int (*munmap_status)(void *private, snd_pcm_mmap_status_t *status);
- int (*munmap_control)(void *private, snd_pcm_mmap_control_t *control);
- int (*munmap_data)(void *private, void *buffer, size_t bsize);
+ int (*nonblock)(snd_pcm_t *pcm, int nonblock);
+ int (*status)(snd_pcm_t *pcm, snd_pcm_status_t *status);
+ int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
+ int (*channel_params)(snd_pcm_t *pcm, snd_pcm_channel_params_t *params);
+ int (*channel_setup)(snd_pcm_t *pcm, snd_pcm_channel_setup_t *setup);
+ int (*prepare)(snd_pcm_t *pcm);
+ int (*go)(snd_pcm_t *pcm);
+ int (*drain)(snd_pcm_t *pcm);
+ int (*flush)(snd_pcm_t *pcm);
+ int (*pause)(snd_pcm_t *pcm, int enable);
+ int (*state)(snd_pcm_t *pcm);
+ ssize_t (*frame_io)(snd_pcm_t *pcm, int update);
+ ssize_t (*frame_data)(snd_pcm_t *pcm, off_t offset);
+ ssize_t (*write)(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const void *buffer, size_t size);
+ ssize_t (*writev)(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count);
+ ssize_t (*read)(snd_pcm_t *pcm, snd_timestamp_t *tstamp, void *buffer, size_t size);
+ ssize_t (*readv)(snd_pcm_t *pcm, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count);
+ int (*file_descriptor)(snd_pcm_t *pcm);
+ int (*channels_mask)(snd_pcm_t *pcm, bitset_t *client_vmask);
+ int (*mmap_status)(snd_pcm_t *pcm, snd_pcm_mmap_status_t **status);
+ int (*mmap_control)(snd_pcm_t *pcm, snd_pcm_mmap_control_t **control);
+ int (*mmap_data)(snd_pcm_t *pcm, void **buffer, size_t bsize);
+ int (*munmap_status)(snd_pcm_t *pcm, snd_pcm_mmap_status_t *status);
+ int (*munmap_control)(snd_pcm_t *pcm, snd_pcm_mmap_control_t *control);
+ int (*munmap_data)(snd_pcm_t *pcm, void *buffer, size_t bsize);
};
struct snd_pcm {
char *mmap_data;
enum { _INTERLEAVED, _NONINTERLEAVED, _COMPLEX } mmap_type;
struct snd_pcm_ops *ops;
- void *op_arg;
struct snd_pcm_fast_ops *fast_ops;
- void *fast_op_arg;
+ snd_pcm_t *op_arg;
+ snd_pcm_t *fast_op_arg;
void *private;
};
} snd_pcm_multi_bind_t;
typedef struct {
- snd_pcm_t *handle;
size_t slaves_count;
snd_pcm_multi_slave_t *slaves;
size_t bindings_count;
int one_to_many;
} snd_pcm_multi_t;
-static int snd_pcm_multi_close(void *private)
+static int snd_pcm_multi_close(snd_pcm_t *pcm)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
int ret = 0;
for (i = 0; i < multi->slaves_count; ++i) {
}
free(multi->slaves);
free(multi->bindings);
- free(private);
+ free(multi);
return ret;
}
-static int snd_pcm_multi_nonblock(void *private, int nonblock)
+static int snd_pcm_multi_nonblock(snd_pcm_t *pcm, int nonblock)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
snd_pcm_t *handle = multi->slaves[0].handle;
return snd_pcm_nonblock(handle, nonblock);
}
-static int snd_pcm_multi_info(void *private, snd_pcm_info_t *info)
+static int snd_pcm_multi_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
int err;
snd_pcm_t *handle_0 = multi->slaves[0].handle;
return 0;
}
-static int snd_pcm_multi_params_info(void *private, snd_pcm_params_info_t *info)
+static int snd_pcm_multi_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t *info)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
int err;
snd_pcm_t *handle_0 = multi->slaves[0].handle;
return 0;
}
-static int snd_pcm_multi_params(void *private, snd_pcm_params_t *params)
+static int snd_pcm_multi_params(snd_pcm_t *pcm, snd_pcm_params_t *params)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
snd_pcm_params_t p;
if (params->format.channels != multi->channels_count)
return 0;
}
-static int snd_pcm_multi_setup(void *private, snd_pcm_setup_t *setup)
+static int snd_pcm_multi_setup(snd_pcm_t *pcm, snd_pcm_setup_t *setup)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
int err;
size_t frames_alloc;
free(s->iovec);
if (!sh->setup.format.interleave) {
s->iovec = calloc(s->channels_total, sizeof(*s->iovec));
- if (!multi->handle->setup.format.interleave)
+ if (!pcm->setup.format.interleave)
continue;
}
s->buf = malloc(frames_alloc * sh->bits_per_frame / 8);
return 0;
}
-static int snd_pcm_multi_status(void *private, snd_pcm_status_t *status)
+static int snd_pcm_multi_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
snd_pcm_t *handle = multi->slaves[0].handle;
return snd_pcm_status(handle, status);
}
-static int snd_pcm_multi_state(void *private)
+static int snd_pcm_multi_state(snd_pcm_t *pcm)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
snd_pcm_t *handle = multi->slaves[0].handle;
return snd_pcm_state(handle);
}
-static ssize_t snd_pcm_multi_frame_io(void *private, int update)
+static ssize_t snd_pcm_multi_frame_io(snd_pcm_t *pcm, int update)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
snd_pcm_t *handle = multi->slaves[0].handle;
return snd_pcm_frame_io(handle, update);
}
-static int snd_pcm_multi_prepare(void *private)
+static int snd_pcm_multi_prepare(snd_pcm_t *pcm)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
return snd_pcm_prepare(multi->slaves[0].handle);
}
-static int snd_pcm_multi_go(void *private)
+static int snd_pcm_multi_go(snd_pcm_t *pcm)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
return snd_pcm_go(multi->slaves[0].handle);
}
-static int snd_pcm_multi_drain(void *private)
+static int snd_pcm_multi_drain(snd_pcm_t *pcm)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
return snd_pcm_drain(multi->slaves[0].handle);
}
-static int snd_pcm_multi_flush(void *private)
+static int snd_pcm_multi_flush(snd_pcm_t *pcm)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
return snd_pcm_flush(multi->slaves[0].handle);
}
-static int snd_pcm_multi_pause(void *private, int enable)
+static int snd_pcm_multi_pause(snd_pcm_t *pcm, int enable)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
return snd_pcm_pause(multi->slaves[0].handle, enable);
}
-static int snd_pcm_multi_channel_info(void *private, snd_pcm_channel_info_t *info)
+static int snd_pcm_multi_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
{
int err;
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int channel = info->channel;
unsigned int i;
for (i = 0; i < multi->bindings_count; ++i) {
return -EINVAL;
}
-static int snd_pcm_multi_channel_params(void *private, snd_pcm_channel_params_t *params)
+static int snd_pcm_multi_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t *params)
{
int err;
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int channel = params->channel;
unsigned int i;
for (i = 0; i < multi->bindings_count; ++i) {
return -EINVAL;
}
-static int snd_pcm_multi_channel_setup(void *private, snd_pcm_channel_setup_t *setup)
+static int snd_pcm_multi_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t *setup)
{
int err;
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int channel = setup->channel;
unsigned int i;
for (i = 0; i < multi->bindings_count; ++i) {
return 0;
}
-static ssize_t snd_pcm_multi_frame_data(void *private, off_t offset)
+static ssize_t snd_pcm_multi_frame_data(snd_pcm_t *pcm, off_t offset)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
ssize_t pos, newpos;
unsigned int i;
snd_pcm_t *handle_0 = multi->slaves[0].handle;
return newpos;
}
-static int snd_pcm_multi_write_copy(snd_pcm_multi_t *multi, const void *buf,
+static int snd_pcm_multi_write_copy(snd_pcm_t *pcm, const void *buf,
size_t offset, size_t count)
{
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
snd_pcm_channel_area_t area;
- snd_pcm_t *handle = multi->handle;
- area.addr = (void *) buf + offset * handle->bits_per_frame;
- area.step = handle->bits_per_frame;
+ area.addr = (void *) buf + offset * pcm->bits_per_frame;
+ area.step = pcm->bits_per_frame;
for (i = 0; i < multi->bindings_count; ++i) {
snd_pcm_multi_bind_t *bind = &multi->bindings[i];
snd_pcm_multi_slave_t *slave = &multi->slaves[bind->slave];
int err;
assert(slave->buf);
- area.first = handle->bits_per_sample * bind->client_channel;
- err = snd_pcm_area_copy(&area, 0, &slave->areas[bind->slave_channel], 0, count, handle->setup.format.format);
+ area.first = pcm->bits_per_sample * bind->client_channel;
+ err = snd_pcm_area_copy(&area, 0, &slave->areas[bind->slave_channel], 0, count, pcm->setup.format.format);
if (err < 0)
return err;
if (!slave->handle->setup.format.interleave) {
return 0;
}
-static int snd_pcm_multi_writev_copy(snd_pcm_multi_t *multi, const struct iovec *vec,
+static int snd_pcm_multi_writev_copy(snd_pcm_t *pcm, const struct iovec *vec,
size_t offset, size_t count)
{
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
snd_pcm_channel_area_t area;
- snd_pcm_t *handle = multi->handle;
area.first = 0;
- area.step = handle->bits_per_sample;
+ area.step = pcm->bits_per_sample;
for (i = 0; i < multi->bindings_count; ++i) {
snd_pcm_multi_bind_t *bind = &multi->bindings[i];
snd_pcm_multi_slave_t *slave = &multi->slaves[bind->slave];
int err;
area.addr = vec[bind->client_channel].iov_base +
- offset * handle->bits_per_sample;
+ offset * pcm->bits_per_sample;
if (slave->handle->setup.format.interleave) {
assert(slave->buf);
- err = snd_pcm_area_copy(&area, 0, &slave->areas[bind->slave_channel], 0, count, handle->setup.format.format);
+ err = snd_pcm_area_copy(&area, 0, &slave->areas[bind->slave_channel], 0, count, pcm->setup.format.format);
if (err < 0)
return err;
} else {
return 0;
}
-static ssize_t snd_pcm_multi_write_io(snd_pcm_multi_t *multi, size_t count)
+static ssize_t snd_pcm_multi_write_io(snd_pcm_t *pcm, size_t count)
{
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
ssize_t frames = count;
for (i = 0; i < multi->slaves_count; ++i) {
return frames;
}
-static ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, const void *buf, size_t count)
+static ssize_t snd_pcm_multi_write(snd_pcm_t *pcm, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, const void *buf, size_t count)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
size_t result = 0;
while (count > 0) {
int err;
size_t frames = count;
if (frames > multi->frames_alloc)
frames = multi->frames_alloc;
- err = snd_pcm_multi_write_copy(multi, buf, result, frames);
+ err = snd_pcm_multi_write_copy(pcm, buf, result, frames);
if (err < 0)
return err;
- ret = snd_pcm_multi_write_io(multi, frames);
+ ret = snd_pcm_multi_write_io(pcm, frames);
if (ret > 0)
result += ret;
if (ret != (ssize_t)frames) {
return result;
}
-static ssize_t snd_pcm_multi_writev1(snd_pcm_multi_t *multi, const struct iovec *vector, size_t count)
+static ssize_t snd_pcm_multi_writev1(snd_pcm_t *pcm, const struct iovec *vector, size_t count)
{
+ snd_pcm_multi_t *multi = pcm->private;
size_t result = 0;
while (count > 0) {
int err;
size_t frames = count;
if (frames > multi->frames_alloc)
frames = multi->frames_alloc;
- err = snd_pcm_multi_writev_copy(multi, vector, result, frames);
+ err = snd_pcm_multi_writev_copy(pcm, vector, result, frames);
if (err < 0)
return err;
- ret = snd_pcm_multi_write_io(multi, frames);
+ ret = snd_pcm_multi_write_io(pcm, frames);
if (ret > 0)
result += ret;
if (ret != (ssize_t) frames) {
return result;
}
-static ssize_t snd_pcm_multi_writev(void *private, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, const struct iovec *vector, unsigned long count)
+static ssize_t snd_pcm_multi_writev(snd_pcm_t *pcm, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, const struct iovec *vector, unsigned long count)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
- snd_pcm_t *handle = multi->handle;
unsigned int k, step;
size_t result = 0;
- if (handle->setup.format.interleave)
+ if (pcm->setup.format.interleave)
step = 1;
else
- step = handle->setup.format.channels;
+ step = pcm->setup.format.channels;
for (k = 0; k < count; k += step) {
ssize_t ret;
- if (handle->setup.format.interleave)
- ret = snd_pcm_multi_write(private, timestamp, vector->iov_base, vector->iov_len);
+ if (pcm->setup.format.interleave)
+ ret = snd_pcm_multi_write(pcm, timestamp, vector->iov_base, vector->iov_len);
else
- ret = snd_pcm_multi_writev1(multi, vector, vector->iov_len);
+ ret = snd_pcm_multi_writev1(pcm, vector, vector->iov_len);
if (ret > 0)
result += ret;
if (ret != (ssize_t) vector->iov_len) {
return result;
}
-static ssize_t snd_pcm_multi_read(void *private ATTRIBUTE_UNUSED, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, void *buf ATTRIBUTE_UNUSED, size_t count ATTRIBUTE_UNUSED)
+static ssize_t snd_pcm_multi_read(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, void *buf ATTRIBUTE_UNUSED, size_t count ATTRIBUTE_UNUSED)
{
- // snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ // snd_pcm_multi_t *multi = pcm->private;
return -ENOSYS;
}
-static ssize_t snd_pcm_multi_readv(void *private ATTRIBUTE_UNUSED, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, const struct iovec *vector ATTRIBUTE_UNUSED, unsigned long count ATTRIBUTE_UNUSED)
+static ssize_t snd_pcm_multi_readv(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_timestamp_t *timestamp ATTRIBUTE_UNUSED, const struct iovec *vector ATTRIBUTE_UNUSED, unsigned long count ATTRIBUTE_UNUSED)
{
- // snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ // snd_pcm_multi_t *multi = pcm->private;
return -ENOSYS;
}
-static int snd_pcm_multi_mmap_status(void *private, snd_pcm_mmap_status_t **status)
+static int snd_pcm_multi_mmap_status(snd_pcm_t *pcm, snd_pcm_mmap_status_t **status)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_t *handle = multi->slaves[i].handle;
return 0;
}
-static int snd_pcm_multi_mmap_control(void *private, snd_pcm_mmap_control_t **control)
+static int snd_pcm_multi_mmap_control(snd_pcm_t *pcm, snd_pcm_mmap_control_t **control)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
snd_pcm_setup_t *setup_0 = &multi->slaves[0].handle->setup;
unsigned int i;
for (i = 1; i < multi->slaves_count; ++i) {
return 0;
}
-static int snd_pcm_multi_mmap_data(void *private, void **buffer, size_t bsize ATTRIBUTE_UNUSED)
+static int snd_pcm_multi_mmap_data(snd_pcm_t *pcm, void **buffer, size_t bsize ATTRIBUTE_UNUSED)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_t *handle = multi->slaves[i].handle;
return 0;
}
-static int snd_pcm_multi_munmap_status(void *private, snd_pcm_mmap_status_t *status ATTRIBUTE_UNUSED)
+static int snd_pcm_multi_munmap_status(snd_pcm_t *pcm, snd_pcm_mmap_status_t *status ATTRIBUTE_UNUSED)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
int ret = 0;
for (i = 0; i < multi->slaves_count; ++i) {
return ret;
}
-static int snd_pcm_multi_munmap_control(void *private, snd_pcm_mmap_control_t *control ATTRIBUTE_UNUSED)
+static int snd_pcm_multi_munmap_control(snd_pcm_t *pcm, snd_pcm_mmap_control_t *control ATTRIBUTE_UNUSED)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
int ret = 0;
for (i = 0; i < multi->slaves_count; ++i) {
return ret;
}
-static int snd_pcm_multi_munmap_data(void *private, void *buffer ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED)
+static int snd_pcm_multi_munmap_data(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
int ret = 0;
for (i = 0; i < multi->slaves_count; ++i) {
return ret;
}
-static int snd_pcm_multi_channels_mask(void *private, bitset_t *client_vmask)
+static int snd_pcm_multi_channels_mask(snd_pcm_t *pcm, bitset_t *client_vmask)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
bitset_t *vmasks[multi->slaves_count];
int err;
return err;
}
}
- bitset_zero(client_vmask, multi->handle->setup.format.channels);
+ bitset_zero(client_vmask, pcm->setup.format.channels);
for (i = 0; i < multi->bindings_count; ++i) {
snd_pcm_multi_bind_t *b = &multi->bindings[i];
if (bitset_get(vmasks[b->slave], b->slave_channel))
return 0;
}
-int snd_pcm_multi_file_descriptor(void *private)
+int snd_pcm_multi_file_descriptor(snd_pcm_t *pcm)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
+ snd_pcm_multi_t *multi = pcm->private;
snd_pcm_t *handle = multi->slaves[0].handle;
return snd_pcm_file_descriptor(handle);
}
-static void snd_pcm_multi_dump(void *private, FILE *fp)
+static void snd_pcm_multi_dump(snd_pcm_t *pcm, FILE *fp)
{
- snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
- snd_pcm_t *handle = multi->handle;
+ snd_pcm_multi_t *multi = pcm->private;
unsigned int k;
fprintf(fp, "Multi PCM\n");
- if (handle->valid_setup) {
+ if (pcm->valid_setup) {
fprintf(fp, "\nIts setup is:\n");
- snd_pcm_dump_setup(handle, fp);
+ snd_pcm_dump_setup(pcm, fp);
}
for (k = 0; k < multi->slaves_count; ++k) {
fprintf(fp, "\nSlave #%d: ", k);
stream = slaves_handle[0]->stream;
- multi->handle = handle;
multi->slaves_count = slaves_count;
multi->slaves = calloc(slaves_count, sizeof(*multi->slaves));
multi->bindings_count = bindings_count;
handle->stream = stream;
handle->mode = multi->slaves[0].handle->mode;
handle->ops = &snd_pcm_multi_ops;
- handle->op_arg = multi;
+ handle->op_arg = handle;
handle->fast_ops = &snd_pcm_multi_fast_ops;
- handle->fast_op_arg = multi;
+ handle->fast_op_arg = handle;
handle->private = multi;
*handlep = handle;
return 0;
*
*/
-static int snd_pcm_plug_close(void *private)
+static int snd_pcm_plug_close(snd_pcm_t *pcm)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
snd_pcm_plug_clear(plug);
free(plug->handle->fast_ops);
if (plug->close_slave)
return snd_pcm_close(plug->slave);
- free(private);
+ free(plug);
return 0;
}
-static int snd_pcm_plug_nonblock(void *private, int nonblock)
+static int snd_pcm_plug_nonblock(snd_pcm_t *pcm, int nonblock)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
return snd_pcm_nonblock(plug->slave, nonblock);
}
-static int snd_pcm_plug_info(void *private, snd_pcm_info_t *info)
+static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
{
int err;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
if ((err = snd_pcm_info(plug->slave, info)) < 0)
return err;
return 0;
}
-static int snd_pcm_plug_params_info(void *private, snd_pcm_params_info_t *info)
+static int snd_pcm_plug_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t *info)
{
int err;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
snd_pcm_params_info_t slave_info;
int rate;
int slave_format, slave_rate;
return 0;
}
-static int snd_pcm_plug_setup(void *private, snd_pcm_setup_t *setup)
+static int snd_pcm_plug_setup(snd_pcm_t *pcm, snd_pcm_setup_t *setup)
{
int err;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
err = snd_pcm_setup(plug->slave, setup);
if (err < 0)
return 0;
}
-static int snd_pcm_plug_status(void *private, snd_pcm_status_t *status)
+static int snd_pcm_plug_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
{
int err;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
err = snd_pcm_status(plug->slave, status);
if (err < 0)
return 0;
}
-static int snd_pcm_plug_state(void *private)
+static int snd_pcm_plug_state(snd_pcm_t *pcm)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
return snd_pcm_state(plug->slave);
}
-static ssize_t snd_pcm_plug_frame_io(void *private, int update)
+static ssize_t snd_pcm_plug_frame_io(snd_pcm_t *pcm, int update)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
ssize_t frame_io = snd_pcm_frame_io(plug->slave, update);
if (frame_io < 0)
return frame_io;
return snd_pcm_plug_client_size(plug, frame_io);
}
-static int snd_pcm_plug_prepare(void *private)
+static int snd_pcm_plug_prepare(snd_pcm_t *pcm)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
int err;
err = snd_pcm_prepare(plug->slave);
if (err < 0)
return 0;
}
-static int snd_pcm_plug_go(void *private)
+static int snd_pcm_plug_go(snd_pcm_t *pcm)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
return snd_pcm_go(plug->slave);
}
-static int snd_pcm_plug_drain(void *private)
+static int snd_pcm_plug_drain(snd_pcm_t *pcm)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
int err;
if ((err = snd_pcm_drain(plug->slave)) < 0)
return 0;
}
-static int snd_pcm_plug_flush(void *private)
+static int snd_pcm_plug_flush(snd_pcm_t *pcm)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
int err;
if ((err = snd_pcm_flush(plug->slave)) < 0)
return 0;
}
-static int snd_pcm_plug_pause(void *private, int enable)
+static int snd_pcm_plug_pause(snd_pcm_t *pcm, int enable)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
int err;
if ((err = snd_pcm_pause(plug->slave, enable)) < 0)
return 0;
}
-static int snd_pcm_plug_channel_info(void *private ATTRIBUTE_UNUSED, snd_pcm_channel_info_t *info ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_channel_info(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_channel_info_t *info ATTRIBUTE_UNUSED)
{
/* FIXME: if route plugin is not inserted or its ttable is trivial
this should be implemented */
return -ENOSYS;
}
-static int snd_pcm_plug_channel_params(void *private ATTRIBUTE_UNUSED, snd_pcm_channel_params_t *params ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_channel_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_channel_params_t *params ATTRIBUTE_UNUSED)
{
/* FIXME: if route plugin is not inserted or its ttable is trivial
this should be implemented */
return -ENOSYS;
}
-static int snd_pcm_plug_channel_setup(void *private ATTRIBUTE_UNUSED, snd_pcm_channel_setup_t *setup ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_channel_setup_t *setup ATTRIBUTE_UNUSED)
{
/* FIXME: if route plugin is not inserted or its ttable is trivial
this should be implemented for non mmap setups */
return -ENOSYS;
}
-static ssize_t snd_pcm_plug_frame_data(void *private, off_t offset)
+static ssize_t snd_pcm_plug_frame_data(snd_pcm_t *pcm, off_t offset)
{
ssize_t ret;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
if (offset < 0) {
offset = snd_pcm_plug_slave_size(plug, -offset);
if (offset < 0)
return snd_pcm_plug_client_size(plug, ret);
}
-ssize_t snd_pcm_plug_writev(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, const struct iovec *vector, unsigned long count)
+ssize_t snd_pcm_plug_writev(snd_pcm_t *pcm, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, const struct iovec *vector, unsigned long count)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
snd_pcm_t *handle = plug->handle;
unsigned int k, step;
size_t result = 0;
return result;
}
-ssize_t snd_pcm_plug_readv(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, const struct iovec *vector, unsigned long count)
+ssize_t snd_pcm_plug_readv(snd_pcm_t *pcm, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, const struct iovec *vector, unsigned long count)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
snd_pcm_t *handle = plug->handle;
unsigned int k, step;
size_t result = 0;
return result;
}
-ssize_t snd_pcm_plug_write(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, const void *buf, size_t count)
+ssize_t snd_pcm_plug_write(snd_pcm_t *pcm, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, const void *buf, size_t count)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
snd_pcm_t *handle = plug->handle;
ssize_t frames;
snd_pcm_plugin_channel_t *channels;
return size;
}
-ssize_t snd_pcm_plug_read(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, void *buf, size_t count)
+ssize_t snd_pcm_plug_read(snd_pcm_t *pcm, snd_timestamp_t *tstamp ATTRIBUTE_UNUSED, void *buf, size_t count)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
snd_pcm_t *handle = plug->handle;
ssize_t frames;
snd_pcm_plugin_channel_t *channels;
return size;
}
-static int snd_pcm_plug_mmap_status(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t **status ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_mmap_status(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t **status ATTRIBUTE_UNUSED)
{
return -EBADFD;
}
-static int snd_pcm_plug_mmap_control(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t **control ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_mmap_control(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t **control ATTRIBUTE_UNUSED)
{
return -EBADFD;
}
-static int snd_pcm_plug_mmap_data(void *private ATTRIBUTE_UNUSED, void **buffer ATTRIBUTE_UNUSED, size_t bsize ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_mmap_data(snd_pcm_t *pcm ATTRIBUTE_UNUSED, void **buffer ATTRIBUTE_UNUSED, size_t bsize ATTRIBUTE_UNUSED)
{
return -EBADFD;
}
-static int snd_pcm_plug_munmap_status(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t *status ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_munmap_status(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_status_t *status ATTRIBUTE_UNUSED)
{
return -EBADFD;
}
-static int snd_pcm_plug_munmap_control(void *private ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t *control ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_munmap_control(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_mmap_control_t *control ATTRIBUTE_UNUSED)
{
return -EBADFD;
}
-static int snd_pcm_plug_munmap_data(void *private ATTRIBUTE_UNUSED, void *buffer ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED)
+static int snd_pcm_plug_munmap_data(snd_pcm_t *pcm ATTRIBUTE_UNUSED, void *buffer ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED)
{
return -EBADFD;
}
-static int snd_pcm_plug_channels_mask(void *private,
+static int snd_pcm_plug_channels_mask(snd_pcm_t *pcm,
bitset_t *client_vmask)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
if (plug->handle->stream == SND_PCM_STREAM_PLAYBACK)
return snd_pcm_plug_playback_channels_mask(plug, client_vmask);
else
return snd_pcm_plug_capture_channels_mask(plug, client_vmask);
}
-int snd_pcm_plug_file_descriptor(void *private)
+int snd_pcm_plug_file_descriptor(snd_pcm_t *pcm)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
return snd_pcm_file_descriptor(plug->slave);
}
-static void snd_pcm_plug_dump(void *private, FILE *fp)
+static void snd_pcm_plug_dump(snd_pcm_t *pcm, FILE *fp)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_t *plug = pcm->private;
snd_pcm_t *handle = plug->handle;
snd_pcm_plugin_t *plugin;
if (!plug->first) {
fprintf(fp, "\n");
}
-static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params);
+static int snd_pcm_plug_params(snd_pcm_t *pcm, snd_pcm_params_t *params);
struct snd_pcm_ops snd_pcm_plug_ops = {
close: snd_pcm_plug_close,
-static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params)
+static int snd_pcm_plug_params(snd_pcm_t *pcm, snd_pcm_params_t *params)
{
snd_pcm_params_t slave_params;
snd_pcm_info_t slave_info;
int err;
int first = 1;
- plug = (snd_pcm_plug_t*) private;
+ plug = pcm->private;
/*
* try to decide, if a conversion is required
}
*plug->handle->fast_ops = snd_pcm_plug_fast_ops;
- plug->handle->fast_op_arg = plug;
+ plug->handle->fast_op_arg = pcm;
/*
* I/O plugins
handle->type = SND_PCM_TYPE_PLUG;
handle->stream = slave->stream;
handle->ops = &snd_pcm_plug_ops;
- handle->op_arg = plug;
+ handle->op_arg = handle;
handle->fast_ops = malloc(sizeof(*handle->fast_ops));
*handle->fast_ops = snd_pcm_plug_fast_ops;
- handle->fast_op_arg = plug;
+ handle->fast_op_arg = handle;
handle->mode = slave->mode;
handle->private = plug;
*handlep = handle;