mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-28 05:40:23 -04:00
New async notification API. Removed obsolete surround. Cleaning
This commit is contained in:
parent
57469ec597
commit
157f47aedd
35 changed files with 436 additions and 1581 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
114
src/async.c
Normal 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;
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +25,6 @@
|
|||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include "local.h"
|
||||
#include "list.h"
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "list.h"
|
||||
#include "local.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "list.h"
|
||||
#include "local.h"
|
||||
|
||||
typedef struct _bag1 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 = ©->plug.hw_ptr;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
1090
src/pcm/pcm_surr.c
1090
src/pcm/pcm_surr.c
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue