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
# 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,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
# Foundation, Inc.
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@ -134,6 +132,31 @@ export LANGUAGE
# 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
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
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_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'\" &&
@ -220,21 +244,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
# 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
export CONFIG_SHELL
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+"$@"}
export CONFIG_SHELL
# 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
exit 255
fi
if test x$as_have_required = xno; then :
@ -336,6 +364,14 @@ $as_echo X"$as_dir" |
} # 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
# ----------------------
# 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" ||
{ $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
# (the dirname of $[0] is not the place where we might find the
# 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:
# 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.
# 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 ||
as_ln_s='cp -p'
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@ -512,28 +552,8 @@ else
as_mkdir_p=false
fi
if test -x / >/dev/null 2>&1; then
as_test_x='test -x'
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
as_test_x='test -x'
as_executable_p=as_fn_executable_p
# 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'"
@ -1218,8 +1238,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
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
cross_compiling=yes
fi
@ -1492,9 +1510,9 @@ test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
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
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@ -1608,7 +1626,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@ -1868,7 +1886,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@ -1991,7 +2009,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -2007,7 +2026,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -2033,7 +2053,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -2049,7 +2070,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -2083,7 +2105,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0
test_array [0] = 0;
return test_array [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.
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 $@
@ -2785,7 +2808,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -2825,7 +2848,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -2878,7 +2901,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -2919,7 +2942,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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
ac_prog_rejected=yes
continue
@ -2977,7 +3000,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -3021,7 +3044,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -3467,8 +3490,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@ -3582,7 +3604,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -3626,7 +3648,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -3833,7 +3855,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -3873,7 +3895,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -3925,7 +3947,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -3965,7 +3987,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -4017,7 +4039,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -4057,7 +4079,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -4231,7 +4253,7 @@ do
for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
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
case `"$ac_path_SED" --version 2>&1` in
@ -4307,7 +4329,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
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
case `"$ac_path_GREP" --version 2>&1` in
@ -4373,7 +4395,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
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
case `"$ac_path_EGREP" --version 2>&1` in
@ -4440,7 +4462,7 @@ do
for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
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
case `"$ac_path_FGREP" --version 2>&1` in
@ -4696,7 +4718,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -4740,7 +4762,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5159,7 +5181,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5199,7 +5221,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5502,7 +5524,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5542,7 +5564,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5643,7 +5665,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5687,7 +5709,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5812,7 +5834,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5852,7 +5874,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5911,7 +5933,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -5951,7 +5973,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6055,7 +6077,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6628,7 +6650,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6668,7 +6690,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6748,7 +6770,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6788,7 +6810,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6840,7 +6862,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6880,7 +6902,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6932,7 +6954,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -6972,7 +6994,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -7024,7 +7046,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -7064,7 +7086,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -7116,7 +7138,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -7156,7 +7178,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -14873,7 +14895,7 @@ case $as_dir/ in #((
# by default.
for ac_prog in ginstall scoinst install; 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 &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
@ -14958,7 +14980,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -15391,7 +15413,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -15434,7 +15456,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
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"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@ -15769,7 +15791,7 @@ case "${host_os}" in
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
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)
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
mac_version_min="-mmacosx-version-min=10.4"
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
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
esac
@ -16632,16 +16660,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 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.
# 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 ||
as_ln_s='cp -p'
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@ -16701,28 +16729,16 @@ else
as_mkdir_p=false
fi
if test -x / >/dev/null 2>&1; then
as_test_x='test -x'
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
# 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_test_x='test -x'
as_executable_p=as_fn_executable_p
# 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'"
@ -16744,7 +16760,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# values after options handling.
ac_log="
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_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_version="\\
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\\"
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
gives unlimited permission to copy, distribute and modify it."
@ -16883,7 +16899,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
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
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'

View File

@ -208,7 +208,7 @@ case "${host_os}" in
LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
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)
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
mac_version_min="-mmacosx-version-min=10.4"
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
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
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
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.
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.
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
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.
6) Select "all configurations" in the "Configurations" combo box above. Select "All Platforms" in the "Platforms" combo box.
7) Now set a few options:
C/C++ -> Optimization -> Omit frame pointers = Yes
Required:
C/C++ -> Code Generation -> Runtime library = /MT
Optional:
C/C++ -> Optimization -> Omit frame pointers = Yes
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.
@ -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.
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_DS (DirectSound)[[BR]]
PA_USE_WMME (MME)[[BR]]
PA_USE_WASAPI[[BR]]
PA_USE_WDMKS[[BR]]
PA_USE_ASIO<br>
PA_USE_DS (DirectSound)<br>
PA_USE_WMME (MME)<br>
PA_USE_WASAPI<br>
PA_USE_WDMKS<br>
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
@ -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.
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)
@code
@ -71,13 +77,16 @@ PaUtil_SetLogPrintFunction @55
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:
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
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
Edits by Ross on 1/20/2014
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
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:
@code
/ASIOSDK2
/portaudio
/DirContainingYourVisualStudioProject
/DirContainingYourVisualStudioProject (should directly contain the .sln, .vcproj or .vcprojx etc.)
@endcode
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_win_hostapis.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_x86_plain_converters.c (portaudio\src\os\win)
patest_saw.c (portaudio\test) (Or another file containing main()
for the console exe to be built.)
paex_saw.c (portaudio\examples) (Or another file containing main()
for the console exe to be built.)
@endcode
@ -71,25 +72,26 @@ pa_asio.h (portaudio\include)
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.
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
..\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
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.
We suggest that you start with patest_saw.c because it's one of the simplest test files.
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.)
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
[wiki:UsingThePortAudioSvnRepository SVN instructions]
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
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:

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
#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
* WDM/KS specific extensions
*
@ -52,13 +52,29 @@
extern "C"
{
#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{
unsigned long size; /**< sizeof(PaWinWDMKSInfo) */
PaHostApiTypeId hostApiType; /**< paWDMKS */
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. */
unsigned noOfPackets;
/* If paWinWDMKSUseGivenChannelMask bit is set in flags, use this as channelMask instead of default */
unsigned channelMask;
} PaWinWDMKSInfo;
typedef enum PaWDMKSType

View File

@ -1,7 +1,7 @@
#ifndef 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 API Header File
* Latest version available at: http://www.portaudio.com/
@ -50,18 +50,52 @@ extern "C"
{
#endif /* __cplusplus */
/** Retrieve the release number of the currently running PortAudio build,
eg 1900.
*/
/** Retrieve the release number of the currently running PortAudio build.
* For example, for version "19.5.1" this will return 0x00130501.
*/
int Pa_GetVersion( void );
/** 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 );
/**
* 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.
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
* Validate function parameters and manage multiple host APIs.
*
@ -65,6 +65,7 @@
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h> /* needed for strtol() */
#include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
#include "portaudio.h"
@ -76,25 +77,63 @@
#include "pa_trace.h" /* still usefull?*/
#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 )
{
return PA_VERSION_;
return paVersion;
}
const char* Pa_GetVersionText( void )
{
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

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
* streamCallback <-> host buffer processing adapter
*
@ -238,7 +238,7 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
bp->inputConverter =
PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, tempInputStreamFlags );
bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat );
bp->inputZeroer = PaUtil_SelectZeroer( userInputSampleFormat );
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
@ -743,8 +743,10 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
/* 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)
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved,
* 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;
destBytePtr = (unsigned char *)hostInputChannels[0].data;
@ -832,8 +834,10 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
{
if( bp->userOutputIsInterleaved )
{
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved )
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved,
* 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;
skipOutputConvert = 1;
@ -1683,9 +1687,9 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
hostInputChannels[i].stride,
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) +
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
}
@ -1715,7 +1719,7 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
nonInterleavedDestPtrs[i] = destBytePtr;
/* advance dest ptr for next iteration */
/* advance source ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
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
* Store trace information in real-time for later printing.
*
@ -227,4 +227,12 @@ void PaUtil_DiscardHighSpeedLog( LogHandle hLog )
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 */

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
* Latest Version at: http://www.portaudio.com
* ALSA implementation by Joshua Haberman and Arve Knudsen
@ -602,7 +602,6 @@ typedef enum
typedef struct
{
PaSampleFormat hostSampleFormat;
unsigned long framesPerBuffer;
int numUserChannels, numHostChannels;
int userInterleaved, hostInterleaved;
int canMmap;
@ -613,7 +612,7 @@ typedef struct
int useReventFix; /* Alsa older than 1.0.16, plug devices need a fix */
snd_pcm_t *pcm;
snd_pcm_uframes_t bufferSize;
snd_pcm_uframes_t framesPerPeriod, alsaBufferSize;
snd_pcm_format_t nativeFormat;
unsigned int nfds;
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;
snd_pcm_hw_params_t *hwParams;
snd_pcm_uframes_t lowLatency = 512, highLatency = 2048;
snd_pcm_uframes_t alsaBufferFrames, alsaPeriodFrames;
unsigned int minChans, maxChans;
int* minChannels, * maxChannels;
double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate =
&devInfo->baseDeviceInfo.defaultSampleRate;
double defaultSr = *defaultSampleRate;
int dir;
assert( pcm );
@ -908,36 +908,34 @@ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, in
}
/* TWEAKME:
*
* Giving values for default min and max latency is not
* straightforward. Here are our objectives:
*
* * for low latency, we want to give the lowest value
* that will work reliably. This varies based on the
* sound card, kernel, CPU, etc. I think it is better
* 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.
* Giving values for default min and max latency is not straightforward.
* * for low latency, we want to give the lowest value that will work reliably.
* 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 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 */
ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), 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;
*maxChannels = (int)maxChans;
*defaultSampleRate = defaultSr;
*defaultLowLatency = (double) lowLatency / *defaultSampleRate;
*defaultHighLatency = (double) highLatency / *defaultSampleRate;
end:
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
* wether input/output is available) */
* whether input/output is available) */
static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo )
{
deviceInfo->structVersion = -1;
@ -1080,6 +1078,38 @@ static int IgnorePlugin( const char *pluginId )
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.
*
* 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 )
{
int tries = 0, maxTries = waitOnBusy ? busyRetries_ : 0;
int ret = alsa_snd_pcm_open( pcmp, name, stream, mode );
int ret, tries = 0, maxTries = waitOnBusy ? busyRetries_ : 0;
ret = alsa_snd_pcm_open( pcmp, name, stream, mode );
for( tries = 0; tries < maxTries && -EBUSY == ret; ++tries )
{
Pa_Sleep( 10 );
@ -1114,7 +1146,7 @@ static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream,
return ret;
}
static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceName, int blocking,
static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceHwInfo, int blocking,
PaAlsaDeviceInfo* devInfo, int* devIdx )
{
PaError result = 0;
@ -1122,43 +1154,43 @@ static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* d
snd_pcm_t *pcm = NULL;
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 */
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 */
/* Query capture */
if( deviceName->hasCapture &&
OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_CAPTURE, blocking, 0 ) >= 0 )
if( deviceHwInfo->hasCapture &&
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 */
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;
}
}
/* Query playback */
if( deviceName->hasPlayback &&
OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_PLAYBACK, blocking, 0 ) >= 0 )
if( deviceHwInfo->hasPlayback &&
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 */
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;
}
}
baseDeviceInfo->structVersion = 2;
baseDeviceInfo->hostApi = alsaApi->hostApiIndex;
baseDeviceInfo->name = deviceName->name;
devInfo->alsaName = deviceName->alsaName;
devInfo->isPlug = deviceName->isPlug;
baseDeviceInfo->name = deviceHwInfo->name;
devInfo->alsaName = deviceHwInfo->alsaName;
devInfo->isPlug = deviceHwInfo->isPlug;
/* 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
@ -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 */
if( ( baseApi->info.defaultInputDevice == paNoDevice ||
!strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxInputChannels > 0 )
!strcmp( deviceHwInfo->alsaName, "default" ) ) && baseDeviceInfo->maxInputChannels > 0 )
{
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 ||
!strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxOutputChannels > 0 )
!strcmp( deviceHwInfo->alsaName, "default" ) ) && baseDeviceInfo->maxOutputChannels > 0 )
{
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;
(*devIdx) += 1;
}
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:
@ -1205,6 +1237,8 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
snd_pcm_info_t *pcmInfo;
int res;
int blocking = SND_PCM_NONBLOCK;
int usePlughw = 0;
char *hwPrefix = "";
char alsaCardName[50];
#ifdef PA_ENABLE_DEBUG_OUTPUT
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" ) ) )
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 */
baseApi->info.defaultInputDevice = 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 )
{
char *alsaDeviceName, *deviceName;
char *alsaDeviceName, *deviceName, *infoName;
size_t len;
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 */
alsa_snd_pcm_info_set_device( pcmInfo, devIdx );
@ -1276,12 +1319,13 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
continue;
}
infoName = SkipCardDetailsInName( (char *)alsa_snd_pcm_info_get_name( pcmInfo ), cardName );
/* 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 ),
paInsufficientMemory );
snprintf( deviceName, len, "%s: %s (%s)", cardName,
alsa_snd_pcm_info_get_name( pcmInfo ), buf );
snprintf( deviceName, len, "%s: %s (%s)", cardName, infoName, buf );
++numDeviceNames;
if( !hwDevInfos || numDeviceNames > maxDeviceNames )
@ -1295,7 +1339,7 @@ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName;
hwDevInfos[ numDeviceNames - 1 ].name = deviceName;
hwDevInfos[ numDeviceNames - 1 ].isPlug = 0;
hwDevInfos[ numDeviceNames - 1 ].isPlug = usePlughw;
hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback;
hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture;
}
@ -1662,32 +1706,22 @@ static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat )
/** 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
* device number, it maybe specified through an env variable (PA_ALSA_PLUGHW) that we should open the corresponding plugin
* device.
* The device to be open can be specified by name in a custom PaAlsaStreamInfo struct, or it will be by
* the Portaudio device number supplied in the stream parameters.
*/
static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection
streamDir, snd_pcm_t **pcm )
{
PaError result = paNoError;
int ret;
char dnameArray[50];
const char* deviceName = dnameArray;
const char* deviceName = "";
const PaAlsaDeviceInfo *deviceInfo = NULL;
PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo;
if( !streamInfo )
{
int usePlug = 0;
deviceInfo = GetDeviceInfo( hostApi, params->device );
/* 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;
deviceName = deviceInfo->alsaName;
}
else
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
: devInfo->minOutputChannels );
self->deviceIsPlug = devInfo->isPlug;
PA_DEBUG(( "%s: Host Chans %c %i\n", __FUNCTION__, streamDir == StreamDirection_In ? 'C' : 'P', self->numHostChannels ));
}
else
{
@ -1900,8 +1935,8 @@ error:
static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self )
{
alsa_snd_pcm_close( self->pcm );
if( self->userBuffers )
PaUtil_FreeMemory( self->userBuffers );
PaUtil_FreeMemory( self->userBuffers ); /* (Ptr can be NULL; PaUtil_FreeMemory includes a NULL check) */
PaUtil_FreeMemory( self->nonMmapBuffer );
}
/*
@ -1932,7 +1967,7 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se
double sr = *sampleRate;
unsigned int minPeriods = 2;
/* self->framesPerBuffer = framesPerHostBuffer; */
/* self->framesPerPeriod = framesPerHostBuffer; */
/* ... fill up the configuration space with all possibile
* combinations of parameters this device will accept */
@ -2027,7 +2062,7 @@ error:
/** 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.
*/
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 );
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 );
/* Set the parameters! */
@ -2058,21 +2093,21 @@ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *sel
}
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
{
self->bufferSize = bufSz;
self->alsaBufferSize = bufSz;
}
/* Latency in seconds */
*latency = self->bufferSize / sampleRate;
*latency = (self->alsaBufferSize - self->framesPerPeriod) / sampleRate;
/* Now software parameters... */
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_stop_threshold( self->pcm, swParams, self->bufferSize ), 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->alsaBufferSize ), paUnanticipatedHostError );
/* Silence buffer in the case of underrun */
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_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_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.
*
* 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.
* @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 */
self->framesPerBuffer = framesPerHostBuffer;
self->framesPerPeriod = framesPerHostBuffer;
error:
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
* 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
*
* 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 );
ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ),
paUnanticipatedHostError );
self->capture.framesPerBuffer = self->playback.framesPerBuffer = periodSize;
self->capture.framesPerPeriod = self->playback.framesPerPeriod = periodSize;
framesPerHostBuffer = periodSize;
}
else
@ -2574,15 +2609,15 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double
optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize );
optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize );
self->capture.framesPerBuffer = optimalPeriodSize;
self->capture.framesPerPeriod = optimalPeriodSize;
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 );
self->playback.framesPerBuffer = optimalPeriodSize;
self->playback.framesPerPeriod = optimalPeriodSize;
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 );
framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod );
*hostBufferSizeMode = paUtilBoundedHostBufferSize;
}
}
@ -2612,17 +2647,17 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer,
sampleRate, firstHwParams, &accurate ) );
second->framesPerBuffer = first->framesPerBuffer;
second->framesPerPeriod = first->framesPerPeriod;
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 );
if( self->capture.framesPerBuffer == self->playback.framesPerBuffer )
if( self->capture.framesPerPeriod == self->playback.framesPerPeriod )
{
framesPerHostBuffer = self->capture.framesPerBuffer;
framesPerHostBuffer = self->capture.framesPerPeriod;
}
else
{
framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod );
*hostBufferSizeMode = paUtilBoundedHostBufferSize;
}
}
@ -2633,14 +2668,14 @@ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double
{
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer,
sampleRate, hwParamsCapture, &accurate) );
framesPerHostBuffer = self->capture.framesPerBuffer;
framesPerHostBuffer = self->capture.framesPerPeriod;
}
else
{
assert( self->playback.pcm );
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer,
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 )
{
assert( self->capture.framesPerBuffer != 0 );
assert( self->capture.framesPerPeriod != 0 );
PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr,
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 )
{
assert( self->playback.framesPerBuffer != 0 );
assert( self->playback.framesPerPeriod != 0 );
PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr,
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 */
@ -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,
self->playback.pcm ? self->playback.framesPerBuffer : ULONG_MAX );
unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerPeriod : ULONG_MAX,
self->playback.pcm ? self->playback.framesPerPeriod : ULONG_MAX );
self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer ); /* Period in msecs, rounded up */
/* 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 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 */
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
* on block adaption */
/*
if( framesPerHostBuffer % framesPerBuffer != 0 || (self->capture.pcm && self->playback.pcm &&
self->capture.framesPerBuffer != self->playback.framesPerBuffer) )
if( framesPerHostBuffer % framesPerPeriod != 0 || (self->capture.pcm && self->playback.pcm &&
self->capture.framesPerPeriod != self->playback.framesPerPeriod) )
self->useBlockAdaption = 1;
else
self->alignFrames = 1;
@ -2791,7 +2826,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* XXX: Why do we support this anyway? */
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") );
}
@ -2818,7 +2853,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)(
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;
@ -2859,7 +2894,7 @@ static void SilenceBuffer( PaAlsaStream *stream )
/** 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
* 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.
@ -2945,7 +2980,7 @@ static PaError StartStream( PaStream *s )
{
PaError result = paNoError;
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 */
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
@ -3036,7 +3071,7 @@ error:
/** 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
* returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish
* buffers (drain)
@ -3318,16 +3353,16 @@ static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamD
if( StreamDirection_Out == streamDir )
{
/* 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 )
{
PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" ));
*continuePoll = 0;
}
else if( margin < otherComponent->framesPerBuffer )
else if( margin < otherComponent->framesPerPeriod )
{
*pollTimeout = CalculatePollTimeout( stream, margin );
PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n",
@ -3438,7 +3473,7 @@ static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self,
else
{
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;
int i;
for( i = 0; i < self->numHostChannels; ++i )
@ -3452,13 +3487,6 @@ static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self,
if( self->canMmap )
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 )
{
@ -3771,7 +3799,8 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
}
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 ) );
totalFds += self->playback.nfds;
}
@ -3870,7 +3899,7 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
{
/* Drop input, a period's worth */
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 = 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
* at least one period */
avail = alsa_snd_pcm_avail_update( stream->playback.pcm );
startThreshold = avail - (avail % stream->playback.framesPerBuffer);
assert( startThreshold >= stream->playback.framesPerBuffer );
startThreshold = avail - (avail % stream->playback.framesPerPeriod);
assert( startThreshold >= stream->playback.framesPerPeriod );
}
else
{
@ -4439,10 +4468,10 @@ static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frame
/* Frames residing in buffer */
PA_ENSURE( err = GetStreamWriteAvailable( stream ) );
framesAvail = err;
hwAvail = stream->playback.bufferSize - framesAvail;
hwAvail = stream->playback.alsaBufferSize - framesAvail;
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 );
}

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
*
* Author: Stephane Letz
@ -1019,6 +1019,149 @@ static ASIOSampleRate defaultSampleRateSearchOrder_[]
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) */
typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID);
IsDebuggerPresentPtr IsDebuggerPresent_ = 0;
@ -1142,14 +1285,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
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]));
// 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... */
if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriver.info, asioHostApi->systemSpecific ) == paNoError )
/* Attempt to init device info from the asio driver... */
{
PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
@ -1192,119 +1326,17 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
deviceInfo->hostApi = hostApiIndex;
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;
deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount;
deviceInfo->defaultSampleRate = 0.;
bool foundDefaultSampleRate = false;
for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
if( InitPaDeviceInfoFromAsioDriver( asioHostApi, names[i], i, deviceInfo, asioDeviceInfo ) == paNoError )
{
ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
{
deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
foundDefaultSampleRate = true;
break;
}
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
++(*hostApi)->info.deviceCount;
}
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, 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.;
else
{
PA_DEBUG(("Skipping ASIO device:%s\n",names[i]));
continue;
}
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;
error_unload:
UnloadAsioDriver();
error:
if( asioHostApi )
{

View File

@ -125,83 +125,78 @@ static bool ensureChannelNameSize( int size )
*/
const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input )
{
struct PaUtilHostApiRepresentation *hostApi;
PaError err;
OSStatus error;
err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
assert(err == paNoError);
if( err != paNoError )
return NULL;
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device];
struct PaUtilHostApiRepresentation *hostApi;
PaError err;
OSStatus error;
err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
assert(err == paNoError);
if( err != paNoError )
return NULL;
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
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,
channelIndex + 1,
input,
kAudioDevicePropertyChannelName,
&size,
NULL );
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 );
}
error = AudioDeviceGetProperty( hostApiDevice,
channelIndex + 1,
input,
kAudioDevicePropertyChannelName,
&size,
channelName );
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( !ensureChannelNameSize( size ) )
return NULL;
if( !error )
return channelName;
}
error = AudioDeviceGetProperty( hostApiDevice,
channelIndex + 1,
input,
kAudioDevicePropertyChannelName,
&size,
channelName );
/* as a last-ditch effort, we use the device name and append the channel number. */
nameRef = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%s: %d"), hostApi->deviceInfos[device]->name, channelIndex + 1 );
if( error ) {
ERR( error );
return NULL;
}
return channelName;
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8);;
if( !ensureChannelNameSize( size ) )
{
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. */
#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.
@ -657,26 +652,46 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
Float64 sampleRate;
char *name;
PaError err = paNoError;
CFStringRef nameRef;
UInt32 propSize;
VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId));
memset(deviceInfo, 0, sizeof(deviceInfo));
memset(deviceInfo, 0, sizeof(PaDeviceInfo));
deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex;
/* Get the device name. Fail if we can't get it. */
err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
/* Get the device name using CFString */
propSize = sizeof(nameRef);
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceNameCFString, &propSize, &nameRef));
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);
if ( !name )
return paInsufficientMemory;
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
if (err)
return err;
name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize+1);
if ( !name )
return paInsufficientMemory;
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
if (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;
/* 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
*
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina
@ -208,9 +208,9 @@ static signed long GetStreamWriteAvailable( PaStream* stream );
PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" )
/************************************************* DX Prototypes **********/
static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID,
LPCSTR lpszDesc,
LPCSTR lpszDrvName,
static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
LPCWSTR lpszDesc,
LPCWSTR lpszDrvName,
LPVOID lpContext );
/************************************************************************************/
@ -318,30 +318,43 @@ typedef struct PaWinDsStream
*/
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;
/* Set minimal latency based on whether NT or other OS.
* NT has higher latency.
*/
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof( osvi );
GetVersionEx( &osvi );
osvi.dwOSVersionInfoSize = sizeof( osvi );
GetVersionEx( &osvi );
DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));
DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));
DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));
/* Check for NT */
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
{
minLatencySeconds = PA_DS_WIN_NT_DEFAULT_LATENCY_;
}
else if(osvi.dwMajorVersion >= 5)
{
minLatencySeconds = PA_DS_WIN_WDM_DEFAULT_LATENCY_;
}
else
{
minLatencySeconds = PA_DS_WIN_9X_DEFAULT_LATENCY_;
}
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
{
minLatencySeconds = PA_DS_WIN_NT_DEFAULT_LATENCY_;
}
else if(osvi.dwMajorVersion >= 5)
{
minLatencySeconds = PA_DS_WIN_WDM_DEFAULT_LATENCY_;
}
else
{
minLatencySeconds = PA_DS_WIN_9X_DEFAULT_LATENCY_;
}
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.
** 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;
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) );
if( result )
memcpy( (void *) result, src, len+1 );
if( result ) {
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
{
@ -513,9 +541,9 @@ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *gu
/************************************************************************************
** Collect preliminary device information during DirectSound enumeration
*/
static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID,
LPCSTR lpszDesc,
LPCSTR lpszDrvName,
static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
LPCWSTR lpszDesc,
LPCWSTR lpszDrvName,
LPVOID lpContext )
{
DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext;
@ -938,7 +966,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
}
else
{
deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
}
}
else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )
@ -1211,9 +1239,9 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
if( result != paNoError )
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 )
{
@ -1347,13 +1375,13 @@ static PaError ValidateWinDirectSoundSpecificStreamInfo(
const PaStreamParameters *streamParameters,
const PaWinDirectSoundStreamInfo *streamInfo )
{
if( streamInfo )
{
if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo )
|| streamInfo->version != 2 )
{
return paIncompatibleHostApiSpecificStreamInfo;
}
if( streamInfo )
{
if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo )
|| streamInfo->version != 2 )
{
return paIncompatibleHostApiSpecificStreamInfo;
}
if( streamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
{
@ -1361,9 +1389,9 @@ static PaError ValidateWinDirectSoundSpecificStreamInfo(
return paIncompatibleHostApiSpecificStreamInfo;
}
}
}
return paNoError;
return paNoError;
}
/***********************************************************************************/
@ -1400,8 +1428,8 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
/* validate inputStreamInfo */
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
if( result != paNoError ) return result;
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
if( result != paNoError ) return result;
}
else
{
@ -1429,8 +1457,8 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
/* validate outputStreamInfo */
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
if( result != paNoError ) return result;
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
if( result != paNoError ) return result;
}
else
{
@ -1887,8 +1915,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* validate hostApiSpecificStreamInfo */
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
if( result != paNoError ) return result;
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
if( result != paNoError ) return result;
if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
userRequestedHostInputBufferSizeFrames = inputStreamInfo->framesPerBuffer;
@ -1901,7 +1929,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
else
{
inputChannelCount = 0;
inputSampleFormat = 0;
inputSampleFormat = 0;
suggestedInputLatencyFrames = 0;
}
@ -1927,8 +1955,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* validate hostApiSpecificStreamInfo */
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
if( result != paNoError ) return result;
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
if( result != paNoError ) return result;
if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
userRequestedHostOutputBufferSizeFrames = outputStreamInfo->framesPerBuffer;
@ -1941,7 +1969,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
else
{
outputChannelCount = 0;
outputSampleFormat = 0;
outputSampleFormat = 0;
suggestedOutputLatencyFrames = 0;
}
@ -2022,10 +2050,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
hostInputSampleFormat =
PaUtil_SelectClosestAvailableFormat( nativeInputFormats, inputParameters->sampleFormat );
}
else
{
hostInputSampleFormat = 0;
}
else
{
hostInputSampleFormat = 0;
}
if( outputParameters )
{
@ -2037,9 +2065,9 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaUtil_SelectClosestAvailableFormat( nativeOutputFormats, outputParameters->sampleFormat );
}
else
{
hostOutputSampleFormat = 0;
}
{
hostOutputSampleFormat = 0;
}
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
inputChannelCount, inputSampleFormat, hostInputSampleFormat,
@ -2082,7 +2110,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
#endif
#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 )
{
result = paUnanticipatedHostError;
@ -2482,8 +2510,8 @@ static int TimeSlice( PaWinDsStream *stream )
framesToXfer = numOutFramesReady = bytesEmpty / stream->outputFrameSizeBytes;
/* Check for underflow */
/* 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. */
/* 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. */
if( stream->outputUnderflowCount != previousUnderflowCount )
stream->callbackFlags |= paOutputUnderflow;
@ -2548,8 +2576,8 @@ static int TimeSlice( PaWinDsStream *stream )
if( stream->bufferProcessor.outputChannelCount > 0 )
{
/*
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.
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.
*/
/* timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency; */
timeInfo.outputBufferDacTime = timeInfo.currentTime;
@ -2798,7 +2826,7 @@ static PaError CloseStream( PaStream* s )
#endif
#ifndef PA_WIN_DS_USE_WMME_TIMER
CloseHandle( stream->processingThreadCompleted );
CloseHandle( stream->processingThreadCompleted );
#endif
// Cleanup the sound buffers
@ -2896,7 +2924,7 @@ static PaError StartStream( PaStream *s )
ResetEvent( stream->processingCompleted );
#ifndef PA_WIN_DS_USE_WMME_TIMER
ResetEvent( stream->processingThreadCompleted );
ResetEvent( stream->processingThreadCompleted );
#endif
if( stream->bufferProcessor.inputChannelCount > 0 )
@ -3006,9 +3034,9 @@ static PaError StartStream( PaStream *s )
goto error;
}
#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 )
{
result = paUnanticipatedHostError;
@ -3078,8 +3106,8 @@ static PaError StopStream( PaStream *s )
#else
if( stream->processingThread )
{
if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT )
return paUnanticipatedHostError;
if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT )
return paUnanticipatedHostError;
#ifdef CLOSE_THREAD_HANDLE
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
* Latest Version at: http://www.portaudio.com
* JACK Implementation by Joshua Haberman
@ -232,6 +232,10 @@ typedef struct 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 FALSE 0
@ -492,7 +496,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
* according to the client_name:port_name convention (which is
* enforced by jackd)
* 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 */
while( jack_ports[numPorts] )
++numPorts;
@ -583,7 +587,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
/* ... what are your output ports (that we could input from)? */
clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
NULL, JackPortIsOutput);
JACK_PORT_TYPE_FILTER, JackPortIsOutput);
curDevInfo->maxInputChannels = 0;
curDevInfo->defaultLowInputLatency = 0.;
curDevInfo->defaultHighInputLatency = 0.;
@ -604,7 +608,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
/* ... what are your input ports (that we could output to)? */
clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
NULL, JackPortIsInput);
JACK_PORT_TYPE_FILTER, JackPortIsInput);
curDevInfo->maxOutputChannels = 0;
curDevInfo->defaultLowOutputLatency = 0.;
curDevInfo->defaultHighOutputLatency = 0.;
@ -1235,7 +1239,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
/* Get output ports of our capture device */
snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name );
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++ )
{
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 */
snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name );
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++ )
{
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
* Latest Version at: http://www.portaudio.com
* OSS implementation by:
@ -318,6 +318,13 @@ error:
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,
double *defaultLowLatency, double *defaultHighLatency )
{
@ -327,6 +334,8 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
int devHandle = -1;
int sr;
*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 )
{
@ -354,7 +363,7 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
maxNumChannels = 0;
for( numChannels = 1; numChannels <= 16; numChannels++ )
{
int temp = numChannels;
temp = numChannels;
if( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ) < 0 )
{
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 */
{
/* use most reasonable default value */
int temp = PA_MIN( maxNumChannels, 2 );
ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ), paUnanticipatedHostError );
numChannels = PA_MIN( maxNumChannels, 2 );
ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &numChannels ), paUnanticipatedHostError );
}
/* Get supported sample rate closest to 44100 Hz */
@ -415,9 +424,21 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
}
*maxChannelCount = maxNumChannels;
/* TODO */
*defaultLowLatency = 512. / *defaultSampleRate;
*defaultHighLatency = 2048. / *defaultSampleRate;
/* Attempt to set low latency with 4 frags-per-buffer, 128 frames-per-frag (total buffer 512 frames)
* 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:
if( devHandle >= 0 )
@ -962,13 +983,6 @@ static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *comp
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.
*/
static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long
@ -995,8 +1009,9 @@ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component,
*/
if( framesPerBuffer == paFramesPerBufferUnspecified )
{
bufSz = (unsigned long)(component->latency * sampleRate);
fragSz = bufSz / 4;
/* Aim for 4 fragments in the complete buffer; the latency comes from 3 of these */
fragSz = (unsigned long)(component->latency * sampleRate / 3);
bufSz = fragSz * 4;
}
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
* Implementation of PortAudio for Windows MultiMedia Extensions (WMME)
*
@ -62,7 +62,7 @@
*/
/** @file
@ingroup hostapi_src
@ingroup hostapi_src
@brief Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API.
*/
@ -86,6 +86,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <windows.h>
#include <mmsystem.h>
@ -201,31 +202,52 @@
static const char constInputMapperSuffix_[] = " - Input";
static const char constOutputMapperSuffix_[] = " - Output";
/*
copies TCHAR string to explicit char string
*/
char *StrTCpyToC(char *to, const TCHAR *from)
/********************************************************************/
/* Copy null-terminated TCHAR string to explicit char string using UTF8 encoding */
static char *CopyTCharStringToUtf8CString(char *destination, size_t destLengthBytes, const TCHAR *source)
{
#if !defined(_UNICODE) && !defined(UNICODE)
return strcpy(to, from);
return strcpy(destination, source);
#else
int count = wcslen(from);
if (count != 0)
if (WideCharToMultiByte(CP_ACP, 0, from, count, to, count, NULL, NULL) == 0)
return NULL;
return to;
/* The cbMultiByte parameter ["destLengthBytes" below] is:
"""
Size, in bytes, of the buffer indicated by lpMultiByteStr ["destination" below].
If this parameter is set to 0, the function returns the required buffer
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
}
/*
returns length of TCHAR string
*/
size_t StrTLen(const TCHAR *str)
/* returns required length (in bytes) of destination buffer when
converting TCHAR string to UTF8 bytes, not including the terminating null. */
static size_t TCharStringLen(const TCHAR *str)
{
#if !defined(_UNICODE) && !defined(UNICODE)
return strlen(str);
return strlen(str);
#else
return wcslen(str);
return WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
#endif
}
@ -491,7 +513,7 @@ static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hos
{
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;
WAVEINCAPS wic;
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
size_t len;
*success = 0;
@ -705,31 +728,35 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
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 )
{
len = TCharStringLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_);
/* Append I/O suffix to WAVE_MAPPER device. */
deviceName = (char *)PaUtil_GroupAllocateMemory(
deviceName = (char*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations,
(long) (StrTLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_)) );
(long)len );
if( !deviceName )
{
result = paInsufficientMemory;
goto error;
}
StrTCpyToC( deviceName, wic.szPname );
CopyTCharStringToUtf8CString( deviceName, len, wic.szPname );
strcat( deviceName, constInputMapperSuffix_ );
}
else
{
len = TCharStringLen( wic.szPname ) + 1;
deviceName = (char*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations,
(long) (StrTLen( wic.szPname ) + 1) );
(long)len );
if( !deviceName )
{
result = paInsufficientMemory;
goto error;
}
StrTCpyToC( deviceName, wic.szPname );
CopyTCharStringToUtf8CString( deviceName, len, wic.szPname );
}
deviceInfo->name = deviceName;
@ -811,6 +838,7 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
MMRESULT mmresult;
WAVEOUTCAPS woc;
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
size_t len;
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
int wdmksDeviceOutputChannelCountIsKnown;
#endif
@ -833,31 +861,35 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
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 )
{
/* 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,
(long) (StrTLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_)) );
(long)len );
if( !deviceName )
{
result = paInsufficientMemory;
goto error;
}
StrTCpyToC( deviceName, woc.szPname );
CopyTCharStringToUtf8CString( deviceName, len, woc.szPname );
strcat( deviceName, constOutputMapperSuffix_ );
}
else
{
len = TCharStringLen( woc.szPname ) + 1;
deviceName = (char*)PaUtil_GroupAllocateMemory(
winMmeHostApi->allocations,
(long) (StrTLen( woc.szPname ) + 1) );
(long)len );
if( !deviceName )
{
result = paInsufficientMemory;
goto error;
}
StrTCpyToC( deviceName, woc.szPname );
CopyTCharStringToUtf8CString( deviceName, len, woc.szPname );
}
deviceInfo->name = deviceName;
@ -882,7 +914,7 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
wdmksDeviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels(
winMmeOutputDeviceId, &deviceInfo->maxOutputChannels );
winMmeOutputDeviceId, &deviceInfo->maxOutputChannels );
if( wdmksDeviceOutputChannelCountIsKnown && !winMmeDeviceInfo->deviceOutputChannelCountIsKnown )
winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
@ -901,9 +933,19 @@ error:
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;
osvi.dwOSVersionInfoSize = sizeof( osvi );
GetVersionEx( &osvi );
GetVersionEx( &osvi );
/* Check for NT */
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
@ -920,6 +962,8 @@ static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighL
}
*defaultHighLatency = *defaultLowLatency * 2;
#pragma warning (default : 4996)
}
@ -983,11 +1027,11 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
inputDeviceCount = waveInGetNumDevs();
if( inputDeviceCount > 0 )
maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
outputDeviceCount = waveOutGetNumDevs();
if( outputDeviceCount > 0 )
maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
if( maximumPossibleDeviceCount > 0 ){
@ -2157,29 +2201,29 @@ static PaError ValidateWinMmeSpecificStreamInfo(
char *throttleProcessingThreadOnOverload,
unsigned long *deviceCount )
{
if( streamInfo )
{
if( streamInfo->size != sizeof( PaWinMmeStreamInfo )
|| streamInfo->version != 1 )
{
return paIncompatibleHostApiSpecificStreamInfo;
}
if( streamInfo )
{
if( streamInfo->size != sizeof( PaWinMmeStreamInfo )
|| streamInfo->version != 1 )
{
return paIncompatibleHostApiSpecificStreamInfo;
}
*winMmeSpecificFlags = streamInfo->flags;
if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread )
*throttleProcessingThreadOnOverload = 0;
if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread )
*throttleProcessingThreadOnOverload = 0;
if( streamInfo->flags & paWinMmeUseMultipleDevices )
{
if( streamParameters->device != paUseHostApiSpecificDeviceSpecification )
return paInvalidDevice;
if( streamInfo->flags & paWinMmeUseMultipleDevices )
{
if( streamParameters->device != paUseHostApiSpecificDeviceSpecification )
return paInvalidDevice;
*deviceCount = streamInfo->deviceCount;
}
}
*deviceCount = streamInfo->deviceCount;
}
}
return paNoError;
return paNoError;
}
static PaError RetrieveDevicesFromStreamParameters(
@ -2194,34 +2238,34 @@ static PaError RetrieveDevicesFromStreamParameters(
int totalChannelCount;
PaDeviceIndex hostApiDevice;
if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices )
{
totalChannelCount = 0;
for( i=0; i < deviceCount; ++i )
{
/* validate that the device number is within range */
result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice,
streamInfo->devices[i].device, hostApi );
if( result != paNoError )
return result;
if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices )
{
totalChannelCount = 0;
for( i=0; i < deviceCount; ++i )
{
/* validate that the device number is within range */
result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice,
streamInfo->devices[i].device, hostApi );
if( result != paNoError )
return result;
devices[i].device = hostApiDevice;
devices[i].channelCount = streamInfo->devices[i].channelCount;
devices[i].device = hostApiDevice;
devices[i].channelCount = streamInfo->devices[i].channelCount;
totalChannelCount += devices[i].channelCount;
}
totalChannelCount += devices[i].channelCount;
}
if( totalChannelCount != streamParameters->channelCount )
{
/* channelCount must match total channels specified by multiple devices */
return paInvalidChannelCount; /* REVIEW use of this error code */
}
}
else
{
devices[0].device = streamParameters->device;
devices[0].channelCount = streamParameters->channelCount;
}
if( totalChannelCount != streamParameters->channelCount )
{
/* channelCount must match total channels specified by multiple devices */
return paInvalidChannelCount; /* REVIEW use of this error code */
}
}
else
{
devices[0].device = streamParameters->device;
devices[0].channelCount = streamParameters->channelCount;
}
return result;
}
@ -2235,10 +2279,10 @@ static PaError ValidateInputChannelCounts(
PaWinMmeDeviceInfo *inputDeviceInfo;
PaError paerror;
for( i=0; i < deviceCount; ++i )
{
for( i=0; i < deviceCount; ++i )
{
if( devices[i].channelCount < 1 )
return paInvalidChannelCount;
return paInvalidChannelCount;
inputDeviceInfo =
(PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ];
@ -2246,7 +2290,7 @@ static PaError ValidateInputChannelCounts(
paerror = IsInputChannelCountSupported( inputDeviceInfo, devices[i].channelCount );
if( paerror != paNoError )
return paerror;
}
}
return paNoError;
}
@ -2260,10 +2304,10 @@ static PaError ValidateOutputChannelCounts(
PaWinMmeDeviceInfo *outputDeviceInfo;
PaError paerror;
for( i=0; i < deviceCount; ++i )
{
for( i=0; i < deviceCount; ++i )
{
if( devices[i].channelCount < 1 )
return paInvalidChannelCount;
return paInvalidChannelCount;
outputDeviceInfo =
(PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ];
@ -2271,7 +2315,7 @@ static PaError ValidateOutputChannelCounts(
paerror = IsOutputChannelCountSupported( outputDeviceInfo, devices[i].channelCount );
if( paerror != paNoError )
return paerror;
}
}
return paNoError;
}
@ -2320,28 +2364,28 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
if( inputParameters )
{
inputChannelCount = inputParameters->channelCount;
inputChannelCount = inputParameters->channelCount;
inputSampleFormat = inputParameters->sampleFormat;
suggestedInputLatency = inputParameters->suggestedLatency;
inputDeviceCount = 1;
inputDeviceCount = 1;
/* validate input hostApiSpecificStreamInfo */
/* validate input hostApiSpecificStreamInfo */
inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo,
result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo,
&winMmeSpecificInputFlags,
&throttleProcessingThreadOnOverload,
&inputDeviceCount );
if( result != paNoError ) return result;
&throttleProcessingThreadOnOverload,
&inputDeviceCount );
if( result != paNoError ) return result;
inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount );
inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount );
if( !inputDevices ) return paInsufficientMemory;
result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount );
if( result != paNoError ) return result;
result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount );
if( result != paNoError ) return result;
result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount );
if( result != paNoError ) return result;
result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount );
if( result != paNoError ) return result;
hostInputSampleFormat =
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
@ -2357,7 +2401,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
else
inputChannelMask = PaWin_DefaultChannelMask( inputDevices[0].channelCount );
}
}
}
else
{
inputChannelCount = 0;
@ -2376,22 +2420,22 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
outputDeviceCount = 1;
/* validate output hostApiSpecificStreamInfo */
/* validate output hostApiSpecificStreamInfo */
outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo,
result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo,
&winMmeSpecificOutputFlags,
&throttleProcessingThreadOnOverload,
&outputDeviceCount );
if( result != paNoError ) return result;
&throttleProcessingThreadOnOverload,
&outputDeviceCount );
if( result != paNoError ) return result;
outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount );
outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount );
if( !outputDevices ) return paInsufficientMemory;
result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount );
if( result != paNoError ) return result;
result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount );
if( result != paNoError ) return result;
result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount );
if( result != paNoError ) return result;
result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount );
if( result != paNoError ) return result;
hostOutputSampleFormat =
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
@ -3219,9 +3263,9 @@ static PaError StartStream( PaStream *s )
MMRESULT mmresult;
unsigned int i, j;
int callbackResult;
unsigned int channel;
unsigned long framesProcessed;
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */
unsigned int channel;
unsigned long framesProcessed;
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );

View File

@ -66,33 +66,34 @@
#include "pa_util.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)\
(!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))
static PaError WdmGetPinPropertySimple(
HANDLE handle,
unsigned long pinId,

View File

@ -112,6 +112,18 @@ TODO:
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*/
@ -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(
void *destinationBuffer, signed int destinationStride,
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}