mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Added support for async. Added error callback (and begun to use it). First implementation of pcm_share
This commit is contained in:
parent
d07934a537
commit
dcc88ffaa7
20 changed files with 1363 additions and 32 deletions
|
|
@ -353,6 +353,9 @@ int pcm_shm_cmd(client_t *client)
|
||||||
ctrl->cmd = 0;
|
ctrl->cmd = 0;
|
||||||
pcm = client->device.pcm.handle;
|
pcm = client->device.pcm.handle;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case SND_PCM_IOCTL_ASYNC:
|
||||||
|
ctrl->result = snd_pcm_async(pcm, ctrl->u.async.sig, ctrl->u.async.pid);
|
||||||
|
break;
|
||||||
case SND_PCM_IOCTL_INFO:
|
case SND_PCM_IOCTL_INFO:
|
||||||
ctrl->result = snd_pcm_info(pcm, &ctrl->u.info);
|
ctrl->result = snd_pcm_info(pcm, &ctrl->u.info);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,19 @@
|
||||||
#define SND_PCM_IOCTL_MUNMAP_DATA _IO ('A', 0xf4)
|
#define SND_PCM_IOCTL_MUNMAP_DATA _IO ('A', 0xf4)
|
||||||
#define SND_PCM_IOCTL_MUNMAP_CONTROL _IO ('A', 0xf5)
|
#define SND_PCM_IOCTL_MUNMAP_CONTROL _IO ('A', 0xf5)
|
||||||
#define SND_PCM_IOCTL_MUNMAP_STATUS _IO ('A', 0xf6)
|
#define SND_PCM_IOCTL_MUNMAP_STATUS _IO ('A', 0xf6)
|
||||||
#define SND_PCM_IOCTL_MMAP_FORWARD _IOW('A', 0xf7, size_t)
|
#define SND_PCM_IOCTL_MMAP_FORWARD _IO ('A', 0xf7)
|
||||||
#define SND_PCM_IOCTL_AVAIL_UPDATE _IO ('A', 0xf8)
|
#define SND_PCM_IOCTL_AVAIL_UPDATE _IO ('A', 0xf8)
|
||||||
#define SND_PCM_IOCTL_CLOSE _IO ('A', 0xf9)
|
#define SND_PCM_IOCTL_ASYNC _IO ('A', 0xf9)
|
||||||
|
#define SND_PCM_IOCTL_CLOSE _IO ('A', 0xfa)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
long result;
|
long result;
|
||||||
int cmd;
|
int cmd;
|
||||||
union {
|
union {
|
||||||
|
struct {
|
||||||
|
int sig;
|
||||||
|
pid_t pid;
|
||||||
|
} async;
|
||||||
snd_pcm_info_t info;
|
snd_pcm_info_t info;
|
||||||
snd_pcm_params_t params;
|
snd_pcm_params_t params;
|
||||||
snd_pcm_params_info_t params_info;
|
snd_pcm_params_info_t params_info;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define SND_PCM_NONBLOCK 0x0001
|
#define SND_PCM_NONBLOCK 0x0001
|
||||||
|
#define SND_PCM_ASYNC 0x0002
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -117,6 +118,7 @@ typedef enum {
|
||||||
SND_PCM_TYPE_LBSERVER,
|
SND_PCM_TYPE_LBSERVER,
|
||||||
} snd_pcm_type_t;
|
} snd_pcm_type_t;
|
||||||
|
|
||||||
|
extern void (*snd_pcm_error)(const char *file, int line, const char *function, const char *fmt, ...);
|
||||||
|
|
||||||
int snd_pcm_open(snd_pcm_t **handle, char *name,
|
int snd_pcm_open(snd_pcm_t **handle, char *name,
|
||||||
int stream, int mode);
|
int stream, int mode);
|
||||||
|
|
@ -136,6 +138,7 @@ snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
|
||||||
int snd_pcm_close(snd_pcm_t *pcm);
|
int snd_pcm_close(snd_pcm_t *pcm);
|
||||||
int snd_pcm_poll_descriptor(snd_pcm_t *pcm);
|
int snd_pcm_poll_descriptor(snd_pcm_t *pcm);
|
||||||
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
|
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_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info);
|
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info);
|
||||||
int snd_pcm_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t *info);
|
int snd_pcm_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t *info);
|
||||||
int snd_pcm_params(snd_pcm_t *pcm, snd_pcm_params_t *params);
|
int snd_pcm_params(snd_pcm_t *pcm, snd_pcm_params_t *params);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ EXTRA_LTLIBRARIES = libpcm.la
|
||||||
|
|
||||||
libpcm_la_SOURCES = pcm.c pcm_hw.c pcm_plugin.c pcm_linear.c pcm_route.c \
|
libpcm_la_SOURCES = pcm.c pcm_hw.c pcm_plugin.c pcm_linear.c pcm_route.c \
|
||||||
pcm_mulaw.c pcm_alaw.c pcm_adpcm.c pcm_rate.c pcm_plug.c \
|
pcm_mulaw.c pcm_alaw.c pcm_adpcm.c pcm_rate.c pcm_plug.c \
|
||||||
pcm_misc.c pcm_mmap.c pcm_multi.c pcm_client.c pcm_file.c
|
pcm_misc.c pcm_mmap.c pcm_multi.c pcm_client.c pcm_file.c \
|
||||||
|
pcm_share.c
|
||||||
noinst_HEADERS = pcm_local.h pcm_plugin.h
|
noinst_HEADERS = pcm_local.h pcm_plugin.h
|
||||||
|
|
||||||
all: libpcm.la
|
all: libpcm.la
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
@ -83,7 +84,7 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
assert(pcm);
|
assert(pcm);
|
||||||
if ((err = pcm->ops->nonblock(pcm->fast_op_arg, nonblock)) < 0)
|
if ((err = pcm->ops->nonblock(pcm->op_arg, nonblock)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (nonblock)
|
if (nonblock)
|
||||||
pcm->mode |= SND_PCM_NONBLOCK;
|
pcm->mode |= SND_PCM_NONBLOCK;
|
||||||
|
|
@ -92,6 +93,12 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
|
{
|
||||||
|
assert(pcm);
|
||||||
|
return pcm->ops->async(pcm->op_arg, sig, pid);
|
||||||
|
}
|
||||||
|
|
||||||
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
||||||
{
|
{
|
||||||
assert(pcm && info);
|
assert(pcm && info);
|
||||||
|
|
@ -1037,3 +1044,14 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void snd_pcm_error_default(const char *file, int line, const char *function, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
va_start(arg, fmt);
|
||||||
|
fprintf(stderr, "ALSA PCM lib %s:%i:(%s) ", file, line, function);
|
||||||
|
vfprintf(stderr, fmt, arg);
|
||||||
|
putc('\n', stderr);
|
||||||
|
va_end(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*snd_pcm_error)(const char *file, int line, const char *function, const char *fmt, ...) = snd_pcm_error_default;
|
||||||
|
|
|
||||||
|
|
@ -544,6 +544,7 @@ struct snd_pcm_ops snd_pcm_adpcm_ops = {
|
||||||
channel_setup: snd_pcm_plugin_channel_setup,
|
channel_setup: snd_pcm_plugin_channel_setup,
|
||||||
dump: snd_pcm_adpcm_dump,
|
dump: snd_pcm_adpcm_dump,
|
||||||
nonblock: snd_pcm_plugin_nonblock,
|
nonblock: snd_pcm_plugin_nonblock,
|
||||||
|
async: snd_pcm_plugin_async,
|
||||||
mmap_status: snd_pcm_plugin_mmap_status,
|
mmap_status: snd_pcm_plugin_mmap_status,
|
||||||
mmap_control: snd_pcm_plugin_mmap_control,
|
mmap_control: snd_pcm_plugin_mmap_control,
|
||||||
mmap_data: snd_pcm_plugin_mmap_data,
|
mmap_data: snd_pcm_plugin_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -412,6 +412,7 @@ struct snd_pcm_ops snd_pcm_alaw_ops = {
|
||||||
channel_setup: snd_pcm_plugin_channel_setup,
|
channel_setup: snd_pcm_plugin_channel_setup,
|
||||||
dump: snd_pcm_alaw_dump,
|
dump: snd_pcm_alaw_dump,
|
||||||
nonblock: snd_pcm_plugin_nonblock,
|
nonblock: snd_pcm_plugin_nonblock,
|
||||||
|
async: snd_pcm_plugin_async,
|
||||||
mmap_status: snd_pcm_plugin_mmap_status,
|
mmap_status: snd_pcm_plugin_mmap_status,
|
||||||
mmap_control: snd_pcm_plugin_mmap_control,
|
mmap_control: snd_pcm_plugin_mmap_control,
|
||||||
mmap_data: snd_pcm_plugin_mmap_data,
|
mmap_data: snd_pcm_plugin_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,22 @@ static int snd_pcm_client_shm_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonb
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_client_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
|
{
|
||||||
|
snd_pcm_client_t *client = pcm->private;
|
||||||
|
snd_pcm_client_shm_t *ctrl = client->u.shm.ctrl;
|
||||||
|
int err;
|
||||||
|
ctrl->cmd = SND_PCM_IOCTL_ASYNC;
|
||||||
|
ctrl->u.async.sig = sig;
|
||||||
|
if (pid == 0)
|
||||||
|
pid = getpid();
|
||||||
|
ctrl->u.async.pid = pid;
|
||||||
|
err = snd_pcm_client_shm_action(pcm);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
return ctrl->result;
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_pcm_client_shm_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
static int snd_pcm_client_shm_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
{
|
{
|
||||||
snd_pcm_client_t *client = pcm->private;
|
snd_pcm_client_t *client = pcm->private;
|
||||||
|
|
@ -550,6 +566,7 @@ struct snd_pcm_ops snd_pcm_client_ops = {
|
||||||
channel_setup: snd_pcm_client_shm_channel_setup,
|
channel_setup: snd_pcm_client_shm_channel_setup,
|
||||||
dump: snd_pcm_client_dump,
|
dump: snd_pcm_client_dump,
|
||||||
nonblock: snd_pcm_client_shm_nonblock,
|
nonblock: snd_pcm_client_shm_nonblock,
|
||||||
|
async: snd_pcm_client_async,
|
||||||
mmap_status: snd_pcm_client_shm_mmap_status,
|
mmap_status: snd_pcm_client_shm_mmap_status,
|
||||||
mmap_control: snd_pcm_client_shm_mmap_control,
|
mmap_control: snd_pcm_client_shm_mmap_control,
|
||||||
mmap_data: snd_pcm_client_shm_mmap_data,
|
mmap_data: snd_pcm_client_shm_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@ static int snd_pcm_file_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||||
return snd_pcm_nonblock(file->slave, nonblock);
|
return snd_pcm_nonblock(file->slave, nonblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_file_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
|
{
|
||||||
|
snd_pcm_file_t *file = pcm->private;
|
||||||
|
return snd_pcm_async(file->slave, sig, pid);
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
static int snd_pcm_file_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
|
|
@ -342,6 +348,7 @@ struct snd_pcm_ops snd_pcm_file_ops = {
|
||||||
channel_setup: snd_pcm_file_channel_setup,
|
channel_setup: snd_pcm_file_channel_setup,
|
||||||
dump: snd_pcm_file_dump,
|
dump: snd_pcm_file_dump,
|
||||||
nonblock: snd_pcm_file_nonblock,
|
nonblock: snd_pcm_file_nonblock,
|
||||||
|
async: snd_pcm_file_async,
|
||||||
mmap_status: snd_pcm_file_mmap_status,
|
mmap_status: snd_pcm_file_mmap_status,
|
||||||
mmap_control: snd_pcm_file_mmap_control,
|
mmap_control: snd_pcm_file_mmap_control,
|
||||||
mmap_data: snd_pcm_file_mmap_data,
|
mmap_data: snd_pcm_file_mmap_data,
|
||||||
|
|
|
||||||
143
src/pcm/pcm_hw.c
143
src/pcm/pcm_hw.c
|
|
@ -22,6 +22,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
@ -29,6 +30,10 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "pcm_local.h"
|
#include "pcm_local.h"
|
||||||
|
|
||||||
|
#ifndef F_SETSIG
|
||||||
|
#define F_SETSIG 10
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int fd;
|
int fd;
|
||||||
int card, device, subdevice;
|
int card, device, subdevice;
|
||||||
|
|
@ -44,9 +49,10 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm)
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
free(hw);
|
free(hw);
|
||||||
if (fd >= 0)
|
if (close(fd)) {
|
||||||
if (close(fd))
|
ERR("close failed\n");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,14 +62,53 @@ static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
|
|
||||||
if ((flags = fcntl(fd, F_GETFL)) < 0)
|
if ((flags = fcntl(fd, F_GETFL)) < 0) {
|
||||||
|
ERR("F_GETFL failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
if (nonblock)
|
if (nonblock)
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
else
|
else
|
||||||
flags &= ~O_NONBLOCK;
|
flags &= ~O_NONBLOCK;
|
||||||
if (fcntl(fd, F_SETFL, flags) < 0)
|
if (fcntl(fd, F_SETFL, flags) < 0) {
|
||||||
|
ERR("F_SETFL for O_NONBLOCK failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
|
{
|
||||||
|
long flags;
|
||||||
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
|
int fd = hw->fd;
|
||||||
|
|
||||||
|
if ((flags = fcntl(fd, F_GETFL)) < 0) {
|
||||||
|
ERR("F_GETFL failed");
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
if (sig >= 0)
|
||||||
|
flags |= O_ASYNC;
|
||||||
|
else
|
||||||
|
flags &= ~O_ASYNC;
|
||||||
|
if (fcntl(fd, F_SETFL, flags) < 0) {
|
||||||
|
ERR("F_SETFL for O_ASYNC failed");
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
if (sig < 0)
|
||||||
|
return 0;
|
||||||
|
if (sig == 0)
|
||||||
|
sig = SIGIO;
|
||||||
|
if (fcntl(fd, F_SETSIG, sig) < 0) {
|
||||||
|
ERR("F_SETSIG failed");
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
if (pid == 0)
|
||||||
|
pid = getpid();
|
||||||
|
if (fcntl(fd, F_SETOWN, pid) < 0) {
|
||||||
|
ERR("F_SETOWN failed");
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,8 +116,10 @@ static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_INFO, info) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_INFO, info) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_INFO failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,8 +127,10 @@ static int snd_pcm_hw_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t * info)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_PARAMS_INFO, info) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_PARAMS_INFO, info) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_PARAMS_INFO failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,8 +138,10 @@ static int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_params_t * params)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_PARAMS, params) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_PARAMS, params) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_PARAMS failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,8 +149,10 @@ static int snd_pcm_hw_setup(snd_pcm_t *pcm, snd_pcm_setup_t * setup)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_SETUP, setup) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_SETUP, setup) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_SETUP failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
if (setup->mmap_shape == SND_PCM_MMAP_UNSPECIFIED) {
|
if (setup->mmap_shape == SND_PCM_MMAP_UNSPECIFIED) {
|
||||||
if (setup->xfer_mode == SND_PCM_XFER_INTERLEAVED)
|
if (setup->xfer_mode == SND_PCM_XFER_INTERLEAVED)
|
||||||
setup->mmap_shape = SND_PCM_MMAP_INTERLEAVED;
|
setup->mmap_shape = SND_PCM_MMAP_INTERLEAVED;
|
||||||
|
|
@ -115,8 +168,10 @@ static int snd_pcm_hw_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, info) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, info) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_CHANNEL_INFO failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,8 +179,10 @@ static int snd_pcm_hw_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t *
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PARAMS, params) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PARAMS, params) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_CHANNEL_PARAMS failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,8 +190,10 @@ static int snd_pcm_hw_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * se
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_CHANNEL_SETUP failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
if (hw->mmap_emulation) {
|
if (hw->mmap_emulation) {
|
||||||
if (pcm->setup.mmap_shape == SND_PCM_MMAP_INTERLEAVED) {
|
if (pcm->setup.mmap_shape == SND_PCM_MMAP_INTERLEAVED) {
|
||||||
setup->running_area.addr = pcm->mmap_data;
|
setup->running_area.addr = pcm->mmap_data;
|
||||||
|
|
@ -157,8 +216,10 @@ static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_STATUS, status) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STATUS, status) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_STATUS failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,8 +232,10 @@ static int snd_pcm_hw_delay(snd_pcm_t *pcm, ssize_t *delayp)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_DELAY, delayp) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_DELAY, delayp) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_DELAY failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,8 +243,10 @@ static int snd_pcm_hw_prepare(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_PREPARE) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_PREPARE) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_PREPARE failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,8 +254,10 @@ static int snd_pcm_hw_start(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_START) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_START) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_START failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,8 +265,10 @@ static int snd_pcm_hw_drop(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_DROP) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_DROP) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_DROP failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,8 +276,10 @@ static int snd_pcm_hw_drain(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_DRAIN) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_DRAIN) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_DRAIN failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,8 +287,10 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_PAUSE, enable) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_PAUSE, enable) < 0) {
|
||||||
|
ERR("SND_PCM_IOCTL_PAUSE failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -301,8 +374,10 @@ static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm)
|
||||||
void *ptr;
|
void *ptr;
|
||||||
ptr = mmap(NULL, sizeof(snd_pcm_mmap_status_t), PROT_READ, MAP_FILE|MAP_SHARED,
|
ptr = mmap(NULL, sizeof(snd_pcm_mmap_status_t), PROT_READ, MAP_FILE|MAP_SHARED,
|
||||||
hw->fd, SND_PCM_MMAP_OFFSET_STATUS);
|
hw->fd, SND_PCM_MMAP_OFFSET_STATUS);
|
||||||
if (ptr == MAP_FAILED || ptr == NULL)
|
if (ptr == MAP_FAILED || ptr == NULL) {
|
||||||
|
ERR("status mmap failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
pcm->mmap_status = ptr;
|
pcm->mmap_status = ptr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -313,8 +388,10 @@ static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm)
|
||||||
void *ptr;
|
void *ptr;
|
||||||
ptr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
|
ptr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
|
||||||
hw->fd, SND_PCM_MMAP_OFFSET_CONTROL);
|
hw->fd, SND_PCM_MMAP_OFFSET_CONTROL);
|
||||||
if (ptr == MAP_FAILED || ptr == NULL)
|
if (ptr == MAP_FAILED || ptr == NULL) {
|
||||||
|
ERR("control mmap failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
pcm->mmap_control = ptr;
|
pcm->mmap_control = ptr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -333,8 +410,10 @@ static int snd_pcm_hw_mmap_data(snd_pcm_t *pcm)
|
||||||
ptr = mmap(NULL, pcm->setup.mmap_bytes,
|
ptr = mmap(NULL, pcm->setup.mmap_bytes,
|
||||||
prot, MAP_FILE|MAP_SHARED,
|
prot, MAP_FILE|MAP_SHARED,
|
||||||
hw->fd, SND_PCM_MMAP_OFFSET_DATA);
|
hw->fd, SND_PCM_MMAP_OFFSET_DATA);
|
||||||
if (ptr == MAP_FAILED || ptr == NULL)
|
if (ptr == MAP_FAILED || ptr == NULL) {
|
||||||
|
ERR("data mmap failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pcm->mmap_data = ptr;
|
pcm->mmap_data = ptr;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -342,15 +421,19 @@ static int snd_pcm_hw_mmap_data(snd_pcm_t *pcm)
|
||||||
|
|
||||||
static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm)
|
static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
if (munmap((void*)pcm->mmap_status, sizeof(*pcm->mmap_status)) < 0)
|
if (munmap((void*)pcm->mmap_status, sizeof(*pcm->mmap_status)) < 0) {
|
||||||
|
ERR("status munmap failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm)
|
static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
if (munmap(pcm->mmap_control, sizeof(*pcm->mmap_control)) < 0)
|
if (munmap(pcm->mmap_control, sizeof(*pcm->mmap_control)) < 0) {
|
||||||
|
ERR("control munmap failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -360,8 +443,10 @@ static int snd_pcm_hw_munmap_data(snd_pcm_t *pcm)
|
||||||
if (hw->mmap_emulation)
|
if (hw->mmap_emulation)
|
||||||
free(pcm->mmap_data);
|
free(pcm->mmap_data);
|
||||||
else
|
else
|
||||||
if (munmap(pcm->mmap_data, pcm->setup.mmap_bytes) < 0)
|
if (munmap(pcm->mmap_data, pcm->setup.mmap_bytes) < 0) {
|
||||||
|
ERR("data munmap failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -377,15 +462,14 @@ static ssize_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, size_t size)
|
||||||
static ssize_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
|
static ssize_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = pcm->private;
|
snd_pcm_hw_t *hw = pcm->private;
|
||||||
int fd = hw->fd;
|
|
||||||
size_t avail;
|
size_t avail;
|
||||||
ssize_t err;
|
ssize_t err;
|
||||||
if (pcm->setup.ready_mode == SND_PCM_READY_ASAP ||
|
if (pcm->setup.ready_mode == SND_PCM_READY_ASAP ||
|
||||||
pcm->setup.xrun_mode == SND_PCM_XRUN_ASAP) {
|
pcm->setup.xrun_mode == SND_PCM_XRUN_ASAP) {
|
||||||
ssize_t d;
|
ssize_t d;
|
||||||
int err = ioctl(fd, SND_PCM_IOCTL_DELAY, &d);
|
int err = snd_pcm_hw_delay(pcm, &d);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return -errno;
|
return err;
|
||||||
}
|
}
|
||||||
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
|
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
|
||||||
avail = snd_pcm_mmap_playback_avail(pcm);
|
avail = snd_pcm_mmap_playback_avail(pcm);
|
||||||
|
|
@ -441,6 +525,7 @@ struct snd_pcm_ops snd_pcm_hw_ops = {
|
||||||
channel_setup: snd_pcm_hw_channel_setup,
|
channel_setup: snd_pcm_hw_channel_setup,
|
||||||
dump: snd_pcm_hw_dump,
|
dump: snd_pcm_hw_dump,
|
||||||
nonblock: snd_pcm_hw_nonblock,
|
nonblock: snd_pcm_hw_nonblock,
|
||||||
|
async: snd_pcm_hw_async,
|
||||||
mmap_status: snd_pcm_hw_mmap_status,
|
mmap_status: snd_pcm_hw_mmap_status,
|
||||||
mmap_control: snd_pcm_hw_mmap_control,
|
mmap_control: snd_pcm_hw_mmap_control,
|
||||||
mmap_data: snd_pcm_hw_mmap_data,
|
mmap_data: snd_pcm_hw_mmap_data,
|
||||||
|
|
@ -509,6 +594,8 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int sub
|
||||||
fmode = O_RDWR;
|
fmode = O_RDWR;
|
||||||
if (mode & SND_PCM_NONBLOCK)
|
if (mode & SND_PCM_NONBLOCK)
|
||||||
fmode |= O_NONBLOCK;
|
fmode |= O_NONBLOCK;
|
||||||
|
if (mode & SND_PCM_ASYNC)
|
||||||
|
fmode |= O_ASYNC;
|
||||||
if ((fd = open(filename, fmode)) < 0) {
|
if ((fd = open(filename, fmode)) < 0) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
goto __end;
|
goto __end;
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,7 @@ struct snd_pcm_ops snd_pcm_linear_ops = {
|
||||||
channel_setup: snd_pcm_plugin_channel_setup,
|
channel_setup: snd_pcm_plugin_channel_setup,
|
||||||
dump: snd_pcm_linear_dump,
|
dump: snd_pcm_linear_dump,
|
||||||
nonblock: snd_pcm_plugin_nonblock,
|
nonblock: snd_pcm_plugin_nonblock,
|
||||||
|
async: snd_pcm_plugin_async,
|
||||||
mmap_status: snd_pcm_plugin_mmap_status,
|
mmap_status: snd_pcm_plugin_mmap_status,
|
||||||
mmap_control: snd_pcm_plugin_mmap_control,
|
mmap_control: snd_pcm_plugin_mmap_control,
|
||||||
mmap_data: snd_pcm_plugin_mmap_data,
|
mmap_data: snd_pcm_plugin_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,16 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "asoundlib.h"
|
#include "asoundlib.h"
|
||||||
|
|
||||||
|
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
|
||||||
|
#define ERR(...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define ERR(args...) snd_pcm_error(__FILE__, __LINE__, __FUNCTION__, ##args)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct snd_pcm_ops {
|
struct snd_pcm_ops {
|
||||||
int (*close)(snd_pcm_t *pcm);
|
int (*close)(snd_pcm_t *pcm);
|
||||||
int (*nonblock)(snd_pcm_t *pcm, int nonblock);
|
int (*nonblock)(snd_pcm_t *pcm, int nonblock);
|
||||||
|
int (*async)(snd_pcm_t *pcm, int sig, pid_t pid);
|
||||||
int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
|
int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
|
||||||
int (*params_info)(snd_pcm_t *pcm, snd_pcm_params_info_t *info);
|
int (*params_info)(snd_pcm_t *pcm, snd_pcm_params_info_t *info);
|
||||||
int (*params)(snd_pcm_t *pcm, snd_pcm_params_t *params);
|
int (*params)(snd_pcm_t *pcm, snd_pcm_params_t *params);
|
||||||
|
|
|
||||||
|
|
@ -429,6 +429,7 @@ struct snd_pcm_ops snd_pcm_mulaw_ops = {
|
||||||
channel_setup: snd_pcm_plugin_channel_setup,
|
channel_setup: snd_pcm_plugin_channel_setup,
|
||||||
dump: snd_pcm_mulaw_dump,
|
dump: snd_pcm_mulaw_dump,
|
||||||
nonblock: snd_pcm_plugin_nonblock,
|
nonblock: snd_pcm_plugin_nonblock,
|
||||||
|
async: snd_pcm_plugin_async,
|
||||||
mmap_status: snd_pcm_plugin_mmap_status,
|
mmap_status: snd_pcm_plugin_mmap_status,
|
||||||
mmap_control: snd_pcm_plugin_mmap_control,
|
mmap_control: snd_pcm_plugin_mmap_control,
|
||||||
mmap_data: snd_pcm_plugin_mmap_data,
|
mmap_data: snd_pcm_plugin_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,13 @@ static int snd_pcm_multi_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_multi_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
|
{
|
||||||
|
snd_pcm_multi_t *multi = pcm->private;
|
||||||
|
snd_pcm_t *slave_0 = multi->slaves[0].pcm;
|
||||||
|
return snd_pcm_async(slave_0, sig, pid);
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_pcm_multi_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
static int snd_pcm_multi_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
||||||
{
|
{
|
||||||
snd_pcm_multi_t *multi = pcm->private;
|
snd_pcm_multi_t *multi = pcm->private;
|
||||||
|
|
@ -504,6 +511,7 @@ struct snd_pcm_ops snd_pcm_multi_ops = {
|
||||||
channel_setup: snd_pcm_multi_channel_setup,
|
channel_setup: snd_pcm_multi_channel_setup,
|
||||||
dump: snd_pcm_multi_dump,
|
dump: snd_pcm_multi_dump,
|
||||||
nonblock: snd_pcm_multi_nonblock,
|
nonblock: snd_pcm_multi_nonblock,
|
||||||
|
async: snd_pcm_multi_async,
|
||||||
mmap_status: snd_pcm_multi_mmap_status,
|
mmap_status: snd_pcm_multi_mmap_status,
|
||||||
mmap_control: snd_pcm_multi_mmap_control,
|
mmap_control: snd_pcm_multi_mmap_control,
|
||||||
mmap_data: snd_pcm_multi_mmap_data,
|
mmap_data: snd_pcm_multi_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,12 @@ static int snd_pcm_plug_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||||
return snd_pcm_nonblock(plug->slave, nonblock);
|
return snd_pcm_nonblock(plug->slave, nonblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_plug_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
|
{
|
||||||
|
snd_pcm_plug_t *plug = pcm->private;
|
||||||
|
return snd_pcm_async(plug->slave, sig, pid);
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = pcm->private;
|
snd_pcm_plug_t *plug = pcm->private;
|
||||||
|
|
@ -658,6 +664,7 @@ struct snd_pcm_ops snd_pcm_plug_ops = {
|
||||||
channel_setup: snd_pcm_plug_channel_setup,
|
channel_setup: snd_pcm_plug_channel_setup,
|
||||||
dump: snd_pcm_plug_dump,
|
dump: snd_pcm_plug_dump,
|
||||||
nonblock: snd_pcm_plug_nonblock,
|
nonblock: snd_pcm_plug_nonblock,
|
||||||
|
async: snd_pcm_plug_async,
|
||||||
mmap_status: snd_pcm_plug_mmap_status,
|
mmap_status: snd_pcm_plug_mmap_status,
|
||||||
mmap_control: snd_pcm_plug_mmap_control,
|
mmap_control: snd_pcm_plug_mmap_control,
|
||||||
mmap_data: snd_pcm_plug_mmap_data,
|
mmap_data: snd_pcm_plug_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,12 @@ int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||||
return snd_pcm_nonblock(plugin->slave, nonblock);
|
return snd_pcm_nonblock(plugin->slave, nonblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
|
{
|
||||||
|
snd_pcm_plugin_t *plugin = pcm->private;
|
||||||
|
return snd_pcm_async(plugin->slave, sig, pid);
|
||||||
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin = pcm->private;
|
snd_pcm_plugin_t *plugin = pcm->private;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ typedef struct {
|
||||||
|
|
||||||
int snd_pcm_plugin_close(snd_pcm_t *pcm);
|
int snd_pcm_plugin_close(snd_pcm_t *pcm);
|
||||||
int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock);
|
int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock);
|
||||||
|
int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid);
|
||||||
int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
|
int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
|
||||||
int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
|
int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
|
||||||
int snd_pcm_plugin_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params);
|
int snd_pcm_plugin_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params);
|
||||||
|
|
|
||||||
|
|
@ -576,6 +576,7 @@ struct snd_pcm_ops snd_pcm_rate_ops = {
|
||||||
channel_setup: snd_pcm_plugin_channel_setup,
|
channel_setup: snd_pcm_plugin_channel_setup,
|
||||||
dump: snd_pcm_rate_dump,
|
dump: snd_pcm_rate_dump,
|
||||||
nonblock: snd_pcm_plugin_nonblock,
|
nonblock: snd_pcm_plugin_nonblock,
|
||||||
|
async: snd_pcm_plugin_async,
|
||||||
mmap_status: snd_pcm_plugin_mmap_status,
|
mmap_status: snd_pcm_plugin_mmap_status,
|
||||||
mmap_control: snd_pcm_plugin_mmap_control,
|
mmap_control: snd_pcm_plugin_mmap_control,
|
||||||
mmap_data: snd_pcm_plugin_mmap_data,
|
mmap_data: snd_pcm_plugin_mmap_data,
|
||||||
|
|
|
||||||
|
|
@ -695,6 +695,7 @@ struct snd_pcm_ops snd_pcm_route_ops = {
|
||||||
channel_setup: snd_pcm_route_channel_setup,
|
channel_setup: snd_pcm_route_channel_setup,
|
||||||
dump: snd_pcm_route_dump,
|
dump: snd_pcm_route_dump,
|
||||||
nonblock: snd_pcm_plugin_nonblock,
|
nonblock: snd_pcm_plugin_nonblock,
|
||||||
|
async: snd_pcm_plugin_async,
|
||||||
mmap_status: snd_pcm_plugin_mmap_status,
|
mmap_status: snd_pcm_plugin_mmap_status,
|
||||||
mmap_control: snd_pcm_plugin_mmap_control,
|
mmap_control: snd_pcm_plugin_mmap_control,
|
||||||
mmap_data: snd_pcm_plugin_mmap_data,
|
mmap_data: snd_pcm_plugin_mmap_data,
|
||||||
|
|
|
||||||
1155
src/pcm/pcm_share.c
Normal file
1155
src/pcm/pcm_share.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue