From: Abramo Bagnara Date: Mon, 11 Sep 2000 15:49:10 +0000 (+0000) Subject: Added abstraction layer to controls. Added client/server support to controls. Cleaned... X-Git-Tag: v1.0.3~1137 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=df35e8457a0fed094f7e60b60f7c722f840f3383;p=alsa-lib.git Added abstraction layer to controls. Added client/server support to controls. Cleaned private_data use for PCMs. Cleaned aserver --- diff --git a/TODO b/TODO index 5a776fa4..99b87739 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ -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) diff --git a/include/aserver.h b/include/aserver.h index 7c477fa3..0094b2da 100644 --- a/include/aserver.h +++ b/include/aserver.h @@ -54,6 +54,30 @@ typedef struct { #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; @@ -68,10 +92,3 @@ typedef struct { 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 */ -}; diff --git a/include/control.h b/include/control.h index 446b4fc4..f68b5ac0 100644 --- a/include/control.h +++ b/include/control.h @@ -7,6 +7,8 @@ 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); @@ -35,7 +37,10 @@ int snd_defaults_pcm_device(void); 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); diff --git a/include/mixer.h b/include/mixer.h index e224ecdb..1daef64e 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -11,7 +11,7 @@ typedef struct snd_mixer snd_mixer_t; 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); diff --git a/src/aserver/aserver.c b/src/aserver/aserver.c index f4234ab0..362441cb 100644 --- a/src/aserver/aserver.c +++ b/src/aserver/aserver.c @@ -35,6 +35,7 @@ #include "asoundlib.h" #include "pcm_local.h" #include "aserver.h" +#include "list.h" char *command; @@ -140,20 +141,66 @@ int send_fd(int socket, void *data, size_t len, int fd) 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; @@ -166,12 +213,12 @@ struct client { 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; @@ -186,7 +233,8 @@ struct client { } seq; #endif } device; - enum { CLOSED = 0, STOPPED, NORMAL, UNKNOWN } state; + int polling; + int open; int cookie; union { struct { @@ -196,11 +244,38 @@ struct client { } 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) { @@ -241,6 +316,10 @@ int pcm_shm_close(client_t *client) { 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; @@ -255,53 +334,10 @@ int pcm_shm_close(client_t *client) 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; @@ -362,7 +398,6 @@ int pcm_shm_cmd(client_t *client) 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; @@ -375,7 +410,6 @@ int pcm_shm_cmd(client_t *client) 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; @@ -394,7 +428,6 @@ int pcm_shm_cmd(client_t *client) 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; @@ -423,7 +456,6 @@ int pcm_shm_cmd(client_t *client) 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; @@ -444,17 +476,17 @@ int pcm_shm_cmd(client_t *client) 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; } } @@ -484,7 +516,6 @@ int pcm_shm_cmd(client_t *client) case SND_PCM_IOCTL_MUNMAP_STATUS: ctrl->result = 0; break; - } #endif case SND_PCM_IOCTL_CLOSE: client->ops->close(client); @@ -500,6 +531,10 @@ int pcm_shm_cmd(client_t *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; } @@ -507,11 +542,171 @@ transport_ops_t pcm_shm_ops = { 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; @@ -549,6 +744,16 @@ void snd_client_open(client_t *client) 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; @@ -565,7 +770,7 @@ void snd_client_open(client_t *client) if (err < 0) { ans.result = err; } else { - client->state = STOPPED; + client->open = 1; ans.result = client->data.fd; } @@ -575,53 +780,141 @@ void snd_client_open(client_t *client) 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"); @@ -634,205 +927,30 @@ int server(char *sockname, int port) } } - 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; } diff --git a/src/control/Makefile.am b/src/control/Makefile.am index 61b2679d..8592e654 100644 --- a/src/control/Makefile.am +++ b/src/control/Makefile.am @@ -1,6 +1,7 @@ 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 diff --git a/src/control/cards.c b/src/control/cards.c index d9c39405..e3dabdc6 100644 --- a/src/control/cards.c +++ b/src/control/cards.c @@ -106,7 +106,7 @@ int snd_card_get_index(const char *string) 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); @@ -127,7 +127,7 @@ int snd_card_get_name(int card, char **name) 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); @@ -148,7 +148,7 @@ int snd_card_get_longname(int card, char **name) 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); diff --git a/src/control/control.c b/src/control/control.c index 1a7740e7..bfd38045 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -1,6 +1,6 @@ /* * Control Interface - main file - * Copyright (c) 1998,1999,2000 by Jaroslav Kysela + * Copyright (c) 2000 by Abramo Bagnara * * * This library is free software; you can redistribute it and/or modify @@ -25,145 +25,98 @@ #include #include #include -#include #include #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) @@ -171,26 +124,142 @@ int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * 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; +} diff --git a/src/control/control_client.c b/src/control/control_client.c new file mode 100644 index 00000000..264f4b3a --- /dev/null +++ b/src/control/control_client.c @@ -0,0 +1,433 @@ +/* + * Control - Client + * Copyright (c) 2000 by Abramo Bagnara + * + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; +} + diff --git a/src/control/control_hw.c b/src/control/control_hw.c new file mode 100644 index 00000000..496ce220 --- /dev/null +++ b/src/control/control_hw.c @@ -0,0 +1,194 @@ +/* + * Control Interface - Hardware + * Copyright (c) 1998,1999,2000 by Jaroslav Kysela + * Copyright (c) 2000 by Abramo Bagnara + * + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#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; +} + diff --git a/src/control/control_local.h b/src/control/control_local.h index 4c2e826c..d396df5a 100644 --- a/src/control/control_local.h +++ b/src/control/control_local.h @@ -19,11 +19,30 @@ * */ +#include +#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 */ diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c index 1bea0d5a..ed22bf34 100644 --- a/src/mixer/mixer.c +++ b/src/mixer/mixer.c @@ -32,7 +32,7 @@ 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; @@ -41,7 +41,7 @@ int snd_mixer_open(snd_mixer_t **r_handle, int card) 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) { diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index fc2507a1..fffd6c12 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -788,7 +788,7 @@ static int _snd_pcm_open_client(snd_pcm_t **handlep, snd_config_t *conf, } 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); } } diff --git a/src/pcm/pcm_client.c b/src/pcm/pcm_client.c index ed72f53a..8d721256 100644 --- a/src/pcm/pcm_client.c +++ b/src/pcm/pcm_client.c @@ -38,7 +38,6 @@ #include "aserver.h" typedef struct { - snd_pcm_t *handle; int data_fd; int ctrl_fd; union { @@ -80,13 +79,14 @@ int receive_fd(int socket, void *data, size_t len, int *fd) 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) { @@ -112,11 +112,13 @@ static void clean_state(snd_pcm_client_t *client) } } -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; @@ -130,12 +132,14 @@ static int snd_pcm_client_shm_action(snd_pcm_client_t *client) 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; @@ -151,242 +155,242 @@ static int snd_pcm_client_shm_action_fd(snd_pcm_client_t *client) 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; @@ -394,21 +398,20 @@ static ssize_t snd_pcm_client_shm_write(void *private, snd_timestamp_t *tstamp, // 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; @@ -430,44 +433,42 @@ static ssize_t snd_pcm_client_shm_writev(void *private, snd_timestamp_t *tstamp, 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; @@ -488,13 +489,12 @@ ssize_t snd_pcm_client_shm_readv(void *private, snd_timestamp_t *tstamp, const s 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 */ @@ -505,14 +505,14 @@ ssize_t snd_pcm_client_shm_readv(void *private, snd_timestamp_t *tstamp, const s 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, @@ -524,14 +524,14 @@ static int snd_pcm_client_shm_mmap_status(void *private, snd_pcm_mmap_status_t * 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, @@ -543,18 +543,18 @@ static int snd_pcm_client_shm_mmap_control(void *private, snd_pcm_mmap_control_t 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); @@ -564,14 +564,14 @@ static int snd_pcm_client_shm_mmap_data(void *private, void **buffer, size_t bsi 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; @@ -582,14 +582,14 @@ static int snd_pcm_client_shm_munmap_status(void *private ATTRIBUTE_UNUSED, snd_ #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; @@ -600,14 +600,14 @@ static int snd_pcm_client_shm_munmap_control(void *private ATTRIBUTE_UNUSED, snd #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; @@ -618,26 +618,24 @@ static int snd_pcm_client_shm_munmap_data(void *private ATTRIBUTE_UNUSED, void * #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); } } @@ -844,7 +842,6 @@ int snd_pcm_client_create(snd_pcm_t **handlep, char *host, int port, int transpo goto _err; } - client->handle = handle; client->data_fd = fds[0]; client->ctrl_fd = fds[1]; switch (transport) { @@ -855,9 +852,9 @@ int snd_pcm_client_create(snd_pcm_t **handlep, char *host, int port, int transpo 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; diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index 1f493277..dce890a9 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -30,7 +30,6 @@ #include "pcm_local.h" typedef struct { - snd_pcm_t *handle; int fd; int card, device, subdevice; void *mmap_data_ptr; @@ -40,21 +39,21 @@ typedef struct { #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) @@ -68,63 +67,63 @@ static int snd_pcm_hw_nonblock(void *private, int nonblock) 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; @@ -132,18 +131,18 @@ static int snd_pcm_hw_channel_setup(void *private, snd_pcm_channel_setup_t * set 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) @@ -151,9 +150,9 @@ static int snd_pcm_hw_state(void *private) 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) @@ -161,69 +160,68 @@ static ssize_t snd_pcm_hw_frame_io(void *private, int update ATTRIBUTE_UNUSED) 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) @@ -238,10 +236,10 @@ static ssize_t snd_pcm_hw_write(void *private, snd_timestamp_t *tstamp, const vo 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) @@ -256,10 +254,10 @@ static ssize_t snd_pcm_hw_writev(void *private, snd_timestamp_t *tstamp, const s 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) @@ -274,10 +272,10 @@ static ssize_t snd_pcm_hw_read(void *private, snd_timestamp_t *tstamp, void *buf 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) @@ -292,9 +290,9 @@ ssize_t snd_pcm_hw_readv(void *private, snd_timestamp_t *tstamp, const struct io 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); @@ -304,9 +302,9 @@ static int snd_pcm_hw_mmap_status(void *private, snd_pcm_mmap_status_t **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); @@ -316,12 +314,12 @@ static int snd_pcm_hw_mmap_control(void *private, snd_pcm_mmap_control_t **contr 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) @@ -330,53 +328,52 @@ static int snd_pcm_hw_mmap_data(void *private, void **buffer, size_t bsize) 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); } } @@ -433,7 +430,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int sub 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) { @@ -492,7 +489,6 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int sub ret = -ENOMEM; goto __end; } - hw->handle = handle; hw->card = card; hw->device = device; hw->subdevice = subdevice; @@ -500,9 +496,9 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int sub 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; diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 3ab5d8ec..4511af85 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -23,40 +23,40 @@ #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 { @@ -73,9 +73,9 @@ 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; }; diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index 6a84dd85..41c19e74 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -44,7 +44,6 @@ typedef struct { } 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; @@ -55,9 +54,9 @@ typedef struct { 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) { @@ -78,20 +77,20 @@ static int snd_pcm_multi_close(void *private) } 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; @@ -112,9 +111,9 @@ static int snd_pcm_multi_info(void *private, snd_pcm_info_t *info) 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; @@ -153,9 +152,9 @@ static int snd_pcm_multi_params_info(void *private, snd_pcm_params_info_t *info) 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) @@ -193,9 +192,9 @@ static int snd_pcm_multi_params(void *private, snd_pcm_params_t *params) 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; @@ -231,7 +230,7 @@ static int snd_pcm_multi_setup(void *private, snd_pcm_setup_t *setup) 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); @@ -262,61 +261,61 @@ static int snd_pcm_multi_setup(void *private, snd_pcm_setup_t *setup) 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) { @@ -331,10 +330,10 @@ static int snd_pcm_multi_channel_info(void *private, snd_pcm_channel_info_t *inf 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) { @@ -349,10 +348,10 @@ static int snd_pcm_multi_channel_params(void *private, snd_pcm_channel_params_t 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) { @@ -368,9 +367,9 @@ static int snd_pcm_multi_channel_setup(void *private, snd_pcm_channel_setup_t *s 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; @@ -395,21 +394,21 @@ static ssize_t snd_pcm_multi_frame_data(void *private, off_t offset) 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) { @@ -420,23 +419,23 @@ static int snd_pcm_multi_write_copy(snd_pcm_multi_t *multi, const void *buf, 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 { @@ -448,8 +447,9 @@ static int snd_pcm_multi_writev_copy(snd_pcm_multi_t *multi, const struct iovec 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) { @@ -467,9 +467,9 @@ static ssize_t snd_pcm_multi_write_io(snd_pcm_multi_t *multi, size_t count) 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; @@ -477,10 +477,10 @@ static ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t *timestamp ATT 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) { @@ -493,8 +493,9 @@ static ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t *timestamp ATT 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; @@ -502,10 +503,10 @@ static ssize_t snd_pcm_multi_writev1(snd_pcm_multi_t *multi, const struct iovec 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) { @@ -518,22 +519,20 @@ static ssize_t snd_pcm_multi_writev1(snd_pcm_multi_t *multi, const struct iovec 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) { @@ -546,21 +545,21 @@ static ssize_t snd_pcm_multi_writev(void *private, snd_timestamp_t *timestamp AT 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; @@ -572,9 +571,9 @@ static int snd_pcm_multi_mmap_status(void *private, snd_pcm_mmap_status_t **stat 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) { @@ -594,9 +593,9 @@ static int snd_pcm_multi_mmap_control(void *private, snd_pcm_mmap_control_t **co 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; @@ -619,9 +618,9 @@ static int snd_pcm_multi_mmap_data(void *private, void **buffer, size_t bsize AT 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) { @@ -633,9 +632,9 @@ static int snd_pcm_multi_munmap_status(void *private, snd_pcm_mmap_status_t *sta 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) { @@ -647,9 +646,9 @@ static int snd_pcm_multi_munmap_control(void *private, snd_pcm_mmap_control_t *c 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) { @@ -661,9 +660,9 @@ static int snd_pcm_multi_munmap_data(void *private, void *buffer ATTRIBUTE_UNUSE 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; @@ -683,7 +682,7 @@ static int snd_pcm_multi_channels_mask(void *private, bitset_t *client_vmask) 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)) @@ -694,22 +693,21 @@ static int snd_pcm_multi_channels_mask(void *private, bitset_t *client_vmask) 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); @@ -790,7 +788,6 @@ int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count, 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; @@ -830,9 +827,9 @@ int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_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; diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index a7d03e1c..a4387e92 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -129,27 +129,27 @@ snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_plug_t *plug) * */ -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; @@ -158,10 +158,10 @@ static int snd_pcm_plug_info(void *private, snd_pcm_info_t *info) 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; @@ -260,10 +260,10 @@ static int snd_pcm_plug_action(snd_pcm_plug_t *plug, int action, 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) @@ -292,10 +292,10 @@ static int snd_pcm_plug_setup(void *private, snd_pcm_setup_t *setup) 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) @@ -308,24 +308,24 @@ static int snd_pcm_plug_status(void *private, snd_pcm_status_t *status) 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) @@ -335,15 +335,15 @@ static int snd_pcm_plug_prepare(void *private) 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) @@ -353,9 +353,9 @@ static int snd_pcm_plug_drain(void *private) 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) @@ -365,9 +365,9 @@ static int snd_pcm_plug_flush(void *private) 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) @@ -377,31 +377,31 @@ static int snd_pcm_plug_pause(void *private, int enable) 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) @@ -418,9 +418,9 @@ static ssize_t snd_pcm_plug_frame_data(void *private, off_t offset) 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; @@ -462,9 +462,9 @@ ssize_t snd_pcm_plug_writev(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNU 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; @@ -506,9 +506,9 @@ ssize_t snd_pcm_plug_readv(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNUS 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; @@ -540,9 +540,9 @@ ssize_t snd_pcm_plug_write(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNUS 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; @@ -574,55 +574,55 @@ ssize_t snd_pcm_plug_read(void *private, snd_timestamp_t *tstamp ATTRIBUTE_UNUSE 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) { @@ -644,7 +644,7 @@ static void snd_pcm_plug_dump(void *private, FILE *fp) 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, @@ -706,7 +706,7 @@ static void snd_pcm_plug_slave_params(snd_pcm_plug_t *plug, -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; @@ -717,7 +717,7 @@ static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params) int err; int first = 1; - plug = (snd_pcm_plug_t*) private; + plug = pcm->private; /* * try to decide, if a conversion is required @@ -776,7 +776,7 @@ static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params) } *plug->handle->fast_ops = snd_pcm_plug_fast_ops; - plug->handle->fast_op_arg = plug; + plug->handle->fast_op_arg = pcm; /* * I/O plugins @@ -826,10 +826,10 @@ int snd_pcm_plug_create(snd_pcm_t **handlep, snd_pcm_t *slave, int close_slave) 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;