Update portaudio to svn1954.

This commit is contained in:
Miguel A. Colón Vélez 2015-08-07 05:53:01 -04:00
parent d826d925db
commit c17667971c
31 changed files with 1521 additions and 4330 deletions

12
3rdparty/portaudio/clear_svnrevision.sh vendored Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
#
# Clear the SVN revision in the include file.
# This should be run before checking in code to SVN.
#
revision_filename=src/common/pa_svnrevision.h
# Update the include file with the current SVN revision.
echo "#define PA_SVN_REVISION unknown" > ${revision_filename}
echo ${revision_filename} now contains
cat ${revision_filename}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

294
3rdparty/portaudio/configure vendored Normal file → Executable file
View File

@ -1,11 +1,9 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.68. # Generated by GNU Autoconf 2.69.
# #
# #
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
# Foundation, Inc.
# #
# #
# This configure script is free software; the Free Software Foundation # This configure script is free software; the Free Software Foundation
@ -134,6 +132,31 @@ export LANGUAGE
# CDPATH. # CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# Use a proper internal environment variable to ensure we don't fall
# into an infinite loop, continuously re-executing ourselves.
if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
_as_can_reexec=no; export _as_can_reexec;
# We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
*v*x* | *x*v* ) as_opts=-vx ;;
*v* ) as_opts=-v ;;
*x* ) as_opts=-x ;;
* ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
as_fn_exit 255
fi
# We don't want this to propagate to other subprocesses.
{ _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh emulate sh
@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else else
exitcode=1; echo positional parameters were not saved. exitcode=1; echo positional parameters were not saved.
fi fi
test x\$exitcode = x0 || exit 1" test x\$exitcode = x0 || exit 1
test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@ -220,21 +244,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then : if test "x$CONFIG_SHELL" != x; then :
# We cannot yet assume a decent shell, so we have to provide a export CONFIG_SHELL
# neutralization value for shells without unset; and this also # We cannot yet assume a decent shell, so we have to provide a
# works around shells that cannot unset nonexistent variables. # neutralization value for shells without unset; and this also
# Preserve -v and -x to the replacement shell. # works around shells that cannot unset nonexistent variables.
BASH_ENV=/dev/null # Preserve -v and -x to the replacement shell.
ENV=/dev/null BASH_ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV ENV=/dev/null
export CONFIG_SHELL (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # (((( case $- in # ((((
*v*x* | *x*v* ) as_opts=-vx ;; *v*x* | *x*v* ) as_opts=-vx ;;
*v* ) as_opts=-v ;; *v* ) as_opts=-v ;;
*x* ) as_opts=-x ;; *x* ) as_opts=-x ;;
* ) as_opts= ;; * ) as_opts= ;;
esac esac
exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi fi
if test x$as_have_required = xno; then : if test x$as_have_required = xno; then :
@ -336,6 +364,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p } # as_fn_mkdir_p
# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
test -f "$1" && test -x "$1"
} # as_fn_executable_p
# as_fn_append VAR VALUE # as_fn_append VAR VALUE
# ---------------------- # ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take # Append the text in VALUE to the end of the definition contained in VAR. Take
@ -457,6 +493,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" || chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
# If we had to re-execute with $CONFIG_SHELL, we're ensured to have
# already done that, so ensure we don't try to do so again and fall
# in an infinite loop. This has already happened in practice.
_as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems # Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the # (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this). # original and so on. Autoconf is especially sensitive to this).
@ -491,16 +531,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas: # ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -p'. # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -p' as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln as_ln_s=ln
else else
as_ln_s='cp -p' as_ln_s='cp -pR'
fi fi
else else
as_ln_s='cp -p' as_ln_s='cp -pR'
fi fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null rmdir conf$$.dir 2>/dev/null
@ -512,28 +552,8 @@ else
as_mkdir_p=false as_mkdir_p=false
fi fi
if test -x / >/dev/null 2>&1; then as_test_x='test -x'
as_test_x='test -x' as_executable_p=as_fn_executable_p
else
if ls -dL / >/dev/null 2>&1; then
as_ls_L_option=L
else
as_ls_L_option=
fi
as_test_x='
eval sh -c '\''
if test -d "$1"; then
test -d "$1/.";
else
case $1 in #(
-*)set "./$1";;
esac;
case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
???[sx]*):;;*)false;;esac;fi
'\'' sh
'
fi
as_executable_p=$as_test_x
# Sed expression to map a string onto a valid CPP name. # Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@ -1218,8 +1238,6 @@ target=$target_alias
if test "x$host_alias" != x; then if test "x$host_alias" != x; then
if test "x$build_alias" = x; then if test "x$build_alias" = x; then
cross_compiling=maybe cross_compiling=maybe
$as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes cross_compiling=yes
fi fi
@ -1492,9 +1510,9 @@ test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
configure configure
generated by GNU Autoconf 2.68 generated by GNU Autoconf 2.69
Copyright (C) 2010 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it. gives unlimited permission to copy, distribute and modify it.
_ACEOF _ACEOF
@ -1608,7 +1626,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err test ! -s conftest.err
} && test -s conftest$ac_exeext && { } && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes || test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext test -x conftest$ac_exeext
}; then : }; then :
ac_retval=0 ac_retval=0
else else
@ -1868,7 +1886,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err test ! -s conftest.err
} && test -s conftest$ac_exeext && { } && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes || test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext test -x conftest$ac_exeext
}; then : }; then :
ac_retval=0 ac_retval=0
else else
@ -1991,7 +2009,8 @@ int
main () main ()
{ {
static int test_array [1 - 2 * !(($2) >= 0)]; static int test_array [1 - 2 * !(($2) >= 0)];
test_array [0] = 0 test_array [0] = 0;
return test_array [0];
; ;
return 0; return 0;
@ -2007,7 +2026,8 @@ int
main () main ()
{ {
static int test_array [1 - 2 * !(($2) <= $ac_mid)]; static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0 test_array [0] = 0;
return test_array [0];
; ;
return 0; return 0;
@ -2033,7 +2053,8 @@ int
main () main ()
{ {
static int test_array [1 - 2 * !(($2) < 0)]; static int test_array [1 - 2 * !(($2) < 0)];
test_array [0] = 0 test_array [0] = 0;
return test_array [0];
; ;
return 0; return 0;
@ -2049,7 +2070,8 @@ int
main () main ()
{ {
static int test_array [1 - 2 * !(($2) >= $ac_mid)]; static int test_array [1 - 2 * !(($2) >= $ac_mid)];
test_array [0] = 0 test_array [0] = 0;
return test_array [0];
; ;
return 0; return 0;
@ -2083,7 +2105,8 @@ int
main () main ()
{ {
static int test_array [1 - 2 * !(($2) <= $ac_mid)]; static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0 test_array [0] = 0;
return test_array [0];
; ;
return 0; return 0;
@ -2156,7 +2179,7 @@ This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by $as_me, which was It was created by $as_me, which was
generated by GNU Autoconf 2.68. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2785,7 +2808,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc" ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -2825,7 +2848,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc" ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -2878,7 +2901,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc" ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -2919,7 +2942,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes ac_prog_rejected=yes
continue continue
@ -2977,7 +3000,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog" ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -3021,7 +3044,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog" ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -3467,8 +3490,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> struct stat;
#include <sys/stat.h>
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; }; struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int); FILE * (*rcsopen) (struct buf *, struct stat *, int);
@ -3582,7 +3604,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -3626,7 +3648,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog" ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -3833,7 +3855,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AS="${ac_tool_prefix}as" ac_cv_prog_AS="${ac_tool_prefix}as"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -3873,7 +3895,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AS="as" ac_cv_prog_ac_ct_AS="as"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -3925,7 +3947,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -3965,7 +3987,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DLLTOOL="dlltool" ac_cv_prog_ac_ct_DLLTOOL="dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -4017,7 +4039,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -4057,7 +4079,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="objdump" ac_cv_prog_ac_ct_OBJDUMP="objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -4231,7 +4253,7 @@ do
for ac_prog in sed gsed; do for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
{ test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue as_fn_executable_p "$ac_path_SED" || continue
# Check for GNU ac_path_SED and select it if it is found. # Check for GNU ac_path_SED and select it if it is found.
# Check for GNU $ac_path_SED # Check for GNU $ac_path_SED
case `"$ac_path_SED" --version 2>&1` in case `"$ac_path_SED" --version 2>&1` in
@ -4307,7 +4329,7 @@ do
for ac_prog in grep ggrep; do for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
{ test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found. # Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP # Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in case `"$ac_path_GREP" --version 2>&1` in
@ -4373,7 +4395,7 @@ do
for ac_prog in egrep; do for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
{ test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP # Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in case `"$ac_path_EGREP" --version 2>&1` in
@ -4440,7 +4462,7 @@ do
for ac_prog in fgrep; do for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
{ test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue as_fn_executable_p "$ac_path_FGREP" || continue
# Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU ac_path_FGREP and select it if it is found.
# Check for GNU $ac_path_FGREP # Check for GNU $ac_path_FGREP
case `"$ac_path_FGREP" --version 2>&1` in case `"$ac_path_FGREP" --version 2>&1` in
@ -4696,7 +4718,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -4740,7 +4762,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5159,7 +5181,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5199,7 +5221,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="objdump" ac_cv_prog_ac_ct_OBJDUMP="objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5502,7 +5524,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5542,7 +5564,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DLLTOOL="dlltool" ac_cv_prog_ac_ct_DLLTOOL="dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5643,7 +5665,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="$ac_tool_prefix$ac_prog" ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5687,7 +5709,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog" ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5812,7 +5834,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip" ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5852,7 +5874,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip" ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5911,7 +5933,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -5951,7 +5973,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib" ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6055,7 +6077,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog" ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6628,7 +6650,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6668,7 +6690,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6748,7 +6770,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6788,7 +6810,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6840,7 +6862,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6880,7 +6902,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NMEDIT="nmedit" ac_cv_prog_ac_ct_NMEDIT="nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6932,7 +6954,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LIPO="${ac_tool_prefix}lipo" ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -6972,7 +6994,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_LIPO="lipo" ac_cv_prog_ac_ct_LIPO="lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -7024,7 +7046,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL="${ac_tool_prefix}otool" ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -7064,7 +7086,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL="otool" ac_cv_prog_ac_ct_OTOOL="otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -7116,7 +7138,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -7156,7 +7178,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL64="otool64" ac_cv_prog_ac_ct_OTOOL64="otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -14873,7 +14895,7 @@ case $as_dir/ in #((
# by default. # by default.
for ac_prog in ginstall scoinst install; do for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install && if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention. # AIX install. It has an incompatible calling convention.
@ -14958,7 +14980,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -15391,7 +15413,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -15434,7 +15456,7 @@ do
IFS=$as_save_IFS IFS=$as_save_IFS
test -z "$as_dir" && as_dir=. test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2 break 2
@ -15769,7 +15791,7 @@ case "${host_os}" in
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon" LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
if test "x$enable_mac_universal" = "xyes" ; then if test "x$enable_mac_universal" = "xyes" ; then
case "xcodebuild -version | sed -n 's/Xcode \(.*\)/\1/p'" in case `xcodebuild -version | sed -n 's/Xcode \(.*\)/\1/p'` in
12*|3.0|3.1) 12*|3.0|3.1)
if [ -d /Developer/SDKs/MacOSX10.5.sdk ] ; then if [ -d /Developer/SDKs/MacOSX10.5.sdk ] ; then
@ -15791,8 +15813,14 @@ case "${host_os}" in
elif xcodebuild -version -sdk macosx10.7 Path >/dev/null 2>&1 ; then elif xcodebuild -version -sdk macosx10.7 Path >/dev/null 2>&1 ; then
mac_version_min="-mmacosx-version-min=10.4" mac_version_min="-mmacosx-version-min=10.4"
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.7 Path`" mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.7 Path`"
elif xcodebuild -version -sdk macosx10.8 Path >/dev/null 2>&1 ; then
mac_version_min="-mmacosx-version-min=10.4"
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.8 Path`"
elif xcodebuild -version -sdk macosx10.9 Path >/dev/null 2>&1 ; then
mac_version_min="-mmacosx-version-min=10.4"
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.9 Path`"
else else
as_fn_error $? "Couldn't find 10.5, 10.6, or 10.7 SDK" "$LINENO" 5 as_fn_error $? "Couldn't find 10.5, 10.6, 10.7, 10.8 or 10.9 SDK" "$LINENO" 5
fi fi
esac esac
@ -16632,16 +16660,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas: # ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -p'. # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -p' as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln as_ln_s=ln
else else
as_ln_s='cp -p' as_ln_s='cp -pR'
fi fi
else else
as_ln_s='cp -p' as_ln_s='cp -pR'
fi fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null rmdir conf$$.dir 2>/dev/null
@ -16701,28 +16729,16 @@ else
as_mkdir_p=false as_mkdir_p=false
fi fi
if test -x / >/dev/null 2>&1; then
as_test_x='test -x' # as_fn_executable_p FILE
else # -----------------------
if ls -dL / >/dev/null 2>&1; then # Test if FILE is an executable regular file.
as_ls_L_option=L as_fn_executable_p ()
else {
as_ls_L_option= test -f "$1" && test -x "$1"
fi } # as_fn_executable_p
as_test_x=' as_test_x='test -x'
eval sh -c '\'' as_executable_p=as_fn_executable_p
if test -d "$1"; then
test -d "$1/.";
else
case $1 in #(
-*)set "./$1";;
esac;
case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
???[sx]*):;;*)false;;esac;fi
'\'' sh
'
fi
as_executable_p=$as_test_x
# Sed expression to map a string onto a valid CPP name. # Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@ -16744,7 +16760,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by $as_me, which was This file was extended by $as_me, which was
generated by GNU Autoconf 2.68. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_HEADERS = $CONFIG_HEADERS
@ -16801,10 +16817,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
config.status config.status
configured by $0, generated by GNU Autoconf 2.68, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
Copyright (C) 2010 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it." gives unlimited permission to copy, distribute and modify it."
@ -16883,7 +16899,7 @@ fi
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then if \$ac_cs_recheck; then
set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL' CONFIG_SHELL='$SHELL'

View File

@ -208,7 +208,7 @@ case "${host_os}" in
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon" LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
if test "x$enable_mac_universal" = "xyes" ; then if test "x$enable_mac_universal" = "xyes" ; then
case "xcodebuild -version | sed -n 's/Xcode \(.*\)/\1/p'" in case `xcodebuild -version | sed -n 's/Xcode \(.*\)/\1/p'` in
[12]*|3.0|3.1) [12]*|3.0|3.1)
dnl In pre-3.2 versions of Xcode, xcodebuild doesn't dnl In pre-3.2 versions of Xcode, xcodebuild doesn't
@ -243,8 +243,14 @@ case "${host_os}" in
elif xcodebuild -version -sdk macosx10.7 Path >/dev/null 2>&1 ; then elif xcodebuild -version -sdk macosx10.7 Path >/dev/null 2>&1 ; then
mac_version_min="-mmacosx-version-min=10.4" mac_version_min="-mmacosx-version-min=10.4"
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.7 Path`" mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.7 Path`"
elif xcodebuild -version -sdk macosx10.8 Path >/dev/null 2>&1 ; then
mac_version_min="-mmacosx-version-min=10.4"
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.8 Path`"
elif xcodebuild -version -sdk macosx10.9 Path >/dev/null 2>&1 ; then
mac_version_min="-mmacosx-version-min=10.4"
mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.9 Path`"
else else
AC_MSG_ERROR([Couldn't find 10.5, 10.6, or 10.7 SDK]) AC_MSG_ERROR([Couldn't find 10.5, 10.6, 10.7, 10.8 or 10.9 SDK])
fi fi
esac esac

0
3rdparty/portaudio/depcomp vendored Normal file → Executable file
View File

View File

@ -1,33 +1,39 @@
/** @page compile_windows Building Portaudio for Windows using Microsoft Visual Studio /** @page compile_windows Building PortAudio for Windows using Microsoft Visual Studio
@ingroup tutorial @ingroup tutorial
Below is a list of steps to build PortAudio into a dll and lib file. The resulting dll file may contain all five current win32 PortAudio APIs: MME, DirectSound, WASAPI, WDM/KS and ASIO, depending on the preprocessor definitions set in step 9 below. Below is a list of steps to build PortAudio into a dll and lib file. The resulting dll file may contain all five current win32 PortAudio APIs: MME, DirectSound, WASAPI, WDM/KS and ASIO, depending on the preprocessor definitions set in step 9 below.
PortAudio can be compiled using Visual C++ Express Edition which is available free from Microsoft. If you do not already have a C++ development environment, simply download and install. These instructions have been observed to succeed using Visual Studio 2010 as well. PortAudio can be compiled using Visual C++ Express Edition which is available free from Microsoft. If you do not already have a C++ development environment, simply download and install. These instructions have been observed to succeed using Visual Studio 2010 as well.
1) PortAudio for Windows requires the files <i>dsound.h</i> and <i>dsconf.h</i>. Download and install the DirectX SDK from http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=3021d52b-514e-41d3-ad02-438a3ba730ba to obtain these files. If you installed the DirectX SDK then the !DirectSound libraries and header files should be found automatically by Visual !Studio/Visual C++. If you get an error saying dsound.h or dsconf.h is missing, you can declare these paths by hand. Alternatively, you can copy dsound.h and dsconf.h to portaudio\\include. There should also be a file named ''dsound.lib'' in C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\Lib. 1) Building PortAudio with DirectSound support requires the files <i>dsound.h</i> and <i>dsconf.h</i>. Download and install the DirectX SDK from http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=3021d52b-514e-41d3-ad02-438a3ba730ba to obtain these files. If you installed the DirectX SDK then the DirectSound libraries and header files should be found automatically by Visual Studio/Visual C++. If you get an error saying dsound.h or dsconf.h is missing, you will need to add an extra include path to the Visual Studio project file referencing the DirectX includes directory.
2) For ASIO support, download the ASIO SDK from Steinberg at http://www.steinberg.net/en/company/developer.html. The SDK is free but you will need to set up a developer account with Steinberg. Copy the entire ASIOSDK2 folder into src\\hostapi\\asio\\. Rename it from ASIOSDK2 to ASIOSDK. To build without ASIO (or other host API) see the "Building without ASIO support" section below. 2) For ASIO support, download the ASIO SDK from Steinberg at http://www.steinberg.net/en/company/developer.html . The SDK is free, but you will need to set up a developer account with Steinberg. To use the Visual Studio projects mentioned below, copy the entire ASIOSDK2 folder into src\\hostapi\\asio\\. Rename it from ASIOSDK2 to ASIOSDK. To build without ASIO (or other host API) see the "Building without ASIO support" section below.
3) If you have Visual Studio 6.0, 7.0(VC.NET/2001) or 7.1(VC.2003), open portaudio.dsp and convert if needed. 3) If you have Visual Studio 6.0, 7.0(VC.NET/2001) or 7.1(VC.2003), open portaudio.dsp and convert if needed.
4) If you have Visual Studio 2005, Visual C++ 2008 Express Edition or Visual Studio 2010, double click the portaudio.sln file located in build\\msvc\\. Doing so will open Visual Studio or Visual C++. Click "Finish" if a wizard appears. The sln file contains four configurations: Win32 and Win64 in both Release and Debug variants. 4) If you have Visual Studio 2005, Visual C++ 2008 Express Edition or Visual Studio 2010, open the portaudio.sln file located in build\\msvc\\. Doing so will open Visual Studio or Visual C++. Click "Finish" if a conversion wizard appears. The sln file contains four configurations: Win32 and Win64 in both Release and Debug variants.
@section comp_win1 For Visual Studio 2005, Visual C++ 2008 Express Edition or Visual Studio 2010 @section comp_win1 For Visual Studio 2005, Visual C++ 2008 Express Edition or Visual Studio 2010
The steps below describe settings for recent versions of Visual Studio. Similar settings can be set in earlier versions of Visual Studio.
5) Open Project -> portaudio Properties and select "Configuration Properties" in the tree view. 5) Open Project -> portaudio Properties and select "Configuration Properties" in the tree view.
6) Select "all configurations" in the "Configurations" combo box above. Select "All Platforms" in the "Platforms" combo box. 6) Select "all configurations" in the "Configurations" combo box above. Select "All Platforms" in the "Platforms" combo box.
7) Now set a few options: 7) Now set a few options:
C/C++ -> Optimization -> Omit frame pointers = Yes Required:
C/C++ -> Code Generation -> Runtime library = /MT C/C++ -> Code Generation -> Runtime library = /MT
Optional:
C/C++ -> Optimization -> Omit frame pointers = Yes
Optional: C/C++ -> Code Generation -> Floating point model = fast Optional: C/C++ -> Code Generation -> Floating point model = fast
NOTE: For most users it is not necessary to explicitly set the structure member alignment; the default should work fine. However some languages require, for example, 4-byte alignment. If you are having problems with portaudio.h structure members not being properly read or written to, it may be necessary to explicitly set this value by going to C/C++ -> Code Generation -> Struct member alignment and setting it to an appropriate value (four is a common value). If your compiler is configurable, you should ensure that it is set to use the same structure member alignment value as used for the PortAudio build. NOTE: When using PortAudio from C/C++ it is not usually necessary to explicitly set the structure member alignment; the default should work fine. However some languages require, for example, 4-byte alignment. If you are having problems with portaudio.h structure members not being properly read or written to, it may be necessary to explicitly set this value by going to C/C++ -> Code Generation -> Struct member alignment and setting it to an appropriate value (four is a common value). If your compiler is configurable, you should ensure that it is set to use the same structure member alignment value as used for the PortAudio build.
Click "Ok" when you have finished setting these parameters. Click "Ok" when you have finished setting these parameters.
@ -37,16 +43,16 @@ Since the preprocessor definitions are different for each configuration and plat
8) To suppress PortAudio runtime debug console output, go to Project -> Properties -> Configuration Properties -> C/C++ -> Preprocessor. In the field 'Preprocessor Definitions', find PA_ENABLE_DEBUG_OUTPUT and remove it. The console will not output debug messages. 8) To suppress PortAudio runtime debug console output, go to Project -> Properties -> Configuration Properties -> C/C++ -> Preprocessor. In the field 'Preprocessor Definitions', find PA_ENABLE_DEBUG_OUTPUT and remove it. The console will not output debug messages.
9) Also in the preprocessor definitions you need to explicitly define the audio APIs you wish to use. For Windows the available API definitions are: 9) Also in the preprocessor definitions you need to explicitly define the native audio APIs you wish to use. For Windows the available API definitions are:
PA_USE_ASIO[[BR]] PA_USE_ASIO<br>
PA_USE_DS (DirectSound)[[BR]] PA_USE_DS (DirectSound)<br>
PA_USE_WMME (MME)[[BR]] PA_USE_WMME (MME)<br>
PA_USE_WASAPI[[BR]] PA_USE_WASAPI<br>
PA_USE_WDMKS[[BR]] PA_USE_WDMKS<br>
PA_USE_SKELETON PA_USE_SKELETON
For each of these, the value of 0 indicates that support for this API should not be included. The value 1 indicates that support for this API should be included. For each of these, the value of 0 indicates that support for this API should not be included. The value 1 indicates that support for this API should be included. (PA_USE_SKELETON is not usually used, it is a code sample for developers wanting to support a new API).
@section comp_win3 Building @section comp_win3 Building
@ -54,7 +60,7 @@ As when setting Preprocessor definitions, building is a per-configuration per-pl
10) From the Build menu click Build -> Build solution. For 32-bit compilations, the dll file created by this process (portaudio_x86.dll) can be found in the directory build\\msvc\\Win32\\Release. For 64-bit compilations, the dll file is called portaudio_x64.dll, and is found in the directory build\\msvc\\x64\\Release. 10) From the Build menu click Build -> Build solution. For 32-bit compilations, the dll file created by this process (portaudio_x86.dll) can be found in the directory build\\msvc\\Win32\\Release. For 64-bit compilations, the dll file is called portaudio_x64.dll, and is found in the directory build\\msvc\\x64\\Release.
11) Now, any project which requires portaudio can be linked with portaudio_x86.lib (or _x64) and include the relevant headers (portaudio.h, and/or pa_asio.h , pa_x86_plain_converters.h) You may want to add/remove some DLL entry points. Right now those 6 entries are not from portaudio.h: 11) Now, any project that requires portaudio can be linked with portaudio_x86.lib (or _x64) and include the relevant headers (portaudio.h, and/or pa_asio.h , pa_x86_plain_converters.h) You may want to add/remove some DLL entry points. At the time of writing the following 6 entries are not part of the official PortAudio API defined in portaudio.h:
(from portaudio.def) (from portaudio.def)
@code @code
@ -71,13 +77,16 @@ PaUtil_SetLogPrintFunction @55
To build PortAudio without ASIO support you need to: To build PortAudio without ASIO support you need to:
1) Make sure your project doesn't try to build any ASIO SDK files. If you're using one of the shipped projects, remove the ASIO related files from the project. 1) Make sure your project doesn't try to build any ASIO SDK files. If you're using one of the shipped projects, remove the ASIO related files from the project. In the shipped projects you can find them in the project tree under portaudio > Source Files > hostapi > ASIO > ASIOSDK
2) Make sure your project doesn't try to build the PortAudio ASIO implementation files: 2) Make sure your project doesn't try to build the PortAudio ASIO implementation files:
src\\hostapi\\pa_asio.cpp src\\hostapi\\iasiothiscallresolver.cpp @code
src\\hostapi\\pa_asio.cpp
src\\hostapi\\iasiothiscallresolver.cpp
@endcode
If you're using one of the shipped projects, remove them from the project. If you're using one of the shipped projects, remove them from the project. In the shipped projects you can find them in the project tree under portaudio > Source Files > hostapi > ASIO
3) Define the preprocessor symbols in the project properties as described in step 9 above. In VS2005 this can be accomplished by selecting 3) Define the preprocessor symbols in the project properties as described in step 9 above. In VS2005 this can be accomplished by selecting
Project Properties -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions. Omitting PA_USE_ASIO or setting it to 0 stops src\\os\\win\\pa_win_hostapis.c from trying to initialize the PortAudio ASIO implementation. Project Properties -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions. Omitting PA_USE_ASIO or setting it to 0 stops src\\os\\win\\pa_win_hostapis.c from trying to initialize the PortAudio ASIO implementation.
@ -92,6 +101,8 @@ Updated by Chris on 5/26/2011
Improvements by John Clements on 12/15/2011 Improvements by John Clements on 12/15/2011
Edits by Ross on 1/20/2014
Back to the Tutorial: \ref tutorial_start Back to the Tutorial: \ref tutorial_start
*/ */

View File

@ -7,14 +7,14 @@ This tutorial describes how to build PortAudio with ASIO support using MSVC *fro
ASIO is a low latency audio API from Steinberg. To compile an ASIO ASIO is a low latency audio API from Steinberg. To compile an ASIO
application, you must first download the ASIO SDK from Steinberg. You also application, you must first download the ASIO SDK from Steinberg. You also
need to obtain ASIO drivers for your audio device. Download the ASIO SDK from Steinberg at http://www.steinberg.net/en/company/developer.html. The SDK is free but you will need to set up a developer account with Steinberg. need to obtain ASIO drivers for your audio device. Download the ASIO SDK from Steinberg at http://www.steinberg.net/en/company/developer.html . The SDK is free but you will need to set up a developer account with Steinberg.
This tutorial assumes that you have 3 directories set up at the same level (side by side), one containing PortAudio, one containing the ASIO SDK and one containing your Visual Studio project: This tutorial assumes that you have 3 directories set up at the same level (side by side), one containing PortAudio, one containing the ASIO SDK and one containing your Visual Studio project:
@code @code
/ASIOSDK2 /ASIOSDK2
/portaudio /portaudio
/DirContainingYourVisualStudioProject /DirContainingYourVisualStudioProject (should directly contain the .sln, .vcproj or .vcprojx etc.)
@endcode @endcode
First, make sure that the Steinberg SDK and the portaudio files are "side by side" in the same directory. First, make sure that the Steinberg SDK and the portaudio files are "side by side" in the same directory.
@ -54,10 +54,11 @@ pa_stream.c (portaudio\src\common)
pa_trace.c (portaudio\src\common) pa_trace.c (portaudio\src\common)
pa_win_hostapis.c (portaudio\src\os\win) pa_win_hostapis.c (portaudio\src\os\win)
pa_win_util.c (portaudio\src\os\win) pa_win_util.c (portaudio\src\os\win)
pa_win_coinitialize.c (portaudio\src\os\win)
pa_win_waveformat.c (portaudio\src\os\win) pa_win_waveformat.c (portaudio\src\os\win)
pa_x86_plain_converters.c (portaudio\src\os\win) pa_x86_plain_converters.c (portaudio\src\os\win)
patest_saw.c (portaudio\test) (Or another file containing main() paex_saw.c (portaudio\examples) (Or another file containing main()
for the console exe to be built.) for the console exe to be built.)
@endcode @endcode
@ -71,25 +72,26 @@ pa_asio.h (portaudio\include)
These header files define the interfaces to the PortAudio API. These header files define the interfaces to the PortAudio API.
Next, go to Project Settings > All Configurations > C/C++ > Preprocessor > Preprocessor definitions and add Next, go to Project Settings > All Configurations > C/C++ > Preprocessor > Preprocessor Definitions and add
PA_USE_ASIO=1 to any entries that might be there. PA_USE_ASIO=1 to any entries that might be there.
eg: WIN32;_CONSOLE;_MBCS changes to WIN32;_CONSOLE,_MBCS;PA_USE_ASIO=1 eg: WIN32;_CONSOLE;_MBCS changes to WIN32;_CONSOLE,_MBCS;PA_USE_ASIO=1
Then, on the same Project Settings tab, go down to Additional include directories: and enter the following relative include paths. Then, on the same Project Settings tab, go down to Additional Include Directories (in VS2010 you'll find this setting under C/C++ > General) and enter the following relative include paths:
@code @code
..\portaudio\include,..\portaudio\src\common,..\asiosdk2\common,..\asiosdk2\host,..\asiosdk2\host\pc ..\portaudio\include;..\portaudio\src\common;..\portaudio\src\os\win;..\asiosdk2\common;..\asiosdk2\host;..\asiosdk2\host\pc
@endcode @endcode
You'll need to make sure the relative paths are correct for the particular directory layout you're using. The above should work fine if you use the side-by-side layout we recommended earlier. You'll need to make sure the relative paths are correct for the particular directory layout you're using. The above should work fine if you use the side-by-side layout we recommended earlier.
You should now be able to build any of the test executables in the portaudio\test directory. Some source code in the ASIO SDK is not compatible with the Win32 API UNICODE mode (The ASIO SDK expects the non-Unicode Win32 API). Therefore you need to make sure your project is set to not use Unicode. You do this by setting the project Character Set to "Use Multi-Byte Character Set" (NOT "Use Unicode Character Set"). In VS2010 the Character Set option can be found at Configuration Properties > General > Character Set. (An alternative to setting the project to non-Unicode is to patch asiolist.cpp to work when UNICODE is defined: put #undef UNICODE at the top of the file before windows.h is included.)
We suggest that you start with patest_saw.c because it's one of the simplest test files.
You should now be able to build any of the test executables in the portaudio\\examples directory.
We suggest that you start with paex_saw.c because it's one of the simplest example files.
--- Chris Share, Tom McCandless, Ross Bencina --- Chris Share, Tom McCandless, Ross Bencina
[wiki:UsingThePortAudioSvnRepository SVN instructions]
Back to the Tutorial: \ref tutorial_start Back to the Tutorial: \ref tutorial_start
*/ */

View File

@ -7,7 +7,11 @@ To write a program using PortAudio, you must include the "portaudio.h" include f
@endcode @endcode
The next task is to write your own "callback" function. The "callback" is a function that is called by the PortAudio engine whenever it has captured audio data, or when it needs more audio data for output. The next task is to write your own "callback" function. The "callback" is a function that is called by the PortAudio engine whenever it has captured audio data, or when it needs more audio data for output.
Before we begin, it's important to realize that the callback is a delicate place. This is because some systems perform the callback in a special thread, or interrupt handler, and it is rarely treated the same as the rest of your code. In addition, if you want your audio to reach the speakers on time, you'll need to make sure whatever code you run in the callback runs quickly. What is safe or not safe will vary from platform to platform, but as a rule of thumb, don't do anything like allocating or freeing memory, reading or writing files, printf(), or anything else that might take an unbounded amount of time or rely on the OS or require a context switch. <i>Ed: is this still true?: Also do not call any PortAudio functions in the callback except for Pa_StreamTime() and Pa_GetCPULoad().</i> Before we begin, it's important to realize that the callback is a delicate place. This is because some systems perform the callback in a special thread, or interrupt handler, and it is rarely treated the same as the rest of your code.
For most modern systems, you won't be able to cause crashes by making disallowed calls in the callback, but if you want your code to produce glitch-free audio, you will have to make sure you avoid function calls that may take an unbounded amount of time
to execute. Exactly what these are depend on your platform but almost certainly include the following: memory allocation/deallocation, I/O (including file I/O as well as console I/O, such as printf()), context switching (such as exec() or
yield()), mutex operations, or anything else that might rely on the OS. If you think short critical sections are safe please go read about priority inversion. Windows amd Mac OS schedulers have no real-time safe priority inversion prevention. Other platforms require special mutex flags. In addition, it is not safe to call any PortAudio API functions in the callback except as explicitly permitted in the documentation.
Your callback function must return an int and accept the exact parameters specified in this typedef: Your callback function must return an int and accept the exact parameters specified in this typedef:

0
3rdparty/portaudio/fixdir.bat vendored Normal file → Executable file
View File

0
3rdparty/portaudio/fixfile.bat vendored Normal file → Executable file
View File

View File

@ -1,7 +1,7 @@
#ifndef PA_WIN_WDMKS_H #ifndef PA_WIN_WDMKS_H
#define PA_WIN_WDMKS_H #define PA_WIN_WDMKS_H
/* /*
* $Id: pa_win_wdmks.h 1812 2012-02-14 09:32:57Z robiwan $ * $Id: pa_win_wdmks.h 1924 2014-04-09 14:27:21Z robiwan $
* PortAudio Portable Real-Time Audio Library * PortAudio Portable Real-Time Audio Library
* WDM/KS specific extensions * WDM/KS specific extensions
* *
@ -52,13 +52,29 @@
extern "C" extern "C"
{ {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* Setup flags */
typedef enum PaWinWDMKSFlags
{
/* Makes WDMKS use the supplied latency figures instead of relying on the frame size reported
by the WaveCyclic device. Use at own risk! */
paWinWDMKSOverrideFramesize = (1 << 0),
/* Makes WDMKS (output stream) use the given channelMask instead of the default */
paWinWDMKSUseGivenChannelMask = (1 << 1),
} PaWinWDMKSFlags;
typedef struct PaWinWDMKSInfo{ typedef struct PaWinWDMKSInfo{
unsigned long size; /**< sizeof(PaWinWDMKSInfo) */ unsigned long size; /**< sizeof(PaWinWDMKSInfo) */
PaHostApiTypeId hostApiType; /**< paWDMKS */ PaHostApiTypeId hostApiType; /**< paWDMKS */
unsigned long version; /**< 1 */ unsigned long version; /**< 1 */
unsigned long flags;
/* The number of packets to use for WaveCyclic devices, range is [2, 8]. Set to zero for default value of 2. */ /* The number of packets to use for WaveCyclic devices, range is [2, 8]. Set to zero for default value of 2. */
unsigned noOfPackets; unsigned noOfPackets;
/* If paWinWDMKSUseGivenChannelMask bit is set in flags, use this as channelMask instead of default */
unsigned channelMask;
} PaWinWDMKSInfo; } PaWinWDMKSInfo;
typedef enum PaWDMKSType typedef enum PaWDMKSType

View File

@ -1,7 +1,7 @@
#ifndef PORTAUDIO_H #ifndef PORTAUDIO_H
#define PORTAUDIO_H #define PORTAUDIO_H
/* /*
* $Id: portaudio.h 1859 2012-09-01 00:10:13Z philburk $ * $Id: portaudio.h 1953 2015-04-10 04:00:09Z philburk $
* 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/
@ -50,18 +50,52 @@ extern "C"
{ {
#endif /* __cplusplus */ #endif /* __cplusplus */
/** Retrieve the release number of the currently running PortAudio build.
/** Retrieve the release number of the currently running PortAudio build, * For example, for version "19.5.1" this will return 0x00130501.
eg 1900. */
*/
int Pa_GetVersion( void ); int Pa_GetVersion( void );
/** Retrieve a textual description of the current PortAudio build, /** Retrieve a textual description of the current PortAudio build,
eg "PortAudio V19-devel 13 October 2002". * eg "PortAudio V19.5.0-devel, revision 1952M".
*/ * The format of the text may change so do not try to parse the returned string.
* @deprecated use PaVersionInfo() instead
*/
const char* Pa_GetVersionText( void ); const char* Pa_GetVersionText( void );
/**
* Generate a packed integer version number in the same format used
* by Pa_GetVersion(). Use this to compare a specified version number with
* the currently running version. For example:
*
* if (Pa_GetVersion() < paMakeVersionNumber(19,5,1)) {}
*/
#define paMakeVersionNumber(major, minor, subminor) \
(((major)&0xFF)<<16 | ((minor)&0xFF)<<8 | ((subminor)&0xFF))
/**
* A structure containing the components of the version numbers.
*/
typedef struct PaVersionInfo {
int versionMajor;
int versionMinor;
int versionSubMinor;
/**
* This is currently the SVN revision but may change in the future.
* The versionControlRevision is updated by running a script before compiling code.
* If the update does not occur then this value may be less
* than the actual SVN revision number.
*/
const char *versionControlRevision;
/** Version as a string, for example "PortAudio V19.5.0-devel, revision 1952M" */
const char *versionText;
} PaVersionInfo;
/**
* The structure that this points to is statically allocated.
* Do not attempt to free it or modify it.
*/
const PaVersionInfo* Pa_GetVersionInfo();
/** Error codes returned by PortAudio functions. /** Error codes returned by PortAudio functions.
Note that with the exception of paNoError, all PaErrorCodes are negative. Note that with the exception of paNoError, all PaErrorCodes are negative.

0
3rdparty/portaudio/install-sh vendored Normal file → Executable file
View File

0
3rdparty/portaudio/missing vendored Normal file → Executable file
View File

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_front.c 1880 2012-12-04 18:39:48Z rbencina $ * $Id: pa_front.c 1953 2015-04-10 04:00:09Z philburk $
* 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.
* *
@ -65,6 +65,7 @@
#include <stdio.h> #include <stdio.h>
#include <memory.h> #include <memory.h>
#include <string.h> #include <string.h>
#include <stdlib.h> /* needed for strtol() */
#include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */ #include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
#include "portaudio.h" #include "portaudio.h"
@ -76,25 +77,63 @@
#include "pa_trace.h" /* still usefull?*/ #include "pa_trace.h" /* still usefull?*/
#include "pa_debugprint.h" #include "pa_debugprint.h"
#ifndef PA_SVN_REVISION
#include "pa_svnrevision.h"
#endif
#define PA_VERSION_ 1899 /**
#define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ " " __TIME__ ")" * This is incremented if we make incompatible API changes.
* This version scheme is based loosely on http://semver.org/
*/
#define paVersionMajor 19
/**
* This is incremented when we add functionality in a backwards-compatible manner.
* Or it is set to zero when paVersionMajor is incremented.
*/
#define paVersionMinor 5
/**
* This is incremented when we make backwards-compatible bug fixes.
* Or it is set to zero when paVersionMinor changes.
*/
#define paVersionSubMinor 0
/**
* This is a combination of paVersionMajor, paVersionMinor and paVersionSubMinor.
* It will always increase so that version numbers can be compared as integers to
* see which is later.
*/
#define paVersion paMakeVersionNumber(paVersionMajor, paVersionMinor, paVersionSubMinor)
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define PA_VERSION_STRING_ TOSTRING(paVersionMajor) "." TOSTRING(paVersionMinor) "." TOSTRING(paVersionSubMinor)
#define PA_VERSION_TEXT_ "PortAudio V" PA_VERSION_STRING_ "-devel, revision " TOSTRING(PA_SVN_REVISION)
int Pa_GetVersion( void ) int Pa_GetVersion( void )
{ {
return PA_VERSION_; return paVersion;
} }
const char* Pa_GetVersionText( void ) const char* Pa_GetVersionText( void )
{ {
return PA_VERSION_TEXT_; return PA_VERSION_TEXT_;
} }
static PaVersionInfo versionInfo_ = {
.versionMajor = paVersionMajor,
.versionMinor = paVersionMinor,
.versionSubMinor = paVersionSubMinor,
.versionControlRevision = TOSTRING(PA_SVN_REVISION),
.versionText = PA_VERSION_TEXT_
};
const PaVersionInfo* Pa_GetVersionInfo()
{
return &versionInfo_;
}
#define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024 #define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_process.c 1706 2011-07-21 18:44:58Z philburk $ * $Id: pa_process.c 1954 2015-04-19 18:48:38Z gineera $
* Portable Audio I/O Library * Portable Audio I/O Library
* streamCallback <-> host buffer processing adapter * streamCallback <-> host buffer processing adapter
* *
@ -238,7 +238,7 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
bp->inputConverter = bp->inputConverter =
PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, tempInputStreamFlags ); PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, tempInputStreamFlags );
bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat ); bp->inputZeroer = PaUtil_SelectZeroer( userInputSampleFormat );
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1; bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
@ -743,8 +743,10 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
destSampleStrideSamples = bp->inputChannelCount; destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample; destChannelStrideBytes = bp->bytesPerUserInputSample;
/* 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) * or if num channels differs between the host (set in stride) and the user (eg with some Alsa hw:) */
if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved
&& bp->hostInputChannels[0][0].data && bp->inputChannelCount == hostInputChannels[0].stride )
{ {
userInput = hostInputChannels[0].data; userInput = hostInputChannels[0].data;
destBytePtr = (unsigned char *)hostInputChannels[0].data; destBytePtr = (unsigned char *)hostInputChannels[0].data;
@ -832,8 +834,10 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
{ {
if( bp->userOutputIsInterleaved ) if( bp->userOutputIsInterleaved )
{ {
/* 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 ) * or if num channels differs between the host (set in stride) and the user (eg with some Alsa hw:) */
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved
&& bp->outputChannelCount == hostOutputChannels[0].stride )
{ {
userOutput = hostOutputChannels[0].data; userOutput = hostOutputChannels[0].data;
skipOutputConvert = 1; skipOutputConvert = 1;
@ -1683,9 +1687,9 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
hostInputChannels[i].stride, hostInputChannels[i].stride,
framesToCopy, &bp->ditherGenerator ); framesToCopy, &bp->ditherGenerator );
destBytePtr += destChannelStrideBytes; /* skip to next source channel */ destBytePtr += destChannelStrideBytes; /* skip to next dest channel */
/* advance dest ptr for next iteration */ /* advance source ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
} }
@ -1715,7 +1719,7 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
destBytePtr += bp->bytesPerUserInputSample * framesToCopy; destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
nonInterleavedDestPtrs[i] = destBytePtr; nonInterleavedDestPtrs[i] = destBytePtr;
/* advance dest ptr for next iteration */ /* advance source ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
} }

View File

@ -0,0 +1 @@
#define PA_SVN_REVISION unknown

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_trace.c 1812 2012-02-14 09:32:57Z robiwan $ * $Id: pa_trace.c 1916 2014-01-17 03:45:15Z philburk $
* Portable Audio I/O Library Trace Facility * Portable Audio I/O Library Trace Facility
* Store trace information in real-time for later printing. * Store trace information in real-time for later printing.
* *
@ -227,4 +227,12 @@ void PaUtil_DiscardHighSpeedLog( LogHandle hLog )
PaUtil_FreeMemory(pLog); PaUtil_FreeMemory(pLog);
} }
#else
/* This stub was added so that this file will generate a symbol.
* Otherwise linker/archiver programs will complain.
*/
int PaUtil_TraceStubToSatisfyLinker(void)
{
return 0;
}
#endif /* TRACE_REALTIME_EVENTS */ #endif /* TRACE_REALTIME_EVENTS */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_linux_alsa.c 1834 2012-05-18 16:04:30Z gineera $ * $Id: pa_linux_alsa.c 1911 2013-10-17 12:44:09Z gineera $
* 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
@ -602,7 +602,6 @@ typedef enum
typedef struct typedef struct
{ {
PaSampleFormat hostSampleFormat; PaSampleFormat hostSampleFormat;
unsigned long framesPerBuffer;
int numUserChannels, numHostChannels; int numUserChannels, numHostChannels;
int userInterleaved, hostInterleaved; int userInterleaved, hostInterleaved;
int canMmap; int canMmap;
@ -613,7 +612,7 @@ typedef struct
int useReventFix; /* Alsa older than 1.0.16, plug devices need a fix */ int useReventFix; /* Alsa older than 1.0.16, plug devices need a fix */
snd_pcm_t *pcm; snd_pcm_t *pcm;
snd_pcm_uframes_t bufferSize; snd_pcm_uframes_t framesPerPeriod, alsaBufferSize;
snd_pcm_format_t nativeFormat; snd_pcm_format_t nativeFormat;
unsigned int nfds; unsigned int nfds;
int ready; /* Marked ready from poll */ int ready; /* Marked ready from poll */
@ -837,12 +836,13 @@ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, in
{ {
PaError result = paNoError; PaError result = paNoError;
snd_pcm_hw_params_t *hwParams; snd_pcm_hw_params_t *hwParams;
snd_pcm_uframes_t lowLatency = 512, highLatency = 2048; snd_pcm_uframes_t alsaBufferFrames, alsaPeriodFrames;
unsigned int minChans, maxChans; unsigned int minChans, maxChans;
int* minChannels, * maxChannels; int* minChannels, * maxChannels;
double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate = double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate =
&devInfo->baseDeviceInfo.defaultSampleRate; &devInfo->baseDeviceInfo.defaultSampleRate;
double defaultSr = *defaultSampleRate; double defaultSr = *defaultSampleRate;
int dir;
assert( pcm ); assert( pcm );
@ -908,36 +908,34 @@ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, in
} }
/* TWEAKME: /* TWEAKME:
* * Giving values for default min and max latency is not straightforward.
* Giving values for default min and max latency is not * * for low latency, we want to give the lowest value that will work reliably.
* straightforward. Here are our objectives: * This varies based on the sound card, kernel, CPU, etc. Better to give
* * sub-optimal latency than to give a number too low and cause dropouts.
* * for low latency, we want to give the lowest value * * for high latency we want to give a large enough value that dropouts are basically impossible.
* that will work reliably. This varies based on the * This doesn't really require as much tweaking, since providing too large a number will
* sound card, kernel, CPU, etc. I think it is better * just cause us to select the nearest setting that will work at stream config time.
* to give sub-optimal latency than to give a number
* too low and cause dropouts. My conservative
* estimate at this point is to base it on 4096-sample
* latency at 44.1 kHz, which gives a latency of 23ms.
* * for high latency we want to give a large enough
* value that dropouts are basically impossible. This
* doesn't really require as much tweaking, since
* providing too large a number will just cause us to
* select the nearest setting that will work at stream
* config time.
*/ */
ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &lowLatency ), paUnanticipatedHostError ); /* Try low latency values, (sometimes the buffer & period that result are larger) */
alsaBufferFrames = 512;
alsaPeriodFrames = 128;
ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &alsaBufferFrames ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir ), paUnanticipatedHostError );
*defaultLowLatency = (double) (alsaBufferFrames - alsaPeriodFrames) / defaultSr;
/* Base the high latency case on values four times larger */
alsaBufferFrames = 2048;
alsaPeriodFrames = 512;
/* Have to reset hwParams, to set new buffer size; need to also set sample rate again */ /* Have to reset hwParams, to set new buffer size; need to also set sample rate again */
ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError );
ENSURE_( SetApproximateSampleRate( pcm, hwParams, defaultSr ), paUnanticipatedHostError ); ENSURE_( SetApproximateSampleRate( pcm, hwParams, defaultSr ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &highLatency ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &alsaBufferFrames ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir ), paUnanticipatedHostError );
*defaultHighLatency = (double) (alsaBufferFrames - alsaPeriodFrames) / defaultSr;
*minChannels = (int)minChans; *minChannels = (int)minChans;
*maxChannels = (int)maxChans; *maxChannels = (int)maxChans;
*defaultSampleRate = defaultSr; *defaultSampleRate = defaultSr;
*defaultLowLatency = (double) lowLatency / *defaultSampleRate;
*defaultHighLatency = (double) highLatency / *defaultSampleRate;
end: end:
alsa_snd_pcm_close( pcm ); alsa_snd_pcm_close( pcm );
@ -948,7 +946,7 @@ error:
} }
/* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate /* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate
* wether input/output is available) */ * whether input/output is available) */
static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo ) static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo )
{ {
deviceInfo->structVersion = -1; deviceInfo->structVersion = -1;
@ -1080,6 +1078,38 @@ static int IgnorePlugin( const char *pluginId )
return 0; return 0;
} }
/* Skip past parts at the beginning of a (pcm) info name that are already in the card name, to avoid duplication */
static char *SkipCardDetailsInName( char *infoSkipName, char *cardRefName )
{
char *lastSpacePosn = infoSkipName;
/* Skip matching chars; but only in chunks separated by ' ' (not part words etc), so track lastSpacePosn */
while( *cardRefName )
{
while( *infoSkipName && *cardRefName && *infoSkipName == *cardRefName)
{
infoSkipName++;
cardRefName++;
if( *infoSkipName == ' ' || *infoSkipName == '\0' )
lastSpacePosn = infoSkipName;
}
infoSkipName = lastSpacePosn;
/* Look for another chunk; post-increment means ends pointing to next char */
while( *cardRefName && ( *cardRefName++ != ' ' ));
}
if( *infoSkipName == '\0' )
return "-"; /* The 2 names were identical; instead of a nul-string, return a marker string */
/* Now want to move to the first char after any spaces */
while( *lastSpacePosn && *lastSpacePosn == ' ' )
lastSpacePosn++;
/* Skip a single separator char if present in the remaining pcm name; (pa will add its own) */
if(( *lastSpacePosn == '-' || *lastSpacePosn == ':' ) && *(lastSpacePosn + 1) == ' ' )
lastSpacePosn += 2;
return lastSpacePosn;
}
/** Open PCM device. /** Open PCM device.
* *
* Wrapper around alsa_snd_pcm_open which may repeatedly retry opening a device if it is busy, for * Wrapper around alsa_snd_pcm_open which may repeatedly retry opening a device if it is busy, for
@ -1090,8 +1120,10 @@ static int IgnorePlugin( const char *pluginId )
**/ **/
static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode, int waitOnBusy ) static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode, int waitOnBusy )
{ {
int tries = 0, maxTries = waitOnBusy ? busyRetries_ : 0; int ret, tries = 0, maxTries = waitOnBusy ? busyRetries_ : 0;
int ret = alsa_snd_pcm_open( pcmp, name, stream, mode );
ret = alsa_snd_pcm_open( pcmp, name, stream, mode );
for( tries = 0; tries < maxTries && -EBUSY == ret; ++tries ) for( tries = 0; tries < maxTries && -EBUSY == ret; ++tries )
{ {
Pa_Sleep( 10 ); Pa_Sleep( 10 );
@ -1114,7 +1146,7 @@ static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream,
return ret; return ret;
} }
static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceName, int blocking, static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceHwInfo, int blocking,
PaAlsaDeviceInfo* devInfo, int* devIdx ) PaAlsaDeviceInfo* devInfo, int* devIdx )
{ {
PaError result = 0; PaError result = 0;
@ -1122,43 +1154,43 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d
snd_pcm_t *pcm = NULL; snd_pcm_t *pcm = NULL;
PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep;
PA_DEBUG(( "%s: Filling device info for: %s\n", __FUNCTION__, deviceName->name )); PA_DEBUG(( "%s: Filling device info for: %s\n", __FUNCTION__, deviceHwInfo->name ));
/* Zero fields */ /* Zero fields */
InitializeDeviceInfo( baseDeviceInfo ); InitializeDeviceInfo( baseDeviceInfo );
/* to determine device capabilities, we must open the device and query the /* To determine device capabilities, we must open the device and query the
* hardware parameter configuration space */ * hardware parameter configuration space */
/* Query capture */ /* Query capture */
if( deviceName->hasCapture && if( deviceHwInfo->hasCapture &&
OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_CAPTURE, blocking, 0 ) >= 0 ) OpenPcm( &pcm, deviceHwInfo->alsaName, SND_PCM_STREAM_CAPTURE, blocking, 0 ) >= 0 )
{ {
if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_In, blocking, devInfo ) != paNoError ) if( GropeDevice( pcm, deviceHwInfo->isPlug, StreamDirection_In, blocking, devInfo ) != paNoError )
{ {
/* Error */ /* Error */
PA_DEBUG(( "%s: Failed groping %s for capture\n", __FUNCTION__, deviceName->alsaName )); PA_DEBUG(( "%s: Failed groping %s for capture\n", __FUNCTION__, deviceHwInfo->alsaName ));
goto end; goto end;
} }
} }
/* Query playback */ /* Query playback */
if( deviceName->hasPlayback && if( deviceHwInfo->hasPlayback &&
OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_PLAYBACK, blocking, 0 ) >= 0 ) OpenPcm( &pcm, deviceHwInfo->alsaName, SND_PCM_STREAM_PLAYBACK, blocking, 0 ) >= 0 )
{ {
if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_Out, blocking, devInfo ) != paNoError ) if( GropeDevice( pcm, deviceHwInfo->isPlug, StreamDirection_Out, blocking, devInfo ) != paNoError )
{ {
/* Error */ /* Error */
PA_DEBUG(( "%s: Failed groping %s for playback\n", __FUNCTION__, deviceName->alsaName )); PA_DEBUG(( "%s: Failed groping %s for playback\n", __FUNCTION__, deviceHwInfo->alsaName ));
goto end; goto end;
} }
} }
baseDeviceInfo->structVersion = 2; baseDeviceInfo->structVersion = 2;
baseDeviceInfo->hostApi = alsaApi->hostApiIndex; baseDeviceInfo->hostApi = alsaApi->hostApiIndex;
baseDeviceInfo->name = deviceName->name; baseDeviceInfo->name = deviceHwInfo->name;
devInfo->alsaName = deviceName->alsaName; devInfo->alsaName = deviceHwInfo->alsaName;
devInfo->isPlug = deviceName->isPlug; devInfo->isPlug = deviceHwInfo->isPlug;
/* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object. /* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object.
* Should now be safe to add device info, unless the device supports neither capture nor playback * Should now be safe to add device info, unless the device supports neither capture nor playback
@ -1167,24 +1199,24 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d
{ {
/* 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 || if( ( baseApi->info.defaultInputDevice == paNoDevice ||
!strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxInputChannels > 0 ) !strcmp( deviceHwInfo->alsaName, "default" ) ) && baseDeviceInfo->maxInputChannels > 0 )
{ {
baseApi->info.defaultInputDevice = *devIdx; baseApi->info.defaultInputDevice = *devIdx;
PA_DEBUG(( "Default input device: %s\n", deviceName->name )); PA_DEBUG(( "Default input device: %s\n", deviceHwInfo->name ));
} }
if( ( baseApi->info.defaultOutputDevice == paNoDevice || if( ( baseApi->info.defaultOutputDevice == paNoDevice ||
!strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxOutputChannels > 0 ) !strcmp( deviceHwInfo->alsaName, "default" ) ) && baseDeviceInfo->maxOutputChannels > 0 )
{ {
baseApi->info.defaultOutputDevice = *devIdx; baseApi->info.defaultOutputDevice = *devIdx;
PA_DEBUG(( "Default output device: %s\n", deviceName->name )); PA_DEBUG(( "Default output device: %s\n", deviceHwInfo->name ));
} }
PA_DEBUG(( "%s: Adding device %s: %d\n", __FUNCTION__, deviceName->name, *devIdx )); PA_DEBUG(( "%s: Adding device %s: %d\n", __FUNCTION__, deviceHwInfo->name, *devIdx ));
baseApi->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo; baseApi->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo;
(*devIdx) += 1; (*devIdx) += 1;
} }
else else
{ {
PA_DEBUG(( "%s: Skipped device: %s, all channels == 0\n", __FUNCTION__, deviceName->name )); PA_DEBUG(( "%s: Skipped device: %s, all channels == 0\n", __FUNCTION__, deviceHwInfo->name ));
} }
end: end:
@ -1205,6 +1237,8 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
snd_pcm_info_t *pcmInfo; snd_pcm_info_t *pcmInfo;
int res; int res;
int blocking = SND_PCM_NONBLOCK; int blocking = SND_PCM_NONBLOCK;
int usePlughw = 0;
char *hwPrefix = "";
char alsaCardName[50]; char alsaCardName[50];
#ifdef PA_ENABLE_DEBUG_OUTPUT #ifdef PA_ENABLE_DEBUG_OUTPUT
PaTime startTime = PaUtil_GetTime(); PaTime startTime = PaUtil_GetTime();
@ -1213,6 +1247,14 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
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;
/* If PA_ALSA_PLUGHW is 1 (non-zero), use the plughw: pcm throughout instead of hw: */
if( getenv( "PA_ALSA_PLUGHW" ) && atoi( getenv( "PA_ALSA_PLUGHW" ) ) )
{
usePlughw = 1;
hwPrefix = "plug";
PA_DEBUG(( "%s: Using Plughw\n", __FUNCTION__ ));
}
/* These two will be set to the first working input and output device, respectively */ /* These two will be set to the first working input and output device, respectively */
baseApi->info.defaultInputDevice = paNoDevice; baseApi->info.defaultInputDevice = paNoDevice;
baseApi->info.defaultOutputDevice = paNoDevice; baseApi->info.defaultOutputDevice = paNoDevice;
@ -1250,10 +1292,11 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
while( alsa_snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 ) while( alsa_snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 )
{ {
char *alsaDeviceName, *deviceName; char *alsaDeviceName, *deviceName, *infoName;
size_t len; size_t len;
int hasPlayback = 0, hasCapture = 0; int hasPlayback = 0, hasCapture = 0;
snprintf( buf, sizeof (buf), "hw:%d,%d", cardIdx, devIdx );
snprintf( buf, sizeof (buf), "%s%s,%d", hwPrefix, alsaCardName, devIdx );
/* Obtain info about this particular device */ /* Obtain info about this particular device */
alsa_snd_pcm_info_set_device( pcmInfo, devIdx ); alsa_snd_pcm_info_set_device( pcmInfo, devIdx );
@ -1276,12 +1319,13 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
continue; continue;
} }
infoName = SkipCardDetailsInName( (char *)alsa_snd_pcm_info_get_name( pcmInfo ), cardName );
/* The length of the string written by snprintf plus terminating 0 */ /* The length of the string written by snprintf plus terminating 0 */
len = snprintf( NULL, 0, "%s: %s (%s)", cardName, alsa_snd_pcm_info_get_name( pcmInfo ), buf ) + 1; len = snprintf( NULL, 0, "%s: %s (%s)", cardName, infoName, buf ) + 1;
PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ),
paInsufficientMemory ); paInsufficientMemory );
snprintf( deviceName, len, "%s: %s (%s)", cardName, snprintf( deviceName, len, "%s: %s (%s)", cardName, infoName, buf );
alsa_snd_pcm_info_get_name( pcmInfo ), buf );
++numDeviceNames; ++numDeviceNames;
if( !hwDevInfos || numDeviceNames > maxDeviceNames ) if( !hwDevInfos || numDeviceNames > maxDeviceNames )
@ -1295,7 +1339,7 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName; hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName;
hwDevInfos[ numDeviceNames - 1 ].name = deviceName; hwDevInfos[ numDeviceNames - 1 ].name = deviceName;
hwDevInfos[ numDeviceNames - 1 ].isPlug = 0; hwDevInfos[ numDeviceNames - 1 ].isPlug = usePlughw;
hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback; hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback;
hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture; hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture;
} }
@ -1662,32 +1706,22 @@ static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat )
/** Open an ALSA pcm handle. /** Open an ALSA pcm handle.
* *
* The device to be open can be specified in a custom PaAlsaStreamInfo struct, or it will be a device number. In case of a * The device to be open can be specified by name in a custom PaAlsaStreamInfo struct, or it will be by
* device number, it maybe specified through an env variable (PA_ALSA_PLUGHW) that we should open the corresponding plugin * the Portaudio device number supplied in the stream parameters.
* device.
*/ */
static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection
streamDir, snd_pcm_t **pcm ) streamDir, snd_pcm_t **pcm )
{ {
PaError result = paNoError; PaError result = paNoError;
int ret; int ret;
char dnameArray[50]; const char* deviceName = "";
const char* deviceName = dnameArray;
const PaAlsaDeviceInfo *deviceInfo = NULL; const PaAlsaDeviceInfo *deviceInfo = NULL;
PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo; PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo;
if( !streamInfo ) if( !streamInfo )
{ {
int usePlug = 0;
deviceInfo = GetDeviceInfo( hostApi, params->device ); deviceInfo = GetDeviceInfo( hostApi, params->device );
deviceName = deviceInfo->alsaName;
/* If device name starts with hw: and PA_ALSA_PLUGHW is 1, we open the plughw device instead */
if( !strncmp( "hw:", deviceInfo->alsaName, 3 ) && getenv( "PA_ALSA_PLUGHW" ) )
usePlug = atoi( getenv( "PA_ALSA_PLUGHW" ) );
if( usePlug )
snprintf( dnameArray, 50, "plug%s", deviceInfo->alsaName );
else
deviceName = deviceInfo->alsaName;
} }
else else
deviceName = streamInfo->deviceString; deviceName = streamInfo->deviceString;
@ -1850,6 +1884,7 @@ static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, Pa
self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels
: devInfo->minOutputChannels ); : devInfo->minOutputChannels );
self->deviceIsPlug = devInfo->isPlug; self->deviceIsPlug = devInfo->isPlug;
PA_DEBUG(( "%s: Host Chans %c %i\n", __FUNCTION__, streamDir == StreamDirection_In ? 'C' : 'P', self->numHostChannels ));
} }
else else
{ {
@ -1900,8 +1935,8 @@ error:
static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self ) static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self )
{ {
alsa_snd_pcm_close( self->pcm ); alsa_snd_pcm_close( self->pcm );
if( self->userBuffers ) PaUtil_FreeMemory( self->userBuffers ); /* (Ptr can be NULL; PaUtil_FreeMemory includes a NULL check) */
PaUtil_FreeMemory( self->userBuffers ); PaUtil_FreeMemory( self->nonMmapBuffer );
} }
/* /*
@ -1932,7 +1967,7 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se
double sr = *sampleRate; double sr = *sampleRate;
unsigned int minPeriods = 2; unsigned int minPeriods = 2;
/* self->framesPerBuffer = framesPerHostBuffer; */ /* self->framesPerPeriod = framesPerHostBuffer; */
/* ... fill up the configuration space with all possibile /* ... fill up the configuration space with all possibile
* combinations of parameters this device will accept */ * combinations of parameters this device will accept */
@ -2027,7 +2062,7 @@ error:
/** Finish the configuration of the component's ALSA device. /** Finish the configuration of the component's ALSA device.
* *
* As part of this method, the component's bufferSize attribute will be set. * As part of this method, the component's alsaBufferSize attribute will be set.
* @param latency: The latency for this component. * @param latency: The latency for this component.
*/ */
static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams, static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams,
@ -2040,7 +2075,7 @@ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *sel
alsa_snd_pcm_sw_params_alloca( &swParams ); alsa_snd_pcm_sw_params_alloca( &swParams );
bufSz = params->suggestedLatency * sampleRate; bufSz = params->suggestedLatency * sampleRate + self->framesPerPeriod;
ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError );
/* Set the parameters! */ /* Set the parameters! */
@ -2058,21 +2093,21 @@ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *sel
} }
if( alsa_snd_pcm_hw_params_get_buffer_size != NULL ) if( alsa_snd_pcm_hw_params_get_buffer_size != NULL )
{ {
ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size( hwParams, &self->alsaBufferSize ), paUnanticipatedHostError );
} }
else else
{ {
self->bufferSize = bufSz; self->alsaBufferSize = bufSz;
} }
/* Latency in seconds */ /* Latency in seconds */
*latency = self->bufferSize / sampleRate; *latency = (self->alsaBufferSize - self->framesPerPeriod) / sampleRate;
/* Now software parameters... */ /* Now software parameters... */
ENSURE_( alsa_snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerPeriod ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->bufferSize ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->alsaBufferSize ), paUnanticipatedHostError );
/* Silence buffer in the case of underrun */ /* Silence buffer in the case of underrun */
if( !primeBuffers ) /* XXX: Make sense? */ if( !primeBuffers ) /* XXX: Make sense? */
@ -2083,7 +2118,7 @@ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *sel
ENSURE_( alsa_snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError );
} }
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->framesPerPeriod ), 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_ENABLE ), paUnanticipatedHostError );
@ -2218,7 +2253,7 @@ static unsigned long PaAlsa_GetFramesPerHostBuffer(unsigned long userFramesPerBu
/** Determine size per host buffer. /** Determine size per host buffer.
* *
* During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size * During this method call, the component's framesPerPeriod attribute gets computed, and the corresponding period size
* gets configured for the device. * gets configured for the device.
* @param accurate: If the configured period size is non-integer, this will be set to 0. * @param accurate: If the configured period size is non-integer, this will be set to 0.
*/ */
@ -2434,7 +2469,7 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
} }
/* Set result */ /* Set result */
self->framesPerBuffer = framesPerHostBuffer; self->framesPerPeriod = framesPerHostBuffer;
error: error:
return result; return result;
@ -2461,7 +2496,7 @@ error:
* which should be fine if the period size is the same for capture and playback. In general, if there is a specified user * which should be fine if the period size is the same for capture and playback. In general, if there is a specified user
* buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size. * buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size.
* *
* The framesPerBuffer attributes of the individual capture and playback components of the stream are set to corresponding * The framesPerPeriod attributes of the individual capture and playback components of the stream are set to corresponding
* values determined here. Since these should be reported as * values determined here. Since these should be reported as
* *
* This is one of those blocks of code that will just take a lot of * This is one of those blocks of code that will just take a lot of
@ -2565,7 +2600,7 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double
paUnanticipatedHostError ); paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ), ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ),
paUnanticipatedHostError ); paUnanticipatedHostError );
self->capture.framesPerBuffer = self->playback.framesPerBuffer = periodSize; self->capture.framesPerPeriod = self->playback.framesPerPeriod = periodSize;
framesPerHostBuffer = periodSize; framesPerHostBuffer = periodSize;
} }
else else
@ -2574,15 +2609,15 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double
optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize ); optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize );
optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize ); optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize );
self->capture.framesPerBuffer = optimalPeriodSize; self->capture.framesPerPeriod = optimalPeriodSize;
dir = 0; dir = 0;
ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerBuffer, &dir ), ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerPeriod, &dir ),
paUnanticipatedHostError ); paUnanticipatedHostError );
self->playback.framesPerBuffer = optimalPeriodSize; self->playback.framesPerPeriod = optimalPeriodSize;
dir = 0; dir = 0;
ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerBuffer, &dir ), ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerPeriod, &dir ),
paUnanticipatedHostError ); paUnanticipatedHostError );
framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer ); framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod );
*hostBufferSizeMode = paUtilBoundedHostBufferSize; *hostBufferSizeMode = paUtilBoundedHostBufferSize;
} }
} }
@ -2612,17 +2647,17 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer, PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer,
sampleRate, firstHwParams, &accurate ) ); sampleRate, firstHwParams, &accurate ) );
second->framesPerBuffer = first->framesPerBuffer; second->framesPerPeriod = first->framesPerPeriod;
dir = 0; dir = 0;
ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerBuffer, &dir ), ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerPeriod, &dir ),
paUnanticipatedHostError ); paUnanticipatedHostError );
if( self->capture.framesPerBuffer == self->playback.framesPerBuffer ) if( self->capture.framesPerPeriod == self->playback.framesPerPeriod )
{ {
framesPerHostBuffer = self->capture.framesPerBuffer; framesPerHostBuffer = self->capture.framesPerPeriod;
} }
else else
{ {
framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer ); framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod );
*hostBufferSizeMode = paUtilBoundedHostBufferSize; *hostBufferSizeMode = paUtilBoundedHostBufferSize;
} }
} }
@ -2633,14 +2668,14 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double
{ {
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer, PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer,
sampleRate, hwParamsCapture, &accurate) ); sampleRate, hwParamsCapture, &accurate) );
framesPerHostBuffer = self->capture.framesPerBuffer; framesPerHostBuffer = self->capture.framesPerPeriod;
} }
else else
{ {
assert( self->playback.pcm ); assert( self->playback.pcm );
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer, PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer,
sampleRate, hwParamsPlayback, &accurate ) ); sampleRate, hwParamsPlayback, &accurate ) );
framesPerHostBuffer = self->playback.framesPerBuffer; framesPerHostBuffer = self->playback.framesPerPeriod;
} }
} }
@ -2686,17 +2721,17 @@ static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParamet
if( self->capture.pcm ) if( self->capture.pcm )
{ {
assert( self->capture.framesPerBuffer != 0 ); assert( self->capture.framesPerPeriod != 0 );
PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr, PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr,
inputLatency ) ); inputLatency ) );
PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerBuffer, *inputLatency )); PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerPeriod, *inputLatency ));
} }
if( self->playback.pcm ) if( self->playback.pcm )
{ {
assert( self->playback.framesPerBuffer != 0 ); assert( self->playback.framesPerPeriod != 0 );
PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr, PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr,
outputLatency ) ); outputLatency ) );
PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerBuffer, *outputLatency )); PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerPeriod, *outputLatency ));
} }
/* Should be exact now */ /* Should be exact now */
@ -2716,8 +2751,8 @@ static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParamet
} }
{ {
unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerBuffer : ULONG_MAX, unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerPeriod : ULONG_MAX,
self->playback.pcm ? self->playback.framesPerBuffer : ULONG_MAX ); self->playback.pcm ? self->playback.framesPerPeriod : ULONG_MAX );
self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer ); /* Period in msecs, rounded up */ self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer ); /* Period in msecs, rounded up */
/* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */ /* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */
@ -2727,7 +2762,7 @@ static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParamet
if( self->callbackMode ) if( self->callbackMode )
{ {
/* If the user expects a certain number of frames per callback we will either have to rely on block adaption /* If the user expects a certain number of frames per callback we will either have to rely on block adaption
* (framesPerHostBuffer is not an integer multiple of framesPerBuffer) or we can simply align the number * (framesPerHostBuffer is not an integer multiple of framesPerPeriod) or we can simply align the number
* of host buffer frames with what the user specified */ * of host buffer frames with what the user specified */
if( self->framesPerUserBuffer != paFramesPerBufferUnspecified ) if( self->framesPerUserBuffer != paFramesPerBufferUnspecified )
{ {
@ -2736,8 +2771,8 @@ static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParamet
/* Unless the ratio between number of host and user buffer frames is an integer we will have to rely /* Unless the ratio between number of host and user buffer frames is an integer we will have to rely
* on block adaption */ * on block adaption */
/* /*
if( framesPerHostBuffer % framesPerBuffer != 0 || (self->capture.pcm && self->playback.pcm && if( framesPerHostBuffer % framesPerPeriod != 0 || (self->capture.pcm && self->playback.pcm &&
self->capture.framesPerBuffer != self->playback.framesPerBuffer) ) self->capture.framesPerPeriod != self->playback.framesPerPeriod) )
self->useBlockAdaption = 1; self->useBlockAdaption = 1;
else else
self->alignFrames = 1; self->alignFrames = 1;
@ -2791,7 +2826,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* XXX: Why do we support this anyway? */ /* XXX: Why do we support this anyway? */
if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL ) if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL )
{ {
PA_DEBUG(( "%s: Getting framesPerBuffer from environment\n", __FUNCTION__ )); PA_DEBUG(( "%s: Getting framesPerBuffer (Alsa period-size) from environment\n", __FUNCTION__ ));
framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") ); framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") );
} }
@ -2818,7 +2853,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)( stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)(
PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) / sampleRate); PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) / sampleRate);
PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency = i(%f)/o(%f), \n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency)); PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency i=%f, o=%f\n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency));
*s = (PaStream*)stream; *s = (PaStream*)stream;
@ -2859,7 +2894,7 @@ static void SilenceBuffer( PaAlsaStream *stream )
/** Start/prepare pcm(s) for streaming. /** Start/prepare pcm(s) for streaming.
* *
* Depending on wether the stream is in callback or blocking mode, we will respectively start or simply * Depending on whether the stream is in callback or blocking mode, we will respectively start or simply
* prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and * prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and
* silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will * silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will
* be started automatically as the user writes to output. * be started automatically as the user writes to output.
@ -2945,7 +2980,7 @@ static PaError StartStream( PaStream *s )
{ {
PaError result = paNoError; PaError result = paNoError;
PaAlsaStream* stream = (PaAlsaStream*)s; PaAlsaStream* stream = (PaAlsaStream*)s;
int streamStarted = 0; /* So we can know wether we need to take the stream down */ int streamStarted = 0; /* So we can know whether we need to take the stream down */
/* Ready the processor */ /* Ready the processor */
PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
@ -3036,7 +3071,7 @@ error:
/** Stop or abort stream. /** Stop or abort stream.
* *
* If a stream is in callback mode we will have to inspect wether the background thread has * If a stream is in callback mode we will have to inspect whether the background thread has
* finished, or we will have to take it out. In either case we join the thread before * finished, or we will have to take it out. In either case we join the thread before
* returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish * returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish
* buffers (drain) * buffers (drain)
@ -3318,16 +3353,16 @@ static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamD
if( StreamDirection_Out == streamDir ) if( StreamDirection_Out == streamDir )
{ {
/* Number of eligible frames before capture overrun */ /* Number of eligible frames before capture overrun */
delay = otherComponent->bufferSize - delay; delay = otherComponent->alsaBufferSize - delay;
} }
margin = delay - otherComponent->framesPerBuffer / 2; margin = delay - otherComponent->framesPerPeriod / 2;
if( margin < 0 ) if( margin < 0 )
{ {
PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" )); PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" ));
*continuePoll = 0; *continuePoll = 0;
} }
else if( margin < otherComponent->framesPerBuffer ) else if( margin < otherComponent->framesPerPeriod )
{ {
*pollTimeout = CalculatePollTimeout( stream, margin ); *pollTimeout = CalculatePollTimeout( stream, margin );
PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n", PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n",
@ -3438,7 +3473,7 @@ static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self,
else else
{ {
void *bufs[self->numHostChannels]; void *bufs[self->numHostChannels];
int bufsize = alsa_snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 ); int bufsize = alsa_snd_pcm_format_size( self->nativeFormat, self->framesPerPeriod + 1 );
unsigned char *buffer = self->nonMmapBuffer; unsigned char *buffer = self->nonMmapBuffer;
int i; int i;
for( i = 0; i < self->numHostChannels; ++i ) for( i = 0; i < self->numHostChannels; ++i )
@ -3452,13 +3487,6 @@ static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self,
if( self->canMmap ) if( self->canMmap )
res = alsa_snd_pcm_mmap_commit( self->pcm, self->offset, numFrames ); res = alsa_snd_pcm_mmap_commit( self->pcm, self->offset, numFrames );
else
{
/* using realloc for optimisation
free( self->nonMmapBuffer );
self->nonMmapBuffer = NULL;
*/
}
if( res == -EPIPE || res == -ESTRPIPE ) if( res == -EPIPE || res == -ESTRPIPE )
{ {
@ -3771,7 +3799,8 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
} }
if( pollPlayback ) if( pollPlayback )
{ {
playbackPfds = self->pfds + (self->capture.pcm ? self->capture.nfds : 0); /* self->pfds is in effect an array of fds; if necessary, index past the capture fds */
playbackPfds = self->pfds + (pollCapture ? self->capture.nfds : 0);
PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) ); PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) );
totalFds += self->playback.nfds; totalFds += self->playback.nfds;
} }
@ -3870,7 +3899,7 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
{ {
/* Drop input, a period's worth */ /* Drop input, a period's worth */
assert( self->capture.ready ); assert( self->capture.ready );
PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerBuffer, PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerPeriod,
*framesAvail ), &xrun ); *framesAvail ), &xrun );
*framesAvail = 0; *framesAvail = 0;
self->capture.ready = 0; self->capture.ready = 0;
@ -4168,8 +4197,8 @@ static void *CallbackThreadFunc( void *userData )
/* We can't be certain that the whole ring buffer is available for priming, but there should be /* We can't be certain that the whole ring buffer is available for priming, but there should be
* at least one period */ * at least one period */
avail = alsa_snd_pcm_avail_update( stream->playback.pcm ); avail = alsa_snd_pcm_avail_update( stream->playback.pcm );
startThreshold = avail - (avail % stream->playback.framesPerBuffer); startThreshold = avail - (avail % stream->playback.framesPerPeriod);
assert( startThreshold >= stream->playback.framesPerBuffer ); assert( startThreshold >= stream->playback.framesPerPeriod );
} }
else else
{ {
@ -4439,10 +4468,10 @@ static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frame
/* Frames residing in buffer */ /* Frames residing in buffer */
PA_ENSURE( err = GetStreamWriteAvailable( stream ) ); PA_ENSURE( err = GetStreamWriteAvailable( stream ) );
framesAvail = err; framesAvail = err;
hwAvail = stream->playback.bufferSize - framesAvail; hwAvail = stream->playback.alsaBufferSize - framesAvail;
if( alsa_snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED && if( alsa_snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED &&
hwAvail >= stream->playback.framesPerBuffer ) hwAvail >= stream->playback.framesPerPeriod )
{ {
ENSURE_( alsa_snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_asio.cpp 1879 2012-12-04 14:45:31Z rbencina $ * $Id: pa_asio.cpp 1890 2013-05-02 01:06:01Z rbencina $
* Portable Audio I/O Library for ASIO Drivers * Portable Audio I/O Library for ASIO Drivers
* *
* Author: Stephane Letz * Author: Stephane Letz
@ -1019,6 +1019,149 @@ static ASIOSampleRate defaultSampleRateSearchOrder_[]
192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
static PaError InitPaDeviceInfoFromAsioDriver( PaAsioHostApiRepresentation *asioHostApi,
const char *driverName, int driverIndex,
PaDeviceInfo *deviceInfo, PaAsioDeviceInfo *asioDeviceInfo )
{
PaError result = paNoError;
/* Due to the headless design of the ASIO API, drivers are free to write over data given to them (like M-Audio
drivers f.i.). This is an attempt to overcome that. */
union _tag_local {
PaAsioDriverInfo info;
char _padding[4096];
} paAsioDriver;
asioDeviceInfo->asioChannelInfos = 0; /* we check this below to handle error cleanup */
result = LoadAsioDriver( asioHostApi, driverName, &paAsioDriver.info, asioHostApi->systemSpecific );
if( result == paNoError )
{
PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", driverIndex,deviceInfo->name));
PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", driverIndex, paAsioDriver.info.inputChannelCount));
PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", driverIndex, paAsioDriver.info.outputChannelCount));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", driverIndex, paAsioDriver.info.bufferMinSize));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", driverIndex, paAsioDriver.info.bufferMaxSize));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", driverIndex, paAsioDriver.info.bufferPreferredSize));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", driverIndex, paAsioDriver.info.bufferGranularity));
deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount;
deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount;
deviceInfo->defaultSampleRate = 0.;
bool foundDefaultSampleRate = false;
for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
{
ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
{
deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
foundDefaultSampleRate = true;
break;
}
}
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", driverIndex, deviceInfo->defaultSampleRate));
if( foundDefaultSampleRate ){
/* calculate default latency values from bufferPreferredSize
for default low latency, and bufferMaxSize
for default high latency.
use the default sample rate to convert from samples to
seconds. Without knowing what sample rate the user will
use this is the best we can do.
*/
double defaultLowLatency =
paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
double defaultHighLatency =
paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate;
if( defaultHighLatency < defaultLowLatency )
defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
}else{
deviceInfo->defaultLowInputLatency = 0.;
deviceInfo->defaultLowOutputLatency = 0.;
deviceInfo->defaultHighInputLatency = 0.;
deviceInfo->defaultHighOutputLatency = 0.;
}
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", driverIndex, deviceInfo->defaultLowInputLatency));
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", driverIndex, deviceInfo->defaultLowOutputLatency));
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", driverIndex, deviceInfo->defaultHighInputLatency));
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", driverIndex, deviceInfo->defaultHighOutputLatency));
asioDeviceInfo->minBufferSize = paAsioDriver.info.bufferMinSize;
asioDeviceInfo->maxBufferSize = paAsioDriver.info.bufferMaxSize;
asioDeviceInfo->preferredBufferSize = paAsioDriver.info.bufferPreferredSize;
asioDeviceInfo->bufferGranularity = paAsioDriver.info.bufferGranularity;
asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
asioHostApi->allocations,
sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
+ deviceInfo->maxOutputChannels) );
if( !asioDeviceInfo->asioChannelInfos )
{
result = paInsufficientMemory;
goto error_unload;
}
int a;
for( a=0; a < deviceInfo->maxInputChannels; ++a ){
asioDeviceInfo->asioChannelInfos[a].channel = a;
asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
if( asioError != ASE_OK )
{
result = paUnanticipatedHostError;
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
goto error_unload;
}
}
for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
int b = deviceInfo->maxInputChannels + a;
asioDeviceInfo->asioChannelInfos[b].channel = a;
asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
if( asioError != ASE_OK )
{
result = paUnanticipatedHostError;
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
goto error_unload;
}
}
/* unload the driver */
UnloadAsioDriver();
}
return result;
error_unload:
UnloadAsioDriver();
if( asioDeviceInfo->asioChannelInfos ){
PaUtil_GroupFreeMemory( asioHostApi->allocations, asioDeviceInfo->asioChannelInfos );
asioDeviceInfo->asioChannelInfos = 0;
}
return result;
}
/* we look up IsDebuggerPresent at runtime incase it isn't present (on Win95 for example) */ /* we look up IsDebuggerPresent at runtime incase it isn't present (on Win95 for example) */
typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID); typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID);
IsDebuggerPresentPtr IsDebuggerPresent_ = 0; IsDebuggerPresentPtr IsDebuggerPresent_ = 0;
@ -1142,14 +1285,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
for( i=0; i < driverCount; ++i ) for( i=0; i < driverCount; ++i )
{ {
/* Due to the headless design of the ASIO API, drivers are free to write over data given to them (like M-Audio
drivers f.i.). This is an attempt to overcome that. */
union _tag_local {
PaAsioDriverInfo info;
char _padding[4096];
} paAsioDriver;
PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i])); PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i]));
// Since portaudio opens ALL ASIO drivers, and no one else does that, // Since portaudio opens ALL ASIO drivers, and no one else does that,
@ -1182,8 +1317,7 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
} }
/* Attempt to load the asio driver... */ /* Attempt to init device info from the asio driver... */
if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriver.info, asioHostApi->systemSpecific ) == paNoError )
{ {
PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo; PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
@ -1192,119 +1326,17 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
deviceInfo->hostApi = hostApiIndex; deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = names[i]; deviceInfo->name = names[i];
PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", i,deviceInfo->name));
PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", i, paAsioDriver.info.inputChannelCount));
PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", i, paAsioDriver.info.outputChannelCount));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", i, paAsioDriver.info.bufferMinSize));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", i, paAsioDriver.info.bufferMaxSize));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriver.info.bufferPreferredSize));
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", i, paAsioDriver.info.bufferGranularity));
deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount; if( InitPaDeviceInfoFromAsioDriver( asioHostApi, names[i], i, deviceInfo, asioDeviceInfo ) == paNoError )
deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount;
deviceInfo->defaultSampleRate = 0.;
bool foundDefaultSampleRate = false;
for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
{ {
ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] ); (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
if( asioError != ASE_NoClock && asioError != ASE_NotPresent ) ++(*hostApi)->info.deviceCount;
{
deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
foundDefaultSampleRate = true;
break;
}
} }
else
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, deviceInfo->defaultSampleRate)); {
PA_DEBUG(("Skipping ASIO device:%s\n",names[i]));
if( foundDefaultSampleRate ){ continue;
/* calculate default latency values from bufferPreferredSize
for default low latency, and bufferMaxSize
for default high latency.
use the default sample rate to convert from samples to
seconds. Without knowing what sample rate the user will
use this is the best we can do.
*/
double defaultLowLatency =
paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate;
deviceInfo->defaultLowInputLatency = defaultLowLatency;
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
double defaultHighLatency =
paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate;
if( defaultHighLatency < defaultLowLatency )
defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */
deviceInfo->defaultHighInputLatency = defaultHighLatency;
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
}else{
deviceInfo->defaultLowInputLatency = 0.;
deviceInfo->defaultLowOutputLatency = 0.;
deviceInfo->defaultHighInputLatency = 0.;
deviceInfo->defaultHighOutputLatency = 0.;
} }
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", i, deviceInfo->defaultLowInputLatency));
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", i, deviceInfo->defaultLowOutputLatency));
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", i, deviceInfo->defaultHighInputLatency));
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", i, deviceInfo->defaultHighOutputLatency));
asioDeviceInfo->minBufferSize = paAsioDriver.info.bufferMinSize;
asioDeviceInfo->maxBufferSize = paAsioDriver.info.bufferMaxSize;
asioDeviceInfo->preferredBufferSize = paAsioDriver.info.bufferPreferredSize;
asioDeviceInfo->bufferGranularity = paAsioDriver.info.bufferGranularity;
asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
asioHostApi->allocations,
sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
+ deviceInfo->maxOutputChannels) );
if( !asioDeviceInfo->asioChannelInfos )
{
result = paInsufficientMemory;
goto error_unload;
}
int a;
for( a=0; a < deviceInfo->maxInputChannels; ++a ){
asioDeviceInfo->asioChannelInfos[a].channel = a;
asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
if( asioError != ASE_OK )
{
result = paUnanticipatedHostError;
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
goto error_unload;
}
}
for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
int b = deviceInfo->maxInputChannels + a;
asioDeviceInfo->asioChannelInfos[b].channel = a;
asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
if( asioError != ASE_OK )
{
result = paUnanticipatedHostError;
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
goto error_unload;
}
}
/* unload the driver */
UnloadAsioDriver();
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
++(*hostApi)->info.deviceCount;
} }
} }
} }
@ -1338,9 +1370,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
return result; return result;
error_unload:
UnloadAsioDriver();
error: error:
if( asioHostApi ) if( asioHostApi )
{ {

View File

@ -125,83 +125,78 @@ static bool ensureChannelNameSize( int size )
*/ */
const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ) const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input )
{ {
struct PaUtilHostApiRepresentation *hostApi; struct PaUtilHostApiRepresentation *hostApi;
PaError err; PaError err;
OSStatus error; OSStatus error;
err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio ); err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
assert(err == paNoError); assert(err == paNoError);
if( err != paNoError ) if( err != paNoError )
return NULL; return NULL;
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi; PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device]; AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device];
CFStringRef nameRef;
UInt32 size = 0; /* First try with CFString */
UInt32 size = sizeof(nameRef);
error = AudioDeviceGetProperty( hostApiDevice,
channelIndex + 1,
input,
kAudioDevicePropertyChannelNameCFString,
&size,
&nameRef );
if( error )
{
/* try the C String */
size = 0;
error = AudioDeviceGetPropertyInfo( hostApiDevice,
channelIndex + 1,
input,
kAudioDevicePropertyChannelName,
&size,
NULL);
if( !error )
{
if( !ensureChannelNameSize( size ) )
return NULL;
error = AudioDeviceGetPropertyInfo( hostApiDevice, error = AudioDeviceGetProperty( hostApiDevice,
channelIndex + 1, channelIndex + 1,
input, input,
kAudioDevicePropertyChannelName, kAudioDevicePropertyChannelName,
&size, &size,
NULL ); channelName );
if( error ) {
//try the CFString
CFStringRef name;
bool isDeviceName = false;
size = sizeof( name );
error = AudioDeviceGetProperty( hostApiDevice,
channelIndex + 1,
input,
kAudioDevicePropertyChannelNameCFString,
&size,
&name );
if( error ) { //as a last-ditch effort, get the device name. Later we'll append the channel number.
size = sizeof( name );
error = AudioDeviceGetProperty( hostApiDevice,
channelIndex + 1,
input,
kAudioDevicePropertyDeviceNameCFString,
&size,
&name );
if( error )
return NULL;
isDeviceName = true;
}
if( isDeviceName ) {
name = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%@: %d"), name, channelIndex + 1 );
}
CFIndex length = CFStringGetLength(name);
while( ensureChannelNameSize( length * sizeof(UniChar) + 1 ) ) {
if( CFStringGetCString( name, channelName, channelNameSize, kCFStringEncodingUTF8 ) ) {
if( isDeviceName )
CFRelease( name );
return channelName;
}
if( length == 0 )
++length;
length *= 2;
}
if( isDeviceName )
CFRelease( name );
return NULL;
}
//continue with C string: if( !error )
if( !ensureChannelNameSize( size ) ) return channelName;
return NULL; }
error = AudioDeviceGetProperty( hostApiDevice, /* as a last-ditch effort, we use the device name and append the channel number. */
channelIndex + 1, nameRef = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%s: %d"), hostApi->deviceInfos[device]->name, channelIndex + 1 );
input,
kAudioDevicePropertyChannelName,
&size,
channelName );
if( error ) {
ERR( error ); size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8);;
return NULL; if( !ensureChannelNameSize( size ) )
} {
return channelName; CFRelease( nameRef );
return NULL;
}
CFStringGetCString( nameRef, channelName, size+1, kCFStringEncodingUTF8 );
CFRelease( nameRef );
}
else
{
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8);;
if( !ensureChannelNameSize( size ) )
{
CFRelease( nameRef );
return NULL;
}
CFStringGetCString( nameRef, channelName, size+1, kCFStringEncodingUTF8 );
CFRelease( nameRef );
}
return channelName;
} }
@ -312,7 +307,7 @@ static PaError OpenAndSetupOneAudioUnit(
/* for setting errors. */ /* for setting errors. */
#define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \ #define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \
PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) PaUtil_SetLastHostErrorInfo( paCoreAudio, errorCode, errorText )
/* /*
* Callback called when starting or stopping a stream. * Callback called when starting or stopping a stream.
@ -657,26 +652,46 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
Float64 sampleRate; Float64 sampleRate;
char *name; char *name;
PaError err = paNoError; PaError err = paNoError;
CFStringRef nameRef;
UInt32 propSize; UInt32 propSize;
VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId)); VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId));
memset(deviceInfo, 0, sizeof(deviceInfo)); memset(deviceInfo, 0, sizeof(PaDeviceInfo));
deviceInfo->structVersion = 2; deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex; deviceInfo->hostApi = hostApiIndex;
/* Get the device name. Fail if we can't get it. */ /* Get the device name using CFString */
err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL)); propSize = sizeof(nameRef);
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceNameCFString, &propSize, &nameRef));
if (err) if (err)
return err; {
/* Get the device name using c string. Fail if we can't get it. */
err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
if (err)
return err;
name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize); name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize+1);
if ( !name ) if ( !name )
return paInsufficientMemory; return paInsufficientMemory;
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name)); err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
if (err) if (err)
return err; return err;
}
else
{
/* valid CFString so we just allocate a c string big enough to contain the data */
propSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8);
name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations, propSize+1);
if ( !name )
{
CFRelease(nameRef);
return paInsufficientMemory;
}
CFStringGetCString(nameRef, name, propSize+1, kCFStringEncodingUTF8);
CFRelease(nameRef);
}
deviceInfo->name = name; deviceInfo->name = name;
/* Try to get the default sample rate. Don't fail if we can't get this. */ /* Try to get the default sample rate. Don't fail if we can't get this. */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_win_ds.c 1877 2012-11-10 02:55:20Z rbencina $ * $Id: pa_win_ds.c 1945 2015-01-21 06:24:32Z rbencina $
* Portable Audio I/O Library DirectSound implementation * Portable Audio I/O Library DirectSound implementation
* *
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina * Authors: Phil Burk, Robert Marsanyi & Ross Bencina
@ -208,9 +208,9 @@ static signed long GetStreamWriteAvailable( PaStream* stream );
PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" ) PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" )
/************************************************* DX Prototypes **********/ /************************************************* DX Prototypes **********/
static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID, static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
LPCSTR lpszDesc, LPCWSTR lpszDesc,
LPCSTR lpszDrvName, LPCWSTR lpszDrvName,
LPVOID lpContext ); LPVOID lpContext );
/************************************************************************************/ /************************************************************************************/
@ -318,30 +318,43 @@ typedef struct PaWinDsStream
*/ */
static double PaWinDS_GetMinSystemLatencySeconds( void ) static double PaWinDS_GetMinSystemLatencySeconds( void )
{ {
/*
NOTE: GetVersionEx() is deprecated as of Windows 8.1 and can not be used to reliably detect
versions of Windows higher than Windows 8 (due to manifest requirements for reporting higher versions).
Microsoft recommends switching to VerifyVersionInfo (available on Win 2k and later), however GetVersionEx
is is faster, for now we just disable the deprecation warning.
See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx
See: http://www.codeproject.com/Articles/678606/Part-Overcoming-Windows-s-deprecation-of-GetVe
*/
#pragma warning (disable : 4996) /* use of GetVersionEx */
double minLatencySeconds; double minLatencySeconds;
/* Set minimal latency based on whether NT or other OS. /* Set minimal latency based on whether NT or other OS.
* NT has higher latency. * NT has higher latency.
*/ */
OSVERSIONINFO osvi; OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof( osvi ); osvi.dwOSVersionInfoSize = sizeof( osvi );
GetVersionEx( &osvi ); GetVersionEx( &osvi );
DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId )); DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));
DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion )); DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));
DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion )); DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));
/* Check for NT */ /* Check for NT */
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
{ {
minLatencySeconds = PA_DS_WIN_NT_DEFAULT_LATENCY_; minLatencySeconds = PA_DS_WIN_NT_DEFAULT_LATENCY_;
} }
else if(osvi.dwMajorVersion >= 5) else if(osvi.dwMajorVersion >= 5)
{ {
minLatencySeconds = PA_DS_WIN_WDM_DEFAULT_LATENCY_; minLatencySeconds = PA_DS_WIN_WDM_DEFAULT_LATENCY_;
} }
else else
{ {
minLatencySeconds = PA_DS_WIN_9X_DEFAULT_LATENCY_; minLatencySeconds = PA_DS_WIN_9X_DEFAULT_LATENCY_;
} }
return minLatencySeconds; return minLatencySeconds;
#pragma warning (default : 4996)
} }
@ -385,20 +398,35 @@ static double PaWinDs_GetMinLatencySeconds( double sampleRate )
/************************************************************************************ /************************************************************************************
** Duplicate the input string using the allocations allocator. ** Duplicate and convert the input string using the group allocations allocator.
** A NULL string is converted to a zero length string. ** A NULL string is converted to a zero length string.
** If memory cannot be allocated, NULL is returned. ** If memory cannot be allocated, NULL is returned.
**/ **/
static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const char* src ) static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const wchar_t* src )
{ {
char *result = 0; char *result = 0;
if( src != NULL ) if( src != NULL )
{ {
size_t len = strlen(src); #if !defined(_UNICODE) && !defined(UNICODE)
size_t len = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) ); result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) );
if( result ) if( result ) {
memcpy( (void *) result, src, len+1 ); if (WideCharToMultiByte(CP_ACP, 0, src, -1, result, (int)len, NULL, NULL) == 0) {
result = 0;
}
}
#else
size_t len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) );
if( result ) {
if (WideCharToMultiByte(CP_UTF8, 0, src, -1, result, (int)len, NULL, NULL) == 0) {
result = 0;
}
}
#endif
} }
else else
{ {
@ -513,9 +541,9 @@ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *gu
/************************************************************************************ /************************************************************************************
** Collect preliminary device information during DirectSound enumeration ** Collect preliminary device information during DirectSound enumeration
*/ */
static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID, static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
LPCSTR lpszDesc, LPCWSTR lpszDesc,
LPCSTR lpszDrvName, LPCWSTR lpszDrvName,
LPVOID lpContext ) LPVOID lpContext )
{ {
DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext; DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext;
@ -938,7 +966,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
} }
else else
{ {
deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
} }
} }
else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) ) else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )
@ -1211,9 +1239,9 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
if( result != paNoError ) if( result != paNoError )
goto error; goto error;
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA( (LPDSENUMCALLBACKA)CollectGUIDsProcA, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs ); paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW( (LPDSENUMCALLBACKW)CollectGUIDsProcW, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs );
paWinDsDSoundEntryPoints.DirectSoundEnumerateA( (LPDSENUMCALLBACKA)CollectGUIDsProcA, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs ); paWinDsDSoundEntryPoints.DirectSoundEnumerateW( (LPDSENUMCALLBACKW)CollectGUIDsProcW, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs );
if( deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError != paNoError ) if( deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError != paNoError )
{ {
@ -1347,13 +1375,13 @@ static PaError ValidateWinDirectSoundSpecificStreamInfo(
const PaStreamParameters *streamParameters, const PaStreamParameters *streamParameters,
const PaWinDirectSoundStreamInfo *streamInfo ) const PaWinDirectSoundStreamInfo *streamInfo )
{ {
if( streamInfo ) if( streamInfo )
{ {
if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo ) if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo )
|| streamInfo->version != 2 ) || streamInfo->version != 2 )
{ {
return paIncompatibleHostApiSpecificStreamInfo; return paIncompatibleHostApiSpecificStreamInfo;
} }
if( streamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters ) if( streamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
{ {
@ -1361,9 +1389,9 @@ static PaError ValidateWinDirectSoundSpecificStreamInfo(
return paIncompatibleHostApiSpecificStreamInfo; return paIncompatibleHostApiSpecificStreamInfo;
} }
} }
return paNoError; return paNoError;
} }
/***********************************************************************************/ /***********************************************************************************/
@ -1400,8 +1428,8 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
/* validate inputStreamInfo */ /* validate inputStreamInfo */
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo; inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo ); result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
if( result != paNoError ) return result; if( result != paNoError ) return result;
} }
else else
{ {
@ -1429,8 +1457,8 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
/* validate outputStreamInfo */ /* validate outputStreamInfo */
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo; outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo ); result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
if( result != paNoError ) return result; if( result != paNoError ) return result;
} }
else else
{ {
@ -1887,8 +1915,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* validate hostApiSpecificStreamInfo */ /* validate hostApiSpecificStreamInfo */
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo; inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo ); result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
if( result != paNoError ) return result; if( result != paNoError ) return result;
if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters ) if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
userRequestedHostInputBufferSizeFrames = inputStreamInfo->framesPerBuffer; userRequestedHostInputBufferSizeFrames = inputStreamInfo->framesPerBuffer;
@ -1901,7 +1929,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
else else
{ {
inputChannelCount = 0; inputChannelCount = 0;
inputSampleFormat = 0; inputSampleFormat = 0;
suggestedInputLatencyFrames = 0; suggestedInputLatencyFrames = 0;
} }
@ -1927,8 +1955,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* validate hostApiSpecificStreamInfo */ /* validate hostApiSpecificStreamInfo */
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo; outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo ); result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
if( result != paNoError ) return result; if( result != paNoError ) return result;
if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters ) if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
userRequestedHostOutputBufferSizeFrames = outputStreamInfo->framesPerBuffer; userRequestedHostOutputBufferSizeFrames = outputStreamInfo->framesPerBuffer;
@ -1941,7 +1969,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
else else
{ {
outputChannelCount = 0; outputChannelCount = 0;
outputSampleFormat = 0; outputSampleFormat = 0;
suggestedOutputLatencyFrames = 0; suggestedOutputLatencyFrames = 0;
} }
@ -2022,10 +2050,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
hostInputSampleFormat = hostInputSampleFormat =
PaUtil_SelectClosestAvailableFormat( nativeInputFormats, inputParameters->sampleFormat ); PaUtil_SelectClosestAvailableFormat( nativeInputFormats, inputParameters->sampleFormat );
} }
else else
{ {
hostInputSampleFormat = 0; hostInputSampleFormat = 0;
} }
if( outputParameters ) if( outputParameters )
{ {
@ -2037,9 +2065,9 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaUtil_SelectClosestAvailableFormat( nativeOutputFormats, outputParameters->sampleFormat ); PaUtil_SelectClosestAvailableFormat( nativeOutputFormats, outputParameters->sampleFormat );
} }
else else
{ {
hostOutputSampleFormat = 0; hostOutputSampleFormat = 0;
} }
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
inputChannelCount, inputSampleFormat, hostInputSampleFormat, inputChannelCount, inputSampleFormat, hostInputSampleFormat,
@ -2082,7 +2110,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
#endif #endif
#ifndef PA_WIN_DS_USE_WMME_TIMER #ifndef PA_WIN_DS_USE_WMME_TIMER
stream->processingThreadCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL ); stream->processingThreadCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL );
if( stream->processingThreadCompleted == NULL ) if( stream->processingThreadCompleted == NULL )
{ {
result = paUnanticipatedHostError; result = paUnanticipatedHostError;
@ -2482,8 +2510,8 @@ static int TimeSlice( PaWinDsStream *stream )
framesToXfer = numOutFramesReady = bytesEmpty / stream->outputFrameSizeBytes; framesToXfer = numOutFramesReady = bytesEmpty / stream->outputFrameSizeBytes;
/* Check for underflow */ /* Check for underflow */
/* FIXME QueryOutputSpace should not adjust underflow count as a side effect. /* FIXME QueryOutputSpace should not adjust underflow count as a side effect.
A query function should be a const operator on the stream and return a flag on underflow. */ A query function should be a const operator on the stream and return a flag on underflow. */
if( stream->outputUnderflowCount != previousUnderflowCount ) if( stream->outputUnderflowCount != previousUnderflowCount )
stream->callbackFlags |= paOutputUnderflow; stream->callbackFlags |= paOutputUnderflow;
@ -2548,8 +2576,8 @@ static int TimeSlice( PaWinDsStream *stream )
if( stream->bufferProcessor.outputChannelCount > 0 ) if( stream->bufferProcessor.outputChannelCount > 0 )
{ {
/* /*
We don't currently add outputLatency here because it appears to produce worse We don't currently add outputLatency here because it appears to produce worse
results than not adding it. Need to do more testing to verify this. results than not adding it. Need to do more testing to verify this.
*/ */
/* timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency; */ /* timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency; */
timeInfo.outputBufferDacTime = timeInfo.currentTime; timeInfo.outputBufferDacTime = timeInfo.currentTime;
@ -2798,7 +2826,7 @@ static PaError CloseStream( PaStream* s )
#endif #endif
#ifndef PA_WIN_DS_USE_WMME_TIMER #ifndef PA_WIN_DS_USE_WMME_TIMER
CloseHandle( stream->processingThreadCompleted ); CloseHandle( stream->processingThreadCompleted );
#endif #endif
// Cleanup the sound buffers // Cleanup the sound buffers
@ -2896,7 +2924,7 @@ static PaError StartStream( PaStream *s )
ResetEvent( stream->processingCompleted ); ResetEvent( stream->processingCompleted );
#ifndef PA_WIN_DS_USE_WMME_TIMER #ifndef PA_WIN_DS_USE_WMME_TIMER
ResetEvent( stream->processingThreadCompleted ); ResetEvent( stream->processingThreadCompleted );
#endif #endif
if( stream->bufferProcessor.inputChannelCount > 0 ) if( stream->bufferProcessor.inputChannelCount > 0 )
@ -3006,9 +3034,9 @@ static PaError StartStream( PaStream *s )
goto error; goto error;
} }
#else #else
/* Create processing thread which calls TimerCallback */ /* Create processing thread which calls TimerCallback */
stream->processingThread = CREATE_THREAD( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ); stream->processingThread = CREATE_THREAD( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId );
if( !stream->processingThread ) if( !stream->processingThread )
{ {
result = paUnanticipatedHostError; result = paUnanticipatedHostError;
@ -3078,8 +3106,8 @@ static PaError StopStream( PaStream *s )
#else #else
if( stream->processingThread ) if( stream->processingThread )
{ {
if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT ) if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT )
return paUnanticipatedHostError; return paUnanticipatedHostError;
#ifdef CLOSE_THREAD_HANDLE #ifdef CLOSE_THREAD_HANDLE
CloseHandle( stream->processingThread ); /* Delete thread. */ CloseHandle( stream->processingThread ); /* Delete thread. */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_jack.c 1668 2011-05-02 17:07:11Z rossb $ * $Id: pa_jack.c 1912 2013-11-15 12:27:07Z gineera $
* 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
@ -232,6 +232,10 @@ typedef struct PaJackStream
} }
PaJackStream; PaJackStream;
/* In calls to jack_get_ports() this filter expression is used instead of ""
* to prevent any other types (eg Midi ports etc) being listed */
#define JACK_PORT_TYPE_FILTER "audio"
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
@ -492,7 +496,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
* according to the client_name:port_name convention (which is * according to the client_name:port_name convention (which is
* enforced by jackd) * enforced by jackd)
* A: If jack_get_ports returns NULL, there's nothing for us to do */ * A: If jack_get_ports returns NULL, there's nothing for us to do */
UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", "", 0 )) && jack_ports[0], paNoError ); UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", JACK_PORT_TYPE_FILTER, 0 )) && jack_ports[0], paNoError );
/* Find number of ports */ /* Find number of ports */
while( jack_ports[numPorts] ) while( jack_ports[numPorts] )
++numPorts; ++numPorts;
@ -583,7 +587,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
/* ... what are your output ports (that we could input from)? */ /* ... what are your output ports (that we could input from)? */
clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
NULL, JackPortIsOutput); JACK_PORT_TYPE_FILTER, JackPortIsOutput);
curDevInfo->maxInputChannels = 0; curDevInfo->maxInputChannels = 0;
curDevInfo->defaultLowInputLatency = 0.; curDevInfo->defaultLowInputLatency = 0.;
curDevInfo->defaultHighInputLatency = 0.; curDevInfo->defaultHighInputLatency = 0.;
@ -604,7 +608,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
/* ... what are your input ports (that we could output to)? */ /* ... what are your input ports (that we could output to)? */
clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
NULL, JackPortIsInput); JACK_PORT_TYPE_FILTER, JackPortIsInput);
curDevInfo->maxOutputChannels = 0; curDevInfo->maxOutputChannels = 0;
curDevInfo->defaultLowOutputLatency = 0.; curDevInfo->defaultLowOutputLatency = 0.;
curDevInfo->defaultHighOutputLatency = 0.; curDevInfo->defaultHighOutputLatency = 0.;
@ -1235,7 +1239,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* Get output ports of our capture device */ /* Get output ports of our capture device */
snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name ); snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name );
UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
NULL, JackPortIsOutput ), paUnanticipatedHostError ); JACK_PORT_TYPE_FILTER, JackPortIsOutput ), paUnanticipatedHostError );
for( i = 0; i < inputChannelCount && jack_ports[i]; i++ ) for( i = 0; i < inputChannelCount && jack_ports[i]; i++ )
{ {
if( (stream->remote_output_ports[i] = jack_port_by_name( if( (stream->remote_output_ports[i] = jack_port_by_name(
@ -1259,7 +1263,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* Get input ports of our playback device */ /* Get input ports of our playback device */
snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name ); snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name );
UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
NULL, JackPortIsInput ), paUnanticipatedHostError ); JACK_PORT_TYPE_FILTER, JackPortIsInput ), paUnanticipatedHostError );
for( i = 0; i < outputChannelCount && jack_ports[i]; i++ ) for( i = 0; i < outputChannelCount && jack_ports[i]; i++ )
{ {
if( (stream->remote_input_ports[i] = jack_port_by_name( if( (stream->remote_input_ports[i] = jack_port_by_name(

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_unix_oss.c 1668 2011-05-02 17:07:11Z rossb $ * $Id: pa_unix_oss.c 1894 2013-06-08 19:30:41Z gineera $
* 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:
@ -318,6 +318,13 @@ error:
return result; return result;
} }
static int CalcHigherLogTwo( int n )
{
int log2 = 0;
while( (1<<log2) < n ) log2++;
return log2;
}
static PaError QueryDirection( const char *deviceName, StreamMode mode, double *defaultSampleRate, int *maxChannelCount, static PaError QueryDirection( const char *deviceName, StreamMode mode, double *defaultSampleRate, int *maxChannelCount,
double *defaultLowLatency, double *defaultHighLatency ) double *defaultLowLatency, double *defaultHighLatency )
{ {
@ -327,6 +334,8 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
int devHandle = -1; int devHandle = -1;
int sr; int sr;
*maxChannelCount = 0; /* Default value in case this fails */ *maxChannelCount = 0; /* Default value in case this fails */
int temp, frgmt;
unsigned long fragFrames;
if ( (devHandle = open( deviceName, (mode == StreamMode_In ? O_RDONLY : O_WRONLY) | O_NONBLOCK )) < 0 ) if ( (devHandle = open( deviceName, (mode == StreamMode_In ? O_RDONLY : O_WRONLY) | O_NONBLOCK )) < 0 )
{ {
@ -354,7 +363,7 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
maxNumChannels = 0; maxNumChannels = 0;
for( numChannels = 1; numChannels <= 16; numChannels++ ) for( numChannels = 1; numChannels <= 16; numChannels++ )
{ {
int temp = numChannels; temp = numChannels;
if( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ) < 0 ) if( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ) < 0 )
{ {
busy = EAGAIN == errno || EBUSY == errno; busy = EAGAIN == errno || EBUSY == errno;
@ -401,8 +410,8 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
* to a supported number of channels. SG20011005 */ * to a supported number of channels. SG20011005 */
{ {
/* use most reasonable default value */ /* use most reasonable default value */
int temp = PA_MIN( maxNumChannels, 2 ); numChannels = PA_MIN( maxNumChannels, 2 );
ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ), paUnanticipatedHostError ); ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &numChannels ), paUnanticipatedHostError );
} }
/* Get supported sample rate closest to 44100 Hz */ /* Get supported sample rate closest to 44100 Hz */
@ -415,9 +424,21 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
} }
*maxChannelCount = maxNumChannels; *maxChannelCount = maxNumChannels;
/* TODO */
*defaultLowLatency = 512. / *defaultSampleRate; /* Attempt to set low latency with 4 frags-per-buffer, 128 frames-per-frag (total buffer 512 frames)
*defaultHighLatency = 2048. / *defaultSampleRate; * since the ioctl sets bytes, multiply by numChannels, and base on 2 bytes-per-sample, */
fragFrames = 128;
frgmt = (4 << 16) + (CalcHigherLogTwo( fragFrames * numChannels * 2 ) & 0xffff);
ENSURE_( ioctl( devHandle, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError );
/* Use the value set by the ioctl to give the latency achieved */
fragFrames = pow( 2, frgmt & 0xffff ) / (numChannels * 2);
*defaultLowLatency = ((frgmt >> 16) - 1) * fragFrames / *defaultSampleRate;
/* Cannot now try setting a high latency (device would need closing and opening again). Make
* high-latency 4 times the low unless the fragFrames are significantly more than requested 128 */
temp = (fragFrames < 256) ? 4 : (fragFrames < 512) ? 2 : 1;
*defaultHighLatency = temp * *defaultLowLatency;
error: error:
if( devHandle >= 0 ) if( devHandle >= 0 )
@ -962,13 +983,6 @@ static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *comp
return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs; return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs;
} }
static int CalcHigherLogTwo( int n )
{
int log2 = 0;
while( (1<<log2) < n ) log2++;
return log2;
}
/** Configure stream component device parameters. /** Configure stream component device parameters.
*/ */
static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long
@ -995,8 +1009,9 @@ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component,
*/ */
if( framesPerBuffer == paFramesPerBufferUnspecified ) if( framesPerBuffer == paFramesPerBufferUnspecified )
{ {
bufSz = (unsigned long)(component->latency * sampleRate); /* Aim for 4 fragments in the complete buffer; the latency comes from 3 of these */
fragSz = bufSz / 4; fragSz = (unsigned long)(component->latency * sampleRate / 3);
bufSz = fragSz * 4;
} }
else else
{ {

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* $Id: pa_win_wmme.c 1874 2012-10-31 06:20:59Z rbencina $ * $Id: pa_win_wmme.c 1948 2015-01-21 06:52:11Z rbencina $
* pa_win_wmme.c * pa_win_wmme.c
* Implementation of PortAudio for Windows MultiMedia Extensions (WMME) * Implementation of PortAudio for Windows MultiMedia Extensions (WMME)
* *
@ -62,7 +62,7 @@
*/ */
/** @file /** @file
@ingroup hostapi_src @ingroup hostapi_src
@brief Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API. @brief Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API.
*/ */
@ -86,6 +86,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h>
#include <math.h> #include <math.h>
#include <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
@ -201,31 +202,52 @@
static const char constInputMapperSuffix_[] = " - Input"; static const char constInputMapperSuffix_[] = " - Input";
static const char constOutputMapperSuffix_[] = " - Output"; static const char constOutputMapperSuffix_[] = " - Output";
/* /********************************************************************/
copies TCHAR string to explicit char string
*/ /* Copy null-terminated TCHAR string to explicit char string using UTF8 encoding */
char *StrTCpyToC(char *to, const TCHAR *from) static char *CopyTCharStringToUtf8CString(char *destination, size_t destLengthBytes, const TCHAR *source)
{ {
#if !defined(_UNICODE) && !defined(UNICODE) #if !defined(_UNICODE) && !defined(UNICODE)
return strcpy(to, from); return strcpy(destination, source);
#else #else
int count = wcslen(from); /* The cbMultiByte parameter ["destLengthBytes" below] is:
if (count != 0) """
if (WideCharToMultiByte(CP_ACP, 0, from, count, to, count, NULL, NULL) == 0) Size, in bytes, of the buffer indicated by lpMultiByteStr ["destination" below].
return NULL; If this parameter is set to 0, the function returns the required buffer
return to; size for lpMultiByteStr and makes no use of the output parameter itself.
"""
Source: WideCharToMultiByte at MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130(v=vs.85).aspx
*/
int intDestLengthBytes; /* cbMultiByte */
/* intDestLengthBytes is an int, destLengthBytes is a size_t. Ensure that we don't overflow
intDestLengthBytes by only using at most INT_MAX bytes of destination buffer.
*/
if (destLengthBytes < INT_MAX)
{
#pragma warning (disable : 4267) /* "conversion from 'size_t' to 'int', possible loss of data" */
intDestLengthBytes = (int)destLengthBytes; /* destLengthBytes is guaranteed < INT_MAX here */
#pragma warning (default : 4267)
}
else
{
intDestLengthBytes = INT_MAX;
}
if (WideCharToMultiByte(CP_UTF8, 0, source, -1, destination, /*cbMultiByte=*/intDestLengthBytes, NULL, NULL) == 0)
return NULL;
return destination;
#endif #endif
} }
/* /* returns required length (in bytes) of destination buffer when
returns length of TCHAR string converting TCHAR string to UTF8 bytes, not including the terminating null. */
*/ static size_t TCharStringLen(const TCHAR *str)
size_t StrTLen(const TCHAR *str)
{ {
#if !defined(_UNICODE) && !defined(UNICODE) #if !defined(_UNICODE) && !defined(UNICODE)
return strlen(str); return strlen(str);
#else #else
return wcslen(str); return WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
#endif #endif
} }
@ -491,7 +513,7 @@ static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hos
{ {
assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount ); assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount );
return hostApi->winMmeDeviceIds[ device ]; return hostApi->winMmeDeviceIds[ device ];
} }
@ -686,6 +708,7 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
MMRESULT mmresult; MMRESULT mmresult;
WAVEINCAPS wic; WAVEINCAPS wic;
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
size_t len;
*success = 0; *success = 0;
@ -705,31 +728,35 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
return paNoError; return paNoError;
} }
/* NOTE: the WAVEOUTCAPS.szPname is a null-terminated array of 32 characters,
so we are limited to displaying only the first 31 characters of the device name. */
if( winMmeInputDeviceId == WAVE_MAPPER ) if( winMmeInputDeviceId == WAVE_MAPPER )
{ {
len = TCharStringLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_);
/* Append I/O suffix to WAVE_MAPPER device. */ /* Append I/O suffix to WAVE_MAPPER device. */
deviceName = (char *)PaUtil_GroupAllocateMemory( deviceName = (char*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, winMmeHostApi->allocations,
(long) (StrTLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_)) ); (long)len );
if( !deviceName ) if( !deviceName )
{ {
result = paInsufficientMemory; result = paInsufficientMemory;
goto error; goto error;
} }
StrTCpyToC( deviceName, wic.szPname ); CopyTCharStringToUtf8CString( deviceName, len, wic.szPname );
strcat( deviceName, constInputMapperSuffix_ ); strcat( deviceName, constInputMapperSuffix_ );
} }
else else
{ {
len = TCharStringLen( wic.szPname ) + 1;
deviceName = (char*)PaUtil_GroupAllocateMemory( deviceName = (char*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, winMmeHostApi->allocations,
(long) (StrTLen( wic.szPname ) + 1) ); (long)len );
if( !deviceName ) if( !deviceName )
{ {
result = paInsufficientMemory; result = paInsufficientMemory;
goto error; goto error;
} }
StrTCpyToC( deviceName, wic.szPname ); CopyTCharStringToUtf8CString( deviceName, len, wic.szPname );
} }
deviceInfo->name = deviceName; deviceInfo->name = deviceName;
@ -811,6 +838,7 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
MMRESULT mmresult; MMRESULT mmresult;
WAVEOUTCAPS woc; WAVEOUTCAPS woc;
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
size_t len;
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO #ifdef PAWIN_USE_WDMKS_DEVICE_INFO
int wdmksDeviceOutputChannelCountIsKnown; int wdmksDeviceOutputChannelCountIsKnown;
#endif #endif
@ -833,31 +861,35 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
return paNoError; return paNoError;
} }
/* NOTE: the WAVEOUTCAPS.szPname is a null-terminated array of 32 characters,
so we are limited to displaying only the first 31 characters of the device name. */
if( winMmeOutputDeviceId == WAVE_MAPPER ) if( winMmeOutputDeviceId == WAVE_MAPPER )
{ {
/* Append I/O suffix to WAVE_MAPPER device. */ /* Append I/O suffix to WAVE_MAPPER device. */
deviceName = (char *)PaUtil_GroupAllocateMemory( len = TCharStringLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_);
deviceName = (char*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, winMmeHostApi->allocations,
(long) (StrTLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_)) ); (long)len );
if( !deviceName ) if( !deviceName )
{ {
result = paInsufficientMemory; result = paInsufficientMemory;
goto error; goto error;
} }
StrTCpyToC( deviceName, woc.szPname ); CopyTCharStringToUtf8CString( deviceName, len, woc.szPname );
strcat( deviceName, constOutputMapperSuffix_ ); strcat( deviceName, constOutputMapperSuffix_ );
} }
else else
{ {
len = TCharStringLen( woc.szPname ) + 1;
deviceName = (char*)PaUtil_GroupAllocateMemory( deviceName = (char*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations, winMmeHostApi->allocations,
(long) (StrTLen( woc.szPname ) + 1) ); (long)len );
if( !deviceName ) if( !deviceName )
{ {
result = paInsufficientMemory; result = paInsufficientMemory;
goto error; goto error;
} }
StrTCpyToC( deviceName, woc.szPname ); CopyTCharStringToUtf8CString( deviceName, len, woc.szPname );
} }
deviceInfo->name = deviceName; deviceInfo->name = deviceName;
@ -882,7 +914,7 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO #ifdef PAWIN_USE_WDMKS_DEVICE_INFO
wdmksDeviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels( wdmksDeviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels(
winMmeOutputDeviceId, &deviceInfo->maxOutputChannels ); winMmeOutputDeviceId, &deviceInfo->maxOutputChannels );
if( wdmksDeviceOutputChannelCountIsKnown && !winMmeDeviceInfo->deviceOutputChannelCountIsKnown ) if( wdmksDeviceOutputChannelCountIsKnown && !winMmeDeviceInfo->deviceOutputChannelCountIsKnown )
winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
@ -901,9 +933,19 @@ error:
static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency ) static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency )
{ {
/*
NOTE: GetVersionEx() is deprecated as of Windows 8.1 and can not be used to reliably detect
versions of Windows higher than Windows 8 (due to manifest requirements for reporting higher versions).
Microsoft recommends switching to VerifyVersionInfo (available on Win 2k and later), however GetVersionEx
is is faster, for now we just disable the deprecation warning.
See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx
See: http://www.codeproject.com/Articles/678606/Part-Overcoming-Windows-s-deprecation-of-GetVe
*/
#pragma warning (disable : 4996) /* use of GetVersionEx */
OSVERSIONINFO osvi; OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof( osvi ); osvi.dwOSVersionInfoSize = sizeof( osvi );
GetVersionEx( &osvi ); GetVersionEx( &osvi );
/* Check for NT */ /* Check for NT */
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
@ -920,6 +962,8 @@ static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighL
} }
*defaultHighLatency = *defaultLowLatency * 2; *defaultHighLatency = *defaultLowLatency * 2;
#pragma warning (default : 4996)
} }
@ -983,11 +1027,11 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
inputDeviceCount = waveInGetNumDevs(); inputDeviceCount = waveInGetNumDevs();
if( inputDeviceCount > 0 ) if( inputDeviceCount > 0 )
maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
outputDeviceCount = waveOutGetNumDevs(); outputDeviceCount = waveOutGetNumDevs();
if( outputDeviceCount > 0 ) if( outputDeviceCount > 0 )
maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
if( maximumPossibleDeviceCount > 0 ){ if( maximumPossibleDeviceCount > 0 ){
@ -2157,29 +2201,29 @@ static PaError ValidateWinMmeSpecificStreamInfo(
char *throttleProcessingThreadOnOverload, char *throttleProcessingThreadOnOverload,
unsigned long *deviceCount ) unsigned long *deviceCount )
{ {
if( streamInfo ) if( streamInfo )
{ {
if( streamInfo->size != sizeof( PaWinMmeStreamInfo ) if( streamInfo->size != sizeof( PaWinMmeStreamInfo )
|| streamInfo->version != 1 ) || streamInfo->version != 1 )
{ {
return paIncompatibleHostApiSpecificStreamInfo; return paIncompatibleHostApiSpecificStreamInfo;
} }
*winMmeSpecificFlags = streamInfo->flags; *winMmeSpecificFlags = streamInfo->flags;
if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread ) if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread )
*throttleProcessingThreadOnOverload = 0; *throttleProcessingThreadOnOverload = 0;
if( streamInfo->flags & paWinMmeUseMultipleDevices ) if( streamInfo->flags & paWinMmeUseMultipleDevices )
{ {
if( streamParameters->device != paUseHostApiSpecificDeviceSpecification ) if( streamParameters->device != paUseHostApiSpecificDeviceSpecification )
return paInvalidDevice; return paInvalidDevice;
*deviceCount = streamInfo->deviceCount; *deviceCount = streamInfo->deviceCount;
} }
} }
return paNoError; return paNoError;
} }
static PaError RetrieveDevicesFromStreamParameters( static PaError RetrieveDevicesFromStreamParameters(
@ -2194,34 +2238,34 @@ static PaError RetrieveDevicesFromStreamParameters(
int totalChannelCount; int totalChannelCount;
PaDeviceIndex hostApiDevice; PaDeviceIndex hostApiDevice;
if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices ) if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices )
{ {
totalChannelCount = 0; totalChannelCount = 0;
for( i=0; i < deviceCount; ++i ) for( i=0; i < deviceCount; ++i )
{ {
/* validate that the device number is within range */ /* validate that the device number is within range */
result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice,
streamInfo->devices[i].device, hostApi ); streamInfo->devices[i].device, hostApi );
if( result != paNoError ) if( result != paNoError )
return result; return result;
devices[i].device = hostApiDevice; devices[i].device = hostApiDevice;
devices[i].channelCount = streamInfo->devices[i].channelCount; devices[i].channelCount = streamInfo->devices[i].channelCount;
totalChannelCount += devices[i].channelCount; totalChannelCount += devices[i].channelCount;
} }
if( totalChannelCount != streamParameters->channelCount ) if( totalChannelCount != streamParameters->channelCount )
{ {
/* channelCount must match total channels specified by multiple devices */ /* channelCount must match total channels specified by multiple devices */
return paInvalidChannelCount; /* REVIEW use of this error code */ return paInvalidChannelCount; /* REVIEW use of this error code */
} }
} }
else else
{ {
devices[0].device = streamParameters->device; devices[0].device = streamParameters->device;
devices[0].channelCount = streamParameters->channelCount; devices[0].channelCount = streamParameters->channelCount;
} }
return result; return result;
} }
@ -2235,10 +2279,10 @@ static PaError ValidateInputChannelCounts(
PaWinMmeDeviceInfo *inputDeviceInfo; PaWinMmeDeviceInfo *inputDeviceInfo;
PaError paerror; PaError paerror;
for( i=0; i < deviceCount; ++i ) for( i=0; i < deviceCount; ++i )
{ {
if( devices[i].channelCount < 1 ) if( devices[i].channelCount < 1 )
return paInvalidChannelCount; return paInvalidChannelCount;
inputDeviceInfo = inputDeviceInfo =
(PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ];
@ -2246,7 +2290,7 @@ static PaError ValidateInputChannelCounts(
paerror = IsInputChannelCountSupported( inputDeviceInfo, devices[i].channelCount ); paerror = IsInputChannelCountSupported( inputDeviceInfo, devices[i].channelCount );
if( paerror != paNoError ) if( paerror != paNoError )
return paerror; return paerror;
} }
return paNoError; return paNoError;
} }
@ -2260,10 +2304,10 @@ static PaError ValidateOutputChannelCounts(
PaWinMmeDeviceInfo *outputDeviceInfo; PaWinMmeDeviceInfo *outputDeviceInfo;
PaError paerror; PaError paerror;
for( i=0; i < deviceCount; ++i ) for( i=0; i < deviceCount; ++i )
{ {
if( devices[i].channelCount < 1 ) if( devices[i].channelCount < 1 )
return paInvalidChannelCount; return paInvalidChannelCount;
outputDeviceInfo = outputDeviceInfo =
(PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ];
@ -2271,7 +2315,7 @@ static PaError ValidateOutputChannelCounts(
paerror = IsOutputChannelCountSupported( outputDeviceInfo, devices[i].channelCount ); paerror = IsOutputChannelCountSupported( outputDeviceInfo, devices[i].channelCount );
if( paerror != paNoError ) if( paerror != paNoError )
return paerror; return paerror;
} }
return paNoError; return paNoError;
} }
@ -2320,28 +2364,28 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
if( inputParameters ) if( inputParameters )
{ {
inputChannelCount = inputParameters->channelCount; inputChannelCount = inputParameters->channelCount;
inputSampleFormat = inputParameters->sampleFormat; inputSampleFormat = inputParameters->sampleFormat;
suggestedInputLatency = inputParameters->suggestedLatency; suggestedInputLatency = inputParameters->suggestedLatency;
inputDeviceCount = 1; inputDeviceCount = 1;
/* validate input hostApiSpecificStreamInfo */ /* validate input hostApiSpecificStreamInfo */
inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo; inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo, result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo,
&winMmeSpecificInputFlags, &winMmeSpecificInputFlags,
&throttleProcessingThreadOnOverload, &throttleProcessingThreadOnOverload,
&inputDeviceCount ); &inputDeviceCount );
if( result != paNoError ) return result; if( result != paNoError ) return result;
inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount ); inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount );
if( !inputDevices ) return paInsufficientMemory; if( !inputDevices ) return paInsufficientMemory;
result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount ); result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount );
if( result != paNoError ) return result; if( result != paNoError ) return result;
result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount ); result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount );
if( result != paNoError ) return result; if( result != paNoError ) return result;
hostInputSampleFormat = hostInputSampleFormat =
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
@ -2357,7 +2401,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
else else
inputChannelMask = PaWin_DefaultChannelMask( inputDevices[0].channelCount ); inputChannelMask = PaWin_DefaultChannelMask( inputDevices[0].channelCount );
} }
} }
else else
{ {
inputChannelCount = 0; inputChannelCount = 0;
@ -2376,22 +2420,22 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
outputDeviceCount = 1; outputDeviceCount = 1;
/* validate output hostApiSpecificStreamInfo */ /* validate output hostApiSpecificStreamInfo */
outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo; outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo, result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo,
&winMmeSpecificOutputFlags, &winMmeSpecificOutputFlags,
&throttleProcessingThreadOnOverload, &throttleProcessingThreadOnOverload,
&outputDeviceCount ); &outputDeviceCount );
if( result != paNoError ) return result; if( result != paNoError ) return result;
outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount ); outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount );
if( !outputDevices ) return paInsufficientMemory; if( !outputDevices ) return paInsufficientMemory;
result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount ); result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount );
if( result != paNoError ) return result; if( result != paNoError ) return result;
result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount ); result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount );
if( result != paNoError ) return result; if( result != paNoError ) return result;
hostOutputSampleFormat = hostOutputSampleFormat =
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
@ -3219,9 +3263,9 @@ static PaError StartStream( PaStream *s )
MMRESULT mmresult; MMRESULT mmresult;
unsigned int i, j; unsigned int i, j;
int callbackResult; int callbackResult;
unsigned int channel; unsigned int channel;
unsigned long framesProcessed; unsigned long framesProcessed;
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */ PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */
PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); PaUtil_ResetBufferProcessor( &stream->bufferProcessor );

View File

@ -66,33 +66,34 @@
#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) && !defined(__GNUC__)
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200) && (_MSC_VER < 1600))) /* MSC version 6 up to 2008 */
#pragma comment( lib, "ksguid.lib" )
#endif
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
#else
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_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
#endif
/* PortAudio-local instances of GUIDs previously sourced from ksguid.lib */
/* GUID KSDATAFORMAT_TYPE_AUDIO */
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
/* GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT */
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
/* GUID KSDATAFORMAT_SUBTYPE_PCM */
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
/* GUID KSDATAFORMAT_SUBTYPE_WAVEFORMATEX */
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
/* GUID KSMEDIUMSETID_Standard */
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
/* GUID KSINTERFACESETID_Standard */
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
/* GUID KSPROPSETID_Pin */
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
#define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\ #define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\
(!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT))) (!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))
static PaError WdmGetPinPropertySimple( static PaError WdmGetPinPropertySimple(
HANDLE handle, HANDLE handle,
unsigned long pinId, unsigned long pinId,

View File

@ -112,6 +112,18 @@ TODO:
0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000 0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000
*/ */
#if defined(_WIN64) || defined(_WIN32_WCE)
/*
-EMT64/AMD64 uses different asm
-VC2005 doesnt allow _WIN64 with inline assembly either!
*/
void PaUtil_InitializeX86PlainConverters( void )
{
}
#else
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/ static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/
@ -130,19 +142,6 @@ static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if defined(_WIN64) || defined(_WIN32_WCE)
/*
-EMT64/AMD64 uses different asm
-VC2005 doesnt allow _WIN64 with inline assembly either!
*/
void PaUtil_InitializeX86PlainConverters( void )
{
}
#else
static void Float32_To_Int32( static void Float32_To_Int32(
void *destinationBuffer, signed int destinationStride, void *destinationBuffer, signed int destinationStride,
void *sourceBuffer, signed int sourceStride, void *sourceBuffer, signed int sourceStride,

17
3rdparty/portaudio/update_svnrevision.sh vendored Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
#
# Write the SVN revision to an include file.
# This should be run before compiling code on Linux or Macintosh.
#
revision_filename=src/common/pa_svnrevision.h
# Run svnversion first to make sure it is installed before corrupting the
# include file.
svnversion .
# Update the include file with the current SVN revision.
echo -n "#define PA_SVN_REVISION " > ${revision_filename}
svnversion . >> ${revision_filename}
echo ${revision_filename} now contains
cat ${revision_filename}