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);
+# 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 types:
-
-- hw Kernel PCM
-Fields:
-card Card name or number
-[device] Device number (default 0)
-[subdevice] Subdevice number, -1 first available (default -1)
-
-- plug Format adjusted PCM
-Fields:
-sname Slave PCM name
-ttable Transfer table (bidimensional compound of
- cchannels * schannels numbers)
- .C
- .S route value
-
-- 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)
-
-
-- 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
-
-
-CTL common fields:
-type CTL type
-[comment] Saved comments
-
-- hw Kernel CTL
-Fields:
-card Card name or number
-
-- shm Shared memory client CTL
-Fields:
-server Server name
-sname Slave CTL name on server
-
-Other related definitions:
-
-- pcmtype PCM type
-Fields:
-[lib] Library file
-open Open function
-
-- ctltype Control type
-Fields:
-[lib] Library file
-open Open function
-
-- scopetype PCM scope type
-Fields:
-[lib] Library file
-open Open function
-
-- 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
+# PCM type definition
+pcm_type.NAME {
+ [lib STR] # Library file (default libasound.so)
+ [open STR] # Open function (default _snd_pcm_NAME_open)
+}
+
+# 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)
+}
+
+# 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.
+}
+
+# PCM definition
+pcm.NAME {
+ type STR # Type
+ [comment ANY] # Saved comments
+
+# 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)
+
+
+ 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)
+ }
+ }
+
+
+ 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
+ }
+
+
+ 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
+ }
+
+
+ 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)
+ }
+ }
+
+
+ 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
+ }
+ }
+
+
+ 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
+ }
-Some examples:
-pcmtype.hw {
- open _snd_pcm_hw_open
}
-pcmtype.plug {
- open _snd_pcm_plug_open
+# 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:
+
pcm.trident {
type hw
card 0
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
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);
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;
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);
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);
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
#include <string.h>
#include <malloc.h>
#include <stdarg.h>
+#include <signal.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/shm.h>
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)
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);
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);
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);
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);
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);
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;
+}
+
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);
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 */
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);
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 */
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);
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)
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;
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) {
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;
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);
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 */
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 */
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)
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);
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) {
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) {
}
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;
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)
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);
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 */
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;
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);
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;
- goto _free;
- }
- if (!name) {
- SNDERR("name is not defined");
- err = -EINVAL;
- goto _free;
- }
- if (channels < 0) {
- SNDERR("channels is not defined");
- err = -EINVAL;
+ err = snd_pcm_slave_conf(m, &name, 1,
+ SND_PCM_HW_PARAM_CHANNELS, 1, &channels);
+ if (err < 0)
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;
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);
}
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);
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;
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) {
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,
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);
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 */
#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;
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;
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) {
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);
#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 {
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;
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;
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;
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)) {
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)
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);
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;
}
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;
}
_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;
}
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) {
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);
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)
{
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;
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);
}
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]);
}
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) {
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);
{
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);
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);
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;
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);
{
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;
}
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;
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);
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);
}
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
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) {
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);
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) {
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);