Compare commits

...
Sign in to create a new pull request.
Author SHA1 Message Date
Ross Bencina
66bda13f84 Ports Portaudio WMME device timeout system to MacOsX CoreAudio in order to
avoid deadlock when a device is unplugged.
Vincent Lucas committed on Jan 10, 2013
2a20693 from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:53:30 +10:00
Ross Bencina
ab8b64023c Commits the C source code of a refining of the automatic audio device
selection to pick up devices from the same hardware.
lyubomir committed on Dec 19, 2012
6441b56 from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:51:44 +10:00
Ross Bencina
c534056a7b Fixes freezes in Pa_ReadStream, Pa_StopStream and Pa_WriteStream and
incorrect causes of paInvalidChannelCount errors in PortAudio on
Windows/WMME. Mitigates an issue with hightened CPU usage (on all
supported operating systems) related to hotplug.
lyubomir committed on Dec 4, 2012
a45b993 from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:49:43 +10:00
Ross Bencina
6c6269425f - Fixes multiple crashes in PortAudio.
- Removes the DirectSound support from PortAudio in order to prevent
  issues with bad audio quality.
  - Attempts to recognize USB PortAudio devices on Windows as such,
    ignores the virtual Microsoft Sound Mapper devices to avoid user
    confusion. Contributed by Vincent Lucas.
    lyubomir committed on Nov 15, 2012
    a93910c from
    https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:46:54 +10:00
Ross Bencina
15d77417bf Adds hotplug to portaudio wmme host api, also fixes a NPE that can prevent
device change updates.
damencho committed on Nov 6, 2012
5ca6fed from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:44:31 +10:00
Ross Bencina
0a7b80cfce Adds device uid for wmme and dsound devices.
damencho committed on Nov 3, 2012
7e70e94 from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:36:13 +10:00
Ross Bencina
e7a274942b Improves device selection via portaudio for MacOSX (hostapi coreaudio):
adds the possibility to get the device transport type (USB, bluetooth,
etc.) and an unique identifier. Corrects problems when: loading the same
device twice (for the moment only for the same hostapi), a new plugged
device is selected during a call or if the selected device is unchanged.
Vincent Lucas committed on Oct 29, 2012
26848f0 from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:34:22 +10:00
Ross Bencina
b77a1f828c Adds portaudio sources [adds hotplug support for pa_linux_alsa,
pa_mac_core, plus some other tweaks]
damencho committed on Mar 29, 2012
d2076b1 from https://github.com/jitsi/libsrc/commits/master/portaudio.zip
2016-09-03 22:29:58 +10:00
Ross Bencina
d13fcd8ea9 Roll-up of SVN hotplug branch at most recent revision (r1677), based at the same point in the master revision history as it was originally applied. 2016-09-03 22:22:52 +10:00
39 changed files with 3567 additions and 1724 deletions

View file

@ -107,6 +107,7 @@ TESTS = \
bin/patest_wire \ bin/patest_wire \
bin/patest_write_sine \ bin/patest_write_sine \
bin/patest_write_sine_nonint \ bin/patest_write_sine_nonint \
bin/patest_update_available_device_list \
bin/pa_devs \ bin/pa_devs \
bin/pa_fuzz \ bin/pa_fuzz \
bin/pa_minlat bin/pa_minlat
@ -146,6 +147,7 @@ SRC_DIRS = \
src/hostapi/wdmks \ src/hostapi/wdmks \
src/hostapi/wmme \ src/hostapi/wmme \
src/os/unix \ src/os/unix \
src/os/mac_osx \
src/os/win src/os/win
SUBDIRS = SUBDIRS =

492
aclocal.m4 vendored
View file

@ -680,7 +680,7 @@ _LT_CONFIG_SAVE_COMMANDS([
# commands through without removal of \ escapes. # commands through without removal of \ escapes.
if test -n "${ZSH_VERSION+set}" ; then if test -n "${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST setopt NO_GLOB_SUBST
fi fi
cfgfile="${ofile}T" cfgfile="${ofile}T"
trap "$RM \"$cfgfile\"; exit 1" 1 2 15 trap "$RM \"$cfgfile\"; exit 1" 1 2 15
@ -1101,104 +1101,104 @@ fi
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
if test -z "$lt_ECHO"; then if test -z "$lt_ECHO"; then
if test "X${echo_test_string+set}" != Xset; then if test "X${echo_test_string+set}" != Xset; then
# find a string as large as possible, as long as the shell can cope with it # find a string as large as possible, as long as the shell can cope with it
for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
# expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
if { echo_test_string=`eval $cmd`; } 2>/dev/null && if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
{ test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
then then
break break
fi fi
done done
fi fi
if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
: :
else else
# The Solaris, AIX, and Digital Unix default echo programs unquote # The Solaris, AIX, and Digital Unix default echo programs unquote
# backslashes. This makes it impossible to quote backslashes using # backslashes. This makes it impossible to quote backslashes using
# echo "$something" | sed 's/\\/\\\\/g' # echo "$something" | sed 's/\\/\\\\/g'
# #
# So, first we look for a working echo in the user's PATH. # So, first we look for a working echo in the user's PATH.
lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for dir in $PATH /usr/ucb; do for dir in $PATH /usr/ucb; do
IFS="$lt_save_ifs"
if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
ECHO="$dir/echo"
break
fi
done
IFS="$lt_save_ifs" IFS="$lt_save_ifs"
if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
ECHO="$dir/echo"
break
fi
done
IFS="$lt_save_ifs"
if test "X$ECHO" = Xecho; then if test "X$ECHO" = Xecho; then
# We didn't find a better echo, so look for alternatives. # We didn't find a better echo, so look for alternatives.
if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
# This shell has a builtin print -r that does the trick. # This shell has a builtin print -r that does the trick.
ECHO='print -r' ECHO='print -r'
elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
test "X$CONFIG_SHELL" != X/bin/ksh; then test "X$CONFIG_SHELL" != X/bin/ksh; then
# If we have ksh, try running configure again with it. # If we have ksh, try running configure again with it.
ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
export ORIGINAL_CONFIG_SHELL export ORIGINAL_CONFIG_SHELL
CONFIG_SHELL=/bin/ksh CONFIG_SHELL=/bin/ksh
export CONFIG_SHELL export CONFIG_SHELL
exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
else else
# Try using printf. # Try using printf.
ECHO='printf %s\n' ECHO='printf %s\n'
if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
# Cool, printf works
:
elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
test "X$echo_testing_string" = 'X\t' &&
echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
# Cool, printf works CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
: export CONFIG_SHELL
elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && SHELL="$CONFIG_SHELL"
test "X$echo_testing_string" = 'X\t' && export SHELL
echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
export CONFIG_SHELL
SHELL="$CONFIG_SHELL"
export SHELL
ECHO="$CONFIG_SHELL [$]0 --fallback-echo" ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
test "X$echo_testing_string" = 'X\t' && test "X$echo_testing_string" = 'X\t' &&
echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
ECHO="$CONFIG_SHELL [$]0 --fallback-echo" ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
else else
# maybe with a smaller string... # maybe with a smaller string...
prev=: prev=:
for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
then then
break break
fi
prev="$cmd"
done
if test "$prev" != 'sed 50q "[$]0"'; then
echo_test_string=`eval $prev`
export echo_test_string
exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
else
# Oops. We lost completely, so just stick with echo.
ECHO=echo
fi fi
fi prev="$cmd"
done
if test "$prev" != 'sed 50q "[$]0"'; then
echo_test_string=`eval $prev`
export echo_test_string
exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
else
# Oops. We lost completely, so just stick with echo.
ECHO=echo
fi
fi fi
fi fi
fi fi
fi fi
fi
# Copy echo and quote the copy suitably for passing to libtool from # Copy echo and quote the copy suitably for passing to libtool from
# the Makefile, instead of quoting the original, which is used later. # the Makefile, instead of quoting the original, which is used later.
@ -1220,7 +1220,7 @@ _LT_DECL([], [ECHO], [1],
m4_defun([_LT_ENABLE_LOCK], m4_defun([_LT_ENABLE_LOCK],
[AC_ARG_ENABLE([libtool-lock], [AC_ARG_ENABLE([libtool-lock],
[AS_HELP_STRING([--disable-libtool-lock], [AS_HELP_STRING([--disable-libtool-lock],
[avoid locking (might break parallel builds)])]) [avoid locking (might break parallel builds)])])
test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good # Some flags need to be propagated to the compiler or linker for good
@ -1231,12 +1231,12 @@ ia64-*-hpux*)
echo 'int i;' > conftest.$ac_ext echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.$ac_objext` in case `/usr/bin/file conftest.$ac_objext` in
*ELF-32*) *ELF-32*)
HPUX_IA64_MODE="32" HPUX_IA64_MODE="32"
;; ;;
*ELF-64*) *ELF-64*)
HPUX_IA64_MODE="64" HPUX_IA64_MODE="64"
;; ;;
esac esac
fi fi
rm -rf conftest* rm -rf conftest*
@ -1245,31 +1245,31 @@ ia64-*-hpux*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '[#]line __oline__ "configure"' > conftest.$ac_ext echo '[#]line __oline__ "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
if test "$lt_cv_prog_gnu_ld" = yes; then if test "$lt_cv_prog_gnu_ld" = yes; then
case `/usr/bin/file conftest.$ac_objext` in case `/usr/bin/file conftest.$ac_objext` in
*32-bit*) *32-bit*)
LD="${LD-ld} -melf32bsmip" LD="${LD-ld} -melf32bsmip"
;; ;;
*N32*) *N32*)
LD="${LD-ld} -melf32bmipn32" LD="${LD-ld} -melf32bmipn32"
;; ;;
*64-bit*) *64-bit*)
LD="${LD-ld} -melf64bmip" LD="${LD-ld} -melf64bmip"
;; ;;
esac esac
else else
case `/usr/bin/file conftest.$ac_objext` in case `/usr/bin/file conftest.$ac_objext` in
*32-bit*) *32-bit*)
LD="${LD-ld} -32" LD="${LD-ld} -32"
;; ;;
*N32*) *N32*)
LD="${LD-ld} -n32" LD="${LD-ld} -n32"
;; ;;
*64-bit*) *64-bit*)
LD="${LD-ld} -64" LD="${LD-ld} -64"
;; ;;
esac esac
fi fi
fi fi
rm -rf conftest* rm -rf conftest*
;; ;;
@ -1280,44 +1280,44 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
echo 'int i;' > conftest.$ac_ext echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in case `/usr/bin/file conftest.o` in
*32-bit*) *32-bit*)
case $host in case $host in
x86_64-*kfreebsd*-gnu) x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_i386_fbsd" LD="${LD-ld} -m elf_i386_fbsd"
;; ;;
x86_64-*linux*) x86_64-*linux*)
LD="${LD-ld} -m elf_i386" LD="${LD-ld} -m elf_i386"
;; ;;
ppc64-*linux*|powerpc64-*linux*) ppc64-*linux*|powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux" LD="${LD-ld} -m elf32ppclinux"
;; ;;
s390x-*linux*) s390x-*linux*)
LD="${LD-ld} -m elf_s390" LD="${LD-ld} -m elf_s390"
;; ;;
sparc64-*linux*) sparc64-*linux*)
LD="${LD-ld} -m elf32_sparc" LD="${LD-ld} -m elf32_sparc"
;; ;;
esac esac
;; ;;
*64-bit*) *64-bit*)
case $host in case $host in
x86_64-*kfreebsd*-gnu) x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_x86_64_fbsd" LD="${LD-ld} -m elf_x86_64_fbsd"
;; ;;
x86_64-*linux*) x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64" LD="${LD-ld} -m elf_x86_64"
;; ;;
ppc*-*linux*|powerpc*-*linux*) ppc*-*linux*|powerpc*-*linux*)
LD="${LD-ld} -m elf64ppc" LD="${LD-ld} -m elf64ppc"
;; ;;
s390*-*linux*|s390*-*tpf*) s390*-*linux*|s390*-*tpf*)
LD="${LD-ld} -m elf64_s390" LD="${LD-ld} -m elf64_s390"
;; ;;
sparc*-*linux*) sparc*-*linux*)
LD="${LD-ld} -m elf64_sparc" LD="${LD-ld} -m elf64_sparc"
;; ;;
esac esac
;; ;;
esac esac
fi fi
rm -rf conftest* rm -rf conftest*
@ -1454,7 +1454,7 @@ dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
# [ACTION-SUCCESS], [ACTION-FAILURE]) # [ACTION-SUCCESS], [ACTION-FAILURE])
# ---------------------------------------------------- # ----------------------------------------------------
# Check whether the given linker option works # Check whether the given linker option works
AC_DEFUN([_LT_LINKER_OPTION], AC_DEFUN([_LT_LINKER_OPTION],
@ -1578,7 +1578,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
sysv5* | sco5v6* | sysv4.2uw2*) sysv5* | sco5v6* | sysv4.2uw2*)
kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
if test -n "$kargmax"; then if test -n "$kargmax"; then
lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
else else
lt_cv_sys_max_cmd_len=32768 lt_cv_sys_max_cmd_len=32768
fi fi
@ -1595,23 +1595,23 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
teststring=$teststring$teststring teststring=$teststring$teststring
done done
SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
# If test is not a shell built-in, we'll probably end up computing a # If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but # maximum length that is only half of the actual maximum length, but
# we can't tell. # we can't tell.
while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
= "XX$teststring$teststring"; } >/dev/null 2>&1 && = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
test $i != 17 # 1/2 MB should be enough test $i != 17 # 1/2 MB should be enough
do do
i=`expr $i + 1` i=`expr $i + 1`
teststring=$teststring$teststring teststring=$teststring$teststring
done done
# Only check the string length outside the loop. # Only check the string length outside the loop.
lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
teststring= teststring=
# Add a significant safety factor because C++ compilers can tack on # Add a significant safety factor because C++ compilers can tack on
# massive amounts of additional arguments before passing them to the # massive amounts of additional arguments before passing them to the
# linker. It appears as though 1/2 is a usable value. # linker. It appears as though 1/2 is a usable value.
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
fi fi
;; ;;
esac esac
@ -1640,7 +1640,7 @@ m4_defun([_LT_HEADER_DLFCN],
# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
# ---------------------------------------------------------------- # ----------------------------------------------------------------
m4_defun([_LT_TRY_DLOPEN_SELF], m4_defun([_LT_TRY_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl [m4_require([_LT_HEADER_DLFCN])dnl
@ -1748,12 +1748,12 @@ else
mingw* | pw32* | cegcc*) mingw* | pw32* | cegcc*)
lt_cv_dlopen="LoadLibrary" lt_cv_dlopen="LoadLibrary"
lt_cv_dlopen_libs= lt_cv_dlopen_libs=
;; ;;
cygwin*) cygwin*)
lt_cv_dlopen="dlopen" lt_cv_dlopen="dlopen"
lt_cv_dlopen_libs= lt_cv_dlopen_libs=
;; ;;
darwin*) darwin*)
# if libdl is installed we need to link against it # if libdl is installed we need to link against it
@ -1763,7 +1763,7 @@ else
lt_cv_dlopen_libs= lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes lt_cv_dlopen_self=yes
]) ])
;; ;;
*) *)
AC_CHECK_FUNC([shl_load], AC_CHECK_FUNC([shl_load],
@ -1813,7 +1813,7 @@ else
if test "x$lt_cv_dlopen_self" = xyes; then if test "x$lt_cv_dlopen_self" = xyes; then
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
AC_CACHE_CHECK([whether a statically linked program can dlopen itself], AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
lt_cv_dlopen_self_static, [dnl lt_cv_dlopen_self_static, [dnl
_LT_TRY_DLOPEN_SELF( _LT_TRY_DLOPEN_SELF(
lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
@ -2016,17 +2016,17 @@ if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
else else
# FIXME - insert some real tests, host_os isn't really good enough # FIXME - insert some real tests, host_os isn't really good enough
case $host_os in case $host_os in
darwin*) darwin*)
if test -n "$STRIP" ; then if test -n "$STRIP" ; then
striplib="$STRIP -x" striplib="$STRIP -x"
old_striplib="$STRIP -S" old_striplib="$STRIP -S"
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
else else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
fi fi
;; ;;
*) *)
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
;; ;;
esac esac
fi fi
@ -2180,10 +2180,10 @@ amigaos*)
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
;; ;;
m68k) m68k)
library_names_spec='$libname.ixlibrary $libname.a' library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs. # Create ${libname}_ixlibrary.a entries in /sys/libs.
finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;; ;;
esac esac
;; ;;
@ -2218,7 +2218,7 @@ cygwin* | mingw* | pw32* | cegcc*)
library_names_spec='$libname.dll.a' library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds # DLL is installed to $(libdir)/../bin by postinstall_cmds
postinstall_cmds='base_file=`basename \${file}`~ postinstall_cmds='base_file=`basename \${file}`~
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~ dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~ test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname~ $install_prog $dir/$dlname \$dldir/$dlname~
@ -2373,18 +2373,18 @@ hpux9* | hpux10* | hpux11*)
fi fi
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;; ;;
hppa*64*) hppa*64*)
shrext_cmds='.sl' shrext_cmds='.sl'
hardcode_into_libs=yes hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl" dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major' soname_spec='${libname}${release}${shared_ext}$major'
sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;; ;;
*) *)
shrext_cmds='.sl' shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl" dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH shlibpath_var=SHLIB_PATH
@ -2547,8 +2547,8 @@ openbsd*)
need_lib_prefix=no need_lib_prefix=no
# Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
case $host_os in case $host_os in
openbsd3.3 | openbsd3.3.*) need_version=yes ;; openbsd3.3 | openbsd3.3.*) need_version=yes ;;
*) need_version=no ;; *) need_version=no ;;
esac esac
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
@ -2702,10 +2702,10 @@ fi
if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
fi fi
if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
fi fi
_LT_DECL([], [variables_saved_for_relink], [1], _LT_DECL([], [variables_saved_for_relink], [1],
[Variables whose values should be saved in libtool wrapper scripts and [Variables whose values should be saved in libtool wrapper scripts and
@ -3022,8 +3022,8 @@ mingw* | pw32*)
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid' lt_cv_file_magic_cmd='func_win32_libid'
else else
lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
lt_cv_file_magic_cmd='$OBJDUMP -f' lt_cv_file_magic_cmd='$OBJDUMP -f'
fi fi
;; ;;
@ -3230,7 +3230,7 @@ else
: ${lt_cv_path_NM=no} : ${lt_cv_path_NM=no}
fi]) fi])
if test "$lt_cv_path_NM" != "no"; then if test "$lt_cv_path_NM" != "no"; then
NM="$lt_cv_path_NM" NM="$lt_cv_path_NM"
else else
# Didn't find any BSD compatible name lister, look for dumpbin. # Didn't find any BSD compatible name lister, look for dumpbin.
AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
@ -3422,7 +3422,7 @@ for ac_symprfx in "" "_"; do
" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx]" " ' prfx=^$ac_symprfx]"
else else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
fi fi
# Check to see that the pipe works correctly. # Check to see that the pipe works correctly.
@ -3467,7 +3467,7 @@ _LT_EOF
cat <<_LT_EOF >> conftest.$ac_ext cat <<_LT_EOF >> conftest.$ac_ext
/* The mapping between symbol names and symbols. */ /* The mapping between symbol names and symbols. */
const struct { const struct {
const char *name; const char *name;
void *address; void *address;
@ -3579,11 +3579,11 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
m68k) m68k)
# FIXME: we need at least 68020 code to build shared libraries, but # FIXME: we need at least 68020 code to build shared libraries, but
# adding the `-m68020' flag to GCC prevents building anything better, # adding the `-m68020' flag to GCC prevents building anything better,
# like `-m68040'. # like `-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;; ;;
esac esac
;; ;;
@ -3758,11 +3758,11 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
;;
esac
;; ;;
esac esac
;; ;;
esac
;;
lynxos*) lynxos*)
;; ;;
m88k*) m88k*)
@ -3885,11 +3885,11 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
m68k) m68k)
# FIXME: we need at least 68020 code to build shared libraries, but # FIXME: we need at least 68020 code to build shared libraries, but
# adding the `-m68020' flag to GCC prevents building anything better, # adding the `-m68020' flag to GCC prevents building anything better,
# like `-m68040'. # like `-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;; ;;
esac esac
;; ;;
@ -3950,10 +3950,10 @@ m4_if([$1], [CXX], [
fi fi
;; ;;
*) *)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
esac esac
else else
# PORTME Check for flag to pass linker flags through the system compiler. # PORTME Check for flag to pass linker flags through the system compiler.
case $host_os in case $host_os in
@ -4049,8 +4049,8 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='' _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
;; ;;
esac esac
;; ;;
esac esac
;; ;;
@ -4209,7 +4209,7 @@ m4_if([$1], [CXX], [
;; ;;
esac esac
_LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
], [ ],[
runpath_var= runpath_var=
_LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(allow_undefined_flag, $1)=
_LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(always_export_symbols, $1)=no
@ -4287,7 +4287,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# ancient GNU ld didn't support --whole-archive et. al. # ancient GNU ld didn't support --whole-archive et. al.
if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
_LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
else else
_LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)=
fi fi
supports_anon_versioning=no supports_anon_versioning=no
@ -4324,7 +4324,7 @@ _LT_EOF
# see comment about AmigaOS4 .so support # see comment about AmigaOS4 .so support
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='' _LT_TAGVAR(archive_expsym_cmds, $1)=''
;; ;;
m68k) m68k)
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
@ -4397,14 +4397,14 @@ _LT_EOF
tmp_addflag= tmp_addflag=
tmp_sharedflag='-shared' tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler pgcc*) # Portland Group C compiler
_LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag' tmp_addflag=' $pic_flag'
;; ;;
pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
_LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;; tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;; tmp_addflag=' -i_dynamic' ;;
efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
tmp_addflag=' -i_dynamic -nofor_main' ;; tmp_addflag=' -i_dynamic -nofor_main' ;;
@ -4429,10 +4429,10 @@ _LT_EOF
if test "x$supports_anon_versioning" = xyes; then if test "x$supports_anon_versioning" = xyes; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~
$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
fi fi
case $cc_basename in case $cc_basename in
xlf*) xlf*)
@ -4578,10 +4578,10 @@ _LT_EOF
# need to do runtime linking. # need to do runtime linking.
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes aix_use_runtimelinking=yes
break break
fi fi
done done
;; ;;
esac esac
@ -4611,14 +4611,14 @@ _LT_EOF
if test -f "$collect2name" && if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then then
# We have reworked collect2 # We have reworked collect2
: :
else else
# We have old collect2 # We have old collect2
_LT_TAGVAR(hardcode_direct, $1)=unsupported _LT_TAGVAR(hardcode_direct, $1)=unsupported
# It fails to find uninstalled libraries when the uninstalled # It fails to find uninstalled libraries when the uninstalled
# path is not listed in the libpath. Setting hardcode_minus_L # path is not listed in the libpath. Setting hardcode_minus_L
# to unsupported forces relinking # to unsupported forces relinking
_LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)=
@ -4633,8 +4633,8 @@ _LT_EOF
else else
# not using gcc # not using gcc
if test "$host_cpu" = ia64; then if test "$host_cpu" = ia64; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct: # chokes on -Wl,-G. The following line is correct:
shared_flag='-G' shared_flag='-G'
else else
if test "$aix_use_runtimelinking" = yes; then if test "$aix_use_runtimelinking" = yes; then
@ -4658,7 +4658,7 @@ _LT_EOF
_LT_SYS_MODULE_PATH_AIX _LT_SYS_MODULE_PATH_AIX
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else else
if test "$host_cpu" = ia64; then if test "$host_cpu" = ia64; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
@ -4687,7 +4687,7 @@ _LT_EOF
# see comment about AmigaOS4 .so support # see comment about AmigaOS4 .so support
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='' _LT_TAGVAR(archive_expsym_cmds, $1)=''
;; ;;
m68k) m68k)
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
@ -4723,7 +4723,7 @@ _LT_EOF
darwin* | rhapsody*) darwin* | rhapsody*)
_LT_DARWIN_LINKER_FEATURES($1) _LT_DARWIN_LINKER_FEATURES($1)
;; ;;
dgux*) dgux*)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
@ -4900,18 +4900,18 @@ _LT_EOF
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
else else
case $host_os in case $host_os in
openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
;; ;;
*) *)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
;; ;;
esac esac
fi fi
else else
_LT_TAGVAR(ld_shlibs, $1)=no _LT_TAGVAR(ld_shlibs, $1)=no
fi fi
@ -4966,7 +4966,7 @@ _LT_EOF
else else
case `$CC -V 2>&1` in case `$CC -V 2>&1` in
*"Compilers 5.0"*) *"Compilers 5.0"*)
wlarc='' wlarc=''
_LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
@ -4987,7 +4987,7 @@ _LT_EOF
# The compiler driver will combine and reorder linker options, # The compiler driver will combine and reorder linker options,
# but understands `-z linker_flag'. GCC discards it without `$wl', # but understands `-z linker_flag'. GCC discards it without `$wl',
# but is careful enough not to reorder. # but is careful enough not to reorder.
# Supported since Solaris 2.6 (maybe 2.5.1?) # Supported since Solaris 2.6 (maybe 2.5.1?)
if test "$GCC" = yes; then if test "$GCC" = yes; then
_LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
else else
@ -5108,7 +5108,7 @@ _LT_EOF
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
;; ;;
esac esac
fi fi
fi fi
]) ])
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
@ -5727,7 +5727,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -5792,7 +5792,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -5877,7 +5877,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -5960,7 +5960,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -6987,7 +6987,7 @@ AC_DEFUN([LT_PROG_GCJ],
[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
[m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
[AC_CHECK_TOOL(GCJ, gcj,) [AC_CHECK_TOOL(GCJ, gcj,)
test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
AC_SUBST(GCJFLAGS)])])[]dnl AC_SUBST(GCJFLAGS)])])[]dnl
]) ])
@ -8048,13 +8048,13 @@ fi])
# --------------------------------------------- # ---------------------------------------------
m4_define([_PKG_CONFIG], m4_define([_PKG_CONFIG],
[if test -n "$$1"; then [if test -n "$$1"; then
pkg_cv_[]$1="$$1" pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3], PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
[pkg_failed=yes]) [pkg_failed=yes])
else else
pkg_failed=untried pkg_failed=untried
fi[]dnl fi[]dnl
])# _PKG_CONFIG ])# _PKG_CONFIG

View file

@ -48,7 +48,7 @@ may remove or edit it.
you want to change it or regenerate `configure' using a newer version you want to change it or regenerate `configure' using a newer version
of `autoconf'. of `autoconf'.
The simplest way to compile this package is: The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type 1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. `./configure' to configure the package for your system.
@ -111,7 +111,7 @@ is an example:
Compiling For Multiple Architectures Compiling For Multiple Architectures
==================================== ====================================
You can compile the package for more than one kind of computer at the You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run directory where you want the object files and executables to go and run
@ -141,7 +141,7 @@ using the `lipo' tool if you have problems.
Installation Names Installation Names
================== ==================
By default, `make install' installs the package's commands under By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You `/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an `configure' the option `--prefix=PREFIX', where PREFIX must be an
@ -196,7 +196,7 @@ Optional Features
with an extra prefix or suffix on their names by giving `configure' the with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package. `configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The is something like `gnu-as' or `x' (for the X Window System). The
@ -292,7 +292,7 @@ A warning: not all `configure' scripts look for a site script.
Defining Variables Defining Variables
================== ==================
Variables not defined in a site shell script can be set in the Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set variables may be lost. In order to avoid this problem, you should set

View file

@ -262,15 +262,15 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
*$$dep*) \ *$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \ && exit 0; \
exit 1;; \ exit 1;; \
esac; \ esac; \
done; \ done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
$(am__cd) $(top_srcdir) && \ $(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile $(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile .PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \ @case '$?' in \
@ -429,7 +429,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \ test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \ if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \ "$$@" $$unique; \
else \ else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@ -470,14 +470,14 @@ distdir: $(DISTFILES)
*/*) $(MKDIR_P) `echo "$$dist_files" | \ */*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \ sort -u` ;; \
esac; \ esac; \
for file in $$dist_files; do \ for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \ if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \ if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \ fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \

View file

@ -688,7 +688,7 @@ _LT_CONFIG_SAVE_COMMANDS([
# commands through without removal of \ escapes. # commands through without removal of \ escapes.
if test -n "${ZSH_VERSION+set}" ; then if test -n "${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST setopt NO_GLOB_SUBST
fi fi
cfgfile="${ofile}T" cfgfile="${ofile}T"
trap "$RM \"$cfgfile\"; exit 1" 1 2 15 trap "$RM \"$cfgfile\"; exit 1" 1 2 15
@ -1109,104 +1109,104 @@ fi
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
if test -z "$lt_ECHO"; then if test -z "$lt_ECHO"; then
if test "X${echo_test_string+set}" != Xset; then if test "X${echo_test_string+set}" != Xset; then
# find a string as large as possible, as long as the shell can cope with it # find a string as large as possible, as long as the shell can cope with it
for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
# expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
if { echo_test_string=`eval $cmd`; } 2>/dev/null && if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
{ test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
then then
break break
fi fi
done done
fi fi
if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
: :
else else
# The Solaris, AIX, and Digital Unix default echo programs unquote # The Solaris, AIX, and Digital Unix default echo programs unquote
# backslashes. This makes it impossible to quote backslashes using # backslashes. This makes it impossible to quote backslashes using
# echo "$something" | sed 's/\\/\\\\/g' # echo "$something" | sed 's/\\/\\\\/g'
# #
# So, first we look for a working echo in the user's PATH. # So, first we look for a working echo in the user's PATH.
lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for dir in $PATH /usr/ucb; do for dir in $PATH /usr/ucb; do
IFS="$lt_save_ifs"
if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
ECHO="$dir/echo"
break
fi
done
IFS="$lt_save_ifs" IFS="$lt_save_ifs"
if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
ECHO="$dir/echo"
break
fi
done
IFS="$lt_save_ifs"
if test "X$ECHO" = Xecho; then if test "X$ECHO" = Xecho; then
# We didn't find a better echo, so look for alternatives. # We didn't find a better echo, so look for alternatives.
if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
# This shell has a builtin print -r that does the trick. # This shell has a builtin print -r that does the trick.
ECHO='print -r' ECHO='print -r'
elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
test "X$CONFIG_SHELL" != X/bin/ksh; then test "X$CONFIG_SHELL" != X/bin/ksh; then
# If we have ksh, try running configure again with it. # If we have ksh, try running configure again with it.
ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
export ORIGINAL_CONFIG_SHELL export ORIGINAL_CONFIG_SHELL
CONFIG_SHELL=/bin/ksh CONFIG_SHELL=/bin/ksh
export CONFIG_SHELL export CONFIG_SHELL
exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
else else
# Try using printf. # Try using printf.
ECHO='printf %s\n' ECHO='printf %s\n'
if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
# Cool, printf works
:
elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
test "X$echo_testing_string" = 'X\t' &&
echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
# Cool, printf works CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
: export CONFIG_SHELL
elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && SHELL="$CONFIG_SHELL"
test "X$echo_testing_string" = 'X\t' && export SHELL
echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then
CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
export CONFIG_SHELL
SHELL="$CONFIG_SHELL"
export SHELL
ECHO="$CONFIG_SHELL [$]0 --fallback-echo" ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
test "X$echo_testing_string" = 'X\t' && test "X$echo_testing_string" = 'X\t' &&
echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
test "X$echo_testing_string" = "X$echo_test_string"; then test "X$echo_testing_string" = "X$echo_test_string"; then
ECHO="$CONFIG_SHELL [$]0 --fallback-echo" ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
else else
# maybe with a smaller string... # maybe with a smaller string...
prev=: prev=:
for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
then then
break break
fi
prev="$cmd"
done
if test "$prev" != 'sed 50q "[$]0"'; then
echo_test_string=`eval $prev`
export echo_test_string
exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
else
# Oops. We lost completely, so just stick with echo.
ECHO=echo
fi fi
fi prev="$cmd"
done
if test "$prev" != 'sed 50q "[$]0"'; then
echo_test_string=`eval $prev`
export echo_test_string
exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
else
# Oops. We lost completely, so just stick with echo.
ECHO=echo
fi
fi fi
fi fi
fi fi
fi fi
fi
# Copy echo and quote the copy suitably for passing to libtool from # Copy echo and quote the copy suitably for passing to libtool from
# the Makefile, instead of quoting the original, which is used later. # the Makefile, instead of quoting the original, which is used later.
@ -1228,7 +1228,7 @@ _LT_DECL([], [ECHO], [1],
m4_defun([_LT_ENABLE_LOCK], m4_defun([_LT_ENABLE_LOCK],
[AC_ARG_ENABLE([libtool-lock], [AC_ARG_ENABLE([libtool-lock],
[AS_HELP_STRING([--disable-libtool-lock], [AS_HELP_STRING([--disable-libtool-lock],
[avoid locking (might break parallel builds)])]) [avoid locking (might break parallel builds)])])
test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good # Some flags need to be propagated to the compiler or linker for good
@ -1239,12 +1239,12 @@ ia64-*-hpux*)
echo 'int i;' > conftest.$ac_ext echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.$ac_objext` in case `/usr/bin/file conftest.$ac_objext` in
*ELF-32*) *ELF-32*)
HPUX_IA64_MODE="32" HPUX_IA64_MODE="32"
;; ;;
*ELF-64*) *ELF-64*)
HPUX_IA64_MODE="64" HPUX_IA64_MODE="64"
;; ;;
esac esac
fi fi
rm -rf conftest* rm -rf conftest*
@ -1253,31 +1253,31 @@ ia64-*-hpux*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '[#]line __oline__ "configure"' > conftest.$ac_ext echo '[#]line __oline__ "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
if test "$lt_cv_prog_gnu_ld" = yes; then if test "$lt_cv_prog_gnu_ld" = yes; then
case `/usr/bin/file conftest.$ac_objext` in case `/usr/bin/file conftest.$ac_objext` in
*32-bit*) *32-bit*)
LD="${LD-ld} -melf32bsmip" LD="${LD-ld} -melf32bsmip"
;; ;;
*N32*) *N32*)
LD="${LD-ld} -melf32bmipn32" LD="${LD-ld} -melf32bmipn32"
;; ;;
*64-bit*) *64-bit*)
LD="${LD-ld} -melf64bmip" LD="${LD-ld} -melf64bmip"
;; ;;
esac esac
else else
case `/usr/bin/file conftest.$ac_objext` in case `/usr/bin/file conftest.$ac_objext` in
*32-bit*) *32-bit*)
LD="${LD-ld} -32" LD="${LD-ld} -32"
;; ;;
*N32*) *N32*)
LD="${LD-ld} -n32" LD="${LD-ld} -n32"
;; ;;
*64-bit*) *64-bit*)
LD="${LD-ld} -64" LD="${LD-ld} -64"
;; ;;
esac esac
fi fi
fi fi
rm -rf conftest* rm -rf conftest*
;; ;;
@ -1288,44 +1288,44 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
echo 'int i;' > conftest.$ac_ext echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in case `/usr/bin/file conftest.o` in
*32-bit*) *32-bit*)
case $host in case $host in
x86_64-*kfreebsd*-gnu) x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_i386_fbsd" LD="${LD-ld} -m elf_i386_fbsd"
;; ;;
x86_64-*linux*) x86_64-*linux*)
LD="${LD-ld} -m elf_i386" LD="${LD-ld} -m elf_i386"
;; ;;
ppc64-*linux*|powerpc64-*linux*) ppc64-*linux*|powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux" LD="${LD-ld} -m elf32ppclinux"
;; ;;
s390x-*linux*) s390x-*linux*)
LD="${LD-ld} -m elf_s390" LD="${LD-ld} -m elf_s390"
;; ;;
sparc64-*linux*) sparc64-*linux*)
LD="${LD-ld} -m elf32_sparc" LD="${LD-ld} -m elf32_sparc"
;; ;;
esac esac
;; ;;
*64-bit*) *64-bit*)
case $host in case $host in
x86_64-*kfreebsd*-gnu) x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_x86_64_fbsd" LD="${LD-ld} -m elf_x86_64_fbsd"
;; ;;
x86_64-*linux*) x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64" LD="${LD-ld} -m elf_x86_64"
;; ;;
ppc*-*linux*|powerpc*-*linux*) ppc*-*linux*|powerpc*-*linux*)
LD="${LD-ld} -m elf64ppc" LD="${LD-ld} -m elf64ppc"
;; ;;
s390*-*linux*|s390*-*tpf*) s390*-*linux*|s390*-*tpf*)
LD="${LD-ld} -m elf64_s390" LD="${LD-ld} -m elf64_s390"
;; ;;
sparc*-*linux*) sparc*-*linux*)
LD="${LD-ld} -m elf64_sparc" LD="${LD-ld} -m elf64_sparc"
;; ;;
esac esac
;; ;;
esac esac
fi fi
rm -rf conftest* rm -rf conftest*
@ -1462,7 +1462,7 @@ dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
# [ACTION-SUCCESS], [ACTION-FAILURE]) # [ACTION-SUCCESS], [ACTION-FAILURE])
# ---------------------------------------------------- # ----------------------------------------------------
# Check whether the given linker option works # Check whether the given linker option works
AC_DEFUN([_LT_LINKER_OPTION], AC_DEFUN([_LT_LINKER_OPTION],
@ -1586,7 +1586,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
sysv5* | sco5v6* | sysv4.2uw2*) sysv5* | sco5v6* | sysv4.2uw2*)
kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
if test -n "$kargmax"; then if test -n "$kargmax"; then
lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
else else
lt_cv_sys_max_cmd_len=32768 lt_cv_sys_max_cmd_len=32768
fi fi
@ -1603,23 +1603,23 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
teststring=$teststring$teststring teststring=$teststring$teststring
done done
SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
# If test is not a shell built-in, we'll probably end up computing a # If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but # maximum length that is only half of the actual maximum length, but
# we can't tell. # we can't tell.
while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
= "XX$teststring$teststring"; } >/dev/null 2>&1 && = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
test $i != 17 # 1/2 MB should be enough test $i != 17 # 1/2 MB should be enough
do do
i=`expr $i + 1` i=`expr $i + 1`
teststring=$teststring$teststring teststring=$teststring$teststring
done done
# Only check the string length outside the loop. # Only check the string length outside the loop.
lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
teststring= teststring=
# Add a significant safety factor because C++ compilers can tack on # Add a significant safety factor because C++ compilers can tack on
# massive amounts of additional arguments before passing them to the # massive amounts of additional arguments before passing them to the
# linker. It appears as though 1/2 is a usable value. # linker. It appears as though 1/2 is a usable value.
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
fi fi
;; ;;
esac esac
@ -1648,7 +1648,7 @@ m4_defun([_LT_HEADER_DLFCN],
# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
# ---------------------------------------------------------------- # ----------------------------------------------------------------
m4_defun([_LT_TRY_DLOPEN_SELF], m4_defun([_LT_TRY_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl [m4_require([_LT_HEADER_DLFCN])dnl
@ -1756,12 +1756,12 @@ else
mingw* | pw32* | cegcc*) mingw* | pw32* | cegcc*)
lt_cv_dlopen="LoadLibrary" lt_cv_dlopen="LoadLibrary"
lt_cv_dlopen_libs= lt_cv_dlopen_libs=
;; ;;
cygwin*) cygwin*)
lt_cv_dlopen="dlopen" lt_cv_dlopen="dlopen"
lt_cv_dlopen_libs= lt_cv_dlopen_libs=
;; ;;
darwin*) darwin*)
# if libdl is installed we need to link against it # if libdl is installed we need to link against it
@ -1771,7 +1771,7 @@ else
lt_cv_dlopen_libs= lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes lt_cv_dlopen_self=yes
]) ])
;; ;;
*) *)
AC_CHECK_FUNC([shl_load], AC_CHECK_FUNC([shl_load],
@ -1821,7 +1821,7 @@ else
if test "x$lt_cv_dlopen_self" = xyes; then if test "x$lt_cv_dlopen_self" = xyes; then
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
AC_CACHE_CHECK([whether a statically linked program can dlopen itself], AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
lt_cv_dlopen_self_static, [dnl lt_cv_dlopen_self_static, [dnl
_LT_TRY_DLOPEN_SELF( _LT_TRY_DLOPEN_SELF(
lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
@ -2024,17 +2024,17 @@ if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
else else
# FIXME - insert some real tests, host_os isn't really good enough # FIXME - insert some real tests, host_os isn't really good enough
case $host_os in case $host_os in
darwin*) darwin*)
if test -n "$STRIP" ; then if test -n "$STRIP" ; then
striplib="$STRIP -x" striplib="$STRIP -x"
old_striplib="$STRIP -S" old_striplib="$STRIP -S"
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
else else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
fi fi
;; ;;
*) *)
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
;; ;;
esac esac
fi fi
@ -2188,10 +2188,10 @@ amigaos*)
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
;; ;;
m68k) m68k)
library_names_spec='$libname.ixlibrary $libname.a' library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs. # Create ${libname}_ixlibrary.a entries in /sys/libs.
finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;; ;;
esac esac
;; ;;
@ -2226,7 +2226,7 @@ cygwin* | mingw* | pw32* | cegcc*)
library_names_spec='$libname.dll.a' library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds # DLL is installed to $(libdir)/../bin by postinstall_cmds
postinstall_cmds='base_file=`basename \${file}`~ postinstall_cmds='base_file=`basename \${file}`~
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~ dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~ test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname~ $install_prog $dir/$dlname \$dldir/$dlname~
@ -2381,18 +2381,18 @@ hpux9* | hpux10* | hpux11*)
fi fi
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;; ;;
hppa*64*) hppa*64*)
shrext_cmds='.sl' shrext_cmds='.sl'
hardcode_into_libs=yes hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl" dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major' soname_spec='${libname}${release}${shared_ext}$major'
sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;; ;;
*) *)
shrext_cmds='.sl' shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl" dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH shlibpath_var=SHLIB_PATH
@ -2555,8 +2555,8 @@ openbsd*)
need_lib_prefix=no need_lib_prefix=no
# Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
case $host_os in case $host_os in
openbsd3.3 | openbsd3.3.*) need_version=yes ;; openbsd3.3 | openbsd3.3.*) need_version=yes ;;
*) need_version=no ;; *) need_version=no ;;
esac esac
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
@ -2710,10 +2710,10 @@ fi
if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
fi fi
if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
fi fi
_LT_DECL([], [variables_saved_for_relink], [1], _LT_DECL([], [variables_saved_for_relink], [1],
[Variables whose values should be saved in libtool wrapper scripts and [Variables whose values should be saved in libtool wrapper scripts and
@ -3030,8 +3030,8 @@ mingw* | pw32*)
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid' lt_cv_file_magic_cmd='func_win32_libid'
else else
lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
lt_cv_file_magic_cmd='$OBJDUMP -f' lt_cv_file_magic_cmd='$OBJDUMP -f'
fi fi
;; ;;
@ -3238,7 +3238,7 @@ else
: ${lt_cv_path_NM=no} : ${lt_cv_path_NM=no}
fi]) fi])
if test "$lt_cv_path_NM" != "no"; then if test "$lt_cv_path_NM" != "no"; then
NM="$lt_cv_path_NM" NM="$lt_cv_path_NM"
else else
# Didn't find any BSD compatible name lister, look for dumpbin. # Didn't find any BSD compatible name lister, look for dumpbin.
AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
@ -3430,7 +3430,7 @@ for ac_symprfx in "" "_"; do
" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx]" " ' prfx=^$ac_symprfx]"
else else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
fi fi
# Check to see that the pipe works correctly. # Check to see that the pipe works correctly.
@ -3475,7 +3475,7 @@ _LT_EOF
cat <<_LT_EOF >> conftest.$ac_ext cat <<_LT_EOF >> conftest.$ac_ext
/* The mapping between symbol names and symbols. */ /* The mapping between symbol names and symbols. */
const struct { const struct {
const char *name; const char *name;
void *address; void *address;
@ -3587,11 +3587,11 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
m68k) m68k)
# FIXME: we need at least 68020 code to build shared libraries, but # FIXME: we need at least 68020 code to build shared libraries, but
# adding the `-m68020' flag to GCC prevents building anything better, # adding the `-m68020' flag to GCC prevents building anything better,
# like `-m68040'. # like `-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;; ;;
esac esac
;; ;;
@ -3766,11 +3766,11 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
;;
esac
;; ;;
esac esac
;; ;;
esac
;;
lynxos*) lynxos*)
;; ;;
m88k*) m88k*)
@ -3893,11 +3893,11 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
m68k) m68k)
# FIXME: we need at least 68020 code to build shared libraries, but # FIXME: we need at least 68020 code to build shared libraries, but
# adding the `-m68020' flag to GCC prevents building anything better, # adding the `-m68020' flag to GCC prevents building anything better,
# like `-m68040'. # like `-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;; ;;
esac esac
;; ;;
@ -3958,10 +3958,10 @@ m4_if([$1], [CXX], [
fi fi
;; ;;
*) *)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;; ;;
esac esac
else else
# PORTME Check for flag to pass linker flags through the system compiler. # PORTME Check for flag to pass linker flags through the system compiler.
case $host_os in case $host_os in
@ -4057,8 +4057,8 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='' _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
;; ;;
esac esac
;; ;;
esac esac
;; ;;
@ -4217,7 +4217,7 @@ m4_if([$1], [CXX], [
;; ;;
esac esac
_LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
], [ ],[
runpath_var= runpath_var=
_LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(allow_undefined_flag, $1)=
_LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(always_export_symbols, $1)=no
@ -4295,7 +4295,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# ancient GNU ld didn't support --whole-archive et. al. # ancient GNU ld didn't support --whole-archive et. al.
if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
_LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
else else
_LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)=
fi fi
supports_anon_versioning=no supports_anon_versioning=no
@ -4332,7 +4332,7 @@ _LT_EOF
# see comment about AmigaOS4 .so support # see comment about AmigaOS4 .so support
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='' _LT_TAGVAR(archive_expsym_cmds, $1)=''
;; ;;
m68k) m68k)
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
@ -4405,14 +4405,14 @@ _LT_EOF
tmp_addflag= tmp_addflag=
tmp_sharedflag='-shared' tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler pgcc*) # Portland Group C compiler
_LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag' tmp_addflag=' $pic_flag'
;; ;;
pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
_LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;; tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;; tmp_addflag=' -i_dynamic' ;;
efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
tmp_addflag=' -i_dynamic -nofor_main' ;; tmp_addflag=' -i_dynamic -nofor_main' ;;
@ -4437,10 +4437,10 @@ _LT_EOF
if test "x$supports_anon_versioning" = xyes; then if test "x$supports_anon_versioning" = xyes; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~
$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
fi fi
case $cc_basename in case $cc_basename in
xlf*) xlf*)
@ -4586,10 +4586,10 @@ _LT_EOF
# need to do runtime linking. # need to do runtime linking.
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes aix_use_runtimelinking=yes
break break
fi fi
done done
;; ;;
esac esac
@ -4619,14 +4619,14 @@ _LT_EOF
if test -f "$collect2name" && if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then then
# We have reworked collect2 # We have reworked collect2
: :
else else
# We have old collect2 # We have old collect2
_LT_TAGVAR(hardcode_direct, $1)=unsupported _LT_TAGVAR(hardcode_direct, $1)=unsupported
# It fails to find uninstalled libraries when the uninstalled # It fails to find uninstalled libraries when the uninstalled
# path is not listed in the libpath. Setting hardcode_minus_L # path is not listed in the libpath. Setting hardcode_minus_L
# to unsupported forces relinking # to unsupported forces relinking
_LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)=
@ -4641,8 +4641,8 @@ _LT_EOF
else else
# not using gcc # not using gcc
if test "$host_cpu" = ia64; then if test "$host_cpu" = ia64; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct: # chokes on -Wl,-G. The following line is correct:
shared_flag='-G' shared_flag='-G'
else else
if test "$aix_use_runtimelinking" = yes; then if test "$aix_use_runtimelinking" = yes; then
@ -4666,7 +4666,7 @@ _LT_EOF
_LT_SYS_MODULE_PATH_AIX _LT_SYS_MODULE_PATH_AIX
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else else
if test "$host_cpu" = ia64; then if test "$host_cpu" = ia64; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
@ -4695,7 +4695,7 @@ _LT_EOF
# see comment about AmigaOS4 .so support # see comment about AmigaOS4 .so support
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='' _LT_TAGVAR(archive_expsym_cmds, $1)=''
;; ;;
m68k) m68k)
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
@ -4731,7 +4731,7 @@ _LT_EOF
darwin* | rhapsody*) darwin* | rhapsody*)
_LT_DARWIN_LINKER_FEATURES($1) _LT_DARWIN_LINKER_FEATURES($1)
;; ;;
dgux*) dgux*)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
@ -4908,18 +4908,18 @@ _LT_EOF
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
else else
case $host_os in case $host_os in
openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
;; ;;
*) *)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
;; ;;
esac esac
fi fi
else else
_LT_TAGVAR(ld_shlibs, $1)=no _LT_TAGVAR(ld_shlibs, $1)=no
fi fi
@ -4974,7 +4974,7 @@ _LT_EOF
else else
case `$CC -V 2>&1` in case `$CC -V 2>&1` in
*"Compilers 5.0"*) *"Compilers 5.0"*)
wlarc='' wlarc=''
_LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
@ -4995,7 +4995,7 @@ _LT_EOF
# The compiler driver will combine and reorder linker options, # The compiler driver will combine and reorder linker options,
# but understands `-z linker_flag'. GCC discards it without `$wl', # but understands `-z linker_flag'. GCC discards it without `$wl',
# but is careful enough not to reorder. # but is careful enough not to reorder.
# Supported since Solaris 2.6 (maybe 2.5.1?) # Supported since Solaris 2.6 (maybe 2.5.1?)
if test "$GCC" = yes; then if test "$GCC" = yes; then
_LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
else else
@ -5116,7 +5116,7 @@ _LT_EOF
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
;; ;;
esac esac
fi fi
fi fi
]) ])
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
@ -5735,7 +5735,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -5800,7 +5800,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -5885,7 +5885,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -5968,7 +5968,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
# #
# There doesn't appear to be a way to prevent this compiler from # There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
@ -6995,7 +6995,7 @@ AC_DEFUN([LT_PROG_GCJ],
[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
[m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
[AC_CHECK_TOOL(GCJ, gcj,) [AC_CHECK_TOOL(GCJ, gcj,)
test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
AC_SUBST(GCJFLAGS)])])[]dnl AC_SUBST(GCJFLAGS)])])[]dnl
]) ])
@ -8317,44 +8317,44 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
shift shift
for mf for mf
do do
# Strip MF so we end up with the name of the file. # Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'` mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not. # Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but # We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content. # some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process # Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so. # each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line # Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000. # limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")` dirpart=`AS_DIRNAME("$mf")`
else else
continue continue
fi fi
# Extract the definition of DEPDIR, am__include, and am__quote # Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running `make'. # from the Makefile without running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"` am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "am__include" && continue test -z "am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"` am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# When using ansi2knr, U may be empty or an underscore; expand it # When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"` U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with # Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the # $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the # simplest approach to changing $(DEPDIR) to its actual value in the
# expansion. # expansion.
for file in `sed -n " for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists. # Make sure the directory exists.
test -f "$dirpart/$file" && continue test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])` fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir]) AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file" # echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file" echo '# dummy' > "$dirpart/$file"
done
done done
done
} }
])# _AM_OUTPUT_DEPENDENCY_COMMANDS ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
@ -8408,10 +8408,10 @@ if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I." # is not polluted with repeated "-I."
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
# test to see if srcdir already configured # test to see if srcdir already configured
if test -f $srcdir/config.status; then if test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi fi
fi fi
# test whether we have cygpath # test whether we have cygpath
@ -8458,17 +8458,17 @@ AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
[_AM_PROG_TAR([v7])])]) [_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],, _AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC], [AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)], [_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC], [define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX], AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)], [_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX], [define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC], AC_PROVIDE_IFELSE([AC_PROG_OBJC],
[_AM_DEPENDENCIES(OBJC)], [_AM_DEPENDENCIES(OBJC)],
[define([AC_PROG_OBJC], [define([AC_PROG_OBJC],
@ -8623,9 +8623,9 @@ echo "include confinc" > confmf
# Ignore all kinds of additional output from `make'. # Ignore all kinds of additional output from `make'.
case `$am_make -s -f confmf 2> /dev/null` in #( case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*) *the\ am__doit\ target*)
am__include=include am__include=include
am__quote= am__quote=
_am_result=GNU _am_result=GNU
;; ;;
esac esac
# Now try BSD make style include. # Now try BSD make style include.
@ -8633,12 +8633,12 @@ if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #( case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*) *the\ am__doit\ target*)
am__include=.include am__include=.include
am__quote="\"" am__quote="\""
_am_result=BSD _am_result=BSD
;; ;;
esac esac
fi fi
AC_SUBST([am__include]) AC_SUBST([am__include])
AC_SUBST([am__quote]) AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result]) AC_MSG_RESULT([$_am_result])

BIN
bindings/cpp/configure vendored

Binary file not shown.

View file

@ -35,6 +35,8 @@ Pa_GetStreamReadAvailable @31
Pa_GetStreamWriteAvailable @32 Pa_GetStreamWriteAvailable @32
Pa_GetSampleSize @33 Pa_GetSampleSize @33
Pa_Sleep @34 Pa_Sleep @34
Pa_UpdateAvailableDeviceList @35
Pa_SetDevicesChangedCallback @36
PaAsio_GetAvailableLatencyValues @50 PaAsio_GetAvailableLatencyValues @50
PaAsio_ShowControlPanel @51 PaAsio_ShowControlPanel @51
PaUtil_InitializeX86PlainConverters @52 PaUtil_InitializeX86PlainConverters @52

BIN
configure vendored

Binary file not shown.

View file

@ -216,7 +216,7 @@ case "${host_os}" in
fi fi
SHARED_FLAGS="$LIBS -dynamiclib $mac_arches $mac_sysroot $mac_version_min" SHARED_FLAGS="$LIBS -dynamiclib $mac_arches $mac_sysroot $mac_version_min"
CFLAGS="-std=c99 $CFLAGS $mac_arches $mac_sysroot $mac_version_min" CFLAGS="-std=c99 $CFLAGS $mac_arches $mac_sysroot $mac_version_min"
OTHER_OBJS="src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o src/common/pa_ringbuffer.o" OTHER_OBJS="src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o src/common/pa_ringbuffer.o src/os/mac_osx/pa_osx_hotplug.o"
PADLL="libportaudio.dylib" PADLL="libportaudio.dylib"
;; ;;
@ -230,7 +230,7 @@ case "${host_os}" in
if [[ "x$with_directx" = "xyes" ]]; then if [[ "x$with_directx" = "xyes" ]]; then
DXDIR="$with_dxdir" DXDIR="$with_dxdir"
add_objects src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/pa_win_ds_dynlink.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o add_objects src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/pa_win_ds_dynlink.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o src/os/win/pa_win_hotplug.o
LIBS="-lwinmm -lm -ldsound -lole32" LIBS="-lwinmm -lm -ldsound -lole32"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -ldsound -lole32" DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -ldsound -lole32"
#VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"" #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\""
@ -249,7 +249,7 @@ case "${host_os}" in
if [[ "x$with_wdmks" = "xyes" ]]; then if [[ "x$with_wdmks" = "xyes" ]]; then
DXDIR="$with_dxdir" DXDIR="$with_dxdir"
add_objects src/hostapi/wdmks/pa_win_wdmks.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o add_objects src/hostapi/wdmks/pa_win_wdmks.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_wdmks_utils.o
LIBS="-lwinmm -lm -luuid -lsetupapi -lole32" LIBS="-lwinmm -lm -luuid -lsetupapi -lole32"
DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -luuid -lsetupapi -lole32" DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -luuid -lsetupapi -lole32"
#VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"" #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\""
@ -319,7 +319,7 @@ case "${host_os}" in
if [[ "$have_alsa" = "yes" ] && [ "$with_alsa" != "no" ]] ; then if [[ "$have_alsa" = "yes" ] && [ "$with_alsa" != "no" ]] ; then
DLL_LIBS="$DLL_LIBS -lasound" DLL_LIBS="$DLL_LIBS -lasound"
LIBS="$LIBS -lasound" LIBS="$LIBS -lasound"
OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o" OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o src/os/unix/pa_linux_hotplug.o"
INCLUDES="$INCLUDES pa_linux_alsa.h" INCLUDES="$INCLUDES pa_linux_alsa.h"
AC_DEFINE(PA_USE_ALSA) AC_DEFINE(PA_USE_ALSA)
fi fi

View file

@ -46,7 +46,7 @@
#include "portaudio.h" #include "portaudio.h"
#include <AudioUnit/AudioUnit.h> #include <AudioUnit/AudioUnit.h>
//#include <AudioToolbox/AudioToolbox.h> #include <AudioToolbox/AudioToolbox.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View file

@ -1,7 +1,7 @@
#ifndef PORTAUDIO_H #ifndef PORTAUDIO_H
#define PORTAUDIO_H #define PORTAUDIO_H
/* /*
* $Id$ * $Id: portaudio.h 1670 2011-05-04 16:37:52Z rob_bielik $
* PortAudio Portable Real-Time Audio Library * PortAudio Portable Real-Time Audio Library
* PortAudio API Header File * PortAudio API Header File
* Latest version available at: http://www.portaudio.com/ * Latest version available at: http://www.portaudio.com/
@ -121,9 +121,17 @@ const char *Pa_GetErrorText( PaError errorCode );
Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not
required to be fully nested. required to be fully nested.
Note that if Pa_Initialize() returns an error code, Pa_Terminate() should If Pa_Initialize() returns an error code, Pa_Terminate() should
NOT be called. NOT be called.
@note The device list returned by Pa_GetDeviceCount() et al. is frozen
at the time Pa_Initialize() is called, and not updated dynamically, even if
hardware devices (e.g. USB or firewire devices) are connected or disconnected
during the course of the program's lifetime. If it is required to re-scan the
list of devices, one must call Pa_UpdateAvailableDeviceList() or, completely
uninitialize PortAudio using Pa_Terminate(), and then reinitialize it by calling
Pa_Initialize().
@return paNoError if successful, otherwise an error code indicating the cause @return paNoError if successful, otherwise an error code indicating the cause
of failure. of failure.
@ -397,6 +405,20 @@ PaDeviceIndex Pa_GetDefaultInputDevice( void );
*/ */
PaDeviceIndex Pa_GetDefaultOutputDevice( void ); PaDeviceIndex Pa_GetDefaultOutputDevice( void );
/** Update the list of available devices to match currently available hardware devices.
PortAudio's list of available devices is usually frozen at the time Pa_Initialize() is
called. Pa_UpdateAvailableDeviceList() may be called to refresh PortAudio's list
of available devices at any time while PortAudio is initialized.
@note Open streams will not be affected by calls to this function, but
any previously returned PaDeviceInfo pointers are invalidated once this
function is called.
@return an error code indicating whether the device refresh was successful.
*/
PaError Pa_UpdateAvailableDeviceList( void );
/** The type used to represent monotonic time in seconds. PaTime is /** The type used to represent monotonic time in seconds. PaTime is
used for the fields of the PaStreamCallbackTimeInfo argument to the used for the fields of the PaStreamCallbackTimeInfo argument to the
@ -439,7 +461,7 @@ typedef unsigned long PaSampleFormat;
#define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */ #define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */
#define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */ #define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */
#define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */ #define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */
#define paCustomFormat ((PaSampleFormat) 0x00010000) /**< @see PaSampleFormat */ #define paCustomFormat ((PaSampleFormat) 0x00010000)/**< @see PaSampleFormat */
#define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */ #define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */
@ -448,7 +470,7 @@ typedef unsigned long PaSampleFormat;
*/ */
typedef struct PaDeviceInfo typedef struct PaDeviceInfo
{ {
int structVersion; /* this is struct version 2 */ int structVersion; /* this is struct version 3 */
const char *name; const char *name;
PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/ PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/
@ -463,6 +485,11 @@ typedef struct PaDeviceInfo
PaTime defaultHighOutputLatency; PaTime defaultHighOutputLatency;
double defaultSampleRate; double defaultSampleRate;
/*The transport type used by this device: USB, BuiltIn, Bluetooth, etc.*/
const char *transportType;
/*The unique identifier of this device (persistent across boots).*/
const char *deviceUID;
} PaDeviceInfo; } PaDeviceInfo;
@ -1143,6 +1170,13 @@ void Pa_Sleep( long msec );
typedef void PaDevicesChangedCallback( void *userData );
PaError Pa_SetDevicesChangedCallback( void *userData, PaStreamFinishedCallback* devicesChangedCallback );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

Binary file not shown.

388
ltmain.sh
View file

@ -162,9 +162,9 @@ func_dirname_and_basename ()
func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
if test "X$func_dirname_result" = "X${1}"; then if test "X$func_dirname_result" = "X${1}"; then
func_dirname_result="${3}" func_dirname_result="${3}"
else else
func_dirname_result="$func_dirname_result${2}" func_dirname_result="$func_dirname_result${2}"
fi fi
func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
} }
@ -193,7 +193,7 @@ case $progpath in
progdir=$func_dirname_result progdir=$func_dirname_result
progdir=`cd "$progdir" && pwd` progdir=`cd "$progdir" && pwd`
progpath="$progdir/$progname" progpath="$progdir/$progname"
;; ;;
*) *)
save_IFS="$IFS" save_IFS="$IFS"
IFS=: IFS=:
@ -204,7 +204,7 @@ case $progpath in
IFS="$save_IFS" IFS="$save_IFS"
test -n "$progdir" || progdir=`pwd` test -n "$progdir" || progdir=`pwd`
progpath="$progdir/$progname" progpath="$progdir/$progname"
;; ;;
esac esac
# Sed substitution that helps us do robust quoting. It backslashifies # Sed substitution that helps us do robust quoting. It backslashifies
@ -280,7 +280,7 @@ func_warning ()
func_fatal_error () func_fatal_error ()
{ {
func_error ${1+"$@"} func_error ${1+"$@"}
exit $EXIT_FAILURE exit $EXIT_FAILURE
} }
# func_fatal_help arg... # func_fatal_help arg...
@ -327,7 +327,7 @@ func_mkdir_p ()
# ...otherwise throw away the child directory and loop # ...otherwise throw away the child directory and loop
my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
done done
my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
save_mkdir_p_IFS="$IFS"; IFS=':' save_mkdir_p_IFS="$IFS"; IFS=':'
@ -343,7 +343,7 @@ func_mkdir_p ()
# Bail out if we (or some other process) failed to create a directory. # Bail out if we (or some other process) failed to create a directory.
test -d "$my_directory_path" || \ test -d "$my_directory_path" || \
func_fatal_error "Failed to create \`$1'" func_fatal_error "Failed to create \`$1'"
fi fi
} }
@ -364,13 +364,13 @@ func_mktempdir ()
my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
if test ! -d "$my_tmpdir"; then if test ! -d "$my_tmpdir"; then
# Failing that, at least try and use $RANDOM to avoid a race # Failing that, at least try and use $RANDOM to avoid a race
my_tmpdir="${my_template}-${RANDOM-0}$$" my_tmpdir="${my_template}-${RANDOM-0}$$"
save_mktempdir_umask=`umask` save_mktempdir_umask=`umask`
umask 0077 umask 0077
$MKDIR "$my_tmpdir" $MKDIR "$my_tmpdir"
umask $save_mktempdir_umask umask $save_mktempdir_umask
fi fi
# If we're not in dry-run mode, bomb out on failure # If we're not in dry-run mode, bomb out on failure
@ -395,7 +395,7 @@ func_quote_for_eval ()
func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
*) *)
func_quote_for_eval_unquoted_result="$1" ;; func_quote_for_eval_unquoted_result="$1" ;;
esac esac
case $func_quote_for_eval_unquoted_result in case $func_quote_for_eval_unquoted_result in
# Double-quote args containing shell metacharacters to delay # Double-quote args containing shell metacharacters to delay
@ -405,7 +405,7 @@ func_quote_for_eval ()
# in scan sets, so we specify it separately. # in scan sets, so we specify it separately.
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
;; ;;
*) *)
func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
esac esac
@ -423,17 +423,17 @@ func_quote_for_expand ()
-e "$double_quote_subst" -e "$sed_double_backslash"` ;; -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
*) *)
my_arg="$1" ;; my_arg="$1" ;;
esac esac
case $my_arg in case $my_arg in
# Double-quote args containing shell metacharacters to delay # Double-quote args containing shell metacharacters to delay
# word splitting and command substitution for a subsequent eval. # word splitting and command substitution for a subsequent eval.
# Many Bourne shells cannot handle close brackets correctly # Many Bourne shells cannot handle close brackets correctly
# in scan sets, so we specify it separately. # in scan sets, so we specify it separately.
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
my_arg="\"$my_arg\"" my_arg="\"$my_arg\""
;; ;;
esac esac
func_quote_for_expand_result="$my_arg" func_quote_for_expand_result="$my_arg"
} }
@ -458,7 +458,7 @@ func_show_eval ()
my_status=$? my_status=$?
if test "$my_status" -eq 0; then :; else if test "$my_status" -eq 0; then :; else
eval "(exit $my_status); $my_fail_exp" eval "(exit $my_status); $my_fail_exp"
fi fi
fi fi
} }
@ -480,11 +480,11 @@ func_show_eval_locale ()
if ${opt_dry_run-false}; then :; else if ${opt_dry_run-false}; then :; else
eval "$lt_user_locale eval "$lt_user_locale
$my_cmd" $my_cmd"
my_status=$? my_status=$?
eval "$lt_safe_locale" eval "$lt_safe_locale"
if test "$my_status" -eq 0; then :; else if test "$my_status" -eq 0; then :; else
eval "(exit $my_status); $my_fail_exp" eval "(exit $my_status); $my_fail_exp"
fi fi
fi fi
} }
@ -566,10 +566,10 @@ elif test "X$1" = X--fallback-echo; then
elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
# Yippee, $ECHO works! # Yippee, $ECHO works!
: :
else else
# Restart under the correct shell, and then maybe $ECHO will work. # Restart under the correct shell, and then maybe $ECHO will work.
exec $SHELL "$progpath" --no-reexec ${1+"$@"} exec $SHELL "$progpath" --no-reexec ${1+"$@"}
fi fi
if test "X$1" = X--fallback-echo; then if test "X$1" = X--fallback-echo; then
# used as fallback echo # used as fallback echo
@ -578,7 +578,7 @@ if test "X$1" = X--fallback-echo; then
$* $*
EOF EOF
exit $EXIT_SUCCESS exit $EXIT_SUCCESS
fi fi
magic="%%%MAGIC variable%%%" magic="%%%MAGIC variable%%%"
magic_exe="%%%MAGIC EXE variable%%%" magic_exe="%%%MAGIC EXE variable%%%"
@ -688,7 +688,7 @@ func_enable_tag ()
else else
func_error "ignoring unknown tag $tagname" func_error "ignoring unknown tag $tagname"
fi fi
;; ;;
esac esac
} }
@ -733,12 +733,12 @@ func_enable_tag ()
func_echo "enabling shell trace mode" func_echo "enabling shell trace mode"
opt_debug='set -x' opt_debug='set -x'
$opt_debug $opt_debug
;; ;;
-dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
execute_dlfiles="$execute_dlfiles $1" execute_dlfiles="$execute_dlfiles $1"
shift shift
;; ;;
--dry-run | -n) opt_dry_run=: ;; --dry-run | -n) opt_dry_run=: ;;
--features) func_features ;; --features) func_features ;;
@ -759,9 +759,9 @@ func_enable_tag ()
# Catch anything else as an error # Catch anything else as an error
*) func_error "invalid argument for $opt" *) func_error "invalid argument for $opt"
exit_cmd=exit exit_cmd=exit
break break
;; ;;
esac esac
mode="$1" mode="$1"
shift shift
@ -772,17 +772,17 @@ func_enable_tag ()
--quiet|--silent) preserve_args="$preserve_args $opt" --quiet|--silent) preserve_args="$preserve_args $opt"
opt_silent=: opt_silent=:
;; ;;
--verbose| -v) preserve_args="$preserve_args $opt" --verbose| -v) preserve_args="$preserve_args $opt"
opt_silent=false opt_silent=false
;; ;;
--tag) test "$#" -eq 0 && func_missing_arg "$opt" && break --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
preserve_args="$preserve_args $opt $1" preserve_args="$preserve_args $opt $1"
func_enable_tag "$1" # tagname is set here func_enable_tag "$1" # tagname is set here
shift shift
;; ;;
# Separate optargs to long options: # Separate optargs to long options:
-dlopen=*|--mode=*|--tag=*) -dlopen=*|--mode=*|--tag=*)
@ -798,10 +798,10 @@ func_enable_tag ()
-*) func_fatal_help "unrecognized option \`$opt'" ;; -*) func_fatal_help "unrecognized option \`$opt'" ;;
*) nonopt="$opt" *) nonopt="$opt"
break break
;; ;;
esac esac
done done
case $host in case $host in
@ -833,14 +833,14 @@ $progname: definition of this LT_INIT comes from an older release.
$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
$progname: and run autoconf again. $progname: and run autoconf again.
_LT_EOF _LT_EOF
else else
cat >&2 <<_LT_EOF cat >&2 <<_LT_EOF
$progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: Version mismatch error. This is $PACKAGE $VERSION, but the
$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
$progname: and run autoconf again. $progname: and run autoconf again.
_LT_EOF _LT_EOF
fi fi
else else
cat >&2 <<_LT_EOF cat >&2 <<_LT_EOF
$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
@ -848,7 +848,7 @@ $progname: but the definition of this LT_INIT comes from revision $macro_revisio
$progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: You should recreate aclocal.m4 with macros from revision $package_revision
$progname: of $PACKAGE $VERSION and run autoconf again. $progname: of $PACKAGE $VERSION and run autoconf again.
_LT_EOF _LT_EOF
fi fi
exit $EXIT_MISMATCH exit $EXIT_MISMATCH
fi fi
@ -1161,7 +1161,7 @@ func_mode_compile ()
args=$func_stripname_result args=$func_stripname_result
lastarg= lastarg=
save_ifs="$IFS"; IFS=',' save_ifs="$IFS"; IFS=','
for arg in $args; do for arg in $args; do
IFS="$save_ifs" IFS="$save_ifs"
func_quote_for_eval "$arg" func_quote_for_eval "$arg"
lastarg="$lastarg $func_quote_for_eval_result" lastarg="$lastarg $func_quote_for_eval_result"
@ -1175,7 +1175,7 @@ func_mode_compile ()
continue continue
;; ;;
*) * )
# Accept the current argument as the source file. # Accept the current argument as the source file.
# The previous "srcfile" becomes the current argument. # The previous "srcfile" becomes the current argument.
# #
@ -1379,11 +1379,11 @@ compiler."
if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
func_show_eval '$MV "$output_obj" "$lobj"' \ func_show_eval '$MV "$output_obj" "$lobj"' \
'error=$?; $opt_dry_run || $RM $removelist; exit $error' 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
fi fi
# Allow error messages only from the first compilation. # Allow error messages only from the first compilation.
if test "$suppress_opt" = yes; then if test "$suppress_opt" = yes; then
suppress_output=' >/dev/null 2>&1' suppress_output=' >/dev/null 2>&1'
fi fi
fi fi
@ -1675,8 +1675,8 @@ func_mode_execute ()
else else
if test ! -f "$dir/$dlname"; then if test ! -f "$dir/$dlname"; then
func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
fi
fi fi
fi
;; ;;
*.lo) *.lo)
@ -1698,7 +1698,7 @@ func_mode_execute ()
# Now add the directory to shlibpath_var. # Now add the directory to shlibpath_var.
if eval "test -z \"\$$shlibpath_var\""; then if eval "test -z \"\$$shlibpath_var\""; then
eval "$shlibpath_var=\"\$dir\"" eval "$shlibpath_var=\"\$dir\""
else else
eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
fi fi
done done
@ -1724,7 +1724,7 @@ func_mode_execute ()
func_source "$func_ltwrapper_scriptname_result" func_source "$func_ltwrapper_scriptname_result"
# Transform arg to wrapped name. # Transform arg to wrapped name.
file="$progdir/$program" file="$progdir/$program"
fi fi
;; ;;
esac esac
# Quote arguments (to preserve shell metacharacters). # Quote arguments (to preserve shell metacharacters).
@ -1755,7 +1755,7 @@ func_mode_execute ()
if test -n "$shlibpath_var"; then if test -n "$shlibpath_var"; then
eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
$ECHO "export $shlibpath_var" $ECHO "export $shlibpath_var"
fi fi
$ECHO "$cmd$args" $ECHO "$cmd$args"
exit $EXIT_SUCCESS exit $EXIT_SUCCESS
fi fi
@ -1891,7 +1891,7 @@ func_mode_install ()
*[\\\ /]cp\ *) ;; *[\\\ /]cp\ *) ;;
*) prev=$arg ;; *) prev=$arg ;;
esac esac
;; ;;
-g | -m | -o) -g | -m | -o)
prev=$arg prev=$arg
;; ;;
@ -2152,7 +2152,7 @@ func_mode_install ()
esac esac
# Do a test to see if this is really a libtool program. # Do a test to see if this is really a libtool program.
case $host in case $host in
*cygwin* | *mingw*) *cygwin* | *mingw*)
if func_ltwrapper_executable_p "$file"; then if func_ltwrapper_executable_p "$file"; then
func_ltwrapper_scriptname "$file" func_ltwrapper_scriptname "$file"
@ -4132,7 +4132,7 @@ func_mode_link ()
-static-libtool-libs) -static-libtool-libs)
if test -z "$pic_flag" && test -n "$link_static_flag"; then if test -z "$pic_flag" && test -n "$link_static_flag"; then
dlopen_self=$dlopen_self_static dlopen_self=$dlopen_self_static
fi fi
prefer_static_libs=yes prefer_static_libs=yes
;; ;;
esac esac
@ -4222,7 +4222,7 @@ func_mode_link ()
case "$deplibs " in case "$deplibs " in
*" $qarg.ltframework "*) ;; *" $qarg.ltframework "*) ;;
*) deplibs="$deplibs $qarg.ltframework" # this is fixed later *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
;; ;;
esac esac
;; ;;
esac esac
@ -4318,10 +4318,10 @@ func_mode_link ()
non_pic_object=$xdir$func_lo2o_result non_pic_object=$xdir$func_lo2o_result
func_append libobjs " $pic_object" func_append libobjs " $pic_object"
func_append non_pic_objects " $non_pic_object" func_append non_pic_objects " $non_pic_object"
else else
func_fatal_error "\`$arg' is not a valid libtool object" func_fatal_error "\`$arg' is not a valid libtool object"
fi
fi fi
fi
done done
else else
func_fatal_error "link input file \`$arg' does not exist" func_fatal_error "link input file \`$arg' does not exist"
@ -4584,8 +4584,8 @@ func_mode_link ()
*" $arg "*) ;; *" $arg "*) ;;
* ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
esac esac
continue continue
;; ;;
-multi_module) -multi_module)
single_module="${wl}-multi_module" single_module="${wl}-multi_module"
@ -4778,7 +4778,7 @@ func_mode_link ()
-* | +*) -* | +*)
func_quote_for_eval "$arg" func_quote_for_eval "$arg"
arg="$func_quote_for_eval_result" arg="$func_quote_for_eval_result"
;; ;;
*.$objext) *.$objext)
# A standard object. # A standard object.
@ -4862,10 +4862,10 @@ func_mode_link ()
non_pic_object=$xdir$func_lo2o_result non_pic_object=$xdir$func_lo2o_result
func_append libobjs " $pic_object" func_append libobjs " $pic_object"
func_append non_pic_objects " $non_pic_object" func_append non_pic_objects " $non_pic_object"
else else
func_fatal_error "\`$arg' is not a valid libtool object" func_fatal_error "\`$arg' is not a valid libtool object"
fi
fi fi
fi
;; ;;
*.$libext) *.$libext)
@ -4898,7 +4898,7 @@ func_mode_link ()
# to be aesthetically quoted because they are evaled later. # to be aesthetically quoted because they are evaled later.
func_quote_for_eval "$arg" func_quote_for_eval "$arg"
arg="$func_quote_for_eval_result" arg="$func_quote_for_eval_result"
;; ;;
esac # arg esac # arg
# Now actually substitute the argument into the commands. # Now actually substitute the argument into the commands.
@ -5081,7 +5081,7 @@ func_mode_link ()
*" $deplib "*) ;; *" $deplib "*) ;;
* ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
esac esac
fi fi
fi fi
continue continue
;; ;;
@ -5149,7 +5149,7 @@ func_mode_link ()
continue continue
fi fi
fi fi
;; ;;
*) ;; *) ;;
esac esac
fi fi
@ -5225,21 +5225,21 @@ func_mode_link ()
case " $dlpreconveniencelibs " in case " $dlpreconveniencelibs " in
*" $deplib "*) ;; *" $deplib "*) ;;
*) *)
valid_a_lib=no valid_a_lib=no
case $deplibs_check_method in case $deplibs_check_method in
match_pattern*) match_pattern*)
set dummy $deplibs_check_method; shift set dummy $deplibs_check_method; shift
match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
| $EGREP "$match_pattern_regex" > /dev/null; then | $EGREP "$match_pattern_regex" > /dev/null; then
valid_a_lib=yes
fi
;;
pass_all)
valid_a_lib=yes valid_a_lib=yes
fi
;; ;;
esac pass_all)
if test "$valid_a_lib" != yes; then valid_a_lib=yes
;;
esac
if test "$valid_a_lib" != yes; then
$ECHO $ECHO
$ECHO "*** Warning: Trying to link with static lib archive $deplib." $ECHO "*** Warning: Trying to link with static lib archive $deplib."
$ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** I have the capability to make that library automatically link in when"
@ -5247,12 +5247,12 @@ func_mode_link ()
$ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** shared version of the library, which you do not appear to have"
$ECHO "*** because the file extensions .$libext of this argument makes me believe" $ECHO "*** because the file extensions .$libext of this argument makes me believe"
$ECHO "*** that it is just a static archive that I should not use here." $ECHO "*** that it is just a static archive that I should not use here."
else else
$ECHO $ECHO
$ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** Warning: Linking the shared library $output against the"
$ECHO "*** static library $deplib is not portable!" $ECHO "*** static library $deplib is not portable!"
deplibs="$deplib $deplibs" deplibs="$deplib $deplibs"
fi fi
;; ;;
esac esac
continue continue
@ -5326,7 +5326,7 @@ func_mode_link ()
case " $new_inherited_linker_flags " in case " $new_inherited_linker_flags " in
*" $tmp_inherited_linker_flag "*) ;; *" $tmp_inherited_linker_flag "*) ;;
*) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
esac esac
done done
fi fi
dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
@ -5351,10 +5351,10 @@ func_mode_link ()
for deplib in $dependency_libs; do for deplib in $dependency_libs; do
deplibs="$deplib $deplibs" deplibs="$deplib $deplibs"
if $opt_duplicate_deps ; then if $opt_duplicate_deps ; then
case "$tmp_libs " in case "$tmp_libs " in
*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
esac esac
fi fi
tmp_libs="$tmp_libs $deplib" tmp_libs="$tmp_libs $deplib"
done done
elif test "$linkmode" != prog && test "$linkmode" != lib; then elif test "$linkmode" != prog && test "$linkmode" != lib; then
@ -5553,7 +5553,7 @@ func_mode_link ()
link_static=no # Whether the deplib will be linked statically link_static=no # Whether the deplib will be linked statically
use_static_libs=$prefer_static_libs use_static_libs=$prefer_static_libs
if test "$use_static_libs" = built && test "$installed" = yes; then if test "$use_static_libs" = built && test "$installed" = yes ; then
use_static_libs=no use_static_libs=no
fi fi
if test -n "$library_names" && if test -n "$library_names" &&
@ -5565,10 +5565,10 @@ func_mode_link ()
need_relink=no need_relink=no
;; ;;
*) *)
if test "$installed" = no; then if test "$installed" = no; then
notinst_deplibs="$notinst_deplibs $lib" notinst_deplibs="$notinst_deplibs $lib"
need_relink=yes need_relink=yes
fi fi
;; ;;
esac esac
# This is a shared library # This is a shared library
@ -5685,16 +5685,16 @@ func_mode_link ()
$GREP ": [^:]* bundle" >/dev/null ; then $GREP ": [^:]* bundle" >/dev/null ; then
if test "X$dlopenmodule" != "X$lib"; then if test "X$dlopenmodule" != "X$lib"; then
$ECHO "*** Warning: lib $linklib is a module, not a shared library" $ECHO "*** Warning: lib $linklib is a module, not a shared library"
if test -z "$old_library" ; then if test -z "$old_library" ; then
$ECHO $ECHO
$ECHO "*** And there doesn't seem to be a static archive available" $ECHO "*** And there doesn't seem to be a static archive available"
$ECHO "*** The link will probably fail, sorry" $ECHO "*** The link will probably fail, sorry"
else else
add="$dir/$old_library" add="$dir/$old_library"
fi fi
elif test -n "$old_library"; then elif test -n "$old_library"; then
add="$dir/$old_library" add="$dir/$old_library"
fi fi
fi fi
esac esac
elif test "$hardcode_minus_L" = no; then elif test "$hardcode_minus_L" = no; then
@ -5782,9 +5782,9 @@ func_mode_link ()
elif test "$hardcode_automatic" = yes; then elif test "$hardcode_automatic" = yes; then
if test -n "$inst_prefix_dir" && if test -n "$inst_prefix_dir" &&
test -f "$inst_prefix_dir$libdir/$linklib" ; then test -f "$inst_prefix_dir$libdir/$linklib" ; then
add="$inst_prefix_dir$libdir/$linklib" add="$inst_prefix_dir$libdir/$linklib"
else else
add="$libdir/$linklib" add="$libdir/$linklib"
fi fi
else else
# We cannot seem to hardcode it, guess we'll fake it. # We cannot seem to hardcode it, guess we'll fake it.
@ -5927,11 +5927,11 @@ func_mode_link ()
darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
if test -z "$darwin_install_name"; then if test -z "$darwin_install_name"; then
darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
fi fi
compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
path= path=
fi fi
fi fi
;; ;;
*) *)
@ -5946,9 +5946,9 @@ func_mode_link ()
func_warning "\`$deplib' seems to be moved" func_warning "\`$deplib' seems to be moved"
path="-L$absdir" path="-L$absdir"
fi fi
;; ;;
esac esac
case " $deplibs " in case " $deplibs " in
*" $path "*) ;; *" $path "*) ;;
*) deplibs="$path $deplibs" ;; *) deplibs="$path $deplibs" ;;
@ -6417,7 +6417,7 @@ func_mode_link ()
$output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
if test "X$precious_files_regex" != "X"; then if test "X$precious_files_regex" != "X"; then
if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
then then
continue continue
fi fi
fi fi
@ -6428,7 +6428,7 @@ func_mode_link ()
done done
test -n "$removelist" && \ test -n "$removelist" && \
func_show_eval "${RM}r \$removelist" func_show_eval "${RM}r \$removelist"
fi fi
# Now set the variables for building old libraries. # Now set the variables for building old libraries.
if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
@ -6502,7 +6502,7 @@ func_mode_link ()
*-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
# Compiler inserts libc in the correct place for threads to work # Compiler inserts libc in the correct place for threads to work
;; ;;
*) *)
# Add libc to deplibs on all other systems if necessary. # Add libc to deplibs on all other systems if necessary.
if test "$build_libtool_need_lc" = "yes"; then if test "$build_libtool_need_lc" = "yes"; then
deplibs="$deplibs -lc" deplibs="$deplibs -lc"
@ -6558,7 +6558,7 @@ EOF
i="" i=""
;; ;;
esac esac
fi fi
if test -n "$i" ; then if test -n "$i" ; then
libname=`eval "\\$ECHO \"$libname_spec\""` libname=`eval "\\$ECHO \"$libname_spec\""`
deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
@ -6678,9 +6678,9 @@ EOF
if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
$SED -e 10q | $SED -e 10q |
$EGREP "$file_magic_regex" > /dev/null; then $EGREP "$file_magic_regex" > /dev/null; then
newdeplibs="$newdeplibs $a_deplib" newdeplibs="$newdeplibs $a_deplib"
a_deplib="" a_deplib=""
break 2 break 2
fi fi
done done
done done
@ -7015,11 +7015,11 @@ EOF
len=$func_len_result len=$func_len_result
if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
func_show_eval "$cmd" 'exit $?' func_show_eval "$cmd" 'exit $?'
skipped_export=false skipped_export=false
else else
# The command line is too long to execute in one step. # The command line is too long to execute in one step.
func_verbose "using reloadable object file for export list..." func_verbose "using reloadable object file for export list..."
skipped_export=: skipped_export=:
# Break out early, otherwise skipped_export may be # Break out early, otherwise skipped_export may be
# set to false by a later but shorter cmd. # set to false by a later but shorter cmd.
break break
@ -7055,12 +7055,12 @@ EOF
tmp_deplibs= tmp_deplibs=
for test_deplib in $deplibs; do for test_deplib in $deplibs; do
case " $convenience " in case " $convenience " in
*" $test_deplib "*) ;; *" $test_deplib "*) ;;
*) *)
tmp_deplibs="$tmp_deplibs $test_deplib" tmp_deplibs="$tmp_deplibs $test_deplib"
;; ;;
esac esac
done done
deplibs="$tmp_deplibs" deplibs="$tmp_deplibs"
@ -7106,12 +7106,12 @@ EOF
cmds=$module_cmds cmds=$module_cmds
fi fi
else else
if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
eval test_cmds=\"$archive_expsym_cmds\" eval test_cmds=\"$archive_expsym_cmds\"
cmds=$archive_expsym_cmds cmds=$archive_expsym_cmds
else else
eval test_cmds=\"$archive_cmds\" eval test_cmds=\"$archive_cmds\"
cmds=$archive_cmds cmds=$archive_cmds
fi fi
fi fi
@ -7177,47 +7177,47 @@ EOF
else else
if test -n "$save_libobjs"; then if test -n "$save_libobjs"; then
func_verbose "creating reloadable object files..." func_verbose "creating reloadable object files..."
output=$output_objdir/$output_la-${k}.$objext output=$output_objdir/$output_la-${k}.$objext
eval test_cmds=\"$reload_cmds\" eval test_cmds=\"$reload_cmds\"
func_len " $test_cmds" func_len " $test_cmds"
len0=$func_len_result len0=$func_len_result
len=$len0 len=$len0
# Loop over the list of objects to be linked. # Loop over the list of objects to be linked.
for obj in $save_libobjs for obj in $save_libobjs
do do
func_len " $obj" func_len " $obj"
func_arith $len + $func_len_result func_arith $len + $func_len_result
len=$func_arith_result len=$func_arith_result
if test "X$objlist" = X || if test "X$objlist" = X ||
test "$len" -lt "$max_cmd_len"; then test "$len" -lt "$max_cmd_len"; then
func_append objlist " $obj" func_append objlist " $obj"
else else
# The command $test_cmds is almost too long, add a # The command $test_cmds is almost too long, add a
# command to the queue. # command to the queue.
if test "$k" -eq 1 ; then if test "$k" -eq 1 ; then
# The first file doesn't have a previous command to add. # The first file doesn't have a previous command to add.
eval concat_cmds=\"$reload_cmds $objlist $last_robj\" eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
else else
# All subsequent reloadable object files will link in # All subsequent reloadable object files will link in
# the last one created. # the last one created.
eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
fi fi
last_robj=$output_objdir/$output_la-${k}.$objext last_robj=$output_objdir/$output_la-${k}.$objext
func_arith $k + 1 func_arith $k + 1
k=$func_arith_result k=$func_arith_result
output=$output_objdir/$output_la-${k}.$objext output=$output_objdir/$output_la-${k}.$objext
objlist=$obj objlist=$obj
func_len " $last_robj" func_len " $last_robj"
func_arith $len0 + $func_len_result func_arith $len0 + $func_len_result
len=$func_arith_result len=$func_arith_result
fi fi
done done
# Handle the remaining objects by creating one last # Handle the remaining objects by creating one last
# reloadable object file. All subsequent reloadable object # reloadable object file. All subsequent reloadable object
# files will link in the last one created. # files will link in the last one created.
test -z "$concat_cmds" || concat_cmds=$concat_cmds~ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
if test -n "$last_robj"; then if test -n "$last_robj"; then
eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
fi fi
@ -7227,26 +7227,26 @@ EOF
output= output=
fi fi
if ${skipped_export-false}; then if ${skipped_export-false}; then
func_verbose "generating symbol list for \`$libname.la'" func_verbose "generating symbol list for \`$libname.la'"
export_symbols="$output_objdir/$libname.exp" export_symbols="$output_objdir/$libname.exp"
$opt_dry_run || $RM $export_symbols $opt_dry_run || $RM $export_symbols
libobjs=$output libobjs=$output
# Append the command to create the export file. # Append the command to create the export file.
test -z "$concat_cmds" || concat_cmds=$concat_cmds~ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
if test -n "$last_robj"; then if test -n "$last_robj"; then
eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
fi fi
fi fi
test -n "$save_libobjs" && test -n "$save_libobjs" &&
func_verbose "creating a temporary reloadable object file: $output" func_verbose "creating a temporary reloadable object file: $output"
# Loop through the commands generated above and execute them. # Loop through the commands generated above and execute them.
save_ifs="$IFS"; IFS='~' save_ifs="$IFS"; IFS='~'
for cmd in $concat_cmds; do for cmd in $concat_cmds; do
IFS="$save_ifs" IFS="$save_ifs"
$opt_silent || { $opt_silent || {
func_quote_for_expand "$cmd" func_quote_for_expand "$cmd"
eval "func_echo $func_quote_for_expand_result" eval "func_echo $func_quote_for_expand_result"
@ -7263,8 +7263,8 @@ EOF
exit $lt_exit exit $lt_exit
} }
done done
IFS="$save_ifs" IFS="$save_ifs"
if test -n "$export_symbols_regex" && ${skipped_export-false}; then if test -n "$export_symbols_regex" && ${skipped_export-false}; then
func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
@ -7313,10 +7313,10 @@ EOF
cmds=$module_cmds cmds=$module_cmds
fi fi
else else
if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
cmds=$archive_expsym_cmds cmds=$archive_expsym_cmds
else else
cmds=$archive_cmds cmds=$archive_cmds
fi fi
fi fi
fi fi
@ -7519,20 +7519,20 @@ EOF
case $host in case $host in
*-*-darwin*) *-*-darwin*)
# Don't allow lazy linking, it breaks C++ global constructors # Don't allow lazy linking, it breaks C++ global constructors
# But is supposedly fixed on 10.4 or later (yay!). # But is supposedly fixed on 10.4 or later (yay!).
if test "$tagname" = CXX ; then if test "$tagname" = CXX ; then
case ${MACOSX_DEPLOYMENT_TARGET-10.0} in case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
10.[0123]) 10.[0123])
compile_command="$compile_command ${wl}-bind_at_load" compile_command="$compile_command ${wl}-bind_at_load"
finalize_command="$finalize_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load"
;; ;;
esac esac
fi fi
# Time to change all our "foo.ltframework" stuff back to "-framework foo" # Time to change all our "foo.ltframework" stuff back to "-framework foo"
compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
;; ;;
esac esac
@ -7677,25 +7677,25 @@ EOF
# template prelinking step # template prelinking step
if test -n "$prelink_cmds"; then if test -n "$prelink_cmds"; then
func_execute_cmds "$prelink_cmds" 'exit $?' func_execute_cmds "$prelink_cmds" 'exit $?'
fi fi
wrappers_required=yes wrappers_required=yes
case $host in case $host in
*cygwin* | *mingw* ) *cygwin* | *mingw* )
if test "$build_libtool_libs" != yes; then if test "$build_libtool_libs" != yes; then
wrappers_required=no wrappers_required=no
fi fi
;; ;;
*cegcc) *cegcc)
# Disable wrappers for cegcc, we are cross compiling anyway. # Disable wrappers for cegcc, we are cross compiling anyway.
wrappers_required=no wrappers_required=no
;; ;;
*) * )
if test "$need_relink" = no || test "$build_libtool_libs" != yes; then if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
wrappers_required=no wrappers_required=no
fi fi
;; ;;
esac esac
if test "$wrappers_required" = no; then if test "$wrappers_required" = no; then
# Replace the output file specification. # Replace the output file specification.
compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
@ -7835,8 +7835,8 @@ EOF
func_dirname_and_basename "$output" "" "." func_dirname_and_basename "$output" "" "."
output_name=$func_basename_result output_name=$func_basename_result
output_path=$func_dirname_result output_path=$func_dirname_result
cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrappersource="$output_path/$objdir/lt-$output_name.c"
cwrapper="$output_path/$output_name.exe" cwrapper="$output_path/$output_name.exe"
$RM $cwrappersource $cwrapper $RM $cwrappersource $cwrapper
trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
@ -7849,7 +7849,7 @@ EOF
$opt_dry_run || { $opt_dry_run || {
$LTCC $LTCFLAGS -o $cwrapper $cwrappersource $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
$STRIP $cwrapper $STRIP $cwrapper
} }
# Now, create the wrapper script for func_source use: # Now, create the wrapper script for func_source use:
func_ltwrapper_scriptname $cwrapper func_ltwrapper_scriptname $cwrapper
@ -7859,11 +7859,11 @@ EOF
# note: this script will not be executed, so do not chmod. # note: this script will not be executed, so do not chmod.
if test "x$build" = "x$host" ; then if test "x$build" = "x$host" ; then
$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
else else
func_emit_wrapper no > $func_ltwrapper_scriptname_result func_emit_wrapper no > $func_ltwrapper_scriptname_result
fi fi
} }
;; ;;
* ) * )
$RM $output $RM $output
trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
@ -7892,7 +7892,7 @@ EOF
oldobjs="$old_deplibs $non_pic_objects" oldobjs="$old_deplibs $non_pic_objects"
if test "$preload" = yes && test -f "$symfileobj"; then if test "$preload" = yes && test -f "$symfileobj"; then
oldobjs="$oldobjs $symfileobj" oldobjs="$oldobjs $symfileobj"
fi fi
fi fi
addlibs="$old_convenience" addlibs="$old_convenience"
fi fi
@ -7907,7 +7907,7 @@ EOF
# Do each command in the archive commands. # Do each command in the archive commands.
if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
cmds=$old_archive_from_new_cmds cmds=$old_archive_from_new_cmds
else else
# Add any objects from preloaded convenience libraries # Add any objects from preloaded convenience libraries
@ -7933,8 +7933,8 @@ EOF
: :
else else
$ECHO "copying selected object files to avoid basename conflicts..." $ECHO "copying selected object files to avoid basename conflicts..."
gentop="$output_objdir/${outputname}x" gentop="$output_objdir/${outputname}x"
generated="$generated $gentop" generated="$generated $gentop"
func_mkdir_p "$gentop" func_mkdir_p "$gentop"
save_oldobjs=$oldobjs save_oldobjs=$oldobjs
oldobjs= oldobjs=
@ -8000,7 +8000,7 @@ EOF
# the above command should be used before it gets too long # the above command should be used before it gets too long
oldobjs=$objlist oldobjs=$objlist
if test "$obj" = "$last_oldobj" ; then if test "$obj" = "$last_oldobj" ; then
RANLIB=$save_RANLIB RANLIB=$save_RANLIB
fi fi
test -z "$concat_cmds" || concat_cmds=$concat_cmds~ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
@ -8018,7 +8018,7 @@ EOF
fi fi
fi fi
func_execute_cmds "$cmds" 'exit $?' func_execute_cmds "$cmds" 'exit $?'
done done
test -n "$generated" && \ test -n "$generated" && \
func_show_eval "${RM}r$generated" func_show_eval "${RM}r$generated"
@ -8079,10 +8079,10 @@ EOF
*.la) *.la)
func_basename "$lib" func_basename "$lib"
name="$func_basename_result" name="$func_basename_result"
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \ test -z "$libdir" && \
func_fatal_error "\`$lib' is not a valid libtool archive" func_fatal_error "\`$lib' is not a valid libtool archive"
newdlfiles="$newdlfiles $libdir/$name" newdlfiles="$newdlfiles $libdir/$name"
;; ;;
*) newdlfiles="$newdlfiles $lib" ;; *) newdlfiles="$newdlfiles $lib" ;;
esac esac
@ -8098,10 +8098,10 @@ EOF
# the library: # the library:
func_basename "$lib" func_basename "$lib"
name="$func_basename_result" name="$func_basename_result"
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \ test -z "$libdir" && \
func_fatal_error "\`$lib' is not a valid libtool archive" func_fatal_error "\`$lib' is not a valid libtool archive"
newdlprefiles="$newdlprefiles $libdir/$name" newdlprefiles="$newdlprefiles $libdir/$name"
;; ;;
esac esac
done done
@ -8187,7 +8187,7 @@ relink_command=\"$relink_command\""
;; ;;
esac esac
exit $EXIT_SUCCESS exit $EXIT_SUCCESS
} }
{ test "$mode" = link || test "$mode" = relink; } && { test "$mode" = link || test "$mode" = relink; } &&
func_mode_link ${1+"$@"} func_mode_link ${1+"$@"}
@ -8274,18 +8274,18 @@ func_mode_uninstall ()
*" $dlname "*) ;; *" $dlname "*) ;;
*) rmfiles="$rmfiles $objdir/$dlname" ;; *) rmfiles="$rmfiles $objdir/$dlname" ;;
esac esac
test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
;; ;;
uninstall) uninstall)
if test -n "$library_names"; then if test -n "$library_names"; then
# Do each command in the postuninstall commands. # Do each command in the postuninstall commands.
func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
fi fi
if test -n "$old_library"; then if test -n "$old_library"; then
# Do each command in the old_postuninstall commands. # Do each command in the old_postuninstall commands.
func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
fi fi
# FIXME: should reinstall the best remaining shared library. # FIXME: should reinstall the best remaining shared library.
;; ;;
esac esac
@ -8331,7 +8331,7 @@ func_mode_uninstall ()
if func_ltwrapper_p "$file"; then if func_ltwrapper_p "$file"; then
if func_ltwrapper_executable_p "$file"; then if func_ltwrapper_executable_p "$file"; then
func_ltwrapper_scriptname "$file" func_ltwrapper_scriptname "$file"
relink_command= relink_command=
func_source $func_ltwrapper_scriptname_result func_source $func_ltwrapper_scriptname_result
rmfiles="$rmfiles $func_ltwrapper_scriptname_result" rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
else else

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_converters.c 1661 2011-04-28 18:54:46Z rob_bielik $
* Portable Audio I/O Library sample conversion mechanism * Portable Audio I/O Library sample conversion mechanism
* *
* Based on the Open Source API proposed by Ross Bencina * Based on the Open Source API proposed by Ross Bencina
@ -1167,8 +1167,8 @@ static void Int24_To_Int16_Dither(
void *sourceBuffer, signed int sourceStride, void *sourceBuffer, signed int sourceStride,
unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
{ {
unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *src = (unsigned char *)sourceBuffer;
PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt16 *dest = (PaInt16 *)destinationBuffer;
PaInt32 temp, dither; PaInt32 temp, dither;
@ -1189,7 +1189,7 @@ static void Int24_To_Int16_Dither(
dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); dither = PaUtil_Generate16BitTriangularDither( ditherGenerator );
*dest = (PaInt16) (((temp >> 1) + dither) >> 15); *dest = (PaInt16) (((temp >> 1) + dither) >> 15);
src += sourceStride * 3; src += sourceStride * 3;
dest += destinationStride; dest += destinationStride;
} }
} }
@ -1255,7 +1255,7 @@ static void Int24_To_Int8_Dither(
src += sourceStride * 3; src += sourceStride * 3;
dest += destinationStride; dest += destinationStride;
} }
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_front.c 1673 2011-05-06 04:40:22Z rob_bielik $
* Portable Audio I/O Library Multi-Host API front end * Portable Audio I/O Library Multi-Host API front end
* Validate function parameters and manage multiple host APIs. * Validate function parameters and manage multiple host APIs.
* *
@ -80,7 +80,8 @@
#define PA_VERSION_ 1899 #define PA_VERSION_ 1899
#define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ " " __TIME__ ")" #define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ " " __TIME__ ")"
extern void PaUtil_InitializeHotPlug();
extern void PaUtil_TerminateHotPlug();
int Pa_GetVersion( void ) int Pa_GetVersion( void )
@ -113,16 +114,26 @@ void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
} }
typedef struct _PaInternalInfo
{
PaUtilHostApiRepresentation **hostApis_;
int hostApisCount_;
int initializationCount_;
int deviceCount_;
static PaUtilHostApiRepresentation **hostApis_ = 0; PaUtilStreamRepresentation *firstOpenStream_;
static int hostApisCount_ = 0;
static int initializationCount_ = 0;
static int deviceCount_ = 0;
PaUtilStreamRepresentation *firstOpenStream_ = NULL; PaDevicesChangedCallback* devicesChangedCallback_;
void* devicesChangedCallbackUserData_;
} PaInternalInfo;
static PaInternalInfo paInternalInfo_ = {0};
#define PA_IS_INITIALISED_ (initializationCount_ != 0)
#define PA_IS_INITIALISED_ (paInternalInfo_.initializationCount_ != 0)
static int CountHostApiInitializers( void ) static int CountHostApiInitializers( void )
@ -140,17 +151,17 @@ static void TerminateHostApis( void )
/* terminate in reverse order from initialization */ /* terminate in reverse order from initialization */
PA_DEBUG(("TerminateHostApis in \n")); PA_DEBUG(("TerminateHostApis in \n"));
while( hostApisCount_ > 0 ) while( paInternalInfo_.hostApisCount_ > 0 )
{ {
--hostApisCount_; --paInternalInfo_.hostApisCount_;
hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] ); paInternalInfo_.hostApis_[paInternalInfo_.hostApisCount_]->Terminate( paInternalInfo_.hostApis_[paInternalInfo_.hostApisCount_] );
} }
hostApisCount_ = 0; paInternalInfo_.hostApisCount_ = 0;
deviceCount_ = 0; paInternalInfo_.deviceCount_ = 0;
if( hostApis_ != 0 ) if( paInternalInfo_.hostApis_ != 0 )
PaUtil_FreeMemory( hostApis_ ); PaUtil_FreeMemory( paInternalInfo_.hostApis_ );
hostApis_ = 0; paInternalInfo_.hostApis_ = 0;
PA_DEBUG(("TerminateHostApis out\n")); PA_DEBUG(("TerminateHostApis out\n"));
} }
@ -163,33 +174,33 @@ static PaError InitializeHostApis( void )
initializerCount = CountHostApiInitializers(); initializerCount = CountHostApiInitializers();
hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory( paInternalInfo_.hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory(
sizeof(PaUtilHostApiRepresentation*) * initializerCount ); sizeof(PaUtilHostApiRepresentation*) * initializerCount );
if( !hostApis_ ) if( !paInternalInfo_.hostApis_ )
{ {
result = paInsufficientMemory; result = paInsufficientMemory;
goto error; goto error;
} }
hostApisCount_ = 0; paInternalInfo_.hostApisCount_ = 0;
deviceCount_ = 0; paInternalInfo_.deviceCount_ = 0;
baseDeviceIndex = 0; baseDeviceIndex = 0;
for( i=0; i< initializerCount; ++i ) for( i=0; i< initializerCount; ++i )
{ {
hostApis_[hostApisCount_] = NULL; paInternalInfo_.hostApis_[paInternalInfo_.hostApisCount_] = NULL;
PA_DEBUG(( "before paHostApiInitializers[%d].\n",i)); PA_DEBUG(( "before paHostApiInitializers[%d].\n",i));
result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ ); result = paHostApiInitializers[i]( &paInternalInfo_.hostApis_[paInternalInfo_.hostApisCount_], paInternalInfo_.hostApisCount_ );
if( result != paNoError ) if( result != paNoError )
goto error; goto error;
PA_DEBUG(( "after paHostApiInitializers[%d].\n",i)); PA_DEBUG(( "after paHostApiInitializers[%d].\n",i));
if( hostApis_[hostApisCount_] ) if( paInternalInfo_.hostApis_[paInternalInfo_.hostApisCount_] )
{ {
PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_]; PaUtilHostApiRepresentation* hostApi = paInternalInfo_.hostApis_[paInternalInfo_.hostApisCount_];
assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount ); assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount ); assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
@ -202,9 +213,9 @@ static PaError InitializeHostApis( void )
hostApi->info.defaultOutputDevice += baseDeviceIndex; hostApi->info.defaultOutputDevice += baseDeviceIndex;
baseDeviceIndex += hostApi->info.deviceCount; baseDeviceIndex += hostApi->info.deviceCount;
deviceCount_ += hostApi->info.deviceCount; paInternalInfo_.deviceCount_ += hostApi->info.deviceCount;
++hostApisCount_; ++paInternalInfo_.hostApisCount_;
} }
} }
@ -233,15 +244,15 @@ static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
if( device < 0 ) if( device < 0 )
return -1; return -1;
while( i < hostApisCount_ while( i < paInternalInfo_.hostApisCount_
&& device >= hostApis_[i]->info.deviceCount ) && device >= paInternalInfo_.hostApis_[i]->info.deviceCount )
{ {
device -= hostApis_[i]->info.deviceCount; device -= paInternalInfo_.hostApis_[i]->info.deviceCount;
++i; ++i;
} }
if( i >= hostApisCount_ ) if( i >= paInternalInfo_.hostApisCount_ )
return -1; return -1;
if( hostSpecificDeviceIndex ) if( hostSpecificDeviceIndex )
@ -253,15 +264,15 @@ static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
static void AddOpenStream( PaStream* stream ) static void AddOpenStream( PaStream* stream )
{ {
((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_; ((PaUtilStreamRepresentation*)stream)->nextOpenStream = paInternalInfo_.firstOpenStream_;
firstOpenStream_ = (PaUtilStreamRepresentation*)stream; paInternalInfo_.firstOpenStream_ = (PaUtilStreamRepresentation*)stream;
} }
static void RemoveOpenStream( PaStream* stream ) static void RemoveOpenStream( PaStream* stream )
{ {
PaUtilStreamRepresentation *previous = NULL; PaUtilStreamRepresentation *previous = NULL;
PaUtilStreamRepresentation *current = firstOpenStream_; PaUtilStreamRepresentation *current = paInternalInfo_.firstOpenStream_;
while( current != NULL ) while( current != NULL )
{ {
@ -269,7 +280,7 @@ static void RemoveOpenStream( PaStream* stream )
{ {
if( previous == NULL ) if( previous == NULL )
{ {
firstOpenStream_ = current->nextOpenStream; paInternalInfo_.firstOpenStream_ = current->nextOpenStream;
} }
else else
{ {
@ -291,8 +302,8 @@ static void CloseOpenStreams( void )
/* we call Pa_CloseStream() here to ensure that the same destruction /* we call Pa_CloseStream() here to ensure that the same destruction
logic is used for automatically closed streams */ logic is used for automatically closed streams */
while( firstOpenStream_ != NULL ) while( paInternalInfo_.firstOpenStream_ != NULL )
Pa_CloseStream( firstOpenStream_ ); Pa_CloseStream( paInternalInfo_.firstOpenStream_ );
} }
@ -304,7 +315,7 @@ PaError Pa_Initialize( void )
if( PA_IS_INITIALISED_ ) if( PA_IS_INITIALISED_ )
{ {
++initializationCount_; ++paInternalInfo_.initializationCount_;
result = paNoError; result = paNoError;
} }
else else
@ -315,9 +326,12 @@ PaError Pa_Initialize( void )
PaUtil_InitializeClock(); PaUtil_InitializeClock();
PaUtil_ResetTraceMessages(); PaUtil_ResetTraceMessages();
/* Initialize hot plug here, so all its internal info is setup */
PaUtil_InitializeHotPlug();
result = InitializeHostApis(); result = InitializeHostApis();
if( result == paNoError ) if( result == paNoError )
++initializationCount_; ++paInternalInfo_.initializationCount_;
} }
PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result ); PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result );
@ -334,12 +348,14 @@ PaError Pa_Terminate( void )
if( PA_IS_INITIALISED_ ) if( PA_IS_INITIALISED_ )
{ {
if( --initializationCount_ == 0 ) if( --paInternalInfo_.initializationCount_ == 0 )
{ {
CloseOpenStreams(); CloseOpenStreams();
TerminateHostApis(); TerminateHostApis();
PaUtil_TerminateHotPlug();
PaUtil_DumpTraceMessages(); PaUtil_DumpTraceMessages();
} }
result = paNoError; result = paNoError;
@ -425,9 +441,9 @@ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
{ {
result = paHostApiNotFound; result = paHostApiNotFound;
for( i=0; i < hostApisCount_; ++i ) for( i=0; i < paInternalInfo_.hostApisCount_; ++i )
{ {
if( hostApis_[i]->info.type == type ) if( paInternalInfo_.hostApis_[i]->info.type == type )
{ {
result = i; result = i;
break; break;
@ -455,11 +471,11 @@ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **ho
{ {
result = paHostApiNotFound; result = paHostApiNotFound;
for( i=0; i < hostApisCount_; ++i ) for( i=0; i < paInternalInfo_.hostApisCount_; ++i )
{ {
if( hostApis_[i]->info.type == type ) if( paInternalInfo_.hostApis_[i]->info.type == type )
{ {
*hostApi = hostApis_[i]; *hostApi = paInternalInfo_.hostApis_[i];
result = paNoError; result = paNoError;
break; break;
} }
@ -504,7 +520,7 @@ PaHostApiIndex Pa_GetHostApiCount( void )
} }
else else
{ {
result = hostApisCount_; result = paInternalInfo_.hostApisCount_;
} }
PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result ); PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result );
@ -530,7 +546,7 @@ PaHostApiIndex Pa_GetDefaultHostApi( void )
/* internal consistency check: make sure that the default host api /* internal consistency check: make sure that the default host api
index is within range */ index is within range */
if( result < 0 || result >= hostApisCount_ ) if( result < 0 || result >= paInternalInfo_.hostApisCount_ )
{ {
result = paInternalError; result = paInternalError;
} }
@ -557,7 +573,7 @@ const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" )); PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" ));
} }
else if( hostApi < 0 || hostApi >= hostApisCount_ ) else if( hostApi < 0 || hostApi >= paInternalInfo_.hostApisCount_ )
{ {
info = NULL; info = NULL;
@ -567,7 +583,7 @@ const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
} }
else else
{ {
info = &hostApis_[hostApi]->info; info = &paInternalInfo_.hostApis_[hostApi]->info;
PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info )); PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info ));
@ -597,20 +613,20 @@ PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int ho
} }
else else
{ {
if( hostApi < 0 || hostApi >= hostApisCount_ ) if( hostApi < 0 || hostApi >= paInternalInfo_.hostApisCount_ )
{ {
result = paInvalidHostApi; result = paInvalidHostApi;
} }
else else
{ {
if( hostApiDeviceIndex < 0 || if( hostApiDeviceIndex < 0 ||
hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount ) hostApiDeviceIndex >= paInternalInfo_.hostApis_[hostApi]->info.deviceCount )
{ {
result = paInvalidDevice; result = paInvalidDevice;
} }
else else
{ {
result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex; result = paInternalInfo_.hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex;
} }
} }
} }
@ -633,7 +649,7 @@ PaDeviceIndex Pa_GetDeviceCount( void )
} }
else else
{ {
result = deviceCount_; result = paInternalInfo_.deviceCount_;
} }
PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result ); PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result );
@ -656,7 +672,7 @@ PaDeviceIndex Pa_GetDefaultInputDevice( void )
} }
else else
{ {
result = hostApis_[hostApi]->info.defaultInputDevice; result = paInternalInfo_.hostApis_[hostApi]->info.defaultInputDevice;
} }
PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result ); PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result );
@ -679,7 +695,7 @@ PaDeviceIndex Pa_GetDefaultOutputDevice( void )
} }
else else
{ {
result = hostApis_[hostApi]->info.defaultOutputDevice; result = paInternalInfo_.hostApis_[hostApi]->info.defaultOutputDevice;
} }
PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result ); PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result );
@ -688,6 +704,116 @@ PaDeviceIndex Pa_GetDefaultOutputDevice( void )
} }
PaError Pa_UpdateAvailableDeviceList( void )
{
PaError result = paNoError;
void **scanResults = NULL;
int *deviceCounts = NULL;
int i = 0;
PA_LOGAPI_ENTER( "Pa_UpdateAvailableDeviceList" );
if( !PA_IS_INITIALISED_ )
{
result = paNotInitialized;
goto done;
}
/* Allocate data structures used in 2-stage commit */
scanResults = (void **) PaUtil_AllocateMemory( sizeof(void*) * paInternalInfo_.hostApisCount_ );
if( !scanResults )
{
result = paInsufficientMemory;
goto done;
}
deviceCounts = ( int * ) PaUtil_AllocateMemory( sizeof( int ) * paInternalInfo_.hostApisCount_ );
if( !deviceCounts )
{
result = paInsufficientMemory;
goto done;
}
/* Phase 1: Perform a scan of new devices */
for( i = 0 ; i < paInternalInfo_.hostApisCount_ ; ++i )
{
PaUtilHostApiRepresentation *hostApi = paInternalInfo_.hostApis_[i];
PA_DEBUG(( "Scanning new device list for host api %d.\n",i));
if( hostApi->ScanDeviceInfos == NULL )
continue;
if( hostApi->ScanDeviceInfos( hostApi, i, &scanResults[ i ], &deviceCounts[ i ] ) != paNoError )
break;
}
/* Check the result of the scan operation */
if( i < paInternalInfo_.hostApisCount_ )
{
/* If failure, rollback the scan changes back to original state */
int j = 0;
for( j = 0 ; j < i ; ++j )
{
PaUtilHostApiRepresentation *hostApi = paInternalInfo_.hostApis_[j];
if( hostApi->DisposeDeviceInfos == NULL )
continue;
PA_DEBUG(( "Performing rollback for device list scan for host api %d.\n",i));
hostApi->DisposeDeviceInfos( hostApi, scanResults[ j ], deviceCounts[ j ] );
}
}
else
{
int baseDeviceIndex = 0;
paInternalInfo_.deviceCount_ = 0;
/* Otherwise, commit the scan changes to each back-end */
for( i = 0 ; i < paInternalInfo_.hostApisCount_ ; ++i )
{
PaUtilHostApiRepresentation *hostApi = paInternalInfo_.hostApis_[i];
if( hostApi->CommitDeviceInfos == NULL )
{
/* Not yet implemented for this backend. Just
assume that the baseDeviceIndex and the paInternalInfo_.deviceCount_ are
incremented according to the values in the info */
baseDeviceIndex += hostApi->info.deviceCount;
paInternalInfo_.deviceCount_ += hostApi->info.deviceCount;
continue;
}
PA_DEBUG(( "Committing device list scan for host api %d.\n",i));
if( hostApi->CommitDeviceInfos( hostApi, i, scanResults[ i ], deviceCounts[ i ] ) != paNoError )
{
PA_DEBUG(( "Committing failed (shouldn't happen) %d.\n",i));
result = paInternalError;
goto done;
}
assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
hostApi->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex;
if( hostApi->info.defaultInputDevice != paNoDevice )
hostApi->info.defaultInputDevice += baseDeviceIndex;
if( hostApi->info.defaultOutputDevice != paNoDevice )
hostApi->info.defaultOutputDevice += baseDeviceIndex;
baseDeviceIndex += hostApi->info.deviceCount;
paInternalInfo_.deviceCount_ += hostApi->info.deviceCount;
}
}
done:
if( scanResults )
PaUtil_FreeMemory( scanResults );
if( deviceCounts )
PaUtil_FreeMemory( deviceCounts );
return result;
}
const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ) const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device )
{ {
int hostSpecificDeviceIndex; int hostSpecificDeviceIndex;
@ -708,7 +834,7 @@ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device )
} }
else else
{ {
result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ]; result = paInternalInfo_.hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ];
PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" ));
PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result )); PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result ));
@ -850,7 +976,7 @@ static PaError ValidateOpenStreamParameters(
if( inputHostApiIndex != -1 ) if( inputHostApiIndex != -1 )
{ {
*hostApiInputDevice = paUseHostApiSpecificDeviceSpecification; *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification;
*hostApi = hostApis_[inputHostApiIndex]; *hostApi = paInternalInfo_.hostApis_[inputHostApiIndex];
} }
else else
{ {
@ -864,14 +990,14 @@ static PaError ValidateOpenStreamParameters(
} }
else else
{ {
if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ ) if( inputParameters->device < 0 || inputParameters->device >= paInternalInfo_.deviceCount_ )
return paInvalidDevice; return paInvalidDevice;
inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice ); inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice );
if( inputHostApiIndex < 0 ) if( inputHostApiIndex < 0 )
return paInternalError; return paInternalError;
*hostApi = hostApis_[inputHostApiIndex]; *hostApi = paInternalInfo_.hostApis_[inputHostApiIndex];
if( inputParameters->channelCount <= 0 ) if( inputParameters->channelCount <= 0 )
return paInvalidChannelCount; return paInvalidChannelCount;
@ -901,7 +1027,7 @@ static PaError ValidateOpenStreamParameters(
if( outputHostApiIndex != -1 ) if( outputHostApiIndex != -1 )
{ {
*hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification; *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification;
*hostApi = hostApis_[outputHostApiIndex]; *hostApi = paInternalInfo_.hostApis_[outputHostApiIndex];
} }
else else
{ {
@ -915,14 +1041,14 @@ static PaError ValidateOpenStreamParameters(
} }
else else
{ {
if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ ) if( outputParameters->device < 0 || outputParameters->device >= paInternalInfo_.deviceCount_ )
return paInvalidDevice; return paInvalidDevice;
outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice ); outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice );
if( outputHostApiIndex < 0 ) if( outputHostApiIndex < 0 )
return paInternalError; return paInternalError;
*hostApi = hostApis_[outputHostApiIndex]; *hostApi = paInternalInfo_.hostApis_[outputHostApiIndex];
if( outputParameters->channelCount <= 0 ) if( outputParameters->channelCount <= 0 )
return paInvalidChannelCount; return paInvalidChannelCount;
@ -1751,3 +1877,29 @@ PaError Pa_GetSampleSize( PaSampleFormat format )
return (PaError) result; return (PaError) result;
} }
extern void PaUtil_LockHotPlug();
extern void PaUtil_UnlockHotPlug();
PaError Pa_SetDevicesChangedCallback( void *userData, PaStreamFinishedCallback* devicesChangedCallback )
{
PaUtil_LockHotPlug();
paInternalInfo_.devicesChangedCallback_ = devicesChangedCallback;
paInternalInfo_.devicesChangedCallbackUserData_ = userData;
PaUtil_UnlockHotPlug();
return paNoError;
}
/* Called whenever a OS audio device change has been detected */
void PaUtil_DevicesChanged(unsigned state, void* pData)
{
(void)state;
(void)pData;
PaUtil_LockHotPlug();
if (paInternalInfo_.devicesChangedCallback_)
{
(paInternalInfo_.devicesChangedCallback_)(paInternalInfo_.devicesChangedCallbackUserData_);
}
PaUtil_UnlockHotPlug();
}

View file

@ -1,7 +1,7 @@
#ifndef PA_HOSTAPI_H #ifndef PA_HOSTAPI_H
#define PA_HOSTAPI_H #define PA_HOSTAPI_H
/* /*
* $Id$ * $Id: pa_hostapi.h 1664 2011-05-01 16:10:58Z rossb $
* Portable Audio I/O Library * Portable Audio I/O Library
* host api representation * host api representation
* *
@ -275,6 +275,37 @@ typedef struct PaUtilHostApiRepresentation {
const PaStreamParameters *inputParameters, const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters, const PaStreamParameters *outputParameters,
double sampleRate ); double sampleRate );
/**
Collect current native device information and compute a new device count.
This method should not result in the host API making any changes to its
internal data structures, instead it is the first step in a two-stage commit
process which will be completed only if all host API scans return with no errors.
Some time later the caller will either (1) pass scanResults and newDeviceCount
to CommitDeviceInfos() to complete the transaction, or (2) pass scanResults
and newDeviceCount to DisposeDeviceInfos() to abort the transaction.
*/
PaError (*ScanDeviceInfos)( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void **scanResults, int *newDeviceCount );
/**
Replace the previous device information with the device information
passed in as an argument via scanResults. This is the second/final stage of
the two-stage transaction required for updating the available device information.
This function should free any resources associated with the previous device
information.
@FIXME: this function should probably not return an error code as it should not be
permitted to fail.
*/
PaError (*CommitDeviceInfos)( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void *scanResults, int deviceCount );
/**
Free device information previously returned by ScanDeviceInfos(). This function
will be called in cases where the update available device info transaction
failed for some reason.
*/
PaError (*DisposeDeviceInfos)( struct PaUtilHostApiRepresentation *hostApi, void *scanResults, int deviceCount );
} PaUtilHostApiRepresentation; } PaUtilHostApiRepresentation;

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_process.c 1661 2011-04-28 18:54:46Z rob_bielik $
* Portable Audio I/O Library * Portable Audio I/O Library
* streamCallback <-> host buffer processing adapter * streamCallback <-> host buffer processing adapter
* *
@ -746,10 +746,10 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */ /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data) if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data)
{ {
userInput = hostInputChannels[0].data; userInput = hostInputChannels[0].data;
destBytePtr = (unsigned char *)hostInputChannels[0].data; destBytePtr = (unsigned char *)hostInputChannels[0].data;
skipInputConvert = 1; skipInputConvert = 1;
} }
else else
{ {
userInput = bp->tempInputBuffer; userInput = bp->tempInputBuffer;
@ -763,8 +763,8 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
/* setup non-interleaved ptrs */ /* setup non-interleaved ptrs */
if( bp->userInputSampleFormatIsEqualToHost && !bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data ) if( bp->userInputSampleFormatIsEqualToHost && !bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data )
{ {
for( i=0; i<bp->inputChannelCount; ++i ) for( i=0; i<bp->inputChannelCount; ++i )
{ {
bp->tempInputBufferPtrs[i] = hostInputChannels[i].data; bp->tempInputBufferPtrs[i] = hostInputChannels[i].data;
} }
skipInputConvert = 1; skipInputConvert = 1;
@ -773,9 +773,9 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
{ {
for( i=0; i<bp->inputChannelCount; ++i ) for( i=0; i<bp->inputChannelCount; ++i )
{ {
bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
i * bp->bytesPerUserInputSample * frameCount; i * bp->bytesPerUserInputSample * frameCount;
} }
} }
userInput = bp->tempInputBufferPtrs; userInput = bp->tempInputBufferPtrs;
@ -793,11 +793,11 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
} }
} }
else else
{ {
if( skipInputConvert ) if( skipInputConvert )
{ {
for( i=0; i<bp->inputChannelCount; ++i ) for( i=0; i<bp->inputChannelCount; ++i )
{ {
/* advance src ptr for next iteration */ /* advance src ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
@ -807,20 +807,20 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
{ {
for( i=0; i<bp->inputChannelCount; ++i ) for( i=0; i<bp->inputChannelCount; ++i )
{ {
bp->inputConverter( destBytePtr, destSampleStrideSamples, bp->inputConverter( destBytePtr, destSampleStrideSamples,
hostInputChannels[i].data, hostInputChannels[i].data,
hostInputChannels[i].stride, hostInputChannels[i].stride,
frameCount, &bp->ditherGenerator ); frameCount, &bp->ditherGenerator );
destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ destBytePtr += destChannelStrideBytes; /* skip to next destination channel */
/* advance src ptr for next iteration */ /* advance src ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
}
} }
} }
} }
}
/* configure user output buffer */ /* configure user output buffer */
if( bp->outputChannelCount == 0 ) if( bp->outputChannelCount == 0 )
@ -835,9 +835,9 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */ /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved ) if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved )
{ {
userOutput = hostOutputChannels[0].data; userOutput = hostOutputChannels[0].data;
skipOutputConvert = 1; skipOutputConvert = 1;
} }
else else
{ {
userOutput = bp->tempOutputBuffer; userOutput = bp->tempOutputBuffer;
@ -847,8 +847,8 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
{ {
if( bp->userOutputSampleFormatIsEqualToHost && !bp->hostOutputIsInterleaved ) if( bp->userOutputSampleFormatIsEqualToHost && !bp->hostOutputIsInterleaved )
{ {
for( i=0; i<bp->outputChannelCount; ++i ) for( i = 0; i < bp->outputChannelCount; ++i )
{ {
bp->tempOutputBufferPtrs[i] = hostOutputChannels[i].data; bp->tempOutputBufferPtrs[i] = hostOutputChannels[i].data;
} }
skipOutputConvert = 1; skipOutputConvert = 1;
@ -857,9 +857,9 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
{ {
for( i=0; i<bp->outputChannelCount; ++i ) for( i=0; i<bp->outputChannelCount; ++i )
{ {
bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
i * bp->bytesPerUserOutputSample * frameCount; i * bp->bytesPerUserOutputSample * frameCount;
} }
} }
userOutput = bp->tempOutputBufferPtrs; userOutput = bp->tempOutputBufferPtrs;
@ -895,33 +895,33 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
else else
{ {
srcBytePtr = (unsigned char *)bp->tempOutputBuffer; srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
if( bp->userOutputIsInterleaved ) if( bp->userOutputIsInterleaved )
{ {
srcSampleStrideSamples = bp->outputChannelCount; srcSampleStrideSamples = bp->outputChannelCount;
srcChannelStrideBytes = bp->bytesPerUserOutputSample; srcChannelStrideBytes = bp->bytesPerUserOutputSample;
} }
else /* user output is not interleaved */ else /* user output is not interleaved */
{ {
srcSampleStrideSamples = 1; srcSampleStrideSamples = 1;
srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample; srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
} }
for( i=0; i<bp->outputChannelCount; ++i ) for( i=0; i<bp->outputChannelCount; ++i )
{ {
bp->outputConverter( hostOutputChannels[i].data, bp->outputConverter( hostOutputChannels[i].data,
hostOutputChannels[i].stride, hostOutputChannels[i].stride,
srcBytePtr, srcSampleStrideSamples, srcBytePtr, srcSampleStrideSamples,
frameCount, &bp->ditherGenerator ); frameCount, &bp->ditherGenerator );
srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
/* advance dest ptr for next iteration */ /* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
} }
} }
} }
framesProcessed += frameCount; framesProcessed += frameCount;

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_linux_alsa.c 1661 2011-04-28 18:54:46Z rob_bielik $
* PortAudio Portable Real-Time Audio Library * PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com * Latest Version at: http://www.portaudio.com
* ALSA implementation by Joshua Haberman and Arve Knudsen * ALSA implementation by Joshua Haberman and Arve Knudsen
@ -668,6 +668,15 @@ typedef struct PaAlsaDeviceInfo
} }
PaAlsaDeviceInfo; PaAlsaDeviceInfo;
/* used for tranferring device infos during scanning / rescanning */
typedef struct PaLinuxScanDeviceInfosResults
{
PaDeviceInfo **deviceInfos;
PaDeviceIndex defaultInputDevice;
PaDeviceIndex defaultOutputDevice;
int deviceCount;
} PaLinuxScanDeviceInfosResults;
/* prototypes for functions declared in this file */ /* prototypes for functions declared in this file */
static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
@ -692,10 +701,17 @@ static PaError IsStreamStopped( PaStream *s );
static PaError IsStreamActive( PaStream *stream ); static PaError IsStreamActive( PaStream *stream );
static PaTime GetStreamTime( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream );
static double GetStreamCpuLoad( PaStream* stream ); static double GetStreamCpuLoad( PaStream* stream );
static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi ); static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi, void** scanResults, int* deviceCount );
static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate ); static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate );
static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ); static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate );
static PaError ScanDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index,
void **newDeviceInfos, int *newDeviceCount );
static PaError CommitDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index,
void *deviceInfos, int deviceCount);
static PaError DisposeDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, void *deviceInfos,
int deviceCount );
/* Callback prototypes */ /* Callback prototypes */
static void *CallbackThreadFunc( void *userData ); static void *CallbackThreadFunc( void *userData );
@ -722,6 +738,8 @@ PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
{ {
PaError result = paNoError; PaError result = paNoError;
PaAlsaHostApiRepresentation *alsaHostApi = NULL; PaAlsaHostApiRepresentation *alsaHostApi = NULL;
void* scanResults = NULL;
int deviceCount = 0;
/* Try loading Alsa library. */ /* Try loading Alsa library. */
if (!PaAlsa_LoadLibrary()) if (!PaAlsa_LoadLibrary())
@ -733,20 +751,29 @@ PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
alsaHostApi->hostApiIndex = hostApiIndex; alsaHostApi->hostApiIndex = hostApiIndex;
*hostApi = (PaUtilHostApiRepresentation*)alsaHostApi; *hostApi = (PaUtilHostApiRepresentation*)alsaHostApi;
(*hostApi)->deviceInfos = NULL;
(*hostApi)->info.structVersion = 1; (*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paALSA; (*hostApi)->info.type = paALSA;
(*hostApi)->info.name = "ALSA"; (*hostApi)->info.name = "ALSA";
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;
(*hostApi)->ScanDeviceInfos = ScanDeviceInfos;
(*hostApi)->CommitDeviceInfos = CommitDeviceInfos;
(*hostApi)->DisposeDeviceInfos = DisposeDeviceInfos;
/** If AlsaErrorHandler is to be used, do not forget to unregister callback pointer in /** If AlsaErrorHandler is to be used, do not forget to unregister callback pointer in
Terminate function. Terminate function.
*/ */
/*ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError );*/ /*ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError );*/
PA_ENSURE( BuildDeviceList( alsaHostApi ) ); ScanDeviceInfos(&alsaHostApi->baseHostApiRep, hostApiIndex, &scanResults,
&deviceCount);
CommitDeviceInfos(&alsaHostApi->baseHostApiRep, hostApiIndex, scanResults, deviceCount);
PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface, PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface,
CloseStream, StartStream, CloseStream, StartStream,
@ -802,7 +829,11 @@ static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
} }
PaUtil_FreeMemory( alsaHostApi ); PaUtil_FreeMemory( alsaHostApi );
alsa_snd_config_update_free_global(); // damencho, removed fo compability with pulseaudio versions before 0.9.16
// segfault application:
// bugtrack alsa: 0002124: snd_config_update_free_global kills applications using user space alsa plugins
// snd_config_update_free_global();
// alsa_snd_config_update_free_global();
/* Close Alsa library. */ /* Close Alsa library. */
PaAlsa_CloseLibrary(); PaAlsa_CloseLibrary();
@ -1075,7 +1106,7 @@ static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream,
} }
static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceName, int blocking, static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceName, int blocking,
PaAlsaDeviceInfo* devInfo, int* devIdx ) PaAlsaDeviceInfo* devInfo, int* devIdx, PaLinuxScanDeviceInfosResults* out )
{ {
PaError result = 0; PaError result = 0;
PaDeviceInfo *baseDeviceInfo = &devInfo->baseDeviceInfo; PaDeviceInfo *baseDeviceInfo = &devInfo->baseDeviceInfo;
@ -1128,20 +1159,20 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d
if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 ) if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 )
{ {
/* Make device default if there isn't already one or it is the ALSA "default" device */ /* Make device default if there isn't already one or it is the ALSA "default" device */
if( (baseApi->info.defaultInputDevice == paNoDevice || !strcmp(deviceName->alsaName, if( (out->defaultInputDevice == paNoDevice || !strcmp(deviceName->alsaName,
"default" )) && baseDeviceInfo->maxInputChannels > 0 ) "default" )) && baseDeviceInfo->maxInputChannels > 0 )
{ {
baseApi->info.defaultInputDevice = *devIdx; out->defaultInputDevice = *devIdx;
PA_DEBUG(("Default input device: %s\n", deviceName->name)); PA_DEBUG(("Default input device: %s\n", deviceName->name));
} }
if( (baseApi->info.defaultOutputDevice == paNoDevice || !strcmp(deviceName->alsaName, if( (out->defaultOutputDevice == paNoDevice || !strcmp(deviceName->alsaName,
"default" )) && baseDeviceInfo->maxOutputChannels > 0 ) "default" )) && baseDeviceInfo->maxOutputChannels > 0 )
{ {
baseApi->info.defaultOutputDevice = *devIdx; out->defaultOutputDevice = *devIdx;
PA_DEBUG(("Default output device: %s\n", deviceName->name)); PA_DEBUG(("Default output device: %s\n", deviceName->name));
} }
PA_DEBUG(("%s: Adding device %s: %d\n", __FUNCTION__, deviceName->name, *devIdx)); PA_DEBUG(("%s: Adding device %s: %d\n", __FUNCTION__, deviceName->name, *devIdx));
baseApi->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo; out->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo;
(*devIdx) += 1; (*devIdx) += 1;
} }
else else
@ -1154,9 +1185,10 @@ end:
} }
/* Build PaDeviceInfo list, ignore devices for which we cannot determine capabilities (possibly busy, sigh) */ /* Build PaDeviceInfo list, ignore devices for which we cannot determine capabilities (possibly busy, sigh) */
static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi, void** scanResults, int* count)
{ {
PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep;
PaLinuxScanDeviceInfosResults *outArgument = NULL;
PaAlsaDeviceInfo *deviceInfoArray; PaAlsaDeviceInfo *deviceInfoArray;
int cardIdx = -1, devIdx = 0; int cardIdx = -1, devIdx = 0;
snd_ctl_card_info_t *cardInfo; snd_ctl_card_info_t *cardInfo;
@ -1171,13 +1203,11 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
#ifdef PA_ENABLE_DEBUG_OUTPUT #ifdef PA_ENABLE_DEBUG_OUTPUT
PaTime startTime = PaUtil_GetTime(); PaTime startTime = PaUtil_GetTime();
#endif #endif
PaLinuxScanDeviceInfosResults* out = NULL;
if( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) && atoi( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) ) ) if( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) && atoi( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) ) )
blocking = 0; blocking = 0;
/* These two will be set to the first working input and output device, respectively */
baseApi->info.defaultInputDevice = paNoDevice;
baseApi->info.defaultOutputDevice = paNoDevice;
/* Gather info about hw devices /* Gather info about hw devices
@ -1341,8 +1371,14 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
else else
PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, alsa_snd_strerror( res ) )); PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, alsa_snd_strerror( res ) ));
out = (PaLinuxScanDeviceInfosResults *) PaUtil_GroupAllocateMemory(
alsaApi->allocations, sizeof(PaLinuxScanDeviceInfosResults) );
out->defaultInputDevice = paNoDevice;
out->defaultOutputDevice = paNoDevice;
/* allocate deviceInfo memory based on the number of devices */ /* allocate deviceInfo memory based on the number of devices */
PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( PA_UNLESS( out->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory ); alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory );
/* allocate all device info structs in a contiguous block */ /* allocate all device info structs in a contiguous block */
@ -1367,7 +1403,7 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
continue; continue;
} }
PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx ) ); PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx, out ) );
} }
assert( devIdx < numDeviceNames ); assert( devIdx < numDeviceNames );
/* Now inspect 'dmix' and 'default' plugins */ /* Now inspect 'dmix' and 'default' plugins */
@ -1381,11 +1417,13 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
} }
PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo,
&devIdx ) ); &devIdx, out ) );
} }
free( hwDevInfos ); free( hwDevInfos );
baseApi->info.deviceCount = devIdx; /* Number of successfully queried devices */ out->deviceCount = devIdx; /* Number of successfully queried devices */
*scanResults = out;
*count = out->deviceCount;
#ifdef PA_ENABLE_DEBUG_OUTPUT #ifdef PA_ENABLE_DEBUG_OUTPUT
PA_DEBUG(( "%s: Building device list took %f seconds\n", __FUNCTION__, PaUtil_GetTime() - startTime )); PA_DEBUG(( "%s: Building device list took %f seconds\n", __FUNCTION__, PaUtil_GetTime() - startTime ));
@ -2037,7 +2075,7 @@ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *sel
ENSURE_( alsa_snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_ENABLE ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_MMAP ), paUnanticipatedHostError );
/* Set the parameters! */ /* Set the parameters! */
ENSURE_( alsa_snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError );
@ -2194,7 +2232,7 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
#ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC #ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
if( framesPerUserBuffer != paFramesPerBufferUnspecified ) if( framesPerUserBuffer != paFramesPerBufferUnspecified )
{ {
/* Preferably the host buffer size should be a multiple of the user buffer size */ /* Preferably the host buffer size should be a multiple of the user buffer size */
if( bufferSize > framesPerUserBuffer ) if( bufferSize > framesPerUserBuffer )
@ -2271,7 +2309,7 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
else else
if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 )
framesPerHostBuffer /= 2; framesPerHostBuffer /= 2;
} }
} }
else else
{ {
@ -2291,7 +2329,7 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
#ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC #ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
if( framesPerUserBuffer != paFramesPerBufferUnspecified ) if( framesPerUserBuffer != paFramesPerBufferUnspecified )
{ {
/* Try to get a power-of-two of the user buffer size. */ /* Try to get a power-of-two of the user buffer size. */
framesPerHostBuffer = framesPerUserBuffer; framesPerHostBuffer = framesPerUserBuffer;
if( framesPerHostBuffer < bufferSize ) if( framesPerHostBuffer < bufferSize )
@ -2373,9 +2411,9 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
framesPerHostBuffer = ((minmax_diff == 2) ? max - 1 : max); framesPerHostBuffer = ((minmax_diff == 2) ? max - 1 : max);
} }
PA_DEBUG(( "%s: device period minimum = %lu\n", __FUNCTION__, min )); PA_DEBUG(( "%s: device period minimum = %lu\n", __FUNCTION__, min ));
PA_DEBUG(( "%s: device period maximum = %lu\n", __FUNCTION__, max )); PA_DEBUG(( "%s: device period maximum = %lu\n", __FUNCTION__, max ));
PA_DEBUG(( "%s: host buffer period = %lu\n", __FUNCTION__, framesPerHostBuffer )); PA_DEBUG(( "%s: host buffer period = %lu\n", __FUNCTION__, framesPerHostBuffer ));
PA_DEBUG(( "%s: host buffer period latency = %f\n", __FUNCTION__, (double)(framesPerHostBuffer / sampleRate) )); PA_DEBUG(( "%s: host buffer period latency = %f\n", __FUNCTION__, (double)(framesPerHostBuffer / sampleRate) ));
/* Try setting period size */ /* Try setting period size */
@ -3137,7 +3175,7 @@ error:
ENSURE_( alsa_snd_pcm_hw_params_get_rate_min( hwParams, &_min, &_dir ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_rate_min( hwParams, &_min, &_dir ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_hw_params_get_rate_max( hwParams, &_max, &_dir ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_rate_max( hwParams, &_max, &_dir ), paUnanticipatedHostError );
PA_DEBUG(( "%s: SR min = %d, max = %d, req = %lu\n", __FUNCTION__, _min, _max, approx )); PA_DEBUG(( "%s: SR min = %d, max = %d, req = %lu\n", __FUNCTION__, _min, _max, approx ));
} }
goto end; goto end;
} }
@ -3544,8 +3582,19 @@ static PaError PaAlsaStreamComponent_GetAvailableFrames( PaAlsaStreamComponent *
snd_pcm_sframes_t framesAvail = alsa_snd_pcm_avail_update( self->pcm ); snd_pcm_sframes_t framesAvail = alsa_snd_pcm_avail_update( self->pcm );
*xrunOccurred = 0; *xrunOccurred = 0;
if( -EPIPE == framesAvail ) /* Get pcm_state and check for xrun condition. On playback I often see
{ * xrun but avail_update does not return -EPIPE but framesAvail larger
* than bufferSize. In case of xrun status set xrun flag, leave framesize
* as reported by avail_update, will be fixed below. In case avail_update
* returns -EPIPE process as usual. wd-xxx
*/
snd_pcm_state_t state = snd_pcm_state( self->pcm ); /* wd-xxx */
if (state == SND_PCM_STATE_XRUN) {
// printf("xrun, fav %d\n", framesAvail); fflush(stdout); // DEBUG-WD
*xrunOccurred = 1;
}
if( -EPIPE == framesAvail) {
// printf("xrun-1, fav %d\n", framesAvail); fflush(stdout); // DEBUG-WD
*xrunOccurred = 1; *xrunOccurred = 1;
framesAvail = 0; framesAvail = 0;
} }
@ -3554,6 +3603,11 @@ static PaError PaAlsaStreamComponent_GetAvailableFrames( PaAlsaStreamComponent *
ENSURE_( framesAvail, paUnanticipatedHostError ); ENSURE_( framesAvail, paUnanticipatedHostError );
} }
/* Fix frames avail, should not be bigger than bufferSize wd-xxx */
if (framesAvail > self->bufferSize) {
// printf("xrun-2, fav %d\n", framesAvail); fflush(stdout); // DEBUG-WD
framesAvail = self->bufferSize;
}
*numFrames = framesAvail; *numFrames = framesAvail;
error: error:
@ -3603,6 +3657,13 @@ static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, st
*shouldPoll = 0; *shouldPoll = 0;
} }
else
{
// not actually used
unsigned long framesAvail = 0;
// now check for xrun
PaAlsaStreamComponent_GetAvailableFrames(self, &framesAvail, xrun );
}
error: error:
return result; return result;
@ -3693,6 +3754,10 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
framesAvail, &xrun ) ); framesAvail, &xrun ) );
if( xrun ) if( xrun )
{ {
if(*framesAvail == 0)
{
result = paInternalError;
}
goto end; goto end;
} }
@ -3740,6 +3805,7 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
Pa_Sleep( 1 ); /* avoid hot loop */ Pa_Sleep( 1 ); /* avoid hot loop */
continue; continue;
} }
result = paInternalError;
/* TODO: Add macro for checking system calls */ /* TODO: Add macro for checking system calls */
PA_ENSURE( paInternalError ); PA_ENSURE( paInternalError );
@ -3769,6 +3835,7 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
xrun = 1; /* try recovering device */ xrun = 1; /* try recovering device */
PA_DEBUG(( "%s: poll timed out\n", __FUNCTION__, timeouts )); PA_DEBUG(( "%s: poll timed out\n", __FUNCTION__, timeouts ));
result = paTimedOut;
goto end;/*PA_ENSURE( paTimedOut );*/ goto end;/*PA_ENSURE( paTimedOut );*/
} }
} }
@ -4144,7 +4211,7 @@ static void *CallbackThreadFunc( void *userData )
int xrun = 0; int xrun = 0;
#ifdef PTHREAD_CANCELED #ifdef PTHREAD_CANCELED
pthread_testcancel(); pthread_testcancel();
#endif #endif
/* @concern StreamStop if the main thread has requested a stop and the stream has not been effectively /* @concern StreamStop if the main thread has requested a stop and the stream has not been effectively
@ -4194,7 +4261,7 @@ static void *CallbackThreadFunc( void *userData )
xrun = 0; xrun = 0;
#ifdef PTHREAD_CANCELED #ifdef PTHREAD_CANCELED
pthread_testcancel(); pthread_testcancel();
#endif #endif
/** @concern Xruns Under/overflows are to be reported to the callback */ /** @concern Xruns Under/overflows are to be reported to the callback */
@ -4326,9 +4393,24 @@ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames )
while( frames > 0 ) while( frames > 0 )
{ {
int xrun = 0; int xrun = 0;
PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) );
framesGot = PA_MIN( framesAvail, frames ); /*
* In case of overrun WaitForFrames leaves the capture stream in STATE_PREPARED
* most of the time. handleXrun() restarts the ALSA stream only in case
* snd_pcm_recover() fails, which usually does not happen.
* Here we start the pcm stream again and go for another try. Another
* option is: set result to paOverrun and return to caller. Then
* the caller needs to call ReadStream again. This takes more time and
* we lose even more frames.
*/
if (xrun) { /* wd-xxx */
if( snd_pcm_state( stream->capture.pcm ) == SND_PCM_STATE_PREPARED ) {
ENSURE_( snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError );
}
continue;
}
framesGot = PA_MIN( framesAvail, frames );
PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) );
if( framesGot > 0 ) if( framesGot > 0 )
{ {
@ -4546,3 +4628,75 @@ PaError PaAlsa_SetRetriesBusy( int retries )
busyRetries_ = retries; busyRetries_ = retries;
return paNoError; return paNoError;
} }
static PaError ScanDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex hostApiIndex,
void **scanResults, int *newDeviceCount)
{
PaAlsaHostApiRepresentation* alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;
PaError result = paNoError;
PA_ENSURE(BuildDeviceList( alsaHostApi, scanResults, newDeviceCount ));
return paNoError;
error:
return result;
}
static PaError CommitDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index,
void *scanResults, int deviceCount)
{
PaAlsaHostApiRepresentation* alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;
PaError result = paNoError;
/* These two will be set to the first working input and output device, respectively */
hostApi->info.defaultInputDevice = paNoDevice;
hostApi->info.defaultOutputDevice = paNoDevice;
/* Free any old memory which might be in the device info */
if( hostApi->deviceInfos )
{
/* all device info structs are allocated in a block so we can destroy them here */
PaUtil_GroupFreeMemory( alsaHostApi->allocations, hostApi->deviceInfos[0] );
PaUtil_GroupFreeMemory( alsaHostApi->allocations, hostApi->deviceInfos );
hostApi->deviceInfos = NULL;
}
if( scanResults != NULL )
{
PaLinuxScanDeviceInfosResults *scanDeviceInfosResults = ( PaLinuxScanDeviceInfosResults * ) scanResults;
if( deviceCount > 0 )
{
/* use the array allocated in ScanDeviceInfos() as our deviceInfos */
hostApi->deviceInfos = scanDeviceInfosResults->deviceInfos;
hostApi->info.defaultInputDevice = scanDeviceInfosResults->defaultInputDevice;
hostApi->info.defaultOutputDevice = scanDeviceInfosResults->defaultOutputDevice;
hostApi->info.deviceCount = deviceCount;
}
PaUtil_GroupFreeMemory( alsaHostApi->allocations, scanDeviceInfosResults );
}
return result;
}
static PaError DisposeDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, void *scanResults, int deviceCount)
{
PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;
if( scanResults != NULL )
{
PaLinuxScanDeviceInfosResults *scanDeviceInfosResults = ( PaLinuxScanDeviceInfosResults * ) scanResults;
if( scanDeviceInfosResults->deviceInfos )
{
/* all device info structs are allocated in a block so we can destroy them here */
PaUtil_GroupFreeMemory( alsaHostApi->allocations, scanDeviceInfosResults->deviceInfos[0] );
PaUtil_GroupFreeMemory( alsaHostApi->allocations, scanDeviceInfosResults->deviceInfos );
}
PaUtil_GroupFreeMemory(alsaHostApi->allocations, scanDeviceInfosResults );
}
return paNoError;
}

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_asio.cpp 1661 2011-04-28 18:54:46Z rob_bielik $
* Portable Audio I/O Library for ASIO Drivers * Portable Audio I/O Library for ASIO Drivers
* *
* Author: Stephane Letz * Author: Stephane Letz
@ -1315,6 +1315,9 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
} }
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;

View file

@ -67,6 +67,8 @@
#include <string.h> /* strlen(), memcmp() etc. */ #include <string.h> /* strlen(), memcmp() etc. */
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
#include <CoreFoundation/CFString.h>
#include "pa_mac_core.h" #include "pa_mac_core.h"
#include "pa_mac_core_utilities.h" #include "pa_mac_core_utilities.h"
#include "pa_mac_core_blocking.h" #include "pa_mac_core_blocking.h"
@ -80,6 +82,27 @@ extern "C"
/* prototypes for functions declared in this file */ /* prototypes for functions declared in this file */
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
static PaError ScanDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index,
void **newDeviceInfos, int *newDeviceCount );
static PaError CommitDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index,
void *deviceInfos, int deviceCount);
static PaError DisposeDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, void *deviceInfos,
int deviceCount );
/* structures */
/* used for tranferring device infos during scanning / rescanning */
typedef struct PaMacScanDeviceInfosResults
{
PaDeviceInfo **deviceInfos;
PaDeviceIndex defaultInputDevice;
PaDeviceIndex defaultOutputDevice;
AudioDeviceID* devIds;
int devCount;
AudioDeviceID devInputDevice;
AudioDeviceID devOutputDevice;
} PaMacScanDeviceInfosResults;
/* /*
* Function declared in pa_mac_core.h. Sets up a PaMacCoreStreamInfoStruct * Function declared in pa_mac_core.h. Sets up a PaMacCoreStreamInfoStruct
@ -132,7 +155,6 @@ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input )
return NULL; return NULL;
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi; PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device]; AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device];
UInt32 size = 0; UInt32 size = 0;
error = AudioDeviceGetPropertyInfo( hostApiDevice, error = AudioDeviceGetPropertyInfo( hostApiDevice,
@ -311,46 +333,57 @@ static void startStopCallback(
} }
/*currently, this is only used in initialization, but it might be modified //static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi)
to be used when the list of devices changes.*/ static PaError gatherDeviceInfo(PaMacAUHAL* auhalHostApi, void** scanResults, int* count)
static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi)
{ {
UInt32 size; UInt32 propsize = 0;
UInt32 propsize; UInt32 size = sizeof(AudioDeviceID);
VVDBUG(("gatherDeviceInfo()\n")); PaMacScanDeviceInfosResults *outArgument = NULL;
/* -- free any previous allocations -- */ PaError result = paNoError;
if( auhalHostApi->devIds )
PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds);
auhalHostApi->devIds = NULL;
VVDBUG(("gatherDeviceInfo()\n"));
/* -- figure out how many devices there are -- */ /* -- figure out how many devices there are -- */
AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices,
&propsize, &propsize,
NULL ); NULL );
auhalHostApi->devCount = propsize / sizeof( AudioDeviceID ); *count = (propsize / sizeof(AudioDeviceID));
VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) ); VDBUG( ( "Found %ld device(s).\n", *count ) );
if(*count == 0)
return paNoError;
/* Allocate the out param for all the info we need */
outArgument = (PaMacScanDeviceInfosResults *) PaUtil_GroupAllocateMemory(
auhalHostApi->allocations, sizeof(PaMacScanDeviceInfosResults) );
if( !outArgument )
{
result = paInsufficientMemory;
return result;
}
outArgument->devCount = *count;
/* -- copy the device IDs -- */ /* -- copy the device IDs -- */
auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory( outArgument->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory(
auhalHostApi->allocations, auhalHostApi->allocations,
propsize ); propsize );
if( !auhalHostApi->devIds ) if( !outArgument->devIds )
return paInsufficientMemory; return paInsufficientMemory;
AudioHardwareGetProperty( kAudioHardwarePropertyDevices, AudioHardwareGetProperty( kAudioHardwarePropertyDevices,
&propsize, &propsize,
auhalHostApi->devIds ); outArgument->devIds );
#ifdef MAC_CORE_VERBOSE_DEBUG #ifdef MAC_CORE_VERBOSE_DEBUG
{ {
int i; int i;
for( i=0; i<auhalHostApi->devCount; ++i ) for( i=0; i<outArgument->devCount; ++i )
printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] ); printf( "Device %d\t: %ld\n", i, outArgument->devIds[i] );
} }
#endif #endif
size = sizeof(AudioDeviceID); outArgument->devInputDevice = kAudioDeviceUnknown;
auhalHostApi->defaultIn = kAudioDeviceUnknown; outArgument->devOutputDevice = kAudioDeviceUnknown;
auhalHostApi->defaultOut = kAudioDeviceUnknown;
/* determine the default device. */ /* determine the default device. */
/* I am not sure how these calls to AudioHardwareGetProperty() /* I am not sure how these calls to AudioHardwareGetProperty()
@ -358,42 +391,44 @@ static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi)
device as the default. */ device as the default. */
if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
&size, &size,
&auhalHostApi->defaultIn) ) { &outArgument->devInputDevice) ) {
int i; int i;
auhalHostApi->defaultIn = kAudioDeviceUnknown; outArgument->devInputDevice = kAudioDeviceUnknown;
VDBUG(("Failed to get default input device from OS.")); VDBUG(("Failed to get default input device from OS."));
VDBUG((" I will substitute the first available input Device.")); VDBUG((" I will substitute the first available input Device."));
for( i=0; i<auhalHostApi->devCount; ++i ) {
for( i=0; i< outArgument->devCount; ++i ) {
PaDeviceInfo devInfo; PaDeviceInfo devInfo;
if( 0 != GetChannelInfo( auhalHostApi, &devInfo, if( 0 != GetChannelInfo( auhalHostApi, &devInfo,
auhalHostApi->devIds[i], TRUE ) ) outArgument->devIds[i], TRUE ) )
if( devInfo.maxInputChannels ) { if( devInfo.maxInputChannels ) {
auhalHostApi->defaultIn = auhalHostApi->devIds[i]; outArgument->devInputDevice = outArgument->devIds[i];
break; break;
} }
} }
} }
if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
&size, &size,
&auhalHostApi->defaultOut) ) { &outArgument->devOutputDevice) ) {
int i; int i;
auhalHostApi->defaultIn = kAudioDeviceUnknown; outArgument->devOutputDevice = kAudioDeviceUnknown;
VDBUG(("Failed to get default output device from OS.")); VDBUG(("Failed to get default output device from OS."));
VDBUG((" I will substitute the first available output Device.")); VDBUG((" I will substitute the first available output Device."));
for( i=0; i<auhalHostApi->devCount; ++i ) { for( i=0; i<outArgument->devCount; ++i ) {
PaDeviceInfo devInfo; PaDeviceInfo devInfo;
if( 0 != GetChannelInfo( auhalHostApi, &devInfo, if( 0 != GetChannelInfo( auhalHostApi, &devInfo,
auhalHostApi->devIds[i], FALSE ) ) outArgument->devIds[i], FALSE ) )
if( devInfo.maxOutputChannels ) { if( devInfo.maxOutputChannels ) {
auhalHostApi->defaultOut = auhalHostApi->devIds[i]; outArgument->devOutputDevice = outArgument->devIds[i];
break; break;
} }
} }
} }
VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn ) ); VDBUG( ( "Default in : %ld\n", outArgument->devInputDevice ) );
VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) ); VDBUG( ( "Default out: %ld\n", outArgument->devOutputDevice ) );
*scanResults = outArgument;
return paNoError; return paNoError;
} }
@ -402,9 +437,9 @@ static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi,
AudioDeviceID macCoreDeviceId, AudioDeviceID macCoreDeviceId,
int isInput) int isInput)
{ {
UInt32 propSize; UInt32 propSize = 0;
PaError err = paNoError; PaError err = paNoError;
UInt32 i; UInt32 i = 0;
int numChannels = 0; int numChannels = 0;
AudioBufferList *buflist = NULL; AudioBufferList *buflist = NULL;
UInt32 frameLatency; UInt32 frameLatency;
@ -488,9 +523,111 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
memset(deviceInfo, 0, sizeof(deviceInfo)); memset(deviceInfo, 0, sizeof(deviceInfo));
deviceInfo->structVersion = 2; deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex; deviceInfo->hostApi = hostApiIndex;
// target device UID property
unsigned long deviceUID = 0;
AudioObjectPropertyAddress addr;
addr.mSelector = kAudioDevicePropertyDeviceUID;
addr.mScope = kAudioObjectPropertyScopeGlobal;
addr.mElement = kAudioObjectPropertyElementMaster;
CFStringRef deviceUIDString;
propSize = sizeof(deviceUIDString);
err = ERR(AudioObjectGetPropertyData(
macCoreDeviceId,
&addr,
0,
NULL,
&propSize,
&deviceUIDString));
if (err)
return err;
CFIndex deviceUIDLength = CFStringGetLength(deviceUIDString) + 1;
char *ASCIIDeviceUID
= PaUtil_GroupAllocateMemory(auhalHostApi->allocations,deviceUIDLength);
if ( !ASCIIDeviceUID )
return paInsufficientMemory;
deviceInfo->deviceUID = NULL;
if(CFStringGetCString (
deviceUIDString,
ASCIIDeviceUID,
deviceUIDLength,
kCFStringEncodingASCII))
{
deviceInfo->deviceUID = ASCIIDeviceUID;
}
// target device transport type property
addr.mSelector = kAudioDevicePropertyTransportType;
addr.mScope = kAudioObjectPropertyScopeGlobal;
addr.mElement = kAudioObjectPropertyElementMaster;
unsigned int transportType = 0;
propSize = sizeof(transportType);
err = ERR(AudioObjectGetPropertyData(
macCoreDeviceId,
&addr,
0,
NULL,
&propSize,
&transportType));
if (err)
return err;
switch(transportType)
{
case kAudioDeviceTransportTypeAggregate:
deviceInfo->transportType = "Aggregate";
break;
case kAudioDeviceTransportTypeAirPlay:
deviceInfo->transportType = "AirPlay";
break;
case kAudioDeviceTransportTypeAutoAggregate:
deviceInfo->transportType = "Auto aggregate";
break;
case kAudioDeviceTransportTypeAVB:
deviceInfo->transportType = "AVB";
break;
case kAudioDeviceTransportTypeBluetooth:
deviceInfo->transportType = "Bluetooth";
break;
case kAudioDeviceTransportTypeBuiltIn:
deviceInfo->transportType = "Built-in";
break;
case kAudioDeviceTransportTypeDisplayPort:
deviceInfo->transportType = "DisplayPort";
break;
case kAudioDeviceTransportTypeFireWire:
deviceInfo->transportType = "FireWire";
break;
case kAudioDeviceTransportTypeHDMI:
deviceInfo->transportType = "HDMI";
break;
case kAudioDeviceTransportTypePCI:
deviceInfo->transportType = "PCI";
break;
case kAudioDeviceTransportTypeThunderbolt:
deviceInfo->transportType = "Thunderbolt";
break;
case kAudioDeviceTransportTypeUnknown:
deviceInfo->transportType = "Unknown";
break;
case kAudioDeviceTransportTypeUSB:
deviceInfo->transportType = "USB";
break;
case kAudioDeviceTransportTypeVirtual:
deviceInfo->transportType = "Virtual";
break;
default:
deviceInfo->transportType = NULL;
break;
}
/* Get the device name. Fail if we can't get it. */ /* Get the device name. Fail if we can't get it. */
err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL)); err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
if (err) if (err)
@ -528,10 +665,10 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
{ {
PaError result = paNoError; PaError result = paNoError;
int i;
PaMacAUHAL *auhalHostApi = NULL; PaMacAUHAL *auhalHostApi = NULL;
PaDeviceInfo *deviceInfoArray;
int unixErr; int unixErr;
void* scanResults = NULL;
int deviceCount = 0;
VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex)); VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex));
@ -572,65 +709,29 @@ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIn
auhalHostApi->devIds = NULL; auhalHostApi->devIds = NULL;
auhalHostApi->devCount = 0; auhalHostApi->devCount = 0;
/* get the info we need about the devices */
result = gatherDeviceInfo( auhalHostApi );
if( result != paNoError )
goto error;
*hostApi = &auhalHostApi->inheritedHostApiRep; *hostApi = &auhalHostApi->inheritedHostApiRep;
(*hostApi)->info.structVersion = 1; (*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paCoreAudio; (*hostApi)->info.type = paCoreAudio;
(*hostApi)->info.name = "Core Audio"; (*hostApi)->info.name = "Core Audio";
(*hostApi)->deviceInfos = NULL;
(*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultInputDevice = paNoDevice;
(*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice;
(*hostApi)->info.deviceCount = 0; (*hostApi)->info.deviceCount = 0;
if( auhalHostApi->devCount > 0 ) (*hostApi)->ScanDeviceInfos = ScanDeviceInfos;
{ (*hostApi)->CommitDeviceInfos = CommitDeviceInfos;
(*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( (*hostApi)->DisposeDeviceInfos = DisposeDeviceInfos;
auhalHostApi->allocations, sizeof(PaDeviceInfo*) * auhalHostApi->devCount);
if( !(*hostApi)->deviceInfos )
{
result = paInsufficientMemory;
goto error;
}
/* allocate all device info structs in a contiguous block */ result = ScanDeviceInfos(&auhalHostApi->inheritedHostApiRep, hostApiIndex, &scanResults,
deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( &deviceCount);
auhalHostApi->allocations, sizeof(PaDeviceInfo) * auhalHostApi->devCount );
if( !deviceInfoArray )
{
result = paInsufficientMemory;
goto error;
}
for( i=0; i < auhalHostApi->devCount; ++i ) if(result != paNoError)
{ goto error;
int err;
err = InitializeDeviceInfo( auhalHostApi, &deviceInfoArray[i], /* FIXME for now we ignore the result of CommitDeviceInfos(), it should probably be an atomic non-failing operation */
auhalHostApi->devIds[i], CommitDeviceInfos( &auhalHostApi->inheritedHostApiRep, hostApiIndex, scanResults, deviceCount );
hostApiIndex );
if (err == paNoError)
{ /* copy some info and set the defaults */
(*hostApi)->deviceInfos[(*hostApi)->info.deviceCount] = &deviceInfoArray[i];
if (auhalHostApi->devIds[i] == auhalHostApi->defaultIn)
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
if (auhalHostApi->devIds[i] == auhalHostApi->defaultOut)
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
(*hostApi)->info.deviceCount++;
}
else
{ /* there was an error. we need to shift the devices down, so we ignore this one */
int j;
auhalHostApi->devCount--;
for( j=i; j<auhalHostApi->devCount; ++j )
auhalHostApi->devIds[j] = auhalHostApi->devIds[j+1];
i--;
}
}
}
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
@ -1756,10 +1857,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
AudioDeviceAddPropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency, AudioDeviceAddPropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency,
AudioDevicePropertyInputLatencySamplesListenerProc, stream ); AudioDevicePropertyInputLatencySamplesListenerProc, stream );
}else{ } else {
stream->deviceInputLatencySamples = 0; stream->deviceInputLatencySamples = 0;
stream->deviceInputLatencySamples_ioProcCopy = 0; stream->deviceInputLatencySamples_ioProcCopy = 0;
} }
stream->state = STOPPED; stream->state = STOPPED;
stream->xrunFlags = 0; stream->xrunFlags = 0;
@ -1869,7 +1970,7 @@ static OSStatus AudioIOProc( void *inRefCon,
stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate; stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples; stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples;
pthread_mutex_unlock( &stream->timingInformationMutex ); pthread_mutex_unlock( &stream->timingInformationMutex );
} }
/* For timeInfo.currentTime we could calculate current time backwards from the HAL audio /* For timeInfo.currentTime we could calculate current time backwards from the HAL audio
output time to give a more accurate impression of the current timeslice but it doesn't output time to give a more accurate impression of the current timeslice but it doesn't
@ -1899,7 +2000,7 @@ static OSStatus AudioIOProc( void *inRefCon,
- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here? - stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime) timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; + stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
} }
else /* full duplex with ring-buffer from a separate input AUHAL ioproc */ else /* full duplex with ring-buffer from a separate input AUHAL ioproc */
{ {
/* FIXME: review. this computation of inputBufferAdcTime is definitely wrong since it doesn't take the ring buffer latency into account */ /* FIXME: review. this computation of inputBufferAdcTime is definitely wrong since it doesn't take the ring buffer latency into account */
@ -2261,7 +2362,7 @@ static PaError CloseStream( PaStream* s )
if( stream ) { if( stream ) {
if( stream->outputUnit ) { if( stream->outputUnit ) {
AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate, AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate,
AudioDevicePropertyActualSampleRateListenerProc ); AudioDevicePropertyActualSampleRateListenerProc );
AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency, AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency,
@ -2359,15 +2460,32 @@ static PaError StartStream( PaStream *s )
// it's not clear from appl's docs that this really waits // it's not clear from appl's docs that this really waits
// until all data is flushed. // until all data is flushed.
static ComponentResult BlockWhileAudioUnitIsRunning( AudioUnit audioUnit, AudioUnitElement element ) static ComponentResult BlockWhileAudioUnitIsRunning(
AudioUnit audioUnit,
AudioUnitElement element)
{ {
long waitTime = 100;
// If PaUtil_GetRingBufferWriteAvailable starts repetitively and
// consecutively returning that there is no data available, do eventually
// give up in order to allow the caller to handle such cases.
long totalTimeout = 0;
Boolean isRunning = 1; Boolean isRunning = 1;
while( isRunning ) { while( isRunning ) {
UInt32 s = sizeof( isRunning ); UInt32 s = sizeof( isRunning );
ComponentResult err = AudioUnitGetProperty( audioUnit, kAudioOutputUnitProperty_IsRunning, kAudioUnitScope_Global, element, &isRunning, &s ); ComponentResult err = AudioUnitGetProperty( audioUnit, kAudioOutputUnitProperty_IsRunning, kAudioUnitScope_Global, element, &isRunning, &s );
if( err ) if( err )
return err; return err;
Pa_Sleep( 100 ); Pa_Sleep( waitTime );
// If a timeout is encountered, continue. However, testing has
// shown that it is possible to unplug a device and to wait here
// forever. In order to allow the caller to handle such cases of
// repeated timeouts, do eventually given up.
totalTimeout += waitTime;
if( PA_COREAUDIO_MIN_TIMEOUT_MSEC_ <= totalTimeout)
{
return paTimedOut;
}
} }
return noErr; return noErr;
} }
@ -2380,7 +2498,7 @@ static PaError StopStream( PaStream *s )
VVDBUG(("StopStream()\n")); VVDBUG(("StopStream()\n"));
VDBUG( ("Waiting for BLIO.\n") ); VDBUG( ("Waiting for BLIO.\n") );
waitUntilBlioWriteBufferIsFlushed( &stream->blio ); waitUntilBlioWriteBufferIsFlushed( &stream->blio);
VDBUG( ( "Stopping stream.\n" ) ); VDBUG( ( "Stopping stream.\n" ) );
stream->state = STOPPING; stream->state = STOPPING;
@ -2406,7 +2524,7 @@ static PaError StopStream( PaStream *s )
if( stream->outputUnit ) if( stream->outputUnit )
{ {
ERR_WRAP(AudioOutputUnitStop(stream->outputUnit)); ERR_WRAP(AudioOutputUnitStop(stream->outputUnit));
ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0));
ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0)); ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0));
} }
} }
@ -2468,3 +2586,148 @@ static double GetStreamCpuLoad( PaStream* s )
return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
} }
static PaError ScanDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex hostApiIndex,
void **scanResults, int *newDeviceCount)
{
PaMacAUHAL* auhalHostApi = (PaMacAUHAL*)hostApi;
PaDeviceInfo *deviceInfoArray = NULL;
PaError result = paNoError;
int i = 0;
PaMacScanDeviceInfosResults* out = NULL;
/* get the info we need about the devices */
result = gatherDeviceInfo( auhalHostApi, scanResults, newDeviceCount );
if( result != paNoError )
return result;
out = (PaMacScanDeviceInfosResults*)*scanResults;
if( out->devCount > 0 )
{
int count = 0;
/* allocate array for pointers to PaDeviceInfo structs */
out->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
auhalHostApi->allocations, sizeof(PaDeviceInfo*) * out->devCount);
if( !out->deviceInfos )
{
result = paInsufficientMemory;
return result;
}
/* allocate all device info structs in a contiguous block */
deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
auhalHostApi->allocations, sizeof(PaDeviceInfo) * out->devCount );
if( !deviceInfoArray )
{
result = paInsufficientMemory;
return result;
}
for( i=0; i < out->devCount; ++i )
{
int err;
err = InitializeDeviceInfo( auhalHostApi, &deviceInfoArray[i],
out->devIds[i],
hostApiIndex );
if (err == paNoError)
{
/* copy some info and set the defaults */
out->deviceInfos[count] = &deviceInfoArray[i];
if (out->devIds[i] == out->devInputDevice)
{
out->defaultInputDevice = count;
}
if (out->devIds[i] == out->devOutputDevice)
{
out->defaultOutputDevice = count;
}
count++;
}
else
{
/* there was an error. we need to shift the devices down, so we ignore this one */
int j;
out->devCount--;
for( j=i; j<out->devCount; ++j )
out->devIds[j] = out->devIds[j+1];
i--;
}
}
}
*newDeviceCount = out->devCount;
return paNoError;
}
static PaError CommitDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index,
void *scanResults, int deviceCount)
{
PaMacAUHAL* auhalHostApi = (PaMacAUHAL*)hostApi;
PaError result = paNoError;
hostApi->info.deviceCount = 0;
hostApi->info.defaultInputDevice = paNoDevice;
hostApi->info.defaultOutputDevice = paNoDevice;
/* -- free any previous allocations -- */
if( auhalHostApi->devIds )
{
PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds);
}
auhalHostApi->devIds = NULL;
/* Free any old memory which might be in the device info */
if( hostApi->deviceInfos )
{
PaUtil_GroupFreeMemory( auhalHostApi->allocations, hostApi->deviceInfos[0] );
PaUtil_GroupFreeMemory( auhalHostApi->allocations, hostApi->deviceInfos );
hostApi->deviceInfos = NULL;
}
if( scanResults != NULL )
{
PaMacScanDeviceInfosResults *scanDeviceInfosResults = ( PaMacScanDeviceInfosResults * ) scanResults;
if( deviceCount > 0 )
{
/* use the array allocated in ScanDeviceInfos() as our deviceInfos */
hostApi->deviceInfos = scanDeviceInfosResults->deviceInfos;
hostApi->info.defaultInputDevice = scanDeviceInfosResults->defaultInputDevice;
hostApi->info.defaultOutputDevice = scanDeviceInfosResults->defaultOutputDevice;
hostApi->info.deviceCount = deviceCount;
auhalHostApi->devIds = scanDeviceInfosResults->devIds;
auhalHostApi->devCount = scanDeviceInfosResults->devCount;
auhalHostApi->defaultIn = scanDeviceInfosResults->devInputDevice;
auhalHostApi->defaultOut = scanDeviceInfosResults->devOutputDevice;
}
PaUtil_GroupFreeMemory( auhalHostApi->allocations, scanDeviceInfosResults );
}
return result;
}
static PaError DisposeDeviceInfos(struct PaUtilHostApiRepresentation *hostApi, void *scanResults, int deviceCount)
{
PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi;
if( scanResults != NULL )
{
PaMacScanDeviceInfosResults *scanDeviceInfosResults = ( PaMacScanDeviceInfosResults * ) scanResults;
if( scanDeviceInfosResults->deviceInfos )
{
/* all device info structs are allocated in a block so we can destroy them here */
PaUtil_GroupFreeMemory( auhalHostApi->allocations, scanDeviceInfosResults->deviceInfos[0] );
PaUtil_GroupFreeMemory( auhalHostApi->allocations, scanDeviceInfosResults->deviceInfos );
}
PaUtil_GroupFreeMemory(auhalHostApi->allocations, scanDeviceInfosResults );
}
return paNoError;
}

View file

@ -415,6 +415,10 @@ PaError ReadStream( PaStream* stream,
while( frames > 0 ) { while( frames > 0 ) {
long avail; long avail;
long toRead; long toRead;
// If PaUtil_GetRingBufferReadAvailable starts repetitively and
// consecutively returning that there is no data available, do eventually
// give up in order to allow the caller to handle such cases.
long totalTimeout = 0;
do { do {
avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ); avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
/* /*
@ -438,6 +442,16 @@ PaError ReadStream( PaStream* stream,
return ret; return ret;
#else #else
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
// If a timeout is encountered, continue. However, testing has
// shown that it is possible to unplug a device and to wait here
// forever. In order to allow the caller to handle such cases of
// repeated timeouts, do eventually given up.
totalTimeout += PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL;
if( PA_COREAUDIO_MAX_TIMEOUT_MSEC_ <= totalTimeout)
{
return paTimedOut;
}
#endif #endif
} }
} while( avail == 0 ); } while( avail == 0 );
@ -491,6 +505,10 @@ PaError WriteStream( PaStream* stream,
while( frames > 0 ) { while( frames > 0 ) {
long avail = 0; long avail = 0;
long toWrite; long toWrite;
// If PaUtil_GetRingBufferWriteAvailable starts repetitively and
// consecutively returning that there is no data available, do eventually
// give up in order to allow the caller to handle such cases.
long totalTimeout = 0;
do { do {
avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
@ -515,6 +533,16 @@ PaError WriteStream( PaStream* stream,
return ret; return ret;
#else #else
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
// If a timeout is encountered, continue. However, testing has
// shown that it is possible to unplug a device and to wait here
// forever. In order to allow the caller to handle such cases of
// repeated timeouts, do eventually given up.
totalTimeout += PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL;
if( PA_COREAUDIO_MAX_TIMEOUT_MSEC_ <= totalTimeout)
{
return paTimedOut;
}
#endif #endif
} }
} while( avail == 0 ); } while( avail == 0 );
@ -561,13 +589,30 @@ PaError WriteStream( PaStream* stream,
void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ) void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio )
{ {
if( blio->outputRingBuffer.buffer ) { if( blio->outputRingBuffer.buffer ) {
// If PaUtil_GetRingBufferWriteAvailable starts repetitively and
// consecutively returning that there is no data available, do eventually
// give up in order to allow the caller to handle such cases.
long totalTimeout = 0;
long avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); long avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
while( avail != blio->outputRingBuffer.bufferSize ) { while( avail != blio->outputRingBuffer.bufferSize ) {
if( avail == 0 ) if( avail == 0 )
{
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
// If a timeout is encountered, continue. However, testing has
// shown that it is possible to unplug a device and to wait here
// forever. In order to allow the caller to handle such cases of
// repeated timeouts, do eventually given up.
totalTimeout += PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL;
if( PA_COREAUDIO_MIN_TIMEOUT_MSEC_ <= totalTimeout)
{
return paTimedOut;
}
}
avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
} }
} }
return paNoError;
} }

View file

@ -76,6 +76,9 @@
#define PA_MAC_BLIO_MUTEX #define PA_MAC_BLIO_MUTEX
*/ */
#define PA_COREAUDIO_MIN_TIMEOUT_MSEC_ (1000)
#define PA_COREAUDIO_MAX_TIMEOUT_MSEC_ (2000)
typedef struct { typedef struct {
PaUtilRingBuffer inputRingBuffer; PaUtilRingBuffer inputRingBuffer;
PaUtilRingBuffer outputRingBuffer; PaUtilRingBuffer outputRingBuffer;

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_jack.c 1661 2011-04-28 18:54:46Z rob_bielik $
* PortAudio Portable Real-Time Audio Library * PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com * Latest Version at: http://www.portaudio.com
* JACK Implementation by Joshua Haberman * JACK Implementation by Joshua Haberman
@ -749,6 +749,9 @@ PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi,
/* Register functions */ /* Register functions */
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;
@ -1181,7 +1184,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
minimum_buffer_frames = jackHostApi->jack_buffer_size * 3; minimum_buffer_frames = jackHostApi->jack_buffer_size * 3;
/* setup blocking API data structures (FIXME: can fail) */ /* setup blocking API data structures (FIXME: can fail) */
BlockingBegin( stream, minimum_buffer_frames ); BlockingBegin( stream, minimum_buffer_frames );
/* install our own callback for the blocking API */ /* install our own callback for the blocking API */
streamCallback = BlockingCallback; streamCallback = BlockingCallback;

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_unix_oss.c 1661 2011-04-28 18:54:46Z rob_bielik $
* PortAudio Portable Real-Time Audio Library * PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com * Latest Version at: http://www.portaudio.com
* OSS implementation by: * OSS implementation by:
@ -256,6 +256,9 @@ PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
PA_ENSURE( BuildDeviceList( ossHostApi ) ); PA_ENSURE( BuildDeviceList( ossHostApi ) );

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_hostapi_skeleton.c 1661 2011-04-28 18:54:46Z rob_bielik $
* Portable Audio I/O Library skeleton implementation * Portable Audio I/O Library skeleton implementation
* demonstrates how to use the common functions to implement support * demonstrates how to use the common functions to implement support
* for a host API * for a host API
@ -206,9 +206,15 @@ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiI
} }
} }
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream, PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive, StopStream, AbortStream, IsStreamStopped, IsStreamActive,

View file

@ -83,13 +83,13 @@
#define _WIN32_WINNT WINVER #define _WIN32_WINNT WINVER
#ifndef _AVRT_ //<< fix MinGW dummy compile by defining missing type: AVRT_PRIORITY #ifndef _AVRT_ //<< fix MinGW dummy compile by defining missing type: AVRT_PRIORITY
typedef enum _AVRT_PRIORITY typedef enum _AVRT_PRIORITY
{ {
AVRT_PRIORITY_LOW = -1, AVRT_PRIORITY_LOW = -1,
AVRT_PRIORITY_NORMAL, AVRT_PRIORITY_NORMAL,
AVRT_PRIORITY_HIGH, AVRT_PRIORITY_HIGH,
AVRT_PRIORITY_CRITICAL AVRT_PRIORITY_CRITICAL
} AVRT_PRIORITY, *PAVRT_PRIORITY; } AVRT_PRIORITY, *PAVRT_PRIORITY;
#endif #endif
#include <basetyps.h> // << for IID/CLSID #include <basetyps.h> // << for IID/CLSID
@ -363,10 +363,10 @@ PaWasapiDeviceInfo;
typedef struct typedef struct
{ {
PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilHostApiRepresentation inheritedHostApiRep;
PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface callbackStreamInterface;
PaUtilStreamInterface blockingStreamInterface; PaUtilStreamInterface blockingStreamInterface;
PaUtilAllocationGroup *allocations; PaUtilAllocationGroup *allocations;
/* implementation specific data goes here */ /* implementation specific data goes here */
@ -450,22 +450,22 @@ typedef struct PaWasapiStream
{ {
/* IMPLEMENT ME: rename this */ /* IMPLEMENT ME: rename this */
PaUtilStreamRepresentation streamRepresentation; PaUtilStreamRepresentation streamRepresentation;
PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilCpuLoadMeasurer cpuLoadMeasurer;
PaUtilBufferProcessor bufferProcessor; PaUtilBufferProcessor bufferProcessor;
// input // input
PaWasapiSubStream in; PaWasapiSubStream in;
IAudioCaptureClient *captureClientParent; IAudioCaptureClient *captureClientParent;
IStream *captureClientStream; IStream *captureClientStream;
IAudioCaptureClient *captureClient; IAudioCaptureClient *captureClient;
IAudioEndpointVolume *inVol; IAudioEndpointVolume *inVol;
// output // output
PaWasapiSubStream out; PaWasapiSubStream out;
IAudioRenderClient *renderClientParent; IAudioRenderClient *renderClientParent;
IStream *renderClientStream; IStream *renderClientStream;
IAudioRenderClient *renderClient; IAudioRenderClient *renderClient;
IAudioEndpointVolume *outVol; IAudioEndpointVolume *outVol;
// event handles for event-driven processing mode // event handles for event-driven processing mode
HANDLE event[S_COUNT]; HANDLE event[S_COUNT];
@ -1034,7 +1034,7 @@ static MixMonoToStereoF _GetMonoToStereoMixer(PaSampleFormat format, EMixerDir d
case paInt24: return _MixMonoToStereo_2TO1_24_L; case paInt24: return _MixMonoToStereo_2TO1_24_L;
case paInt32: return _MixMonoToStereo_2TO1_32_L; case paInt32: return _MixMonoToStereo_2TO1_32_L;
case paFloat32: return _MixMonoToStereo_2TO1_32f_L; case paFloat32: return _MixMonoToStereo_2TO1_32f_L;
} }
break; break;
} }
@ -1118,7 +1118,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
// We need to set the result to a value otherwise we will return paNoError // We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);] // [IF_FAILED_JUMP(hResult, error);]
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error); IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
} }
} }
else else
{ {
@ -1142,7 +1142,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
// We need to set the result to a value otherwise we will return paNoError // We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);] // [IF_FAILED_JUMP(hResult, error);]
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error); IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
} }
} }
else else
{ {
@ -1386,6 +1386,9 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
} }
} }
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;
@ -1572,20 +1575,20 @@ static void LogWAVEFORMATEXTENSIBLE(const WAVEFORMATEXTENSIBLE *in)
{ {
case WAVE_FORMAT_EXTENSIBLE: { case WAVE_FORMAT_EXTENSIBLE: {
PRINT(("wFormatTag =WAVE_FORMAT_EXTENSIBLE\n")); PRINT(("wFormatTag=WAVE_FORMAT_EXTENSIBLE\n"));
if (IsEqualGUID(&in->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) if (IsEqualGUID(&in->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))
{ {
PRINT(("SubFormat =KSDATAFORMAT_SUBTYPE_IEEE_FLOAT\n")); PRINT(("SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT\n"));
} }
else else
if (IsEqualGUID(&in->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_PCM)) if (IsEqualGUID(&in->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_PCM))
{ {
PRINT(("SubFormat =KSDATAFORMAT_SUBTYPE_PCM\n")); PRINT(("SubFormat=KSDATAFORMAT_SUBTYPE_PCM\n"));
} }
else else
{ {
PRINT(("SubFormat =CUSTOM GUID{%d:%d:%d:%d%d%d%d%d%d%d%d}\n", PRINT(("SubFormat=CUSTOM GUID{%d:%d:%d:%d%d%d%d%d%d%d%d}\n",
in->SubFormat.Data1, in->SubFormat.Data1,
in->SubFormat.Data2, in->SubFormat.Data2,
in->SubFormat.Data3, in->SubFormat.Data3,
@ -1598,13 +1601,13 @@ static void LogWAVEFORMATEXTENSIBLE(const WAVEFORMATEXTENSIBLE *in)
(int)in->SubFormat.Data4[6], (int)in->SubFormat.Data4[6],
(int)in->SubFormat.Data4[7])); (int)in->SubFormat.Data4[7]));
} }
PRINT(("Samples.wValidBitsPerSample =%d\n", in->Samples.wValidBitsPerSample)); PRINT(("Samples.wValidBitsPerSample=%d\n", in->Samples.wValidBitsPerSample));
PRINT(("dwChannelMask =0x%X\n",in->dwChannelMask)); PRINT(("dwChannelMask =0x%X\n",in->dwChannelMask));
break; } break; }
case WAVE_FORMAT_PCM: PRINT(("wFormatTag =WAVE_FORMAT_PCM\n")); break; case WAVE_FORMAT_PCM: PRINT(("wFormatTag=WAVE_FORMAT_PCM\n")); break;
case WAVE_FORMAT_IEEE_FLOAT: PRINT(("wFormatTag =WAVE_FORMAT_IEEE_FLOAT\n")); break; case WAVE_FORMAT_IEEE_FLOAT: PRINT(("wFormatTag=WAVE_FORMAT_IEEE_FLOAT\n")); break;
default: default:
PRINT(("wFormatTag =UNKNOWN(%d)\n",old->wFormatTag)); break; PRINT(("wFormatTag =UNKNOWN(%d)\n",old->wFormatTag)); break;
} }
@ -1689,13 +1692,13 @@ static PaError MakeWaveFormatFromParams(WAVEFORMATEXTENSIBLE *wavex, const PaStr
old->nBlockAlign = (old->nChannels * (old->wBitsPerSample/8)); old->nBlockAlign = (old->nChannels * (old->wBitsPerSample/8));
old->nAvgBytesPerSec = (old->nSamplesPerSec * old->nBlockAlign); old->nAvgBytesPerSec = (old->nSamplesPerSec * old->nBlockAlign);
// WAVEFORMATEX //WAVEFORMATEX
if ((params->channelCount <= 2) && ((bitsPerSample == 16) || (bitsPerSample == 8))) if ((params->channelCount <= 2) && ((bitsPerSample == 16) || (bitsPerSample == 8)))
{ {
old->cbSize = 0; old->cbSize = 0;
old->wFormatTag = WAVE_FORMAT_PCM; old->wFormatTag = WAVE_FORMAT_PCM;
} }
// WAVEFORMATEXTENSIBLE //WAVEFORMATEXTENSIBLE
else else
{ {
old->wFormatTag = WAVE_FORMAT_EXTENSIBLE; old->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
@ -1894,7 +1897,7 @@ static PaError GetClosestFormat(IAudioClient *myClient, double sampleRate,
// Try selecting suitable sample type // Try selecting suitable sample type
for (i = 0; i < STATIC_ARRAY_SIZE(BestToWorst); ++i) for (i = 0; i < STATIC_ARRAY_SIZE(BestToWorst); ++i)
{ {
WAVEFORMATEXTENSIBLE sample = { 0 }; WAVEFORMATEXTENSIBLE sample = { 0 };
PaStreamParameters sample_params = stereo_params; PaStreamParameters sample_params = stereo_params;
@ -1904,7 +1907,7 @@ static PaError GetClosestFormat(IAudioClient *myClient, double sampleRate,
hr = IAudioClient_IsFormatSupported(myClient, shareMode, &sample.Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL)); hr = IAudioClient_IsFormatSupported(myClient, shareMode, &sample.Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));
if (hr == S_OK) if (hr == S_OK)
{ {
memcpy(outWavex, &sample, sizeof(WAVEFORMATEXTENSIBLE)); memcpy(outWavex, &sample, sizeof(WAVEFORMATEXTENSIBLE));
CoTaskMemFree(sharedClosestMatch); CoTaskMemFree(sharedClosestMatch);
return (answer = paFormatIsSupported); return (answer = paFormatIsSupported);
@ -1923,14 +1926,14 @@ static PaError GetClosestFormat(IAudioClient *myClient, double sampleRate,
MakeWaveFormatFromParams(&spfmt, &spfmt_params, sampleRate); MakeWaveFormatFromParams(&spfmt, &spfmt_params, sampleRate);
hr = IAudioClient_IsFormatSupported(myClient, shareMode, &spfmt.Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL)); hr = IAudioClient_IsFormatSupported(myClient, shareMode, &spfmt.Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));
if (hr == S_OK) if (hr == S_OK)
{ {
memcpy(outWavex, &spfmt, sizeof(WAVEFORMATEXTENSIBLE)); memcpy(outWavex, &spfmt, sizeof(WAVEFORMATEXTENSIBLE));
CoTaskMemFree(sharedClosestMatch); CoTaskMemFree(sharedClosestMatch);
answer = paFormatIsSupported; answer = paFormatIsSupported;
break; break;
}
} }
}
// Nothing helped // Nothing helped
LogHostError(hr); LogHostError(hr);
@ -2258,7 +2261,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
// Recalculate aligned period // Recalculate aligned period
framesPerLatency = MakeFramesFromHns(pSub->period, pSub->wavex.Format.nSamplesPerSec); framesPerLatency = MakeFramesFromHns(pSub->period, pSub->wavex.Format.nSamplesPerSec);
_CalculateAlignedPeriod(pSub, &framesPerLatency, ALIGN_BWD); _CalculateAlignedPeriod(pSub, &framesPerLatency, ALIGN_BWD);
} }
} }
else else
{ {
@ -2268,7 +2271,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
// Recalculate aligned period // Recalculate aligned period
framesPerLatency = MakeFramesFromHns(pSub->period, pSub->wavex.Format.nSamplesPerSec); framesPerLatency = MakeFramesFromHns(pSub->period, pSub->wavex.Format.nSamplesPerSec);
_CalculateAlignedPeriod(pSub, &framesPerLatency, ALIGN_FWD); _CalculateAlignedPeriod(pSub, &framesPerLatency, ALIGN_FWD);
} }
} }
/*! Windows 7 does not allow to set latency lower than minimal device period and will /*! Windows 7 does not allow to set latency lower than minimal device period and will
@ -2766,7 +2769,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
// Only get IAudioCaptureClient input once here instead of getting it at multiple places based on the use // Only get IAudioCaptureClient input once here instead of getting it at multiple places based on the use
hr = IAudioClient_GetService(stream->in.clientParent, &pa_IID_IAudioCaptureClient, (void **)&stream->captureClientParent); hr = IAudioClient_GetService(stream->in.clientParent, &pa_IID_IAudioCaptureClient, (void **)&stream->captureClientParent);
if (hr != S_OK) if (hr != S_OK)
{ {
LogHostError(hr); LogHostError(hr);
LogPaError(result = paUnanticipatedHostError); LogPaError(result = paUnanticipatedHostError);
@ -2782,10 +2785,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
// buffer // buffer
if ((stream->in.tailBuffer = PaUtil_AllocateMemory(sizeof(PaUtilRingBuffer))) == NULL) if ((stream->in.tailBuffer = PaUtil_AllocateMemory(sizeof(PaUtilRingBuffer))) == NULL)
{ {
LogPaError(result = paInsufficientMemory); LogPaError(result = paInsufficientMemory);
goto error; goto error;
} }
memset(stream->in.tailBuffer, 0, sizeof(PaUtilRingBuffer)); memset(stream->in.tailBuffer, 0, sizeof(PaUtilRingBuffer));
// buffer memory region // buffer memory region
@ -2801,7 +2804,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
{ {
LogPaError(result = paInternalError); LogPaError(result = paInternalError);
goto error; goto error;
} }
} }
} }
else else
@ -2873,10 +2876,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
goto error; goto error;
} }
// Get closest format // Get closest format
hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( WaveToPaFormat(&stream->out.wavex), outputSampleFormat ); hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( WaveToPaFormat(&stream->out.wavex), outputSampleFormat );
// Set user-side custom host processor // Set user-side custom host processor
if ((outputStreamInfo != NULL) && if ((outputStreamInfo != NULL) &&
(outputStreamInfo->flags & paWinWasapiRedirectHostProcessor)) (outputStreamInfo->flags & paWinWasapiRedirectHostProcessor))
{ {
@ -2886,13 +2889,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
// Only get IAudioCaptureClient output once here instead of getting it at multiple places based on the use // Only get IAudioCaptureClient output once here instead of getting it at multiple places based on the use
hr = IAudioClient_GetService(stream->out.clientParent, &pa_IID_IAudioRenderClient, (void **)&stream->renderClientParent); hr = IAudioClient_GetService(stream->out.clientParent, &pa_IID_IAudioRenderClient, (void **)&stream->renderClientParent);
if (hr != S_OK) if (hr != S_OK)
{ {
LogHostError(hr); LogHostError(hr);
LogPaError(result = paUnanticipatedHostError); LogPaError(result = paUnanticipatedHostError);
goto error; goto error;
} }
} }
else else
{ {
outputChannelCount = 0; outputChannelCount = 0;
@ -3268,7 +3271,7 @@ static PaError StartStream( PaStream *s )
PRINT(("Failed creating thread: ProcThreadEvent.")); PRINT(("Failed creating thread: ProcThreadEvent."));
result = paUnanticipatedHostError; result = paUnanticipatedHostError;
goto nonblocking_start_error; goto nonblocking_start_error;
} }
} }
else else
{ {
@ -3277,7 +3280,7 @@ static PaError StartStream( PaStream *s )
PRINT(("Failed creating thread: ProcThreadPoll.")); PRINT(("Failed creating thread: ProcThreadPoll."));
result = paUnanticipatedHostError; result = paUnanticipatedHostError;
goto nonblocking_start_error; goto nonblocking_start_error;
} }
} }
// Wait for thread to start // Wait for thread to start
@ -3286,7 +3289,7 @@ static PaError StartStream( PaStream *s )
PRINT(("Failed starting thread: timeout.")); PRINT(("Failed starting thread: timeout."));
result = paUnanticipatedHostError; result = paUnanticipatedHostError;
goto nonblocking_start_error; goto nonblocking_start_error;
} }
} }
else else
{ {
@ -3300,7 +3303,7 @@ static PaError StartStream( PaStream *s )
} }
} }
if (stream->in.clientParent != NULL) if (stream->in.clientParent != NULL)
{ {
if ((stream->hBlockingOpStreamRD = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL) if ((stream->hBlockingOpStreamRD = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
{ {
result = paInsufficientMemory; result = paInsufficientMemory;
@ -3506,7 +3509,7 @@ static PaError ReadStream( PaStream* s, void *_buffer, unsigned long frames )
} }
if (buf2 != NULL) if (buf2 != NULL)
{ {
// Register available frames to processor // Register available frames to processor
PaUtil_SetInputFrameCount(&stream->bufferProcessor, buf2_size); PaUtil_SetInputFrameCount(&stream->bufferProcessor, buf2_size);
@ -3525,9 +3528,9 @@ static PaError ReadStream( PaStream* s, void *_buffer, unsigned long frames )
// Read hardware // Read hardware
while (frames != 0) while (frames != 0)
{ {
// Check if blocking call must be interrupted // Check if blocking call must be interrupted
if (WaitForSingleObject(stream->hCloseRequest, sleep) != WAIT_TIMEOUT) if (WaitForSingleObject(stream->hCloseRequest, sleep) != WAIT_TIMEOUT)
break; break;
// Get available frames (must be finding out available frames before call to IAudioCaptureClient_GetBuffer // Get available frames (must be finding out available frames before call to IAudioCaptureClient_GetBuffer
// othervise audio glitches will occur inExclusive mode as it seems that WASAPI has some scheduling/ // othervise audio glitches will occur inExclusive mode as it seems that WASAPI has some scheduling/
@ -3536,7 +3539,7 @@ static PaError ReadStream( PaStream* s, void *_buffer, unsigned long frames )
{ {
LogHostError(hr); LogHostError(hr);
return paUnanticipatedHostError; return paUnanticipatedHostError;
} }
// Wait for more frames to become available // Wait for more frames to become available
if (available == 0) if (available == 0)
@ -3558,7 +3561,7 @@ static PaError ReadStream( PaStream* s, void *_buffer, unsigned long frames )
// Avoid busy waiting, schedule next 1 millesecond wait // Avoid busy waiting, schedule next 1 millesecond wait
if (sleep == 0) if (sleep == 0)
sleep = ThreadIdleScheduler_NextSleep(&sched); sleep = ThreadIdleScheduler_NextSleep(&sched);
} }
else else
{ {
if ((sleep = ThreadIdleScheduler_NextSleep(&sched)) != 0) if ((sleep = ThreadIdleScheduler_NextSleep(&sched)) != 0)
@ -3588,7 +3591,7 @@ static PaError ReadStream( PaStream* s, void *_buffer, unsigned long frames )
PaUtil_SetInputFrameCount(&stream->bufferProcessor, available); PaUtil_SetInputFrameCount(&stream->bufferProcessor, available);
// Register host buffer pointer to processor // Register host buffer pointer to processor
PaUtil_SetInterleavedInputChannels(&stream->bufferProcessor, 0, wasapi_buffer, stream->bufferProcessor.inputChannelCount); PaUtil_SetInterleavedInputChannels(&stream->bufferProcessor, 0, wasapi_buffer, stream->bufferProcessor.inputChannelCount);
// Copy user data to host buffer (with conversion if applicable) // Copy user data to host buffer (with conversion if applicable)
processed = PaUtil_CopyInput(&stream->bufferProcessor, (void **)&user_buffer, frames); processed = PaUtil_CopyInput(&stream->bufferProcessor, (void **)&user_buffer, frames);
@ -3658,18 +3661,18 @@ static PaError WriteStream( PaStream* s, const void *_buffer, unsigned long fram
} }
// Blocking (potentially, untill 'frames' are consumed) loop // Blocking (potentially, untill 'frames' are consumed) loop
while (frames != 0) while (frames != 0)
{ {
// Check if blocking call must be interrupted // Check if blocking call must be interrupted
if (WaitForSingleObject(stream->hCloseRequest, sleep) != WAIT_TIMEOUT) if (WaitForSingleObject(stream->hCloseRequest, sleep) != WAIT_TIMEOUT)
break; break;
// Get frames available // Get frames available
if ((hr = _PollGetOutputFramesAvailable(stream, &available)) != S_OK) if ((hr = _PollGetOutputFramesAvailable(stream, &available)) != S_OK)
{ {
LogHostError(hr); LogHostError(hr);
goto end; goto end;
} }
// Wait for more frames to become available // Wait for more frames to become available
if (available == 0) if (available == 0)
@ -3688,42 +3691,42 @@ static PaError WriteStream( PaStream* s, const void *_buffer, unsigned long fram
// Keep in 'frmaes' range // Keep in 'frmaes' range
if (available > frames) if (available > frames)
available = frames; available = frames;
// Get pointer to host buffer // Get pointer to host buffer
if ((hr = IAudioRenderClient_GetBuffer(stream->renderClient, available, &wasapi_buffer)) != S_OK) if ((hr = IAudioRenderClient_GetBuffer(stream->renderClient, available, &wasapi_buffer)) != S_OK)
{ {
// Buffer size is too big, waiting // Buffer size is too big, waiting
if (hr == AUDCLNT_E_BUFFER_TOO_LARGE) if (hr == AUDCLNT_E_BUFFER_TOO_LARGE)
continue; continue;
LogHostError(hr); LogHostError(hr);
goto end; goto end;
} }
// Keep waiting again (on Vista it was noticed that WASAPI could SOMETIMES return NULL pointer // Keep waiting again (on Vista it was noticed that WASAPI could SOMETIMES return NULL pointer
// to buffer without returning AUDCLNT_E_BUFFER_TOO_LARGE instead) // to buffer without returning AUDCLNT_E_BUFFER_TOO_LARGE instead)
if (wasapi_buffer == NULL) if (wasapi_buffer == NULL)
continue; continue;
// Register available frames to processor // Register available frames to processor
PaUtil_SetOutputFrameCount(&stream->bufferProcessor, available); PaUtil_SetOutputFrameCount(&stream->bufferProcessor, available);
// Register host buffer pointer to processor // Register host buffer pointer to processor
PaUtil_SetInterleavedOutputChannels(&stream->bufferProcessor, 0, wasapi_buffer, stream->bufferProcessor.outputChannelCount); PaUtil_SetInterleavedOutputChannels(&stream->bufferProcessor, 0, wasapi_buffer, stream->bufferProcessor.outputChannelCount);
// Copy user data to host buffer (with conversion if applicable), this call will advance // Copy user data to host buffer (with conversion if applicable), this call will advance
// pointer 'user_buffer' to consumed portion of data // pointer 'user_buffer' to consumed portion of data
processed = PaUtil_CopyOutput(&stream->bufferProcessor, (const void **)&user_buffer, frames); processed = PaUtil_CopyOutput(&stream->bufferProcessor, (const void **)&user_buffer, frames);
frames -= processed; frames -= processed;
// Release host buffer // Release host buffer
if ((hr = IAudioRenderClient_ReleaseBuffer(stream->renderClient, available, 0)) != S_OK) if ((hr = IAudioRenderClient_ReleaseBuffer(stream->renderClient, available, 0)) != S_OK)
{ {
LogHostError(hr); LogHostError(hr);
goto end; goto end;
}
} }
}
end: end:
@ -4715,14 +4718,14 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
{ {
if ((hr = IAudioClient_Start(stream->in.clientProc)) != S_OK) if ((hr = IAudioClient_Start(stream->in.clientProc)) != S_OK)
{ {
LogHostError(hr); LogHostError(hr);
goto thread_error; goto thread_error;
}
} }
}
// Initialize event & start OUTPUT stream // Initialize event & start OUTPUT stream
if (stream->out.clientProc) if (stream->out.clientProc)
{ {
// Preload buffer (obligatory, othervise ->Start() will fail), avoid processing // Preload buffer (obligatory, othervise ->Start() will fail), avoid processing
// when in full-duplex mode as it requires input processing as well // when in full-duplex mode as it requires input processing as well
if (!PA_WASAPI__IS_FULLDUPLEX(stream)) if (!PA_WASAPI__IS_FULLDUPLEX(stream))
@ -4739,22 +4742,22 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
if ((hr = ProcessOutputBuffer(stream, processor, frames)) != S_OK) if ((hr = ProcessOutputBuffer(stream, processor, frames)) != S_OK)
{ {
LogHostError(hr); // not fatal, just log LogHostError(hr); // not fatal, just log
} }
} }
} }
else else
{ {
if (frames != 0) if (frames != 0)
{ {
if ((hr = ProcessOutputBuffer(stream, processor, frames)) != S_OK) if ((hr = ProcessOutputBuffer(stream, processor, frames)) != S_OK)
{ {
LogHostError(hr); // not fatal, just log LogHostError(hr); // not fatal, just log
} }
} }
} }
} }
else else
{ {
LogHostError(hr); // not fatal, just log LogHostError(hr); // not fatal, just log
} }
} }
@ -4827,7 +4830,7 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
{ {
LogHostError(hr); LogHostError(hr);
goto thread_error; goto thread_error;
} }
} }
} }
else else
@ -4838,7 +4841,7 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
{ {
LogHostError(hr); LogHostError(hr);
goto thread_error; goto thread_error;
} }
} }
} }
@ -4908,7 +4911,7 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
LogPaError(paInsufficientMemory); LogPaError(paInsufficientMemory);
break; break;
} }
} }
// replace buffer pointer // replace buffer pointer
@ -4981,7 +4984,7 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
if (sleep_ms == 0) if (sleep_ms == 0)
{ {
next_sleep = ThreadIdleScheduler_NextSleep(&scheduler); next_sleep = ThreadIdleScheduler_NextSleep(&scheduler);
} }
// get available frames // get available frames
if ((hr = _PollGetOutputFramesAvailable(stream, &o_frames)) != S_OK) if ((hr = _PollGetOutputFramesAvailable(stream, &o_frames)) != S_OK)

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_win_wdmks.c 1661 2011-04-28 18:54:46Z rob_bielik $
* PortAudio Windows WDM-KS interface * PortAudio Windows WDM-KS interface
* *
* Author: Andrew Baldwin * Author: Andrew Baldwin
@ -59,8 +59,12 @@
#ifdef __GNUC__ #ifdef __GNUC__
#include <initguid.h> #include <initguid.h>
#define _WIN32_WINNT 0x0501 #ifndef _WIN32_WINNT
#define WINVER 0x0501 #define _WIN32_WINNT 0x0501
#endif /* #ifndef _WIN32_WINNT */
#ifndef WINVER
#define WINVER 0x0501
#endif /* #ifndef WINVER */
#endif #endif
#include <string.h> /* strlen() */ #include <string.h> /* strlen() */
@ -76,7 +80,7 @@
#include "pa_debugprint.h" #include "pa_debugprint.h"
#include <windows.h> #include <windows.h>
#include <winioctl.h> /* #include <winioctl.h> MinGW-w64 4.7.1 from TDM-GCC throws multiple redefinition errors. */
#include <process.h> #include <process.h>
#ifdef __GNUC__ #ifdef __GNUC__
@ -1885,6 +1889,9 @@ PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
(*hostApi)->info.deviceCount = deviceCount; (*hostApi)->info.deviceCount = deviceCount;
(*hostApi)->ScanDeviceInfos = NULL;
(*hostApi)->CommitDeviceInfos = NULL;
(*hostApi)->DisposeDeviceInfos = NULL;
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_win_wmme.c 1663 2011-05-01 13:21:43Z rossb $
* pa_win_wmme.c * pa_win_wmme.c
* Implementation of PortAudio for Windows MultiMedia Extensions (WMME) * Implementation of PortAudio for Windows MultiMedia Extensions (WMME)
* *
@ -153,6 +153,9 @@
#define PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) /* For debugging glitches. */ #define PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) /* For debugging glitches. */
#define DRV_QUERYFUNCTIONINSTANCEID (DRV_RESERVED + 17)
#define DRV_QUERYFUNCTIONINSTANCEIDSIZE (DRV_RESERVED + 18)
#if PA_MME_USE_HIGH_DEFAULT_LATENCY_ #if PA_MME_USE_HIGH_DEFAULT_LATENCY_
#define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.4) #define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.4)
#define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (4) #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (4)
@ -177,7 +180,7 @@
#define PA_MME_WIN_NT_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_ * 2) #define PA_MME_WIN_NT_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_ * 2)
#define PA_MME_WIN_WDM_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_) #define PA_MME_WIN_WDM_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_)
#define PA_MME_MAX_TIMEOUT_MSEC_ (2000)
#define PA_MME_MIN_TIMEOUT_MSEC_ (1000) #define PA_MME_MIN_TIMEOUT_MSEC_ (1000)
static const char constInputMapperSuffix_[] = " - Input"; static const char constInputMapperSuffix_[] = " - Input";
@ -242,6 +245,9 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
const PaStreamParameters *inputParameters, const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters, const PaStreamParameters *outputParameters,
double sampleRate ); double sampleRate );
static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void **newDeviceInfos, int *newDeviceCount );
static PaError CommitDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void *deviceInfos, int deviceCount );
static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, void *deviceInfos, int deviceCount );
static PaError CloseStream( PaStream* stream ); static PaError CloseStream( PaStream* stream );
static PaError StartStream( PaStream *stream ); static PaError StartStream( PaStream *stream );
static PaError StopStream( PaStream *stream ); static PaError StopStream( PaStream *stream );
@ -377,6 +383,92 @@ static PaError CloseHandleWithPaError( HANDLE handle )
return result; return result;
} }
/**
* Sets the <tt>transportType</tt> of a specific <tt>PaDeviceInfo</tt>.
*
* @param winMmeDeviceId
* @param deviceInfo the <tt>PaDeviceInfo</tt> to set the <tt>transportType</tt>
* of
*/
static void
SetDeviceInfoTransportType(UINT winMmeDeviceId, PaDeviceInfo *deviceInfo)
{
deviceInfo->transportType = NULL;
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
if (!(deviceInfo->transportType))
{
DWORD deviceInterfaceSize;
LPWSTR deviceInterface = NULL;
if (deviceInfo->maxInputChannels > 0)
{
if (waveInMessage(
(HWAVEIN)winMmeDeviceId,
DRV_QUERYDEVICEINTERFACESIZE,
(DWORD_PTR)&deviceInterfaceSize,
0)
== MMSYSERR_NOERROR)
{
deviceInterface = PaUtil_AllocateMemory(deviceInterfaceSize);
if (deviceInterface
&& (waveInMessage(
(HWAVEIN)winMmeDeviceId,
DRV_QUERYDEVICEINTERFACE,
(DWORD_PTR)deviceInterface,
deviceInterfaceSize)
!= MMSYSERR_NOERROR))
{
PaUtil_FreeMemory(deviceInterface);
deviceInterface = NULL;
}
}
}
else if (deviceInfo->maxOutputChannels > 0)
{
if (waveOutMessage(
(HWAVEOUT)winMmeDeviceId,
DRV_QUERYDEVICEINTERFACESIZE,
(DWORD_PTR)&deviceInterfaceSize,
0)
== MMSYSERR_NOERROR)
{
deviceInterface = PaUtil_AllocateMemory(deviceInterfaceSize);
if (deviceInterface
&& (waveOutMessage(
(HWAVEOUT)winMmeDeviceId,
DRV_QUERYDEVICEINTERFACE,
(DWORD_PTR)deviceInterface,
deviceInterfaceSize)
!= MMSYSERR_NOERROR))
{
PaUtil_FreeMemory(deviceInterface);
deviceInterface = NULL;
}
}
}
if (deviceInterface)
{
if (wcsstr(deviceInterface, L"\\usb#")
|| wcsstr(deviceInterface, L"\\USB#"))
deviceInfo->transportType = "USB";
PaUtil_FreeMemory(deviceInterface);
}
}
#endif /* #ifdef PAWIN_USE_WDMKS_DEVICE_INFO */
/*
* As a last resort, attempt to make a decision about the transportType
* based on the name of the specified deviceInfo.
*/
if (!(deviceInfo->transportType))
{
const char *s = deviceInfo->name;
if (s && (s = strrchr(s,'(')) && (s = strstr(s,"USB")) && strchr(s,')'))
deviceInfo->transportType = "USB";
}
}
/* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */ /* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */
@ -396,6 +488,8 @@ typedef struct
device ids. device ids.
*/ */
UINT *winMmeDeviceIds; UINT *winMmeDeviceIds;
//char comWasInitialized;
} }
PaWinMmeHostApiRepresentation; PaWinMmeHostApiRepresentation;
@ -409,6 +503,14 @@ typedef struct
} }
PaWinMmeDeviceInfo; PaWinMmeDeviceInfo;
typedef struct PaWinMmeScanDeviceInfosResults{ /* used for tranferring device infos during scanning / rescanning */
PaDeviceInfo **deviceInfos;
PaDeviceIndex defaultInputDevice;
PaDeviceIndex defaultOutputDevice;
int inputDeviceCount, outputDeviceCount;
} PaWinMmeScanDeviceInfosResults;
/************************************************************************* /*************************************************************************
* Returns recommended device ID. * Returns recommended device ID.
@ -665,12 +767,19 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
{ {
PaError result = paNoError; PaError result = paNoError;
char *deviceName; /* non-const ptr */ char *deviceName; /* non-const ptr */
char *deviceUID;
MMRESULT mmresult; MMRESULT mmresult;
WAVEINCAPS wic; WAVEINCAPS wic;
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
*success = 0; *success = 0;
/* We do not want Microsoft's Sound Mapper because it is a virtual device
* and we want the real (hardware) devices only.
*/
if (WAVE_MAPPER == winMmeInputDeviceId)
return paNoError;
mmresult = waveInGetDevCaps( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPS ) ); mmresult = waveInGetDevCaps( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPS ) );
if( mmresult == MMSYSERR_NOMEM ) if( mmresult == MMSYSERR_NOMEM )
{ {
@ -737,6 +846,51 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
QueryWaveInKSFilterMaxChannels( winMmeInputDeviceId, &deviceInfo->maxInputChannels ); QueryWaveInKSFilterMaxChannels( winMmeInputDeviceId, &deviceInfo->maxInputChannels );
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
/* transportType */
SetDeviceInfoTransportType(winMmeInputDeviceId, deviceInfo);
MMRESULT mmr;
size_t cbEndpointIdSize;
// Get the size (including the terminating null) of
// the endpoint ID string of the waveOut device.
mmr = waveInMessage(
winMmeInputDeviceId,
DRV_QUERYFUNCTIONINSTANCEIDSIZE,
(DWORD_PTR)&cbEndpointIdSize, NULL);
if (mmr == MMSYSERR_NOERROR) // do sizes match?
{
WCHAR *pstrEndpointId = NULL;
pstrEndpointId = (WCHAR *)PaUtil_GroupAllocateMemory(winMmeHostApi->allocations, cbEndpointIdSize);
// Get the endpoint ID string for this waveOut device.
mmr = waveInMessage(
winMmeInputDeviceId,
DRV_QUERYFUNCTIONINSTANCEID,
(DWORD_PTR)pstrEndpointId,
cbEndpointIdSize);
if (mmr == MMSYSERR_NOERROR)
{
deviceUID = (char *)PaUtil_GroupAllocateMemory(winMmeHostApi->allocations, wcslen(pstrEndpointId));
if( !deviceUID )
{
result = paInsufficientMemory;
goto error;
}
wcstombs(deviceUID, pstrEndpointId, sizeof(deviceUID));
WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\
pstrEndpointId, -1, deviceUID, wcslen(pstrEndpointId), NULL, NULL );
deviceInfo->deviceUID = deviceUID;
}
/*else
{
char mmeErrorText[ MAXERRORLENGTH ];
waveOutGetErrorText( mmr, mmeErrorText, MAXERRORLENGTH );
PA_DEBUG(("Error %i: %s\n", mmr ,mmeErrorText));
}*/
}
winMmeDeviceInfo->dwFormats = wic.dwFormats; winMmeDeviceInfo->dwFormats = wic.dwFormats;
DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId, DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId,
@ -788,6 +942,7 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
{ {
PaError result = paNoError; PaError result = paNoError;
char *deviceName; /* non-const ptr */ char *deviceName; /* non-const ptr */
char *deviceUID;
MMRESULT mmresult; MMRESULT mmresult;
WAVEOUTCAPS woc; WAVEOUTCAPS woc;
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
@ -795,6 +950,12 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
*success = 0; *success = 0;
/* We do not want Microsoft's Sound Mapper because it is a virtual device
* and we want the real (hardware) devices only.
*/
if (WAVE_MAPPER == winMmeOutputDeviceId)
return paNoError;
mmresult = waveOutGetDevCaps( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPS ) ); mmresult = waveOutGetDevCaps( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPS ) );
if( mmresult == MMSYSERR_NOMEM ) if( mmresult == MMSYSERR_NOMEM )
{ {
@ -863,6 +1024,52 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
/* transportType */
SetDeviceInfoTransportType(winMmeOutputDeviceId, deviceInfo);
MMRESULT mmr;
size_t cbEndpointIdSize;
// Get the size (including the terminating null) of
// the endpoint ID string of the waveOut device.
mmr = waveOutMessage(
winMmeOutputDeviceId,
DRV_QUERYFUNCTIONINSTANCEIDSIZE,
(DWORD_PTR)&cbEndpointIdSize, NULL);
if (mmr == MMSYSERR_NOERROR) // do sizes match?
{
WCHAR *pstrEndpointId = NULL;
pstrEndpointId = (WCHAR *)PaUtil_GroupAllocateMemory(winMmeHostApi->allocations, cbEndpointIdSize);
// Get the endpoint ID string for this waveOut device.
mmr = waveOutMessage(
winMmeOutputDeviceId,
DRV_QUERYFUNCTIONINSTANCEID,
(DWORD_PTR)pstrEndpointId,
cbEndpointIdSize);
if (mmr == MMSYSERR_NOERROR)
{
deviceUID = (char *)PaUtil_GroupAllocateMemory(winMmeHostApi->allocations, wcslen(pstrEndpointId));
if( !deviceUID )
{
result = paInsufficientMemory;
goto error;
}
wcstombs(deviceUID, pstrEndpointId, sizeof(deviceUID));
WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\
pstrEndpointId, -1, deviceUID, wcslen(pstrEndpointId), NULL, NULL );
deviceInfo->deviceUID = deviceUID;
}
/*else
{
char mmeErrorText[ MAXERRORLENGTH ];
waveOutGetErrorText( mmr, mmeErrorText, MAXERRORLENGTH );
PA_DEBUG(("Error %i: %s\n", mmr ,mmeErrorText));
}*/
}
winMmeDeviceInfo->dwFormats = woc.dwFormats; winMmeDeviceInfo->dwFormats = woc.dwFormats;
DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId, DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId,
@ -902,14 +1109,10 @@ static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighL
PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
{ {
PaError result = paNoError; PaError result = paNoError;
int i; int deviceCount;
PaWinMmeHostApiRepresentation *winMmeHostApi; PaWinMmeHostApiRepresentation *winMmeHostApi;
int inputDeviceCount, outputDeviceCount, maximumPossibleDeviceCount; //char comWasInitialized = 1;
PaWinMmeDeviceInfo *deviceInfoArray; void *scanResults = 0;
int deviceInfoInitializationSucceeded;
PaTime defaultLowLatency, defaultHighLatency;
DWORD waveInPreferredDevice, waveOutPreferredDevice;
DWORD preferredDeviceStatusFlags;
winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) ); winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) );
if( !winMmeHostApi ) if( !winMmeHostApi )
@ -918,6 +1121,8 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
goto error; goto error;
} }
//winMmeHostApi->comWasInitialized = comWasInitialized;
winMmeHostApi->allocations = PaUtil_CreateAllocationGroup(); winMmeHostApi->allocations = PaUtil_CreateAllocationGroup();
if( !winMmeHostApi->allocations ) if( !winMmeHostApi->allocations )
{ {
@ -930,163 +1135,32 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
(*hostApi)->info.type = paMME; (*hostApi)->info.type = paMME;
(*hostApi)->info.name = "MME"; (*hostApi)->info.name = "MME";
/* initialise device counts and default devices under the assumption that /* initialise device counts and default devices under the assumption that
there are no devices. These values are incremented below if and when there are no devices. These values are incremented below if and when
devices are successfully initialized. devices are successfully initialized.
*/ */
/* these are all updated by CommitDeviceInfos() */
(*hostApi)->info.deviceCount = 0; (*hostApi)->info.deviceCount = 0;
(*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultInputDevice = paNoDevice;
(*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice;
winMmeHostApi->inputDeviceCount = 0; winMmeHostApi->inputDeviceCount = 0;
winMmeHostApi->outputDeviceCount = 0; winMmeHostApi->outputDeviceCount = 0;
#if !defined(DRVM_MAPPER_PREFERRED_GET) result = ScanDeviceInfos( &winMmeHostApi->inheritedHostApiRep, hostApiIndex, &scanResults, &deviceCount );
/* DRVM_MAPPER_PREFERRED_GET is defined in mmddk.h but we avoid a dependency on the DDK by defining it here */ if( result != paNoError )
#define DRVM_MAPPER_PREFERRED_GET (0x2000+21) {
#endif goto error;
/* the following calls assume that if wave*Message fails the preferred device parameter won't be modified */
preferredDeviceStatusFlags = 0;
waveInPreferredDevice = -1;
waveInMessage( (HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveInPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
preferredDeviceStatusFlags = 0;
waveOutPreferredDevice = -1;
waveOutMessage( (HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveOutPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
maximumPossibleDeviceCount = 0;
inputDeviceCount = waveInGetNumDevs();
if( inputDeviceCount > 0 )
maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
outputDeviceCount = waveOutGetNumDevs();
if( outputDeviceCount > 0 )
maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
if( maximumPossibleDeviceCount > 0 ){
(*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount );
if( !(*hostApi)->deviceInfos )
{
result = paInsufficientMemory;
goto error;
}
/* allocate all device info structs in a contiguous block */
deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount );
if( !deviceInfoArray )
{
result = paInsufficientMemory;
goto error;
}
winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount );
if( !winMmeHostApi->winMmeDeviceIds )
{
result = paInsufficientMemory;
goto error;
}
GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency );
if( inputDeviceCount > 0 ){
/* -1 is the WAVE_MAPPER */
for( i = -1; i < inputDeviceCount; ++i ){
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;
wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1;
deviceInfo->maxOutputChannels = 0;
wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
if( result != paNoError )
goto error;
if( deviceInfoInitializationSucceeded ){
if( (*hostApi)->info.defaultInputDevice == paNoDevice ){
/* if there is currently no default device, use the first one available */
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
}else if( winMmeDeviceId == waveInPreferredDevice ){
/* set the default device to the system preferred device */
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
}
winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId;
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
winMmeHostApi->inputDeviceCount++;
(*hostApi)->info.deviceCount++;
}
}
}
if( outputDeviceCount > 0 ){
/* -1 is the WAVE_MAPPER */
for( i = -1; i < outputDeviceCount; ++i ){
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->maxInputChannels = 0;
wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1;
deviceInfo->maxOutputChannels = 0;
wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
if( result != paNoError )
goto error;
if( deviceInfoInitializationSucceeded ){
if( (*hostApi)->info.defaultOutputDevice == paNoDevice ){
/* if there is currently no default device, use the first one available */
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
}else if( winMmeDeviceId == waveOutPreferredDevice ){
/* set the default device to the system preferred device */
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
}
winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId;
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
winMmeHostApi->outputDeviceCount++;
(*hostApi)->info.deviceCount++;
}
}
}
} }
InitializeDefaultDeviceIdsFromEnv( winMmeHostApi ); /* FIXME for now we ignore the result of CommitDeviceInfos(), it should probably be an atomic non-failing operation */
CommitDeviceInfos( &winMmeHostApi->inheritedHostApiRep, hostApiIndex, scanResults, deviceCount );
(*hostApi)->Terminate = Terminate; (*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream; (*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported; (*hostApi)->IsFormatSupported = IsFormatSupported;
(*hostApi)->ScanDeviceInfos = ScanDeviceInfos;
(*hostApi)->CommitDeviceInfos = CommitDeviceInfos;
(*hostApi)->DisposeDeviceInfos = DisposeDeviceInfos;
PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream, PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive, StopStream, AbortStream, IsStreamStopped, IsStreamActive,
@ -1323,7 +1397,298 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
return paFormatIsSupported; return paFormatIsSupported;
} }
/***********************************************************************************/
static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex hostApiIndex, void **scanResults, int *newDeviceCount )
{
PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
PaWinMmeDeviceInfo *deviceInfoArray;
//char comWasInitialized = winMmeHostApi->comWasInitialized;
PaError result = paNoError;
PaWinMmeScanDeviceInfosResults *outArgument = 0;
//DSDeviceNamesAndGUIDs deviceNamesAndGUIDs;
int i = 0;
int maximumPossibleDeviceCount = 0;
int inputDeviceCount, outputDeviceCount;
int deviceInfoInitializationSucceeded;
PaTime defaultLowLatency, defaultHighLatency;
DWORD waveInPreferredDevice, waveOutPreferredDevice;
DWORD preferredDeviceStatusFlags;
// Check preconditions
if( /*!comWasInitialized ||*/ scanResults == NULL || newDeviceCount == NULL )
return paInternalError;
/* initialize the out params */
*scanResults = NULL;
*newDeviceCount = 0;
#if !defined(DRVM_MAPPER_PREFERRED_GET)
/* DRVM_MAPPER_PREFERRED_GET is defined in mmddk.h but we avoid a dependency on the DDK by defining it here */
#define DRVM_MAPPER_PREFERRED_GET (0x2000+21)
#endif
/* the following calls assume that if wave*Message fails the preferred device parameter won't be modified */
preferredDeviceStatusFlags = 0;
waveInPreferredDevice = -1;
waveInMessage( (HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveInPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
preferredDeviceStatusFlags = 0;
waveOutPreferredDevice = -1;
waveOutMessage( (HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveOutPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags );
maximumPossibleDeviceCount = 0;
inputDeviceCount = waveInGetNumDevs();
if( inputDeviceCount > 0 )
maximumPossibleDeviceCount += inputDeviceCount + 1; // assume there is a WAVE_MAPPER
outputDeviceCount = waveOutGetNumDevs();
if( outputDeviceCount > 0 )
maximumPossibleDeviceCount += outputDeviceCount + 1;// assume there is a WAVE_MAPPER
if( maximumPossibleDeviceCount > 0 )
{
/* Allocate the out param for all the info we need */
outArgument = (PaWinMmeScanDeviceInfosResults *) PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaWinMmeScanDeviceInfosResults) );
if( !outArgument )
{
result = paInsufficientMemory;
goto error;
}
/* allocate array for pointers to PaDeviceInfo structs */
outArgument->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount );
if( !outArgument->deviceInfos )
{
result = paInsufficientMemory;
goto error;
}
// allocate all device info structs in a contiguous block
deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount );
if( !deviceInfoArray )
{
result = paInsufficientMemory;
goto error;
}
winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount );
if( !winMmeHostApi->winMmeDeviceIds )
{
result = paInsufficientMemory;
goto error;
}
for( i = 0 ; i < maximumPossibleDeviceCount; ++i )
{
PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[i];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 3;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = 0;
/*
* The fields maxInputChannels and maxOutputChannels used to be
* initialized in each of the loops bellow to the effect of the
* second loop overwriting/throwing away the results of the first
* loop. In order to resolve the described issue, the initialization
* of the two fields in question has been moved here.
*/
deviceInfo->maxInputChannels = 0;
deviceInfo->maxOutputChannels = 0;
/*
* The fields defaultLowInputLatency, defaultLowOutputLatency,
* defaultHighInputLatency and defaultHighOutputLatency used to be
* initialized in each of the loops bellow. For the sake of clarity,
* their initialization has been moved here.
*/
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
/*
* The fields deviceInputChannelCountIsKnown and
* deviceOutputChannelCountIsKnown used to be initialized in each of
* the loops bellow to the effect of the second loop
* overwriting/throwing away the results of the first loop. In order
* to resolve the described issue, the initialization of the two
* fields in question has been moved here.
*/
wmmeDeviceInfo->deviceInputChannelCountIsKnown = 0;
wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 0;
outArgument->deviceInfos[ i ] = deviceInfo;
}
outArgument->inputDeviceCount = 0;
outArgument->outputDeviceCount = 0;
GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency );
if( inputDeviceCount > 0 )
{
// -1 is the WAVE_MAPPER
for( i = -1; i < inputDeviceCount; ++i )
{
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = (PaWinMmeDeviceInfo*)outArgument->deviceInfos[*newDeviceCount];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
/* ignore error results here and just skip the device */
if( result != paNoError )
continue;
if( deviceInfoInitializationSucceeded )
{
if( outArgument->defaultInputDevice == paNoDevice )
{
// if there is currently no default device, use the first one available
outArgument->defaultInputDevice = *newDeviceCount;
}
else if( winMmeDeviceId == waveInPreferredDevice )
{
// set the default device to the system preferred device
outArgument->defaultInputDevice = *newDeviceCount;
}
winMmeHostApi->winMmeDeviceIds[ *newDeviceCount ] = winMmeDeviceId;
outArgument->inputDeviceCount++;
(*newDeviceCount)++;
}
}
}
if( outputDeviceCount > 0 )
{
// -1 is the WAVE_MAPPER
for( i = -1; i < outputDeviceCount; ++i )
{
UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
PaWinMmeDeviceInfo *wmmeDeviceInfo = (PaWinMmeDeviceInfo*)outArgument->deviceInfos[*newDeviceCount];
PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
winMmeDeviceId, &deviceInfoInitializationSucceeded );
/* ignore error results here and just skip the device */
if( result != paNoError )
continue;
if( deviceInfoInitializationSucceeded )
{
if( outArgument->defaultOutputDevice == paNoDevice )
{
// if there is currently no default device, use the first one available
outArgument->defaultOutputDevice = *newDeviceCount;
}
else if( winMmeDeviceId == waveOutPreferredDevice )
{
// set the default device to the system preferred device
outArgument->defaultOutputDevice = *newDeviceCount;
}
winMmeHostApi->winMmeDeviceIds[ *newDeviceCount ] = winMmeDeviceId;
outArgument->outputDeviceCount++;
(*newDeviceCount)++;
}
}
}
}
InitializeDefaultDeviceIdsFromEnv( winMmeHostApi );
*scanResults = outArgument;
return result;
error:
if( outArgument )
{
if( outArgument->deviceInfos )
{
if( outArgument->deviceInfos[0] )
{
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, outArgument->deviceInfos[0] );
}
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, outArgument->deviceInfos );
}
}
return result;
}
static PaError CommitDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void *scanResults, int deviceCount )
{
PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
PaError result = paNoError;
int i = 0;
hostApi->info.deviceCount = 0;
hostApi->info.defaultInputDevice = paNoDevice;
hostApi->info.defaultOutputDevice = paNoDevice;
/* Free any old memory which might be in the device info */
if( hostApi->deviceInfos )
{
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, hostApi->deviceInfos[0] );
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, hostApi->deviceInfos );
hostApi->deviceInfos = NULL;
}
if( scanResults != NULL )
{
PaWinMmeScanDeviceInfosResults *scanDeviceInfosResults = ( PaWinMmeScanDeviceInfosResults * ) scanResults;
if( deviceCount > 0 )
{
// use the array allocated in ScanDeviceInfos() as our deviceInfos
hostApi->deviceInfos = scanDeviceInfosResults->deviceInfos;
hostApi->info.defaultInputDevice = scanDeviceInfosResults->defaultInputDevice;
hostApi->info.defaultOutputDevice = scanDeviceInfosResults->defaultOutputDevice;
hostApi->info.deviceCount = deviceCount;
winMmeHostApi->inputDeviceCount = scanDeviceInfosResults->inputDeviceCount;
winMmeHostApi->outputDeviceCount = scanDeviceInfosResults->outputDeviceCount;
}
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults );
}
return result;
}
static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, void *scanResults, int deviceCount )
{
PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
if( scanResults != NULL )
{
PaWinMmeScanDeviceInfosResults *scanDeviceInfosResults = ( PaWinMmeScanDeviceInfosResults * ) scanResults;
if( scanDeviceInfosResults->deviceInfos )
{
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults->deviceInfos[0] ); // all device info structs are allocated in a block so we can destroy them here
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults->deviceInfos );
}
PaUtil_GroupFreeMemory( winMmeHostApi->allocations, scanDeviceInfosResults );
}
return paNoError;
}
/***********************************************************************************/
static void SelectBufferSizeAndCount( unsigned long baseBufferSize, static void SelectBufferSizeAndCount( unsigned long baseBufferSize,
unsigned long requestedLatency, unsigned long requestedLatency,
@ -1805,18 +2170,18 @@ static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostA
{ {
switch(j){ switch(j){
case 0: case 0:
/* first, attempt to open the device using WAVEFORMATEXTENSIBLE, /* first, attempt to open the device using WAVEFORMATEXTENSIBLE,
if this fails we fall back to WAVEFORMATEX */ if this fails we fall back to WAVEFORMATEX */
PaWin_InitializeWaveFormatExtensible( &waveFormat, devices[i].channelCount, PaWin_InitializeWaveFormatExtensible( &waveFormat, devices[i].channelCount,
sampleFormat, waveFormatTag, sampleRate, channelMask ); sampleFormat, waveFormatTag, sampleRate, channelMask );
break; break;
case 1: case 1:
/* retry with WAVEFORMATEX */ /* retry with WAVEFORMATEX */
PaWin_InitializeWaveFormatEx( &waveFormat, devices[i].channelCount, PaWin_InitializeWaveFormatEx( &waveFormat, devices[i].channelCount,
sampleFormat, waveFormatTag, sampleRate ); sampleFormat, waveFormatTag, sampleRate );
break; break;
} }
@ -3391,7 +3756,7 @@ static PaError StopStream( PaStream *s )
{ {
PaError result = paNoError; PaError result = paNoError;
PaWinMmeStream *stream = (PaWinMmeStream*)s; PaWinMmeStream *stream = (PaWinMmeStream*)s;
int timeout; DWORD timeout;
DWORD waitResult; DWORD waitResult;
MMRESULT mmresult; MMRESULT mmresult;
signed int hostOutputBufferIndex; signed int hostOutputBufferIndex;
@ -3412,7 +3777,7 @@ static PaError StopStream( PaStream *s )
stream->stopProcessing = 1; stream->stopProcessing = 1;
/* Calculate timeOut longer than longest time it could take to return all buffers. */ /* Calculate timeOut longer than longest time it could take to return all buffers. */
timeout = (int)(stream->allBuffersDurationMs * 1.5); timeout = (DWORD)(stream->allBuffersDurationMs * 1.5);
if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ )
timeout = PA_MME_MIN_TIMEOUT_MSEC_; timeout = PA_MME_MIN_TIMEOUT_MSEC_;
@ -3441,6 +3806,12 @@ static PaError StopStream( PaStream *s )
if( PA_IS_OUTPUT_STREAM_(stream) ) if( PA_IS_OUTPUT_STREAM_(stream) )
{ {
/* If WaitForSingleObject starts repetitively and consecutively
returning WAIT_TIMEOUT, do eventually give up. Otherwise, the
method may never return.
*/
DWORD totalTimeout;
if( stream->output.framesUsedInCurrentBuffer > 0 ) if( stream->output.framesUsedInCurrentBuffer > 0 )
{ {
/* there are still unqueued frames in the current buffer, so flush them */ /* there are still unqueued frames in the current buffer, so flush them */
@ -3481,6 +3852,7 @@ static PaError StopStream( PaStream *s )
timeout = PA_MME_MIN_TIMEOUT_MSEC_; timeout = PA_MME_MIN_TIMEOUT_MSEC_;
waitCount = 0; waitCount = 0;
totalTimeout = 0;
while( !NoBuffersAreQueued( &stream->output ) && waitCount <= stream->output.bufferCount ) while( !NoBuffersAreQueued( &stream->output ) && waitCount <= stream->output.bufferCount )
{ {
/* wait for MME to signal that a buffer is available */ /* wait for MME to signal that a buffer is available */
@ -3491,8 +3863,19 @@ static PaError StopStream( PaStream *s )
} }
else if( waitResult == WAIT_TIMEOUT ) else if( waitResult == WAIT_TIMEOUT )
{ {
/* keep waiting */ /* Keep waiting. However, testing has shown that it is
possible to unplug a device and to wait here forever. In
order to prevent such a scenario, do eventually given up.
*/
totalTimeout += timeout;
if( PA_MME_MAX_TIMEOUT_MSEC_ <= totalTimeout)
{
result = paTimedOut;
break;
}
} }
else
totalTimeout = 0;
++waitCount; ++waitCount;
} }
@ -3668,6 +4051,12 @@ static PaError ReadStream( PaStream* s,
if( PA_IS_INPUT_STREAM_(stream) ) if( PA_IS_INPUT_STREAM_(stream) )
{ {
/* If WaitForSingleObject starts repetitively and consecutively
returning WAIT_TIMEOUT, do eventually give up in order to allow the
caller to handle such cases.
*/
DWORD totalTimeout = 0;
/* make a local copy of the user buffer pointer(s). this is necessary /* make a local copy of the user buffer pointer(s). this is necessary
because PaUtil_CopyInput() advances these pointers every time because PaUtil_CopyInput() advances these pointers every time
it is called. it is called.
@ -3688,6 +4077,8 @@ static PaError ReadStream( PaStream* s,
do{ do{
if( CurrentInputBuffersAreDone( stream ) ) if( CurrentInputBuffersAreDone( stream ) )
{ {
totalTimeout = 0;
if( NoBuffersAreQueued( &stream->input ) ) if( NoBuffersAreQueued( &stream->input ) )
{ {
/** @todo REVIEW: consider what to do if the input overflows. /** @todo REVIEW: consider what to do if the input overflows.
@ -3741,9 +4132,17 @@ static PaError ReadStream( PaStream* s,
} }
else if( waitResult == WAIT_TIMEOUT ) else if( waitResult == WAIT_TIMEOUT )
{ {
/* if a timeout is encountered, continue, /* If a timeout is encountered, continue. However, testing
perhaps we should give up eventually has shown that it is possible to unplug a device and to
wait here forever. In order to allow the caller to handle
such cases of repeated timeouts, do eventually given up.
*/ */
totalTimeout += timeout;
if( PA_MME_MAX_TIMEOUT_MSEC_ <= totalTimeout)
{
result = paTimedOut;
break;
}
} }
} }
}while( framesRead < frames ); }while( framesRead < frames );
@ -3774,6 +4173,12 @@ static PaError WriteStream( PaStream* s,
if( PA_IS_OUTPUT_STREAM_(stream) ) if( PA_IS_OUTPUT_STREAM_(stream) )
{ {
/* If WaitForSingleObject starts repetitively and consecutively
returning WAIT_TIMEOUT, do eventually give up in order to allow the
caller to handle such cases.
*/
DWORD totalTimeout = 0;
/* make a local copy of the user buffer pointer(s). this is necessary /* make a local copy of the user buffer pointer(s). this is necessary
because PaUtil_CopyOutput() advances these pointers every time because PaUtil_CopyOutput() advances these pointers every time
it is called. it is called.
@ -3794,6 +4199,8 @@ static PaError WriteStream( PaStream* s,
do{ do{
if( CurrentOutputBuffersAreDone( stream ) ) if( CurrentOutputBuffersAreDone( stream ) )
{ {
totalTimeout = 0;
if( NoBuffersAreQueued( &stream->output ) ) if( NoBuffersAreQueued( &stream->output ) )
{ {
/** @todo REVIEW: consider what to do if the output /** @todo REVIEW: consider what to do if the output
@ -3849,9 +4256,17 @@ static PaError WriteStream( PaStream* s,
} }
else if( waitResult == WAIT_TIMEOUT ) else if( waitResult == WAIT_TIMEOUT )
{ {
/* if a timeout is encountered, continue, /* If a timeout is encountered, continue. However, testing
perhaps we should give up eventually has shown that it is possible to unplug a device and to
wait here forever. In order to allow the caller to handle
such cases of repeated timeouts, do eventually given up.
*/ */
totalTimeout += timeout;
if( PA_MME_MAX_TIMEOUT_MSEC_ <= totalTimeout)
{
result = paTimedOut;
break;
}
} }
} }
}while( framesWritten < frames ); }while( framesWritten < frames );

View file

@ -0,0 +1,76 @@
#include "pa_util.h"
#include "pa_debugprint.h"
#include "pa_allocation.h"
#include <stdio.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
/* Implemented in pa_front.c
@param first 0 = unknown, 1 = insertion, 2 = removal
@param second Host specific device change info (in windows it is the (unicode) device path)
*/
extern void PaUtil_DevicesChanged(unsigned, void*);
/* Callback for audio hardware property changes. */
static OSStatus audioPropertyCallback(AudioHardwarePropertyID inPropertyID,
void *refCon)
{
(void)refCon;
switch (inPropertyID)
{
/*
* These are the other types of notifications we might receive, however, they are beyond
* the scope of this sample and we ignore them.
*/
case kAudioHardwarePropertyDefaultInputDevice:
PA_DEBUG(("audioPropertyCallback: default input device changed\n"));
break;
case kAudioHardwarePropertyDefaultOutputDevice:
PA_DEBUG(("audioPropertyCallback: default output device changed\n"));
break;
case kAudioHardwarePropertyDefaultSystemOutputDevice:
PA_DEBUG(("audioPropertyCallback: default system output device changed\n"));
break;
case kAudioHardwarePropertyDevices:
PA_DEBUG(("audioPropertyCallback: device list changed\n"));
PaUtil_DevicesChanged(1, NULL);
break;
default:
PA_DEBUG(("audioPropertyCallback: unknown message id=%08lx\n", inPropertyID));
break;
}
return noErr;
}
void PaUtil_InitializeHotPlug()
{
AudioHardwareAddPropertyListener(kAudioHardwarePropertyDevices,
audioPropertyCallback, NULL);
AudioHardwareAddPropertyListener(kAudioHardwarePropertyDefaultInputDevice,
audioPropertyCallback, NULL);
AudioHardwareAddPropertyListener(kAudioHardwarePropertyDefaultOutputDevice,
audioPropertyCallback, NULL);
}
void PaUtil_TerminateHotPlug()
{
AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDevices,
audioPropertyCallback);
AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDefaultInputDevice,
audioPropertyCallback);
AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDefaultOutputDevice,
audioPropertyCallback);
}
void PaUtil_LockHotPlug()
{
}
void PaUtil_UnlockHotPlug()
{
}

View file

@ -0,0 +1,147 @@
#include "pa_util.h"
#include "pa_debugprint.h"
#include "pa_allocation.h"
#include "pa_linux_alsa.h"
#include "pa_hostapi.h"
#include <alsa/asoundlib.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
/* Implemented in pa_front.c
@param first 0 = unknown, 1 = insertion, 2 = removal
@param second Host specific device change info (in windows it is the (unicode) device path)
*/
extern void PaUtil_DevicesChanged(unsigned, void*);
static pthread_t g_thread_id;
static pthread_mutex_t g_mutex;
static volatile sig_atomic_t g_run = 0;
static int device_list_size(void)
{
snd_ctl_t *handle;
int card, err, dev, idx;
int nb = 0;
snd_ctl_card_info_t *info;
snd_pcm_info_t *pcminfo;
snd_ctl_card_info_alloca(&info);
snd_pcm_info_alloca(&pcminfo);
card = -1;
if (snd_card_next(&card) < 0 || card < 0)
{
return nb;
}
while (card >= 0)
{
char name[32];
sprintf(name, "hw:%d", card);
if ((err = snd_ctl_open(&handle, name, 0)) < 0)
{
goto next_card;
}
if ((err = snd_ctl_card_info(handle, info)) < 0)
{
snd_ctl_close(handle);
goto next_card;
}
dev = -1;
while (1)
{
unsigned int count;
int hasPlayback = 0;
int hasCapture = 0;
snd_ctl_pcm_next_device(handle, &dev);
if (dev < 0)
break;
snd_pcm_info_set_device(pcminfo, dev);
snd_pcm_info_set_subdevice(pcminfo, 0);
snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
if ((err = snd_ctl_pcm_info(handle, pcminfo)) >= 0)
{
hasCapture = 1;
}
snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
if ((err = snd_ctl_pcm_info(handle, pcminfo)) >= 0)
{
hasPlayback = 1;
count = snd_pcm_info_get_subdevices_count(pcminfo);
}
if(hasPlayback == 0 && hasCapture == 0)
continue;
nb++;
}
snd_ctl_close(handle);
next_card:
if (snd_card_next(&card) < 0)
{
break;
}
}
return nb;
}
static void* thread_fcn(void* data)
{
int currentDevices = 0;
currentDevices = device_list_size();
while(g_run)
{
int count = 0;
sleep(1);
count = device_list_size();
if(count != currentDevices)
{
/* 1 = add device, 2 = remove device */
int add = (count > currentDevices) ? 1 : 2;
currentDevices = count;
PaUtil_DevicesChanged(add, NULL);
}
}
return NULL;
}
void PaUtil_InitializeHotPlug()
{
pthread_mutex_init(&g_mutex, NULL);
g_run = 1;
pthread_create(&g_thread_id, NULL, thread_fcn, NULL);
}
void PaUtil_TerminateHotPlug()
{
void* ret = NULL;
g_run = 0;
pthread_join(g_thread_id, &ret);
pthread_mutex_destroy(&g_mutex);
}
void PaUtil_LockHotPlug()
{
pthread_mutex_lock(&g_mutex);
}
void PaUtil_UnlockHotPlug()
{
pthread_mutex_unlock(&g_mutex);
}

View file

@ -1,5 +1,5 @@
/* /*
* $Id$ * $Id: pa_win_hostapis.c 1661 2011-04-28 18:54:46Z rob_bielik $
* Portable Audio I/O Library Windows initialization table * Portable Audio I/O Library Windows initialization table
* *
* Based on the Open Source API proposed by Ross Bencina * Based on the Open Source API proposed by Ross Bencina
@ -81,7 +81,7 @@ PaUtilHostApiInitializer *paHostApiInitializers[] =
#endif #endif
#if PA_USE_WDMKS #if PA_USE_WDMKS
PaWinWdm_Initialize, //PaWinWdm_Initialize,
#endif #endif
#if PA_USE_SKELETON #if PA_USE_SKELETON

318
src/os/win/pa_win_hotplug.c Normal file
View file

@ -0,0 +1,318 @@
#include "pa_util.h"
#include "pa_debugprint.h"
#include "pa_allocation.h"
#include "pa_win_wdmks_utils.h"
#include <windows.h>
#include <dbt.h>
#include <process.h>
#include <assert.h>
#include <ks.h>
#include <ksmedia.h>
#include <setupapi.h>
#include <stdio.h>
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
#pragma comment( lib, "setupapi.lib" )
#endif
/* Implemented in pa_front.c
@param first 0 = unknown, 1 = insertion, 2 = removal
@param second Host specific device change info (in windows it is the (unicode) device path)
*/
extern void PaUtil_DevicesChanged(unsigned, void*);
/* use CreateThread for CYGWIN/Windows Mobile, _beginthreadex for all others */
#if !defined(__CYGWIN__) && !defined(_WIN32_WCE)
#define CREATE_THREAD_FUNCTION (HANDLE)_beginthreadex
#define PA_THREAD_FUNC static unsigned WINAPI
#else
#define CREATE_THREAD_FUNCTION CreateThread
#define PA_THREAD_FUNC static DWORD WINAPI
#endif
typedef struct PaHotPlugDeviceInfo
{
wchar_t name[MAX_PATH];
struct PaHotPlugDeviceInfo* next;
} PaHotPlugDeviceInfo;
typedef struct PaHotPlugDeviceEventHandlerInfo
{
HANDLE hWnd;
HANDLE hMsgThread;
HANDLE hNotify;
CRITICAL_SECTION lock;
PaUtilAllocationGroup* cacheAllocGroup;
PaHotPlugDeviceInfo* cache;
} PaHotPlugDeviceEventHandlerInfo;
static BOOL RemoveDeviceFromCache(PaHotPlugDeviceEventHandlerInfo* pInfo, const wchar_t* name)
{
if (pInfo->cache != NULL)
{
PaHotPlugDeviceInfo* lastEntry = 0;
PaHotPlugDeviceInfo* entry = pInfo->cache;
while (entry != NULL)
{
if (_wcsicmp(entry->name, name) == 0)
{
if (lastEntry)
{
lastEntry->next = entry->next;
}
else
{
pInfo->cache = NULL;
}
PaUtil_GroupFreeMemory(pInfo->cacheAllocGroup, entry);
return TRUE;
}
lastEntry = entry;
entry = entry->next;
}
}
return FALSE;
}
static void InsertDeviceIntoCache(PaHotPlugDeviceEventHandlerInfo* pInfo, const wchar_t* name)
{
PaHotPlugDeviceInfo** ppEntry = NULL;
/* Remove it first (if possible) so we don't accidentally get duplicates */
RemoveDeviceFromCache(pInfo, name);
if (pInfo->cache == NULL)
{
ppEntry = &pInfo->cache;
}
else
{
PaHotPlugDeviceInfo* entry = pInfo->cache;
while (entry->next != NULL)
{
entry = entry->next;
}
ppEntry = &entry->next;
}
*ppEntry = (PaHotPlugDeviceInfo*)PaUtil_GroupAllocateMemory(pInfo->cacheAllocGroup, sizeof(PaHotPlugDeviceInfo));
wcsncpy((*ppEntry)->name, name, MAX_PATH-1);
(*ppEntry)->next = NULL;
}
static BOOL IsDeviceAudio(const wchar_t* deviceName)
{
int channelCnt = 0;
channelCnt += PaWin_WDMKS_QueryFilterMaximumChannelCount((void*)deviceName, 1);
channelCnt += PaWin_WDMKS_QueryFilterMaximumChannelCount((void*)deviceName, 0);
return (channelCnt > 0);
}
static void PopulateCacheWithAvailableAudioDevices(PaHotPlugDeviceEventHandlerInfo* pInfo)
{
HDEVINFO handle = NULL;
const int sizeInterface = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + (MAX_PATH * sizeof(WCHAR));
SP_DEVICE_INTERFACE_DETAIL_DATA_W* devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)PaUtil_AllocateMemory(sizeInterface);
if (devInterfaceDetails)
{
devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
/* Open a handle to search for devices (filters) */
handle = SetupDiGetClassDevsW(&KSCATEGORY_AUDIO,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if( handle != NULL )
{
int device;
/* Iterate through the devices */
for( device = 0;;device++ )
{
SP_DEVICE_INTERFACE_DATA interfaceData;
SP_DEVINFO_DATA devInfoData;
int noError;
interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
interfaceData.Reserved = 0;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
devInfoData.Reserved = 0;
noError = SetupDiEnumDeviceInterfaces(handle,NULL,&KSCATEGORY_AUDIO,device,&interfaceData);
if( !noError )
break; /* No more devices */
noError = SetupDiGetDeviceInterfaceDetailW(handle,&interfaceData,devInterfaceDetails,sizeInterface,NULL,&devInfoData);
if( noError )
{
if (IsDeviceAudio(devInterfaceDetails->DevicePath))
{
PA_DEBUG(("Hotplug cache populated with: '%S'\n", devInterfaceDetails->DevicePath));
InsertDeviceIntoCache(pInfo, devInterfaceDetails->DevicePath);
}
}
}
SetupDiDestroyDeviceInfoList(handle);
}
PaUtil_FreeMemory(devInterfaceDetails);
}
}
static LRESULT CALLBACK PaMsgWinProcW(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PaHotPlugDeviceEventHandlerInfo* pInfo = (PaHotPlugDeviceEventHandlerInfo*)( GetWindowLongPtr(hWnd, GWLP_USERDATA) );
switch(msg)
{
case WM_DEVICECHANGE:
switch(wParam)
{
case DBT_DEVICEARRIVAL:
{
PDEV_BROADCAST_DEVICEINTERFACE_W ptr = (PDEV_BROADCAST_DEVICEINTERFACE_W)lParam;
if (ptr->dbcc_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
break;
if (!IsEqualGUID(&ptr->dbcc_classguid, &KSCATEGORY_AUDIO))
break;
if (IsDeviceAudio(ptr->dbcc_name))
{
PA_DEBUG(("Device inserted : %S\n", ptr->dbcc_name));
InsertDeviceIntoCache(pInfo, ptr->dbcc_name);
/* yield some seconds because added device may not be completely configured */
Sleep(2000);
PaUtil_DevicesChanged(1, ptr->dbcc_name);
}
}
break;
case DBT_DEVICEREMOVECOMPLETE:
{
PDEV_BROADCAST_DEVICEINTERFACE_W ptr = (PDEV_BROADCAST_DEVICEINTERFACE_W)lParam;
if (ptr->dbcc_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
break;
if (!IsEqualGUID(&ptr->dbcc_classguid, &KSCATEGORY_AUDIO))
break;
if (RemoveDeviceFromCache(pInfo, ptr->dbcc_name))
{
PA_DEBUG(("Device removed : %S\n", ptr->dbcc_name));
Sleep(2000);
PaUtil_DevicesChanged(2, ptr->dbcc_name);
}
}
break;
default:
break;
}
break;
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
PA_THREAD_FUNC PaRunMessageLoop(void* ptr)
{
PaHotPlugDeviceEventHandlerInfo* pInfo = (PaHotPlugDeviceEventHandlerInfo*)ptr;
WNDCLASSW wnd = { 0 };
HMODULE hInstance = GetModuleHandleW(NULL);
wnd.lpfnWndProc = PaMsgWinProcW;
wnd.hInstance = hInstance;
wnd.lpszClassName = L"{1E0D4F5A-B31F-4dcc-AE3C-4F30A47BD521}"; /* Using a GUID as class name */
pInfo->hWnd = CreateWindowW((LPCWSTR)MAKEINTATOM(RegisterClassW(&wnd)), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
if (pInfo->hWnd)
{
DEV_BROADCAST_DEVICEINTERFACE_W NotificationFilter = { sizeof(DEV_BROADCAST_DEVICEINTERFACE_W) };
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
#ifndef DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
#define DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 0x00000004
#endif
pInfo->hNotify = RegisterDeviceNotificationW(
pInfo->hWnd,
&NotificationFilter,
DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
);
assert(pInfo->hNotify);
SetWindowLongPtr(pInfo->hWnd, GWLP_USERDATA, (LONG_PTR)pInfo);
if (pInfo->hNotify)
{
MSG msg;
BOOL result;
while((result = GetMessageW(&msg, pInfo->hWnd, 0, 0)) != 0)
{
if (result == -1)
{
break;
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
UnregisterDeviceNotification(pInfo->hNotify);
pInfo->hNotify = 0;
}
DestroyWindow(pInfo->hWnd);
pInfo->hWnd = 0;
}
return 0;
}
static PaHotPlugDeviceEventHandlerInfo* s_handler = 0;
void PaUtil_InitializeHotPlug()
{
if (s_handler == 0)
{
s_handler = (PaHotPlugDeviceEventHandlerInfo*)PaUtil_AllocateMemory(sizeof(PaHotPlugDeviceEventHandlerInfo));
if (s_handler)
{
s_handler->cacheAllocGroup = PaUtil_CreateAllocationGroup();
InitializeCriticalSection(&s_handler->lock);
PopulateCacheWithAvailableAudioDevices(s_handler);
/* Start message thread */
s_handler->hMsgThread = CREATE_THREAD_FUNCTION(NULL, 0, PaRunMessageLoop, s_handler, 0, NULL);
assert(s_handler->hMsgThread != 0);
}
}
}
void PaUtil_TerminateHotPlug()
{
if (s_handler != 0)
{
if (s_handler->hWnd)
{
PostMessage(s_handler->hWnd, WM_QUIT, 0, 0);
if (WaitForSingleObject(s_handler->hMsgThread, 1000) == WAIT_TIMEOUT)
{
TerminateThread(s_handler->hMsgThread, -1);
}
}
DeleteCriticalSection(&s_handler->lock);
PaUtil_FreeAllAllocations( s_handler->cacheAllocGroup );
PaUtil_DestroyAllocationGroup( s_handler->cacheAllocGroup );
PaUtil_FreeMemory( s_handler );
s_handler = 0;
}
}
void PaUtil_LockHotPlug()
{
EnterCriticalSection(&s_handler->lock);
}
void PaUtil_UnlockHotPlug()
{
LeaveCriticalSection(&s_handler->lock);
}

View file

@ -49,31 +49,31 @@
#include <winioctl.h> // MinGW32 does not define this automatically #include <winioctl.h> // MinGW32 does not define this automatically
#include <ks.h> #include <ks.h>
#include <ksmedia.h> #include <ksmedia.h>
#include <stdio.h> // just for some development printfs #include <stdio.h> // just for some development printfs
#include "portaudio.h" #include "portaudio.h"
#include "pa_util.h" #include "pa_util.h"
#include "pa_win_wdmks_utils.h" #include "pa_win_wdmks_utils.h"
#if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB) #if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB)
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
#pragma comment( lib, "ksguid.lib" ) #pragma comment( lib, "ksguid.lib" )
#endif #endif
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO #define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM #define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX #define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard #define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard #define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin #define pa_KSPROPSETID_Pin KSPROPSETID_Pin
#else #else
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO }; static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT }; static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM }; static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX }; static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard }; static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard }; static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin }; static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
#endif #endif

View file

@ -9,7 +9,7 @@
@author Phil Burk <philburk@softsynth.com> @author Phil Burk <philburk@softsynth.com>
*/ */
/* /*
* $Id$ * $Id: patest_leftright.c 1661 2011-04-28 18:54:46Z rob_bielik $
* *
* This program uses the PortAudio Portable Audio Library. * This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com * For more information see: http://www.portaudio.com
@ -90,13 +90,13 @@ static int patestCallback( const void *inputBuffer,
{ {
// Smoothly pan between left and right. // Smoothly pan between left and right.
if( data->currentBalance < data->targetBalance ) if( data->currentBalance < data->targetBalance )
{ {
data->currentBalance += BALANCE_DELTA; data->currentBalance += BALANCE_DELTA;
} }
else if( data->currentBalance > data->targetBalance ) else if( data->currentBalance > data->targetBalance )
{ {
data->currentBalance -= BALANCE_DELTA; data->currentBalance -= BALANCE_DELTA;
} }
// Apply left/right balance. // Apply left/right balance.
*out++ = data->sine[data->left_phase] * (1.0f - data->currentBalance); /* left */ *out++ = data->sine[data->left_phase] * (1.0f - data->currentBalance); /* left */
*out++ = data->sine[data->right_phase] * data->currentBalance; /* right */ *out++ = data->sine[data->right_phase] * data->currentBalance; /* right */
@ -159,7 +159,7 @@ int main(void)
printf("Play for several seconds.\n"); printf("Play for several seconds.\n");
for( i=0; i<4; i++ ) for( i=0; i<4; i++ )
{ {
printf("Hear low sound on left side.\n"); printf("Hear low sound on left side.\n");
data.targetBalance = 0.01; data.targetBalance = 0.01;
Pa_Sleep( 1000 ); Pa_Sleep( 1000 );
@ -167,7 +167,7 @@ int main(void)
printf("Hear high sound on right side.\n"); printf("Hear high sound on right side.\n");
data.targetBalance = 0.99; data.targetBalance = 0.99;
Pa_Sleep( 1000 ); Pa_Sleep( 1000 );
} }
err = Pa_StopStream( stream ); err = Pa_StopStream( stream );
if( err != paNoError ) goto error; if( err != paNoError ) goto error;

View file

@ -6,7 +6,7 @@
@author Phil Burk <philburk@softsynth.com> @author Phil Burk <philburk@softsynth.com>
*/ */
/* /*
* $Id$ * $Id: patest_out_underflow.c 1661 2011-04-28 18:54:46Z rob_bielik $
* *
* This program uses the PortAudio Portable Audio Library. * This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com * For more information see: http://www.portaudio.com
@ -160,7 +160,7 @@ int main(void)
/* Determine number of sines required to get to 50% */ /* Determine number of sines required to get to 50% */
do do
{ {
Pa_Sleep( 100 ); Pa_Sleep( 100 );
load = Pa_GetStreamCpuLoad( stream ); load = Pa_GetStreamCpuLoad( stream );
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load ); printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
@ -168,7 +168,7 @@ int main(void)
if( load < 0.3 ) if( load < 0.3 )
{ {
data.sineCount += 10; data.sineCount += 10;
} }
else if( load < 0.4 ) else if( load < 0.4 )
{ {
data.sineCount += 2; data.sineCount += 2;

View file

@ -89,7 +89,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer,
timeInfo->currentTime, timeInfo->currentTime,
timeInfo->outputBufferDacTime ); timeInfo->outputBufferDacTime );
printf( "getStreamTime() returns: %g\n", Pa_GetStreamTime(data->stream) - data->start ); printf( "getStreamTime() returns: %g\n", Pa_GetStreamTime(data->stream)-data->start );
for( i=0; i<framesPerBuffer; i++ ) for( i=0; i<framesPerBuffer; i++ )
{ {

View file

@ -4,7 +4,7 @@
@author Phil Burk <philburk@softsynth.com> @author Phil Burk <philburk@softsynth.com>
*/ */
/* /*
* $Id$ * $Id: patest_two_rates.c 1661 2011-04-28 18:54:46Z rob_bielik $
* *
* Author: Phil Burk http://www.softsynth.com * Author: Phil Burk http://www.softsynth.com
* *
@ -64,11 +64,11 @@ typedef struct
} paTestData; } paTestData;
/* This routine will be called by the PortAudio engine when audio is needed. /* This routine will be called by the PortAudio engine when audio is needed.
** It may called at interrupt level on some machines so don't do anything ** It may called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free(). ** that could mess up the system like calling malloc() or free().
*/ */
static int patestCallback( const void *inputBuffer, void *outputBuffer, static int patestCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo, const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, PaStreamCallbackFlags statusFlags,
void *userData ) void *userData )
@ -121,15 +121,15 @@ int main(void)
/* Start first stream. **********************/ /* Start first stream. **********************/
err = Pa_OpenStream( err = Pa_OpenStream(
&stream1, &stream1,
NULL, /* no input */ NULL, /* no input */
&outputParameters, &outputParameters,
SAMPLE_RATE_1, SAMPLE_RATE_1,
FRAMES_PER_BUFFER, FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */ paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback, patestCallback,
&data1 ); &data1 );
if( err != paNoError ) goto error; if( err != paNoError ) goto error;
err = Pa_StartStream( stream1 ); err = Pa_StartStream( stream1 );
if( err != paNoError ) goto error; if( err != paNoError ) goto error;
@ -138,14 +138,14 @@ int main(void)
/* Start second stream. **********************/ /* Start second stream. **********************/
err = Pa_OpenStream( err = Pa_OpenStream(
&stream2, &stream2,
NULL, /* no input */ NULL, /* no input */
&outputParameters, &outputParameters,
SAMPLE_RATE_2, SAMPLE_RATE_2,
FRAMES_PER_BUFFER, FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */ paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback, patestCallback,
&data2 ); &data2 );
if( err != paNoError ) goto error; if( err != paNoError ) goto error;
err = Pa_StartStream( stream2 ); err = Pa_StartStream( stream2 );

View file

@ -0,0 +1,50 @@
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include "portaudio.h"
void printDevices()
{
int deviceCount = Pa_GetDeviceCount();
int i;
for( i=0; i < deviceCount; ++i ){
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(i);
const PaHostApiInfo *hostApiInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
assert( deviceInfo != 0 );
printf( "%d %s (%s)\n", i, deviceInfo->name, hostApiInfo->name );
}
}
static void devicesChangedCallback(void* p)
{
(void)p;
printf( "Portaudio device list have changed!\n" );
}
int main(int argc, char* argv[])
{
Pa_Initialize();
Pa_SetDevicesChangedCallback(NULL, devicesChangedCallback);
for(;;){
printDevices();
printf( "press [enter] to update the device list. or q + [enter] to quit.\n" );
char ch = getchar();
if( ch == 'q' )
break;
Pa_UpdateAvailableDeviceList();
}
Pa_Terminate();
return 0;
}