# libasound must be compiled with -fno-short-enums, as it makes extensive
# use of enums which are often type casted to unsigned ints.
LOCAL_CFLAGS := \
- -fno-short-enums -fPIC \
+ -fPIC -DPIC -D_POSIX_SOURCE \
-DALSA_CONFIG_DIR=\"/system/usr/share/alsa\" \
-DALSA_PLUGIN_DIR=\"/system/usr/lib/alsa-lib\" \
-DALSA_DEVICE_DIRECTORY=\"/dev/snd/\"
-LOCAL_SRC_FILES := $(addprefix src/, \
- conf.c \
- confmisc.c \
- input.c \
- output.c \
- async.c \
- error.c \
- dlmisc.c \
- socket.c \
- shmarea.c \
- userfile.c \
- names.c \
- hwdep/hwdep.c \
- hwdep/hwdep_hw.c \
- hwdep/hwdep_symbols.c \
- mixer/bag.c \
- mixer/mixer.c \
- mixer/simple.c \
- mixer/simple_abst.c \
- mixer/simple_none.c \
- pcm/atomic.c \
- pcm/mask.c \
- pcm/interval.c \
- pcm/pcm.c \
- pcm/pcm_params.c \
- pcm/pcm_simple.c \
- pcm/pcm_hw.c \
- pcm/pcm_misc.c \
- pcm/pcm_mmap.c \
- pcm/pcm_symbols.c \
- pcm/pcm_generic.c \
- pcm/pcm_plugin.c \
- pcm/pcm_copy.c \
- pcm/pcm_linear.c \
- pcm/pcm_plug.c \
- pcm/pcm_null.c \
- pcm/pcm_empty.c \
- pcm/pcm_hooks.c \
- pcm/pcm_asym.c \
- pcm/pcm_extplug.c \
- pcm/pcm_ioplug.c \
- control/cards.c \
- control/tlv.c \
- control/namehint.c \
- control/hcontrol.c \
- control/control.c \
- control/control_hw.c \
- control/setup.c \
- control/control_symbols.c \
- control/control_ext.c \
- timer/timer.c \
- timer/timer_hw.c \
- timer/timer_query.c \
- timer/timer_query_hw.c \
- timer/timer_symbols.c \
- )
+LOCAL_SRC_FILES := $(sort $(call all-c-files-under, src))
+
+# It is easier to exclude the ones we don't want...
+#
+LOCAL_SRC_FILES := $(filter-out src/pcm/pcm_ladspa.c, $(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(filter-out src/pcm/scopes/level.c, $(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(filter-out src/pcm/pcm_d%.c, $(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(filter-out src/alisp/alisp_snd.c, $(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(filter-out src/compat/hsearch_r.c, $(LOCAL_SRC_FILES))
include $(BUILD_STATIC_LIBRARY)
+ACLOCAL_AMFLAGS = -I m4
+
SUBDIRS=doc include src
if BUILD_MODULES
SUBDIRS += modules
endif
endif
SUBDIRS += test utils
-EXTRA_DIST=ChangeLog INSTALL TODO NOTES configure hgcompile libtool depcomp version MEMORY-LEAK
+EXTRA_DIST=ChangeLog INSTALL TODO NOTES configure gitcompile libtool \
+ depcomp version MEMORY-LEAK m4/attributes.m4
AUTOMAKE_OPTIONS=foreign
INCLUDES=-I$(top_srcdir)/include
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_MODULES_TRUE@am__append_1 = modules
@BUILD_PCM_PLUGIN_SHM_TRUE@am__append_2 = aserver
@BUILD_ALISP_TRUE@@BUILD_MIXER_TRUE@am__append_3 = alsalisp
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
+ACLOCAL_AMFLAGS = -I m4
SUBDIRS = doc include src $(am__append_1) $(am__append_2) \
$(am__append_3) test utils
-EXTRA_DIST = ChangeLog INSTALL TODO NOTES configure hgcompile libtool depcomp version MEMORY-LEAK
+EXTRA_DIST = ChangeLog INSTALL TODO NOTES configure gitcompile libtool \
+ depcomp version MEMORY-LEAK m4/attributes.m4
+
AUTOMAKE_OPTIONS = foreign
INCLUDES = -I$(top_srcdir)/include
all: all-recursive
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
- $(mkdir_p) $(distdir)/src $(distdir)/utils
+ $(mkdir_p) $(distdir)/doc $(distdir)/m4 $(distdir)/src $(distdir)/utils
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
This version of the ALSA library was obtained from the following location:
-ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.16.tar.bz2
+ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.19.tar.bz2
-This package was configured with the following options:
+This package was (previously in 1.0.16) configured with the following options:
./configure \
--disable-debug \
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
noinst_PROGRAMS = alsalisp$(EXEEXT)
subdir = alsalisp
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
alsalisp_SOURCES = alsalisp.c
alsalisp_LDADD = ../src/libasound.la
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/alisp
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
bin_PROGRAMS = aserver$(EXEEXT)
subdir = aserver
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
aserver_SOURCES = aserver.c
# aserver_LDADD = -lasound
aserver_LDADD = ../src/libasound.la
int main(int argc, char **argv)
{
- static struct option long_options[] = {
+ static const struct option long_options[] = {
{"help", 0, 0, 'h'},
{ 0 , 0 , 0, 0 }
};
host_cpu
host_vendor
host_os
-target
-target_cpu
-target_vendor
-target_os
INSTALL_PROGRAM
INSTALL_SCRIPT
INSTALL_DATA
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
- --target=TARGET configure for building compilers for TARGET [HOST]
_ACEOF
fi
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+case m4 in
+ [\\/]* | ?:[\\/]* ) ac_macro_dir=m4 ;;
+ *) ac_macro_dir=$srcdir/m4 ;;
+esac
+test -d "$ac_macro_dir" ||
+ { { echo "$as_me:$LINENO: error: cannot find macro directory \`m4'" >&5
+echo "$as_me: error: cannot find macro directory \`m4'" >&2;}
+ { (exit 1); exit 1; }; }
+
+
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
if test -f "$ac_dir/install-sh"; then
case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-{ echo "$as_me:$LINENO: checking target system type" >&5
-echo $ECHO_N "checking target system type... $ECHO_C" >&6; }
-if test "${ac_cv_target+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "x$target_alias" = x; then
- ac_cv_target=$ac_cv_host
-else
- ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
- { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5
-echo "${ECHO_T}$ac_cv_target" >&6; }
-case $ac_cv_target in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5
-echo "$as_me: error: invalid value of canonical target" >&2;}
- { (exit 1); exit 1; }; };;
-esac
-target=$ac_cv_target
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_target
-shift
-target_cpu=$1
-target_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-target_os=$*
-IFS=$ac_save_IFS
-case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
-
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-test -n "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
am__api_version="1.9"
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# Define the identity of the package.
PACKAGE=alsa-lib
- VERSION=1.0.16
+ VERSION=1.0.19
cat >>confdefs.h <<_ACEOF
-if test "x$target" != "x$host" -a -z "`echo $CC | grep -e '-gcc'`";
+if test "x$host" != "x$build" -a -z "`echo $CC | grep -e '-gcc'`";
then
{ echo "$as_me:$LINENO: checking for cross-compiler" >&5
echo $ECHO_N "checking for cross-compiler... $ECHO_C" >&6; }
which ${program_prefix}gcc >/dev/null 2>&1 && CC=${program_prefix}gcc
- which ${target_cpu}-${target_os}-gcc >/dev/null 2>&1 \
- && CC=${target_cpu}-${target-os}-gcc
- which ${target_cpu}-${target_vendor}-${target_os}-gcc >/dev/null 2>&1 \
- && CC=${target_cpu}-${target_vendor}-${target_os}-gcc
+ which ${host_cpu}-${host_os}-gcc >/dev/null 2>&1 \
+ && CC=${host_cpu}-${host-os}-gcc
+ which ${host_cpu}-${host_vendor}-${host_os}-gcc >/dev/null 2>&1 \
+ && CC=${host_cpu}-${host_vendor}-${host_os}-gcc
{ echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6; }
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 4894 "configure"' > conftest.$ac_ext
+ echo '#line 4857 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7595: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7558: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7599: \$? = $ac_status" >&5
+ echo "$as_me:7562: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7863: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7826: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7867: \$? = $ac_status" >&5
+ echo "$as_me:7830: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7967: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7930: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7971: \$? = $ac_status" >&5
+ echo "$as_me:7934: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10419 "configure"
+#line 10382 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10519 "configure"
+#line 10482 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12887: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12850: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:12891: \$? = $ac_status" >&5
+ echo "$as_me:12854: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12991: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12954: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:12995: \$? = $ac_status" >&5
+ echo "$as_me:12958: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14561: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14524: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:14565: \$? = $ac_status" >&5
+ echo "$as_me:14528: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14665: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14628: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:14669: \$? = $ac_status" >&5
+ echo "$as_me:14632: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16895: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16858: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16899: \$? = $ac_status" >&5
+ echo "$as_me:16862: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17163: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17126: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17167: \$? = $ac_status" >&5
+ echo "$as_me:17130: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17267: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17230: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17271: \$? = $ac_status" >&5
+ echo "$as_me:17234: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
+CC_NOUNDEFINED
+
{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
if test "${ac_cv_header_stdc+set}" = set; then
ac_config_headers="$ac_config_headers include/config.h"
-
{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
if test "${ac_cv_c_const+set}" = set; then
{ echo "$as_me:$LINENO: checking for architecture" >&5
echo $ECHO_N "checking for architecture... $ECHO_C" >&6; }
-case "$target" in
+case "$host" in
i?86*)
{ echo "$as_me:$LINENO: result: x86" >&5
echo "${ECHO_T}x86" >&6; }
_ACEOF
fi
+if test "$build_pcm_mmap_emul" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define BUILD_PCM_PLUGIN_MMAP_EMUL "1"
+_ACEOF
+
+fi
rm -f "$srcdir"/src/pcm/pcm_symbols_list.c
ln -sf . "$srcdir"/include/alsa
fi
-ac_config_files="$ac_config_files Makefile doc/Makefile doc/pictures/Makefile include/Makefile include/sound/Makefile src/Versions src/Makefile src/control/Makefile src/mixer/Makefile src/pcm/Makefile src/pcm/scopes/Makefile src/rawmidi/Makefile src/timer/Makefile src/hwdep/Makefile src/seq/Makefile src/compat/Makefile src/alisp/Makefile src/conf/Makefile src/conf/cards/Makefile src/conf/pcm/Makefile modules/Makefile modules/mixer/Makefile modules/mixer/simple/Makefile alsalisp/Makefile aserver/Makefile test/Makefile utils/Makefile utils/alsa-lib.spec utils/alsa.pc"
+ac_config_files="$ac_config_files Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg include/Makefile include/sound/Makefile src/Versions src/Makefile src/control/Makefile src/mixer/Makefile src/pcm/Makefile src/pcm/scopes/Makefile src/rawmidi/Makefile src/timer/Makefile src/hwdep/Makefile src/seq/Makefile src/compat/Makefile src/alisp/Makefile src/conf/Makefile src/conf/cards/Makefile src/conf/pcm/Makefile modules/Makefile modules/mixer/Makefile modules/mixer/simple/Makefile alsalisp/Makefile aserver/Makefile test/Makefile utils/Makefile utils/alsa-lib.spec utils/alsa.pc"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"doc/pictures/Makefile") CONFIG_FILES="$CONFIG_FILES doc/pictures/Makefile" ;;
+ "doc/doxygen.cfg") CONFIG_FILES="$CONFIG_FILES doc/doxygen.cfg" ;;
"include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
"include/sound/Makefile") CONFIG_FILES="$CONFIG_FILES include/sound/Makefile" ;;
"src/Versions") CONFIG_FILES="$CONFIG_FILES src/Versions" ;;
host_cpu!$host_cpu$ac_delim
host_vendor!$host_vendor$ac_delim
host_os!$host_os$ac_delim
-target!$target$ac_delim
-target_cpu!$target_cpu$ac_delim
-target_vendor!$target_vendor$ac_delim
-target_os!$target_os$ac_delim
INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
INSTALL_DATA!$INSTALL_DATA$ac_delim
RANLIB!$RANLIB$ac_delim
CXX!$CXX$ac_delim
CXXFLAGS!$CXXFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
+CXXDEPMODE!$CXXDEPMODE$ac_delim
+am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim
+am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
-ac_ct_CXX!$ac_ct_CXX$ac_delim
-CXXDEPMODE!$CXXDEPMODE$ac_delim
-am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim
-am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim
CXXCPP!$CXXCPP$ac_delim
F77!$F77$ac_delim
FFLAGS!$FFLAGS$ac_delim
BUILD_PCM_PLUGIN_SOFTVOL_FALSE!$BUILD_PCM_PLUGIN_SOFTVOL_FALSE$ac_delim
BUILD_PCM_PLUGIN_EXTPLUG_TRUE!$BUILD_PCM_PLUGIN_EXTPLUG_TRUE$ac_delim
BUILD_PCM_PLUGIN_EXTPLUG_FALSE!$BUILD_PCM_PLUGIN_EXTPLUG_FALSE$ac_delim
+BUILD_PCM_PLUGIN_IOPLUG_TRUE!$BUILD_PCM_PLUGIN_IOPLUG_TRUE$ac_delim
+BUILD_PCM_PLUGIN_IOPLUG_FALSE!$BUILD_PCM_PLUGIN_IOPLUG_FALSE$ac_delim
+BUILD_PCM_PLUGIN_MMAP_EMUL_TRUE!$BUILD_PCM_PLUGIN_MMAP_EMUL_TRUE$ac_delim
+BUILD_PCM_PLUGIN_MMAP_EMUL_FALSE!$BUILD_PCM_PLUGIN_MMAP_EMUL_FALSE$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
-BUILD_PCM_PLUGIN_IOPLUG_TRUE!$BUILD_PCM_PLUGIN_IOPLUG_TRUE$ac_delim
-BUILD_PCM_PLUGIN_IOPLUG_FALSE!$BUILD_PCM_PLUGIN_IOPLUG_FALSE$ac_delim
-BUILD_PCM_PLUGIN_MMAP_EMUL_TRUE!$BUILD_PCM_PLUGIN_MMAP_EMUL_TRUE$ac_delim
-BUILD_PCM_PLUGIN_MMAP_EMUL_FALSE!$BUILD_PCM_PLUGIN_MMAP_EMUL_FALSE$ac_delim
BUILD_CTL_PLUGIN_TRUE!$BUILD_CTL_PLUGIN_TRUE$ac_delim
BUILD_CTL_PLUGIN_FALSE!$BUILD_CTL_PLUGIN_FALSE$ac_delim
BUILD_CTL_PLUGIN_SHM_TRUE!$BUILD_CTL_PLUGIN_SHM_TRUE$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 12; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 8; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(src/control/control.c)
+
+AC_CONFIG_MACRO_DIR([m4])
+
dnl *************************************************
dnl current:revision:age
dnl change (without API) = c:r+1:a
dnl add API = c+1:0:a+1
dnl remove API = c+1:0:0
dnl *************************************************
-AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(alsa-lib, 1.0.16)
+AC_CANONICAL_HOST
+AM_INIT_AUTOMAKE(alsa-lib, 1.0.19)
eval LIBTOOL_VERSION_INFO="2:0:0"
dnl *************************************************
AM_CONDITIONAL(INSTALL_M4, test -n "${ACLOCAL}")
dnl Checks for programs.
dnl try to gues cross-compiler if not set
-if test "x$target" != "x$host" -a -z "`echo $CC | grep -e '-gcc'`";
+if test "x$host" != "x$build" -a -z "`echo $CC | grep -e '-gcc'`";
then
AC_MSG_CHECKING(for cross-compiler)
which ${program_prefix}gcc >/dev/null 2>&1 && CC=${program_prefix}gcc
- which ${target_cpu}-${target_os}-gcc >/dev/null 2>&1 \
- && CC=${target_cpu}-${target-os}-gcc
- which ${target_cpu}-${target_vendor}-${target_os}-gcc >/dev/null 2>&1 \
- && CC=${target_cpu}-${target_vendor}-${target_os}-gcc
+ which ${host_cpu}-${host_os}-gcc >/dev/null 2>&1 \
+ && CC=${host_cpu}-${host-os}-gcc
+ which ${host_cpu}-${host_vendor}-${host_os}-gcc >/dev/null 2>&1 \
+ && CC=${host_cpu}-${host_vendor}-${host_os}-gcc
AC_MSG_RESULT($CC)
fi
AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
+CC_NOUNDEFINED
+
dnl Checks for header files.
AC_HEADER_STDC
AM_CONFIG_HEADER(include/config.h)
-
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
dnl Check for architecture
AC_MSG_CHECKING(for architecture)
-case "$target" in
+case "$host" in
i?86*)
AC_MSG_RESULT(x86)
;;
if test "$build_pcm_alaw" = "yes"; then
AC_DEFINE([BUILD_PCM_PLUGIN_ALAW], "1", [Build PCM alaw plugin])
fi
+if test "$build_pcm_mmap_emul" = "yes"; then
+ AC_DEFINE([BUILD_PCM_PLUGIN_MMAP_EMUL], "1", [Build PCM mmap-emul plugin])
+fi
dnl Create PCM plugin symbol list for static library
ln -sf . "$srcdir"/include/alsa
fi
-AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile include/Makefile
- include/sound/Makefile src/Versions src/Makefile \
+AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \
+ include/Makefile include/sound/Makefile src/Versions src/Makefile \
src/control/Makefile src/mixer/Makefile \
src/pcm/Makefile src/pcm/scopes/Makefile \
src/rawmidi/Makefile src/timer/Makefile \
INCLUDES=-I$(top_srcdir)/include
doc:
+ test -e doxygen.cfg || sed s:@top_srcdir@:..:g doxygen.cfg.in > doxygen.cfg
doxygen doxygen.cfg
doc-pack: doc
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = doc
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/doxygen.cfg.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.in
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = doxygen.cfg
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
SUBDIRS = pictures
EXTRA_DIST = README.1st asoundrc.txt doxygen.cfg index.doxygen
INCLUDES = -I$(top_srcdir)/include
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+doxygen.cfg: $(top_builddir)/config.status $(srcdir)/doxygen.cfg.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
mostlyclean-libtool:
-rm -f *.lo
doc:
+ test -e doxygen.cfg || sed s:@top_srcdir@:..:g doxygen.cfg.in > doxygen.cfg
doxygen doxygen.cfg
doc-pack: doc
GENERATE_RTF = NO
CASE_SENSE_NAMES = NO
-INPUT = index.doxygen \
+INPUT = ../doc/index.doxygen \
../include/asoundlib.h \
../include/version.h \
../include/global.h \
../src/mixer \
../src/pcm/pcm.c \
../src/pcm/pcm_mmap.c \
- ../src/pcm/pcm_plugin.c \
+ ../src/pcm/pcm_plugin.c \
../src/pcm/pcm_hw.c \
../src/pcm/pcm_mmap_emul.c \
../src/pcm/pcm_shm.c \
--- /dev/null
+PROJECT_NAME = "ALSA project - the C library reference"
+OUTPUT_DIRECTORY = doxygen
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+
+CASE_SENSE_NAMES = NO
+INPUT = @top_srcdir@/doc/index.doxygen \
+ @top_srcdir@/include/asoundlib.h \
+ @top_srcdir@/include/version.h \
+ @top_srcdir@/include/global.h \
+ @top_srcdir@/include/asoundef.h \
+ @top_srcdir@/include/input.h \
+ @top_srcdir@/include/output.h \
+ @top_srcdir@/include/error.h \
+ @top_srcdir@/include/conf.h \
+ @top_srcdir@/include/control.h \
+ @top_srcdir@/include/pcm.h \
+ @top_srcdir@/include/rawmidi.h \
+ @top_srcdir@/include/timer.h \
+ @top_srcdir@/include/hwdep.h \
+ @top_srcdir@/include/seq.h \
+ @top_srcdir@/include/seq_event.h \
+ @top_srcdir@/include/seqmid.h \
+ @top_srcdir@/include/seq_midi_event.h \
+ @top_srcdir@/include/pcm_external.h \
+ @top_srcdir@/include/pcm_extplug.h \
+ @top_srcdir@/include/pcm_ioplug.h \
+ @top_srcdir@/include/control_external.h \
+ @top_srcdir@/include/mixer.h \
+ @top_srcdir@/src/error.c \
+ @top_srcdir@/src/dlmisc.c \
+ @top_srcdir@/src/async.c \
+ @top_srcdir@/src/input.c \
+ @top_srcdir@/src/output.c \
+ @top_srcdir@/src/conf.c \
+ @top_srcdir@/src/confmisc.c \
+ @top_srcdir@/src/names.c \
+ @top_srcdir@/src/shmarea.c \
+ @top_srcdir@/src/userfile.c \
+ @top_srcdir@/src/control \
+ @top_srcdir@/src/mixer \
+ @top_srcdir@/src/pcm/pcm.c \
+ @top_srcdir@/src/pcm/pcm_mmap.c \
+ @top_srcdir@/src/pcm/pcm_plugin.c \
+ @top_srcdir@/src/pcm/pcm_hw.c \
+ @top_srcdir@/src/pcm/pcm_mmap_emul.c \
+ @top_srcdir@/src/pcm/pcm_shm.c \
+ @top_srcdir@/src/pcm/pcm_null.c \
+ @top_srcdir@/src/pcm/pcm_copy.c \
+ @top_srcdir@/src/pcm/pcm_linear.c \
+ @top_srcdir@/src/pcm/pcm_lfloat.c \
+ @top_srcdir@/src/pcm/pcm_mulaw.c \
+ @top_srcdir@/src/pcm/pcm_alaw.c \
+ @top_srcdir@/src/pcm/pcm_adpcm.c \
+ @top_srcdir@/src/pcm/pcm_route.c \
+ @top_srcdir@/src/pcm/pcm_rate.c \
+ @top_srcdir@/src/pcm/pcm_plug.c \
+ @top_srcdir@/src/pcm/pcm_file.c \
+ @top_srcdir@/src/pcm/pcm_multi.c \
+ @top_srcdir@/src/pcm/pcm_share.c \
+ @top_srcdir@/src/pcm/pcm_hooks.c \
+ @top_srcdir@/src/pcm/pcm_dmix.c \
+ @top_srcdir@/src/pcm/pcm_dshare.c \
+ @top_srcdir@/src/pcm/pcm_dsnoop.c \
+ @top_srcdir@/src/pcm/pcm_meter.c \
+ @top_srcdir@/src/pcm/pcm_ladspa.c \
+ @top_srcdir@/src/pcm/pcm_asym.c \
+ @top_srcdir@/src/pcm/pcm_iec958.c \
+ @top_srcdir@/src/pcm/pcm_softvol.c \
+ @top_srcdir@/src/pcm/pcm_extplug.c \
+ @top_srcdir@/src/pcm/pcm_ioplug.c \
+ @top_srcdir@/src/pcm/pcm_empty.c \
+ @top_srcdir@/src/pcm/pcm_misc.c \
+ @top_srcdir@/src/pcm/pcm_simple.c \
+ @top_srcdir@/src/rawmidi \
+ @top_srcdir@/src/timer \
+ @top_srcdir@/src/hwdep \
+ @top_srcdir@/src/seq
+EXCLUDE = @top_srcdir@/src/control/control_local.h \
+ @top_srcdir@/src/pcm/atomic.h \
+ @top_srcdir@/src/pcm/interval.h \
+ @top_srcdir@/src/pcm/interval_inline.h \
+ @top_srcdir@/src/pcm/mask.h \
+ @top_srcdir@/src/pcm/mask_inline.h \
+ @top_srcdir@/src/pcm/pcm_local.h \
+ @top_srcdir@/src/pcm/pcm_meter.h \
+ @top_srcdir@/src/pcm/pcm_plugin.h \
+ @top_srcdir@/src/pcm/plugin_ops.h \
+ @top_srcdir@/src/pcm/ladspa.h \
+ @top_srcdir@/src/hwdep/hwdep_local.h \
+ @top_srcdir@/src/mixer/mixer_local.h \
+ @top_srcdir@/src/rawmidi/rawmidi_local.h \
+ @top_srcdir@/src/seq/seq_local.h
+RECURSIVE = YES
+FILE_PATTERNS = *.c *.h
+EXAMPLE_PATH = @top_srcdir@/test
+IMAGE_PATH = pictures
+QUIET = YES
+
+EXTRACT_ALL = NO
+EXTRACT_STATIC = NO
+SHOW_INCLUDE_FILES = NO
+JAVADOC_AUTOBRIEF = NO
+INHERIT_DOCS = YES
+ENABLED_SECTIONS = ""
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+PREDEFINED = DOXYGEN PIC "DOC_HIDDEN" \
+ "ATTRIBUTE_UNUSED=" \
+ ALSA_PCM_NEW_HW_PARAMS_API \
+ _POSIX_C_SOURCE \
+ "use_default_symbol_version(x,y,z)=" \
+ "link_warning(x,y)="
+
+OPTIMIZE_OUTPUT_FOR_C = YES # doxygen 1.2.6 option
+
+#INPUT_FILTER = inputfilter
+#FILTER_SOURCE_FILES = YES
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = doc/pictures
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_DIST = wave1.gif wave2.gif
all: all-am
echo "./configure $@"
./configure $@ || exit 1
unset CFLAGS
-if [ -z "$HGCOMPILE_NO_MAKE" ]; then
+if [ -z "$GITCOMPILE_NO_MAKE" ]; then
make
fi
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_CTL_PLUGIN_EXT_TRUE@am__append_1 = control_external.h
@BUILD_PCM_TRUE@am__append_2 = pcm.h pcm_old.h timer.h
@BUILD_PCM_PLUGIN_TRUE@@BUILD_PCM_TRUE@am__append_3 = pcm_plugin.h
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
SUBDIRS = sound
sysincludedir = ${includedir}/sys
alsaincludedir = ${includedir}/alsa
#define IEC958_AES1_PRO_USERBITS_UDEF (12<<4) /**< user defined application */
#define IEC958_AES1_CON_CATEGORY 0x7f /**< consumer category */
#define IEC958_AES1_CON_GENERAL 0x00 /**< general category */
-#define IEC958_AES1_CON_EXPERIMENTAL 0x40 /**< experimental category */
-#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f /**< ??? */
-#define IEC958_AES1_CON_SOLIDMEM_ID 0x08 /**< ??? */
-#define IEC958_AES1_CON_BROADCAST1_MASK 0x07 /**< ??? */
-#define IEC958_AES1_CON_BROADCAST1_ID 0x04 /**< ??? */
-#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07 /**< digital<->digital converter mask */
-#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02 /**< digital<->digital converter id */
-#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f /**< ADC Copyright mask */
-#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x06 /**< ADC Copyright ID */
-#define IEC958_AES1_CON_ADC_MASK 0x1f /**< ADC Mask */
-#define IEC958_AES1_CON_ADC_ID 0x16 /**< ADC ID */
-#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f /**< Broadcast mask */
-#define IEC958_AES1_CON_BROADCAST2_ID 0x0e /**< Broadcast ID */
#define IEC958_AES1_CON_LASEROPT_MASK 0x07 /**< Laser-optical mask */
#define IEC958_AES1_CON_LASEROPT_ID 0x01 /**< Laser-optical ID */
-#define IEC958_AES1_CON_MUSICAL_MASK 0x07 /**< Musical device mask */
-#define IEC958_AES1_CON_MUSICAL_ID 0x05 /**< Musical device ID */
-#define IEC958_AES1_CON_MAGNETIC_MASK 0x07 /**< Magnetic device mask */
-#define IEC958_AES1_CON_MAGNETIC_ID 0x03 /**< Magnetic device ID */
#define IEC958_AES1_CON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x00) /**< IEC958 CD compatible device */
#define IEC958_AES1_CON_NON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x08) /**< non-IEC958 CD compatible device */
+#define IEC958_AES1_CON_MINI_DISC (IEC958_AES1_CON_LASEROPT_ID|0x48) /**< Mini-Disc device */
+#define IEC958_AES1_CON_DVD (IEC958_AES1_CON_LASEROPT_ID|0x18) /**< DVD device */
+#define IEC958_AES1_CON_LASTEROPT_OTHER (IEC958_AES1_CON_LASEROPT_ID|0x78) /**< Other laser-optical product */
+#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07 /**< digital<->digital converter mask */
+#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02 /**< digital<->digital converter id */
#define IEC958_AES1_CON_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00) /**< PCM coder */
-#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20) /**< PCM sampler */
-#define IEC958_AES1_CON_MIXER (IEC958_AES1_CON_DIGDIGCONV_ID|0x10) /**< Mixer */
+#define IEC958_AES1_CON_MIXER (IEC958_AES1_CON_DIGDIGCONV_ID|0x10) /**< Digital signal mixer */
#define IEC958_AES1_CON_RATE_CONVERTER (IEC958_AES1_CON_DIGDIGCONV_ID|0x18) /**< Rate converter */
-#define IEC958_AES1_CON_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00) /**< Synthesizer */
-#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08) /**< Microphone */
+#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20) /**< PCM sampler */
+#define IEC958_AES1_CON_DSP (IEC958_AES1_CON_DIGDIGCONV_ID|0x28) /**< Digital sound processor */
+#define IEC958_AES1_CON_DIGDIGCONV_OTHER (IEC958_AES1_CON_DIGDIGCONV_ID|0x78) /**< Other digital<->digital product */
+#define IEC958_AES1_CON_MAGNETIC_MASK 0x07 /**< Magnetic device mask */
+#define IEC958_AES1_CON_MAGNETIC_ID 0x03 /**< Magnetic device ID */
#define IEC958_AES1_CON_DAT (IEC958_AES1_CON_MAGNETIC_ID|0x00) /**< Digital Audio Tape */
#define IEC958_AES1_CON_VCR (IEC958_AES1_CON_MAGNETIC_ID|0x08) /**< Video recorder */
+#define IEC958_AES1_CON_DCC (IEC958_AES1_CON_MAGNETIC_ID|0x40) /**< Digital compact cassette */
+#define IEC958_AES1_CON_MAGNETIC_DISC (IEC958_AES1_CON_MAGNETIC_ID|0x18) /**< Magnetic disc digital audio device */
+#define IEC958_AES1_CON_MAGNETIC_OTHER (IEC958_AES1_CON_MAGNETIC_ID|0x78) /**< Other magnetic device */
+#define IEC958_AES1_CON_BROADCAST1_MASK 0x07 /**< Broadcast mask */
+#define IEC958_AES1_CON_BROADCAST1_ID 0x04 /**< Broadcast ID */
+#define IEC958_AES1_CON_DAB_JAPAN (IEC958_AES1_CON_BROADCAST1_ID|0x00) /**< Digital audio broadcast (Japan) */
+#define IEC958_AES1_CON_DAB_EUROPE (IEC958_AES1_CON_BROADCAST1_ID|0x08) /**< Digital audio broadcast (Europe) */
+#define IEC958_AES1_CON_DAB_USA (IEC958_AES1_CON_BROADCAST1_ID|0x60) /**< Digital audio broadcast (USA) */
+#define IEC958_AES1_CON_SOFTWARE (IEC958_AES1_CON_BROADCAST1_ID|0x40) /**< Electronic software delivery */
+#define IEC958_AES1_CON_IEC62105 (IEC958_AES1_CON_BROADCAST1_ID|0x20) /**< Used by another standard (IEC 62105) */
+#define IEC958_AES1_CON_BROADCAST1_OTHER (IEC958_AES1_CON_BROADCAST1_ID|0x78) /**< Other broadcast product */
+#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f /**< Broadcast alternative mask */
+#define IEC958_AES1_CON_BROADCAST2_ID 0x0e /**< Broadcast alternative ID */
+#define IEC958_AES1_CON_MUSICAL_MASK 0x07 /**< Musical device mask */
+#define IEC958_AES1_CON_MUSICAL_ID 0x05 /**< Musical device ID */
+#define IEC958_AES1_CON_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00) /**< Synthesizer */
+#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08) /**< Microphone */
+#define IEC958_AES1_CON_MUSICAL_OTHER (IEC958_AES1_CON_MUSICAL_ID|0x78) /**< Other musical device */
+#define IEC958_AES1_CON_ADC_MASK 0x1f /**< ADC Mask */
+#define IEC958_AES1_CON_ADC_ID 0x06 /**< ADC ID */
+#define IEC958_AES1_CON_ADC (IEC958_AES1_CON_ADC_ID|0x00) /**< ADC without copyright information */
+#define IEC958_AES1_CON_ADC_OTHER (IEC958_AES1_CON_ADC_ID|0x60) /**< Other ADC product (with no copyright information) */
+#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f /**< ADC Copyright mask */
+#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x16 /**< ADC Copyright ID */
+#define IEC958_AES1_CON_ADC_COPYRIGHT (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x00) /**< ADC with copyright information */
+#define IEC958_AES1_CON_ADC_COPYRIGHT_OTHER (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x60) /**< Other ADC with copyright information product */
+#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f /**< Solid memory based products mask */
+#define IEC958_AES1_CON_SOLIDMEM_ID 0x08 /**< Solid memory based products ID */
+#define IEC958_AES1_CON_SOLIDMEM_DIGITAL_RECORDER_PLAYER (IEC958_AES1_CON_SOLIDMEM_ID|0x00) /**< Digital audio recorder and player using solid state memory */
+#define IEC958_AES1_CON_SOLIDMEM_OTHER (IEC958_AES1_CON_SOLIDMEM_ID|0x70) /**< Other solid state memory based product */
+#define IEC958_AES1_CON_EXPERIMENTAL 0x40 /**< experimental category */
#define IEC958_AES1_CON_ORIGINAL (1<<7) /**< this bits depends on the category code */
#define IEC958_AES2_PRO_SBITS (7<<0) /**< mask - sample bits */
#define IEC958_AES2_PRO_SBITS_20 (2<<0) /**< 20-bit - coordination */
#define IEC958_AES2_CON_CHANNEL_UNSPEC (0<<4) /**< channel number unspecified */
#define IEC958_AES3_CON_FS (15<<0) /**< mask - sample frequency */
#define IEC958_AES3_CON_FS_44100 (0<<0) /**< 44.1kHz */
+#define IEC958_AES3_CON_FS_NOTID (1<<0) /**< sample frequency non indicated */
#define IEC958_AES3_CON_FS_48000 (2<<0) /**< 48kHz */
#define IEC958_AES3_CON_FS_32000 (3<<0) /**< 32kHz */
+#define IEC958_AES3_CON_FS_22050 (4<<0) /**< 22.05kHz */
+#define IEC958_AES3_CON_FS_24000 (6<<0) /**< 24kHz */
+#define IEC958_AES3_CON_FS_88200 (8<<0) /**< 88.2kHz */
+#define IEC958_AES3_CON_FS_768000 (9<<0) /**< 768kHz */
+#define IEC958_AES3_CON_FS_96000 (10<<0) /**< 96kHz */
+#define IEC958_AES3_CON_FS_176400 (12<<0) /**< 176.4kHz */
+#define IEC958_AES3_CON_FS_192000 (14<<0) /**< 192kHz */
#define IEC958_AES3_CON_CLOCK (3<<4) /**< mask - clock accuracy */
#define IEC958_AES3_CON_CLOCK_1000PPM (0<<4) /**< 1000 ppm */
#define IEC958_AES3_CON_CLOCK_50PPM (1<<4) /**< 50 ppm */
#define IEC958_AES3_CON_CLOCK_VARIABLE (2<<4) /**< variable pitch */
+#define IEC958_AES4_CON_MAX_WORDLEN_24 (1<<0) /**< 0 = 20-bit, 1 = 24-bit */
+#define IEC958_AES4_CON_WORDLEN (7<<1) /**< mask - sample word length */
+#define IEC958_AES4_CON_WORDLEN_NOTID (0<<1) /**< not indicated */
+#define IEC958_AES4_CON_WORDLEN_20_16 (1<<1) /**< 20-bit or 16-bit */
+#define IEC958_AES4_CON_WORDLEN_22_18 (2<<1) /**< 22-bit or 18-bit */
+#define IEC958_AES4_CON_WORDLEN_23_19 (4<<1) /**< 23-bit or 19-bit */
+#define IEC958_AES4_CON_WORDLEN_24_20 (5<<1) /**< 24-bit or 20-bit */
+#define IEC958_AES4_CON_WORDLEN_21_17 (6<<1) /**< 21-bit or 17-bit */
+#define IEC958_AES4_CON_ORIGFS (15<<4) /**< mask - original sample frequency */
+#define IEC958_AES4_CON_ORIGFS_NOTID (0<<4) /**< original sample frequency not indicated */
+#define IEC958_AES4_CON_ORIGFS_192000 (1<<4) /**< 192kHz */
+#define IEC958_AES4_CON_ORIGFS_12000 (2<<4) /**< 12kHz */
+#define IEC958_AES4_CON_ORIGFS_176400 (3<<4) /**< 176.4kHz */
+#define IEC958_AES4_CON_ORIGFS_96000 (5<<4) /**< 96kHz */
+#define IEC958_AES4_CON_ORIGFS_8000 (6<<4) /**< 8kHz */
+#define IEC958_AES4_CON_ORIGFS_88200 (7<<4) /**< 88.2kHz */
+#define IEC958_AES4_CON_ORIGFS_16000 (8<<4) /**< 16kHz */
+#define IEC958_AES4_CON_ORIGFS_24000 (9<<4) /**< 24kHz */
+#define IEC958_AES4_CON_ORIGFS_11025 (10<<4) /**< 11.025kHz */
+#define IEC958_AES4_CON_ORIGFS_22050 (11<<4) /**< 22.05kHz */
+#define IEC958_AES4_CON_ORIGFS_32000 (12<<4) /**< 32kHz */
+#define IEC958_AES4_CON_ORIGFS_48000 (13<<4) /**< 48kHz */
+#define IEC958_AES4_CON_ORIGFS_44100 (15<<4) /**< 44.1kHz */
+#define IEC958_AES5_CON_CGMSA (3<<0) /**< mask - CGMS-A */
+#define IEC958_AES5_CON_CGMSA_COPYFREELY (0<<0) /**< copying is permitted without restriction */
+#define IEC958_AES5_CON_CGMSA_COPYONCE (1<<0) /**< one generation of copies may be made */
+#define IEC958_AES5_CON_CGMSA_COPYNOMORE (2<<0) /**< condition not be used */
+#define IEC958_AES5_CON_CGMSA_COPYNEVER (3<<0) /**< no copying is permitted */
/** \} */
/* Build PCM lfloat plugin */
#undef BUILD_PCM_PLUGIN_LFLOAT
+/* Build PCM mmap-emul plugin */
+#undef BUILD_PCM_PLUGIN_MMAP_EMUL
+
/* Build PCM mulaw plugin */
#undef BUILD_PCM_PLUGIN_MULAW
int snd_user_file(const char *file, char **result);
-#if 0
-/* Bionic has struct timeval and struct timespec, but it does not define
- _POSIX_C_SOURCE and _POSIX_SOURCE */
#if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE)
struct timeval {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif
-#endif
/** Timestamp */
typedef struct timeval snd_timestamp_t;
/** Hi-res timestamp */
typedef struct timespec snd_htimestamp_t;
-/* The arm-eabi headers do not define O_ASYNC. */
-#ifndef O_ASYNC
-#define O_ASYNC FASYNC
-#endif
-
/** \} */
#ifdef __cplusplus
#endif /* __arm__ */
+#ifdef __sh__
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) != 0)
+
+#define atomic_add(i,v) atomic_add_return((i),(v))
+#define atomic_sub(i,v) atomic_sub_return((i),(v))
+#define atomic_inc(v) atomic_add(1,(v))
+#define atomic_dec(v) atomic_sub(1,(v))
+
+static __inline__ int atomic_add_return(int i, volatile atomic_t *v)
+{
+ int result;
+
+ asm volatile (
+ " .align 2\n"
+ " mova 99f, r0\n"
+ " mov r15, r1\n"
+ " mov #-6, r15\n"
+ " mov.l @%2, %0\n"
+ " add %1, %0\n"
+ " mov.l %0, @%2\n"
+ "99: mov r1, r15"
+ : "=&r"(result)
+ : "r"(i), "r"(v)
+ : "r0", "r1");
+
+ return result;
+}
+
+static __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
+{
+ int result;
+
+ asm volatile (
+ " .align 2\n"
+ " mova 99f, r0\n"
+ " mov r15, r1\n"
+ " mov #-6, r15\n"
+ " mov.l @%2, %0\n"
+ " sub %1, %0\n"
+ " mov.l %0, @%2\n"
+ "99: mov r1, r15"
+ : "=&r"(result)
+ : "r"(i), "r"(v)
+ : "r0", "r1");
+
+ return result;
+}
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+#define rmb() mb()
+#define wmb() mb()
+
+#define IATOMIC_DEFINED 1
+
+#endif /* __sh__ */
+
#ifndef IATOMIC_DEFINED
/*
* non supported architecture.
/** Mixer element type */
typedef enum _snd_mixer_elem_type {
- /* Simple (legacy) mixer elements */
+ /* Simple mixer elements */
SND_MIXER_ELEM_SIMPLE,
SND_MIXER_ELEM_LAST = SND_MIXER_ELEM_SIMPLE
} snd_mixer_elem_type_t;
* \{
*/
-/* Simple (legacy) mixer elements API */
+/* Simple mixer elements API */
/** Mixer simple element channel identifier */
typedef enum _snd_mixer_selem_channel_id {
int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem);
int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem);
+int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue);
+int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue);
+int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value);
+int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value);
int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value);
int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value);
int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value);
int (*get_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max);
int (*set_range)(snd_mixer_elem_t *elem, int dir, long min, long max);
int (*get_dB_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max);
+ int (*ask_vol_dB)(snd_mixer_elem_t *elem, int dir, long value, long *dbValue);
+ int (*ask_dB_vol)(snd_mixer_elem_t *elem, int dir, long dbValue, long *value, int xdir);
int (*get_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value);
int (*get_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value);
int (*set_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value);
int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
int snd_pcm_resume(snd_pcm_t *pcm);
int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
+snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
+int snd_pcm_avail_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp);
+snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
int snd_pcm_unlink(snd_pcm_t *pcm);
+//int snd_pcm_mixer_element(snd_pcm_t *pcm, snd_mixer_t *mixer, snd_mixer_elem_t **elem);
+
/*
* application helpers - these functions are implemented on top
* of the basic API
int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_forward(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_rewind(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params);
int snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val);
int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val);
+int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val);
int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
int snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *paramsm, snd_pcm_uframes_t *val);
int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
int snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val) __attribute__((deprecated));
int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val) __attribute__((deprecated));
int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params, unsigned int *val) __attribute__((deprecated));
+#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */
+#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_HW_PARAMS_API)
int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
-#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */
+#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_HW_PARAMS_API */
/** \} */
void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val);
void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter);
+void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info);
+void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type);
+void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type);
+int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type);
+
int snd_seq_get_client_info(snd_seq_t *handle, snd_seq_client_info_t *info);
int snd_seq_get_any_client_info(snd_seq_t *handle, int client, snd_seq_client_info_t *info);
int snd_seq_set_client_info(snd_seq_t *handle, snd_seq_client_info_t *info);
*/
void snd_seq_set_bit(int nr, void *array);
+void snd_seq_unset_bit(int nr, void *array);
int snd_seq_change_bit(int nr, void *array);
int snd_seq_get_bit(int nr, void *array);
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = include/sound
DIST_COMMON = $(alsasoundinclude_HEADERS) $(noinst_HEADERS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
alsasoundincludedir = ${includedir}/alsa/sound
alsasoundinclude_HEADERS = asound_fm.h hdsp.h sb16_csp.h sscape_ioctl.h emu10k1.h \
type_compat.h
#ifndef __KERNEL__
#include <sys/time.h>
#include <sys/types.h>
+#include <sys/ioctl.h>
#endif
/*
sndrv_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */
sndrv_pcm_uframes_t silence_size; /* silence block size */
sndrv_pcm_uframes_t boundary; /* pointers wrap point */
- unsigned char reserved[64]; /* reserved for future */
+ unsigned char reserved[60]; /* reserved for future */
+ unsigned int period_event; /* for alsa-lib implementation */
};
struct sndrv_pcm_channel_info {
* *
****************************************************************************/
-#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 5)
+#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
struct sndrv_ctl_card_info {
int card; /* card number */
unsigned char longname[80]; /* name + info text about soundcard */
unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */
unsigned char mixername[80]; /* visual mixer identification */
- unsigned char components[80]; /* card components / fine identification, delimited with one space (AC97 etc..) */
- unsigned char reserved[48]; /* reserved for future */
+ unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */
};
enum sndrv_ctl_elem_type {
#define SND_LIB_MAJOR 1 /**< major number of library version */
#define SND_LIB_MINOR 0 /**< minor number of library version */
-#define SND_LIB_SUBMINOR 16 /**< subminor number of library version */
+#define SND_LIB_SUBMINOR 19 /**< subminor number of library version */
#define SND_LIB_EXTRAVER 1000000 /**< extra version number, used mainly for betas */
/** library version */
#define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\
(SND_LIB_MINOR<<8)|\
SND_LIB_SUBMINOR)
/** library version (string) */
-#define SND_LIB_VERSION_STR "1.0.16"
+#define SND_LIB_VERSION_STR "1.0.19"
#! /bin/sh
# libtoolT - Provide generalized library-building support services.
-# Generated automatically by (GNU alsa-lib 1.0.16)
+# Generated automatically by (GNU alsa-lib 1.0.19)
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
#
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
--- /dev/null
+dnl Macros to check the presence of generic (non-typed) symbols.
+dnl Copyright (c) 2006-2007 Diego Pettenò <flameeyes@gmail.com>
+dnl Copyright (c) 2006-2007 xine project
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2, or (at your option)
+dnl any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+dnl 02110-1301, USA.
+dnl
+dnl As a special exception, the copyright owners of the
+dnl macro gives unlimited permission to copy, distribute and modify the
+dnl configure scripts that are the output of Autoconf when processing the
+dnl Macro. You need not follow the terms of the GNU General Public
+dnl License when using or distributing such scripts, even though portions
+dnl of the text of the Macro appear in them. The GNU General Public
+dnl License (GPL) does govern all other use of the material that
+dnl constitutes the Autoconf Macro.
+dnl
+dnl This special exception to the GPL applies to versions of the
+dnl Autoconf Macro released by this project. When you make and
+dnl distribute a modified version of the Autoconf Macro, you may extend
+dnl this special exception to the GPL to apply to your modified version as
+dnl well.
+
+dnl Check if the flag is supported by compiler
+dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
+ AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_COMPILE_IFELSE([int a;],
+ [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+dnl Check if the flag is supported by compiler (cacheable)
+dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_CFLAGS], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_cflags_$1]),
+ CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
+ )
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
+dnl Check for CFLAG and appends them to CFLAGS if supported
+AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_cflags_$1]),
+ CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
+ )
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [CFLAGS="$CFLAGS $1"; $2], [$3])
+])
+
+dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
+AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [
+ for flag in $1; do
+ CC_CHECK_CFLAG_APPEND($flag, [$2], [$3])
+ done
+])
+
+dnl Check if the flag is supported by linker (cacheable)
+dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_LDFLAGS], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_ldflags_$1]),
+ [ac_save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $1"
+ AC_LINK_IFELSE([int main() { return 1; }],
+ [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_ldflags_$1])="])
+ LDFLAGS="$ac_save_LDFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
+dnl the current linker to avoid undefined references in a shared object.
+AC_DEFUN([CC_NOUNDEFINED], [
+ dnl We check $host for which systems to enable this for.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+
+ case $host in
+ dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads
+ dnl are requested, as different implementations are present; to avoid problems
+ dnl use -Wl,-z,defs only for those platform not behaving this way.
+ *-freebsd*) ;;
+ *)
+ dnl First of all check for the --no-undefined variant of GNU ld. This allows
+ dnl for a much more readable commandline, so that people can understand what
+ dnl it does without going to look for what the heck -z defs does.
+ for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do
+ CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"])
+ break
+ done
+ ;;
+ esac
+
+ AC_SUBST([LDFLAGS_NOUNDEFINED])
+])
+
+dnl Check for a -Werror flag or equivalent. -Werror is the GCC
+dnl and ICC flag that tells the compiler to treat all the warnings
+dnl as fatal. We usually need this option to make sure that some
+dnl constructs (like attributes) are not simply ignored.
+dnl
+dnl Other compilers don't support -Werror per se, but they support
+dnl an equivalent flag:
+dnl - Sun Studio compiler supports -errwarn=%all
+AC_DEFUN([CC_CHECK_WERROR], [
+ AC_CACHE_CHECK(
+ [for $CC way to treat warnings as errors],
+ [cc_cv_werror],
+ [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
+ [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
+ ])
+])
+
+AC_DEFUN([CC_CHECK_ATTRIBUTE], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
+ AS_TR_SH([cc_cv_attribute_$1]),
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ AC_COMPILE_IFELSE([$3],
+ [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
+ [AC_DEFINE(
+ AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
+ [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
+ )
+ $4],
+ [$5])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
+ CC_CHECK_ATTRIBUTE(
+ [constructor],,
+ [void __attribute__((constructor)) ctor() { int a; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
+ CC_CHECK_ATTRIBUTE(
+ [format], [format(printf, n, n)],
+ [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
+ CC_CHECK_ATTRIBUTE(
+ [format_arg], [format_arg(printf)],
+ [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
+ CC_CHECK_ATTRIBUTE(
+ [visibility_$1], [visibility("$1")],
+ [void __attribute__((visibility("$1"))) $1_function() { }],
+ [$2], [$3])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
+ CC_CHECK_ATTRIBUTE(
+ [nonnull], [nonnull()],
+ [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
+ CC_CHECK_ATTRIBUTE(
+ [unused], ,
+ [void some_function(void *foo, __attribute__((unused)) void *bar);],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
+ CC_CHECK_ATTRIBUTE(
+ [sentinel], ,
+ [void some_function(void *foo, ...) __attribute__((sentinel));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
+ CC_CHECK_ATTRIBUTE(
+ [deprecated], ,
+ [void some_function(void *foo, ...) __attribute__((deprecated));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
+ CC_CHECK_ATTRIBUTE(
+ [alias], [weak, alias],
+ [void other_function(void *foo) { }
+ void some_function(void *foo) __attribute__((weak, alias("other_function")));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
+ CC_CHECK_ATTRIBUTE(
+ [malloc], ,
+ [void * __attribute__((malloc)) my_alloc(int n);],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_PACKED], [
+ CC_CHECK_ATTRIBUTE(
+ [packed], ,
+ [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONST], [
+ CC_CHECK_ATTRIBUTE(
+ [const], ,
+ [int __attribute__((const)) twopow(int n) { return 1 << n; } ],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_FLAG_VISIBILITY], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
+ [cc_cv_flag_visibility],
+ [cc_flag_visibility_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
+ cc_cv_flag_visibility='yes',
+ cc_cv_flag_visibility='no')
+ CFLAGS="$cc_flag_visibility_save_CFLAGS"])
+
+ AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
+ [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
+ [Define this if the compiler supports the -fvisibility flag])
+ $1],
+ [$2])
+])
+
+AC_DEFUN([CC_FUNC_EXPECT], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if compiler has __builtin_expect function],
+ [cc_cv_func_expect],
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ AC_COMPILE_IFELSE(
+ [int some_function() {
+ int a = 3;
+ return (int)__builtin_expect(a, 3);
+ }],
+ [cc_cv_func_expect=yes],
+ [cc_cv_func_expect=no])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([test "x$cc_cv_func_expect" = "xyes"],
+ [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
+ [Define this if the compiler supports __builtin_expect() function])
+ $1],
+ [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
+ [cc_cv_attribute_aligned],
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ for cc_attribute_align_try in 64 32 16 8 4 2; do
+ AC_COMPILE_IFELSE([
+ int main() {
+ static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
+ return c;
+ }], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
+ done
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ if test "x$cc_cv_attribute_aligned" != "x"; then
+ AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
+ [Define the highest alignment supported])
+ fi
+])
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = modules
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
@BUILD_MIXER_TRUE@SUBDIRS = mixer
all: all-recursive
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = modules/mixer
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
SUBDIRS = simple
all: all-recursive
-pkglibdir = @ALSA_PLUGIN_DIR@/smixer
-pythonlibs = @PYTHON_LIBS@
-pythonincludes = @PYTHON_INCLUDES@
+alsaplugindir = @ALSA_PLUGIN_DIR@
+pkglibdir = $(alsaplugindir)/smixer
AM_CFLAGS = -g -O2 -W -Wall
noinst_HEADERS = sbase.h
smixer_sbase_la_SOURCES = sbase.c
-smixer_sbase_la_LDFLAGS = -module -avoid-version
+smixer_sbase_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
smixer_sbase_la_LIBADD = ../../../src/libasound.la
smixer_ac97_la_SOURCES = ac97.c sbasedl.c
-smixer_ac97_la_LDFLAGS = -module -avoid-version
+smixer_ac97_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
smixer_ac97_la_LIBADD = ../../../src/libasound.la
smixer_hda_la_SOURCES = hda.c sbasedl.c
-smixer_hda_la_LDFLAGS = -module -avoid-version
+smixer_hda_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
smixer_hda_la_LIBADD = ../../../src/libasound.la
if BUILD_PYTHON
smixer_python_la_SOURCES = python.c
-smixer_python_la_LDFLAGS = -module -avoid-version $(pythonlibs)
-smixer_python_la_CFLAGS = $(pythonincludes)
-smixer_python_la_LIBADD = ../../../src/libasound.la
+smixer_python_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
+smixer_python_la_CFLAGS = $(PYTHON_INCLUDES)
+smixer_python_la_LIBADD = ../../../src/libasound.la $(PYTHON_LIBS)
endif
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_PYTHON_TRUE@am__append_1 = smixer-python.la
subdir = modules/mixer/simple
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
smixer_hda_la_DEPENDENCIES = ../../../src/libasound.la
am_smixer_hda_la_OBJECTS = hda.lo sbasedl.lo
smixer_hda_la_OBJECTS = $(am_smixer_hda_la_OBJECTS)
+am__DEPENDENCIES_1 =
@BUILD_PYTHON_TRUE@smixer_python_la_DEPENDENCIES = \
-@BUILD_PYTHON_TRUE@ ../../../src/libasound.la
+@BUILD_PYTHON_TRUE@ ../../../src/libasound.la \
+@BUILD_PYTHON_TRUE@ $(am__DEPENDENCIES_1)
am__smixer_python_la_SOURCES_DIST = python.c
@BUILD_PYTHON_TRUE@am_smixer_python_la_OBJECTS = \
@BUILD_PYTHON_TRUE@ smixer_python_la-python.lo
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-pkglibdir = @ALSA_PLUGIN_DIR@/smixer
+pkglibdir = $(alsaplugindir)/smixer
ACLOCAL = @ACLOCAL@
ALSA_CONFIG_DIR = @ALSA_CONFIG_DIR@
ALSA_DEPLIBS = @ALSA_DEPLIBS@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
-pythonlibs = @PYTHON_LIBS@
-pythonincludes = @PYTHON_INCLUDES@
+alsaplugindir = @ALSA_PLUGIN_DIR@
AM_CFLAGS = -g -O2 -W -Wall
INCLUDES = -I$(top_srcdir)/include
pkglib_LTLIBRARIES = smixer-sbase.la smixer-ac97.la smixer-hda.la \
$(am__append_1)
noinst_HEADERS = sbase.h
smixer_sbase_la_SOURCES = sbase.c
-smixer_sbase_la_LDFLAGS = -module -avoid-version
+smixer_sbase_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
smixer_sbase_la_LIBADD = ../../../src/libasound.la
smixer_ac97_la_SOURCES = ac97.c sbasedl.c
-smixer_ac97_la_LDFLAGS = -module -avoid-version
+smixer_ac97_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
smixer_ac97_la_LIBADD = ../../../src/libasound.la
smixer_hda_la_SOURCES = hda.c sbasedl.c
-smixer_hda_la_LDFLAGS = -module -avoid-version
+smixer_hda_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
smixer_hda_la_LIBADD = ../../../src/libasound.la
@BUILD_PYTHON_TRUE@smixer_python_la_SOURCES = python.c
-@BUILD_PYTHON_TRUE@smixer_python_la_LDFLAGS = -module -avoid-version $(pythonlibs)
-@BUILD_PYTHON_TRUE@smixer_python_la_CFLAGS = $(pythonincludes)
-@BUILD_PYTHON_TRUE@smixer_python_la_LIBADD = ../../../src/libasound.la
+@BUILD_PYTHON_TRUE@smixer_python_la_LDFLAGS = -module -avoid-version $(LDFLAGS_NOUNDEFINED)
+@BUILD_PYTHON_TRUE@smixer_python_la_CFLAGS = $(PYTHON_INCLUDES)
+@BUILD_PYTHON_TRUE@smixer_python_la_LIBADD = ../../../src/libasound.la $(PYTHON_LIBS)
all: all-am
.SUFFIXES:
}
static int get_x_ops(snd_mixer_elem_t *elem, int dir,
- snd_mixer_selem_channel_id_t channel, long *value,
+ long channel, long *value,
const char *attr)
{
PyObject *obj1, *res;
return res;
}
+static int ask_vol_dB_ops(snd_mixer_elem_t *elem,
+ int dir,
+ long value,
+ long *dbValue)
+{
+ return get_x_ops(elem, dir, value, dbValue, "opsGetVolDB");
+}
+
+static int ask_dB_vol_ops(snd_mixer_elem_t *elem,
+ int dir,
+ long value,
+ long *dbValue,
+ int xdir)
+{
+ PyObject *obj1, *res;
+ struct pymelem *pymelem = melem_to_pymelem(elem);
+ int err;
+
+ obj1 = PyTuple_New(3);
+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir));
+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(value));
+ PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(xdir));
+ err = pcall(pymelem, "opsGetDBVol", obj1, &res);
+ if (err >= 0) {
+ err = !PyInt_Check(PyTuple_GetItem(res, 1));
+ if (err) {
+ err = !PyLong_Check(PyTuple_GetItem(res, 1));
+ if (err) {
+ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)");
+ PyErr_Print();
+ PyErr_Clear();
+ err = -EIO;
+ } else {
+ *dbValue = PyLong_AsLong(PyTuple_GetItem(res, 1));
+ }
+ } else {
+ *dbValue = PyInt_AsLong(PyTuple_GetItem(res, 1));
+ }
+ }
+ Py_XDECREF(res);
+ return err;
+}
+
static int get_dB_ops(snd_mixer_elem_t *elem,
int dir,
snd_mixer_selem_channel_id_t channel,
return pcall(pymelem, "opsSetVolume", obj1, NULL);
}
-
static int set_switch_ops(snd_mixer_elem_t *elem, int dir,
snd_mixer_selem_channel_id_t channel, int value)
{
.get_range = get_range_ops,
.get_dB_range = get_dB_range_ops,
.set_range = set_range_ops,
+ .ask_vol_dB = ask_vol_dB_ops,
+ .ask_dB_vol = ask_dB_vol_ops,
.get_volume = get_volume_ops,
.get_dB = get_dB_ops,
.set_volume = set_volume_ops,
SUBDIRS += compat conf
libasound_la_LIBADD += compat/libcompat.la @ALSA_DEPLIBS@
-libasound_la_LDFLAGS = -version-info $(COMPATNUM) $(VSYMS) $(SYMFUNCS)
+libasound_la_LDFLAGS = -version-info $(COMPATNUM) $(VSYMS) $(SYMFUNCS) $(LDFLAGS_NOUNDEFINED)
control/libcontrol.la:
$(MAKE) -C control libcontrol.la
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_MIXER_TRUE@am__append_1 = mixer
@BUILD_MIXER_TRUE@am__append_2 = mixer/libmixer.la
@BUILD_PCM_TRUE@am__append_3 = pcm timer
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_DIST = Versions
COMPATNUM = @LIBTOOL_VERSION_INFO@
@VERSIONED_SYMBOLS_FALSE@VSYMS =
$(am__append_4) $(am__append_6) $(am__append_8) \
$(am__append_10) $(am__append_12) compat/libcompat.la \
@ALSA_DEPLIBS@ $(am__empty)
-libasound_la_LDFLAGS = -version-info $(COMPATNUM) $(VSYMS) $(SYMFUNCS)
+libasound_la_LDFLAGS = -version-info $(COMPATNUM) $(VSYMS) $(SYMFUNCS) $(LDFLAGS_NOUNDEFINED)
INCLUDES = -I$(top_srcdir)/include
all: all-recursive
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = src/alisp
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_LTLIBRARIES = libalisp.la
EXTRA_DIST = alisp_snd.c
libalisp_la_SOURCES = alisp.c
struct alisp_object * (*func)(struct alisp_instance *instance, struct alisp_object * args);
};
-static struct intrinsic intrinsics[] = {
+static const struct intrinsic intrinsics[] = {
{ "!=", F_numneq },
{ "%", F_mod },
{ "&check-memory", F_check_memory },
int err, mode;
void *handle;
struct alisp_object *p1, *p2;
- static struct flags flags[] = {
+ static const struct flags flags[] = {
{ "nonblock", SND_CTL_NONBLOCK },
{ "async", SND_CTL_ASYNC },
{ "readonly", SND_CTL_READONLY },
* main code
*/
-static struct acall_table acall_table[] = {
+static const struct acall_table acall_table[] = {
{ "card_get_index", &FA_int_str, (void *)snd_card_get_index, NULL },
{ "card_get_longname", &FA_int_int_strp, (void *)snd_card_get_longname, NULL },
{ "card_get_name", &FA_int_int_strp, (void *)snd_card_get_name, NULL },
return &alsa_lisp_t;
}
-static struct intrinsic snd_intrinsics[] = {
+static const struct intrinsic snd_intrinsics[] = {
{ "Acall", F_acall },
{ "Aerror", F_aerror },
{ "Ahandle", F_ahandle },
}
#else
/** async signal number */
-static int snd_async_signo = SIGIO;
+static const int snd_async_signo = SIGIO;
#endif
static LIST_HEAD(snd_async_handlers);
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = src/compat
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
noinst_LTLIBRARIES = libcompat.la
EXTRA_libcompat_la_SOURCES = hsearch_r.c
@ALSA_HSEARCH_R_FALSE@libcompat_la_SOURCES = empty.c
if (!*str)
return -EINVAL;
errno = 0;
- if (sscanf(str, "%lli%n", &v, &endidx) < 1)
+ if (sscanf(str, "%Li%n", &v, &endidx) < 1)
return -EINVAL;
if (str[endidx])
return -EINVAL;
snd_output_printf(out, "%ld", n->u.integer);
break;
case SND_CONFIG_TYPE_INTEGER64:
- snd_output_printf(out, "%lld", n->u.integer64);
+ snd_output_printf(out, "%Ld", n->u.integer64);
break;
case SND_CONFIG_TYPE_REAL:
snd_output_printf(out, "%-16g", n->u.real);
{
char res[32];
int err;
- err = snprintf(res, sizeof(res), "%lli", config->u.integer64);
+ err = snprintf(res, sizeof(res), "%Li", config->u.integer64);
if (err < 0 || err == sizeof(res)) {
assert(0);
return -ENOMEM;
configs = cfgs;
if (!configs) {
configs = getenv(ALSA_CONFIG_PATH_VAR);
- if (!configs)
+ if (!configs || !*configs)
configs = ALSA_CONFIG_PATH_DEFAULT;
}
for (k = 0, c = configs; (l = strcspn(c, ": ")) > 0; ) {
EXTRA_DIST = $(cfg_files)
-alsadir = @ALSA_CONFIG_DIR@
+alsaconfigdir = @ALSA_CONFIG_DIR@
+alsadir = $(alsaconfigdir)
alsa_DATA = $(cfg_files)
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_ALISP_TRUE@am__append_1 = sndo-mixer.alisp
@BUILD_MODULES_TRUE@am__append_2 = smixer.conf
subdir = src/conf
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
SUBDIRS = cards pcm
cfg_files = alsa.conf $(am__append_1) $(am__append_2)
EXTRA_DIST = $(cfg_files)
-alsadir = @ALSA_CONFIG_DIR@
+alsaconfigdir = @ALSA_CONFIG_DIR@
+alsadir = $(alsaconfigdir)
alsa_DATA = $(cfg_files)
all: all-recursive
{
func load
files [
- "/system/etc/asound.conf"
+ "/etc/asound.conf"
"~/.asoundrc"
]
errors false
defaults.pcm.iec958.device defaults.pcm.device
defaults.pcm.modem.card defaults.pcm.card
defaults.pcm.modem.device defaults.pcm.device
+# truncate files via file or tee PCM
+defaults.pcm.file_format "raw"
+defaults.pcm.file_truncate true
defaults.rawmidi.card 0
defaults.rawmidi.device 0
defaults.rawmidi.subdevice -1
pcm.surround71 cards.pcm.surround71
pcm.iec958 cards.pcm.iec958
pcm.spdif iec958
+pcm.hdmi cards.pcm.hdmi
pcm.dmix cards.pcm.dmix
pcm.dsnoop cards.pcm.dsnoop
pcm.modem cards.pcm.modem
}
@args.FORMAT {
type string
- default raw
+ default {
+ @func refer
+ name defaults.pcm.file_format
+ }
}
type file
slave.pcm $SLAVE
file $FILE
format $FORMAT
+ truncate {
+ @func refer
+ name defaults.pcm.file_truncate
+ }
}
pcm.file {
}
@args.FORMAT {
type string
- default raw
+ default {
+ @func refer
+ name defaults.pcm.file_format
+ }
}
type file
slave.pcm null
file $FILE
format $FORMAT
+ truncate {
+ @func refer
+ name defaults.pcm.file_truncate
+ }
}
pcm.null {
}
type asym
playback.pcm {
+ type linear
+ slave.pcm {
type hooks
slave.pcm {
type hw
}
]
}
+ }
+ slave.format S32_LE
}
capture.pcm {
+ type linear
+ slave.pcm {
type hooks
slave.pcm {
type hw
}
]
}
+ }
+ slave.format S32_LE
}
}
}
type asym
playback.pcm {
+ type linear
+ slave.pcm {
type hooks
slave.pcm {
type hw
}
]
}
+ }
+ slave.format S32_LE
}
capture.pcm {
+ type linear
+ slave.pcm {
type hooks
slave.pcm {
type hw
}
]
}
+ }
+ slave.format S32_LE
}
}
card $CARD
}
-# default with dmix & dsnoop
+# default with dmix+softvol & dsnoop
CMI8788.pcm.default {
@args [ CARD ]
@args.CARD {
playback.pcm {
type plug
slave.pcm {
- @func concat
- strings [ "dmix:" $CARD ",FORMAT=S32_LE" ]
+ type softvol
+ slave.pcm {
+ @func concat
+ strings [ "dmix:" $CARD ",FORMAT=S32_LE" ]
+ }
+ control {
+ name "PCM Playback Volume"
+ card $CARD
+ }
}
}
capture.pcm {
hint.device 1
}
+<confdir:pcm/hdmi.conf>
+
+HDA-Intel.pcm.hdmi.0 {
+ @args [ CARD AES0 AES1 AES2 AES3 ]
+ @args.CARD {
+ type string
+ }
+ @args.AES0 {
+ type integer
+ }
+ @args.AES1 {
+ type integer
+ }
+ @args.AES2 {
+ type integer
+ }
+ @args.AES3 {
+ type integer
+ }
+ type hooks
+ slave.pcm {
+ type hw
+ card $CARD
+ device 3
+ }
+ hooks.0 {
+ type ctl_elems
+ hook_args [
+ {
+ name "IEC958 Playback Default"
+ lock true
+ preserve true
+ value [ $AES0 $AES1 $AES2 $AES3 ]
+ }
+ {
+ name "IEC958 Playback Switch"
+ lock true
+ preserve true
+ value true
+ }
+ ]
+ }
+ hint.device 3
+}
+
<confdir:pcm/modem.conf>
HDA-Intel.pcm.modem.0 {
}
type asym
playback.pcm {
+ type linear
+ slave.pcm {
type hooks
slave.pcm {
type hw
}
]
}
+ }
+ slave.format S32_LE
}
capture.pcm {
+ type linear
+ slave.pcm {
type hooks
slave.pcm {
type hw
}
]
}
+ }
+ slave.format S32_LE
}
}
-alsadir = @ALSA_CONFIG_DIR@/cards
+alsaconfigdir = @ALSA_CONFIG_DIR@
+alsadir = $(alsaconfigdir)/cards
cfg_files = aliases.conf \
AACI.conf \
ATIIXP.conf \
alsa_DATA = $(cfg_files)
if BUILD_ALISP
-SI7018dir = @ALSA_CONFIG_DIR@/cards/SI7018
+SI7018dir = $(alsaconfigdir)/cards/SI7018
SI7018_files = \
SI7018/sndoc-mixer.alisp \
SI7018/sndop-mixer.alisp
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_ALISP_TRUE@am__append_1 = aliases.alisp
subdir = src/conf/cards
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
-alsadir = @ALSA_CONFIG_DIR@/cards
+alsaconfigdir = @ALSA_CONFIG_DIR@
+alsadir = $(alsaconfigdir)/cards
cfg_files = aliases.conf AACI.conf ATIIXP.conf ATIIXP-SPDMA.conf \
ATIIXP-MODEM.conf AU8810.conf AU8820.conf AU8830.conf \
Audigy.conf Audigy2.conf Aureon51.conf Aureon71.conf \
VIA8233A.conf VIA8237.conf VX222.conf VXPocket.conf \
VXPocket440.conf $(am__append_1)
alsa_DATA = $(cfg_files)
-@BUILD_ALISP_TRUE@SI7018dir = @ALSA_CONFIG_DIR@/cards/SI7018
+@BUILD_ALISP_TRUE@SI7018dir = $(alsaconfigdir)/cards/SI7018
@BUILD_ALISP_FALSE@SI7018_files =
@BUILD_ALISP_TRUE@SI7018_files = \
@BUILD_ALISP_TRUE@ SI7018/sndoc-mixer.alisp \
}
}
+<confdir:pcm/surround71.conf>
+
+NFORCE.pcm.surround71.0 {
+ @args [ CARD ]
+ @args.CARD {
+ type string
+ }
+ type softvol
+ slave.pcm {
+ type route
+ ttable.0.0 1
+ ttable.1.1 1
+ ttable.2.4 1
+ ttable.3.5 1
+ ttable.4.2 1
+ ttable.5.3 1
+ ttable.6.6 1
+ ttable.7.7 1
+ slave.pcm {
+ type hooks
+ slave.pcm {
+ type hw
+ card $CARD
+ device 0
+ }
+ hooks.0 {
+ type ctl_elems
+ hook_args [
+ {
+ name "Channel Mode"
+ preserve true
+ value "8ch"
+ lock true
+ optional true
+ }
+ # for old drivers
+ {
+ name "Line-In As Surround"
+ preserve true
+ value true
+ optional true
+ }
+ {
+ name "Mic As Center/LFE"
+ preserve true
+ value true
+ optional true
+ }
+ {
+ name "Surround Down Mix"
+ preserve true
+ value off
+ lock true
+ optional true
+ }
+ {
+ name "Center/LFE Down Mix"
+ preserve true
+ value off
+ lock true
+ optional true
+ }
+ ]
+ }
+ }
+ slave.channels 8
+ }
+ control {
+ name "PCM Playback Volume"
+ card $CARD
+ }
+}
+
<confdir:pcm/iec958.conf>
NFORCE.pcm.iec958.0 {
type plug
slave.pcm {
type softvol
- slave.pcm {
- @func concat
- strings [ "dmix:" $CARD ]
- }
control {
name "Master Playback Volume"
card $CARD
}
min_dB -10.0
max_dB 20.0
+ slave.pcm {
+ @func concat
+ strings [ "dmix:" $CARD ]
+ }
}
}
capture.pcm {
}
}
}
+
+<confdir:pcm/iec958.conf>
+
+PS3.pcm.iec958.0 {
+ @args [ CARD AES0 AES1 AES2 AES3 ]
+ @args.CARD {
+ type string
+ }
+ @args.AES0 {
+ type integer
+ }
+ @args.AES1 {
+ type integer
+ }
+ @args.AES2 {
+ type integer
+ }
+ @args.AES3 {
+ type integer
+ }
+ type hooks
+ slave.pcm {
+ type hw
+ card $CARD
+ }
+ hooks.0 {
+ type ctl_elems
+ hook_args [
+ {
+ interface PCM
+ name "IEC958 Playback Default"
+ lock true
+ preserve true
+ optional true
+ value [ $AES0 $AES1 $AES2 $AES3 ]
+ }
+ ]
+ }
+}
# Define aliases for various drivers
#
+YMF724 cards.YMF744
+YMF724F cards.YMF744
+YMF740 cards.YMF744
+YMF740C cards.YMF744
+YMF754 cards.YMF744
+CMIPCI cards.CMI8338
+CMI8738 cards.CMI8338
+CMI8738-SWIEC cards.CMI8338-SWIEC
+CMI8738-MC4 cards.CMI8738-MC6
+'E-mu APS' cards.EMU10K1
+'GUS MAX' cards.GUS
+'GUS ACE' cards.GUS
+'GUS Extreme' cards.GUS
+'AMD InterWave' cards.GUS
+'Dynasonic 3-D' cards.GUS
+'InterWave STB' cards.GUS
+au8810 cards.AU8810
+au8820 cards.AU8820
+au8830 cards.AU8830
+Prodigy71 cards.Aureon71
+Prodigy71LT cards.Aureon71
+Prodigy71HIFI cards.Aureon71
+Aureon71Univ cards.Aureon71
+VIA82XX-MODEM cards.ICH-MODEM
+'MPU-401 UART' cards.MPU-401
+'VX222/Old' cards.VX222
+'VX222/v2' cards.VX222
+'VX222/Mic' cards.VX222
+'CMI8330/C3D' cards.CMI8330
+'SB AWE' cards.SBAWE
+'SB Pro' cards.SBPro
+'PMac Burgundy' cards.PMac
+'PMac DACA' cards.PMac
+'PMac Tumbler' cards.PMac
+'PMac Snapper' cards.PMac
+'PMac Screamer' cards.PMac
+'PMac AWACS' cards.PMac
+'PMac Toonie' cards.PMacToonie
+AppleOnbdAudio cards.PMacToonie
+'USB US-X2Y' cards.US-X2Y
+'Serial MIDI' cards.SerialMIDI
+'Prodif Plus' cards.ProdifPlus
+ESM1 cards.ES1968
+ES1978 cards.ES1968
+Allegro cards.Maestro3
+Canyon3D-2 cards.Maestro3
+Azalia cards.HDA-Intel
+aaci-pl041 cards.AACI
+AV200 cards.CMI8788
+
<confdir:pcm/default.conf>
-# <confdir:pcm/dmix.conf>
-# <confdir:pcm/dsnoop.conf>
+<confdir:pcm/dmix.conf>
+<confdir:pcm/dsnoop.conf>
cfg_files = default.conf front.conf rear.conf center_lfe.conf side.conf\
surround40.conf surround41.conf \
surround50.conf surround51.conf \
- surround71.conf iec958.conf modem.conf \
+ surround71.conf iec958.conf hdmi.conf modem.conf \
dmix.conf dsnoop.conf \
dpl.conf
EXTRA_DIST = $(cfg_files)
-alsadir = @ALSA_CONFIG_DIR@/pcm
+alsaconfigdir = @ALSA_CONFIG_DIR@
+alsadir = $(alsaconfigdir)/pcm
alsa_DATA = $(cfg_files)
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = src/conf/pcm
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
cfg_files = default.conf front.conf rear.conf center_lfe.conf side.conf\
surround40.conf surround41.conf \
surround50.conf surround51.conf \
- surround71.conf iec958.conf modem.conf \
+ surround71.conf iec958.conf hdmi.conf modem.conf \
dmix.conf dsnoop.conf \
dpl.conf
EXTRA_DIST = $(cfg_files)
-alsadir = @ALSA_CONFIG_DIR@/pcm
+alsaconfigdir = @ALSA_CONFIG_DIR@
+alsadir = $(alsaconfigdir)/pcm
alsa_DATA = $(cfg_files)
all: all-am
--- /dev/null
+#
+# Hardware output from HDMI
+#
+
+pcm.!hdmi {
+ @args [ CARD DEV AES0 AES1 AES2 AES3 ]
+ @args.CARD {
+ type string
+ default {
+ @func getenv
+ vars [
+ ALSA_IEC958_CARD
+ ALSA_PCM_CARD
+ ALSA_CARD
+ ]
+ default {
+ @func refer
+ name defaults.pcm.iec958.card
+ }
+ }
+ }
+ @args.DEV {
+ type integer
+ default {
+ @func igetenv
+ vars [
+ ALSA_IEC958_DEVICE
+ ]
+ default {
+ @func refer
+ name defaults.pcm.iec958.device
+ }
+ }
+ }
+ @args.AES0 {
+ type integer
+ # consumer, not-copyright, emphasis-none, mode=0
+ default 0x04
+ }
+ @args.AES1 {
+ type integer
+ # original, PCM coder
+ default 0x82
+ }
+ @args.AES2 {
+ type integer
+ # source and channel
+ default 0x00
+ }
+ @args.AES3 {
+ type integer
+ # fs=48000Hz, clock accuracy=1000ppm
+ default 0x02
+ }
+ type empty
+ slave.pcm {
+ @func refer
+ name {
+ @func concat
+ strings [
+ "cards."
+ {
+ @func card_driver
+ card $CARD
+ }
+ ".pcm.hdmi." $DEV ":"
+ "CARD=" $CARD ","
+ "AES0=" $AES0 ","
+ "AES1=" $AES1 ","
+ "AES2=" $AES2 ","
+ "AES3=" $AES3
+ ]
+ }
+ }
+ hint {
+ show {
+ @func refer
+ name defaults.namehint.basic
+ }
+ description "HDMI Audio Output"
+ device $DEV
+ }
+}
int snd_config_get_bool_ascii(const char *ascii)
{
unsigned int k;
- static struct {
- const char *str;
+ static const struct {
+ const char str[8];
int val;
} b[] = {
{ "0", 0 },
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_CTL_PLUGIN_SHM_TRUE@am__append_1 = control_shm.c
@BUILD_CTL_PLUGIN_EXT_TRUE@am__append_2 = control_ext.c
subdir = src/control
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_LTLIBRARIES = libcontrol.la
libcontrol_la_SOURCES = cards.c tlv.c namehint.c hcontrol.c control.c \
control_hw.c setup.c control_symbols.c $(am__append_1) \
return handler->u.ctl;
}
-static const char *build_in_ctls[] = {
+static const char *const build_in_ctls[] = {
"hw", "shm", NULL
};
sprintf(buf, "_snd_ctl_%s_open", str);
}
if (!lib) {
- const char **build_in = build_in_ctls;
+ const char *const *build_in = build_in_ctls;
while (*build_in) {
if (!strcmp(*build_in, str))
break;
#define IFACE1(v, n) [SND_CTL_ELEM_IFACE_##v] = #n
#define EVENT(v) [SND_CTL_EVENT_##v] = #v
-static const char *snd_ctl_elem_type_names[] = {
+static const char *const snd_ctl_elem_type_names[] = {
TYPE(NONE),
TYPE(BOOLEAN),
TYPE(INTEGER),
TYPE(INTEGER64),
};
-static const char *snd_ctl_elem_iface_names[] = {
+static const char *const snd_ctl_elem_iface_names[] = {
IFACE(CARD),
IFACE(HWDEP),
IFACE(MIXER),
IFACE(SEQUENCER),
};
-static const char *snd_ctl_event_type_names[] = {
+static const char *const snd_ctl_event_type_names[] = {
EVENT(ELEM),
};
#endif
case SND_CTL_ELEM_TYPE_INTEGER64:
if (! ext->callback->read_integer64)
goto err;
- ret = ext->callback->read_integer64(ext, key, control->value.integer64.value);
+ ret = ext->callback->read_integer64(ext, key,
+ (int64_t*)control->value.integer64.value);
break;
case SND_CTL_ELEM_TYPE_ENUMERATED:
if (! ext->callback->read_enumerated)
return -EINVAL;
}
-static snd_ctl_ops_t snd_ctl_ext_ops = {
+static const snd_ctl_ops_t snd_ctl_ext_ops = {
.close = snd_ctl_ext_close,
.nonblock = snd_ctl_ext_nonblock,
.async = snd_ctl_ext_async,
SYSERR("SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS failed");
return -errno;
}
- return subscribe;
+ return 0;
}
static int snd_ctl_hw_card_info(snd_ctl_t *handle, snd_ctl_card_info_t *info)
ssize_t res = read(hw->fd, event, sizeof(*event));
if (res <= 0)
return -errno;
- assert(res == sizeof(*event));
+ if (CHECK_SANITY(res != sizeof(*event))) {
+ SNDMSG("snd_ctl_hw_read: read size error (req:%d, got:%d)\n",
+ sizeof(*event), res);
+ return -EINVAL;
+ }
return 1;
}
-snd_ctl_ops_t snd_ctl_hw_ops = {
+static const snd_ctl_ops_t snd_ctl_hw_ops = {
.close = snd_ctl_hw_close,
.nonblock = snd_ctl_hw_nonblock,
.async = snd_ctl_hw_async,
*handle = NULL;
- assert(card >= 0 && card < 32);
+ if (CHECK_SANITY(card < 0 || card >= 32)) {
+ SNDMSG("Invalid card index %d", card);
+ return -EINVAL;
+ }
sprintf(filename, SNDRV_FILE_CONTROL, card);
if (mode & SND_CTL_READONLY)
fmode = O_RDONLY;
void *dl_handle;
char *name;
snd_ctl_type_t type;
- snd_ctl_ops_t *ops;
+ const snd_ctl_ops_t *ops;
void *private_data;
int nonblock;
int poll_fd;
return err;
}
-snd_ctl_ops_t snd_ctl_shm_ops = {
+static const snd_ctl_ops_t snd_ctl_shm_ops = {
.close = snd_ctl_shm_close,
.nonblock = snd_ctl_shm_nonblock,
.async = snd_ctl_shm_async,
+++ /dev/null
-&_snd_module_control_ext,
static int get_compare_weight(const snd_ctl_elem_id_t *id)
{
- static const char *names[] = {
+ static const char *const names[] = {
"Master",
"Hardware Master",
"Headphone",
"IEC958",
NULL
};
- static const char *names1[] = {
+ static const char *const names1[] = {
"Switch",
"Volume",
"Playback",
"-",
NULL
};
- static const char *names2[] = {
+ static const char *const names2[] = {
"Switch",
"Volume",
"Bypass",
{
}
-static int get_dev_name1(struct hint_list *list, char **res)
+static int get_dev_name1(struct hint_list *list, char **res, int device,
+ int stream)
{
*res = NULL;
- if (list->device < 0)
+ if (device < 0)
return 0;
switch (list->iface) {
#ifdef BUILD_HWDEP
{
snd_hwdep_info_t *info;
snd_hwdep_info_alloca(&info);
- snd_hwdep_info_set_device(info, list->device);
+ snd_hwdep_info_set_device(info, device);
if (snd_ctl_hwdep_info(list->ctl, info) < 0)
return 0;
*res = strdup(snd_hwdep_info_get_name(info));
{
snd_pcm_info_t *info;
snd_pcm_info_alloca(&info);
- snd_pcm_info_set_device(info, list->device);
- snd_pcm_info_set_stream(info, list->stream ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK);
+ snd_pcm_info_set_device(info, device);
+ snd_pcm_info_set_stream(info, stream ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK);
if (snd_ctl_pcm_info(list->ctl, info) < 0)
return 0;
switch (snd_pcm_info_get_class(info)) {
{
snd_rawmidi_info_t *info;
snd_rawmidi_info_alloca(&info);
- snd_rawmidi_info_set_device(info, list->device);
- snd_rawmidi_info_set_stream(info, list->stream ? SND_RAWMIDI_STREAM_INPUT : SND_RAWMIDI_STREAM_OUTPUT);
+ snd_rawmidi_info_set_device(info, device);
+ snd_rawmidi_info_set_stream(info, stream ? SND_RAWMIDI_STREAM_INPUT : SND_RAWMIDI_STREAM_OUTPUT);
if (snd_ctl_rawmidi_info(list->ctl, info) < 0)
return 0;
*res = strdup(snd_rawmidi_info_get_name(info));
static char *get_dev_name(struct hint_list *list)
{
char *str1, *str2, *res;
+ int device;
- list->device = list->device_input >= 0 ? list->device_input : list->device;
- list->stream = 1;
- if (get_dev_name1(list, &str1) < 0)
+ device = list->device_input >= 0 ? list->device_input : list->device;
+ if (get_dev_name1(list, &str1, device, 1) < 0)
return NULL;
- list->device = list->device_output >= 0 ? list->device_input : list->device;
- list->stream = 0;
- if (get_dev_name1(list, &str2) < 0) {
+ device = list->device_output >= 0 ? list->device_output : list->device;
+ if (get_dev_name1(list, &str2, device, 0) < 0) {
if (str1)
free(str1);
return NULL;
free(str1);
return res;
}
- } else {
- return strdup(list->cardname);
}
- return NULL;
+ /* if the specified device doesn't exist, skip this entry */
+ if (list->device >= 0 || list->device_input >= 0 || list->device_output >= 0)
+ return NULL;
+ return strdup(list->cardname);
}
#ifndef DOC_HIDDEN
err = -EINVAL;
goto __cleanup;
}
- list->device_input = -1;
- list->device_output = -1;
+ list->device_input = dev;
+ list->device_output = dev;
}
if (snd_config_search(cfg, "device_input", &n) >= 0) {
if (snd_config_get_integer(n, &list->device_input) < 0) {
typedef int (*next_devices_t)(snd_ctl_t *, int *);
-static next_devices_t next_devices[] = {
+static const next_devices_t next_devices[] = {
IFACE(CARD, NULL),
IFACE(HWDEP, snd_ctl_hwdep_next_device),
IFACE(MIXER, NULL),
#else
#ifdef HAVE_LIBDL
if (name == NULL) {
+#ifdef ANDROID
+ return RTLD_DEFAULT;
+#else
Dl_info dlinfo;
if (dladdr(snd_dlopen, &dlinfo) > 0)
name = dlinfo.dli_fname;
+#endif
}
#endif
#endif
return 0;
#endif
#ifdef HAVE_LIBDL
+#ifdef ANDROID
+ if (handle == RTLD_DEFAULT)
+ return 0;
+#endif
return dlclose(handle);
#else
return 0;
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = src/hwdep
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_LTLIBRARIES = libhwdep.la
libhwdep_la_SOURCES = hwdep.c hwdep_hw.c hwdep_symbols.c
noinst_HEADERS = hwdep_local.h
return result;
}
-static snd_hwdep_ops_t snd_hwdep_hw_ops = {
+static const snd_hwdep_ops_t snd_hwdep_hw_ops = {
.close = snd_hwdep_hw_close,
.nonblock = snd_hwdep_hw_nonblock,
.info = snd_hwdep_hw_info,
snd_hwdep_type_t type;
int mode;
int poll_fd;
- snd_hwdep_ops_t *ops;
+ const snd_hwdep_ops_t *ops;
void *private_data;
};
struct _snd_input {
snd_input_type_t type;
- snd_input_ops_t *ops;
+ const snd_input_ops_t *ops;
void *private_data;
};
#endif
return ungetc(c, stdio->fp);
}
-static snd_input_ops_t snd_input_stdio_ops = {
+static const snd_input_ops_t snd_input_stdio_ops = {
.close = snd_input_stdio_close,
.scan = snd_input_stdio_scan,
.gets = snd_input_stdio_gets,
return c;
}
-static snd_input_ops_t snd_input_buffer_ops = {
+static const snd_input_ops_t snd_input_buffer_ops = {
.close = snd_input_buffer_close,
.scan = snd_input_buffer_scan,
.gets = snd_input_buffer_gets,
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = src/mixer
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_LTLIBRARIES = libmixer.la
libmixer_la_SOURCES = bag.c mixer.c simple.c simple_none.c simple_abst.c
noinst_HEADERS = mixer_local.h mixer_simple.h
*/
const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel)
{
- static const char *array[SND_MIXER_SCHN_LAST + 1] = {
+ static const char *const array[SND_MIXER_SCHN_LAST + 1] = {
[SND_MIXER_SCHN_FRONT_LEFT] = "Front Left",
[SND_MIXER_SCHN_FRONT_RIGHT] = "Front Right",
[SND_MIXER_SCHN_REAR_LEFT] = "Rear Left",
}
/**
+ * \brief Return corresponding dB value to an integer playback volume for a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param value value to be converted to dB range
+ * \param dBvalue pointer to returned dB value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
+{
+ CHECK_BASIC(elem);
+ CHECK_DIR(elem, SM_CAP_PVOLUME);
+ return sm_selem_ops(elem)->ask_vol_dB(elem, SM_PLAY, value, dBvalue);
+}
+
+/**
+ * \brief Return corresponding integer playback volume for given dB value for a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param value value to be converted to dB range
+ * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
+ * \param dBvalue pointer to returned dB value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
+{
+ CHECK_BASIC(elem);
+ CHECK_DIR(elem, SM_CAP_PVOLUME);
+ return sm_selem_ops(elem)->ask_dB_vol(elem, SM_PLAY, dBvalue, value, dir);
+}
+
+/**
* \brief Return value of playback volume control of a mixer simple element
* \param elem Mixer simple element handle
* \param channel mixer simple element channel identifier
}
/**
+ * \brief Return corresponding dB value to an integer capture volume for a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param value value to be converted to dB range
+ * \param dBvalue pointer to returned dB value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
+{
+ CHECK_BASIC(elem);
+ CHECK_DIR(elem, SM_CAP_CVOLUME);
+ return sm_selem_ops(elem)->ask_vol_dB(elem, SM_CAPT, value, dBvalue);
+}
+
+/**
+ * \brief Return corresponding integer capture volume for given dB value for a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param dBvalue dB value to be converted to integer range
+ * \param value pointer to returned integer value
+ * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
+{
+ CHECK_BASIC(elem);
+ CHECK_DIR(elem, SM_CAP_CVOLUME);
+ return sm_selem_ops(elem)->ask_dB_vol(elem, SM_CAPT, dBvalue, value, dir);
+}
+
+/**
* \brief Return value of capture volume control of a mixer simple element
* \param elem Mixer simple element handle
* \param channel mixer simple element channel identifier
} str[2];
} selem_none_t;
-static struct mixer_name_table {
+static const struct mixer_name_table {
const char *longname;
const char *shortname;
} name_table[] = {
static const char *get_short_name(const char *lname)
{
- struct mixer_name_table *p;
+ const struct mixer_name_table *p;
for (p = name_table; p->longname; p++) {
if (!strcmp(lname, p->longname))
return p->shortname;
static int get_compare_weight(const char *name, unsigned int idx)
{
- static const char *names[] = {
+ static const char *const names[] = {
"Master",
"Headphone",
"Tone",
"Mix",
NULL
};
- static const char *names1[] = {
+ static const char *const names1[] = {
"-",
NULL,
};
- static const char *names2[] = {
+ static const char *const names2[] = {
"Mono",
"Digital",
"Switch",
if (caps & (SM_CAP_GSWITCH|SM_CAP_CSWITCH))
caps |= SM_CAP_CSWITCH_JOIN;
if (caps & (SM_CAP_GVOLUME|SM_CAP_CVOLUME))
- caps |= SM_CAP_PVOLUME_JOIN;
+ caps |= SM_CAP_CVOLUME_JOIN;
if (pchannels > 1 || cchannels > 1) {
if (simple->ctls[CTL_SINGLE].elem &&
simple->ctls[CTL_SINGLE].values > 1) {
if (caps & SM_CAP_GSWITCH)
- caps &= ~SM_CAP_PSWITCH_JOIN;
+ caps &= ~(SM_CAP_PSWITCH_JOIN|SM_CAP_CSWITCH_JOIN);
else
- caps &= ~SM_CAP_PVOLUME_JOIN;
+ caps &= ~(SM_CAP_PVOLUME_JOIN|SM_CAP_CVOLUME_JOIN);
}
if (simple->ctls[CTL_GLOBAL_ROUTE].elem ||
(simple->ctls[CTL_GLOBAL_SWITCH].elem &&
}
#ifndef DOC_HIDDEN
-static struct suf {
+static const struct suf {
const char *suffix;
selem_ctl_type_t type;
} suffixes[] = {
/* Return base length or 0 on failure */
static int base_len(const char *name, selem_ctl_type_t *type)
{
- struct suf *p;
+ const struct suf *p;
size_t nlen = strlen(name);
p = suffixes;
while (p->suffix) {
static int _snd_mixer_selem_set_volume(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value)
{
selem_none_t *s = snd_mixer_elem_get_private(elem);
+ if (s->selem.caps & SM_CAP_GVOLUME)
+ dir = SM_PLAY;
if ((unsigned int) channel >= s->str[dir].channels)
return 0;
if (value < s->str[dir].min || value > s->str[dir].max)
snd_mixer_selem_channel_id_t channel, long *value)
{
selem_none_t *s = snd_mixer_elem_get_private(elem);
+ if (s->selem.caps & SM_CAP_GVOLUME)
+ dir = SM_PLAY;
if ((unsigned int) channel >= s->str[dir].channels)
return -EINVAL;
*value = s->str[dir].vol[channel];
selem_none_t *s = snd_mixer_elem_get_private(elem);
selem_ctl_t *c;
+ if (s->selem.caps & SM_CAP_GVOLUME)
+ dir = SM_PLAY;
c = get_selem_ctl(s, dir);
if (! c)
return -EINVAL;
db_gain, value, xdir);
}
+static int ask_vol_dB_ops(snd_mixer_elem_t *elem,
+ int dir,
+ long value,
+ long *dBvalue)
+{
+ selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_ctl_t *c;
+
+ c = get_selem_ctl(s, dir);
+ if (! c)
+ return -EINVAL;
+ int res = convert_to_dB(c->elem, &s->str[dir], value, dBvalue);
+ return res;
+}
+
static int get_dB_ops(snd_mixer_elem_t *elem,
int dir,
snd_mixer_selem_channel_id_t channel,
int err;
long volume, db_gain;
+ if (s->selem.caps & SM_CAP_GVOLUME)
+ dir = SM_PLAY;
c = get_selem_ctl(s, dir);
if (! c)
return -EINVAL;
snd_mixer_selem_channel_id_t channel, int *value)
{
selem_none_t *s = snd_mixer_elem_get_private(elem);
+ if (s->selem.caps & SM_CAP_GSWITCH)
+ dir = SM_PLAY;
if ((unsigned int) channel >= s->str[dir].channels)
return -EINVAL;
*value = !!(s->str[dir].sw & (1 << channel));
return 0;
}
+static int ask_dB_vol_ops(snd_mixer_elem_t *elem, int dir,
+ long dbValue, long *value, int xdir)
+{
+ selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_ctl_t *c;
+
+ if (s->selem.caps & SM_CAP_GVOLUME)
+ dir = SM_PLAY;
+ c = get_selem_ctl(s, dir);
+ if (! c)
+ return -EINVAL;
+ return convert_from_dB(c->elem, &s->str[dir], dbValue, value, xdir);
+}
+
static int set_dB_ops(snd_mixer_elem_t *elem, int dir,
snd_mixer_selem_channel_id_t channel,
long db_gain, int xdir)
long value;
int err;
+ if (s->selem.caps & SM_CAP_GVOLUME)
+ dir = SM_PLAY;
c = get_selem_ctl(s, dir);
if (! c)
return -EINVAL;
{
int changed;
selem_none_t *s = snd_mixer_elem_get_private(elem);
+ if (s->selem.caps & SM_CAP_GSWITCH)
+ dir = SM_PLAY;
if (dir == SM_PLAY) {
if (! (s->selem.caps & (SM_CAP_GSWITCH|SM_CAP_PSWITCH)))
return -EINVAL;
.get_range = get_range_ops,
.get_dB_range = get_dB_range_ops,
.set_range = set_range_ops,
+ .ask_vol_dB = ask_vol_dB_ops,
+ .ask_dB_vol = ask_dB_vol_ops,
.get_volume = get_volume_ops,
.get_dB = get_dB_ops,
.set_volume = set_volume_ops,
struct _snd_output {
snd_output_type_t type;
- snd_output_ops_t *ops;
+ const snd_output_ops_t *ops;
void *private_data;
};
#endif
return fflush(stdio->fp);
}
-static snd_output_ops_t snd_output_stdio_ops = {
+static const snd_output_ops_t snd_output_stdio_ops = {
.close = snd_output_stdio_close,
.print = snd_output_stdio_print,
.puts = snd_output_stdio_puts,
return 0;
}
-static snd_output_ops_t snd_output_buffer_ops = {
+static const snd_output_ops_t snd_output_buffer_ops = {
.close = snd_output_buffer_close,
.print = snd_output_buffer_print,
.puts = snd_output_buffer_puts,
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_PCM_PLUGIN_TRUE@am__append_1 = pcm_generic.c pcm_plugin.c
@BUILD_PCM_PLUGIN_COPY_TRUE@am__append_2 = pcm_copy.c
@BUILD_PCM_PLUGIN_LINEAR_TRUE@am__append_3 = pcm_linear.c
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
SUBDIRS =
DIST_SUBDIRS = scopes
EXTRA_LTLIBRARIES = libpcm.la
\subsection pcm_status_fast Obtaining stream state fast and update r/w pointer
+<p>
The function #snd_pcm_avail_update() updates the current
available count of samples for writing (playback) or filled samples for
reading (capture). This call is mandatory for updating actual r/w pointer.
because it does not require the user <-> kernel context switch, but the value
is less accurate, because ring buffer pointers are updated in kernel drivers
only when an interrupt occurs. If you want to get accurate stream state,
-use functions #snd_pcm_hwsync() or #snd_pcm_delay().
-Note that both of these functions do not update the current r/w pointer
-for applications, so the function #snd_pcm_avail_update() must
-be called afterwards before any read/write begin+commit operations.
+use functions #snd_pcm_avail(), #snd_pcm_delay() or #snd_pcm_avail_delay().
+</p>
<p>
-The function #snd_pcm_hwsync() reads the current hardware pointer
-in the ring buffer from hardware. Note that this function does not update the current
-r/w pointer for applications, so the function #snd_pcm_avail_update()
-must be called afterwards before any read/write/begin+commit operations.
+The function #snd_pcm_avail() reads the current hardware pointer
+in the ring buffer from hardware and calls #snd_pcm_avail_update() then.
+</p>
<p>
The function #snd_pcm_delay() returns the delay in samples.
For playback, it means count of samples in the ring buffer before
Note that this function does not update the current r/w pointer for applications,
so the function #snd_pcm_avail_update() must be called afterwards
before any read/write begin+commit operations.
+</p>
+<p>
+The function #snd_pcm_avail_delay() combines #snd_pcm_avail() and
+#snd_pcm_delay() and returns both values in sync.
+</p>
\section pcm_action Managing the stream state
pcm->tstamp_mode = params->tstamp_mode;
pcm->period_step = params->period_step;
pcm->avail_min = params->avail_min;
+ pcm->period_event = params->period_event;
pcm->start_threshold = params->start_threshold;
pcm->stop_threshold = params->stop_threshold;
pcm->silence_threshold = params->silence_threshold;
}
/**
- * \brief Synchronize stream position with hardware
+ * \brief (DEPRECATED) Synchronize stream position with hardware
* \param pcm PCM handle
* \return 0 on success otherwise a negative error code
*
}
return pcm->fast_ops->hwsync(pcm->fast_op_arg);
}
+#ifndef DOC_HIDDEN
+link_warning(snd_pcm_hwsync, "Warning: snd_pcm_hwsync() is deprecated, consider to use snd_pcm_avail()");
+#endif
/**
* \brief Obtain delay for a running PCM handle
* \param delayp Returned delay in frames
* \return 0 on success otherwise a negative error code
*
- * Delay is distance between current application frame position and
- * sound frame position.
- * It's positive and less than buffer size in normal situation,
- * negative on playback underrun and greater than buffer size on
- * capture overrun.
+ * For playback the delay is defined as the time that a frame that is written
+ * to the PCM stream shortly after this call will take to be actually
+ * audible. It is as such the overall latency from the write call to the final
+ * DAC.
+ *
+ * For capture the delay is defined as the time that a frame that was
+ * digitized by the audio device takes until it can be read from the PCM
+ * stream shortly after this call returns. It is as such the overall latency
+ * from the initial ADC to the read call.
+ *
+ * Please note that hence in case of a playback underrun this value will not
+ * necessarily got down to 0.
+ *
+ * If the application is interested in the fill level of the playback buffer
+ * of the device, it should use #snd_pcm_avail*() functions. The
+ * value returned by that call is not directly related to the delay, since the
+ * latter might include some additional, fixed latencies the former does not.
*
* Note this function does not update the actual r/w pointer
* for applications. The function #snd_pcm_avail_update()
}
/**
+ * \brief Get safe count of frames which can be rewinded
+ * \param pcm PCM handle
+ * \return a positive number of frames or negative error code
+ *
+ * Note: The snd_pcm_rewind() can accept bigger value than returned
+ * by this function. But it is not guaranteed that output stream
+ * will be consistent with bigger value.
+ */
+snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm)
+{
+ assert(pcm);
+ if (CHECK_SANITY(! pcm->setup)) {
+ SNDMSG("PCM not set up");
+ return -EIO;
+ }
+ return pcm->fast_ops->rewindable(pcm->fast_op_arg);
+}
+
+/**
* \brief Move application frame position backward
* \param pcm PCM handle
* \param frames wanted displacement in frames
}
/**
+ * \brief Get safe count of frames which can be forwarded
+ * \param pcm PCM handle
+ * \return a positive number of frames or negative error code
+ *
+ * Note: The snd_pcm_forward() can accept bigger value than returned
+ * by this function. But it is not guaranteed that output stream
+ * will be consistent with bigger value.
+ */
+snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm)
+{
+ assert(pcm);
+ if (CHECK_SANITY(! pcm->setup)) {
+ SNDMSG("PCM not set up");
+ return -EIO;
+ }
+ return pcm->fast_ops->forwardable(pcm->fast_op_arg);
+}
+
+/**
* \brief Move application frame position forward
* \param pcm PCM handle
* \param frames wanted skip in frames
* \brief Read interleaved frames from a PCM
* \param pcm PCM handle
* \param buffer frames containing buffer
- * \param size frames to be written
+ * \param size frames to be read
* \return a positive number of frames actually read otherwise a
* negative error code
* \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
* \brief Read non interleaved frames to a PCM
* \param pcm PCM handle
* \param bufs frames containing buffers (one for each channel)
- * \param size frames to be written
+ * \param size frames to be read
* \return a positive number of frames actually read otherwise a
* negative error code
* \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
#define SUBFORMATD(v, d) [SND_PCM_SUBFORMAT_##v] = d
-static const char *snd_pcm_stream_names[] = {
+static const char *const snd_pcm_stream_names[] = {
STREAM(PLAYBACK),
STREAM(CAPTURE),
};
-static const char *snd_pcm_state_names[] = {
+static const char *const snd_pcm_state_names[] = {
STATE(OPEN),
STATE(SETUP),
STATE(PREPARED),
STATE(DISCONNECTED),
};
-static const char *snd_pcm_access_names[] = {
+static const char *const snd_pcm_access_names[] = {
ACCESS(MMAP_INTERLEAVED),
ACCESS(MMAP_NONINTERLEAVED),
ACCESS(MMAP_COMPLEX),
ACCESS(RW_NONINTERLEAVED),
};
-static const char *snd_pcm_format_names[] = {
+static const char *const snd_pcm_format_names[] = {
FORMAT(S8),
FORMAT(U8),
FORMAT(S16_LE),
FORMAT(U18_3BE),
};
-static const char *snd_pcm_format_aliases[SND_PCM_FORMAT_LAST+1] = {
+static const char *const snd_pcm_format_aliases[SND_PCM_FORMAT_LAST+1] = {
FORMAT(S16),
FORMAT(U16),
FORMAT(S24),
FORMAT(IEC958_SUBFRAME),
};
-static const char *snd_pcm_format_descriptions[] = {
+static const char *const snd_pcm_format_descriptions[] = {
FORMATD(S8, "Signed 8 bit"),
FORMATD(U8, "Unsigned 8 bit"),
FORMATD(S16_LE, "Signed 16 bit Little Endian"),
FORMATD(U18_3BE, "Unsigned 18 bit Big Endian in 3bytes"),
};
-static const char *snd_pcm_type_names[] = {
+static const char *const snd_pcm_type_names[] = {
PCMTYPE(HW),
PCMTYPE(HOOKS),
PCMTYPE(MULTI),
PCMTYPE(EXTPLUG),
};
-static const char *snd_pcm_subformat_names[] = {
+static const char *const snd_pcm_subformat_names[] = {
SUBFORMAT(STD),
};
-static const char *snd_pcm_subformat_descriptions[] = {
+static const char *const snd_pcm_subformat_descriptions[] = {
SUBFORMATD(STD, "Standard"),
};
-static const char *snd_pcm_start_mode_names[] = {
+static const char *const snd_pcm_start_mode_names[] = {
START(EXPLICIT),
START(DATA),
};
-static const char *snd_pcm_xrun_mode_names[] = {
+static const char *const snd_pcm_xrun_mode_names[] = {
XRUN(NONE),
XRUN(STOP),
};
-static const char *snd_pcm_tstamp_mode_names[] = {
+static const char *const snd_pcm_tstamp_mode_names[] = {
TSTAMP(NONE),
TSTAMP(ENABLE),
};
snd_output_printf(out, " tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode));
snd_output_printf(out, " period_step : %d\n", pcm->period_step);
snd_output_printf(out, " avail_min : %ld\n", pcm->avail_min);
+ snd_output_printf(out, " period_event : %i\n", pcm->period_event);
snd_output_printf(out, " start_threshold : %ld\n", pcm->start_threshold);
snd_output_printf(out, " stop_threshold : %ld\n", pcm->stop_threshold);
snd_output_printf(out, " silence_threshold: %ld\n", pcm->silence_threshold);
return handler->u.pcm;
}
-static char *build_in_pcms[] = {
+static const char *const build_in_pcms[] = {
"adpcm", "alaw", "copy", "dmix", "file", "hooks", "hw", "ladspa", "lfloat",
"linear", "meter", "mulaw", "multi", "null", "empty", "plug", "rate", "route", "share",
"shm", "dsnoop", "dshare", "asym", "iec958", "softvol", "mmap_emul",
sprintf(buf, "_snd_pcm_%s_open", str);
}
if (!lib) {
- char **build_in = build_in_pcms;
+ const char *const *build_in = build_in_pcms;
while (*build_in) {
if (!strcmp(*build_in, str))
break;
#endif
/**
- * \brief Return number of frames ready to be read/written
+ * \brief Return number of frames ready to be read (capture) / written (playback)
* \param pcm PCM handle
* \return a positive number of frames ready otherwise a negative
* error code
* On capture does all the actions needed to transport to application
* level all the ready frames across underlying layers.
*
- * Using of this function is useless for the standard read/write
- * operations. Use it only for mmap access. See to #snd_pcm_delay.
+ * The position is not synced with hardware (driver) position in the sound
+ * ring buffer in this function. This function is a light version of
+ * #snd_pcm_avail() .
+ *
+ * Using this function is ideal after poll() or select() when audio
+ * file descriptor made the event and when application expects just period
+ * timing.
+ *
+ * Also this function might be called after #snd_pcm_delay() or
+ * #snd_pcm_hwsync() functions to move private ring buffer pointers
+ * in alsa-lib (the internal plugin chain).
*/
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
{
}
/**
+ * \brief Return number of frames ready to be read (capture) / written (playback)
+ * \param pcm PCM handle
+ * \return a positive number of frames ready otherwise a negative
+ * error code
+ *
+ * On capture does all the actions needed to transport to application
+ * level all the ready frames across underlying layers.
+ *
+ * The position is synced with hardware (driver) position in the sound
+ * ring buffer in this functions.
+ */
+snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm)
+{
+ int err;
+
+ assert(pcm);
+ if (CHECK_SANITY(! pcm->setup)) {
+ SNDMSG("PCM not set up");
+ return -EIO;
+ }
+ err = pcm->fast_ops->hwsync(pcm->fast_op_arg);
+ if (err < 0)
+ return err;
+ return pcm->fast_ops->avail_update(pcm->fast_op_arg);
+}
+
+/**
+ * \brief Combine snd_pcm_avail and snd_pcm_delay functions
+ * \param pcm PCM handle
+ * \param avail Number of available frames in the ring buffer
+ * \param delay Total I/O latency in frames
+ * \return zero on success otherwise a negative error code
+ *
+ * The avail and delay values retuned are in sync.
+ */
+int snd_pcm_avail_delay(snd_pcm_t *pcm,
+ snd_pcm_sframes_t *availp,
+ snd_pcm_sframes_t *delayp)
+{
+ snd_pcm_sframes_t sf;
+
+ assert(pcm && availp && delayp);
+ if (CHECK_SANITY(! pcm->setup)) {
+ SNDMSG("PCM not set up");
+ return -EIO;
+ }
+ sf = pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
+ if (sf < 0)
+ return (int)sf;
+ sf = pcm->fast_ops->avail_update(pcm->fast_op_arg);
+ if (sf < 0)
+ return (int)sf;
+ *availp = sf;
+ return 0;
+}
+
+/**
* \brief Silence an area
* \param dst_area area specification
* \param dst_offset offset in frames inside area
}
/**
+ * \brief Check, if timestamps are monotonic for given configuration
+ * \param params Configuration space
+ * \return Boolean value
+ * \retval 0 Device doesn't do monotomic timestamps
+ * \retval 1 Device does monotonic timestamps
+ *
+ * It is not allowed to call this function when given configuration is not exactly one.
+ * Usually, #snd_pcm_hw_params() function chooses one configuration
+ * from the configuration space.
+ */
+int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params)
+{
+ assert(params);
+ if (CHECK_SANITY(params->info == ~0U)) {
+ SNDMSG("invalid PCM info field");
+ return 0; /* FIXME: should be a negative error? */
+ }
+ return !!(params->info & SND_PCM_INFO_MONOTONIC);
+}
+
+/**
* \brief Check, if hardware supports overrange detection
* \param params Configuration space
* \return Boolean value
params->period_step = pcm->period_step;
params->sleep_min = 0;
params->avail_min = pcm->avail_min;
+ params->period_event = pcm->period_event;
params->xfer_align = 1;
params->start_threshold = pcm->start_threshold;
params->stop_threshold = pcm->stop_threshold;
return 0;
}
+/**
+ * \brief Set period event inside a software configuration container
+ * \param pcm PCM handle
+ * \param params Software configuration container
+ * \param val 0 = disable period event, 1 = enable period event
+ * \return 0 otherwise a negative error code
+ *
+ * An poll (select) wakeup event is raised if enabled.
+ */
+int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val)
+{
+ assert(pcm && params);
+ params->period_event = val;
+ return 0;
+}
+
+/**
+ * \brief Get period event from a software configuration container
+ * \param params Software configuration container
+ * \param val returned period event state
+ * \return 0 otherwise a negative error code
+ */
+int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val)
+{
+ assert(params && val);
+ *val = params->period_event;
+ return 0;
+}
/**
* \brief (DEPRECATED) Set xfer align inside a software configuration container
* \brief Get trigger timestamp from a PCM status container
* \param obj #snd_pcm_status_t pointer
* \param ptr Pointer to returned timestamp
+ *
+ * Trigger means a PCM state transition (from stopped to running or
+ * versa vice). It applies also to pause and suspend. In other words,
+ * timestamp contains time when stream started or when it was stopped.
*/
void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
{
* \brief Get trigger hi-res timestamp from a PCM status container
* \param obj #snd_pcm_status_t pointer
* \param ptr Pointer to returned timestamp
+ *
+ * Trigger means a PCM state transition (from stopped to running or
+ * versa vice). It applies also to pause and suspend. In other words,
+ * timestamp contains time when stream started or when it was stopped.
*/
#ifndef DOXYGEN
void INTERNAL(snd_pcm_status_get_trigger_htstamp)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
link_warning(_snd_pcm_boundary, "Warning: _snd_pcm_boundary() is deprecated, consider to use snd_pcm_sw_params_current()");
#endif
-static const char *names[SND_PCM_HW_PARAM_LAST_INTERVAL + 1] = {
+static const char *const names[SND_PCM_HW_PARAM_LAST_INTERVAL + 1] = {
[SND_PCM_HW_PARAM_FORMAT] = "format",
[SND_PCM_HW_PARAM_CHANNELS] = "channels",
[SND_PCM_HW_PARAM_RATE] = "rate",
int snd_pcm_conf_generic_id(const char *id)
{
- static const char *ids[] = { "comment", "type", "hint" };
+ static const char ids[3][8] = { "comment", "type", "hint" };
unsigned int k;
for (k = 0; k < sizeof(ids) / sizeof(ids[0]); ++k) {
if (strcmp(id, ids[k]) == 0)
#endif
/* First table lookup for Ima-ADPCM quantizer */
-static char IndexAdjust[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
+static const char IndexAdjust[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
/* Second table lookup for Ima-ADPCM quantizer */
-static short StepSize[89] = {
+static const short StepSize[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
snd_pcm_dump(adpcm->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_adpcm_ops = {
+static const snd_pcm_ops_t snd_pcm_adpcm_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_adpcm_hw_refine,
snd_pcm_dump(alaw->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_alaw_ops = {
+static const snd_pcm_ops_t snd_pcm_alaw_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_alaw_hw_refine,
snd_pcm_dump(copy->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_copy_ops = {
+static const snd_pcm_ops_t snd_pcm_copy_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_copy_hw_refine,
int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_direct_t *dshare = pcm->private_data;
- static snd_mask_t access = { .bits = {
+ static const snd_mask_t access = { .bits = {
(1<<SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) |
(1<<SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) |
(1<<SNDRV_PCM_ACCESS_RW_INTERLEAVED) |
snd_pcm_info_get_subdevice(info) * 2 + capture);
ret = snd_timer_open(&dmix->timer, name, SND_TIMER_OPEN_NONBLOCK | SND_TIMER_OPEN_TREAD);
if (ret < 0) {
- dmix->tread = 1;
+ dmix->tread = 0;
ret = snd_timer_open(&dmix->timer, name, SND_TIMER_OPEN_NONBLOCK);
if (ret < 0) {
SNDERR("unable to open timer '%s'", name);
const snd_pcm_channel_area_t *dst_areas;
const snd_pcm_channel_area_t *src_areas;
- bits = snd_pcm_format_physical_width(dmix->type);
+ bits = snd_pcm_format_physical_width(pcm->format);
if ((bits % 8) != 0)
interleaved = 0;
channels = dmix->channels;
if (size >= pcm->boundary / 2)
size = pcm->boundary - size;
- /* the slave_app_ptr can be far behing the slave_hw_ptr */
+ /* the slave_app_ptr can be far behind the slave_hw_ptr */
/* reduce mixing and errors here - just skip not catched writes */
- if (dmix->slave_hw_ptr < dmix->slave_appl_ptr)
+ if (dmix->slave_hw_ptr <= dmix->slave_appl_ptr)
slave_size = dmix->slave_appl_ptr - dmix->slave_hw_ptr;
else
slave_size = dmix->slave_appl_ptr + (dmix->slave_boundary - dmix->slave_hw_ptr);
return -EIO;
}
+static snd_pcm_sframes_t snd_pcm_dmix_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_direct_t *dmix = pcm->private_data;
return result + frames;
}
+static snd_pcm_sframes_t snd_pcm_dmix_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dmix_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_sframes_t avail;
snd_pcm_dump(dmix->spcm, out);
}
-static snd_pcm_ops_t snd_pcm_dmix_ops = {
+static const snd_pcm_ops_t snd_pcm_dmix_ops = {
.close = snd_pcm_dmix_close,
.info = snd_pcm_direct_info,
.hw_refine = snd_pcm_direct_hw_refine,
.munmap = snd_pcm_direct_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
.status = snd_pcm_dmix_status,
.state = snd_pcm_dmix_state,
.hwsync = snd_pcm_dmix_hwsync,
.drop = snd_pcm_dmix_drop,
.drain = snd_pcm_dmix_drain,
.pause = snd_pcm_dmix_pause,
+ .rewindable = snd_pcm_dmix_rewindable,
.rewind = snd_pcm_dmix_rewind,
+ .forwardable = snd_pcm_dmix_forwardable,
.forward = snd_pcm_dmix_forward,
.resume = snd_pcm_direct_resume,
.link = NULL,
"\tmovzwl (%%esi), %%ecx\n"
"\tmovl (%%ebx), %%edx\n"
"\tsall $16, %%eax\n"
- "\t" LOCK_PREFIX "btsl $0, (%%edi)\n"
+ "\t" LOCK_PREFIX "btsw $0, (%%edi)\n"
"\tleal (%%ecx,%%eax,1), %%ecx\n"
"\tjc 2f\n"
"\t" XSUB " %%edx, %%ecx\n"
"\tmovzwl (%%esi), %%ecx\n"
"\tmovl (%%ebx), %%edx\n"
"\tsall $16, %%eax\n"
- "\t" LOCK_PREFIX "btsl $0, (%%edi)\n"
+ "\t" LOCK_PREFIX "btsw $0, (%%edi)\n"
"\tleal (%%ecx,%%eax,1), %%ecx\n"
"\tjc 2f\n"
"\t" XSUB " %%edx, %%ecx\n"
"\tmovswl (%%rsi), %%ecx\n"
"\tmovl (%%rbx), %%edx\n"
"\tsall $16, %%eax\n"
- "\t" LOCK_PREFIX "btsl $0, (%%rdi)\n"
+ "\t" LOCK_PREFIX "btsw $0, (%%rdi)\n"
"\t.byte 0x67, 0x8d, 0x0c, 0x01\n"
"\tjc 2f\n"
"\t" XSUB " %%edx, %%ecx\n"
return -EIO;
}
-static snd_pcm_sframes_t snd_pcm_dshare_rewind(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_uframes_t frames ATTRIBUTE_UNUSED)
+static snd_pcm_sframes_t snd_pcm_dshare_rewindable(snd_pcm_t *pcm)
{
-#if 0
- /* FIXME: substract samples from the mix ring buffer, too? */
+ return snd_pcm_mmap_playback_hw_avail(pcm);
+}
+
+static snd_pcm_sframes_t snd_pcm_dshare_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+ snd_pcm_sframes_t avail;
+
+ avail = snd_pcm_mmap_playback_hw_avail(pcm);
+ if (avail < 0)
+ return 0;
+ if (frames > (snd_pcm_uframes_t)avail)
+ frames = avail;
snd_pcm_mmap_appl_backward(pcm, frames);
return frames;
-#else
- return -EIO;
-#endif
+}
+
+static snd_pcm_sframes_t snd_pcm_dshare_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_playback_avail(pcm);
}
static snd_pcm_sframes_t snd_pcm_dshare_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
snd_pcm_dump(dshare->spcm, out);
}
-static snd_pcm_ops_t snd_pcm_dshare_ops = {
+static const snd_pcm_ops_t snd_pcm_dshare_ops = {
.close = snd_pcm_dshare_close,
.info = snd_pcm_direct_info,
.hw_refine = snd_pcm_direct_hw_refine,
.munmap = snd_pcm_direct_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
.status = snd_pcm_dshare_status,
.state = snd_pcm_dshare_state,
.hwsync = snd_pcm_dshare_hwsync,
.drop = snd_pcm_dshare_drop,
.drain = snd_pcm_dshare_drain,
.pause = snd_pcm_dshare_pause,
+ .rewindable = snd_pcm_dshare_rewindable,
.rewind = snd_pcm_dshare_rewind,
+ .forwardable = snd_pcm_dshare_forwardable,
.forward = snd_pcm_dshare_forward,
.resume = snd_pcm_direct_resume,
.link = NULL,
return -EIO;
}
+static snd_pcm_sframes_t snd_pcm_dsnoop_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_capture_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dsnoop_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
+ snd_pcm_sframes_t avail;
+
+ avail = snd_pcm_mmap_capture_avail(pcm);
+ if (avail < 0)
+ return 0;
+ if (frames > (snd_pcm_uframes_t)avail)
+ frames = avail;
snd_pcm_mmap_appl_backward(pcm, frames);
return frames;
}
+static snd_pcm_sframes_t snd_pcm_dsnoop_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_capture_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dsnoop_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_sframes_t avail;
snd_pcm_dump(dsnoop->spcm, out);
}
-static snd_pcm_ops_t snd_pcm_dsnoop_ops = {
+static const snd_pcm_ops_t snd_pcm_dsnoop_ops = {
.close = snd_pcm_dsnoop_close,
.info = snd_pcm_direct_info,
.hw_refine = snd_pcm_direct_hw_refine,
.munmap = snd_pcm_direct_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
.status = snd_pcm_dsnoop_status,
.state = snd_pcm_dsnoop_state,
.hwsync = snd_pcm_dsnoop_hwsync,
.drop = snd_pcm_dsnoop_drop,
.drain = snd_pcm_dsnoop_drain,
.pause = snd_pcm_dsnoop_pause,
+ .rewindable = snd_pcm_dsnoop_rewindable,
.rewind = snd_pcm_dsnoop_rewind,
+ .forwardable = snd_pcm_dsnoop_forwardable,
.forward = snd_pcm_dsnoop_forward,
.resume = snd_pcm_direct_resume,
.link = NULL,
struct snd_ext_parm sparams[SND_PCM_EXTPLUG_HW_PARAMS];
} extplug_priv_t;
-static int hw_params_type[SND_PCM_EXTPLUG_HW_PARAMS] = {
+static const int hw_params_type[SND_PCM_EXTPLUG_HW_PARAMS] = {
[SND_PCM_EXTPLUG_HW_FORMAT] = SND_PCM_HW_PARAM_FORMAT,
[SND_PCM_EXTPLUG_HW_CHANNELS] = SND_PCM_HW_PARAM_CHANNELS
};
#define is_mask_type(i) (hw_params_type[i] < SND_PCM_HW_PARAM_FIRST_INTERVAL)
-static unsigned int excl_parbits[SND_PCM_EXTPLUG_HW_PARAMS] = {
+static const unsigned int excl_parbits[SND_PCM_EXTPLUG_HW_PARAMS] = {
[SND_PCM_EXTPLUG_HW_FORMAT] = (SND_PCM_HW_PARBIT_FORMAT|
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_SAMPLE_BITS),
return 0;
}
-static snd_pcm_ops_t snd_pcm_extplug_ops = {
+static const snd_pcm_ops_t snd_pcm_extplug_ops = {
.close = snd_pcm_extplug_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_extplug_hw_refine,
*
*/
+#include <endian.h>
#include <byteswap.h>
#include <ctype.h>
#include "pcm_local.h"
#ifndef DOC_HIDDEN
typedef enum _snd_pcm_file_format {
- SND_PCM_FILE_FORMAT_RAW
+ SND_PCM_FILE_FORMAT_RAW,
+ SND_PCM_FILE_FORMAT_WAV
} snd_pcm_file_format_t;
+/* WAV format chunk */
+struct wav_fmt {
+ short fmt;
+ short chan;
+ int rate;
+ int bps;
+ short bwidth;
+ short bits;
+};
+
typedef struct {
snd_pcm_generic_t gen;
char *fname;
char *rbuf;
snd_pcm_channel_area_t *wbuf_areas;
size_t buffer_bytes;
+ struct wav_fmt wav_header;
+ size_t filelen;
} snd_pcm_file_t;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define TO_LE32(x) (x)
+#define TO_LE16(x) (x)
+#else
+#define TO_LE32(x) bswap_32(x)
+#define TO_LE16(x) bswap_16(x)
+#endif
+
+static void setup_wav_header(snd_pcm_t *pcm, struct wav_fmt *fmt)
+{
+ fmt->fmt = TO_LE16(0x01);
+ fmt->chan = TO_LE16(pcm->channels);
+ fmt->rate = TO_LE32(pcm->rate);
+ fmt->bwidth = pcm->frame_bits / 8;
+ fmt->bps = fmt->bwidth * pcm->rate;
+ fmt->bits = snd_pcm_format_width(pcm->format);
+ fmt->bps = TO_LE32(fmt->bps);
+ fmt->bwidth = TO_LE16(fmt->bwidth);
+ fmt->bits = TO_LE16(fmt->bits);
+}
+
+static int write_wav_header(snd_pcm_t *pcm)
+{
+ snd_pcm_file_t *file = pcm->private_data;
+ static const char header[] = {
+ 'R', 'I', 'F', 'F',
+ 0x24, 0, 0, 0,
+ 'W', 'A', 'V', 'E',
+ 'f', 'm', 't', ' ',
+ 0x10, 0, 0, 0,
+ };
+ static const char header2[] = {
+ 'd', 'a', 't', 'a',
+ 0, 0, 0, 0
+ };
+
+ setup_wav_header(pcm, &file->wav_header);
+
+ if (write(file->fd, header, sizeof(header)) != sizeof(header) ||
+ write(file->fd, &file->wav_header, sizeof(file->wav_header)) !=
+ sizeof(file->wav_header) ||
+ write(file->fd, header2, sizeof(header2)) != sizeof(header2)) {
+ int err = errno;
+ SYSERR("Write error.\n");
+ return -err;
+ }
+ return 0;
+}
+
+/* fix up the length fields in WAV header */
+static void fixup_wav_header(snd_pcm_t *pcm)
+{
+ snd_pcm_file_t *file = pcm->private_data;
+ int len, ret;
+
+ /* RIFF length */
+ if (lseek(file->fd, 4, SEEK_SET) == 4) {
+ len = (file->filelen + 0x24) > 0x7fffffff ?
+ 0x7fffffff : (int)(file->filelen + 0x24);
+ len = TO_LE32(len);
+ ret = write(file->fd, &len, 4);
+ if (ret < 0)
+ return;
+ }
+ /* data length */
+ if (lseek(file->fd, 0x28, SEEK_SET) == 0x28) {
+ len = file->filelen > 0x7fffffff ?
+ 0x7fffffff : (int)file->filelen;
+ len = TO_LE32(len);
+ ret = write(file->fd, &len, 4);
+ if (ret < 0)
+ return;
+ }
+}
#endif /* DOC_HIDDEN */
static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
{
snd_pcm_file_t *file = pcm->private_data;
assert(bytes <= file->wbuf_used_bytes);
+
+ if (file->format == SND_PCM_FILE_FORMAT_WAV &&
+ !file->wav_header.fmt) {
+ if (write_wav_header(pcm) < 0)
+ return;
+ }
+
while (bytes > 0) {
snd_pcm_sframes_t err;
size_t n = bytes;
file->file_ptr_bytes += err;
if (file->file_ptr_bytes == file->wbuf_size_bytes)
file->file_ptr_bytes = 0;
+ file->filelen += err;
if ((snd_pcm_uframes_t)err != n)
break;
}
{
snd_pcm_file_t *file = pcm->private_data;
if (file->fname) {
+ if (file->wav_header.fmt)
+ fixup_wav_header(pcm);
free((void *)file->fname);
close(file->fd);
}
return err;
}
+static snd_pcm_sframes_t snd_pcm_file_rewindable(snd_pcm_t *pcm)
+{
+ snd_pcm_file_t *file = pcm->private_data;
+ snd_pcm_sframes_t res = snd_pcm_rewindable(pcm);
+ snd_pcm_sframes_t n = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+ if (res > n)
+ res = n;
+ return res;
+}
+
static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_file_t *file = pcm->private_data;
return err;
}
+static snd_pcm_sframes_t snd_pcm_file_forwardable(snd_pcm_t *pcm)
+{
+ snd_pcm_file_t *file = pcm->private_data;
+ snd_pcm_sframes_t res = snd_pcm_forwardable(pcm);
+ snd_pcm_sframes_t n = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
+ if (res > n)
+ res = n;
+ return res;
+}
+
static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_file_t *file = pcm->private_data;
{
snd_pcm_file_t *file = pcm->private_data;
snd_pcm_channel_area_t areas[pcm->channels];
- snd_pcm_sframes_t n /* , bytesn */;
+ snd_pcm_sframes_t n;
+ n = snd_pcm_readi(file->gen.slave, buffer, size);
+ if (n <= 0)
+ return n;
if (file->ifd >= 0) {
- n = /* bytesn = */ read(file->ifd, buffer, size * pcm->frame_bits / 8);
- if (n > 0)
- n = n * 8 / pcm->frame_bits;
- /* SNDERR("DEBUG: channels = %d, sample_bits = %d, frame_bits = %d, bytes = %d, frames = %d",
- pcm->channels, pcm->sample_bits, pcm->frame_bits, bytesn, n); */
- } else {
- n = snd_pcm_readi(file->gen.slave, buffer, size);
- if (n > 0) {
- snd_pcm_areas_from_buf(pcm, areas, buffer);
- snd_pcm_file_add_frames(pcm, areas, 0, n);
- }
+ n = read(file->ifd, buffer, n * pcm->frame_bits / 8);
+ if (n < 0)
+ return n;
+ return n * 8 / pcm->frame_bits;
}
+ snd_pcm_areas_from_buf(pcm, areas, buffer);
+ snd_pcm_file_add_frames(pcm, areas, 0, n);
return n;
}
snd_pcm_dump(file->gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_file_ops = {
+static const snd_pcm_ops_t snd_pcm_file_ops = {
.close = snd_pcm_file_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_generic_hw_refine,
.munmap = snd_pcm_generic_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
.status = snd_pcm_generic_status,
.state = snd_pcm_generic_state,
.hwsync = snd_pcm_generic_hwsync,
.drop = snd_pcm_file_drop,
.drain = snd_pcm_file_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_file_rewindable,
.rewind = snd_pcm_file_rewind,
+ .forwardable = snd_pcm_file_forwardable,
.forward = snd_pcm_file_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
* \param ifname Input filename (or NULL if file descriptor ifd is available)
* \param ifd Input file descriptor (if (ifd < 0) && (ifname == NULL), no input
* redirection will be performed)
- * \param fmt File format ("raw" is supported only)
+ * \param trunc Truncate the file if it already exists
+ * \param fmt File format ("raw" or "wav" are available)
* \param perm File permission
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* changed in future.
*/
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
- const char *fname, int fd, const char *ifname, int ifd,
+ const char *fname, int fd, const char *ifname, int ifd,
+ int trunc,
const char *fmt, int perm, snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
snd_pcm_file_t *file;
snd_pcm_file_format_t format;
struct timespec timespec;
+ char *tmpname = NULL;
int err;
assert(pcmp);
if (fmt == NULL ||
strcmp(fmt, "raw") == 0)
format = SND_PCM_FILE_FORMAT_RAW;
+ else if (!strcmp(fmt, "wav"))
+ format = SND_PCM_FILE_FORMAT_WAV;
else {
SNDERR("file format %s is unknown", fmt);
return -EINVAL;
}
if (fname) {
- fd = open(fname, O_WRONLY|O_CREAT, perm);
+ if (trunc)
+ fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, perm);
+ else {
+ fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, perm);
+ if (fd < 0) {
+ int idx, len;
+ len = strlen(fname) + 6;
+ tmpname = malloc(len);
+ if (!tmpname)
+ return -ENOMEM;
+ for (idx = 1; idx < 10000; idx++) {
+ snprintf(tmpname, len,
+ "%s.%04d", fname, idx);
+ fd = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, perm);
+ if (fd >= 0) {
+ fname = tmpname;
+ break;
+ }
+ }
+ }
+ }
if (fd < 0) {
SYSERR("open %s for writing failed", fname);
+ free(tmpname);
return -errno;
}
}
if (!file) {
if (fname)
close(fd);
+ free(tmpname);
return -ENOMEM;
}
SYSERR("open %s for reading failed", ifname);
if (fname)
close(fd);
+ free(file);
+ free(tmpname);
return -errno;
}
}
if (err < 0) {
free(file->fname);
free(file);
+ free(tmpname);
return err;
}
pcm->ops = &snd_pcm_file_ops;
pcm->poll_fd = slave->poll_fd;
pcm->poll_events = slave->poll_events;
pcm->mmap_shadow = 1;
-#ifdef HAVE_CLOCK_GETTIME
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
pcm->monotonic = clock_gettime(CLOCK_MONOTONIC, ×pec) == 0;
#else
pcm->monotonic = 0;
snd_pcm_link_appl_ptr(pcm, slave);
*pcmp = pcm;
+ free(tmpname);
return 0;
}
file STR # Output filename
or
file INT # Output file descriptor number
- infile STR # Input filename
+ infile STR # Input filename - only raw format
or
infile INT # Input file descriptor number
- [format STR] # File format (only "raw" at the moment)
+ [format STR] # File format ("raw" or "wav")
[perm INT] # Output file permission (octal, def. 0600)
}
\endcode
snd_config_t *slave = NULL, *sconf;
const char *fname = NULL, *ifname = NULL;
const char *format = NULL;
- long fd = -1, ifd = -1;
+ long fd = -1, ifd = -1, trunc = 1;
long perm = 0600;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
}
continue;
}
+ if (strcmp(id, "truncate") == 0) {
+ err = snd_config_get_bool(n);
+ if (err < 0)
+ return -EINVAL;
+ trunc = err;
+ continue;
+ }
SNDERR("Unknown field %s", id);
return -EINVAL;
}
+ if (!format) {
+ snd_config_t *n;
+ /* read defaults */
+ if (snd_config_search(root, "defaults.pcm.file_format", &n) >= 0) {
+ err = snd_config_get_string(n, &format);
+ if (err < 0) {
+ SNDERR("Invalid file format");
+ return -EINVAL;
+ }
+ }
+ }
if (!slave) {
SNDERR("slave is not defined");
return -EINVAL;
err = snd_pcm_slave_conf(root, slave, &sconf, 0);
if (err < 0)
return err;
- if (!fname && fd < 0) {
+ if (!fname && fd < 0 && !ifname) {
snd_config_delete(sconf);
SNDERR("file is not defined");
return -EINVAL;
snd_config_delete(sconf);
if (err < 0)
return err;
- err = snd_pcm_file_open(pcmp, name, fname, fd, ifname, ifd, format, perm, spcm, 1);
+ err = snd_pcm_file_open(pcmp, name, fname, fd, ifname, ifd,
+ trunc, format, perm, spcm, 1);
if (err < 0)
snd_pcm_close(spcm);
return err;
return snd_pcm_delay(generic->slave, delayp);
}
+snd_pcm_sframes_t snd_pcm_generic_forwardable(snd_pcm_t *pcm)
+{
+ snd_pcm_generic_t *generic = pcm->private_data;
+ return snd_pcm_forwardable(generic->slave);
+}
+
snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_generic_t *generic = pcm->private_data;
return INTERNAL(snd_pcm_forward)(generic->slave, frames);
}
+snd_pcm_sframes_t snd_pcm_generic_rewindable(snd_pcm_t *pcm)
+{
+ snd_pcm_generic_t *generic = pcm->private_data;
+ return snd_pcm_rewindable(generic->slave);
+}
+
snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_generic_t *generic = pcm->private_data;
snd1_pcm_generic_resume
#define snd_pcm_generic_delay \
snd1_pcm_generic_delay
+#define snd_pcm_generic_forwardable \
+ snd1_pcm_generic_forwardable
#define snd_pcm_generic_forward \
snd1_pcm_generic_forward
+#define snd_pcm_generic_rewindable \
+ snd1_pcm_generic_rewindable
#define snd_pcm_generic_rewind \
snd1_pcm_generic_rewind
#define snd_pcm_generic_link \
int snd_pcm_generic_pause(snd_pcm_t *pcm, int enable);
int snd_pcm_generic_resume(snd_pcm_t *pcm);
int snd_pcm_generic_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+snd_pcm_sframes_t snd_pcm_generic_forwardable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_generic_rewindable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
int snd_pcm_generic_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
int snd_pcm_generic_link_slaves(snd_pcm_t *pcm, snd_pcm_t *master);
snd_pcm_dump(h->gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_hooks_ops = {
+static const snd_pcm_ops_t snd_pcm_hooks_ops = {
.close = snd_pcm_hooks_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_generic_hw_refine,
.munmap = snd_pcm_generic_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
.status = snd_pcm_generic_status,
.state = snd_pcm_generic_state,
.hwsync = snd_pcm_generic_hwsync,
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_generic_rewindable,
.rewind = snd_pcm_generic_rewind,
+ .forwardable = snd_pcm_generic_forwardable,
.forward = snd_pcm_generic_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
#include <sys/shm.h>
#include "pcm_local.h"
#include "../control/control_local.h"
+#include "../timer/timer_local.h"
//#define DEBUG_RW /* use to debug readi/writei/readn/writen */
//#define DEBUG_MMAP /* debug mmap_commit */
static int use_old_hw_params_ioctl(int fd, unsigned int cmd, snd_pcm_hw_params_t *params);
static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm);
+static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops;
+static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops_timer;
/*
*
struct sndrv_pcm_sync_ptr *sync_ptr;
snd_pcm_uframes_t hw_ptr;
snd_pcm_uframes_t appl_ptr;
+ int period_event;
+ snd_timer_t *period_timer;
+ struct pollfd period_timer_pfd;
+ int period_timer_need_poll;
/* restricted parameters */
snd_pcm_format_t format;
int rate;
return hw->sync_ptr ? sync_ptr1(hw, flags) : 0;
}
+static int snd_pcm_hw_clear_timer_queue(snd_pcm_hw_t *hw)
+{
+ if (hw->period_timer_need_poll) {
+ while (poll(&hw->period_timer_pfd, 1, 0) > 0) {
+ snd_timer_tread_t rbuf[4];
+ snd_timer_read(hw->period_timer, rbuf, sizeof(rbuf));
+ }
+ } else {
+ snd_timer_tread_t rbuf[4];
+ snd_timer_read(hw->period_timer, rbuf, sizeof(rbuf));
+ }
+ return 0;
+}
+
+static int snd_pcm_hw_poll_descriptors_count(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return 2;
+}
+
+static int snd_pcm_hw_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
+{
+ snd_pcm_hw_t *hw = pcm->private_data;
+
+ if (space < 2)
+ return -ENOMEM;
+ pfds[0].fd = hw->fd;
+ pfds[0].events = pcm->poll_events | POLLERR | POLLNVAL;
+ pfds[1].fd = hw->period_timer_pfd.fd;
+ pfds[1].events = POLLIN | POLLERR | POLLNVAL;
+ return 2;
+}
+
+static int snd_pcm_hw_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned nfds, unsigned short *revents)
+{
+ snd_pcm_hw_t *hw = pcm->private_data;
+ unsigned int events;
+
+ if (nfds != 2 || pfds[0].fd != hw->fd || pfds[1].fd != hw->period_timer_pfd.fd)
+ return -EINVAL;
+ events = pfds[0].revents;
+ if (pfds[1].revents & POLLIN) {
+ snd_pcm_hw_clear_timer_queue(hw);
+ events |= pcm->poll_events & ~(POLLERR|POLLNVAL);
+ }
+ *revents = events;
+ return 0;
+}
+
static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
{
long flags;
// SYSMSG("SNDRV_PCM_IOCTL_HW_REFINE failed");
return err;
}
+
+ if (params->info != ~0U) {
+ params->info &= ~0xf0000000;
+ params->info |= (pcm->monotonic ? SND_PCM_INFO_MONOTONIC : 0);
+ }
return 0;
}
return 0;
}
+static void snd_pcm_hw_close_timer(snd_pcm_hw_t *hw)
+{
+ if (hw->period_timer) {
+ snd_timer_close(hw->period_timer);
+ hw->period_timer = NULL;
+ }
+}
+
+static int snd_pcm_hw_change_timer(snd_pcm_t *pcm, int enable)
+{
+ snd_pcm_hw_t *hw = pcm->private_data;
+ snd_timer_params_t *params;
+ unsigned int suspend, resume;
+ int err;
+
+ if (enable) {
+ snd_timer_params_alloca(¶ms);
+ err = snd_timer_hw_open(&hw->period_timer, "hw-pcm-period-event", SND_TIMER_CLASS_PCM, SND_TIMER_SCLASS_NONE, hw->card, hw->device, hw->subdevice, SND_TIMER_OPEN_NONBLOCK | SND_TIMER_OPEN_TREAD);
+ if (err < 0) {
+ err = snd_timer_hw_open(&hw->period_timer, "hw-pcm-period-event", SND_TIMER_CLASS_PCM, SND_TIMER_SCLASS_NONE, hw->card, hw->device, hw->subdevice, SND_TIMER_OPEN_NONBLOCK);
+ return err;
+ }
+ if (snd_timer_poll_descriptors_count(hw->period_timer) != 1) {
+ snd_pcm_hw_close_timer(hw);
+ return -EINVAL;
+ }
+ hw->period_timer_pfd.events = POLLIN;
+ hw->period_timer_pfd.revents = 0;
+ snd_timer_poll_descriptors(hw->period_timer, &hw->period_timer_pfd, 1);
+ hw->period_timer_need_poll = 0;
+ suspend = 1<<SND_TIMER_EVENT_MSUSPEND;
+ resume = 1<<SND_TIMER_EVENT_MRESUME;
+ /*
+ * hacks for older kernel drivers
+ */
+ {
+ int ver = 0;
+ ioctl(hw->period_timer_pfd.fd, SNDRV_TIMER_IOCTL_PVERSION, &ver);
+ /* In older versions, check via poll before read() is needed
+ * because of the confliction between TIMER_START and
+ * FIONBIO ioctls.
+ */
+ if (ver < SNDRV_PROTOCOL_VERSION(2, 0, 4))
+ hw->period_timer_need_poll = 1;
+ /*
+ * In older versions, timer uses pause events instead
+ * suspend/resume events.
+ */
+ if (ver < SNDRV_PROTOCOL_VERSION(2, 0, 5)) {
+ suspend = 1<<SND_TIMER_EVENT_MPAUSE;
+ resume = 1<<SND_TIMER_EVENT_MCONTINUE;
+ }
+ }
+ snd_timer_params_set_auto_start(params, 1);
+ snd_timer_params_set_ticks(params, 1);
+ snd_timer_params_set_filter(params, (1<<SND_TIMER_EVENT_TICK) |
+ suspend | resume);
+ err = snd_timer_params(hw->period_timer, params);
+ if (err < 0) {
+ snd_pcm_hw_close_timer(hw);
+ return err;
+ }
+ err = snd_timer_start(hw->period_timer);
+ if (err < 0) {
+ snd_pcm_hw_close_timer(hw);
+ return err;
+ }
+ pcm->fast_ops = &snd_pcm_hw_fast_ops_timer;
+ } else {
+ snd_pcm_hw_close_timer(hw);
+ pcm->fast_ops = &snd_pcm_hw_fast_ops;
+ }
+ return 0;
+}
+
static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
{
snd_pcm_hw_t *hw = pcm->private_data;
int fd = hw->fd, err;
+ int old_period_event = params->period_event;
+ params->period_event = 0;
if ((snd_pcm_tstamp_t) params->tstamp_mode == pcm->tstamp_mode &&
params->period_step == pcm->period_step &&
params->start_threshold == pcm->start_threshold &&
params->stop_threshold == pcm->stop_threshold &&
params->silence_threshold == pcm->silence_threshold &&
- params->silence_size == pcm->silence_size) {
+ params->silence_size == pcm->silence_size &&
+ old_period_event == hw->period_event) {
hw->mmap_control->avail_min = params->avail_min;
return sync_ptr(hw, 0);
}
SYSMSG("SNDRV_PCM_IOCTL_SW_PARAMS failed");
return err;
}
+ params->period_event = old_period_event;
hw->mmap_control->avail_min = params->avail_min;
+ if (hw->period_event != old_period_event) {
+ err = snd_pcm_hw_change_timer(pcm, old_period_event);
+ if (err < 0)
+ return err;
+ hw->period_event = old_period_event;
+ }
return 0;
}
err = -errno;
SYSMSG("SNDRV_PCM_IOCTL_DROP failed");
return err;
+ } else {
}
return 0;
}
return 0;
}
+static snd_pcm_sframes_t snd_pcm_hw_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_hw_t *hw = pcm->private_data;
return frames;
}
+static snd_pcm_sframes_t snd_pcm_hw_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_hw_t *hw = pcm->private_data;
}
}
-static snd_pcm_ops_t snd_pcm_hw_ops = {
+static const snd_pcm_ops_t snd_pcm_hw_ops = {
.close = snd_pcm_hw_close,
.info = snd_pcm_hw_info,
.hw_refine = snd_pcm_hw_hw_refine,
.munmap = snd_pcm_hw_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
.status = snd_pcm_hw_status,
.state = snd_pcm_hw_state,
.hwsync = snd_pcm_hw_hwsync,
.drop = snd_pcm_hw_drop,
.drain = snd_pcm_hw_drain,
.pause = snd_pcm_hw_pause,
+ .rewindable = snd_pcm_hw_rewindable,
.rewind = snd_pcm_hw_rewind,
+ .forwardable = snd_pcm_hw_forwardable,
.forward = snd_pcm_hw_forward,
.resume = snd_pcm_hw_resume,
.link = snd_pcm_hw_link,
.poll_revents = NULL,
};
+static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops_timer = {
+ .status = snd_pcm_hw_status,
+ .state = snd_pcm_hw_state,
+ .hwsync = snd_pcm_hw_hwsync,
+ .delay = snd_pcm_hw_delay,
+ .prepare = snd_pcm_hw_prepare,
+ .reset = snd_pcm_hw_reset,
+ .start = snd_pcm_hw_start,
+ .drop = snd_pcm_hw_drop,
+ .drain = snd_pcm_hw_drain,
+ .pause = snd_pcm_hw_pause,
+ .rewindable = snd_pcm_hw_rewindable,
+ .rewind = snd_pcm_hw_rewind,
+ .forwardable = snd_pcm_hw_forwardable,
+ .forward = snd_pcm_hw_forward,
+ .resume = snd_pcm_hw_resume,
+ .link = snd_pcm_hw_link,
+ .link_slaves = snd_pcm_hw_link_slaves,
+ .unlink = snd_pcm_hw_unlink,
+ .writei = snd_pcm_hw_writei,
+ .writen = snd_pcm_hw_writen,
+ .readi = snd_pcm_hw_readi,
+ .readn = snd_pcm_hw_readn,
+ .avail_update = snd_pcm_hw_avail_update,
+ .mmap_commit = snd_pcm_hw_mmap_commit,
+ .htimestamp = snd_pcm_hw_htimestamp,
+ .poll_descriptors = snd_pcm_hw_poll_descriptors,
+ .poll_descriptors_count = snd_pcm_hw_poll_descriptors_count,
+ .poll_revents = snd_pcm_hw_poll_revents,
+};
+
/**
* \brief Creates a new hw PCM
* \param pcmp Returns created PCM handle
if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_PCM_VERSION_MAX))
return -SND_ERROR_INCOMPATIBLE_VERSION;
-#ifdef HAVE_CLOCK_GETTIME
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
if (SNDRV_PROTOCOL_VERSION(2, 0, 9) <= ver) {
struct timespec timespec;
if (clock_gettime(CLOCK_MONOTONIC, ×pec) == 0) {
}
monotonic = 1;
}
- }
+ } else
#endif
- else if (SNDRV_PROTOCOL_VERSION(2, 0, 5) <= ver) {
+ if (SNDRV_PROTOCOL_VERSION(2, 0, 5) <= ver) {
int on = 1;
if (ioctl(fd, SNDRV_PCM_IOCTL_TSTAMP, &on) < 0) {
ret = -errno;
/* revert to blocking mode for read/write access */
snd_pcm_hw_nonblock(*pcmp, 0);
(*pcmp)->mode = mode;
- }
+ } else
+ /* make sure the SND_PCM_NO_xxx flags don't get lost on the
+ * way */
+ (*pcmp)->mode |= mode & (SND_PCM_NO_AUTO_RESAMPLE|
+ SND_PCM_NO_AUTO_CHANNELS|
+ SND_PCM_NO_AUTO_FORMAT|
+ SND_PCM_NO_SOFTVOL);
hw = (*pcmp)->private_data;
if (format != SND_PCM_FORMAT_UNKNOWN)
snd_pcm_dump(iec->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_iec958_ops = {
+static const snd_pcm_ops_t snd_pcm_iec958_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_iec958_hw_refine,
snd_pcm_t *pcm;
snd_pcm_iec958_t *iec;
int err;
- static unsigned char default_status_bits[] = {
+ static const unsigned char default_status_bits[] = {
IEC958_AES0_CON_EMPHASIS_NONE,
IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
0,
return 0;
}
-static int hw_params_type[SND_PCM_IOPLUG_HW_PARAMS] = {
+static const int hw_params_type[SND_PCM_IOPLUG_HW_PARAMS] = {
[SND_PCM_IOPLUG_HW_ACCESS] = SND_PCM_HW_PARAM_ACCESS,
[SND_PCM_IOPLUG_HW_FORMAT] = SND_PCM_HW_PARAM_FORMAT,
[SND_PCM_IOPLUG_HW_CHANNELS] = SND_PCM_HW_PARAM_CHANNELS,
static int snd_pcm_ioplug_pause(snd_pcm_t *pcm, int enable)
{
ioplug_priv_t *io = pcm->private_data;
- static snd_pcm_state_t states[2] = {
- SND_PCM_STATE_PAUSED, SND_PCM_STATE_RUNNING
+ static const snd_pcm_state_t states[2] = {
+ SND_PCM_STATE_RUNNING, SND_PCM_STATE_PAUSED
};
int prev, err;
return 0;
}
+static snd_pcm_sframes_t snd_pcm_ioplug_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_ioplug_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_mmap_appl_backward(pcm, frames);
return frames;
}
+static snd_pcm_sframes_t snd_pcm_ioplug_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_ioplug_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_mmap_appl_forward(pcm, frames);
return 0;
}
-static snd_pcm_ops_t snd_pcm_ioplug_ops = {
+static const snd_pcm_ops_t snd_pcm_ioplug_ops = {
.close = snd_pcm_ioplug_close,
.nonblock = snd_pcm_ioplug_nonblock,
.async = snd_pcm_ioplug_async,
.munmap = snd_pcm_ioplug_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_ioplug_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_ioplug_fast_ops = {
.status = snd_pcm_ioplug_status,
.prepare = snd_pcm_ioplug_prepare,
.reset = snd_pcm_ioplug_reset,
.link = NULL,
.link_slaves = NULL,
.unlink = NULL,
+ .rewindable = snd_pcm_ioplug_rewindable,
.rewind = snd_pcm_ioplug_rewind,
+ .forwardable = snd_pcm_ioplug_forwardable,
.forward = snd_pcm_ioplug_forward,
.writei = snd_pcm_ioplug_writei,
.writen = snd_pcm_ioplug_writen,
snd_pcm_dump(ladspa->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_ladspa_ops = {
+static const snd_pcm_ops_t snd_pcm_ladspa_ops = {
.close = snd_pcm_ladspa_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_ladspa_hw_refine,
snd_pcm_dump(lfloat->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_lfloat_ops = {
+static const snd_pcm_ops_t snd_pcm_lfloat_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_lfloat_hw_refine,
snd_pcm_dump(linear->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_linear_ops = {
+static const snd_pcm_ops_t snd_pcm_linear_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_linear_hw_refine,
#define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE
#define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER
+#define SND_PCM_INFO_MONOTONIC 0x80000000
+
typedef struct _snd_pcm_rbptr {
snd_pcm_t *master;
volatile snd_pcm_uframes_t *ptr;
int (*link)(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
int (*link_slaves)(snd_pcm_t *pcm, snd_pcm_t *master);
int (*unlink)(snd_pcm_t *pcm);
+ snd_pcm_sframes_t (*rewindable)(snd_pcm_t *pcm);
snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+ snd_pcm_sframes_t (*forwardable)(snd_pcm_t *pcm);
snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
snd_pcm_tstamp_t tstamp_mode; /* timestamp mode */
unsigned int period_step;
snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */
- snd_pcm_uframes_t start_threshold;
- snd_pcm_uframes_t stop_threshold;
+ int period_event;
+ snd_pcm_uframes_t start_threshold;
+ snd_pcm_uframes_t stop_threshold;
snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
noise is nearest than this */
snd_pcm_uframes_t silence_size; /* Silence filling size */
snd_pcm_channel_info_t *mmap_channels;
snd_pcm_channel_area_t *running_areas;
snd_pcm_channel_area_t *stopped_areas;
- snd_pcm_ops_t *ops;
- snd_pcm_fast_ops_t *fast_ops;
+ const snd_pcm_ops_t *ops;
+ const snd_pcm_fast_ops_t *fast_ops;
snd_pcm_t *op_arg;
snd_pcm_t *fast_op_arg;
void *private_data;
int snd_pcm_conf_generic_id(const char *id);
int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd, int mmap_emulation, int sync_ptr_ioctl);
+int __snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_t *slave, int close_slave);
int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout);
/* get the current timestamp */
static inline void gettimestamp(snd_htimestamp_t *tstamp, int monotonic)
{
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
if (monotonic) {
clock_gettime(CLOCK_MONOTONIC, tstamp);
} else {
+#endif
struct timeval tv;
gettimeofday(&tv, 0);
tstamp->tv_sec = tv.tv_sec;
tstamp->tv_nsec = tv.tv_usec * 1000L;
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
}
+#endif
}
snd_pcm_dump(meter->gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_meter_ops = {
+static const snd_pcm_ops_t snd_pcm_meter_ops = {
.close = snd_pcm_meter_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_meter_hw_refine,
.munmap = snd_pcm_generic_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
.status = snd_pcm_generic_status,
.state = snd_pcm_generic_state,
.hwsync = snd_pcm_generic_hwsync,
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_generic_rewindable,
.rewind = snd_pcm_meter_rewind,
+ .forwardable = snd_pcm_generic_forwardable,
.forward = snd_pcm_meter_forward,
.resume = snd_pcm_generic_resume,
.writei = snd_pcm_mmap_writei,
snd_config_iterator_t i, next;
const char *id;
const char *lib = NULL, *open_name = NULL, *str = NULL;
- snd_config_t *c, *type_conf;
+ snd_config_t *c, *type_conf = NULL;
int (*open_func)(snd_pcm_t *, const char *,
snd_config_t *, snd_config_t *) = NULL;
snd_pcm_meter_t *meter = pcm->private_data;
s16->old = meter->now;
}
-snd_pcm_scope_ops_t s16_ops = {
+static const snd_pcm_scope_ops_t s16_ops = {
.enable = s16_enable,
.disable = s16_disable,
.close = s16_close,
#include <byteswap.h>
#include "pcm_local.h"
-/* Bionic does not provide bswap_64() */
-#ifndef bswap_64
-#undef __ASM_ARM_BYTEORDER_H
-#include <asm/byteorder.h>
-#include <linux/byteorder/swab.h>
-
-#define bswap_64 __swab64
-#endif
-
/**
* \brief Return sign info for a PCM sample linear format
return 0;
}
-static int linear_formats[4][2][2] = {
+static const int linear_formats[4][2][2] = {
{ { SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8 },
{ SNDRV_PCM_FORMAT_U8, SNDRV_PCM_FORMAT_U8 } },
{ { SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_FORMAT_S16_BE },
{ SNDRV_PCM_FORMAT_U32_LE, SNDRV_PCM_FORMAT_U32_BE } }
};
-static int linear24_formats[3][2][2] = {
+static const int linear24_formats[3][2][2] = {
{ { SNDRV_PCM_FORMAT_S24_3LE, SNDRV_PCM_FORMAT_S24_3BE },
{ SNDRV_PCM_FORMAT_U24_3LE, SNDRV_PCM_FORMAT_U24_3BE } },
{ { SNDRV_PCM_FORMAT_S20_3LE, SNDRV_PCM_FORMAT_S20_3BE },
#include <sys/poll.h>
#include <sys/mman.h>
#include <sys/shm.h>
-#include <unistd.h>
#include "pcm_local.h"
size_t page_size(void)
{
- int s = getpagesize();
+ long s = sysconf(_SC_PAGE_SIZE);
assert(s > 0);
return s;
}
snd_mask_none(&mask);
err = snd_pcm_hw_refine(map->gen.slave, params);
if (err < 0) {
- /* try to use RW_* */
snd_pcm_hw_params_t new = *params;
- if (!(params->rmask & (1<<SND_PCM_HW_PARAM_ACCESS)))
- return err;
+ /* try to use RW_* */
if (snd_pcm_access_mask_test(&oldmask,
SND_PCM_ACCESS_MMAP_INTERLEAVED) &&
!snd_pcm_access_mask_test(&oldmask,
snd_pcm_hw_params_t old = *params;
snd_pcm_access_t access;
snd_pcm_access_mask_t oldmask;
- const snd_mask_t *pmask;
+ snd_pcm_access_mask_t *pmask;
int err;
err = _snd_pcm_hw_params(map->gen.slave, params);
}
*params = old;
- pmask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS);
- oldmask = *(snd_pcm_access_mask_t *)pmask;
+ pmask = (snd_pcm_access_mask_t *)snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS);
+ oldmask = *pmask;
if (INTERNAL(snd_pcm_hw_params_get_access)(params, &access) < 0)
goto _err;
switch (access) {
case SND_PCM_ACCESS_MMAP_INTERLEAVED:
- snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask,
+ snd_pcm_access_mask_reset(pmask,
SND_PCM_ACCESS_MMAP_INTERLEAVED);
- snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask,
- SND_PCM_ACCESS_RW_INTERLEAVED);
+ snd_pcm_access_mask_set(pmask, SND_PCM_ACCESS_RW_INTERLEAVED);
break;
case SND_PCM_ACCESS_MMAP_NONINTERLEAVED:
- snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask,
+ snd_pcm_access_mask_reset(pmask,
SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
- snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask,
+ snd_pcm_access_mask_set(pmask,
SND_PCM_ACCESS_RW_NONINTERLEAVED);
break;
default:
goto _err;
/* need to back the access type to relieve apps */
- *(snd_pcm_access_mask_t *)pmask = oldmask;
+ *pmask = oldmask;
/* OK, we do fake */
map->mmap_emul = 1;
snd_pcm_dump(map->gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_mmap_emul_ops = {
+static const snd_pcm_ops_t snd_pcm_mmap_emul_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_mmap_emul_hw_refine,
.munmap = snd_pcm_generic_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_mmap_emul_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_mmap_emul_fast_ops = {
.status = snd_pcm_generic_status,
.state = snd_pcm_generic_state,
.hwsync = snd_pcm_generic_hwsync,
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_generic_rewindable,
.rewind = snd_pcm_mmap_emul_rewind,
+ .forwardable = snd_pcm_generic_forwardable,
.forward = snd_pcm_mmap_emul_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
.poll_revents = snd_pcm_generic_poll_revents,
};
-static int snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name,
- snd_pcm_t *slave, int close_slave)
+#ifndef DOC_HIDDEN
+int __snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
mmap_emul_t *map;
return 0;
}
+#endif
/*! \page pcm_plugins
snd_config_delete(sconf);
if (err < 0)
return err;
- err = snd_pcm_mmap_emul_open(pcmp, name, spcm, 1);
+ err = __snd_pcm_mmap_emul_open(pcmp, name, spcm, 1);
if (err < 0)
snd_pcm_close(spcm);
return err;
snd_pcm_dump(mulaw->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_mulaw_ops = {
+static const snd_pcm_ops_t snd_pcm_mulaw_ops = {
.close = snd_pcm_generic_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_mulaw_hw_refine,
}
}
-static snd_pcm_ops_t snd_pcm_multi_ops = {
+static const snd_pcm_ops_t snd_pcm_multi_ops = {
.close = snd_pcm_multi_close,
.info = snd_pcm_multi_info,
.hw_refine = snd_pcm_multi_hw_refine,
.munmap = snd_pcm_multi_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
.status = snd_pcm_multi_status,
.state = snd_pcm_multi_state,
.hwsync = snd_pcm_multi_hwsync,
static int snd_pcm_null_drop(snd_pcm_t *pcm)
{
snd_pcm_null_t *null = pcm->private_data;
+ assert(null->state != SND_PCM_STATE_OPEN);
null->state = SND_PCM_STATE_SETUP;
return 0;
}
static int snd_pcm_null_drain(snd_pcm_t *pcm)
{
snd_pcm_null_t *null = pcm->private_data;
+ assert(null->state != SND_PCM_STATE_OPEN);
null->state = SND_PCM_STATE_SETUP;
return 0;
}
}
}
-static snd_pcm_ops_t snd_pcm_null_ops = {
+static const snd_pcm_ops_t snd_pcm_null_ops = {
.close = snd_pcm_null_close,
.info = snd_pcm_null_info,
.hw_refine = snd_pcm_null_hw_refine,
.munmap = snd_pcm_generic_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
.status = snd_pcm_null_status,
.state = snd_pcm_null_state,
.hwsync = snd_pcm_null_hwsync,
#define HW_PARAM(v) [SND_PCM_HW_PARAM_##v] = #v
-const char *snd_pcm_hw_param_names[] = {
+static const char *const snd_pcm_hw_param_names[] = {
HW_PARAM(ACCESS),
HW_PARAM(FORMAT),
HW_PARAM(SUBFORMAT),
typedef struct _snd_pcm_hw_rule snd_pcm_hw_rule_t;
typedef int (*snd_pcm_hw_rule_func_t)(snd_pcm_hw_params_t *params,
- snd_pcm_hw_rule_t *rule);
+ const snd_pcm_hw_rule_t *rule);
struct _snd_pcm_hw_rule {
int var;
};
static int snd_pcm_hw_rule_mul(snd_pcm_hw_params_t *params,
- snd_pcm_hw_rule_t *rule)
+ const snd_pcm_hw_rule_t *rule)
{
snd_interval_t t;
snd_interval_mul(hw_param_interval_c(params, rule->deps[0]),
}
static int snd_pcm_hw_rule_div(snd_pcm_hw_params_t *params,
- snd_pcm_hw_rule_t *rule)
+ const snd_pcm_hw_rule_t *rule)
{
snd_interval_t t;
snd_interval_div(hw_param_interval_c(params, rule->deps[0]),
}
static int snd_pcm_hw_rule_muldivk(snd_pcm_hw_params_t *params,
- snd_pcm_hw_rule_t *rule)
+ const snd_pcm_hw_rule_t *rule)
{
snd_interval_t t;
snd_interval_muldivk(hw_param_interval_c(params, rule->deps[0]),
}
static int snd_pcm_hw_rule_mulkdiv(snd_pcm_hw_params_t *params,
- snd_pcm_hw_rule_t *rule)
+ const snd_pcm_hw_rule_t *rule)
{
snd_interval_t t;
snd_interval_mulkdiv(hw_param_interval_c(params, rule->deps[0]),
}
static int snd_pcm_hw_rule_format(snd_pcm_hw_params_t *params,
- snd_pcm_hw_rule_t *rule)
+ const snd_pcm_hw_rule_t *rule)
{
int changed = 0;
snd_pcm_format_t k;
static int snd_pcm_hw_rule_sample_bits(snd_pcm_hw_params_t *params,
- snd_pcm_hw_rule_t *rule)
+ const snd_pcm_hw_rule_t *rule)
{
unsigned int min, max;
snd_pcm_format_t k;
return changed;
}
-static snd_pcm_hw_rule_t refine_rules[] = {
+static const snd_pcm_hw_rule_t refine_rules[] = {
{
.var = SND_PCM_HW_PARAM_FORMAT,
.func = snd_pcm_hw_rule_format,
#define RULES (sizeof(refine_rules) / sizeof(refine_rules[0]))
-static snd_mask_t refine_masks[SND_PCM_HW_PARAM_LAST_MASK - SND_PCM_HW_PARAM_FIRST_MASK + 1] = {
+static const snd_mask_t refine_masks[SND_PCM_HW_PARAM_LAST_MASK - SND_PCM_HW_PARAM_FIRST_MASK + 1] = {
[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK] = {
.bits = { 0x1f },
},
},
};
-static snd_interval_t refine_intervals[SND_PCM_HW_PARAM_LAST_INTERVAL - SND_PCM_HW_PARAM_FIRST_INTERVAL + 1] = {
+static const snd_interval_t refine_intervals[SND_PCM_HW_PARAM_LAST_INTERVAL - SND_PCM_HW_PARAM_FIRST_INTERVAL + 1] = {
[SND_PCM_HW_PARAM_SAMPLE_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
.min = 1, .max = UINT_MAX,
.openmin = 0, .openmax = 0, .integer = 1, .empty = 0,
do {
again = 0;
for (k = 0; k < RULES; k++) {
- snd_pcm_hw_rule_t *r = &refine_rules[k];
+ const snd_pcm_hw_rule_t *r = &refine_rules[k];
unsigned int d;
int doit = 0;
for (d = 0; r->deps[d] >= 0; d++) {
return 0;
}
-static snd_pcm_format_t linear_preferred_formats[] = {
+static const snd_pcm_format_t linear_preferred_formats[] = {
#ifdef SND_LITTLE_ENDIAN
SND_PCM_FORMAT_S16_LE,
SND_PCM_FORMAT_U16_LE,
#endif
#ifdef BUILD_PCM_NONLINEAR
-static snd_pcm_format_t nonlinear_preferred_formats[] = {
+static const snd_pcm_format_t nonlinear_preferred_formats[] = {
#ifdef BUILD_PCM_PLUGIN_MULAW
SND_PCM_FORMAT_MU_LAW,
#endif
#endif
#ifdef BUILD_PCM_PLUGIN_LFLOAT
-static snd_pcm_format_t float_preferred_formats[] = {
+static const snd_pcm_format_t float_preferred_formats[] = {
#ifdef SND_LITTLE_ENDIAN
SND_PCM_FORMAT_FLOAT_LE,
SND_PCM_FORMAT_FLOAT64_LE,
};
#endif
-static char linear_format_widths[32] = {
+static const char linear_format_widths[32] = {
0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 1,
0, 1, 0, 1, 0, 0, 0, 1,
return 1;
}
+#ifdef BUILD_PCM_PLUGIN_MMAP_EMUL
+static int snd_pcm_plug_change_mmap(snd_pcm_t *pcm, snd_pcm_t **new,
+ snd_pcm_plug_params_t *clt,
+ snd_pcm_plug_params_t *slv)
+{
+ snd_pcm_plug_t *plug = pcm->private_data;
+ int err;
+
+ if (clt->access == slv->access)
+ return 0;
+
+ switch (slv->access) {
+ case SND_PCM_ACCESS_MMAP_INTERLEAVED:
+ case SND_PCM_ACCESS_MMAP_NONINTERLEAVED:
+ case SND_PCM_ACCESS_MMAP_COMPLEX:
+ return 0;
+ default:
+ break;
+ }
+
+ err = __snd_pcm_mmap_emul_open(new, NULL, plug->gen.slave,
+ plug->gen.slave != plug->req_slave);
+ if (err < 0)
+ return err;
+ slv->access = clt->access;
+ return 1;
+}
+#endif
+
static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
snd_pcm_plug_params_t *client,
snd_pcm_plug_params_t *slave)
{
snd_pcm_plug_t *plug = pcm->private_data;
- static int (*funcs[])(snd_pcm_t *_pcm, snd_pcm_t **new, snd_pcm_plug_params_t *s, snd_pcm_plug_params_t *d) = {
+ static int (*const funcs[])(snd_pcm_t *_pcm, snd_pcm_t **new, snd_pcm_plug_params_t *s, snd_pcm_plug_params_t *d) = {
+#ifdef BUILD_PCM_PLUGIN_MMAP_EMUL
+ snd_pcm_plug_change_mmap,
+#endif
snd_pcm_plug_change_format,
#ifdef BUILD_PCM_PLUGIN_ROUTE
snd_pcm_plug_change_channels,
return 0;
}
+static int check_access_change(snd_pcm_hw_params_t *cparams,
+ snd_pcm_hw_params_t *sparams)
+{
+ snd_pcm_access_mask_t *smask;
+#ifdef BUILD_PCM_PLUGIN_MMAP_EMUL
+ const snd_pcm_access_mask_t *cmask;
+ snd_pcm_access_mask_t mask;
+#endif
+
+ smask = (snd_pcm_access_mask_t *)
+ snd_pcm_hw_param_get_mask(sparams,
+ SND_PCM_HW_PARAM_ACCESS);
+ if (snd_pcm_access_mask_test(smask, SND_PCM_ACCESS_MMAP_INTERLEAVED) ||
+ snd_pcm_access_mask_test(smask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED) ||
+ snd_pcm_access_mask_test(smask, SND_PCM_ACCESS_MMAP_COMPLEX))
+ return 0; /* OK, we have mmap support */
+#ifdef BUILD_PCM_PLUGIN_MMAP_EMUL
+ /* no mmap support - we need mmap emulation */
+ cmask = (const snd_pcm_access_mask_t *)
+ snd_pcm_hw_param_get_mask(cparams,
+ SND_PCM_HW_PARAM_ACCESS);
+ snd_mask_none(&mask);
+ if (snd_pcm_access_mask_test(cmask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
+ snd_pcm_access_mask_test(cmask, SND_PCM_ACCESS_MMAP_INTERLEAVED))
+ snd_pcm_access_mask_set(&mask,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+ if (snd_pcm_access_mask_test(cmask, SND_PCM_ACCESS_RW_NONINTERLEAVED) ||
+ snd_pcm_access_mask_test(cmask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED))
+ snd_pcm_access_mask_set(&mask,
+ SND_PCM_ACCESS_RW_NONINTERLEAVED);
+ *smask = mask;
+ return 0;
+#else
+ return -EINVAL;
+#endif
+}
+
static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *sparams)
{
return -EINVAL;
}
- if (snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_FORMAT, sparams) ||
- snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_CHANNELS, sparams) ||
- snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_RATE, sparams) ||
- snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_ACCESS, sparams)) {
- snd_pcm_access_mask_t access_mask = { SND_PCM_ACCBIT_MMAP };
- _snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
- &access_mask);
- if (snd_pcm_access_mask_empty(snd_pcm_hw_param_get_mask(sparams, SND_PCM_HW_PARAM_ACCESS))) {
- SNDERR("Unable to find an usable access for '%s'", pcm->name);
- return -EINVAL;
+ if (snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_ACCESS, sparams)) {
+ err = check_access_change(params, sparams);
+ if (err < 0) {
+ SNDERR("Unable to find an usable access for '%s'",
+ pcm->name);
+ return err;
}
}
+
if ((links & SND_PCM_HW_PARBIT_RATE) ||
snd_pcm_hw_param_always_eq(params, SND_PCM_HW_PARAM_RATE, sparams))
links |= (SND_PCM_HW_PARBIT_PERIOD_SIZE |
snd_pcm_dump(plug->gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_plug_ops = {
+static const snd_pcm_ops_t snd_pcm_plug_ops = {
.close = snd_pcm_plug_close,
.info = snd_pcm_plug_info,
.hw_refine = snd_pcm_plug_hw_refine,
return 0;
}
+static snd_pcm_sframes_t snd_pcm_plugin_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_plugin_t *plugin = pcm->private_data;
snd_pcm_sframes_t n = snd_pcm_mmap_hw_avail(pcm);
snd_pcm_sframes_t sframes;
- if ((snd_pcm_uframes_t)n > frames)
+ if ((snd_pcm_uframes_t)n < frames)
frames = n;
if (frames == 0)
return 0;
- /* FIXME: rate plugin */
if (plugin->slave_frames)
sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
else
frames = plugin->client_frames(pcm, sframes);
snd_pcm_mmap_appl_backward(pcm, (snd_pcm_uframes_t) frames);
snd_atomic_write_end(&plugin->watom);
- return n;
+ return (snd_pcm_sframes_t) frames;
+}
+
+static snd_pcm_sframes_t snd_pcm_plugin_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
}
static snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_plugin_t *plugin = pcm->private_data;
snd_pcm_sframes_t n = snd_pcm_mmap_avail(pcm);
- snd_pcm_uframes_t sframes;
+ snd_pcm_sframes_t sframes;
- if ((snd_pcm_uframes_t)n > frames)
+ if ((snd_pcm_uframes_t)n < frames)
frames = n;
if (frames == 0)
return 0;
- /* FIXME: rate plugin */
if (plugin->slave_frames)
sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
else
sframes = frames;
snd_atomic_write_begin(&plugin->watom);
- sframes = INTERNAL(snd_pcm_forward)(plugin->gen.slave, (snd_pcm_uframes_t) sframes);
- if ((snd_pcm_sframes_t) sframes < 0) {
+ sframes = INTERNAL(snd_pcm_forward)(plugin->gen.slave, sframes);
+ if (sframes < 0) {
snd_atomic_write_end(&plugin->watom);
return sframes;
}
frames = plugin->client_frames(pcm, sframes);
snd_pcm_mmap_appl_forward(pcm, (snd_pcm_uframes_t) frames);
snd_atomic_write_end(&plugin->watom);
- return n;
+ return (snd_pcm_sframes_t) frames;
}
static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
return 0;
}
-snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
+const snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
.status = snd_pcm_plugin_status,
.state = snd_pcm_generic_state,
.hwsync = snd_pcm_generic_hwsync,
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_plugin_rewindable,
.rewind = snd_pcm_plugin_rewind,
+ .forwardable = snd_pcm_plugin_forwardable,
.forward = snd_pcm_plugin_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
void snd_pcm_plugin_init(snd_pcm_plugin_t *plugin);
-extern snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops;
+extern const snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops;
snd_pcm_sframes_t snd_pcm_plugin_undo_read_generic
(snd_pcm_t *pcm,
return snd_pcm_generic_close(pcm);
}
-static snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = {
.status = snd_pcm_rate_status,
.state = snd_pcm_rate_state,
.hwsync = snd_pcm_rate_hwsync,
.poll_revents = snd_pcm_rate_poll_revents,
};
-static snd_pcm_ops_t snd_pcm_rate_ops = {
+static const snd_pcm_ops_t snd_pcm_rate_ops = {
.close = snd_pcm_rate_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_rate_hw_refine,
return strcmp(type, "linear") == 0;
}
-static const char *default_rate_plugins[] = {
+static const char *const default_rate_plugins[] = {
"speexrate", "linear", NULL
};
#ifdef PIC
err = -ENOENT;
if (!converter) {
- const char **types;
+ const char *const *types;
for (types = default_rate_plugins; *types; types++) {
err = rate_open_func(rate, *types);
if (!err) {
free(obj);
}
-static snd_pcm_rate_ops_t linear_ops = {
+static const snd_pcm_rate_ops_t linear_ops = {
.close = linear_close,
.init = linear_init,
.free = linear_free,
#include "plugin_ops.h"
#undef GETS_LABELS
#undef PUT32_LABELS
- static void *zero_labels[3] = {
+ static void *const zero_labels[3] = {
&&zero_int32, &&zero_int64,
#if SND_PCM_PLUGIN_ROUTE_FLOAT
&&zero_float
#endif
};
/* sum_type att */
- static void *add_labels[3 * 2] = {
+ static void *const add_labels[3 * 2] = {
&&add_int32_noatt, &&add_int32_att,
&&add_int64_noatt, &&add_int64_att,
#if SND_PCM_PLUGIN_ROUTE_FLOAT
#endif
};
/* sum_type att shift */
- static void *norm_labels[3 * 2 * 4] = {
+ static void *const norm_labels[3 * 2 * 4] = {
0,
&&norm_int32_8_noatt,
&&norm_int32_16_noatt,
snd_pcm_dump(route->plug.gen.slave, out);
}
-static snd_pcm_ops_t snd_pcm_route_ops = {
+static const snd_pcm_ops_t snd_pcm_route_ops = {
.close = snd_pcm_route_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_route_hw_refine,
return n;
}
+static snd_pcm_sframes_t snd_pcm_share_rewindable(snd_pcm_t *pcm)
+{
+ snd_pcm_share_t *share = pcm->private_data;
+ snd_pcm_share_slave_t *slave = share->slave;
+ snd_pcm_sframes_t ret;
+ Pthread_mutex_lock(&slave->mutex);
+ ret = snd_pcm_rewindable(slave->pcm);
+ Pthread_mutex_unlock(&slave->mutex);
+ return ret;
+}
+
static snd_pcm_sframes_t snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_share_t *share = pcm->private_data;
return n;
}
+static snd_pcm_sframes_t snd_pcm_share_forwardable(snd_pcm_t *pcm)
+{
+ snd_pcm_share_t *share = pcm->private_data;
+ snd_pcm_share_slave_t *slave = share->slave;
+ snd_pcm_sframes_t ret;
+ Pthread_mutex_lock(&slave->mutex);
+ ret = snd_pcm_forwardable(slave->pcm);
+ Pthread_mutex_unlock(&slave->mutex);
+ return ret;
+}
+
static snd_pcm_sframes_t snd_pcm_share_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_share_t *share = pcm->private_data;
snd_pcm_dump(slave->pcm, out);
}
-static snd_pcm_ops_t snd_pcm_share_ops = {
+static const snd_pcm_ops_t snd_pcm_share_ops = {
.close = snd_pcm_share_close,
.info = snd_pcm_share_info,
.hw_refine = snd_pcm_share_hw_refine,
.munmap = snd_pcm_share_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
.status = snd_pcm_share_status,
.state = snd_pcm_share_state,
.hwsync = snd_pcm_share_hwsync,
.writen = snd_pcm_mmap_writen,
.readi = snd_pcm_mmap_readi,
.readn = snd_pcm_mmap_readn,
+ .rewindable = snd_pcm_share_rewindable,
.rewind = snd_pcm_share_rewind,
+ .forwardable = snd_pcm_share_forwardable,
.forward = snd_pcm_share_forward,
.resume = snd_pcm_share_resume,
.avail_update = snd_pcm_share_avail_update,
return snd_pcm_shm_action(pcm);
}
+static snd_pcm_sframes_t snd_pcm_shm_rewindable(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return 0; /* FIX ME */
+}
+
static snd_pcm_sframes_t snd_pcm_shm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_shm_t *shm = pcm->private_data;
return snd_pcm_shm_action(pcm);
}
+static snd_pcm_sframes_t snd_pcm_shm_forwardable(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return 0; /* FIX ME */
+}
+
static snd_pcm_sframes_t snd_pcm_shm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_shm_t *shm = pcm->private_data;
}
}
-static snd_pcm_ops_t snd_pcm_shm_ops = {
+static const snd_pcm_ops_t snd_pcm_shm_ops = {
.close = snd_pcm_shm_close,
.info = snd_pcm_shm_info,
.hw_refine = snd_pcm_shm_hw_refine,
.munmap = snd_pcm_shm_munmap,
};
-static snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
+static const snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
.status = snd_pcm_shm_status,
.state = snd_pcm_shm_state,
.hwsync = snd_pcm_shm_hwsync,
.drop = snd_pcm_shm_drop,
.drain = snd_pcm_shm_drain,
.pause = snd_pcm_shm_pause,
+ .rewindable = snd_pcm_shm_rewindable,
.rewind = snd_pcm_shm_rewind,
+ .forwardable = snd_pcm_shm_forwardable,
.forward = snd_pcm_shm_forward,
.resume = snd_pcm_shm_resume,
.writei = snd_pcm_mmap_writei,
#define ZERO_DB 0.0
#define MAX_DB_UPPER_LIMIT 50
-static unsigned int preset_dB_value[PRESET_RESOLUTION] = {
+static const unsigned int preset_dB_value[PRESET_RESOLUTION] = {
0x00b8, 0x00bd, 0x00c1, 0x00c5, 0x00ca, 0x00cf, 0x00d4, 0x00d9,
0x00de, 0x00e3, 0x00e8, 0x00ed, 0x00f3, 0x00f9, 0x00fe, 0x0104,
0x010a, 0x0111, 0x0117, 0x011e, 0x0124, 0x012b, 0x0132, 0x0139,
return;
}
- vol[0] = svol->dB_value[svol->cur_vol[0]];
- vol[1] = svol->dB_value[svol->cur_vol[1]];
- vol_c = svol->dB_value[(svol->cur_vol[0] + svol->cur_vol[1]) / 2];
+ if (svol->max_val == 1) {
+ vol[0] = svol->cur_vol[0] ? 0xffff : 0;
+ vol[1] = svol->cur_vol[1] ? 0xffff : 0;
+ vol_c = vol[0] | vol[1];
+ } else {
+ vol[0] = svol->dB_value[svol->cur_vol[0]];
+ vol[1] = svol->dB_value[svol->cur_vol[1]];
+ vol_c = svol->dB_value[(svol->cur_vol[0] + svol->cur_vol[1]) / 2];
+ }
switch (svol->sformat) {
case SND_PCM_FORMAT_S16_LE:
case SND_PCM_FORMAT_S16_BE:
return;
}
- vol_scale = svol->dB_value[svol->cur_vol[0]];
+ if (svol->max_val == 1)
+ vol_scale = svol->cur_vol[0] ? 0xffff : 0;
+ else
+ vol_scale = svol->dB_value[svol->cur_vol[0]];
switch (svol->sformat) {
case SND_PCM_FORMAT_S16_LE:
case SND_PCM_FORMAT_S16_BE:
return 0;
}
+/*
+ * refine the access mask
+ */
+static int check_access_mask(snd_pcm_hw_params_t *src,
+ snd_pcm_hw_params_t *dst)
+{
+ const snd_pcm_access_mask_t *mask;
+ snd_pcm_access_mask_t smask;
+
+ mask = snd_pcm_hw_param_get_mask(src, SND_PCM_HW_PARAM_ACCESS);
+ snd_mask_none(&smask);
+ if (snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
+ snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED)) {
+ snd_pcm_access_mask_set(&smask,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+ snd_pcm_access_mask_set(&smask,
+ SND_PCM_ACCESS_MMAP_INTERLEAVED);
+ }
+ if (snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_RW_NONINTERLEAVED) ||
+ snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) {
+ snd_pcm_access_mask_set(&smask,
+ SND_PCM_ACCESS_RW_NONINTERLEAVED);
+ snd_pcm_access_mask_set(&smask,
+ SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
+ }
+ if (snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_MMAP_COMPLEX))
+ snd_pcm_access_mask_set(&smask,
+ SND_PCM_ACCESS_MMAP_COMPLEX);
+
+ return _snd_pcm_hw_param_set_mask(dst, SND_PCM_HW_PARAM_ACCESS, &smask);
+}
+
static int snd_pcm_softvol_hw_refine_schange(snd_pcm_t *pcm,
snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *sparams)
err = _snd_pcm_hw_params_refine(sparams, links, params);
if (err < 0)
return err;
+
+ err = check_access_mask(params, sparams);
+ if (err < 0)
+ return err;
+
return 0;
}
err = _snd_pcm_hw_params_refine(params, links, sparams);
if (err < 0)
return err;
+
+ err = check_access_mask(sparams, params);
+ if (err < 0)
+ return err;
+
return 0;
}
snd_pcm_softvol_t *svol = pcm->private_data;
snd_output_printf(out, "Soft volume PCM\n");
snd_output_printf(out, "Control: %s\n", svol->elem.id.name);
- snd_output_printf(out, "min_dB: %g\n", svol->min_dB);
- snd_output_printf(out, "max_dB: %g\n", svol->max_dB);
- snd_output_printf(out, "resolution: %d\n", svol->max_val + 1);
+ if (svol->max_val == 1)
+ snd_output_printf(out, "boolean\n");
+ else {
+ snd_output_printf(out, "min_dB: %g\n", svol->min_dB);
+ snd_output_printf(out, "max_dB: %g\n", svol->max_dB);
+ snd_output_printf(out, "resolution: %d\n", svol->max_val + 1);
+ }
if (pcm->setup) {
snd_output_printf(out, "Its setup is:\n");
snd_pcm_dump_setup(pcm, out);
int i;
unsigned int def_val;
- err = snd_ctl_elem_add_integer(svol->ctl, &cinfo->id, count, 0, svol->max_val, 0);
+ if (svol->max_val == 1)
+ err = snd_ctl_elem_add_boolean(svol->ctl, &cinfo->id, count);
+ else
+ err = snd_ctl_elem_add_integer(svol->ctl, &cinfo->id, count,
+ 0, svol->max_val, 0);
if (err < 0)
return err;
- add_tlv_info(svol, cinfo);
- /* set zero dB value as default, or max_val if
- there is no 0 dB setting */
- def_val = svol->zero_dB_val ? svol->zero_dB_val : svol->max_val;
+ if (svol->max_val == 1)
+ def_val = 1;
+ else {
+ add_tlv_info(svol, cinfo);
+ /* set zero dB value as default, or max_val if
+ there is no 0 dB setting */
+ def_val = svol->zero_dB_val ? svol->zero_dB_val : svol->max_val;
+ }
for (i = 0; i < count; i++)
svol->elem.value.integer.value[i] = def_val;
return snd_ctl_elem_write(svol->ctl, &svol->elem);
svol->max_val = resolution - 1;
svol->min_dB = min_dB;
svol->max_dB = max_dB;
- if (svol->max_dB == ZERO_DB)
+ if (svol->max_val == 1 || svol->max_dB == ZERO_DB)
svol->zero_dB_val = svol->max_val;
else if (svol->max_dB < 0)
svol->zero_dB_val = 0; /* there is no 0 dB setting */
/* hardware control exists */
return 1; /* notify */
- } else if (cinfo->type != SND_CTL_ELEM_TYPE_INTEGER ||
+ } else if ((cinfo->type != SND_CTL_ELEM_TYPE_INTEGER &&
+ cinfo->type != SND_CTL_ELEM_TYPE_BOOLEAN) ||
cinfo->count != (unsigned int)cchannels ||
cinfo->value.integer.min != 0 ||
cinfo->value.integer.max != resolution - 1) {
SNDERR("Cannot add a control");
return err;
}
- } else {
+ } else if (svol->max_val > 1) {
/* check TLV availability */
unsigned int tlv[4];
err = snd_ctl_elem_tlv_read(svol->ctl, &cinfo->id, tlv, sizeof(tlv));
}
}
+ if (svol->max_val == 1)
+ return 0;
+
+ /* set up dB table */
if (min_dB == PRESET_MIN_DB && max_dB == ZERO_DB && resolution == PRESET_RESOLUTION)
- svol->dB_value = preset_dB_value;
+ svol->dB_value = (unsigned int*)preset_dB_value;
else {
#ifndef HAVE_SOFT_FLOAT
svol->dB_value = calloc(resolution, sizeof(unsigned int));
return 0;
}
-static snd_pcm_ops_t snd_pcm_softvol_ops = {
+static const snd_pcm_ops_t snd_pcm_softvol_ops = {
.close = snd_pcm_softvol_close,
.info = snd_pcm_generic_info,
.hw_refine = snd_pcm_softvol_hw_refine,
[min_dB REAL] # minimal dB value (default: -51.0)
[max_dB REAL] # maximal dB value (default: 0.0)
[resolution INT] # resolution (default: 256)
+ # resolution = 2 means a mute switch
}
\endcode
MAX_DB_UPPER_LIMIT);
return -EINVAL;
}
- if (resolution < 0 || resolution > 1024) {
+ if (resolution <= 1 || resolution > 1024) {
SNDERR("Invalid resolution value %d", resolution);
return -EINVAL;
}
+++ /dev/null
-&_snd_module_pcm_copy,
-&_snd_module_pcm_linear,
-&_snd_module_pcm_plug,
-&_snd_module_pcm_null,
-&_snd_module_pcm_empty,
-&_snd_module_pcm_hooks,
-&_snd_module_pcm_asym,
-&_snd_module_pcm_extplug,
-&_snd_module_pcm_ioplug,
#ifdef CONV_LABELS
/* src_wid src_endswap sign_toggle dst_wid dst_endswap */
-static void *conv_labels[4 * 2 * 2 * 4 * 2] = {
+static void *const conv_labels[4 * 2 * 2 * 4 * 2] = {
&&conv_xxx1_xxx1, /* 8h -> 8h */
&&conv_xxx1_xxx1, /* 8h -> 8s */
&&conv_xxx1_xx10, /* 8h -> 16h */
#ifdef GET16_LABELS
/* src_wid src_endswap sign_toggle */
-static void *get16_labels[4 * 2 * 2 + 4 * 3] = {
+static void *const get16_labels[4 * 2 * 2 + 4 * 3] = {
&&get16_1_10, /* 8h -> 16h */
&&get16_1_90, /* 8h ^> 16h */
&&get16_1_10, /* 8s -> 16h */
#ifdef PUT16_LABELS
/* dst_wid dst_endswap sign_toggle */
-static void *put16_labels[4 * 2 * 2] = {
+static void *const put16_labels[4 * 2 * 2] = {
&&put16_12_1, /* 16h -> 8h */
&&put16_12_9, /* 16h ^> 8h */
&&put16_12_1, /* 16h -> 8s */
#ifdef GET32_LABELS
/* src_wid src_endswap sign_toggle */
-static void *get32_labels[4 * 2 * 2 + 4 * 3] = {
+static void *const get32_labels[4 * 2 * 2 + 4 * 3] = {
&&get32_1_1000, /* 8h -> 32h */
&&get32_1_9000, /* 8h ^> 32h */
&&get32_1_1000, /* 8s -> 32h */
#ifdef PUT32_LABELS
/* dst_wid dst_endswap sign_toggle */
-static void *put32_labels[4 * 2 * 2 + 4 * 3] = {
+static void *const put32_labels[4 * 2 * 2 + 4 * 3] = {
&&put32_1234_1, /* 32h -> 8h */
&&put32_1234_9, /* 32h ^> 8h */
&&put32_1234_1, /* 32h -> 8s */
#ifdef GETU_LABELS
/* width endswap sign_toggle */
-static void *getu_labels[4 * 2 * 2] = {
+static void *const getu_labels[4 * 2 * 2] = {
&&getu_1_1, /* 8h -> 8h */
&&getu_1_9, /* 8h ^> 8h */
&&getu_1_1, /* 8s -> 8h */
#ifdef GETS_LABELS
/* width endswap sign_toggle */
-static void *gets_labels[4 * 2 * 2] = {
+static void *const gets_labels[4 * 2 * 2] = {
&&gets_1_1, /* 8h -> 8h */
&&gets_1_9, /* 8h ^> 8h */
&&gets_1_1, /* 8s -> 8h */
#ifdef PUT_LABELS
/* width endswap sign_toggle */
-static void *put_labels[4 * 2 * 2] = {
+static void *const put_labels[4 * 2 * 2] = {
&&put_1_1, /* 8h -> 8h */
&&put_1_9, /* 8h ^> 8h */
&&put_1_1, /* 8h -> 8s */
#ifdef PUT32F_LABELS
/* type (0 = float, 1 = float64), endswap */
-static void *put32float_labels[2 * 2] = {
+static void *const put32float_labels[2 * 2] = {
&&put32f_1234_1234F, /* 32h -> (float)h */
&&put32f_1234_4321F, /* 32h -> (float)s */
&&put32f_1234_1234D, /* 32h -> (float64)h */
#ifdef GET32F_LABELS
/* type (0 = float, 1 = float64), endswap */
-static void *get32float_labels[2 * 2] = {
+static void *const get32float_labels[2 * 2] = {
&&get32f_1234F_1234, /* (float)h -> 32h */
&&get32f_4321F_1234, /* (float)s -> 32h */
&&get32f_1234D_1234, /* (float64)h -> 32h */
}
/* src_wid dst_sign dst_wid dst_end */
-static void *norms_labels[4 * 2 * 4 * 2] = {
+static void *const norms_labels[4 * 2 * 4 * 2] = {
&&norms_8_u8, /* s8 -> u8 */
&&norms_8_u8, /* s8 -> u8 */
&&norms_8_u16h, /* s8 -> u16h */
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = src/pcm/scopes
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
AM_CFLAGS = -g -O2 -W -Wall
pkglib_LTLIBRARIES = scope-level.la
scope_level_la_SOURCES = level.c
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@BUILD_SEQ_TRUE@am__append_1 = rawmidi_virt.c
subdir = src/rawmidi
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_LTLIBRARIES = librawmidi.la
librawmidi_la_SOURCES = rawmidi.c rawmidi_hw.c rawmidi_symbols.c \
$(am__append_1)
int snd_rawmidi_conf_generic_id(const char *id)
{
- static const char *ids[] = {
+ static const char ids[][8] = {
"comment",
"type",
"hint",
return result;
}
-snd_rawmidi_ops_t snd_rawmidi_hw_ops = {
+static const snd_rawmidi_ops_t snd_rawmidi_hw_ops = {
.close = snd_rawmidi_hw_close,
.nonblock = snd_rawmidi_hw_nonblock,
.info = snd_rawmidi_hw_info,
snd_rawmidi_stream_t stream;
int mode;
int poll_fd;
- snd_rawmidi_ops_t *ops;
+ const snd_rawmidi_ops_t *ops;
void *private_data;
size_t buffer_size;
size_t avail_min;
return result;
}
-snd_rawmidi_ops_t snd_rawmidi_virtual_ops = {
+static const snd_rawmidi_ops_t snd_rawmidi_virtual_ops = {
.close = snd_rawmidi_virtual_close,
.nonblock = snd_rawmidi_virtual_nonblock,
.info = snd_rawmidi_virtual_info,
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
@KEEP_OLD_SYMBOLS_TRUE@am__append_1 = seq_old.c
subdir = src/seq
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_LTLIBRARIES = libseq.la
libseq_la_SOURCES = seq_hw.c seq.c seq_event.c seqmid.c \
seq_midi_event.c seq_symbols.c $(am__append_1)
}
/**
- * \brief Get the event filter bitmap of a client_info container
+ * \brief (DEPRECATED) Get the event filter bitmap of a client_info container
* \param info client_info container
* \return NULL if no event filter, or pointer to event filter bitmap
*
- * \sa snd_seq_get_client_info(), snd_seq_client_info_set_event_filter()
+ * Use #snd_seq_client_info_event_filter_check() instead.
+ *
+ * \sa snd_seq_client_info_event_filter_add(),
+ * snd_seq_client_info_event_filter_del(),
+ * snd_seq_client_info_event_filter_check(),
+ * snd_seq_client_info_event_filter_clear(),
+ * snd_seq_get_client_info()
*/
const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
{
}
/**
+ * \brief Disable event filtering of a client_info container
+ * \param info client_info container
+ *
+ * Remove all event types added with #snd_seq_client_info_event_filter_add and clear
+ * the event filtering flag of this client_info container.
+ *
+ * \sa snd_seq_client_info_event_filter_add(),
+ * snd_seq_client_info_event_filter_del(),
+ * snd_seq_client_info_event_filter_check(),
+ * snd_seq_get_client_info(),
+ * snd_seq_set_client_info()
+ */
+void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info)
+{
+ assert(info);
+ info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
+ memset(info->event_filter, 0, sizeof(info->event_filter));
+}
+
+/**
+ * \brief Add an event type to the event filtering of a client_info container
+ * \param info client_info container
+ * \param event_type event type to be added
+ *
+ * Set the event filtering flag of this client_info and add the specified event type to the
+ * filter bitmap of this client_info container.
+ *
+ * \sa snd_seq_get_client_info(),
+ * snd_seq_set_client_info(),
+ * snd_seq_client_info_event_filter_del(),
+ * snd_seq_client_info_event_filter_check(),
+ * snd_seq_client_info_event_filter_clear()
+ */
+void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type)
+{
+ assert(info);
+ info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
+ snd_seq_set_bit(event_type, info->event_filter);
+}
+
+/**
+ * \brief Remove an event type from the event filtering of a client_info container
+ * \param info client_info container
+ * \param event_type event type to be removed
+ *
+ * Removes the specified event from the filter bitmap of this client_info container. It will
+ * not clear the event filtering flag, use #snd_seq_client_info_event_filter_clear instead.
+ *
+ * \sa snd_seq_get_client_info(),
+ * snd_seq_set_client_info(),
+ * snd_seq_client_info_event_filter_add(),
+ * snd_seq_client_info_event_filter_check(),
+ * snd_seq_client_info_event_filter_clear()
+ */
+void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type)
+{
+ assert(info);
+ snd_seq_unset_bit(event_type, info->event_filter);
+}
+
+/**
+ * \brief Check if an event type is present in the event filtering of a client_info container
+ * \param info client_info container
+ * \param event_type event type to be checked
+ * \return 1 if the event type is present, 0 otherwise
+ *
+ * Test if the event type is in the filter bitamp of this client_info container.
+ *
+ * \sa snd_seq_get_client_info(),
+ * snd_seq_set_client_info(),
+ * snd_seq_client_info_event_filter_add(),
+ * snd_seq_client_info_event_filter_del(),
+ * snd_seq_client_info_event_filter_clear()
+ */
+int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type)
+{
+ assert(info);
+ return snd_seq_get_bit(event_type, info->event_filter);
+}
+
+/**
* \brief Get the number of opened ports of a client_info container
* \param info client_info container
* \return number of opened ports
}
/**
- * \brief Set the event filter bitmap of a client_info container
+ * \brief (DEPRECATED) Set the event filter bitmap of a client_info container
* \param info client_info container
- * \param filter event filter bitmap
+ * \param filter event filter bitmap, pass NULL for no event filtering
+ *
+ * Use #snd_seq_client_info_event_filter_add instead.
*
- * \sa snd_seq_get_client_info(), snd_seq_client_info_get_event_filger(),
- * snd_seq_set_client_event_filter()
+ * \sa snd_seq_client_info_event_filter_add(),
+ * snd_seq_client_info_event_filter_del(),
+ * snd_seq_client_info_event_filter_check(),
+ * snd_seq_client_info_event_filter_clear(),
+ * snd_seq_set_client_info()
*/
void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
{
}
/**
+ * \brief unset a bit flag
+ */
+void snd_seq_unset_bit(int nr, void *array)
+{
+ ((unsigned int *)array)[nr >> 5] &= ~(1UL << (nr & 31));
+}
+
+/**
* \brief change a bit flag
*/
int snd_seq_change_bit(int nr, void *array)
int result;
result = ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
- ((unsigned int *)array)[nr >> 5] |= 1UL << (nr & 31);
+ ((unsigned int *)array)[nr >> 5] ^= 1UL << (nr & 31);
return result;
}
return 0;
}
-snd_seq_ops_t snd_seq_hw_ops = {
+static const snd_seq_ops_t snd_seq_hw_ops = {
.close = snd_seq_hw_close,
.nonblock = snd_seq_hw_nonblock,
.system_info = snd_seq_hw_system_info,
int mode;
int poll_fd;
void *dl_handle;
- snd_seq_ops_t *ops;
+ const snd_seq_ops_t *ops;
void *private_data;
int client; /* client number */
/* buffers */
* event list
*/
#ifndef DOC_HIDDEN
-static struct status_event_list_t {
+static const struct status_event_list_t {
int event;
int qlen;
event_encode_t encode;
static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, const snd_seq_event_t *ev);
static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev);
-static struct extra_event_list_t {
+static const struct extra_event_list_t {
int event;
int (*decode)(snd_midi_event_t *dev, unsigned char *buf, int len, const snd_seq_event_t *ev);
} extra_event[] = {
static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev)
{
unsigned char cmd;
- char *cbytes;
- static char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
+ const char *cbytes;
+ static const char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
MIDI_CTL_NONREG_PARM_NUM_LSB,
MIDI_CTL_MSB_DATA_ENTRY,
MIDI_CTL_LSB_DATA_ENTRY };
- static char cbytes_rpn[4] = { MIDI_CTL_REGIST_PARM_NUM_MSB,
+ static const char cbytes_rpn[4] = { MIDI_CTL_REGIST_PARM_NUM_MSB,
MIDI_CTL_REGIST_PARM_NUM_LSB,
MIDI_CTL_MSB_DATA_ENTRY,
MIDI_CTL_LSB_DATA_ENTRY };
if ((err = snd_seq_get_client_info(seq, &info)) < 0)
return err;
- info.filter |= SNDRV_SEQ_FILTER_USE_EVENT;
- snd_seq_set_bit(event_type, info.event_filter);
+ snd_seq_client_info_event_filter_add(&info, event_type);
return snd_seq_set_client_info(seq, &info);
}
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = src/timer
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
EXTRA_LTLIBRARIES = libtimer.la
libtimer_la_SOURCES = timer.c timer_hw.c timer_query.c timer_query_hw.c \
timer_symbols.c
return result;
}
-static snd_timer_ops_t snd_timer_hw_ops = {
+static const snd_timer_ops_t snd_timer_hw_ops = {
.close = snd_timer_hw_close,
.nonblock = snd_timer_hw_nonblock,
.async = snd_timer_hw_async,
snd_timer_type_t type;
int mode;
int poll_fd;
- snd_timer_ops_t *ops;
+ const snd_timer_ops_t *ops;
void *private_data;
struct list_head async_handlers;
};
return 0;
}
-static snd_timer_query_ops_t snd_timer_query_hw_ops = {
+static const snd_timer_query_ops_t snd_timer_query_hw_ops = {
.close = snd_timer_query_hw_close,
.next_device = snd_timer_query_hw_next_device,
.info = snd_timer_query_hw_info,
check_PROGRAMS=control pcm pcm_min latency seq \
playmidi1 timer rawmidi midiloop \
- oldapi queue_timer namehint
+ oldapi queue_timer namehint client_event_filter
control_LDADD=../src/libasound.la
pcm_LDADD=../src/libasound.la
oldapi_LDADD=../src/libasound.la
queue_timer_LDADD=../src/libasound.la
namehint_LDADD=../src/libasound.la
+client_event_filter_LDADD=../src/libasound.la
code_CFLAGS=-Wall -pipe -g -O2
INCLUDES=-I$(top_srcdir)/include
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
check_PROGRAMS = control$(EXEEXT) pcm$(EXEEXT) pcm_min$(EXEEXT) \
latency$(EXEEXT) seq$(EXEEXT) playmidi1$(EXEEXT) \
timer$(EXEEXT) rawmidi$(EXEEXT) midiloop$(EXEEXT) \
- oldapi$(EXEEXT) queue_timer$(EXEEXT) namehint$(EXEEXT)
+ oldapi$(EXEEXT) queue_timer$(EXEEXT) namehint$(EXEEXT) \
+ client_event_filter$(EXEEXT)
subdir = test
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES =
+client_event_filter_SOURCES = client_event_filter.c
+client_event_filter_OBJECTS = client_event_filter.$(OBJEXT)
+client_event_filter_DEPENDENCIES = ../src/libasound.la
control_SOURCES = control.c
control_OBJECTS = control.$(OBJEXT)
control_DEPENDENCIES = ../src/libasound.la
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = control.c latency.c midiloop.c namehint.c oldapi.c pcm.c \
- pcm_min.c playmidi1.c queue_timer.c rawmidi.c seq.c timer.c
-DIST_SOURCES = control.c latency.c midiloop.c namehint.c oldapi.c \
- pcm.c pcm_min.c playmidi1.c queue_timer.c rawmidi.c seq.c \
- timer.c
+SOURCES = client_event_filter.c control.c latency.c midiloop.c \
+ namehint.c oldapi.c pcm.c pcm_min.c playmidi1.c queue_timer.c \
+ rawmidi.c seq.c timer.c
+DIST_SOURCES = client_event_filter.c control.c latency.c midiloop.c \
+ namehint.c oldapi.c pcm.c pcm_min.c playmidi1.c queue_timer.c \
+ rawmidi.c seq.c timer.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
control_LDADD = ../src/libasound.la
pcm_LDADD = ../src/libasound.la
pcm_min_LDADD = ../src/libasound.la
oldapi_LDADD = ../src/libasound.la
queue_timer_LDADD = ../src/libasound.la
namehint_LDADD = ../src/libasound.la
+client_event_filter_LDADD = ../src/libasound.la
code_CFLAGS = -Wall -pipe -g -O2
INCLUDES = -I$(top_srcdir)/include
AM_CFLAGS = -Wall -pipe -g
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
+client_event_filter$(EXEEXT): $(client_event_filter_OBJECTS) $(client_event_filter_DEPENDENCIES)
+ @rm -f client_event_filter$(EXEEXT)
+ $(LINK) $(client_event_filter_LDFLAGS) $(client_event_filter_OBJECTS) $(client_event_filter_LDADD) $(LIBS)
control$(EXEEXT): $(control_OBJECTS) $(control_DEPENDENCIES)
@rm -f control$(EXEEXT)
$(LINK) $(control_LDFLAGS) $(control_OBJECTS) $(control_LDADD) $(LIBS)
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_event_filter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/latency.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midiloop.Po@am__quote@
--- /dev/null
+#include <alsa/asoundlib.h>
+
+void dump_event_filter(snd_seq_client_info_t *client_info) {
+ int i, b;
+
+ for (i = 0; i <= 255;) {
+ b = snd_seq_client_info_event_filter_check(client_info, i);
+ i++;
+ printf("%c%s%s", (b ? 'X' : '.'),
+ (i % 8 == 0 ? " " : ""),
+ (i % 32 == 0 ? "\n" : ""));
+ }
+ printf("\n");
+}
+
+int main(void) {
+ snd_seq_client_info_t *client_info;
+
+ snd_seq_client_info_alloca(&client_info);
+
+ printf("first client_info_event_filter :\n");
+ dump_event_filter(client_info);
+
+ snd_seq_client_info_event_filter_add(client_info, SND_SEQ_EVENT_NOTEON);
+ printf("after snd_seq_client_info_event_filter_add(client_info, SND_SEQ_EVENT_NOTEON);\n");
+ dump_event_filter(client_info);
+
+ snd_seq_client_info_event_filter_add(client_info, SND_SEQ_EVENT_PGMCHANGE);
+ printf("after snd_seq_client_info_event_filter_add(client_info, SND_SEQ_EVENT_PGMCHANGE);\n");
+ dump_event_filter(client_info);
+
+ snd_seq_client_info_event_filter_del(client_info, SND_SEQ_EVENT_NOTEON);
+ printf("after snd_seq_client_info_event_filter_del(client_info, SND_SEQ_EVENT_NOTEON);\n");
+ dump_event_filter(client_info);
+
+ snd_seq_client_info_event_filter_clear(client_info);
+ printf("after snd_seq_client_info_event_filter_clear(client_info);\n");
+ dump_event_filter(client_info);
+
+ snd_seq_client_info_event_filter_add(client_info, SND_SEQ_EVENT_NOTEON);
+ printf("after snd_seq_client_info_event_filter_add(client_info, SND_SEQ_EVENT_NOTEON);\n");
+ dump_event_filter(client_info);
+
+ return 0;
+}
+
static unsigned int buffer_time = 500000; /* ring buffer length in us */
static unsigned int period_time = 100000; /* period time in us */
static double freq = 440; /* sinusoidal wave frequency in Hz */
-static int verbose = 0; /* verbose flag */
+static int verbose = 0; /* verbose flag */
static int resample = 1; /* enable alsa-lib resampling */
+static int period_event = 0; /* produce poll event after each period */
static snd_pcm_sframes_t buffer_size;
static snd_pcm_sframes_t period_size;
unsigned char *samples[channels], *tmp;
int steps[channels];
unsigned int chn, byte;
- int ires;
+ union {
+ int i;
+ unsigned char c[4];
+ } ires;
unsigned int maxval = (1 << (snd_pcm_format_width(format) - 1)) - 1;
int bps = snd_pcm_format_width(format) / 8; /* bytes per sample */
/* fill the channel areas */
while (count-- > 0) {
res = sin(phase) * maxval;
- ires = res;
- tmp = (unsigned char *)(&ires);
+ ires.i = res;
+ tmp = ires.c;
for (chn = 0; chn < channels; chn++) {
for (byte = 0; byte < (unsigned int)bps; byte++)
*(samples[chn] + byte) = tmp[byte];
return err;
}
/* allow the transfer when at least period_size samples can be processed */
- err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size);
+ /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
+ err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_event ? buffer_size : period_size);
if (err < 0) {
printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
return err;
}
+ /* enable period events when requested */
+ if (period_event) {
+ err = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
+ if (err < 0) {
+ printf("Unable to set period event: %s\n", snd_strerror(err));
+ return err;
+ }
+ }
/* write the parameters to the playback device */
err = snd_pcm_sw_params(handle, swparams);
if (err < 0) {
static int xrun_recovery(snd_pcm_t *handle, int err)
{
+ if (verbose)
+ printf("stream recovery\n");
if (err == -EPIPE) { /* under-run */
err = snd_pcm_prepare(handle);
if (err < 0)
generate_sine(areas, 0, period_size, &data->phase);
err = snd_pcm_writei(handle, samples, period_size);
if (err < 0) {
- printf("Initial write error: %s\n", snd_strerror(err));
+ printf("Write error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
if (err != period_size) {
- printf("Initial write error: written %i expected %li\n", err, period_size);
+ printf("Write error: written %i expected %li\n", err, period_size);
exit(EXIT_FAILURE);
}
avail = snd_pcm_avail_update(handle);
exit(EXIT_FAILURE);
}
}
- err = snd_pcm_start(handle);
- if (err < 0) {
- printf("Start error: %s\n", snd_strerror(err));
- exit(EXIT_FAILURE);
+ if (snd_pcm_state(handle) == SND_PCM_STATE_PREPARED) {
+ err = snd_pcm_start(handle);
+ if (err < 0) {
+ printf("Start error: %s\n", snd_strerror(err));
+ exit(EXIT_FAILURE);
+ }
}
/* because all other work is done in the signal handler,
"-m,--method transfer method\n"
"-o,--format sample format\n"
"-v,--verbose show the PCM setup parameters\n"
+"-n,--noresample do not resample\n"
+"-e,--pevent enable poll event after each period\n"
"\n");
printf("Recognized sample formats are:");
for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
{"format", 1, NULL, 'o'},
{"verbose", 1, NULL, 'v'},
{"noresample", 1, NULL, 'n'},
+ {"pevent", 1, NULL, 'e'},
{NULL, 0, NULL, 0},
};
snd_pcm_t *handle;
morehelp = 0;
while (1) {
int c;
- if ((c = getopt_long(argc, argv, "hD:r:c:f:b:p:m:o:vn", long_option, NULL)) < 0)
+ if ((c = getopt_long(argc, argv, "hD:r:c:f:b:p:m:o:vne", long_option, NULL)) < 0)
break;
switch (c) {
case 'h':
case 'n':
resample = 0;
break;
+ case 'e':
+ period_event = 1;
+ break;
}
}
if (verbose > 0)
snd_pcm_dump(handle, output);
- samples = malloc((period_size * channels * snd_pcm_format_width(format)) / 8);
+ samples = malloc((period_size * channels * snd_pcm_format_physical_width(format)) / 8);
if (samples == NULL) {
printf("No enough memory\n");
exit(EXIT_FAILURE);
}
for (chn = 0; chn < channels; chn++) {
areas[chn].addr = samples;
- areas[chn].first = chn * snd_pcm_format_width(format);
- areas[chn].step = channels * snd_pcm_format_width(format);
+ areas[chn].first = chn * snd_pcm_format_physical_width(format);
+ areas[chn].step = channels * snd_pcm_format_physical_width(format);
}
err = transfer_methods[method].transfer_loop(handle, samples, areas);
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
subdir = utils
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/alsa-lib.spec.in $(srcdir)/alsa.pc.in
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
@INSTALL_M4_TRUE@aclocaldir = $(datadir)/aclocal
@INSTALL_M4_TRUE@aclocal_DATA = alsa.m4
EXTRA_DIST = alsa.m4 buildrpm alsa.pc.in