Improved .asoundrc changes

This commit is contained in:
Abramo Bagnara 2001-03-17 16:34:43 +00:00
parent 0300bbbbb3
commit a275d66356
25 changed files with 888 additions and 612 deletions

View file

@ -968,11 +968,15 @@ int main(int argc, char **argv)
return 1;
}
srvname = argv[optind];
err = snd_config_searchv(snd_config, &conf, "server", srvname, 0);
err = snd_config_search_alias(snd_config, "server", srvname, &conf);
if (err < 0) {
ERROR("Missing definition for server %s", srvname);
return 1;
}
if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for server %s definition", srvname);
return -EINVAL;
}
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);

View file

@ -1,169 +1,261 @@
# Server definition
server.NAME {
host STR # host where the server is located (if map to local address
# server is local, and then it may be started automatically)
[socket STR] # PF_LOCAL socket name to listen/connect
[port INT] # PF_INET port number to listen/connect
}
PCM common fields:
type PCM type
[comment] Saved comments
# PCM type definition
pcm_type.NAME {
[lib STR] # Library file (default libasound.so)
[open STR] # Open function (default _snd_pcm_NAME_open)
}
PCM types:
# PCM scope type definition
pcm_scope_type.NAME {
[lib STR] # Library file (default libasound.so)
[open STR] # Open function (default _snd_pcm_scope_NAME_open)
}
- hw Kernel PCM
Fields:
card Card name or number
[device] Device number (default 0)
[subdevice] Subdevice number, -1 first available (default -1)
# Slave PCM definition
pcm_slave.NAME {
pcm STR # PCM name
format STR # Format
channels INT # Channels
rate INT # Rate
period_time INT # Period time
buffer_time INT # Buffer time
etc.
}
- plug Format adjusted PCM
Fields:
sname Slave PCM name
ttable Transfer table (bidimensional compound of
cchannels * schannels numbers)
.C
.S route value
# PCM definition
pcm.NAME {
type STR # Type
[comment ANY] # Saved comments
- linear Linear format conversion PCM
- adpcm IMA-ADPCM format conversion PCM
- alaw A-Law format conversion PCM
- mulaw Mu-Law format conversion PCM
Fields:
sformat Slave format
sname Slave PCM name
- rate Rate conversion PCM
Fields:
[sformat] Slave format (default client format)
srate Slave rate
sname Slave PCM name
- route Attenuated static route PCM
Fields:
[sformat] Slave format (default client format)
[schannels] Slave channels (default client channels)
sname Slave PCM name
ttable Transfer table (bidimensional compound of
cchannels * schannels numbers)
.C
.S route value
- multi Linked PCMs (exclusive access to selected channels)
Fields:
slave Slaves definitions
.N Slave definition
.name Slave PCM name
.channels Slave channels
binding Bindings table
.N Binding for client channel N
.sidx Slave key for slave definition
.schannel Slave channel
- file File plugin
Fields:
sname Slave PCM name
file File name (or fd)
[format] File format (NYI)
# PCM types:
type hw # Kernel PCM
card INT/STR # Card name or number
[device] INT # Device number (default 0)
[subdevice] INT # Subdevice number, -1 first available (default -1)
- null Null endpoint plugin (NYI)
Fields:
time Time related or not
- shm Shared memory client PCM
Fields:
server Server name
sname Slave PCM name on server
- share Share PCM
Fields:
sname Slave name
[schannels] Slave channels
[sformat] Slave format
[srate] Slave rate
binding Bindings table
.N Slave channel for client channel N
- meter Meter PCM
Fields:
sname Slave name
[frequency] Updates per second
scope Scopes
.N Scope #N
.type Scope type
[.PARAMS] Scope params
- mix Mix PCM (NYI)
Fields:
sname Server name
binding Bindings table
.N Binding for client channel N
.schannel Slave channel
- droute Attenuated dynamic route PCM (NYI)
Fields:
[sformat] Slave format (default client format)
[schannels] Slave channels (default client channels)
sname Slave PCM name
binding Bindings table
.N Binding entry
.cchannel Client channels
.C Client channel
.schannel Slave channels
.S Slave channel
.control Control name of C * S values or C values (only if C == S)
- lbserver Loopback server (NYI)
Fields:
name Loopback PCM ID (useful for multiple loopback served by the
same server)
[socket] PF_LOCAL socket name to listen
[port] PF_INET port number to listen
sname Slave name
type plug # Format adjusted PCM
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
}
ttable { # Transfer table (bidimensional compound of
# cchannels * schannels numbers)
CCHANNEL {
SCHANNEL REAL # route value (0.0 ... 1.0)
}
}
CTL common fields:
type CTL type
[comment] Saved comments
type linear # Linear format conversion PCM
type adpcm # IMA-ADPCM format conversion PCM
type alaw # A-Law format conversion PCM
type mulaw # Mu-Law format conversion PCM
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
format STR # Slave format
}
- hw Kernel CTL
Fields:
card Card name or number
- shm Shared memory client CTL
Fields:
server Server name
sname Slave CTL name on server
type rate # Rate conversion PCM
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
[format STR] # Slave format (default client format)
rate INT # Slave rate
}
Other related definitions:
- pcmtype PCM type
Fields:
[lib] Library file
open Open function
type route # Attenuated static route PCM
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
[format STR] # Slave format (default client format)
[channels INT] # Slave channels (default client channels)
}
ttable { # Transfer table (bidimensional compound of
# cchannels * schannels numbers)
CCHANNEL {
SCHANNEL REAL # route value (0.0 ... 1.0)
}
}
- ctltype Control type
Fields:
[lib] Library file
open Open function
- scopetype PCM scope type
Fields:
[lib] Library file
open Open function
type multi # Linked PCMs (exclusive access to selected channels)
slaves { # Slaves definitions
N STR # Slave name for slave N
# or
N { # Slave definition for slave N
pcm STR # Slave PCM name
channels INT # Slave channels
}
}
bindings { # Bindings table
N { # Binding for client channel N
slave STR # Slave key
channel INT # Slave channel
}
}
- server Server
Fields:
host host where the server is located (if map to local address
server is local, and then it may be started automatically)
[socket] PF_LOCAL socket name to listen/connect
[port] PF_INET port number to listen/connect
type file # File plugin
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
}
[format STR] # File format (NYI)
type meter # Meter PCM
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
}
[frequency INT] # Updates per second
scopes { # Scopes
N { # Scope definition
type STR # Scope type
[PARAMS] # Scope params
}
}
type droute # Attenuated dynamic route PCM (NYI)
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
[format STR] # Slave format (default client format)
[channels INT] # Slave channels (default client channels)
}
ctl STR # Ctl name
bindings { # Bindings table
N { # Binding entry
cchannels { # Client channels
C INT # Client channel
}
schannel { # Slave channels
S INT # Slave channel
}
control STR # Control name of C * S (or C values: only if C == S)
}
}
type loopback # Loopback server (NYI)
server STR # Server name
slave STR # Slave name
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
}
type null # Null endpoint plugin
[time INT] # Time related or not (NYI)
type shm # Shared memory client PCM
server STR # Server name
pcm STR # PCM name on server
type share # Share PCM
slave STR # Slave name
bindings { # Bindings table
N INT # Slave channel for client channel N
}
type mix # Mix PCM
slave STR # Slave name
bindings { # Bindings table
N INT # Slave channel for client channel N
}
}
# CTL type definition
ctl_type.NAME {
[lib STR] # Library file (default libasound.so)
[open STR] # Open function (default _snd_ctl_NAME_open)
}
# CTL definition
ctl.NAME {
type STR # Type
[comment ANY] # Saved comments
# CTL types
type hw
card STR/INT # Card name or number
type shm # Shared memory client CTL
server STR # Server name
ctl STR # CTL name on server
}
# RAWMIDI type definition
rawmidi_type.NAME {
[lib STR] # Library file (default libasound.so)
[open STR] # Open function (default _snd_rawmidi_NAME_open)
}
# RAWMIDI definition
rawmidi.NAME {
type STR # Type
[comment ANY] # Saved comments
# RAWMIDI types:
type hw # Kernel RAWMIDI
card INT/STR # Card name or number
[device] INT # Device number (default 0)
[subdevice] INT # Subdevice number, -1 first available (default -1)
}
# SEQ type definition
seq_type.NAME {
[lib STR] # Library file (default libasound.so)
[open STR] # Open function (default _snd_seq_NAME_open)
}
# SEQ definition
seq.NAME {
type STR # Type
[comment ANY] # Saved comments
# SEQ types:
type hw # Kernel SEQ
}
# Aliases
DEF.NAME1 NAME2 # DEF.NAME1 is an alias for DEF.NAME2
Some examples:
pcmtype.hw {
open _snd_pcm_hw_open
}
pcmtype.plug {
open _snd_pcm_plug_open
}
pcm.trident {
type hw
card 0
@ -180,31 +272,41 @@ pcm.ice1712_spdif {
type plug
ttable.0.8 1
ttable.1.9 1
sname ice1712
slave.pcm ice1712
}
pcm_slave.rs {
pcm trident
rate 44100
}
pcm.r {
type rate
slave rs
}
pcm.m {
type meter
sname plug:trident
slave.pcm plug:trident
frequency 50
scope.0 {
scopes.0 {
type level
}
}
scopetype.level {
scope_type.level {
lib /home/abramo/scopes/liblevel.so
}
Special PCM names:
hw:#card,#dev,#subdev
hw:#card,#dev
plug:#card,#dev,#subdev
plug:#card,#dev
plug:sname
shm:socket,sname
file:fname,fmt,sname
file:fname,fmt
file:fname
hw:CARD,DEV,SUBDEV
hw:CARD,DEV
plug:CARD,DEV,SUBDEV
plug:CARD,DEV
plug:SLAVE_PCM
shm:SOCKET,PCM
file:FNAME,FMT,SLAVE_PCM
file:FNAME,FMT
file:FNAME
null

View file

@ -36,6 +36,9 @@ int snd_config_search(snd_config_t *config, const char *key,
snd_config_t **result);
int snd_config_searchv(snd_config_t *config,
snd_config_t **result, ...);
int snd_config_search_alias(snd_config_t *config,
const char *base, const char *key,
snd_config_t **result);
int snd_config_add(snd_config_t *config, snd_config_t *leaf);
int snd_config_delete(snd_config_t *config);

View file

@ -1014,6 +1014,21 @@ int snd_config_searchv(snd_config_t *config,
return 0;
}
int snd_config_search_alias(snd_config_t *config,
const char *base, const char *key,
snd_config_t **result)
{
int err;
assert(config && base && key && result);
err = snd_config_searchv(config, result, base, key, 0);
if (err < 0)
return err;
while (snd_config_get_string(*result, &key) >= 0 &&
snd_config_searchv(config, result, base, key, 0) >= 0)
;
return 0;
}
snd_config_t *snd_config = 0;
static dev_t sys_asoundrc_device;
static ino_t sys_asoundrc_inode;

View file

@ -204,33 +204,42 @@ int snd_ctl_open(snd_ctl_t **ctlp, const char *name)
const char *lib = NULL, *open = NULL;
int (*open_func)(snd_ctl_t **ctlp, const char *name, snd_config_t *conf);
void *h;
const char *name1;
assert(ctlp && name);
err = snd_config_update();
if (err < 0)
return err;
err = snd_config_searchv(snd_config, &ctl_conf, "ctl", name, 0);
if (err < 0) {
err = snd_config_search_alias(snd_config, "ctl", name, &ctl_conf);
name1 = name;
if (err < 0 || snd_config_get_string(ctl_conf, &name1) >= 0) {
int card;
char socket[256], sname[256];
err = sscanf(name, "hw:%d", &card);
err = sscanf(name1, "hw:%d", &card);
if (err == 1)
return snd_ctl_hw_open(ctlp, name, card);
err = sscanf(name, "shm:%256[^,],%256[^,]", socket, sname);
err = sscanf(name1, "shm:%256[^,],%256[^,]", socket, sname);
if (err == 2)
return snd_ctl_shm_open(ctlp, name, socket, sname);
SNDERR("Unknown control %s", name);
SNDERR("Unknown ctl %s", name1);
return -ENOENT;
}
if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND)
if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for %s", snd_config_get_id(ctl_conf));
return -EINVAL;
}
err = snd_config_search(ctl_conf, "type", &conf);
if (err < 0)
return err;
err = snd_config_get_string(conf, &str);
if (err < 0)
return err;
err = snd_config_searchv(snd_config, &type_conf, "ctltype", str, 0);
err = snd_config_search_alias(snd_config, "ctl_type", str, &type_conf);
if (err >= 0) {
if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for ctl type %s definition", str);
return -EINVAL;
}
snd_config_for_each(i, next, type_conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);

View file

@ -544,11 +544,15 @@ int _snd_ctl_shm_open(snd_ctl_t **handlep, char *name, snd_config_t *conf)
SNDERR("server is not defined");
return -EINVAL;
}
err = snd_config_searchv(snd_config, &sconfig, "server", server, 0);
err = snd_config_search_alias(snd_config, "server", server, &sconfig);
if (err < 0) {
SNDERR("Unknown server %s", server);
return -EINVAL;
}
if (snd_config_get_type(sconfig) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for server %s definition", server);
return -EINVAL;
}
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);

View file

@ -5,8 +5,8 @@ libpcm_la_SOURCES = atomic.c mask.c interval.c \
pcm.c pcm_m4.c pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
pcm_route.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_shm.c pcm_file.c pcm_share.c pcm_null.c pcm_meter.c \
pcm_params.c
pcm_shm.c pcm_file.c pcm_null.c pcm_share.c \
pcm_meter.c pcm_params.c
noinst_HEADERS = atomic.h pcm_local.h pcm_plugin.h mask.h mask_inline.h \
interval.h interval_inline.h plugin_ops.h

View file

@ -23,6 +23,7 @@
#include <string.h>
#include <malloc.h>
#include <stdarg.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/shm.h>
@ -89,8 +90,20 @@ 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);
return pcm->ops->async(pcm->op_arg, sig, pid);
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;
}
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
@ -564,28 +577,31 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
int (*open_func)(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
snd_pcm_stream_t stream, int mode);
void *h;
const char *name1;
assert(pcmp && name);
err = snd_config_update();
if (err < 0)
return err;
err = snd_config_searchv(snd_config, &pcm_conf, "pcm", name, 0);
if (err < 0) {
err = snd_config_search_alias(snd_config, "pcm", name, &pcm_conf);
name1 = name;
if (err < 0 || snd_config_get_string(pcm_conf, &name1) >= 0) {
int card, dev, subdev;
char socket[256], sname[256];
char format[16], file[256];
err = sscanf(name, "hw:%d,%d,%d", &card, &dev, &subdev);
err = sscanf(name1, "hw:%d,%d,%d", &card, &dev, &subdev);
if (err == 3)
return snd_pcm_hw_open(pcmp, name, card, dev, subdev, stream, mode);
err = sscanf(name, "hw:%d,%d", &card, &dev);
err = sscanf(name1, "hw:%d,%d", &card, &dev);
if (err == 2)
return snd_pcm_hw_open(pcmp, name, card, dev, -1, stream, mode);
err = sscanf(name, "plug:%d,%d,%d", &card, &dev, &subdev);
err = sscanf(name1, "plug:%d,%d,%d", &card, &dev, &subdev);
if (err == 3)
return snd_pcm_plug_open_hw(pcmp, name, card, dev, subdev, stream, mode);
err = sscanf(name, "plug:%d,%d", &card, &dev);
err = sscanf(name1, "plug:%d,%d", &card, &dev);
if (err == 2)
return snd_pcm_plug_open_hw(pcmp, name, card, dev, -1, stream, mode);
err = sscanf(name, "plug:%256[^,]", sname);
err = sscanf(name1, "plug:%256[^,]", sname);
if (err == 1) {
snd_pcm_t *slave;
err = snd_pcm_open(&slave, sname, stream, mode);
@ -593,18 +609,18 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
return err;
return snd_pcm_plug_open(pcmp, name, NULL, 0, 0, 0, slave, 1);
}
err = sscanf(name, "shm:%256[^,],%256[^,]", socket, sname);
err = sscanf(name1, "shm:%256[^,],%256[^,]", socket, sname);
if (err == 2)
return snd_pcm_shm_open(pcmp, name, socket, sname, stream, mode);
err = sscanf(name, "file:%256[^,],%16[^,],%256[^,]", file, format, sname);
err = sscanf(name1, "file:%256[^,],%16[^,],%256[^,]", file, format, sname);
if (err == 3) {
snd_pcm_t *slave;
err = snd_pcm_open(&slave, sname, stream, mode);
if (err < 0)
return err;
return snd_pcm_file_open(pcmp, name, file, -1, format, slave, 1);
return snd_pcm_file_open(pcmp, name1, file, -1, format, slave, 1);
}
err = sscanf(name, "file:%256[^,],%16[^,]", file, format);
err = sscanf(name1, "file:%256[^,],%16[^,]", file, format);
if (err == 2) {
snd_pcm_t *slave;
err = snd_pcm_null_open(&slave, name, stream, mode);
@ -612,7 +628,7 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
return err;
return snd_pcm_file_open(pcmp, name, file, -1, format, slave, 1);
}
err = sscanf(name, "file:%256[^,]", file);
err = sscanf(name1, "file:%256[^,]", file);
if (err == 1) {
snd_pcm_t *slave;
err = snd_pcm_null_open(&slave, name, stream, mode);
@ -620,13 +636,13 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
return err;
return snd_pcm_file_open(pcmp, name, file, -1, "raw", slave, 1);
}
if (strcmp(name, "null") == 0)
if (strcmp(name1, "null") == 0)
return snd_pcm_null_open(pcmp, name, stream, mode);
SNDERR("Unknown PCM %s", name);
SNDERR("Unknown PCM %s", name1);
return -ENOENT;
}
if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for PCM %s definition", name);
SNDERR("Invalid type for PCM %s definition", name1);
return -EINVAL;
}
err = snd_config_search(pcm_conf, "type", &conf);
@ -639,8 +655,12 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
SNDERR("Invalid type for %s", snd_config_get_id(conf));
return err;
}
err = snd_config_searchv(snd_config, &type_conf, "pcmtype", str, 0);
err = snd_config_search_alias(snd_config, "pcm_type", str, &type_conf);
if (err >= 0) {
if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for PCM type %s definition", str);
return -EINVAL;
}
snd_config_for_each(i, next, type_conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -1181,3 +1201,109 @@ snd_pcm_uframes_t _snd_pcm_boundary(snd_pcm_t *pcm)
return pcm->boundary;
}
static const char *names[SND_PCM_HW_PARAM_LAST + 1] = {
[SND_PCM_HW_PARAM_FORMAT] = "format",
[SND_PCM_HW_PARAM_CHANNELS] = "channels",
[SND_PCM_HW_PARAM_RATE] = "rate",
[SND_PCM_HW_PARAM_PERIOD_TIME] = "period_time",
[SND_PCM_HW_PARAM_BUFFER_TIME] = "buffer_time"
};
int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
unsigned int count, ...)
{
snd_config_iterator_t i, next;
const char *str;
struct {
unsigned int index;
int mandatory;
void *ptr;
int valid;
} fields[count];
unsigned int k;
int pcm_valid = 0;
int err;
va_list args;
if (snd_config_get_string(conf, &str) >= 0) {
err = snd_config_search_alias(snd_config, "pcm_slave", str, &conf);
if (err < 0) {
SNDERR("unkown pcm_slave %s", str);
return err;
}
}
va_start(args, count);
for (k = 0; k < count; ++k) {
fields[k].index = va_arg(args, int);
fields[k].mandatory = va_arg(args, int);
fields[k].ptr = va_arg(args, void *);
fields[k].valid = 0;
}
va_end(args);
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
if (strcmp(id, "comment") == 0)
continue;
if (strcmp(id, "pcm") == 0) {
if (pcm_valid) {
_duplicated:
SNDERR("duplicated %s", id);
return -EINVAL;
}
err = snd_config_get_string(n, namep);
if (err < 0) {
_invalid:
SNDERR("invalid type for %s", id);
return err;
}
pcm_valid = 1;
continue;
}
for (k = 0; k < count; ++k) {
unsigned int idx = fields[k].index;
long v;
assert(idx < SND_PCM_HW_PARAM_LAST);
assert(names[idx]);
if (strcmp(id, names[idx]) != 0)
continue;
if (fields[k].valid)
goto _duplicated;
switch (idx) {
case SND_PCM_HW_PARAM_FORMAT:
{
snd_pcm_format_t f;
err = snd_config_get_string(n, &str);
if (err < 0)
goto _invalid;
f = snd_pcm_format_value(str);
if (f == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("unknown format");
return -EINVAL;
}
*(snd_pcm_format_t*)fields[k].ptr = f;
break;
}
default:
err = snd_config_get_integer(n, &v);
if (err < 0)
goto _invalid;
*(int*)fields[k].ptr = v;
break;
}
fields[k].valid = 1;
break;
}
if (k < count)
continue;
SNDERR("Unknown field %s", id);
return -EINVAL;
}
for (k = 0; k < count; ++k) {
if (fields[k].mandatory && !fields[k].valid) {
SNDERR("missing field %s", names[fields[k].index]);
return -EINVAL;
}
}
return 0;
}

View file

@ -552,7 +552,8 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
snd_config_t *slave = NULL;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -560,42 +561,24 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "sformat") == 0) {
const char *f;
err = snd_config_get_string(n, &f);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
sformat = snd_pcm_format_value(f);
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("Unknown sformat");
return -EINVAL;
}
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_IMA_ADPCM) {
SNDERR("Invalid sformat");
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("sformat is not defined");
err = snd_pcm_slave_conf(slave, &sname, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_IMA_ADPCM) {
SNDERR("invalid slave format");
return -EINVAL;
}
/* This is needed cause snd_config_update may destroy config */

View file

@ -425,7 +425,8 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
snd_config_t *slave = NULL;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -433,42 +434,24 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "sformat") == 0) {
const char *f;
err = snd_config_get_string(n, &f);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
sformat = snd_pcm_format_value(f);
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("Unknown sformat");
return -EINVAL;
}
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_A_LAW) {
SNDERR("Invalid sformat");
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("sformat is not defined");
err = snd_pcm_slave_conf(slave, &sname, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_A_LAW) {
SNDERR("invalid slave format");
return -EINVAL;
}
/* This is needed cause snd_config_update may destroy config */

View file

@ -198,6 +198,7 @@ int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_config_t *slave = NULL;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -205,21 +206,20 @@ int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
err = snd_pcm_slave_conf(slave, &sname, 0);
if (err < 0)
return err;
/* This is needed cause snd_config_update may destroy config */
sname = strdup(sname);
if (!sname)

View file

@ -467,6 +467,7 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_config_t *slave = NULL;
const char *fname = NULL;
const char *format = NULL;
long fd = -1;
@ -477,12 +478,8 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
if (strcmp(id, "format") == 0) {
@ -507,10 +504,13 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
err = snd_pcm_slave_conf(slave, &sname, 0);
if (err < 0)
return err;
if (!fname && fd < 0) {
SNDERR("file is not defined");
return -EINVAL;

View file

@ -329,10 +329,11 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
const char *sname = NULL;
const char *sname;
int err;
snd_pcm_t *spcm;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
snd_config_t *slave = NULL;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -340,41 +341,23 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "sformat") == 0) {
const char *f;
err = snd_config_get_string(n, &f);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
sformat = snd_pcm_format_value(f);
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("Unknown sformat %s", f);
return err;
}
if (snd_pcm_format_linear(sformat) != 1) {
SNDERR("sformat is not linear");
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("sformat is not defined");
err = snd_pcm_slave_conf(slave, &sname, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
if (snd_pcm_format_linear(sformat) != 1) {
SNDERR("slave format is not linear");
return -EINVAL;
}
/* This is needed cause snd_config_update may destroy config */

View file

@ -143,6 +143,8 @@ 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 */
@ -486,6 +488,9 @@ int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int orde
unsigned int count,
snd_pcm_hw_strategy_simple_choices_list_t *choices);
int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
unsigned int count, ...);
#define SND_PCM_HW_PARBIT_ACCESS (1 << SND_PCM_HW_PARAM_ACCESS)
#define SND_PCM_HW_PARBIT_FORMAT (1 << SND_PCM_HW_PARAM_FORMAT)
#define SND_PCM_HW_PARBIT_SUBFORMAT (1 << SND_PCM_HW_PARAM_SUBFORMAT)

View file

@ -658,7 +658,7 @@ int snd_pcm_meter_add_scope_conf(snd_pcm_t *pcm, const char *name,
SNDERR("Invalid type for %s", snd_config_get_id(c));
return err;
}
err = snd_config_searchv(snd_config, &type_conf, "scopetype", str, 0);
err = snd_config_search_alias(snd_config, "pcm_scope_type", str, &type_conf);
if (err >= 0) {
snd_config_for_each(i, next, type_conf) {
snd_config_t *n = snd_config_iterator_entry(i);
@ -714,6 +714,7 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_config_t *slave = NULL;
long frequency = -1;
snd_config_t *scopes = NULL;
snd_config_for_each(i, next, conf) {
@ -723,12 +724,8 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
if (strcmp(id, "frequency") == 0) {
@ -739,7 +736,7 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
}
continue;
}
if (strcmp(id, "scope") == 0) {
if (strcmp(id, "scopes") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
@ -750,11 +747,13 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
err = snd_pcm_slave_conf(slave, &sname, 0);
if (err < 0)
return err;
/* This is needed cause snd_config_update may destroy config */
sname = strdup(sname);
if (!sname)

View file

@ -440,7 +440,8 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
snd_config_t *slave = NULL;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -448,42 +449,24 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "sformat") == 0) {
const char *f;
err = snd_config_get_string(n, &f);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
sformat = snd_pcm_format_value(f);
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("Unknown sformat");
return -EINVAL;
}
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_MU_LAW) {
SNDERR("Invalid sformat");
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("sformat is not defined");
err = snd_pcm_slave_conf(slave, &sname, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
if (snd_pcm_format_linear(sformat) != 1 &&
sformat != SND_PCM_FORMAT_MU_LAW) {
SNDERR("invalid slave format");
return -EINVAL;
}
/* This is needed cause snd_config_update may destroy config */

View file

@ -584,8 +584,8 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, inext, j, jnext;
snd_config_t *slave = NULL;
snd_config_t *binding = NULL;
snd_config_t *slaves = NULL;
snd_config_t *bindings = NULL;
int err;
unsigned int idx;
const char **slaves_id = NULL;
@ -603,37 +603,37 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "slave") == 0) {
if (strcmp(id, "slaves") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
slave = n;
slaves = n;
continue;
}
if (strcmp(id, "binding") == 0) {
if (strcmp(id, "bindings") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
binding = n;
bindings = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!slave) {
SNDERR("slave is not defined");
if (!slaves) {
SNDERR("slaves is not defined");
return -EINVAL;
}
if (!binding) {
SNDERR("binding is not defined");
if (!bindings) {
SNDERR("bindings is not defined");
return -EINVAL;
}
snd_config_for_each(i, inext, slave) {
snd_config_for_each(i, inext, slaves) {
++slaves_count;
}
snd_config_for_each(i, inext, binding) {
snd_config_for_each(i, inext, bindings) {
int cchannel = -1;
char *p;
snd_config_t *m = snd_config_iterator_entry(i);
@ -661,52 +661,21 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
for (idx = 0; idx < channels_count; ++idx)
channels_sidx[idx] = -1;
idx = 0;
snd_config_for_each(i, inext, slave) {
snd_config_for_each(i, inext, slaves) {
snd_config_t *m = snd_config_iterator_entry(i);
const char *name = NULL;
long channels = -1;
const char *name;
int channels;
slaves_id[idx] = snd_config_get_id(m);
snd_config_for_each(j, jnext, m) {
snd_config_t *n = snd_config_iterator_entry(j);
const char *id = snd_config_get_id(n);
if (strcmp(id, "comment") == 0)
continue;
if (strcmp(id, "name") == 0) {
err = snd_config_get_string(n, &name);
if (err < 0) {
SNDERR("Invalid type for %s", id);
goto _free;
}
continue;
}
if (strcmp(id, "channels") == 0) {
err = snd_config_get_integer(n, &channels);
if (err < 0) {
SNDERR("Invalid type for %s", id);
goto _free;
}
continue;
}
SNDERR("Unknown field %s", id);
err = -EINVAL;
err = snd_pcm_slave_conf(m, &name, 1,
SND_PCM_HW_PARAM_CHANNELS, 1, &channels);
if (err < 0)
goto _free;
}
if (!name) {
SNDERR("name is not defined");
err = -EINVAL;
goto _free;
}
if (channels < 0) {
SNDERR("channels is not defined");
err = -EINVAL;
goto _free;
}
slaves_name[idx] = strdup(name);
slaves_channels[idx] = channels;
++idx;
}
snd_config_for_each(i, inext, binding) {
snd_config_for_each(i, inext, bindings) {
snd_config_t *m = snd_config_iterator_entry(i);
long cchannel = -1;
long schannel = -1;
@ -725,7 +694,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
const char *id = snd_config_get_id(n);
if (strcmp(id, "comment") == 0)
continue;
if (strcmp(id, "sidx") == 0) {
if (strcmp(id, "slave") == 0) {
char buf[32];
unsigned int k;
err = snd_config_get_string(n, &str);
@ -744,7 +713,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
}
continue;
}
if (strcmp(id, "schannel") == 0) {
if (strcmp(id, "channel") == 0) {
err = snd_config_get_integer(n, &schannel);
if (err < 0) {
SNDERR("Invalid type for %s", id);

View file

@ -718,6 +718,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_config_t *slave = NULL;
snd_config_t *tt = NULL;
snd_pcm_route_ttable_entry_t *ttable = NULL;
unsigned int cused, sused;
@ -728,12 +729,8 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
if (strcmp(id, "ttable") == 0) {
@ -747,10 +744,13 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
err = snd_pcm_slave_conf(slave, &sname, 0);
if (err < 0)
return err;
if (tt) {
ttable = malloc(MAX_CHANNELS * MAX_CHANNELS * sizeof(*ttable));
err = snd_pcm_route_load_ttable(tt, ttable, MAX_CHANNELS, MAX_CHANNELS,

View file

@ -542,8 +542,9 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_config_t *slave = NULL;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
long srate = -1;
int srate = -1;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -551,49 +552,25 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "sformat") == 0) {
const char *f;
err = snd_config_get_string(n, &f);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
sformat = snd_pcm_format_value(f);
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("Unknown sformat");
return -EINVAL;
}
if (snd_pcm_format_linear(sformat) != 1) {
SNDERR("sformat is not linear");
return -EINVAL;
}
continue;
}
if (strcmp(id, "srate") == 0) {
err = snd_config_get_integer(n, &srate);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
if (srate < 0) {
SNDERR("srate is not defined");
err = snd_pcm_slave_conf(slave, &sname, 2,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_RATE, 1, &srate);
if (err < 0)
return err;
if (sformat != SND_PCM_FORMAT_UNKNOWN &&
snd_pcm_format_linear(sformat) != 1) {
SNDERR("slave format is not linear");
return -EINVAL;
}
/* This is needed cause snd_config_update may destroy config */

View file

@ -156,44 +156,47 @@ void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
#include "plugin_ops.h"
#undef GETU_LABELS
#undef PUT32_LABELS
static void *zero_labels[3] = { &&zero_int32, &&zero_int64,
static void *zero_labels[3] = {
&&zero_int32, &&zero_int64,
#if ROUTE_PLUGIN_FLOAT
&&zero_float
&&zero_float
#endif
};
/* sum_type att */
static void *add_labels[3 * 2] = { &&add_int32_noatt, &&add_int32_att,
&&add_int64_noatt, &&add_int64_att,
static void *add_labels[3 * 2] = {
&&add_int32_noatt, &&add_int32_att,
&&add_int64_noatt, &&add_int64_att,
#if ROUTE_PLUGIN_FLOAT
&&add_float_noatt, &&add_float_att
&&add_float_noatt, &&add_float_att
#endif
};
/* sum_type att shift */
static void *norm_labels[3 * 2 * 4] = { 0,
&&norm_int32_8_noatt,
&&norm_int32_16_noatt,
&&norm_int32_24_noatt,
0,
&&norm_int32_8_att,
&&norm_int32_16_att,
&&norm_int32_24_att,
&&norm_int64_0_noatt,
&&norm_int64_8_noatt,
&&norm_int64_16_noatt,
&&norm_int64_24_noatt,
&&norm_int64_0_att,
&&norm_int64_8_att,
&&norm_int64_16_att,
&&norm_int64_24_att,
static void *norm_labels[3 * 2 * 4] = {
0,
&&norm_int32_8_noatt,
&&norm_int32_16_noatt,
&&norm_int32_24_noatt,
0,
&&norm_int32_8_att,
&&norm_int32_16_att,
&&norm_int32_24_att,
&&norm_int64_0_noatt,
&&norm_int64_8_noatt,
&&norm_int64_16_noatt,
&&norm_int64_24_noatt,
&&norm_int64_0_att,
&&norm_int64_8_att,
&&norm_int64_16_att,
&&norm_int64_24_att,
#if ROUTE_PLUGIN_FLOAT
&&norm_float_0,
&&norm_float_8,
&&norm_float_16,
&&norm_float_24,
&&norm_float_0,
&&norm_float_8,
&&norm_float_16,
&&norm_float_24,
&&norm_float_0,
&&norm_float_8,
&&norm_float_16,
&&norm_float_24,
&&norm_float_0,
&&norm_float_8,
&&norm_float_16,
&&norm_float_24,
#endif
};
void *zero, *get, *add, *norm, *put32;
@ -843,8 +846,9 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
const char *sname = NULL;
int err;
snd_pcm_t *spcm;
snd_config_t *slave = NULL;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
long schannels = -1;
int schannels = -1;
snd_config_t *tt = NULL;
snd_pcm_route_ttable_entry_t ttable[MAX_CHANNELS*MAX_CHANNELS];
unsigned int cused, sused;
@ -855,38 +859,8 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "sformat") == 0) {
const char *f;
err = snd_config_get_string(n, &f);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
sformat = snd_pcm_format_value(f);
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("Unknown sformat");
return -EINVAL;
}
if (snd_pcm_format_linear(sformat) != 1) {
SNDERR("sformat is not linear");
return -EINVAL;
}
continue;
}
if (strcmp(id, "schannels") == 0) {
err = snd_config_get_integer(n, &schannels);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
if (strcmp(id, "slave") == 0) {
slave = n;
continue;
}
if (strcmp(id, "ttable") == 0) {
@ -900,14 +874,24 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
if (!tt) {
SNDERR("ttable is not defined");
return -EINVAL;
}
err = snd_pcm_slave_conf(slave, &sname, 2,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_CHANNELS, 0, &schannels);
if (err < 0)
return err;
if (sformat != SND_PCM_FORMAT_UNKNOWN &&
snd_pcm_format_linear(sformat) != 1) {
SNDERR("slave format is not linear");
return -EINVAL;
}
err = snd_pcm_route_load_ttable(tt, ttable, MAX_CHANNELS, MAX_CHANNELS,
&cused, &sused, schannels);

View file

@ -33,33 +33,31 @@
#include "pcm_local.h"
#include "list.h"
static LIST_HEAD(slaves);
static pthread_mutex_t slaves_mutex = PTHREAD_MUTEX_INITIALIZER;
char *slaves_mutex_holder;
#define _S(x) #x
#define S(x) _S(x)
static LIST_HEAD(snd_pcm_share_slaves);
static pthread_mutex_t snd_pcm_share_slaves_mutex = PTHREAD_MUTEX_INITIALIZER;
#if 1
#define Pthread_mutex_lock(mutex) pthread_mutex_lock(mutex)
#define Pthread_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
#else
#ifdef MUTEX_DEBUG
#define Pthread_mutex_lock(mutex) \
char *snd_pcm_share_slaves_mutex_holder;
do { \
int err = pthread_mutex_trylock(mutex); \
if (err == EBUSY) { \
fprintf(stderr, "lock " #mutex " is busy (%s): waiting in " __FUNCTION__ "\n", *(mutex##_holder)); \
pthread_mutex_lock(mutex); \
fprintf(stderr, "... got\n"); \
} \
*(mutex##_holder) = __FUNCTION__; \
int err = pthread_mutex_trylock(mutex); \
if (err < 0) { \
fprintf(stderr, "lock " #mutex " is busy (%s): waiting in " __FUNCTION__ "\n", *(mutex##_holder)); \
pthread_mutex_lock(mutex); \
fprintf(stderr, "... got\n"); \
} \
*(mutex##_holder) = __FUNCTION__; \
} while (0)
#define Pthread_mutex_unlock(mutex) \
do { \
*(mutex##_holder) = 0; \
pthread_mutex_unlock(mutex); \
*(mutex##_holder) = 0; \
pthread_mutex_unlock(mutex); \
} while (0)
#else
#define Pthread_mutex_lock(mutex) pthread_mutex_lock(mutex)
#define Pthread_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
#endif
typedef struct {
@ -68,7 +66,9 @@ typedef struct {
snd_pcm_t *pcm;
snd_pcm_format_t format;
int rate;
unsigned int channels_count;
unsigned int channels;
int period_time;
int buffer_time;
unsigned int open_count;
unsigned int setup_count;
unsigned int mmap_count;
@ -82,7 +82,9 @@ typedef struct {
int polling;
pthread_t thread;
pthread_mutex_t mutex;
#ifdef MUTEX_DEBUG
char *mutex_holder;
#endif
pthread_cond_t poll_cond;
} snd_pcm_share_slave_t;
@ -92,11 +94,6 @@ typedef struct {
snd_pcm_share_slave_t *slave;
unsigned int channels_count;
int *slave_channels;
int xfer_mode;
int xrun_mode;
snd_pcm_uframes_t avail_min;
int async_sig;
pid_t async_pid;
int drain_silenced;
struct timeval trigger_tstamp;
snd_pcm_state_t state;
@ -138,7 +135,7 @@ static snd_pcm_uframes_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *sla
min_frames = slave_avail;
max_frames = 0;
slave_appl_ptr = *slave->pcm->appl_ptr;
for (i = slave->clients.next; i != &slave->clients; i = i->next) {
list_for_each(i, &slave->clients) {
snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
snd_pcm_t *pcm = share->pcm;
switch (snd_enum_to_int(share->state)) {
@ -259,7 +256,7 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
if ((snd_pcm_uframes_t)hw_avail < missing)
missing = hw_avail;
}
ready_missing = share->avail_min - avail;
ready_missing = pcm->avail_min - avail;
if (ready_missing > 0) {
ready = 0;
if ((snd_pcm_uframes_t)ready_missing < missing)
@ -328,7 +325,7 @@ static snd_pcm_uframes_t _snd_pcm_share_slave_missing(snd_pcm_share_slave_t *sla
snd_pcm_sframes_t avail = snd_pcm_avail_update(slave->pcm);
int slave_xrun = (avail == -EPIPE);
slave->hw_ptr = *slave->pcm->hw_ptr;
for (i = slave->clients.next; i != &slave->clients; i = i->next) {
list_for_each(i, &slave->clients) {
snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
snd_pcm_t *pcm = share->pcm;
snd_pcm_uframes_t m = _snd_pcm_share_missing(pcm, slave_xrun);
@ -432,17 +429,8 @@ static int snd_pcm_share_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock
return 0;
}
static int snd_pcm_share_async(snd_pcm_t *pcm, int sig, pid_t pid)
static int snd_pcm_share_async(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int sig ATTRIBUTE_UNUSED, pid_t pid ATTRIBUTE_UNUSED)
{
snd_pcm_share_t *share = pcm->private_data;
if (sig)
share->async_sig = sig;
else
share->async_sig = SIGIO;
if (pid)
share->async_pid = pid;
else
share->async_pid = getpid();
return -ENOSYS;
}
@ -480,6 +468,18 @@ static int snd_pcm_share_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t
if (err < 0)
return err;
}
if (slave->period_time >= 0) {
err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_PERIOD_TIME,
slave->period_time, 0);
if (err < 0)
return err;
}
if (slave->buffer_time >= 0) {
err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_BUFFER_TIME,
slave->buffer_time, 0);
if (err < 0)
return err;
}
params->info |= SND_PCM_INFO_DOUBLE;
return 0;
}
@ -493,7 +493,7 @@ static int snd_pcm_share_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t
_snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
&saccess_mask);
_snd_pcm_hw_param_set(sparams, SND_PCM_HW_PARAM_CHANNELS,
slave->channels_count, 0);
slave->channels, 0);
return 0;
}
@ -1093,7 +1093,7 @@ static int snd_pcm_share_close(snd_pcm_t *pcm)
snd_pcm_share_t *share = pcm->private_data;
snd_pcm_share_slave_t *slave = share->slave;
int err = 0;
Pthread_mutex_lock(&slaves_mutex);
Pthread_mutex_lock(&snd_pcm_share_slaves_mutex);
Pthread_mutex_lock(&slave->mutex);
slave->open_count--;
if (slave->open_count == 0) {
@ -1111,7 +1111,7 @@ static int snd_pcm_share_close(snd_pcm_t *pcm)
list_del(&share->list);
Pthread_mutex_unlock(&slave->mutex);
}
Pthread_mutex_unlock(&slaves_mutex);
Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
close(share->client_socket);
close(share->slave_socket);
free(share->slave_channels);
@ -1183,6 +1183,7 @@ snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
snd_pcm_format_t sformat, int srate,
unsigned int schannels_count,
int speriod_time, int sbuffer_time,
unsigned int channels_count, int *channels_map,
snd_pcm_stream_t stream, int mode)
{
@ -1263,8 +1264,8 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
return err;
}
Pthread_mutex_lock(&slaves_mutex);
for (i = slaves.next; i != &slaves; i = i->next) {
Pthread_mutex_lock(&snd_pcm_share_slaves_mutex);
list_for_each(i, &snd_pcm_share_slaves) {
snd_pcm_share_slave_t *s = list_entry(i, snd_pcm_share_slave_t, list);
if (s->pcm->name && strcmp(s->pcm->name, sname) == 0) {
slave = s;
@ -1275,7 +1276,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
snd_pcm_t *spcm;
err = snd_pcm_open(&spcm, sname, stream, mode);
if (err < 0) {
Pthread_mutex_unlock(&slaves_mutex);
Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
close(sd[0]);
close(sd[1]);
free(pcm);
@ -1285,7 +1286,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
}
slave = calloc(1, sizeof(*slave));
if (!slave) {
Pthread_mutex_unlock(&slaves_mutex);
Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
snd_pcm_close(spcm);
close(sd[0]);
close(sd[1]);
@ -1296,20 +1297,22 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
}
INIT_LIST_HEAD(&slave->clients);
slave->pcm = spcm;
slave->channels_count = schannels_count;
slave->channels = schannels_count;
slave->format = sformat;
slave->rate = srate;
slave->period_time = speriod_time;
slave->buffer_time = sbuffer_time;
pthread_mutex_init(&slave->mutex, NULL);
pthread_cond_init(&slave->poll_cond, NULL);
list_add_tail(&slave->list, &slaves);
list_add_tail(&slave->list, &snd_pcm_share_slaves);
Pthread_mutex_lock(&slave->mutex);
err = pthread_create(&slave->thread, NULL, snd_pcm_share_thread, slave);
assert(err == 0);
Pthread_mutex_unlock(&slaves_mutex);
Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
} else {
Pthread_mutex_lock(&slave->mutex);
Pthread_mutex_unlock(&slaves_mutex);
for (i = slave->clients.next; i != &slave->clients; i = i->next) {
Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
list_for_each(i, &slave->clients) {
snd_pcm_share_t *sh = list_entry(i, snd_pcm_share_t, list);
unsigned int k;
for (k = 0; k < sh->channels_count; ++k) {
@ -1331,8 +1334,6 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
share->pcm = pcm;
share->client_socket = sd[0];
share->slave_socket = sd[1];
share->async_sig = SIGIO;
share->async_pid = getpid();
if (name)
pcm->name = strdup(name);
@ -1363,15 +1364,17 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
{
snd_config_iterator_t i, next;
const char *sname = NULL;
snd_config_t *binding = NULL;
snd_config_t *bindings = NULL;
int err;
snd_config_t *slave = NULL;
unsigned int idx;
int *channels_map;
unsigned int channels_count = 0;
long schannels_count = -1;
unsigned int schannel_max = 0;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
long srate = -1;
int schannels = -1;
int srate = -1;
int speriod_time= -1, sbuffer_time = -1;
unsigned int schannel_max = 0;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
@ -1380,64 +1383,43 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
continue;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "sname") == 0) {
if (strcmp(id, "slave") == 0) {
err = snd_config_get_string(n, &sname);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
slave = n;
continue;
}
if (strcmp(id, "sformat") == 0) {
const char *f;
err = snd_config_get_string(n, &f);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
sformat = snd_pcm_format_value(f);
if (sformat == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("Unknown format %s", f);
return -EINVAL;
}
continue;
}
if (strcmp(id, "schannels") == 0) {
err = snd_config_get_integer(n, &schannels_count);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "srate") == 0) {
err = snd_config_get_integer(n, &srate);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "binding") == 0) {
if (strcmp(id, "bindings") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
binding = n;
bindings = n;
continue;
}
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
}
if (!binding) {
SNDERR("binding is not defined");
err = snd_pcm_slave_conf(slave, &sname, 5,
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);
if (err < 0)
return err;
if (!bindings) {
SNDERR("bindings is not defined");
return -EINVAL;
}
snd_config_for_each(i, next, binding) {
snd_config_for_each(i, next, bindings) {
int cchannel = -1;
char *p;
snd_config_t *n = snd_config_iterator_entry(i);
@ -1459,7 +1441,7 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
for (idx = 0; idx < channels_count; ++idx)
channels_map[idx] = -1;
snd_config_for_each(i, next, binding) {
snd_config_for_each(i, next, bindings) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
long cchannel;
@ -1468,15 +1450,15 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
err = snd_config_get_integer(n, &schannel);
if (err < 0)
goto _free;
assert(schannels_count <= 0 || schannel < schannels_count);
assert(schannels <= 0 || schannel < schannels);
channels_map[cchannel] = schannel;
if ((unsigned)schannel > schannel_max)
schannel_max = schannel;
}
if (schannels_count <= 0)
schannels_count = schannel_max + 1;
if (schannels <= 0)
schannels = schannel_max + 1;
err = snd_pcm_share_open(pcmp, name, sname, sformat, srate,
schannels_count,
schannels, speriod_time, sbuffer_time,
channels_count, channels_map, stream, mode);
_free:
free(channels_map);

View file

@ -721,7 +721,7 @@ int _snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
{
snd_config_iterator_t i, next;
const char *server = NULL;
const char *sname = NULL;
const char *pcm_name = NULL;
snd_config_t *sconfig;
const char *host = NULL;
const char *socket = NULL;
@ -744,8 +744,8 @@ int _snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
}
continue;
}
if (strcmp(id, "sname") == 0) {
err = snd_config_get_string(n, &sname);
if (strcmp(id, "pcm") == 0) {
err = snd_config_get_string(n, &pcm_name);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
@ -755,19 +755,23 @@ int _snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
SNDERR("Unknown field %s", id);
return -EINVAL;
}
if (!sname) {
SNDERR("sname is not defined");
if (!pcm_name) {
SNDERR("pcm is not defined");
return -EINVAL;
}
if (!server) {
SNDERR("server is not defined");
return -EINVAL;
}
err = snd_config_searchv(snd_config, &sconfig, "server", server, 0);
err = snd_config_search_alias(snd_config, "server", server, &sconfig);
if (err < 0) {
SNDERR("Unknown server %s", server);
return -EINVAL;
}
if (snd_config_get_type(sconfig) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for server %s definition", server);
return -EINVAL;
}
snd_config_for_each(i, next, sconfig) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
@ -819,6 +823,6 @@ int _snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
SNDERR("%s is not the local host", host);
return -EINVAL;
}
return snd_pcm_shm_open(pcmp, name, socket, sname, stream, mode);
return snd_pcm_shm_open(pcmp, name, socket, pcm_name, stream, mode);
}

View file

@ -524,6 +524,163 @@ put_1234_4321: as_s32(dst) = bswap_32(sample); goto PUT_END;
put_1234_4329: as_u32(dst) = bswap_32(sample) ^ 0x80; goto PUT_END;
#endif
#ifdef GETS_LABELS
static inline int32_t getS(const void *src, int src_sign, int src_wid, int src_end,
int dst_wid)
{
int32_t s;
switch (src_wid) {
case 8:
s = *(u_int8_t*)src;
break;
case 16:
s = *(u_int16_t*)src;
if (src_end)
s = bswap_16(s);
break;
case 24:
case 32:
s = *(u_int32_t*)src;
if (src_end)
s = bswap_32(s);
break;
}
if (!src_sign)
s -= 1U << (src_wid - 1);
if (src_wid < dst_wid)
return s * (1 << (dst_wid - src_wid));
else
return s / (1 << (src_wid - dst_wid));
}
/* src_sign src_wid src_end dst_wid */
static void *gets_labels[2 * 4 * 2 * 4] = {
&&gets_u8_8, /* u8h -> s8 */
&&gets_u8_16, /* u8h -> s16 */
&&gets_u8_24, /* u8h -> s24 */
&&gets_u8_32, /* u8h -> s32 */
&&gets_u8_8, /* u8s -> s8 */
&&gets_u8_16, /* u8s -> s16 */
&&gets_u8_24, /* u8s -> s24 */
&&gets_u8_32, /* u8s -> s32 */
&&gets_u16h_8, /* u16h -> s8 */
&&gets_u16h_16, /* u16h -> s16 */
&&gets_u16h_24, /* u16h -> s24 */
&&gets_u16h_32, /* u16h -> s32 */
&&gets_u16s_8, /* u16s -> s8 */
&&gets_u16s_16, /* u16s -> s16 */
&&gets_u16s_24, /* u16s -> s24 */
&&gets_u16s_32, /* u16s -> s32 */
&&gets_u24h_8, /* u24h -> s8 */
&&gets_u24h_16, /* u24h -> s16 */
&&gets_u24h_24, /* u24h -> s24 */
&&gets_u24h_32, /* u24h -> s32 */
&&gets_u24s_8, /* u24s -> s8 */
&&gets_u24s_16, /* u24s -> s16 */
&&gets_u24s_24, /* u24s -> s24 */
&&gets_u24s_32, /* u24s -> s32 */
&&gets_u32h_8, /* u32h -> s8 */
&&gets_u32h_16, /* u32h -> s16 */
&&gets_u32h_24, /* u32h -> s24 */
&&gets_u32h_32, /* u32h -> s32 */
&&gets_u32s_8, /* u32s -> s8 */
&&gets_u32s_16, /* u32s -> s16 */
&&gets_u32s_24, /* u32s -> s24 */
&&gets_u32s_32, /* u32s -> s32 */
&&gets_s8_8, /* s8h -> s8 */
&&gets_s8_16, /* s8h -> s16 */
&&gets_s8_24, /* s8h -> s24 */
&&gets_s8_32, /* s8h -> s32 */
&&gets_s8_8, /* s8s -> s8 */
&&gets_s8_16, /* s8s -> s16 */
&&gets_s8_24, /* s8s -> s24 */
&&gets_s8_32, /* s8s -> s32 */
&&gets_s16h_8, /* s16h -> s8 */
&&gets_s16h_16, /* s16h -> s16 */
&&gets_s16h_24, /* s16h -> s24 */
&&gets_s16h_32, /* s16h -> s32 */
&&gets_s16s_8, /* s16s -> s8 */
&&gets_s16s_16, /* s16s -> s16 */
&&gets_s16s_24, /* s16s -> s24 */
&&gets_s16s_32, /* s16s -> s32 */
&&gets_s24h_8, /* s24h -> s8 */
&&gets_s24h_16, /* s24h -> s16 */
&&gets_s24h_24, /* s24h -> s24 */
&&gets_s24h_32, /* s24h -> s32 */
&&gets_s24s_8, /* s24s -> s8 */
&&gets_s24s_16, /* s24s -> s16 */
&&gets_s24s_24, /* s24s -> s24 */
&&gets_s24s_32, /* s24s -> s32 */
&&gets_s32h_8, /* s32h -> s8 */
&&gets_s32h_16, /* s32h -> s16 */
&&gets_s32h_24, /* s32h -> s24 */
&&gets_s32h_32, /* s32h -> s32 */
&&gets_s32s_8, /* s32s -> s8 */
&&gets_s32s_16, /* s32s -> s16 */
&&gets_s32s_24, /* s32s -> s24 */
&&gets_s32s_32, /* s32s -> s32 */
};
#endif
#ifdef GETS_END
gets_u8_8: sample = getS(src, 0, 8, 0, 8); goto GETS_END;
gets_u8_16: sample = getS(src, 0, 8, 0, 16); goto GETS_END;
gets_u8_24: sample = getS(src, 0, 8, 0, 24); goto GETS_END;
gets_u8_32: sample = getS(src, 0, 8, 0, 32); goto GETS_END;
gets_u16h_8: sample = getS(src, 0, 16, 0, 8); goto GETS_END;
gets_u16h_16: sample = getS(src, 0, 16, 0, 16); goto GETS_END;
gets_u16h_24: sample = getS(src, 0, 16, 0, 24); goto GETS_END;
gets_u16h_32: sample = getS(src, 0, 16, 0, 32); goto GETS_END;
gets_u16s_8: sample = getS(src, 0, 16, 1, 8); goto GETS_END;
gets_u16s_16: sample = getS(src, 0, 16, 1, 16); goto GETS_END;
gets_u16s_24: sample = getS(src, 0, 16, 1, 24); goto GETS_END;
gets_u16s_32: sample = getS(src, 0, 16, 1, 32); goto GETS_END;
gets_u24h_8: sample = getS(src, 0, 24, 0, 8); goto GETS_END;
gets_u24h_16: sample = getS(src, 0, 24, 0, 16); goto GETS_END;
gets_u24h_24: sample = getS(src, 0, 24, 0, 24); goto GETS_END;
gets_u24h_32: sample = getS(src, 0, 24, 0, 32); goto GETS_END;
gets_u24s_8: sample = getS(src, 0, 24, 1, 8); goto GETS_END;
gets_u24s_16: sample = getS(src, 0, 24, 1, 16); goto GETS_END;
gets_u24s_24: sample = getS(src, 0, 24, 1, 24); goto GETS_END;
gets_u24s_32: sample = getS(src, 0, 24, 1, 32); goto GETS_END;
gets_u32h_8: sample = getS(src, 0, 32, 0, 8); goto GETS_END;
gets_u32h_16: sample = getS(src, 0, 32, 0, 16); goto GETS_END;
gets_u32h_24: sample = getS(src, 0, 32, 0, 24); goto GETS_END;
gets_u32h_32: sample = getS(src, 0, 32, 0, 32); goto GETS_END;
gets_u32s_8: sample = getS(src, 0, 32, 1, 8); goto GETS_END;
gets_u32s_16: sample = getS(src, 0, 32, 1, 16); goto GETS_END;
gets_u32s_24: sample = getS(src, 0, 32, 1, 24); goto GETS_END;
gets_u32s_32: sample = getS(src, 0, 32, 1, 32); goto GETS_END;
gets_s8_8: sample = getS(src, 1, 8, 0, 8); goto GETS_END;
gets_s8_16: sample = getS(src, 1, 8, 0, 16); goto GETS_END;
gets_s8_24: sample = getS(src, 1, 8, 0, 24); goto GETS_END;
gets_s8_32: sample = getS(src, 1, 8, 0, 32); goto GETS_END;
gets_s16h_8: sample = getS(src, 1, 16, 0, 8); goto GETS_END;
gets_s16h_16: sample = getS(src, 1, 16, 0, 16); goto GETS_END;
gets_s16h_24: sample = getS(src, 1, 16, 0, 24); goto GETS_END;
gets_s16h_32: sample = getS(src, 1, 16, 0, 32); goto GETS_END;
gets_s16s_8: sample = getS(src, 1, 16, 1, 8); goto GETS_END;
gets_s16s_16: sample = getS(src, 1, 16, 1, 16); goto GETS_END;
gets_s16s_24: sample = getS(src, 1, 16, 1, 24); goto GETS_END;
gets_s16s_32: sample = getS(src, 1, 16, 1, 32); goto GETS_END;
gets_s24h_8: sample = getS(src, 1, 24, 0, 8); goto GETS_END;
gets_s24h_16: sample = getS(src, 1, 24, 0, 16); goto GETS_END;
gets_s24h_24: sample = getS(src, 1, 24, 0, 24); goto GETS_END;
gets_s24h_32: sample = getS(src, 1, 24, 0, 32); goto GETS_END;
gets_s24s_8: sample = getS(src, 1, 24, 1, 8); goto GETS_END;
gets_s24s_16: sample = getS(src, 1, 24, 1, 16); goto GETS_END;
gets_s24s_24: sample = getS(src, 1, 24, 1, 24); goto GETS_END;
gets_s24s_32: sample = getS(src, 1, 24, 1, 32); goto GETS_END;
gets_s32h_8: sample = getS(src, 1, 32, 0, 8); goto GETS_END;
gets_s32h_16: sample = getS(src, 1, 32, 0, 16); goto GETS_END;
gets_s32h_24: sample = getS(src, 1, 32, 0, 24); goto GETS_END;
gets_s32h_32: sample = getS(src, 1, 32, 0, 32); goto GETS_END;
gets_s32s_8: sample = getS(src, 1, 32, 1, 8); goto GETS_END;
gets_s32s_16: sample = getS(src, 1, 32, 1, 16); goto GETS_END;
gets_s32s_24: sample = getS(src, 1, 32, 1, 24); goto GETS_END;
gets_s32s_32: sample = getS(src, 1, 32, 1, 32); goto GETS_END;
#endif
#undef as_u8
#undef as_u16
#undef as_u32

View file

@ -178,20 +178,22 @@ int snd_rawmidi_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
int (*open_func)(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
const char *name, snd_config_t *conf, int mode);
void *h;
const char *name1;
assert((inputp || outputp) && name);
err = snd_config_update();
if (err < 0)
return err;
err = snd_config_searchv(snd_config, &rawmidi_conf, "rawmidi", name, 0);
if (err < 0) {
err = snd_config_search_alias(snd_config, "rawmidi", name, &rawmidi_conf);
name1 = name;
if (err < 0 || snd_config_get_string(rawmidi_conf, &name1) >= 0) {
int card, dev, subdev;
err = sscanf(name, "hw:%d,%d,%d", &card, &dev, &subdev);
err = sscanf(name1, "hw:%d,%d,%d", &card, &dev, &subdev);
if (err == 3)
return snd_rawmidi_hw_open(inputp, outputp, name, card, dev, subdev, mode);
err = sscanf(name, "hw:%d,%d", &card, &dev);
err = sscanf(name1, "hw:%d,%d", &card, &dev);
if (err == 2)
return snd_rawmidi_hw_open(inputp, outputp, name, card, dev, -1, mode);
SNDERR("Unknown RAWMIDI %s", name);
SNDERR("Unknown RAWMIDI %s", name1);
return -ENOENT;
}
if (snd_config_get_type(rawmidi_conf) != SND_CONFIG_TYPE_COMPOUND) {
@ -208,7 +210,7 @@ int snd_rawmidi_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
SNDERR("Invalid type for %s", snd_config_get_id(conf));
return err;
}
err = snd_config_searchv(snd_config, &type_conf, "rawmiditype", str, 0);
err = snd_config_search_alias(snd_config, "rawmidi_type", str, &type_conf);
if (err >= 0) {
snd_config_for_each(i, next, type_conf) {
snd_config_t *n = snd_config_iterator_entry(i);

View file

@ -48,15 +48,17 @@ int snd_seq_open(snd_seq_t **seqp, const char *name,
int (*open_func)(snd_seq_t **seqp, const char *name, snd_config_t *conf,
int streams, int mode);
void *h;
const char *name1;
assert(seqp && name);
err = snd_config_update();
if (err < 0)
return err;
err = snd_config_searchv(snd_config, &seq_conf, "seq", name, 0);
if (err < 0) {
if (strcmp(name, "hw") == 0)
err = snd_config_search_alias(snd_config, "seq", name, &seq_conf);
name1 = name;
if (err < 0 || snd_config_get_string(seq_conf, &name1) >= 0) {
if (strcmp(name1, "hw") == 0)
return snd_seq_hw_open(seqp, name, streams, mode);
SNDERR("Unknown SEQ %s", name);
SNDERR("Unknown SEQ %s", name1);
return -ENOENT;
}
if (snd_config_get_type(seq_conf) != SND_CONFIG_TYPE_COMPOUND) {
@ -73,7 +75,7 @@ int snd_seq_open(snd_seq_t **seqp, const char *name,
SNDERR("Invalid type for %s", snd_config_get_id(conf));
return err;
}
err = snd_config_searchv(snd_config, &type_conf, "seqtype", str, 0);
err = snd_config_search_alias(snd_config, "seq_type", str, &type_conf);
if (err >= 0) {
snd_config_for_each(i, next, type_conf) {
snd_config_t *n = snd_config_iterator_entry(i);