New async notification API. Removed obsolete surround. Cleaning

This commit is contained in:
Abramo Bagnara 2001-06-20 20:52:12 +00:00
parent 57469ec597
commit 157f47aedd
35 changed files with 436 additions and 1581 deletions

View file

@ -31,9 +31,9 @@
#include <netinet/in.h>
#include <netdb.h>
#include <limits.h>
#include <signal.h>
#include "aserver.h"
#include "list.h"
char *command;
@ -199,6 +199,9 @@ struct client {
int stream;
int mode;
transport_ops_t *ops;
snd_async_handler_t *async_handler;
int async_sig;
pid_t async_pid;
union {
struct {
snd_pcm_t *handle;
@ -207,7 +210,7 @@ struct client {
struct {
snd_ctl_t *handle;
int fd;
} control;
} ctl;
#if 0
struct {
snd_rawmidi_t *handle;
@ -358,6 +361,13 @@ static int shm_ack_fd(client_t *client, int fd)
return 0;
}
static void async_handler(snd_async_handler_t *handler)
{
client_t *client = snd_async_handler_get_callback_private(handler);
/* FIXME: use sigqueue */
kill(client->async_pid, client->async_sig);
}
static int pcm_shm_cmd(client_t *client)
{
volatile snd_pcm_shm_ctrl_t *ctrl = client->transport.shm.ctrl;
@ -374,6 +384,19 @@ static int pcm_shm_cmd(client_t *client)
switch (cmd) {
case SND_PCM_IOCTL_ASYNC:
ctrl->result = snd_pcm_async(pcm, ctrl->u.async.sig, ctrl->u.async.pid);
if (ctrl->result < 0)
break;
if (ctrl->u.async.sig >= 0) {
assert(client->async_sig < 0);
ctrl->result = snd_async_add_pcm_handler(&client->async_handler, pcm, async_handler, client);
if (ctrl->result < 0)
break;
} else {
assert(client->async_sig >= 0);
snd_async_del_handler(client->async_handler);
}
client->async_sig = ctrl->u.async.sig;
client->async_pid = ctrl->u.async.pid;
break;
case SNDRV_PCM_IOCTL_INFO:
ctrl->result = snd_pcm_info(pcm, (snd_pcm_info_t *) &ctrl->u.info);
@ -506,8 +529,8 @@ static int ctl_shm_open(client_t *client, int *cookie)
err = snd_ctl_open(&ctl, client->name, SND_CTL_NONBLOCK);
if (err < 0)
return err;
client->device.control.handle = ctl;
client->device.control.fd = _snd_ctl_poll_descriptor(ctl);
client->device.ctl.handle = ctl;
client->device.ctl.fd = _snd_ctl_poll_descriptor(ctl);
shmid = shmget(IPC_PRIVATE, CTL_SHM_SIZE, 0666);
if (shmid < 0) {
@ -524,7 +547,7 @@ static int ctl_shm_open(client_t *client, int *cookie)
goto _err;
}
*cookie = shmid;
add_waiter(client->device.control.fd, POLLIN, ctl_handler, client);
add_waiter(client->device.ctl.fd, POLLIN, ctl_handler, client);
client->polling = 1;
return 0;
@ -539,10 +562,10 @@ static int ctl_shm_close(client_t *client)
int err;
snd_ctl_shm_ctrl_t *ctrl = client->transport.shm.ctrl;
if (client->polling) {
del_waiter(client->device.control.fd);
del_waiter(client->device.ctl.fd);
client->polling = 0;
}
err = snd_ctl_close(client->device.control.handle);
err = snd_ctl_close(client->device.ctl.handle);
ctrl->result = err;
if (err < 0)
ERROR("snd_ctl_close");
@ -571,10 +594,24 @@ static int ctl_shm_cmd(client_t *client)
return -EBADFD;
cmd = ctrl->cmd;
ctrl->cmd = 0;
ctl = client->device.control.handle;
ctl = client->device.ctl.handle;
switch (cmd) {
case SND_CTL_IOCTL_ASYNC:
ctrl->result = snd_ctl_async(ctl, ctrl->u.async.sig, ctrl->u.async.pid);
if (ctrl->result < 0)
break;
if (ctrl->u.async.sig >= 0) {
assert(client->async_sig < 0);
ctrl->result = snd_async_add_ctl_handler(&client->async_handler, ctl, async_handler, client);
if (ctrl->result < 0)
break;
} else {
assert(client->async_sig >= 0);
snd_async_del_handler(client->async_handler);
}
client->async_sig = ctrl->u.async.sig;
client->async_pid = ctrl->u.async.pid;
break;
break;
case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
ctrl->result = snd_ctl_subscribe_events(ctl, ctrl->u.subscribe_events);

View file

@ -274,7 +274,9 @@ int snd_sctl_remove(snd_sctl_t *handle);
int snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode);
int snd_ctl_close(snd_ctl_t *ctl);
int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock);
int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid);
int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
snd_async_callback_t callback, void *private_data);
snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler);
int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl);
int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space);
int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe);
@ -515,7 +517,6 @@ typedef int (*snd_hctl_elem_callback_t)(snd_hctl_elem_t *elem,
int snd_hctl_open(snd_hctl_t **hctl, const char *name, int mode);
int snd_hctl_close(snd_hctl_t *hctl);
int snd_hctl_nonblock(snd_hctl_t *hctl, int nonblock);
int snd_hctl_async(snd_hctl_t *hctl, int sig, pid_t pid);
int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl);
int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int space);
unsigned int snd_hctl_get_count(snd_hctl_t *hctl);

View file

@ -18,3 +18,14 @@
/** \} */
/** Async notification client handler */
typedef struct _snd_async_handler snd_async_handler_t;
/** Async notification callback */
typedef void (*snd_async_callback_t)(snd_async_handler_t *handler);
int snd_async_add_handler(snd_async_handler_t **handler, int fd,
snd_async_callback_t callback, void *private_data);
int snd_async_del_handler(snd_async_handler_t *handler);
int snd_async_handler_get_fd(snd_async_handler_t *handler);
void *snd_async_handler_get_callback_private(snd_async_handler_t *handler);

View file

@ -49,6 +49,24 @@
#define _snd_hwdep_info sndrv_hwdep_info
#include "asoundlib.h"
#include "list.h"
struct _snd_async_handler {
enum {
SND_ASYNC_HANDLER_GENERIC,
SND_ASYNC_HANDLER_PCM,
SND_ASYNC_HANDLER_CTL,
} type;
int fd;
union {
snd_pcm_t *pcm;
snd_ctl_t *ctl;
} u;
snd_async_callback_t callback;
void *private_data;
struct list_head glist;
struct list_head hlist;
};
typedef enum _snd_set_mode {
SND_CHANGE,

View file

@ -305,7 +305,9 @@ int snd_pcm_close(snd_pcm_t *pcm);
int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm);
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid);
int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
snd_async_callback_t callback, void *private_data);
snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler);
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info);
int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
int snd_pcm_hw_free(snd_pcm_t *pcm);

View file

@ -2,7 +2,7 @@ SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat cards
COMPATNUM=@LIBTOOL_VERSION_INFO@
lib_LTLIBRARIES = libasound.la
libasound_la_SOURCES = conf.c confmisc.c input.c output.c error.c
libasound_la_SOURCES = conf.c confmisc.c input.c output.c async.c error.c
libasound_la_LIBADD = control/libcontrol.la mixer/libmixer.la pcm/libpcm.la \
rawmidi/librawmidi.la timer/libtimer.la \
hwdep/libhwdep.la seq/libseq.la instr/libinstr.la \

114
src/async.c Normal file
View file

@ -0,0 +1,114 @@
/*
* Async notification helpers
* Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "pcm/pcm_local.h"
#include "control/control_local.h"
#include <signal.h>
static struct list_head snd_async_handlers;
static void snd_async_handler(int signo ATTRIBUTE_UNUSED, siginfo_t *siginfo, void *context ATTRIBUTE_UNUSED)
{
int fd;
struct list_head *i;
assert(siginfo->si_code = SI_SIGIO);
fd = siginfo->si_fd;
list_for_each(i, &snd_async_handlers) {
snd_async_handler_t *h = list_entry(i, snd_async_handler_t, glist);
if (h->fd == fd) {
h->callback(h);
// break;
}
}
}
int snd_async_add_handler(snd_async_handler_t **handler, int fd,
snd_async_callback_t callback, void *private_data)
{
snd_async_handler_t *h;
int was_empty;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
h->fd = fd;
h->callback = callback;
h->private_data = private_data;
was_empty = list_empty(&snd_async_handlers);
list_add_tail(&h->glist, &snd_async_handlers);
*handler = h;
if (was_empty) {
int err;
struct sigaction act;
act.sa_flags = SA_RESTART | SA_SIGINFO;
act.sa_sigaction = snd_async_handler;
sigemptyset(&act.sa_mask);
err = sigaction(SIGIO, &act, NULL);
if (err < 0) {
SYSERR("sigaction");
return -errno;
}
}
return 0;
}
int snd_async_del_handler(snd_async_handler_t *handler)
{
int err = 0;
list_del(&handler->glist);
if (list_empty(&snd_async_handlers)) {
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = SIG_DFL;
err = sigaction(SIGIO, &act, NULL);
if (err < 0) {
SYSERR("sigaction");
return -errno;
}
}
if (handler->type == SND_ASYNC_HANDLER_GENERIC)
goto _end;
list_del(&handler->hlist);
if (!list_empty(&handler->hlist))
goto _end;
switch (handler->type) {
case SND_ASYNC_HANDLER_PCM:
err = snd_pcm_async(handler->u.pcm, -1, 1);
break;
case SND_ASYNC_HANDLER_CTL:
err = snd_ctl_async(handler->u.ctl, -1, 1);
break;
default:
assert(0);
}
_end:
free(handler);
return err;
}
int snd_async_handler_get_fd(snd_async_handler_t *handler)
{
return handler->fd;
}
void *snd_async_handler_get_callback_private(snd_async_handler_t *handler)
{
return handler->private_data;
}

View file

@ -25,7 +25,6 @@
#include <sys/stat.h>
#include <dlfcn.h>
#include "local.h"
#include "list.h"
#ifndef DOC_HIDDEN

View file

@ -74,12 +74,16 @@ snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl)
*/
int snd_ctl_close(snd_ctl_t *ctl)
{
int res;
res = ctl->ops->close(ctl);
int err;
while (!list_empty(&ctl->async_handlers)) {
snd_async_handler_t *h = list_entry(&ctl->async_handlers.next, snd_async_handler_t, hlist);
snd_async_del_handler(h);
}
err = ctl->ops->close(ctl);
if (ctl->name)
free(ctl->name);
free(ctl);
return res;
return err;
}
/**
@ -99,6 +103,22 @@ int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
return 0;
}
#ifndef DOC_HIDDEN
int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name)
{
snd_ctl_t *ctl;
ctl = calloc(1, sizeof(*ctl));
if (!ctl)
return -ENOMEM;
ctl->type = type;
if (name)
ctl->name = strdup(name);
INIT_LIST_HEAD(&ctl->async_handlers);
*ctlp = ctl;
return 0;
}
/**
* \brief set async mode
* \param ctl CTL handle
@ -110,21 +130,10 @@ int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
*/
int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid)
{
int err;
assert(ctl);
err = ctl->ops->async(ctl, sig, pid);
if (err < 0)
return err;
if (sig)
ctl->async_sig = sig;
else
ctl->async_sig = SIGIO;
if (pid)
ctl->async_pid = pid;
else
ctl->async_pid = getpid();
return 0;
return ctl->ops->async(ctl, sig, pid);
}
#endif
/**
* \brief get count of poll descriptors for CTL handle
@ -148,7 +157,7 @@ int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int s
{
assert(ctl);
if (space > 0) {
pfds->fd = ctl->ops->poll_descriptor(ctl);
pfds->fd = ctl->poll_fd;
pfds->events = POLLIN;
return 1;
}
@ -380,6 +389,50 @@ int snd_ctl_wait(snd_ctl_t *ctl, int timeout)
return 0;
}
/**
* \brief Add an async handler for a CTL
* \param handler Returned handler handle
* \param ctl CTL handle
* \param callback Callback function
* \param private_data Callback private data
* \return 0 otherwise a negative error code on failure
*/
int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
snd_async_callback_t callback, void *private_data)
{
int err;
int was_empty;
snd_async_handler_t *h;
err = snd_async_add_handler(&h, _snd_ctl_async_descriptor(ctl),
callback, private_data);
if (err < 0)
return err;
h->type = SND_ASYNC_HANDLER_CTL;
h->u.ctl = ctl;
was_empty = list_empty(&ctl->async_handlers);
list_add_tail(&h->hlist, &ctl->async_handlers);
if (was_empty) {
err = snd_ctl_async(ctl, getpid(), SIGIO);
if (err < 0) {
snd_async_del_handler(h);
return err;
}
}
*handler = h;
return 0;
}
/**
* \brief Return CTL handle related to an async handler
* \param handler Async handler handle
* \return CTL handle
*/
snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler)
{
assert(handler->type = SND_ASYNC_HANDLER_CTL);
return handler->u.ctl;
}
int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
snd_config_t *ctl_root, snd_config_t *ctl_conf, int mode)
{
@ -701,7 +754,7 @@ unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj)
int _snd_ctl_poll_descriptor(snd_ctl_t *ctl)
{
assert(ctl);
return ctl->ops->poll_descriptor(ctl);
return ctl->poll_fd;
}
#endif

View file

@ -105,12 +105,6 @@ static int snd_ctl_hw_async(snd_ctl_t *ctl, int sig, pid_t pid)
return 0;
}
static int snd_ctl_hw_poll_descriptor(snd_ctl_t *handle)
{
snd_ctl_hw_t *hw = handle->private_data;
return hw->fd;
}
static int snd_ctl_hw_subscribe_events(snd_ctl_t *handle, int subscribe)
{
snd_ctl_hw_t *hw = handle->private_data;
@ -257,7 +251,6 @@ snd_ctl_ops_t snd_ctl_hw_ops = {
close: snd_ctl_hw_close,
nonblock: snd_ctl_hw_nonblock,
async: snd_ctl_hw_async,
poll_descriptor: snd_ctl_hw_poll_descriptor,
subscribe_events: snd_ctl_hw_subscribe_events,
card_info: snd_ctl_hw_card_info,
element_list: snd_ctl_hw_elem_list,
@ -284,6 +277,7 @@ int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode)
int fmode;
snd_ctl_t *ctl;
snd_ctl_hw_t *hw;
int err;
*handle = NULL;
@ -308,24 +302,22 @@ int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode)
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;
if (name)
ctl->name = strdup(name);
ctl->type = SND_CTL_TYPE_HW;
err = snd_ctl_new(&ctl, SND_CTL_TYPE_HW, name);
if (err < 0) {
close(fd);
free(hw);
}
ctl->ops = &snd_ctl_hw_ops;
ctl->private_data = hw;
ctl->poll_fd = fd;
*handle = ctl;
return 0;
}

View file

@ -20,13 +20,11 @@
*/
#include "local.h"
#include "list.h"
typedef struct _snd_ctl_ops {
int (*close)(snd_ctl_t *handle);
int (*nonblock)(snd_ctl_t *handle, int nonblock);
int (*async)(snd_ctl_t *handle, int sig, pid_t pid);
int (*poll_descriptor)(snd_ctl_t *handle);
int (*subscribe_events)(snd_ctl_t *handle, int subscribe);
int (*card_info)(snd_ctl_t *handle, snd_ctl_card_info_t *info);
int (*element_list)(snd_ctl_t *handle, snd_ctl_elem_list_t *list);
@ -53,8 +51,8 @@ struct _snd_ctl {
snd_ctl_ops_t *ops;
void *private_data;
int nonblock;
int async_sig;
pid_t async_pid;
int poll_fd;
struct list_head async_handlers;
};
struct _snd_hctl_elem {
@ -80,6 +78,9 @@ struct _snd_hctl {
};
int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name);
int _snd_ctl_poll_descriptor(snd_ctl_t *ctl);
#define _snd_ctl_async_descriptor _snd_ctl_poll_descriptor
int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode);
int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname, const char *sname, int mode);
int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid);

View file

@ -124,7 +124,7 @@ static int snd_ctl_shm_subscribe_events(snd_ctl_t *ctl, int subscribe)
{
snd_ctl_shm_t *shm = ctl->private_data;
volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
ctrl->cmd = SND_CTL_IOCTL_POLL_DESCRIPTOR;
ctrl->cmd = SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS;
ctrl->u.subscribe_events = subscribe;
return snd_ctl_shm_action(ctl);
}
@ -368,7 +368,6 @@ snd_ctl_ops_t snd_ctl_shm_ops = {
close: snd_ctl_shm_close,
nonblock: snd_ctl_shm_nonblock,
async: snd_ctl_shm_async,
poll_descriptor: snd_ctl_shm_poll_descriptor,
subscribe_events: snd_ctl_shm_subscribe_events,
card_info: snd_ctl_shm_card_info,
element_list: snd_ctl_shm_elem_list,
@ -492,14 +491,8 @@ int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname
goto _err;
}
ctl = calloc(1, sizeof(snd_ctl_t));
if (!ctl) {
result = -ENOMEM;
goto _err;
}
shm = calloc(1, sizeof(snd_ctl_shm_t));
if (!shm) {
free(ctl);
result = -ENOMEM;
goto _err;
}
@ -507,11 +500,19 @@ int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname
shm->socket = sock;
shm->ctrl = ctrl;
if (name)
ctl->name = strdup(name);
ctl->type = SND_CTL_TYPE_SHM;
err = snd_ctl_new(&ctl, SND_CTL_TYPE_SHM, name);
if (err < 0) {
result = err;
goto _err;
}
ctl->ops = &snd_ctl_shm_ops;
ctl->private_data = shm;
err = snd_ctl_shm_poll_descriptor(ctl);
if (err < 0) {
snd_ctl_close(ctl);
return err;
}
ctl->poll_fd = err;
*handlep = ctl;
return 0;

View file

@ -34,7 +34,6 @@
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "list.h"
#include "local.h"
typedef struct {

View file

@ -20,7 +20,6 @@
*
*/
#include "list.h"
#include "local.h"
typedef struct _bag1 {

View file

@ -11,8 +11,6 @@ libpcm_la_SOURCES = atomic.c mask.c interval.c \
noinst_HEADERS = atomic.h pcm_local.h pcm_plugin.h mask.h mask_inline.h \
interval.h interval_inline.h plugin_ops.h
EXTRA_DIST = surround.conf
alsadir = $(datadir)/alsa
alsa_DATA = surround.conf

View file

@ -44,7 +44,6 @@
#include <limits.h>
#include <dlfcn.h>
#include "pcm_local.h"
#include "list.h"
/**
* \brief get identifier of PCM handle
@ -108,6 +107,10 @@ int snd_pcm_close(snd_pcm_t *pcm)
if (err < 0)
return err;
}
while (!list_empty(&pcm->async_handlers)) {
snd_async_handler_t *h = list_entry(&pcm->async_handlers.next, snd_async_handler_t, hlist);
snd_async_del_handler(h);
}
err = pcm->ops->close(pcm->op_arg);
if (err < 0)
return err;
@ -136,6 +139,7 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
return 0;
}
#ifndef DOC_HIDDEN
/**
* \brief set async mode
* \param pcm PCM handle
@ -147,21 +151,14 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
*/
int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)
{
int err;
assert(pcm);
err = pcm->ops->async(pcm->op_arg, sig, pid);
if (err < 0)
return err;
if (sig)
pcm->async_sig = sig;
else
pcm->async_sig = SIGIO;
if (pid)
pcm->async_pid = pid;
else
pcm->async_pid = getpid();
return 0;
if (sig == 0)
sig = SIGIO;
if (pid == 0)
pid = getpid();
return pcm->ops->async(pcm->op_arg, sig, pid);
}
#endif
/**
* \brief Obtain general (static) information for PCM handle
@ -911,6 +908,50 @@ ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples)
return samples * pcm->sample_bits / 8;
}
/**
* \brief Add an async handler for a PCM
* \param handler Returned handler handle
* \param pcm PCM handle
* \param callback Callback function
* \param private_data Callback private data
* \return 0 otherwise a negative error code on failure
*/
int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
snd_async_callback_t callback, void *private_data)
{
int err;
int was_empty;
snd_async_handler_t *h;
err = snd_async_add_handler(&h, _snd_pcm_async_descriptor(pcm),
callback, private_data);
if (err < 0)
return err;
h->type = SND_ASYNC_HANDLER_PCM;
h->u.pcm = pcm;
was_empty = list_empty(&pcm->async_handlers);
list_add_tail(&h->hlist, &pcm->async_handlers);
if (was_empty) {
err = snd_pcm_async(pcm, getpid(), SIGIO);
if (err < 0) {
snd_async_del_handler(h);
return err;
}
}
*handler = h;
return 0;
}
/**
* \brief Return PCM handle related to an async handler
* \param handler Async handler handle
* \return PCM handle
*/
snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler)
{
assert(handler->type = SND_ASYNC_HANDLER_PCM);
return handler->u.pcm;
}
static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
snd_config_t *pcm_root, snd_config_t *pcm_conf,
snd_pcm_stream_t stream, int mode)
@ -1045,6 +1086,26 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
}
#ifndef DOC_HIDDEN
int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
snd_pcm_stream_t stream, int mode)
{
snd_pcm_t *pcm;
pcm = calloc(1, sizeof(*pcm));
if (!pcm)
return -ENOMEM;
pcm->type = type;
if (name)
pcm->name = strdup(name);
pcm->stream = stream;
pcm->mode = mode;
pcm->op_arg = pcm;
pcm->fast_op_arg = pcm;
INIT_LIST_HEAD(&pcm->async_handlers);
*pcmp = pcm;
return 0;
}
int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
snd_config_t *conf, snd_pcm_stream_t stream,
int mode)

View file

@ -509,6 +509,7 @@ int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
{
snd_pcm_t *pcm;
snd_pcm_adpcm_t *adpcm;
int err;
assert(pcmp && slave);
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_IMA_ADPCM)
@ -524,20 +525,13 @@ int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
adpcm->plug.slave = slave;
adpcm->plug.close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_ADPCM, name, slave->stream, slave->mode);
if (err < 0) {
free(adpcm);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_ADPCM;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_adpcm_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_plugin_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = adpcm;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = &adpcm->plug.hw_ptr;

View file

@ -383,6 +383,7 @@ int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
{
snd_pcm_t *pcm;
snd_pcm_alaw_t *alaw;
int err;
assert(pcmp && slave);
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_A_LAW)
@ -397,20 +398,13 @@ int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
alaw->plug.slave = slave;
alaw->plug.close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_ALAW, name, slave->stream, slave->mode);
if (err < 0) {
free(alaw);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_ALAW;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_alaw_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_plugin_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = alaw;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = &alaw->plug.hw_ptr;

View file

@ -157,6 +157,7 @@ int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
{
snd_pcm_t *pcm;
snd_pcm_copy_t *copy;
int err;
assert(pcmp && slave);
copy = calloc(1, sizeof(snd_pcm_copy_t));
if (!copy) {
@ -167,20 +168,13 @@ int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
copy->plug.slave = slave;
copy->plug.close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_COPY, name, slave->stream, slave->mode);
if (err < 0) {
free(copy);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_COPY;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_copy_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_plugin_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = copy;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = &copy->plug.hw_ptr;

View file

@ -401,6 +401,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int
snd_pcm_t *pcm;
snd_pcm_file_t *file;
snd_pcm_file_format_t format;
int err;
assert(pcmp);
if (fmt == NULL ||
strcmp(fmt, "raw") == 0)
@ -430,22 +431,15 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int
file->slave = slave;
file->close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_FILE, name, slave->stream, slave->mode);
if (err < 0) {
if (fname)
free(file->fname);
free(file);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_FILE;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_file_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_file_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = file;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = slave->hw_ptr;

View file

@ -293,6 +293,7 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
snd_pcm_t *pcm;
snd_pcm_hooks_t *h;
unsigned int k;
int err;
assert(pcmp && slave);
h = calloc(1, sizeof(snd_pcm_hooks_t));
if (!h)
@ -302,20 +303,13 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
INIT_LIST_HEAD(&h->hooks[k]);
}
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_HOOKS, name, slave->stream, slave->mode);
if (err < 0) {
free(h);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_HOOKS;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_hooks_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_hooks_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = h;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = slave->hw_ptr;

View file

@ -88,14 +88,10 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid)
}
if (sig < 0)
return 0;
if (sig == 0)
sig = SIGIO;
if (fcntl(fd, F_SETSIG, sig) < 0) {
SYSERR("F_SETSIG failed");
return -errno;
}
if (pid == 0)
pid = getpid();
if (fcntl(fd, F_SETOWN, pid) < 0) {
SYSERR("F_SETOWN failed");
return -errno;
@ -531,12 +527,12 @@ snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
mmap_commit: snd_pcm_hw_mmap_commit,
};
static int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode)
int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode)
{
char filename[32];
const char *filefmt;
int ver;
int ret = 0, fd = -1;
int err, ret = 0, fd = -1;
int attempt = 0;
snd_pcm_info_t info;
int fmode;
@ -610,19 +606,14 @@ static int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int
hw->subdevice = subdevice;
hw->fd = fd;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
ret = -ENOMEM;
err = snd_pcm_new(&pcm, SND_PCM_TYPE_HW, name, stream, mode);
if (err < 0) {
ret = err;
goto _err;
}
snd_ctl_close(ctl);
pcm->type = SND_PCM_TYPE_HW;
pcm->stream = stream;
pcm->mode = mode;
pcm->ops = &snd_pcm_hw_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_hw_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = hw;
pcm->poll_fd = fd;
*pcmp = pcm;
@ -649,16 +640,6 @@ static int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int
return ret;
}
int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode)
{
int err = snd_pcm_hw_open_subdevice(pcmp, card, device, subdevice, stream, mode);
if (err < 0)
return err;
if (name)
(*pcmp)->name = strdup(name);
return 0;
}
int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)

View file

@ -289,6 +289,7 @@ int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
{
snd_pcm_t *pcm;
snd_pcm_linear_t *linear;
int err;
assert(pcmp && slave);
if (snd_pcm_format_linear(sformat) != 1)
return -EINVAL;
@ -302,20 +303,13 @@ int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
linear->plug.slave = slave;
linear->plug.close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_LINEAR, name, slave->stream, slave->mode);
if (err < 0) {
free(linear);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_LINEAR;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_linear_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_plugin_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = linear;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = &linear->plug.hw_ptr;

View file

@ -31,7 +31,6 @@
#define _snd_pcm_subformat_mask _snd_mask
#include "local.h"
#include "list.h"
#define SND_INTERVAL_INLINE
#include "interval.h"
@ -66,15 +65,6 @@ typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
#define SND_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_LAST_INTERVAL
#define SND_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_FIRST_INTERVAL
/** Surround type */
typedef enum _snd_pcm_surround_type {
/** 4.0 speakers */
SND_PCM_SURROUND_40 = 0,
/** 5.1 speakers */
SND_PCM_SURROUND_51 = 1,
SND_PCM_SURROUND_LAST = SND_PCM_SURROUND_51
} snd_pcm_surround_type_t;
typedef struct _snd_pcm_channel_info {
unsigned int channel;
void *addr; /* base address of channel samples */
@ -153,8 +143,6 @@ struct _snd_pcm {
snd_pcm_uframes_t silence_size; /* Silence filling size */
snd_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */
snd_pcm_uframes_t boundary; /* pointers wrap point */
int async_sig;
pid_t async_pid;
unsigned int info; /* Info for returned setup */
unsigned int msbits; /* used most significant bits */
unsigned int rate_num; /* rate numerator */
@ -175,6 +163,7 @@ struct _snd_pcm {
snd_pcm_t *op_arg;
snd_pcm_t *fast_op_arg;
void *private_data;
struct list_head async_handlers;
};
#define ROUTE_PLUGIN_FLOAT 1
@ -192,7 +181,10 @@ typedef int snd_pcm_route_ttable_entry_t;
/* FIXME */
#define _snd_pcm_link_descriptor _snd_pcm_poll_descriptor
#define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor
int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
snd_pcm_stream_t stream, int mode);
int snd_pcm_hw_open(snd_pcm_t **pcm, const char *name, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode);
int snd_pcm_plug_open(snd_pcm_t **pcmp,
const char *name,
@ -204,12 +196,11 @@ int snd_pcm_plug_open_hw(snd_pcm_t **pcm, const char *name, int card, int device
int snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, const char *sockname, const char *sname, snd_pcm_stream_t stream, int mode);
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int fd, const char *fmt, snd_pcm_t *slave, int close_slave);
int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode);
int snd_pcm_surround_open(snd_pcm_t **pcmp, const char *name, int card, int device, snd_pcm_surround_type_t type, snd_pcm_stream_t stream, int mode);
void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void *buf);
void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void **bufs);
int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid);
int snd_pcm_mmap(snd_pcm_t *pcm);
int snd_pcm_munmap(snd_pcm_t *pcm);
int snd_pcm_mmap_ready(snd_pcm_t *pcm);

View file

@ -30,7 +30,6 @@
#include <time.h>
#include <pthread.h>
#include <dlfcn.h>
#include "list.h"
#include "pcm_local.h"
#include "pcm_plugin.h"
@ -614,6 +613,7 @@ int snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, unsigned int frequenc
{
snd_pcm_t *pcm;
snd_pcm_meter_t *meter;
int err;
assert(pcmp);
meter = calloc(1, sizeof(snd_pcm_meter_t));
if (!meter)
@ -624,21 +624,14 @@ int snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, unsigned int frequenc
meter->delay.tv_nsec = 1000000000 / frequency;
INIT_LIST_HEAD(&meter->scopes);
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_METER, name, slave->stream, slave->mode);
if (err < 0) {
free(meter);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_METER;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->mmap_rw = 1;
pcm->ops = &snd_pcm_meter_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_meter_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = meter;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = slave->hw_ptr;

View file

@ -398,6 +398,7 @@ int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
{
snd_pcm_t *pcm;
snd_pcm_mulaw_t *mulaw;
int err;
assert(pcmp && slave);
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_MU_LAW)
@ -412,20 +413,13 @@ int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
mulaw->plug.slave = slave;
mulaw->plug.close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_MULAW, name, slave->stream, slave->mode);
if (err < 0) {
free(mulaw);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_MULAW;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_mulaw_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_plugin_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = mulaw;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = &mulaw->plug.hw_ptr;

View file

@ -587,6 +587,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
unsigned int i;
snd_pcm_stream_t stream;
char slave_map[32][32] = { { 0 } };
int err;
assert(pcmp);
assert(slaves_count > 0 && slaves_pcm && schannels_count);
@ -625,21 +626,15 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
}
multi->channels_count = channels_count;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_MULTI, name, stream,
multi->slaves[0].pcm->mode);
if (err < 0) {
free(multi);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_MULTI;
pcm->stream = stream;
pcm->mode = multi->slaves[0].pcm->mode;
pcm->mmap_rw = 1;
pcm->ops = &snd_pcm_multi_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_multi_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = multi;
pcm->poll_fd = multi->slaves[master_slave].pcm->poll_fd;
pcm->hw_ptr = multi->slaves[master_slave].pcm->hw_ptr;

View file

@ -318,6 +318,7 @@ int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t strea
snd_pcm_t *pcm;
snd_pcm_null_t *null;
int fd;
int err;
assert(pcmp);
if (stream == SND_PCM_STREAM_PLAYBACK) {
fd = open("/dev/null", O_WRONLY);
@ -340,21 +341,14 @@ int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t strea
null->poll_fd = fd;
null->state = SND_PCM_STATE_OPEN;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_NULL, name, stream, mode);
if (err < 0) {
close(fd);
free(null);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_NULL;
pcm->stream = stream;
pcm->mode = mode;
pcm->ops = &snd_pcm_null_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_null_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = null;
pcm->poll_fd = fd;
pcm->hw_ptr = &null->hw_ptr;

View file

@ -664,6 +664,7 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
{
snd_pcm_t *pcm;
snd_pcm_plug_t *plug;
int err;
assert(pcmp && slave);
plug = calloc(1, sizeof(snd_pcm_plug_t));
if (!plug)
@ -675,18 +676,12 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
plug->tt_cused = tt_cused;
plug->tt_sused = tt_sused;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_PLUG, name, slave->stream, slave->mode);
if (err < 0) {
free(plug);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_PLUG;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_plug_ops;
pcm->op_arg = pcm;
pcm->fast_ops = slave->fast_ops;
pcm->fast_op_arg = slave->fast_op_arg;
pcm->private_data = plug;

View file

@ -493,6 +493,7 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
{
snd_pcm_t *pcm;
snd_pcm_rate_t *rate;
int err;
assert(pcmp && slave);
if (sformat != SND_PCM_FORMAT_UNKNOWN &&
snd_pcm_format_linear(sformat) != 1)
@ -511,20 +512,13 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
rate->plug.slave = slave;
rate->plug.close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_RATE, name, slave->stream, slave->mode);
if (err < 0) {
free(rate);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_RATE;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_rate_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_plugin_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = rate;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = &rate->plug.hw_ptr;

View file

@ -747,20 +747,13 @@ int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
route->plug.slave = slave;
route->plug.close_slave = close_slave;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_ROUTE, name, slave->stream, slave->mode);
if (err < 0) {
free(route);
return -ENOMEM;
return err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_ROUTE;
pcm->stream = slave->stream;
pcm->mode = slave->mode;
pcm->ops = &snd_pcm_route_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_plugin_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = route;
pcm->poll_fd = slave->poll_fd;
pcm->hw_ptr = &route->plug.hw_ptr;

View file

@ -31,7 +31,6 @@
#include <sys/shm.h>
#include <pthread.h>
#include "pcm_local.h"
#include "list.h"
static LIST_HEAD(snd_pcm_share_slaves);
@ -1233,11 +1232,11 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
}
memcpy(share->slave_channels, channels_map, channels * sizeof(*share->slave_channels));
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
err = snd_pcm_new(&pcm, SND_PCM_TYPE_SHARE, name, stream, mode);
if (err < 0) {
free(share->slave_channels);
free(share);
return -ENOMEM;
return err;
}
err = socketpair(AF_LOCAL, SOCK_STREAM, 0, sd);
if (err < 0) {
@ -1343,16 +1342,9 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
share->client_socket = sd[0];
share->slave_socket = sd[1];
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_SHARE;
pcm->stream = stream;
pcm->mode = mode;
pcm->mmap_rw = 1;
pcm->ops = &snd_pcm_share_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_share_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = share;
pcm->poll_fd = share->client_socket;
pcm->hw_ptr = &share->hw_ptr;
@ -1415,8 +1407,8 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
return -EINVAL;
}
err = snd_pcm_slave_conf(root, slave, &sconf, 5,
SND_PCM_HW_PARAM_CHANNELS, 0, &schannels,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_CHANNELS, 0, &schannels,
SND_PCM_HW_PARAM_RATE, 0, &srate,
SND_PCM_HW_PARAM_PERIOD_TIME, 0, &speriod_time,
SND_PCM_HW_PARAM_BUFFER_TIME, 0, &sbuffer_time);
@ -1425,8 +1417,8 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
/* FIXME: nothing strictly forces to have named definition */
err = snd_config_get_string(sconf, &sname);
snd_config_delete(sconf);
if (err < 0) {
snd_config_delete(sconf);
SNDERR("slave.pcm is not a string");
return err;
}
@ -1441,7 +1433,6 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
const char *id = snd_config_get_id(n);
err = safe_strtol(id, &cchannel);
if (err < 0 || cchannel < 0) {
snd_config_delete(sconf);
SNDERR("Invalid client channel in binding: %s", id);
return -EINVAL;
}
@ -1449,7 +1440,6 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
channels = cchannel + 1;
}
if (channels == 0) {
snd_config_delete(sconf);
SNDERR("No bindings defined");
return -EINVAL;
}
@ -1463,7 +1453,6 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
cchannel = atoi(id);
err = snd_config_get_integer(n, &schannel);
if (err < 0) {
snd_config_delete(sconf);
goto _free;
}
assert(schannel >= 0);
@ -1478,7 +1467,6 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
(unsigned int) schannels,
speriod_time, sbuffer_time,
channels, channels_map, stream, mode);
snd_config_delete(sconf);
_free:
free(channels_map);
return err;

View file

@ -126,8 +126,6 @@ static int snd_pcm_shm_async(snd_pcm_t *pcm, int sig, pid_t pid)
volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
ctrl->cmd = SND_PCM_IOCTL_ASYNC;
ctrl->u.async.sig = sig;
if (pid == 0)
pid = getpid();
ctrl->u.async.pid = pid;
return snd_pcm_shm_action(pcm);
}
@ -638,21 +636,14 @@ int snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, const char *sockname, c
shm->socket = sock;
shm->ctrl = ctrl;
pcm = calloc(1, sizeof(snd_pcm_t));
if (!pcm) {
result = -ENOMEM;
err = snd_pcm_new(&pcm, SND_PCM_TYPE_SHM, name, stream, mode);
if (err < 0) {
result = err;
goto _err;
}
if (name)
pcm->name = strdup(name);
pcm->type = SND_PCM_TYPE_SHM;
pcm->stream = stream;
pcm->mode = mode;
pcm->mmap_rw = 1;
pcm->ops = &snd_pcm_shm_ops;
pcm->op_arg = pcm;
pcm->fast_ops = &snd_pcm_shm_fast_ops;
pcm->fast_op_arg = pcm;
pcm->private_data = shm;
err = snd_pcm_shm_poll_descriptor(pcm);
if (err < 0) {

File diff suppressed because it is too large Load diff

View file

@ -1,214 +0,0 @@
#
# Configuration for the surround plugin
#
surround_plugin.SI_7018 { # test only
channels_six = true;
open_multi {
device.0 = 0;
subdevice.0 = -1;
device.1 = 0;
subdevice.1 = -1;
device.2 = 0;
subdevice.2 = -1;
}
open_control.0 {
iface = MIXER;
name = 'CD Playback Switch';
index = 0;
lock = true;
preserve = true;
value.0 = 1;
value.1 = 1;
}
open_control.1 {
iface = MIXER;
name = 'CD Playback Volume';
index = 0;
lock = true;
preserve = true;
value.0 = 16;
value.1 = 19;
}
}
surround_plugin.FM801 {
channels_six = true;
open_single {
device = 0;
subdevice = 0;
}
}
surround_plugin.ENS1370 {
use_fd_four = 1;
open_multi {
device.0 = 1;
subdevice.0 = 0;
device.1 = 0;
subdevice.1 = 0;
}
# Reroute PCM0 (rear) to Line-In Jack.
open_control.0 {
iface = CARD;
name = 'PCM 0 Output also on Line-In Jack';
index = 0;
lock = true;
preserve = true;
value.0 = true;
}
# Turn off the PCM volume, the second PCM (front speakers) uses
# the second PCM control.
open_control.1 {
iface = MIXER;
name = 'PCM Switch';
index = 0;
lock = true;
preserve = true;
value.0 = false;
value.1 = false;
}
}
surround_plugin.YMFPCI {
open_multi {
device.0 = 0;
subdevice.0 = 0;
device.1 = 2;
subdevice.1 = 0;
}
}
surround_plugin.TRID4DWAVENX {
open_multi {
device.0 = 0;
subdevice.0 = -1;
device.1 = 0;
subdevice.1 = -1;
}
# Enable rear path
open_control.0 {
iface = MIXER;
name = 'Rear Path';
index = subdevice1;
lock = true;
value.0 = true;
}
# Mute front volume
open_control.1 {
iface = MIXER;
name = 'PCM Front Playback Volume';
index = subdevice1;
lock = true;
value.0 = 0;
value.1 = 0;
}
# Set reverb (rear) volume
open_control.2 {
iface = MIXER;
name = 'PCM Reverb Playback Volume';
index = subdevice1;
lock = true;
value.0 = 127;
value.1 = 127;
}
}
surround_plugin.INTEL8X0 {
channels_six = true;
route_four {
channel.0 = 0; # FR = FR
channel.1 = 1; # FL = FL
channel.2 = 2; # SR = SR
channel.3 = 3; # SL = SL
}
route_six {
channel.0 = 0; # FR = FR
channel.1 = 1; # FL = FL
channel.2 = 4; # SR = Center
channel.3 = 5; # SL = LFE
channel.4 = 2; # Center = SR
channel.5 = 3; # LFE = SL
}
open_single {
device = 0;
subdevice = 0;
}
}
surround_plugin.EMU10K1 {
channels_six = true;
use_fd_four = 1;
use_fd_six = 2;
open_multi {
device.0 = 0;
subdevice.0 = -1;
device.1 = 0;
subdevice.1 = -1;
device.2 = 0;
subdevice.2 = -1;
}
open_control_four.0 {
iface = MIXER;
name = 'Wave Surround Playback Volume';
index = 0;
lock = true;
preserve = true;
value.0 = 0;
value.1 = 0;
}
# change send volume from front to rear
open_control_four.1 {
iface = MIXER;
name = 'EMU10K1 PCM Send Volume';
index = subdevice1;
lock = true;
value.4 = 0;
value.5 = 0;
value.6 = 255;
value.7 = 0;
value.8 = 0;
value.9 = 0;
value.10 = 0;
value.11 = 255;
}
open_control_six.0 {
iface = MIXER;
name = 'Wave Surround Playback Volume';
index = 0;
lock = true;
preserve = true;
value.0 = 0;
value.1 = 0;
}
# change send volume from front to rear
open_control_six.1 {
iface = MIXER;
name = 'EMU10K1 PCM Send Volume';
index = subdevice1;
lock = true;
value.4 = 0;
value.5 = 0;
value.6 = 255;
value.7 = 0;
value.8 = 0;
value.9 = 0;
value.10 = 0;
value.11 = 255;
}
# send routing must be changed to 6 (center) and 7 (LFE)
open_control_six.2 {
iface = MIXER;
name = 'EMU10K1 PCM Send Routing';
index = subdevice2;
lock = true;
value.4 = 6;
value.5 = 7;
value.6 = 0;
value.7 = 1;
value.8 = 6;
value.9 = 7;
value.10 = 0;
value.11 = 1;
}
}