mirror of https://github.com/PCSX2/pcsx2.git
SPU2-X:
Update Portaudio to revision 1826. Hope the Linux side is fine :p git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5153 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
49f4168974
commit
28de2a04c6
|
@ -0,0 +1,344 @@
|
|||
# $Id: $
|
||||
#
|
||||
# For a "How-To" please refer to the Portaudio documentation at:
|
||||
# http://www.portaudio.com/trac/wiki/TutorialDir/Compile/CMake
|
||||
#
|
||||
PROJECT( portaudio )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
OPTION(PA_CONFIG_LIB_OUTPUT_PATH "Make sure that output paths are kept neat" OFF)
|
||||
IF(CMAKE_CL_64)
|
||||
SET(TARGET_POSTFIX x64)
|
||||
IF(PA_CONFIG_LIB_OUTPUT_PATH)
|
||||
SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin/x64)
|
||||
ENDIF(PA_CONFIG_LIB_OUTPUT_PATH)
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(TARGET_POSTFIX x86)
|
||||
IF(PA_CONFIG_LIB_OUTPUT_PATH)
|
||||
SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin/Win32)
|
||||
ENDIF(PA_CONFIG_LIB_OUTPUT_PATH)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
IF(WIN32 AND MSVC)
|
||||
OPTION(PA_DLL_LINK_WITH_STATIC_RUNTIME "Link with static runtime libraries (minimizes runtime dependencies)" ON)
|
||||
IF(PA_DLL_LINK_WITH_STATIC_RUNTIME)
|
||||
FOREACH(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
IF(${flag_var} MATCHES "/MD")
|
||||
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
ENDIF(${flag_var} MATCHES "/MD")
|
||||
ENDFOREACH(flag_var)
|
||||
ENDIF(PA_DLL_LINK_WITH_STATIC_RUNTIME)
|
||||
|
||||
ENDIF(WIN32 AND MSVC)
|
||||
|
||||
IF(WIN32)
|
||||
OPTION(PA_UNICODE_BUILD "Enable Portaudio Unicode build" ON)
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_support)
|
||||
# Try to find DirectX SDK
|
||||
FIND_PACKAGE(DXSDK)
|
||||
# Try to find ASIO SDK (assumes that portaudio and asiosdk folders are side-by-side, see
|
||||
# http://www.portaudio.com/trac/wiki/TutorialDir/Compile/WindowsASIOMSVC)
|
||||
FIND_PACKAGE(ASIOSDK)
|
||||
|
||||
IF(ASIOSDK_FOUND)
|
||||
OPTION(PA_USE_ASIO "Enable support for ASIO" ON)
|
||||
ELSE(ASIOSDK_FOUND)
|
||||
OPTION(PA_USE_ASIO "Enable support for ASIO" OFF)
|
||||
ENDIF(ASIOSDK_FOUND)
|
||||
IF(DXSDK_FOUND)
|
||||
OPTION(PA_USE_DS "Enable support for DirectSound" ON)
|
||||
ELSE(DXSDK_FOUND)
|
||||
OPTION(PA_USE_DS "Enable support for DirectSound" OFF)
|
||||
ENDIF(DXSDK_FOUND)
|
||||
OPTION(PA_USE_WMME "Enable support for MME" ON)
|
||||
OPTION(PA_USE_WASAPI "Enable support for WASAPI" ON)
|
||||
OPTION(PA_USE_WDMKS "Enable support for WDMKS" ON)
|
||||
OPTION(PA_USE_WDMKS_DEVICE_INFO "Use WDM/KS API for device info" ON)
|
||||
MARK_AS_ADVANCED(PA_USE_WDMKS_DEVICE_INFO)
|
||||
IF(PA_USE_DS)
|
||||
OPTION(PA_USE_DIRECTSOUNDFULLDUPLEXCREATE "Use DirectSound full duplex create" ON)
|
||||
MARK_AS_ADVANCED(PA_USE_DIRECTSOUNDFULLDUPLEXCREATE)
|
||||
ENDIF(PA_USE_DS)
|
||||
ENDIF(WIN32)
|
||||
|
||||
# Set variables for DEF file expansion
|
||||
IF(NOT PA_USE_ASIO)
|
||||
SET(DEF_EXCLUDE_ASIO_SYMBOLS ";")
|
||||
ENDIF(NOT PA_USE_ASIO)
|
||||
|
||||
IF(NOT PA_USE_WASAPI)
|
||||
SET(DEF_EXCLUDE_WASAPI_SYMBOLS ";")
|
||||
ENDIF(NOT PA_USE_WASAPI)
|
||||
|
||||
IF(PA_USE_WDMKS_DEVICE_INFO)
|
||||
ADD_DEFINITIONS(-DPAWIN_USE_WDMKS_DEVICE_INFO)
|
||||
ENDIF(PA_USE_WDMKS_DEVICE_INFO)
|
||||
|
||||
IF(PA_USE_DIRECTSOUNDFULLDUPLEXCREATE)
|
||||
ADD_DEFINITIONS(-DPAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE)
|
||||
ENDIF(PA_USE_DIRECTSOUNDFULLDUPLEXCREATE)
|
||||
|
||||
#######################################
|
||||
IF(WIN32)
|
||||
INCLUDE_DIRECTORIES(src/os/win)
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(PA_USE_ASIO)
|
||||
INCLUDE_DIRECTORIES(${ASIOSDK_ROOT_DIR}/common)
|
||||
INCLUDE_DIRECTORIES(${ASIOSDK_ROOT_DIR}/host)
|
||||
INCLUDE_DIRECTORIES(${ASIOSDK_ROOT_DIR}/host/pc)
|
||||
|
||||
SET(PA_ASIO_INCLUDES
|
||||
include/pa_asio.h
|
||||
)
|
||||
|
||||
SET(PA_ASIO_SOURCES
|
||||
src/hostapi/asio/pa_asio.cpp
|
||||
)
|
||||
|
||||
SET(PA_ASIOSDK_SOURCES
|
||||
${ASIOSDK_ROOT_DIR}/common/asio.cpp
|
||||
${ASIOSDK_ROOT_DIR}/host/pc/asiolist.cpp
|
||||
${ASIOSDK_ROOT_DIR}/host/asiodrivers.cpp
|
||||
)
|
||||
|
||||
SOURCE_GROUP("hostapi\\ASIO" FILES
|
||||
${PA_ASIO_SOURCES}
|
||||
)
|
||||
|
||||
SOURCE_GROUP("hostapi\\ASIO\\ASIOSDK" FILES
|
||||
${PA_ASIOSDK_SOURCES}
|
||||
)
|
||||
ENDIF(PA_USE_ASIO)
|
||||
|
||||
IF(PA_USE_DS)
|
||||
INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR})
|
||||
INCLUDE_DIRECTORIES(src/os/win)
|
||||
|
||||
SET(PA_DS_INCLUDES
|
||||
include/pa_win_ds.h
|
||||
src/hostapi/dsound/pa_win_ds_dynlink.h
|
||||
)
|
||||
|
||||
SET(PA_DS_SOURCES
|
||||
src/hostapi/dsound/pa_win_ds.c
|
||||
src/hostapi/dsound/pa_win_ds_dynlink.c
|
||||
)
|
||||
|
||||
SOURCE_GROUP("hostapi\\dsound" FILES
|
||||
${PA_DS_INCLUDES}
|
||||
${PA_DS_SOURCES}
|
||||
)
|
||||
ENDIF(PA_USE_DS)
|
||||
|
||||
IF(PA_USE_WMME)
|
||||
|
||||
SET(PA_WMME_INCLUDES
|
||||
include/pa_win_wmme.h
|
||||
)
|
||||
|
||||
SET(PA_WMME_SOURCES
|
||||
src/hostapi/wmme/pa_win_wmme.c
|
||||
)
|
||||
|
||||
SOURCE_GROUP("hostapi\\wmme" FILES
|
||||
${PA_WMME_SOURCES}
|
||||
)
|
||||
ENDIF(PA_USE_WMME)
|
||||
|
||||
IF(PA_USE_WASAPI)
|
||||
|
||||
SET(PA_WASAPI_INCLUDES
|
||||
include/pa_win_wasapi.h
|
||||
)
|
||||
|
||||
SET(PA_WASAPI_SOURCES
|
||||
src/hostapi/wasapi/pa_win_wasapi.c
|
||||
)
|
||||
|
||||
SOURCE_GROUP("hostapi\\wasapi" FILES
|
||||
${PA_WASAPI_SOURCES}
|
||||
)
|
||||
ENDIF(PA_USE_WASAPI)
|
||||
|
||||
IF(PA_USE_WDMKS)
|
||||
|
||||
SET(PA_WDMKS_INCLUDES
|
||||
include/pa_win_wdmks.h
|
||||
)
|
||||
|
||||
SET(PA_WDMKS_SOURCES
|
||||
src/hostapi/wdmks/pa_win_wdmks.c
|
||||
)
|
||||
|
||||
SOURCE_GROUP("hostapi\\wdmks" FILES
|
||||
${PA_WDMKS_SOURCES}
|
||||
)
|
||||
ENDIF(PA_USE_WDMKS)
|
||||
|
||||
SET(PA_SKELETON_SOURCES
|
||||
src/hostapi/skeleton/pa_hostapi_skeleton.c
|
||||
)
|
||||
|
||||
SOURCE_GROUP("hostapi\\skeleton"
|
||||
${PA_SKELETON_SOURCES})
|
||||
|
||||
#######################################
|
||||
IF(WIN32)
|
||||
SET(PA_INCLUDES
|
||||
include/portaudio.h
|
||||
${PA_ASIO_INCLUDES}
|
||||
${PA_DS_INCLUDES}
|
||||
${PA_WMME_INCLUDES}
|
||||
${PA_WASAPI_INCLUDES}
|
||||
${PA_WDMKS_INCLUDES}
|
||||
)
|
||||
ENDIF(WIN32)
|
||||
|
||||
SOURCE_GROUP("include" FILES
|
||||
${PA_INCLUDES}
|
||||
)
|
||||
|
||||
SET(PA_COMMON_INCLUDES
|
||||
src/common/pa_allocation.h
|
||||
src/common/pa_converters.h
|
||||
src/common/pa_cpuload.h
|
||||
src/common/pa_debugprint.h
|
||||
src/common/pa_dither.h
|
||||
src/common/pa_endianness.h
|
||||
src/common/pa_hostapi.h
|
||||
src/common/pa_memorybarrier.h
|
||||
src/common/pa_process.h
|
||||
src/common/pa_ringbuffer.h
|
||||
src/common/pa_stream.h
|
||||
src/common/pa_trace.h
|
||||
src/common/pa_types.h
|
||||
src/common/pa_util.h
|
||||
)
|
||||
|
||||
SET(PA_COMMON_SOURCES
|
||||
src/common/pa_allocation.c
|
||||
src/common/pa_converters.c
|
||||
src/common/pa_cpuload.c
|
||||
src/common/pa_debugprint.c
|
||||
src/common/pa_dither.c
|
||||
src/common/pa_front.c
|
||||
src/common/pa_process.c
|
||||
src/common/pa_ringbuffer.c
|
||||
src/common/pa_stream.c
|
||||
src/common/pa_trace.c
|
||||
)
|
||||
|
||||
SOURCE_GROUP("common" FILES
|
||||
${PA_COMMON_INCLUDES}
|
||||
${PA_COMMON_SOURCES}
|
||||
)
|
||||
|
||||
SOURCE_GROUP("cmake_generated" FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/portaudio_cmake.def
|
||||
${CMAKE_CURRENT_BINARY_DIR}/options_cmake.h
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
SET(PA_PLATFORM_SOURCES
|
||||
src/os/win/pa_win_hostapis.c
|
||||
src/os/win/pa_win_util.c
|
||||
src/os/win/pa_win_waveformat.c
|
||||
src/os/win/pa_win_wdmks_utils.c
|
||||
src/os/win/pa_win_coinitialize.c
|
||||
src/os/win/pa_x86_plain_converters.c
|
||||
)
|
||||
|
||||
SOURCE_GROUP("os\\win" FILES
|
||||
${PA_PLATFORM_SOURCES}
|
||||
)
|
||||
ENDIF(WIN32)
|
||||
|
||||
INCLUDE_DIRECTORIES( include )
|
||||
INCLUDE_DIRECTORIES( src/common )
|
||||
|
||||
IF(WIN32 AND MSVC)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ENDIF(WIN32 AND MSVC)
|
||||
|
||||
ADD_DEFINITIONS(-DPORTAUDIO_CMAKE_GENERATED)
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
|
||||
SET(SOURCES_LESS_ASIO_SDK
|
||||
${PA_COMMON_SOURCES}
|
||||
${PA_ASIO_SOURCES}
|
||||
${PA_DS_SOURCES}
|
||||
${PA_WMME_SOURCES}
|
||||
${PA_WASAPI_SOURCES}
|
||||
${PA_WDMKS_SOURCES}
|
||||
${PA_SKELETON_SOURCES}
|
||||
${PA_PLATFORM_SOURCES}
|
||||
)
|
||||
|
||||
IF(PA_UNICODE_BUILD)
|
||||
SET_SOURCE_FILES_PROPERTIES(
|
||||
${SOURCES_LESS_ASIO_SDK}
|
||||
PROPERTIES
|
||||
COMPILE_DEFINITIONS "UNICODE;_UNICODE"
|
||||
)
|
||||
ENDIF(PA_UNICODE_BUILD)
|
||||
|
||||
ADD_LIBRARY(portaudio SHARED
|
||||
${PA_INCLUDES}
|
||||
${PA_COMMON_INCLUDES}
|
||||
${SOURCES_LESS_ASIO_SDK}
|
||||
${PA_ASIOSDK_SOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/portaudio_cmake.def
|
||||
${CMAKE_CURRENT_BINARY_DIR}/options_cmake.h
|
||||
)
|
||||
|
||||
ADD_LIBRARY(portaudio_static STATIC
|
||||
${PA_INCLUDES}
|
||||
${PA_COMMON_INCLUDES}
|
||||
${SOURCES_LESS_ASIO_SDK}
|
||||
${PA_ASIOSDK_SOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/options_cmake.h
|
||||
)
|
||||
|
||||
# Configure the exports file according to settings
|
||||
SET(GENERATED_MESSAGE "CMake generated file, do NOT edit! Use CMake-GUI to change configuration instead.")
|
||||
CONFIGURE_FILE( cmake_support/template_portaudio.def ${CMAKE_CURRENT_BINARY_DIR}/portaudio_cmake.def @ONLY )
|
||||
# Configure header for options (PA_USE_xxx)
|
||||
CONFIGURE_FILE( cmake_support/options_cmake.h.in ${CMAKE_CURRENT_BINARY_DIR}/options_cmake.h @ONLY )
|
||||
|
||||
IF(WIN32)
|
||||
# If we use DirectSound, we need this for the library to be found (if not in VS project settings)
|
||||
IF(PA_USE_DS AND DXSDK_FOUND)
|
||||
TARGET_LINK_LIBRARIES(portaudio ${DXSDK_DSOUND_LIBRARY})
|
||||
ENDIF(PA_USE_DS AND DXSDK_FOUND)
|
||||
|
||||
# If we use WDM/KS we need setupapi.lib
|
||||
IF(PA_USE_WDMKS)
|
||||
TARGET_LINK_LIBRARIES(portaudio setupapi)
|
||||
ENDIF(PA_USE_WDMKS)
|
||||
|
||||
SET_TARGET_PROPERTIES(portaudio PROPERTIES OUTPUT_NAME portaudio_${TARGET_POSTFIX})
|
||||
SET_TARGET_PROPERTIES(portaudio_static PROPERTIES OUTPUT_NAME portaudio_static_${TARGET_POSTFIX})
|
||||
ENDIF(WIN32)
|
||||
|
||||
OPTION(PA_BUILD_TESTS "Include test projects" OFF)
|
||||
OPTION(PA_BUILD_EXAMPLES "Include example projects" OFF)
|
||||
|
||||
# Prepared for inclusion of test files
|
||||
IF(PA_BUILD_TESTS)
|
||||
SUBDIRS(test)
|
||||
ENDIF(PA_BUILD_TESTS)
|
||||
|
||||
# Prepared for inclusion of test files
|
||||
IF(PA_BUILD_EXAMPLES)
|
||||
SUBDIRS(examples)
|
||||
ENDIF(PA_BUILD_EXAMPLES)
|
||||
|
||||
#################################
|
||||
|
|
@ -942,6 +942,10 @@
|
|||
RelativePath="..\..\include\pa_win_waveformat.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\pa_win_wdmks.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\pa_win_wmme.h"
|
||||
>
|
||||
|
|
|
@ -639,6 +639,7 @@
|
|||
<ClInclude Include="..\..\include\pa_win_ds.h" />
|
||||
<ClInclude Include="..\..\include\pa_win_wasapi.h" />
|
||||
<ClInclude Include="..\..\include\pa_win_waveformat.h" />
|
||||
<ClInclude Include="..\..\include\pa_win_wdmks.h" />
|
||||
<ClInclude Include="..\..\include\pa_win_wmme.h" />
|
||||
<ClInclude Include="..\..\include\portaudio.h" />
|
||||
<ClInclude Include="..\..\src\os\win\pa_win_coinitialize.h" />
|
||||
|
|
|
@ -175,5 +175,8 @@
|
|||
<ClInclude Include="..\..\src\os\win\pa_win_coinitialize.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\pa_win_wdmks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,41 @@
|
|||
# $Id: $
|
||||
#
|
||||
# - Try to find the ASIO SDK
|
||||
# Once done this will define
|
||||
#
|
||||
# ASIOSDK_FOUND - system has ASIO SDK
|
||||
# ASIOSDK_ROOT_DIR - path to the ASIO SDK base directory
|
||||
# ASIOSDK_INCLUDE_DIR - the ASIO SDK include directory
|
||||
|
||||
if(WIN32)
|
||||
else(WIN32)
|
||||
message(FATAL_ERROR "FindASIOSDK.cmake: Unsupported platform ${CMAKE_SYSTEM_NAME}" )
|
||||
endif(WIN32)
|
||||
|
||||
file(GLOB results "${CMAKE_CURRENT_SOURCE_DIR}/../as*")
|
||||
foreach(f ${results})
|
||||
if(IS_DIRECTORY ${f})
|
||||
set(ASIOSDK_PATH_HINT ${ASIOSDK_PATH_HINT} ${f})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
find_path(ASIOSDK_ROOT_DIR
|
||||
common/asio.h
|
||||
HINTS
|
||||
${ASIOSDK_PATH_HINT}
|
||||
)
|
||||
|
||||
find_path(ASIOSDK_INCLUDE_DIR
|
||||
asio.h
|
||||
PATHS
|
||||
${ASIOSDK_ROOT_DIR}/common
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set ASIOSDK_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ASIOSDK DEFAULT_MSG ASIOSDK_ROOT_DIR ASIOSDK_INCLUDE_DIR)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
ASIOSDK_ROOT_DIR ASIOSDK_INCLUDE_DIR
|
||||
)
|
|
@ -0,0 +1,59 @@
|
|||
# $Id: $
|
||||
#
|
||||
# - Try to find the DirectX SDK
|
||||
# Once done this will define
|
||||
#
|
||||
# DXSDK_FOUND - system has DirectX SDK
|
||||
# DXSDK_ROOT_DIR - path to the DirectX SDK base directory
|
||||
# DXSDK_INCLUDE_DIR - the DirectX SDK include directory
|
||||
# DXSDK_LIBRARY_DIR - DirectX SDK libraries path
|
||||
#
|
||||
# DXSDK_DSOUND_LIBRARY - Path to dsound.lib
|
||||
#
|
||||
|
||||
if(WIN32)
|
||||
else(WIN32)
|
||||
message(FATAL_ERROR "FindDXSDK.cmake: Unsupported platform ${CMAKE_SYSTEM_NAME}" )
|
||||
endif(WIN32)
|
||||
|
||||
find_path(DXSDK_ROOT_DIR
|
||||
include/dxsdkver.h
|
||||
HINTS
|
||||
$ENV{DXSDK_DIR}
|
||||
)
|
||||
|
||||
find_path(DXSDK_INCLUDE_DIR
|
||||
dxsdkver.h
|
||||
PATHS
|
||||
${DXSDK_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
IF(CMAKE_CL_64)
|
||||
find_path(DXSDK_LIBRARY_DIR
|
||||
dsound.lib
|
||||
PATHS
|
||||
${DXSDK_ROOT_DIR}/lib/x64
|
||||
)
|
||||
ELSE(CMAKE_CL_64)
|
||||
find_path(DXSDK_LIBRARY_DIR
|
||||
dsound.lib
|
||||
PATHS
|
||||
${DXSDK_ROOT_DIR}/lib/x86
|
||||
)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
find_library(DXSDK_DSOUND_LIBRARY
|
||||
dsound.lib
|
||||
PATHS
|
||||
${DXSDK_LIBRARY_DIR}
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set DXSDK_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DXSDK DEFAULT_MSG DXSDK_ROOT_DIR DXSDK_INCLUDE_DIR)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
DXSDK_ROOT_DIR DXSDK_INCLUDE_DIR
|
||||
DXSDK_LIBRARY_DIR DXSDK_DSOUND_LIBRARY
|
||||
)
|
|
@ -0,0 +1,31 @@
|
|||
/* $Id: $
|
||||
|
||||
!!! @GENERATED_MESSAGE@ !!!
|
||||
|
||||
Header file configured by CMake to convert CMake options/vars to macros. It is done this way because if set via
|
||||
preprocessor options, MSVC f.i. has no way of knowing when an option (or var) changes as there is no dependency chain.
|
||||
|
||||
The generated "options_cmake.h" should be included like so:
|
||||
|
||||
#ifdef PORTAUDIO_CMAKE_GENERATED
|
||||
#include "options_cmake.h"
|
||||
#endif
|
||||
|
||||
so that non-CMake build environments are left intact.
|
||||
|
||||
Source template: cmake_support/options_cmake.h.in
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(PA_USE_ASIO) || defined(PA_USE_DS) || defined(PA_USE_WMME) || defined(PA_USE_WASAPI) || defined(PA_USE_WDMKS)
|
||||
#error "This header needs to be included before pa_hostapi.h!!"
|
||||
#endif
|
||||
|
||||
#cmakedefine01 PA_USE_ASIO
|
||||
#cmakedefine01 PA_USE_DS
|
||||
#cmakedefine01 PA_USE_WMME
|
||||
#cmakedefine01 PA_USE_WASAPI
|
||||
#cmakedefine01 PA_USE_WDMKS
|
||||
#else
|
||||
#error "Platform currently not supported by CMake script"
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
; $Id: $
|
||||
;
|
||||
; !!! @GENERATED_MESSAGE@ !!!
|
||||
EXPORTS
|
||||
|
||||
;
|
||||
Pa_GetVersion @1
|
||||
Pa_GetVersionText @2
|
||||
Pa_GetErrorText @3
|
||||
Pa_Initialize @4
|
||||
Pa_Terminate @5
|
||||
Pa_GetHostApiCount @6
|
||||
Pa_GetDefaultHostApi @7
|
||||
Pa_GetHostApiInfo @8
|
||||
Pa_HostApiTypeIdToHostApiIndex @9
|
||||
Pa_HostApiDeviceIndexToDeviceIndex @10
|
||||
Pa_GetLastHostErrorInfo @11
|
||||
Pa_GetDeviceCount @12
|
||||
Pa_GetDefaultInputDevice @13
|
||||
Pa_GetDefaultOutputDevice @14
|
||||
Pa_GetDeviceInfo @15
|
||||
Pa_IsFormatSupported @16
|
||||
Pa_OpenStream @17
|
||||
Pa_OpenDefaultStream @18
|
||||
Pa_CloseStream @19
|
||||
Pa_SetStreamFinishedCallback @20
|
||||
Pa_StartStream @21
|
||||
Pa_StopStream @22
|
||||
Pa_AbortStream @23
|
||||
Pa_IsStreamStopped @24
|
||||
Pa_IsStreamActive @25
|
||||
Pa_GetStreamInfo @26
|
||||
Pa_GetStreamTime @27
|
||||
Pa_GetStreamCpuLoad @28
|
||||
Pa_ReadStream @29
|
||||
Pa_WriteStream @30
|
||||
Pa_GetStreamReadAvailable @31
|
||||
Pa_GetStreamWriteAvailable @32
|
||||
Pa_GetSampleSize @33
|
||||
Pa_Sleep @34
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetAvailableBufferSizes @50
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_ShowControlPanel @51
|
||||
PaUtil_InitializeX86PlainConverters @52
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetInputChannelName @53
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetOutputChannelName @54
|
||||
PaUtil_SetDebugPrintFunction @55
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetDeviceDefaultFormat @56
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetDeviceRole @57
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_ThreadPriorityBoost @58
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_ThreadPriorityRevert @59
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetFramesPerHostBuffer @60
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetJackDescription @61
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetJackCount @62
|
|
@ -11,7 +11,7 @@ PortAudio is a cross-platform, open-source C language library for real-time audi
|
|||
- @ref api_overview<br>
|
||||
A top-down view of the PortAudio API, its capabilities, functions and data structures
|
||||
|
||||
- <a href="http://www.portaudio.com/trac/wiki/TutorialDir/TutorialStart">PortAudio Tutorials</a><br>
|
||||
- @ref tutorial_start<br>
|
||||
Get started writing code with PortAudio tutorials
|
||||
|
||||
- @ref examples_src "Examples"<br>
|
||||
|
@ -36,7 +36,7 @@ Documentation for non-portable platform-specific host API extensions
|
|||
|
||||
- <a href="http://music.columbia.edu/mailman/listinfo/portaudio/">Our mailing list for users and developers</a><br>
|
||||
|
||||
- <a href="http://www.portaudio.com/trac">The PortAudio wiki</a>
|
||||
- <a href="http://www.assembla.com/spaces/portaudio/wiki">The PortAudio wiki</a>
|
||||
|
||||
|
||||
@section developer_resources Developer Resources
|
||||
|
@ -45,11 +45,11 @@ Documentation for non-portable platform-specific host API extensions
|
|||
- @ref srcguide
|
||||
@endif
|
||||
|
||||
- <a href="http://www.portaudio.com/trac">Our Trac wiki and issue tracking system</a>
|
||||
- <a href="http://www.assembla.com/spaces/portaudio/wiki">Our wiki and issue tracking system</a>
|
||||
|
||||
- <a href="http://www.portaudio.com/docs/proposals/014-StyleGuide.html">Coding guidelines</a>
|
||||
|
||||
If you're interested in helping out with PortAudio development we're more than happy for you to be involved. Just drop by the PortAudio mailing list and ask how you can help. Or <a href="http://www.portaudio.com/trac/report/3">check out the starter tickets in Trac</a>.
|
||||
If you're interested in helping out with PortAudio development we're more than happy for you to be involved. Just drop by the PortAudio mailing list and ask how you can help. Or <a href="http://www.assembla.com/spaces/portaudio/tickets">check out the starter tickets</a>.
|
||||
|
||||
|
||||
@section older_api_versions Older API Versions
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/** @page blocking_read_write Blocking Read/Write Functions
|
||||
@ingroup tutorial
|
||||
|
||||
PortAudio V19 adds a huge advance over previous versions with a feature called Blocking I/O. Although it may have lower performance that the callback method described earlier in this tutorial, blocking I/O is easier to understand and is, in some cases, more compatible with third party systems than the callback method. Most people starting audio programming also find Blocking I/O easier to learn.
|
||||
|
||||
Blocking I/O works in much the same way as the callback method except that instead of providing a function to provide (or consume) audio data, you must feed data to (or consume data from) PortAudio at regular intervals, usually inside a loop. The example below, excepted from patest_read_write_wire.c, shows how to open the default device, and pass data from its input to its output for a set period of time. Note that we use the default high latency values to help avoid underruns since we are usually reading and writing audio data from a relatively low priority thread, and there is usually extra buffering required to make blocking I/O work.
|
||||
|
||||
Note that not all API's implement Blocking I/O at this point, so for maximum portability or performance, you'll still want to use callbacks.
|
||||
|
||||
@code
|
||||
/* -- initialize PortAudio -- */
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* -- setup input and output -- */
|
||||
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
|
||||
inputParameters.channelCount = NUM_CHANNELS;
|
||||
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
|
||||
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
outputParameters.channelCount = NUM_CHANNELS;
|
||||
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
/* -- setup stream -- */
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
NULL, /* no callback, use blocking API */
|
||||
NULL ); /* no callback, so no callback userData */
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* -- start stream -- */
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Wire on. Will run one minute.\n"); fflush(stdout);
|
||||
|
||||
/* -- Here's the loop where we pass data from input to output -- */
|
||||
for( i=0; i<(60*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i )
|
||||
{
|
||||
err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
|
||||
if( err ) goto xrun;
|
||||
err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
|
||||
if( err ) goto xrun;
|
||||
}
|
||||
/* -- Now we stop the stream -- */
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* -- don't forget to cleanup! -- */
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
return 0;
|
||||
@endcode
|
||||
|
||||
|
||||
Previous: \ref querying_devices | Next: \ref exploring
|
||||
|
||||
*/
|
|
@ -0,0 +1,29 @@
|
|||
/** @page compile_cmake Creating MSVC Build Files via CMake
|
||||
@ingroup tutorial
|
||||
|
||||
This is a simple "How-to" for creating build files for Microsoft Visual C++ via CMake and the CMakeLists.txt file
|
||||
|
||||
1. Install CMake if you haven't got it already ([http://www.cmake.org], minimum version required is 2.8).
|
||||
|
||||
2. If you want ASIO support you need to D/L the ASIO2 SDK from Steinberg, and place it according to \ref compile_windows_asio_msvc
|
||||
|
||||
3. Run the CMake GUI application and browse to <b>source files</b> directory and <b>build</b> directory:
|
||||
a. The <b>source files</b> directory (<i>"Where is the source code"</i>) is where the portaudio CMakeLists.txt file is located.
|
||||
b. The <b>build</b> directory (<i>"Where to build the binaries"</i>) is pretty much anywhere you like. A common practice though is to have the build directory located <b>outside</b> the
|
||||
source files tree (a so called "out-of-source build")
|
||||
|
||||
4. Click <i>Configure</i>. This will prompt you to select which build files to generate. <b>Note</b> Only Microsoft Visual C++ build files currently supported!
|
||||
|
||||
5. In the CMake option list, enable the PORTAUDIO_xxx options you need, then click <i>Configure</i> again (Note that after this there are no options marked with red color)
|
||||
|
||||
6. Click <i>Generate</i> and you'll now (hopefully) have your VS build files in your previously defined <b>build</b> directory.
|
||||
|
||||
Both ASIO and DirectX SDK are automatically searched for by the CMake script, so if you have DirectX SDK installed and have placed the ASIO2 SDK according to point 2 above, you should be able to build portaudio with !DirectSound and ASIO support.
|
||||
|
||||
Should you later on decide to change a portaudio option, just jump in at step 5 above (MSVC will then prompt you to reload projects/solutions/workspace)
|
||||
|
||||
--- Robert Bielik
|
||||
|
||||
Back to the Tutorial: \ref tutorial_start
|
||||
|
||||
*/
|
|
@ -0,0 +1,77 @@
|
|||
/** @page compile_linux Building Portaudio for Linux
|
||||
@ingroup tutorial
|
||||
|
||||
<i>Note: this page has not been reviewed, and may contain errors.</i>
|
||||
|
||||
@section comp_linux1 Installing ALSA Development Kit
|
||||
|
||||
The OSS sound API is very old and not well supported. It is recommended that you use the ALSA sound API.
|
||||
The PortAudio configure script will look for the ALSA SDK. You can install the ALSA SDK on Ubuntu using:
|
||||
|
||||
@code
|
||||
sudo apt-get install libasound-dev
|
||||
@endcode
|
||||
|
||||
You might need to use yum, or some other package manager, instead of apt-get on your machine.
|
||||
If you do not install ALSA then you might get a message when testing that says you have no audio devices.
|
||||
|
||||
You can find out more about ALSA here: http://www.alsa-project.org/
|
||||
|
||||
@section comp_linux2 Configuring and Compiling PortAudio
|
||||
|
||||
You can build PortAudio in Linux Environments using the standard configure/make tools:
|
||||
|
||||
@code
|
||||
./configure && make
|
||||
@endcode
|
||||
|
||||
That will build PortAudio using Jack, ALSA and OSS in whatever combination they are found on your system. For example, if you have Jack and OSS but not ALSA, it will build using Jack and OSS but not ALSA. This step also builds a number of tests, which can be found in the bin directory of PortAudio. It's a good idea to run some of these tests to make sure PortAudio is working correctly.
|
||||
|
||||
@section comp_linux3 Using PortAudio in your Projects
|
||||
|
||||
To use PortAudio in your apps, you can simply install the .so files:
|
||||
|
||||
@code
|
||||
make install
|
||||
@endcode
|
||||
|
||||
Projects built this way will expect PortAudio to be installed on target systems in order to run. If you want to build a more self-contained binary, you may use the libportaudio.a file:
|
||||
|
||||
@code
|
||||
cp lib/.libs/libportaudio.a /YOUR/PROJECT/DIR
|
||||
@endcode
|
||||
|
||||
You may also need to copy portaudio.h, located in the include/ directory of PortAudio into your project. Note that you will usually need to link with the approriate libraries that you used, such as ALSA and JACK, as well as with librt and libpthread. For example:
|
||||
|
||||
@code
|
||||
gcc -lrt -lasound -ljack -lpthread -o YOUR_BINARY main.c libportaudio.a
|
||||
@endcode
|
||||
|
||||
@section comp_linux4 Linux Extensions
|
||||
|
||||
Note that the ALSA PortAudio back-end adds a few extensions to the standard API that you may take advantage of. To use these functions be sure to include the pa_linux_alsa.h file found in the include file in the PortAudio folder. This file contains further documentation on the following functions:
|
||||
|
||||
PaAlsaStreamInfo/PaAlsa_InitializeStreamInfo::
|
||||
Objects of the !PaAlsaStreamInfo type may be used for the !hostApiSpecificStreamInfo attribute of a !PaStreamParameters object, in order to specify the name of an ALSA device to open directly. Specify the device via !PaAlsaStreamInfo.deviceString, after initializing the object with PaAlsa_InitializeStreamInfo.
|
||||
|
||||
PaAlsa_EnableRealtimeScheduling::
|
||||
PA ALSA supports real-time scheduling of the audio callback thread (using the FIFO pthread scheduling policy), via the extension PaAlsa_EnableRealtimeScheduling. Call this on the stream before starting it with the <i>enableScheduling</i> parameter set to true or false, to enable or disable this behaviour respectively.
|
||||
|
||||
PaAlsa_GetStreamInputCard::
|
||||
Use this function to get the ALSA-lib card index of the stream's input device.
|
||||
|
||||
PaAlsa_GetStreamOutputCard::
|
||||
Use this function to get the ALSA-lib card index of the stream's output device.
|
||||
|
||||
Of particular importance is PaAlsa_EnableRealtimeScheduling, which allows ALSA to run at a high priority to prevent ordinary processes on the system from preempting audio playback. Without this, low latency audio playback will be irregular and will contain frequent drop-outs.
|
||||
|
||||
@section comp_linux5 Linux Debugging
|
||||
|
||||
Eliot Blennerhassett writes:
|
||||
|
||||
On linux build, use e.g. "libtool gdb bin/patest_sine8" to debug that program.
|
||||
This is because on linux bin/patest_sine8 is a libtool shell script that wraps
|
||||
bin/.libs/patest_sine8 and allows it to find the appropriate libraries within
|
||||
the build tree.
|
||||
|
||||
*/
|
|
@ -0,0 +1,121 @@
|
|||
/** @page compile_mac_coreaudio Building Portaudio for Mac OS X
|
||||
@ingroup tutorial
|
||||
|
||||
@section comp_mac_ca_1 Requirements
|
||||
|
||||
* OS X 10.4 or later. PortAudio v19 currently only compiles and runs on OS X version 10.4 or later. Because of its heavy reliance on memory barriers, it's not clear how easy it would be to back-port PortAudio to OS X version 10.3. Leopard support requires the 2007 snapshot or later.
|
||||
|
||||
* Apple's Xcode and its related tools installed in the default location. There is no Xcode project for PortAudio.
|
||||
|
||||
* Mac 10.4 SDK. Look for "/Developer/SDKs/MacOSX10.4u.sdk" folder on your system. It may be installed with XCode. If not then you can download it from Apple Developer Connection. http://connect.apple.com/
|
||||
|
||||
@section comp_mac_ca_2 Building
|
||||
|
||||
To build PortAudio, simply use the Unix-style "./configure && make":
|
||||
|
||||
@code
|
||||
./configure && make
|
||||
@endcode
|
||||
|
||||
You do <b>not</b> need to do "make install", and we don't recommend it; however, you may be using software that instructs you to do so, in which case you should follow those instructions. (Note from Phil: I had to do "sudo make install" after the command above, otherwise XCode complained that it could not find "/usr/local/lib/libportaudio.dylib" when I compiled an example.)
|
||||
|
||||
The result of these steps will be a file named "libportaudio.dylib" in the directory "usr/local/lib/".
|
||||
|
||||
By default, this will create universal binaries and therefore requires the Universal SDK from Apple, included with XCode 2.1 and higher.
|
||||
|
||||
@section comp_mac_ca_3 Other Build Options
|
||||
|
||||
There are a variety of other options for building PortAudio. The default described above is recommended as it is the most supported and tested; however, your needs may differ and require other options, which are described below.
|
||||
|
||||
@subsection comp_mac_ca_3.1 Building Non-Universal Libraries
|
||||
|
||||
By default, PortAudio is built as a universal binary. This includes 64-bit versions if you are compiling on 10.5, Leopard. If you want a "thin", or single architecture library, you have two options:
|
||||
|
||||
* build a non-universal library using configure options.
|
||||
* use lipo(1) on whatever part of the library you plan to use.
|
||||
|
||||
Note that the first option may require an extremely recent version of PortAudio (February 5th '08 at least).
|
||||
|
||||
@subsection comp_mac_ca_3.2 Building with <i>--disable-mac-universal</i>
|
||||
|
||||
To build a non-universal library for the host architecture, simply use the <i>--disable-mac-universal</i> option with configure.
|
||||
|
||||
@code
|
||||
./configure --disable-mac-universal && make
|
||||
@endcode
|
||||
|
||||
The <i>--disable-mac-universal</i> option may also be used in conjunction with environment variables to give you more control over the universal binary build process. For example, to build a universal binary for the i386 and ppc architectures using the 10.4u sdk (which is the default on 10.4, but not 10.5), you might specify this configure command line:
|
||||
|
||||
@code
|
||||
CFLAGS="-O2 -g -Wall -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.3" \
|
||||
LDFLAGS="-arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.3" \
|
||||
./configure --disable-mac-universal --disable-dependency-tracking
|
||||
@endcode
|
||||
|
||||
For more info, see Apple's documentation on the matter:
|
||||
|
||||
* http://developer.apple.com/technotes/tn2005/tn2137.html
|
||||
* http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/intro/chapter_1_section_1.html
|
||||
|
||||
@subsection comp_mac_ca_3.3 Using lipo
|
||||
|
||||
The second option is to build normally, and use lipo (1) to extract the architectures you want. For example, if you want a "thin", i386 library only:
|
||||
|
||||
@code
|
||||
lipo lib/.libs/libportaudio.a -thin i386 -output libportaudio.a
|
||||
@endcode
|
||||
|
||||
or if you want to extract a single architecture fat file:
|
||||
|
||||
@code
|
||||
lipo lib/.libs/libportaudio.a -extract i386 -output libportaudio.a
|
||||
@endcode
|
||||
|
||||
@subsection comp_mac_ca_3.4 Building With Debug Options
|
||||
|
||||
By default, PortAudio on the mac is built without any debugging options. This is because asserts are generally inappropriate for a production environment and debugging information has been suspected, though not proven, to cause trouble with some interfaces. If you would like to compile with debugging, you must run configure with the appropriate flags. For example:
|
||||
|
||||
@code
|
||||
./configure --enable-mac-debug && make
|
||||
@endcode
|
||||
|
||||
This will enable -g and disable -DNDEBUG which will effectively enable asserts.
|
||||
|
||||
@section comp_mac_ca_4 Using the Library in XCode Projects
|
||||
|
||||
If you are planning to follow the rest of the tutorial, several project types will work. You can create a "Standard Tool" under "Command Line Utility". If you are not following the rest of the tutorial, any type of project should work with PortAudio, but these instructions may not work perfectly.
|
||||
|
||||
Once you've compiled PortAudio, the easiest and recommended way to use PortAudio in your XCode project is to add "<portaudio>/include/portaudio.h" and "<portaudio>/lib/.libs/libportaudio.a" to your project. Because "<portaudio>/lib/.libs/" is a hidden directory, you won't be able to navigate to it using the finder or the standard Mac OS file dialogs by clicking on files and folders. You can use command-shift-G in the finder to specify the exact path, or, from the shell, if you are in the portaudio directory, you can enter this command:
|
||||
|
||||
@code
|
||||
open lib/.libs
|
||||
@endcode
|
||||
|
||||
Then drag the "libportaudio.a" file into your XCode project and place it in the "External Frameworks and Libraries" group, if the project type has it. If not you can simply add it to the top level folder of the project.
|
||||
|
||||
You will need to add the following frameworks to your XCode project:
|
||||
|
||||
- CoreAudio.framework
|
||||
- AudioToolbox.framework
|
||||
- AudioUnit.framework
|
||||
- CoreServices.framework
|
||||
|
||||
@section comp_mac_ca_5 Using the Library in Other Projects
|
||||
|
||||
For gcc/Make style projects, include "include/portaudio.h" and link "libportaudio.a", and use the frameworks listed in the previous section. How you do so depends on your build.
|
||||
|
||||
@section comp_mac_ca_6 Using Mac-only Extensions to PortAudio
|
||||
|
||||
For additional, Mac-only extensions to the PortAudio interface, you may also want to grab "include/pa_mac_core.h". This file contains some special, mac-only features relating to sample-rate conversion, channel mapping, performance and device hogging. See "src/hostapi/coreaudio/notes.txt" for more details on these features.
|
||||
|
||||
@section comp_mac_ca_7 What Happened to Makefile.darwin?
|
||||
|
||||
Note, there used to be a special makefile just for darwin. This is no longer supported because you can build universal binaries from the standard configure routine. If you find this file in your directory structure it means you have an outdated version of PortAudio.
|
||||
|
||||
@code
|
||||
make -f Makefile.darwin
|
||||
@endcode
|
||||
|
||||
Back to the Tutorial: \ref tutorial_start
|
||||
|
||||
*/
|
|
@ -0,0 +1,97 @@
|
|||
/** @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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@section comp_win1 For Visual Studio 2005, Visual C++ 2008 Express Edition or Visual Studio 2010
|
||||
|
||||
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
|
||||
|
||||
C/C++ -> Code Generation -> Runtime library = /MT
|
||||
|
||||
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.
|
||||
|
||||
Click "Ok" when you have finished setting these parameters.
|
||||
|
||||
@section comp_win2 Preprocessor Definitions
|
||||
|
||||
Since the preprocessor definitions are different for each configuration and platform, you'll need to edit these individually for each configuration/platform combination that you want to modify using the "Configurations" and "Platforms" combo boxes.
|
||||
|
||||
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:
|
||||
|
||||
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.
|
||||
|
||||
@section comp_win3 Building
|
||||
|
||||
As when setting Preprocessor definitions, building is a per-configuration per-platform process. Follow these instructions for each configuration/platform combination that you're interested in.
|
||||
|
||||
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:
|
||||
|
||||
(from portaudio.def)
|
||||
@code
|
||||
...
|
||||
PaAsio_GetAvailableLatencyValues @50
|
||||
PaAsio_ShowControlPanel @51
|
||||
PaUtil_InitializeX86PlainConverters @52
|
||||
PaAsio_GetInputChannelName @53
|
||||
PaAsio_GetOutputChannelName @54
|
||||
PaUtil_SetLogPrintFunction @55
|
||||
@endcode
|
||||
|
||||
@section comp_win4 Building without ASIO support
|
||||
|
||||
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.
|
||||
|
||||
2) Make sure your project doesn't try to build the PortAudio ASIO implementation files:
|
||||
|
||||
src\\hostapi\\pa_asio.cpp src\\hostapi\\iasiothiscallresolver.cpp
|
||||
|
||||
If you're using one of the shipped projects, remove them from the project.
|
||||
|
||||
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.
|
||||
|
||||
4) Remove PaAsio_* entry points from portaudio.def
|
||||
|
||||
|
||||
-----
|
||||
David Viens, davidv@plogue.com
|
||||
|
||||
Updated by Chris on 5/26/2011
|
||||
|
||||
Improvements by John Clements on 12/15/2011
|
||||
|
||||
Back to the Tutorial: \ref tutorial_start
|
||||
|
||||
*/
|
|
@ -0,0 +1,95 @@
|
|||
/** @page compile_windows_asio_msvc Building Portaudio for Windows with ASIO support using MSVC
|
||||
@ingroup tutorial
|
||||
|
||||
@section comp_win_asiomsvc1 Portaudio Windows ASIO with MSVC
|
||||
|
||||
This tutorial describes how to build PortAudio with ASIO support using MSVC *from scratch*, without an existing Visual Studio project. For instructions for building PortAudio (including ASIO support) using the bundled Visual Studio project file see the compiling instructions for \ref compile_windows.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
@endcode
|
||||
|
||||
First, make sure that the Steinberg SDK and the portaudio files are "side by side" in the same directory.
|
||||
|
||||
Open Microsoft Visual C++ and create a new blank Console exe Project/Workspace in that same directory.
|
||||
|
||||
For example, the paths for all three groups might read like this:
|
||||
|
||||
@code
|
||||
C:\Program Files\Microsoft Visual Studio\VC98\My Projects\ASIOSDK2
|
||||
C:\Program Files\Microsoft Visual Studio\VC98\My Projects\portaudio
|
||||
C:\Program Files\Microsoft Visual Studio\VC98\My Projects\Sawtooth
|
||||
@endcode
|
||||
|
||||
|
||||
Next, add the following Steinberg ASIO SDK files to the project Source Files:
|
||||
|
||||
@code
|
||||
asio.cpp (ASIOSDK2\common)
|
||||
asiodrivers.cpp (ASIOSDK2\host)
|
||||
asiolist.cpp (ASIOSDK2\host\pc)
|
||||
@endcode
|
||||
|
||||
|
||||
Then, add the following PortAudio files to the project Source Files:
|
||||
|
||||
@code
|
||||
pa_asio.cpp (portaudio\src\hostapi\asio)
|
||||
pa_allocation.c (portaudio\src\common)
|
||||
pa_converters.c (portaudio\src\common)
|
||||
pa_cpuload.c (portaudio\src\common)
|
||||
pa_dither.c (portaudio\src\common)
|
||||
pa_front.c (portaudio\src\common)
|
||||
pa_process.c (portaudio\src\common)
|
||||
pa_ringbuffer.c (portaudio\src\common)
|
||||
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_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.)
|
||||
@endcode
|
||||
|
||||
|
||||
Although not strictly necessary, you may also want to add the following files to the project Header Files:
|
||||
|
||||
@code
|
||||
portaudio.h (portaudio\include)
|
||||
pa_asio.h (portaudio\include)
|
||||
@endcode
|
||||
|
||||
These header files define the interfaces to the PortAudio API.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
@code
|
||||
..\portaudio\include,..\portaudio\src\common,..\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.
|
||||
|
||||
--- Chris Share, Tom McCandless, Ross Bencina
|
||||
|
||||
[wiki:UsingThePortAudioSvnRepository SVN instructions]
|
||||
Back to the Tutorial: \ref tutorial_start
|
||||
|
||||
*/
|
|
@ -0,0 +1,53 @@
|
|||
/** @page compile_windows_mingw Building Portaudio for Windows with MinGW
|
||||
@ingroup tutorial
|
||||
|
||||
@section comp_mingw1 Portaudio for Windows With MinGW
|
||||
|
||||
<i>The following document is still being reviewed</i>
|
||||
|
||||
= MinGW/MSYS =
|
||||
|
||||
From the [http://www.mingw.org MinGW projectpage]:
|
||||
|
||||
MinGW: A collection of freely available and freely distributable
|
||||
Windows specific header files and import libraries, augmenting
|
||||
the GNU Compiler Collection, (GCC), and its associated
|
||||
tools, (GNU binutils). MinGW provides a complete Open Source
|
||||
programming tool set which is suitable for the development of
|
||||
native Windows programs that do not depend on any 3rd-party C
|
||||
runtime DLLs.
|
||||
|
||||
MSYS: A Minimal SYStem providing a POSIX compatible Bourne shell
|
||||
environment, with a small collection of UNIX command line
|
||||
tools. Primarily developed as a means to execute the configure
|
||||
scripts and Makefiles used to build Open Source software, but
|
||||
also useful as a general purpose command line interface to
|
||||
replace Windows cmd.exe.
|
||||
|
||||
MinGW provides a compiler/linker toolchain while MSYS is required
|
||||
to actually run the PortAudio configure script.
|
||||
|
||||
Once MinGW and MSYS are installed (see the [http://www.mingw.org/MinGWiki MinGW-Wiki]) open an MSYS shell and run the famous:
|
||||
|
||||
@code
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
@endcode
|
||||
|
||||
The above should create a working version though you might want to
|
||||
provide '--prefix=<path-to-install-dir>' to configure.
|
||||
|
||||
'./configure --help' gives details as to what can be tinkered with.
|
||||
|
||||
--- Mikael Magnusson
|
||||
|
||||
To update your copy or check out a fresh copy of the source
|
||||
|
||||
[wiki:UsingThePortAudioSvnRepository SVN instructions]
|
||||
|
||||
--- Bob !McGwier
|
||||
|
||||
Back to the Tutorial: \ref tutorial_start
|
||||
|
||||
*/
|
|
@ -0,0 +1,15 @@
|
|||
/** @page exploring Exploring PortAudio
|
||||
@ingroup tutorial
|
||||
|
||||
Now that you have a good idea of how PortAudio works, you can try out the example programs. You'll find them in the examples/ directory in the PortAudio distribution.
|
||||
|
||||
For an example of playing a sine wave, see examples/paex_sine.c.
|
||||
|
||||
For an example of recording and playing back a sound, see examples/paex_record.c.
|
||||
|
||||
I also encourage you to examine the source for the PortAudio libraries. If you have suggestions on ways to improve them, please let us know. If you want to implement PortAudio on a new platform, please let us know as well so we can coordinate people's efforts.
|
||||
|
||||
|
||||
Previous: \ref blocking_read_write | Next: This is the end of the tutorial.
|
||||
|
||||
*/
|
|
@ -0,0 +1,29 @@
|
|||
/** @page initializing_portaudio Initializing PortAudio
|
||||
@ingroup tutorial
|
||||
|
||||
@section tut_init1 Initializing PortAudio
|
||||
|
||||
Before making any other calls to PortAudio, you 'must' call Pa_Initialize(). This will trigger a scan of available devices which can be queried later. Like most PA functions, it will return a result of type paError. If the result is not paNoError, then an error has occurred.
|
||||
@code
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
@endcode
|
||||
|
||||
You can get a text message that explains the error message by passing it to Pa_GetErrorText( err ). For Example:
|
||||
|
||||
@code
|
||||
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
|
||||
@endcode
|
||||
|
||||
It is also important, when you are done with PortAudio, to Terminate it:
|
||||
|
||||
@code
|
||||
err = Pa_Terminate();
|
||||
if( err != paNoError )
|
||||
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
|
||||
@endcode
|
||||
|
||||
|
||||
Previous: \ref writing_a_callback | Next: \ref open_default_stream
|
||||
|
||||
*/
|
|
@ -0,0 +1,48 @@
|
|||
/** @page open_default_stream Opening a Stream Using Defaults
|
||||
@ingroup tutorial
|
||||
|
||||
The next step is to open a stream, which is similar to opening a file. You can specify whether you want audio input and/or output, how many channels, the data format, sample rate, etc. Opening a ''default'' stream means opening the default input and output devices, which saves you the trouble of getting a list of devices and choosing one from the list. (We'll see how to do that later.)
|
||||
@code
|
||||
#define SAMPLE_RATE (44100)
|
||||
static paTestData data;
|
||||
|
||||
.....
|
||||
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
|
||||
/* Open an audio I/O stream. */
|
||||
err = Pa_OpenDefaultStream( &stream,
|
||||
0, /* no input channels */
|
||||
2, /* stereo output */
|
||||
paFloat32, /* 32 bit floating point output */
|
||||
SAMPLE_RATE,
|
||||
256, /* frames per buffer, i.e. the number
|
||||
of sample frames that PortAudio will
|
||||
request from the callback. Many apps
|
||||
may want to use
|
||||
paFramesPerBufferUnspecified, which
|
||||
tells PortAudio to pick the best,
|
||||
possibly changing, buffer size.*/
|
||||
patestCallback, /* this is your callback function */
|
||||
&data ); /*This is a pointer that will be passed to
|
||||
your callback*/
|
||||
if( err != paNoError ) goto error;
|
||||
@endcode
|
||||
|
||||
The data structure and callback are described in \ref writing_a_callback.
|
||||
|
||||
The above example opens the stream for writing, which is sufficient for playback. It is also possible to open a stream for reading, to do recording, or both reading and writing, for simultaneous recording and playback or even real-time audio processing. If you plan to do playback and recording at the same time, open only one stream with valid input and output parameters.
|
||||
|
||||
There are some caveats to note about simultaneous read/write:
|
||||
|
||||
- Some platforms can only open a read/write stream using the same device.
|
||||
- Although multiple streams can be opened, it is difficult to synchronize them.
|
||||
- Some platforms don't support opening multiple streams on the same device.
|
||||
- Using multiple streams may not be as well tested as other features.
|
||||
- The PortAudio library calls must be made from the same thread or synchronized by the user.
|
||||
|
||||
|
||||
Previous: \ref initializing_portaudio | Next: \ref start_stop_abort
|
||||
|
||||
*/
|
|
@ -0,0 +1,111 @@
|
|||
/** @page querying_devices Enumerating and Querying PortAudio Devices
|
||||
@ingroup tutorial
|
||||
|
||||
@section tut_query1 Querying Devices
|
||||
|
||||
It is often fine to use the default device as we did previously in this tutorial, but there are times when you'll want to explicitly choose the device from a list of available devices on the system. To see a working example of this, check out pa_devs.c in the tests/ directory of the PortAudio source code. To do so, you'll need to first initialize PortAudio and Query for the number of Devices:
|
||||
|
||||
@code
|
||||
int numDevices;
|
||||
|
||||
numDevices = Pa_GetDeviceCount();
|
||||
if( numDevices < 0 )
|
||||
{
|
||||
printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
|
||||
err = numDevices;
|
||||
goto error;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
If you want to get information about each device, simply loop through as follows:
|
||||
|
||||
@code
|
||||
const PaDeviceInfo *deviceInfo;
|
||||
|
||||
for( i=0; i<numDevices; i++ )
|
||||
{
|
||||
deviceInfo = Pa_GetDeviceInfo( i );
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
The Pa_DeviceInfo structure contains a wealth of information such as the name of the devices, the default latency associated with the devices and more. The structure ihas the following fields:
|
||||
|
||||
@code
|
||||
int structVersion
|
||||
const char * name
|
||||
PaHostApiIndex hostApi
|
||||
int maxInputChannels
|
||||
int maxOutputChannels
|
||||
PaTime defaultLowInputLatency
|
||||
PaTime defaultLowOutputLatency
|
||||
PaTime defaultHighInputLatency
|
||||
PaTime defaultHighOutputLatency
|
||||
double defaultSampleRate
|
||||
@endcode
|
||||
|
||||
You may notice that you can't determine, from this information alone, whether or not a particular sample rate is supported. This is because some devices support ranges of sample rates, others support, a list of sample rates, and still others support some sample rates and number of channels combinations but not others. To get around this, PortAudio offers a function for testing a particular device with a given format:
|
||||
|
||||
@code
|
||||
const PaStreamParameters *inputParameters;
|
||||
const PaStreamParameters *outputParameters;
|
||||
double desiredSampleRate;
|
||||
...
|
||||
PaError err;
|
||||
|
||||
err = Pa_IsFormatSupported( inputParameters, outputParameters, desiredSampleRate );
|
||||
if( err == paFormatIsSupported )
|
||||
{
|
||||
printf( "Hooray!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Too Bad.\n");
|
||||
}
|
||||
@endcode
|
||||
|
||||
Filling in the inputParameters and outputParameters fields is shown in a moment.
|
||||
|
||||
Once you've found a configuration you like, or one you'd like to go ahead and try, you can open the stream by filling in the PaStreamParameters structures, and calling Pa_OpenStream:
|
||||
|
||||
@code
|
||||
double srate = ... ;
|
||||
PaStream *stream;
|
||||
unsigned long framesPerBuffer = ... ; //could be paFramesPerBufferUnspecified, in which case PortAudio will do its best to manage it for you, but, on some platforms, the framesPerBuffer will change in each call to the callback
|
||||
PaStreamParameters outputParameters;
|
||||
PaStreamParameters inputParameters;
|
||||
|
||||
bzero( &inputParameters, sizeof( inputParameters ) ); //not necessary if you are filling in all the fields
|
||||
inputParameters.channelCount = inChan;
|
||||
inputParameters.device = inDevNum;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
inputParameters.sampleFormat = paFloat32;
|
||||
inputParameters.suggestedLatency = Pa_GetDeviceInfo(inDevNum)->defaultLowInputLatency ;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL; //See you specific host's API docs for info on using this field
|
||||
|
||||
|
||||
bzero( &outputParameters, sizeof( outputParameters ) ); //not necessary if you are filling in all the fields
|
||||
outputParameters.channelCount = outChan;
|
||||
outputParameters.device = outDevNum;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
outputParameters.sampleFormat = paFloat32;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outDevNum)->defaultLowOutputLatency ;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL; //See you specific host's API docs for info on using this field
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
&outputParameters,
|
||||
srate,
|
||||
framesPerBuffer,
|
||||
paNoFlag, //flags that can be used to define dither, clip settings and more
|
||||
portAudioCallback, //your callback function
|
||||
(void *)this ); //data to be passed to callback. In C++, it is frequently (void *)this
|
||||
//don't forget to check errors!
|
||||
@endcode
|
||||
|
||||
|
||||
Previous: \ref utility_functions | Next: \ref blocking_read_write
|
||||
|
||||
*/
|
|
@ -0,0 +1,35 @@
|
|||
/** @page start_stop_abort Starting, Stopping and Aborting a Stream
|
||||
@ingroup tutorial
|
||||
|
||||
@section tut_startstop1 Starting, Stopping and Aborting a Stream
|
||||
|
||||
PortAudio will not start playing back audio until you start the stream. After calling Pa_StartStream(), PortAudio will start calling your callback function to perform the audio processing.
|
||||
|
||||
@code
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
@endcode
|
||||
|
||||
You can communicate with your callback routine through the data structure you passed in on the open call, or through global variables, or using other interprocess communication techniques, but please be aware that your callback function may be called at interrupt time when your foreground process is least expecting it. So avoid sharing complex data structures that are easily corrupted like double linked lists, and avoid using locks such as mutexs as this may cause your callback function to block and therefore drop audio. Such techniques may even cause deadlock on some platforms.
|
||||
|
||||
PortAudio will continue to call your callback and process audio until you stop the stream. This can be done in one of several ways, but, before we do so, we'll want to see that some of our audio gets processed by sleeping for a few seconds. This is easy to do with Pa_Sleep(), which is used by many of the examples in the patests/ directory for exactly this purpose. Note that, for a variety of reasons, you can not rely on this function for accurate scheduling, so your stream may not run for exactly the same amount of time as you expect, but it's good enough for our example.
|
||||
|
||||
@code
|
||||
/* Sleep for several seconds. */
|
||||
Pa_Sleep(NUM_SECONDS*1000);
|
||||
@endcode
|
||||
|
||||
Now we need to stop playback. There are several ways to do this, the simplest of which is to call Pa_StopStream():
|
||||
|
||||
@code
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
@endcode
|
||||
|
||||
Pa_StopStream() is designed to make sure that the buffers you've processed in your callback are all played, which may cause some delay. Alternatively, you could call Pa_AbortStream(). On some platforms, aborting the stream is much faster and may cause some data processed by your callback not to be played.
|
||||
|
||||
Another way to stop the stream is to return either paComplete, or paAbort from your callback. paComplete ensures that the last buffer is played whereas paAbort stops the stream as soon as possible. If you stop the stream using this technique, you will need to call Pa_StopStream() before starting the stream again.
|
||||
|
||||
Previous: \ref open_default_stream | Next: \ref terminating_portaudio
|
||||
|
||||
*/
|
|
@ -0,0 +1,20 @@
|
|||
/** @page terminating_portaudio Closing a Stream and Terminating PortAudio
|
||||
@ingroup tutorial
|
||||
|
||||
When you are done with a stream, you should close it to free up resources:
|
||||
|
||||
@code
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
@endcode
|
||||
|
||||
We've already mentioned this in \ref initializing_portaudio, but in case you forgot, be sure to terminate PortAudio when you are done:
|
||||
|
||||
@code
|
||||
err = Pa_Terminate( );
|
||||
if( err != paNoError ) goto error;
|
||||
@endcode
|
||||
|
||||
Previous: \ref start_stop_abort | Next: \ref utility_functions
|
||||
|
||||
*/
|
|
@ -0,0 +1,56 @@
|
|||
/** @page tutorial_start PortAudio Tutorials
|
||||
@ingroup tutorial
|
||||
|
||||
These tutorials takes you through a hands-on example of using PortAudio to make sound. If you'd prefer to start with a top-down overview of the PortAudio API, check out the @ref api_overview.
|
||||
|
||||
@section tut_start1 Downloading
|
||||
|
||||
First thing you need to do is download the PortAudio source code either <a href="http://www.portaudio.com/download.html">as a tarball from the website</a>, or <a href="http://www.portaudio.com/usingsvn.html">from the Subversion Repository</a>.
|
||||
|
||||
@section tut_start2 Compiling
|
||||
|
||||
Once you've downloaded PortAudio you'll need to compile it, which of course, depends on your environment:
|
||||
|
||||
- Windows
|
||||
- \ref compile_windows
|
||||
- \ref compile_windows_mingw
|
||||
- \ref compile_windows_asio_msvc
|
||||
- \ref compile_cmake
|
||||
- Mac OS X
|
||||
- \ref compile_mac_coreaudio
|
||||
- POSIX
|
||||
- \ref compile_linux
|
||||
|
||||
Many platforms with GCC/make can use the simple ./configure && make combination and simply use the resulting libraries in their code.
|
||||
|
||||
@section tut_start3 Programming with PortAudio
|
||||
|
||||
Below are the steps to writing a PortAudio application:
|
||||
|
||||
- Write a callback function that will be called by PortAudio when audio processing is needed.
|
||||
- Initialize the PA library and open a stream for audio I/O.
|
||||
- Start the stream. Your callback function will be now be called repeatedly by PA in the background.
|
||||
- In your callback you can read audio data from the inputBuffer and/or write data to the outputBuffer.
|
||||
- Stop the stream by returning 1 from your callback, or by calling a stop function.
|
||||
- Close the stream and terminate the library.
|
||||
|
||||
In addition to this "Callback" architecture, V19 also supports a "Blocking I/O" model which uses read and write calls which may be more familiar to non-audio programmers. Note that at this time, not all APIs support this functionality.
|
||||
|
||||
In this tutorial, we'll show how to use the callback architecture to play a sawtooth wave. Much of the tutorial is taken from the file paex_saw.c, which is part of the PortAudio distribution. When you're done with this tutorial, you'll be armed with the basic knowledge you need to write an audio program. If you need more sample code, look in the "examples" and "test" directory of the PortAudio distribution. Another great source of info is the portaudio.h Doxygen page, which documents the entire V19 API. Also see the page for <a href="http://www.assembla.com/spaces/portaudio/wiki/Tips">tips on programming PortAudio</a> on the PortAudio wiki.
|
||||
|
||||
If you are upgrading from V18, you may want to look at the <a href="http://www.portaudio.com/docs/proposals/index.html">Proposed Enhancements to PortAudio</a>, which describes the differences between V18 and V19.
|
||||
|
||||
- \ref writing_a_callback
|
||||
- \ref initializing_portaudio
|
||||
- \ref open_default_stream
|
||||
- \ref start_stop_abort
|
||||
- \ref terminating_portaudio
|
||||
- \ref utility_functions
|
||||
- \ref querying_devices
|
||||
- \ref blocking_read_write
|
||||
|
||||
Once you have a basic understanding of how to use PortAudio, you might be interested in \ref exploring.
|
||||
|
||||
Next: \ref writing_a_callback
|
||||
|
||||
*/
|
|
@ -0,0 +1,69 @@
|
|||
/** @page utility_functions Utility Functions
|
||||
@ingroup tutorial
|
||||
|
||||
In addition to the functions described elsewhere in this tutorial, PortAudio provides a number of Utility functions that are useful in a variety of circumstances.
|
||||
You'll want to read the portaudio.h reference, which documents the entire V19 API for details, but we'll try to cover the basics here.
|
||||
|
||||
@section tut_util2 Version Information
|
||||
|
||||
PortAudio offers two functions to determine the PortAudio Version. This is most useful when you are using PortAudio as a dynamic library, but it may also be useful at other times.
|
||||
|
||||
@code
|
||||
int Pa_GetVersion (void)
|
||||
const char * Pa_GetVersionText (void)
|
||||
@endcode
|
||||
|
||||
@section tut_util3 Error Text
|
||||
|
||||
PortAudio allows you to get error text from an error number.
|
||||
|
||||
@code
|
||||
const char * Pa_GetErrorText (PaError errorCode)
|
||||
@endcode
|
||||
|
||||
@section tut_util4 Stream State
|
||||
|
||||
PortAudio Streams exist in 3 states: Active, Stopped, and Callback Stopped. If a stream is in callback stopped state, you'll need to stop it before you can start it again. If you need to query the state of a PortAudio stream, there are two functions for doing so:
|
||||
|
||||
@code
|
||||
PaError Pa_IsStreamStopped (PaStream *stream)
|
||||
PaError Pa_IsStreamActive (PaStream *stream)
|
||||
@endcode
|
||||
|
||||
@section tut_util5 Stream Info
|
||||
|
||||
If you need to retrieve info about a given stream, such as latency, and sample rate info, there's a function for that too:
|
||||
|
||||
@code
|
||||
const PaStreamInfo * Pa_GetStreamInfo (PaStream *stream)
|
||||
@endcode
|
||||
|
||||
@section tut_util6 Stream Time
|
||||
|
||||
If you need to synchronise other activities such as display updates or MIDI output with the PortAudio callback you need to know the current time according to the same timebase used by the stream callback timestamps.
|
||||
|
||||
@code
|
||||
PaTime Pa_GetStreamTime (PaStream *stream)
|
||||
@endcode
|
||||
|
||||
@section tut_util6CPU Usage
|
||||
|
||||
To determine how much CPU is being used by the callback, use these:
|
||||
|
||||
@code
|
||||
double Pa_GetStreamCpuLoad (PaStream *stream)
|
||||
@endcode
|
||||
|
||||
@section tut_util7 Other utilities
|
||||
|
||||
These functions allow you to determine the size of a sample from its format and sleep for a given amount of time. The sleep function should not be used for precise timing or synchronization because it makes few guarantees about the exact length of time it waits. It is most useful for testing.
|
||||
|
||||
@code
|
||||
PaError Pa_GetSampleSize (PaSampleFormat format)
|
||||
void Pa_Sleep (long msec)
|
||||
@endcode
|
||||
|
||||
|
||||
Previous: \ref terminating_portaudio | Next: \ref querying_devices
|
||||
|
||||
*/
|
|
@ -0,0 +1,66 @@
|
|||
/** @page writing_a_callback Writing a Callback Function
|
||||
@ingroup tutorial
|
||||
|
||||
To write a program using PortAudio, you must include the "portaudio.h" include file. You may wish to read "portaudio.h" because it contains a complete description of the PortAudio functions and constants. Alternatively, you could browse the [http://www.portaudio.com/docs/v19-doxydocs/portaudio_8h.html "portaudio.h" Doxygen page]
|
||||
@code
|
||||
#include "portaudio.h"
|
||||
@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>
|
||||
|
||||
Your callback function must return an int and accept the exact parameters specified in this typedef:
|
||||
|
||||
@code
|
||||
typedef int PaStreamCallback( const void *input,
|
||||
void *output,
|
||||
unsigned long frameCount,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData ) ;
|
||||
@endcode
|
||||
Here is an example callback function from the test file "patests/patest_saw.c". It calculates a simple left and right sawtooth signal and writes it to the output buffer. Notice that in this example, the signals are of float data type. The signals must be between -1.0 and +1.0. You can also use 16 bit integers or other formats which are specified during setup, but floats are easiest to work with. You can pass a pointer to your data structure through PortAudio which will appear as userData.
|
||||
|
||||
@code
|
||||
typedef struct
|
||||
{
|
||||
float left_phase;
|
||||
float right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
/* Cast data passed through stream to our structure. */
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned int i;
|
||||
(void) inputBuffer; /* Prevent unused variable warning. */
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->left_phase; /* left */
|
||||
*out++ = data->right_phase; /* right */
|
||||
/* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
|
||||
data->left_phase += 0.01f;
|
||||
/* When signal reaches top, drop back down. */
|
||||
if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
|
||||
/* higher pitch so we can distinguish left and right. */
|
||||
data->right_phase += 0.03f;
|
||||
if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Previous: \ref tutorial_start | Next: \ref initializing_portaudio
|
||||
|
||||
*/
|
|
@ -124,6 +124,19 @@ AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s );
|
|||
*/
|
||||
const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input );
|
||||
|
||||
|
||||
/** Retrieve the range of legal native buffer sizes for the specificed device, in sample frames.
|
||||
|
||||
@param device The global index of the PortAudio device about which the query is being made.
|
||||
@param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value.
|
||||
@param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value.
|
||||
|
||||
@see kAudioDevicePropertyBufferFrameSizeRange in the CoreAudio SDK.
|
||||
*/
|
||||
PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device,
|
||||
long *minBufferSizeFrames, long *maxBufferSizeFrames );
|
||||
|
||||
|
||||
/**
|
||||
* Flags
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
#ifndef PA_WIN_WDMKS_H
|
||||
#define PA_WIN_WDMKS_H
|
||||
/*
|
||||
* $Id: pa_win_wdmks.h 1812 2012-02-14 09:32:57Z robiwan $
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* WDM/KS specific extensions
|
||||
*
|
||||
* Copyright (c) 1999-2007 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
@ingroup public_header
|
||||
@brief WDM Kernel Streaming-specific PortAudio API extension header file.
|
||||
*/
|
||||
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
typedef struct PaWinWDMKSInfo{
|
||||
unsigned long size; /**< sizeof(PaWinWDMKSInfo) */
|
||||
PaHostApiTypeId hostApiType; /**< paWDMKS */
|
||||
unsigned long version; /**< 1 */
|
||||
|
||||
/* The number of packets to use for WaveCyclic devices, range is [2, 8]. Set to zero for default value of 2. */
|
||||
unsigned noOfPackets;
|
||||
} PaWinWDMKSInfo;
|
||||
|
||||
typedef enum PaWDMKSType
|
||||
{
|
||||
Type_kNotUsed,
|
||||
Type_kWaveCyclic,
|
||||
Type_kWaveRT,
|
||||
Type_kCnt,
|
||||
} PaWDMKSType;
|
||||
|
||||
typedef enum PaWDMKSSubType
|
||||
{
|
||||
SubType_kUnknown,
|
||||
SubType_kNotification,
|
||||
SubType_kPolled,
|
||||
SubType_kCnt,
|
||||
} PaWDMKSSubType;
|
||||
|
||||
typedef struct PaWinWDMKSDeviceInfo {
|
||||
wchar_t filterPath[MAX_PATH]; /**< KS filter path in Unicode! */
|
||||
wchar_t topologyPath[MAX_PATH]; /**< Topology filter path in Unicode! */
|
||||
PaWDMKSType streamingType;
|
||||
GUID deviceProductGuid; /**< The product GUID of the device (if supported) */
|
||||
} PaWinWDMKSDeviceInfo;
|
||||
|
||||
typedef struct PaWDMKSDirectionSpecificStreamInfo
|
||||
{
|
||||
PaDeviceIndex device;
|
||||
unsigned channels; /**< No of channels the device is opened with */
|
||||
unsigned framesPerHostBuffer; /**< No of frames of the device buffer */
|
||||
int endpointPinId; /**< Endpoint pin ID (on topology filter if topologyName is not empty) */
|
||||
int muxNodeId; /**< Only valid for input */
|
||||
PaWDMKSSubType streamingSubType; /**< Not known until device is opened for streaming */
|
||||
} PaWDMKSDirectionSpecificStreamInfo;
|
||||
|
||||
typedef struct PaWDMKSSpecificStreamInfo {
|
||||
PaWDMKSDirectionSpecificStreamInfo input;
|
||||
PaWDMKSDirectionSpecificStreamInfo output;
|
||||
} PaWDMKSSpecificStreamInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* PA_WIN_DS_H */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_trace.c 1339 2008-02-15 07:50:33Z rossb $
|
||||
* $Id: pa_trace.c 1812 2012-02-14 09:32:57Z robiwan $
|
||||
* Portable Audio I/O Library Trace Facility
|
||||
* Store trace information in real-time for later printing.
|
||||
*
|
||||
|
@ -46,12 +46,16 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "pa_trace.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_debugprint.h"
|
||||
|
||||
#if PA_TRACE_REALTIME_EVENTS
|
||||
|
||||
static char *traceTextArray[PA_MAX_TRACE_RECORDS];
|
||||
static char const *traceTextArray[PA_MAX_TRACE_RECORDS];
|
||||
static int traceIntArray[PA_MAX_TRACE_RECORDS];
|
||||
static int traceIndex = 0;
|
||||
static int traceBlock = 0;
|
||||
|
@ -94,4 +98,133 @@ void PaUtil_AddTraceMessage( const char *msg, int data )
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* High performance log alternative */
|
||||
/************************************************************************/
|
||||
|
||||
typedef unsigned long long PaUint64;
|
||||
|
||||
typedef struct __PaHighPerformanceLog
|
||||
{
|
||||
unsigned magik;
|
||||
int writePtr;
|
||||
int readPtr;
|
||||
int size;
|
||||
double refTime;
|
||||
char* data;
|
||||
} PaHighPerformanceLog;
|
||||
|
||||
static const unsigned kMagik = 0xcafebabe;
|
||||
|
||||
#define USEC_PER_SEC (1000000ULL)
|
||||
|
||||
int PaUtil_InitializeHighSpeedLog( LogHandle* phLog, unsigned maxSizeInBytes )
|
||||
{
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)PaUtil_AllocateMemory(sizeof(PaHighPerformanceLog));
|
||||
if (pLog == 0)
|
||||
{
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
assert(phLog != 0);
|
||||
*phLog = pLog;
|
||||
|
||||
pLog->data = (char*)PaUtil_AllocateMemory(maxSizeInBytes);
|
||||
if (pLog->data == 0)
|
||||
{
|
||||
PaUtil_FreeMemory(pLog);
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
pLog->magik = kMagik;
|
||||
pLog->size = maxSizeInBytes;
|
||||
pLog->refTime = PaUtil_GetTime();
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
void PaUtil_ResetHighSpeedLogTimeRef( LogHandle hLog )
|
||||
{
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
assert(pLog->magik == kMagik);
|
||||
pLog->refTime = PaUtil_GetTime();
|
||||
}
|
||||
|
||||
typedef struct __PaLogEntryHeader
|
||||
{
|
||||
int size;
|
||||
double timeStamp;
|
||||
} PaLogEntryHeader;
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define _vsnprintf vsnprintf
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
|
||||
int PaUtil_AddHighSpeedLogMessage( LogHandle hLog, const char* fmt, ... )
|
||||
{
|
||||
va_list l;
|
||||
int n = 0;
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
if (pLog != 0)
|
||||
{
|
||||
PaLogEntryHeader* pHeader;
|
||||
char* p;
|
||||
int maxN;
|
||||
assert(pLog->magik == kMagik);
|
||||
pHeader = (PaLogEntryHeader*)( pLog->data + pLog->writePtr );
|
||||
p = (char*)( pHeader + 1 );
|
||||
maxN = pLog->size - pLog->writePtr - 2 * sizeof(PaLogEntryHeader);
|
||||
|
||||
pHeader->timeStamp = PaUtil_GetTime() - pLog->refTime;
|
||||
if (maxN > 0)
|
||||
{
|
||||
if (maxN > 32)
|
||||
{
|
||||
va_start(l, fmt);
|
||||
n = _vsnprintf(p, min(1024, maxN), fmt, l);
|
||||
va_end(l);
|
||||
}
|
||||
else {
|
||||
n = sprintf(p, "End of log...");
|
||||
}
|
||||
n = ((n + sizeof(unsigned)) & ~(sizeof(unsigned)-1)) + sizeof(PaLogEntryHeader);
|
||||
pHeader->size = n;
|
||||
#if 0
|
||||
PaUtil_DebugPrint("%05u.%03u: %s\n", pHeader->timeStamp/1000, pHeader->timeStamp%1000, p);
|
||||
#endif
|
||||
pLog->writePtr += n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void PaUtil_DumpHighSpeedLog( LogHandle hLog, const char* fileName )
|
||||
{
|
||||
FILE* f = (fileName != NULL) ? fopen(fileName, "w") : stdout;
|
||||
unsigned localWritePtr;
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
assert(pLog->magik == kMagik);
|
||||
localWritePtr = pLog->writePtr;
|
||||
while (pLog->readPtr != localWritePtr)
|
||||
{
|
||||
const PaLogEntryHeader* pHeader = (const PaLogEntryHeader*)( pLog->data + pLog->readPtr );
|
||||
const char* p = (const char*)( pHeader + 1 );
|
||||
const PaUint64 ts = (const PaUint64)( pHeader->timeStamp * USEC_PER_SEC );
|
||||
assert(pHeader->size < (1024+sizeof(unsigned)+sizeof(PaLogEntryHeader)));
|
||||
fprintf(f, "%05u.%03u: %s\n", (unsigned)(ts/1000), (unsigned)(ts%1000), p);
|
||||
pLog->readPtr += pHeader->size;
|
||||
}
|
||||
if (f != stdout)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void PaUtil_DiscardHighSpeedLog( LogHandle hLog )
|
||||
{
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
assert(pLog->magik == kMagik);
|
||||
PaUtil_FreeMemory(pLog->data);
|
||||
PaUtil_FreeMemory(pLog);
|
||||
}
|
||||
|
||||
#endif /* TRACE_REALTIME_EVENTS */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_TRACE_H
|
||||
#define PA_TRACE_H
|
||||
/*
|
||||
* $Id: pa_trace.h 1339 2008-02-15 07:50:33Z rossb $
|
||||
* $Id: pa_trace.h 1812 2012-02-14 09:32:57Z robiwan $
|
||||
* Portable Audio I/O Library Trace Facility
|
||||
* Store trace information in real-time for later printing.
|
||||
*
|
||||
|
@ -85,12 +85,28 @@ void PaUtil_ResetTraceMessages();
|
|||
void PaUtil_AddTraceMessage( const char *msg, int data );
|
||||
void PaUtil_DumpTraceMessages();
|
||||
|
||||
/* Alternative interface */
|
||||
|
||||
typedef void* LogHandle;
|
||||
|
||||
int PaUtil_InitializeHighSpeedLog(LogHandle* phLog, unsigned maxSizeInBytes);
|
||||
void PaUtil_ResetHighSpeedLogTimeRef(LogHandle hLog);
|
||||
int PaUtil_AddHighSpeedLogMessage(LogHandle hLog, const char* fmt, ...);
|
||||
void PaUtil_DumpHighSpeedLog(LogHandle hLog, const char* fileName);
|
||||
void PaUtil_DiscardHighSpeedLog(LogHandle hLog);
|
||||
|
||||
#else
|
||||
|
||||
#define PaUtil_ResetTraceMessages() /* noop */
|
||||
#define PaUtil_AddTraceMessage(msg,data) /* noop */
|
||||
#define PaUtil_DumpTraceMessages() /* noop */
|
||||
|
||||
#define PaUtil_InitializeHighSpeedLog(phLog, maxSizeInBytes) (0)
|
||||
#define PaUtil_ResetHighSpeedLogTimeRef(hLog)
|
||||
#define PaUtil_AddHighSpeedLogMessage(...) (0)
|
||||
#define PaUtil_DumpHighSpeedLog(hLog, fileName)
|
||||
#define PaUtil_DiscardHighSpeedLog(hLog)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_asio.cpp 1778 2011-11-10 13:59:53Z rossb $
|
||||
* $Id: pa_asio.cpp 1825 2012-04-02 07:58:04Z rbencina $
|
||||
* Portable Audio I/O Library for ASIO Drivers
|
||||
*
|
||||
* Author: Stephane Letz
|
||||
|
@ -1031,8 +1031,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
PaAsioHostApiRepresentation *asioHostApi;
|
||||
PaAsioDeviceInfo *deviceInfoArray;
|
||||
char **names;
|
||||
PaAsioDriverInfo paAsioDriverInfo;
|
||||
|
||||
asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) );
|
||||
if( !asioHostApi )
|
||||
{
|
||||
|
@ -1040,6 +1038,8 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
goto error;
|
||||
}
|
||||
|
||||
memset( asioHostApi, 0, sizeof(PaAsioHostApiRepresentation) ); /* ensure all fields are zeroed. especially asioHostApi->allocations */
|
||||
|
||||
/*
|
||||
We initialize COM ourselves here and uninitialize it in Terminate().
|
||||
This should be the only COM initialization needed in this module.
|
||||
|
@ -1142,6 +1142,13 @@ 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]));
|
||||
|
||||
|
@ -1176,7 +1183,7 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
|
||||
|
||||
/* Attempt to load the asio driver... */
|
||||
if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError )
|
||||
if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriver.info, asioHostApi->systemSpecific ) == paNoError )
|
||||
{
|
||||
PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
|
||||
PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
|
||||
|
@ -1186,15 +1193,15 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
|
||||
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, paAsioDriverInfo.inputChannelCount));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", i, paAsioDriverInfo.outputChannelCount));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", i, paAsioDriverInfo.bufferMinSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", i, paAsioDriverInfo.bufferMaxSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriverInfo.bufferPreferredSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", i, paAsioDriverInfo.bufferGranularity));
|
||||
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 = paAsioDriverInfo.inputChannelCount;
|
||||
deviceInfo->maxOutputChannels = paAsioDriverInfo.outputChannelCount;
|
||||
deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount;
|
||||
deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount;
|
||||
|
||||
deviceInfo->defaultSampleRate = 0.;
|
||||
bool foundDefaultSampleRate = false;
|
||||
|
@ -1222,13 +1229,13 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
*/
|
||||
|
||||
double defaultLowLatency =
|
||||
paAsioDriverInfo.bufferPreferredSize / deviceInfo->defaultSampleRate;
|
||||
paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate;
|
||||
|
||||
deviceInfo->defaultLowInputLatency = defaultLowLatency;
|
||||
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
|
||||
|
||||
double defaultHighLatency =
|
||||
paAsioDriverInfo.bufferMaxSize / deviceInfo->defaultSampleRate;
|
||||
paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate;
|
||||
|
||||
if( defaultHighLatency < defaultLowLatency )
|
||||
defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */
|
||||
|
@ -1249,10 +1256,10 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
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 = paAsioDriverInfo.bufferMinSize;
|
||||
asioDeviceInfo->maxBufferSize = paAsioDriverInfo.bufferMaxSize;
|
||||
asioDeviceInfo->preferredBufferSize = paAsioDriverInfo.bufferPreferredSize;
|
||||
asioDeviceInfo->bufferGranularity = paAsioDriverInfo.bufferGranularity;
|
||||
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(
|
||||
|
@ -3046,7 +3053,7 @@ previousIndex = index;
|
|||
paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency;
|
||||
*/
|
||||
|
||||
/* Disabled! Stopping and re-starting the stream causes an input overflow / output undeflow. S.Fischer */
|
||||
/* Disabled! Stopping and re-starting the stream causes an input overflow / output underflow. S.Fischer */
|
||||
#if 0
|
||||
// detect underflows by checking inter-callback time > 2 buffer period
|
||||
static double previousTime = -1;
|
||||
|
@ -3498,6 +3505,7 @@ static PaError IsStreamActive( PaStream *s )
|
|||
static PaTime GetStreamTime( PaStream *s )
|
||||
{
|
||||
(void) s; /* unused parameter */
|
||||
|
||||
return (double)timeGetTime() * .001;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,7 +205,39 @@ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input )
|
|||
}
|
||||
|
||||
|
||||
PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device,
|
||||
long *minBufferSizeFrames, long *maxBufferSizeFrames )
|
||||
{
|
||||
PaError result;
|
||||
PaUtilHostApiRepresentation *hostApi;
|
||||
|
||||
result = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
|
||||
|
||||
if( result == paNoError )
|
||||
{
|
||||
PaDeviceIndex hostApiDeviceIndex;
|
||||
result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDeviceIndex, device, hostApi );
|
||||
if( result == paNoError )
|
||||
{
|
||||
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
|
||||
AudioDeviceID macCoreDeviceId = macCoreHostApi->devIds[hostApiDeviceIndex];
|
||||
AudioValueRange audioRange;
|
||||
UInt32 propSize = sizeof( audioRange );
|
||||
|
||||
// return the size range for the output scope unless we only have inputs
|
||||
Boolean isInput = 0;
|
||||
if( macCoreHostApi->inheritedHostApiRep.deviceInfos[hostApiDeviceIndex]->maxOutputChannels == 0 )
|
||||
isInput = 1;
|
||||
|
||||
result = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) );
|
||||
|
||||
*minBufferSizeFrames = audioRange.mMinimum;
|
||||
*maxBufferSizeFrames = audioRange.mMaximum;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s )
|
||||
|
@ -1596,12 +1628,19 @@ static UInt32 CalculateOptimalBufferSize( PaMacAUHAL *auhalHostApi,
|
|||
resultBufferSizeFrames = MAX( resultBufferSizeFrames, (UInt32) variableLatencyFrames );
|
||||
}
|
||||
|
||||
// can't have zero frames. code to round up to next user buffer requires non-zero
|
||||
resultBufferSizeFrames = MAX( resultBufferSizeFrames, 1 );
|
||||
|
||||
if( requestedFramesPerBuffer != paFramesPerBufferUnspecified )
|
||||
{
|
||||
// make host buffer the next highest integer multiple of user frames per buffer
|
||||
UInt32 n = (resultBufferSizeFrames + requestedFramesPerBuffer - 1) / requestedFramesPerBuffer;
|
||||
resultBufferSizeFrames = n * requestedFramesPerBuffer;
|
||||
|
||||
|
||||
// FIXME: really we should be searching for a multiple of requestedFramesPerBuffer
|
||||
// that is >= suggested latency and also fits within device buffer min/max
|
||||
|
||||
}else{
|
||||
VDBUG( ("Block Size unspecified. Based on Latency, the user wants a Block Size near: %ld.\n",
|
||||
resultBufferSizeFrames ) );
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_ds.c 1794 2011-11-24 18:11:33Z rossb $
|
||||
* $Id: pa_win_ds.c 1824 2012-04-02 07:45:18Z rbencina $
|
||||
* Portable Audio I/O Library DirectSound implementation
|
||||
*
|
||||
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina
|
||||
|
@ -480,7 +480,7 @@ static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidV
|
|||
else
|
||||
{
|
||||
newItems[i].lpGUID = &newItems[i].guid;
|
||||
memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) );;
|
||||
memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) );
|
||||
}
|
||||
newItems[i].pnpInterface = guidVector->items[i].pnpInterface;
|
||||
}
|
||||
|
@ -1167,6 +1167,8 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
|
|||
goto error;
|
||||
}
|
||||
|
||||
memset( winDsHostApi, 0, sizeof(PaWinDsHostApiRepresentation) ); /* ensure all fields are zeroed. especially winDsHostApi->allocations */
|
||||
|
||||
result = PaWinUtil_CoInitialize( paDirectSound, &winDsHostApi->comInitializationResult );
|
||||
if( result != paNoError )
|
||||
{
|
||||
|
@ -1306,7 +1308,7 @@ error:
|
|||
TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
||||
TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs );
|
||||
|
||||
Terminate( winDsHostApi );
|
||||
Terminate( (struct PaUtilHostApiRepresentation *)winDsHostApi );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1703,9 +1705,9 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
|||
unsigned long suggestedOutputLatencyFrames,
|
||||
double sampleRate, unsigned long userFramesPerBuffer )
|
||||
{
|
||||
unsigned long minimumPollingPeriodFrames = sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS;
|
||||
unsigned long maximumPollingPeriodFrames = sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS;
|
||||
unsigned long pollingJitterFrames = sampleRate * PA_DS_POLLING_JITTER_SECONDS;
|
||||
unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS);
|
||||
|
||||
if( userFramesPerBuffer == paFramesPerBufferUnspecified )
|
||||
{
|
||||
|
@ -1771,9 +1773,9 @@ static void CalculatePollingPeriodFrames( unsigned long hostBufferSizeFrames,
|
|||
unsigned long *pollingPeriodFrames,
|
||||
double sampleRate, unsigned long userFramesPerBuffer )
|
||||
{
|
||||
unsigned long minimumPollingPeriodFrames = sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS;
|
||||
unsigned long maximumPollingPeriodFrames = sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS;
|
||||
unsigned long pollingJitterFrames = sampleRate * PA_DS_POLLING_JITTER_SECONDS;
|
||||
unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS);
|
||||
|
||||
*pollingPeriodFrames = max( max(1, userFramesPerBuffer / 4), hostBufferSizeFrames / 16 );
|
||||
|
||||
|
@ -2471,6 +2473,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. */
|
||||
if( stream->outputUnderflowCount != previousUnderflowCount )
|
||||
stream->callbackFlags |= paOutputUnderflow;
|
||||
|
||||
|
@ -2536,7 +2540,7 @@ static int TimeSlice( PaWinDsStream *stream )
|
|||
{
|
||||
/*
|
||||
We don't currently add outputLatency here because it appears to produce worse
|
||||
results than non adding it. Need to do more testing to verify this.
|
||||
results than not adding it. Need to do more testing to verify this.
|
||||
*/
|
||||
/* timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency; */
|
||||
timeInfo.outputBufferDacTime = timeInfo.currentTime;
|
||||
|
@ -2729,7 +2733,7 @@ PA_THREAD_FUNC ProcessingThreadProc( void *pArg )
|
|||
LARGE_INTEGER dueTime;
|
||||
int timerPeriodMs;
|
||||
|
||||
timerPeriodMs = stream->pollingPeriodSeconds * MSECS_PER_SECOND;
|
||||
timerPeriodMs = (int)(stream->pollingPeriodSeconds * MSECS_PER_SECOND);
|
||||
if( timerPeriodMs < 1 )
|
||||
timerPeriodMs = 1;
|
||||
|
||||
|
@ -2953,7 +2957,7 @@ static PaError StartStream( PaStream *s )
|
|||
if( stream->streamRepresentation.streamCallback )
|
||||
{
|
||||
TIMECAPS timecaps;
|
||||
int timerPeriodMs = stream->pollingPeriodSeconds * MSECS_PER_SECOND;
|
||||
int timerPeriodMs = (int)(stream->pollingPeriodSeconds * MSECS_PER_SECOND);
|
||||
if( timerPeriodMs < 1 )
|
||||
timerPeriodMs = 1;
|
||||
|
||||
|
@ -2967,7 +2971,7 @@ static PaError StartStream( PaStream *s )
|
|||
if( timeGetDevCaps( &timecaps, sizeof(TIMECAPS) == MMSYSERR_NOERROR && timecaps.wPeriodMin > 0 ) )
|
||||
{
|
||||
/* aim for resolution 4 times higher than polling rate */
|
||||
stream->systemTimerResolutionPeriodMs = (stream->pollingPeriodSeconds * MSECS_PER_SECOND) / 4;
|
||||
stream->systemTimerResolutionPeriodMs = (UINT)((stream->pollingPeriodSeconds * MSECS_PER_SECOND) * .25);
|
||||
if( stream->systemTimerResolutionPeriodMs < timecaps.wPeriodMin )
|
||||
stream->systemTimerResolutionPeriodMs = timecaps.wPeriodMin;
|
||||
if( stream->systemTimerResolutionPeriodMs > timecaps.wPeriodMax )
|
||||
|
|
|
@ -1066,6 +1066,8 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
goto error;
|
||||
}
|
||||
|
||||
memset( paWasapi, 0, sizeof(PaWasapiHostApiRepresentation) ); /* ensure all fields are zeroed. especially paWasapi->allocations */
|
||||
|
||||
result = PaWinUtil_CoInitialize( paWASAPI, &paWasapi->comInitializationResult );
|
||||
if( result != paNoError )
|
||||
{
|
||||
|
@ -1248,7 +1250,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
goto error;
|
||||
}
|
||||
if (value.pwszVal)
|
||||
wcstombs(deviceName, value.pwszVal, MAX_STR_LEN-1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, value.pwszVal, (int)wcslen(value.pwszVal), deviceName, MAX_STR_LEN-1, 0, 0);
|
||||
else
|
||||
_snprintf(deviceName, MAX_STR_LEN-1, "baddev%d", i);
|
||||
deviceInfo->name = deviceName;
|
||||
|
@ -2211,11 +2213,15 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
if (framesPerLatency == 0)
|
||||
framesPerLatency = MakeFramesFromHns(pInfo->DefaultDevicePeriod, pSub->wavex.Format.nSamplesPerSec);
|
||||
|
||||
//! Exclusive Input stream renders data in 6 packets, we must set then the size of
|
||||
//! single packet, total buffer size, e.g. required latency will be PacketSize * 6
|
||||
// Exclusive Input stream renders data in 6 packets, we must set then the size of
|
||||
// single packet, total buffer size, e.g. required latency will be PacketSize * 6
|
||||
if (!output && (pSub->shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE))
|
||||
{
|
||||
framesPerLatency /= WASAPI_PACKETS_PER_INPUT_BUFFER;
|
||||
// Do it only for Polling mode
|
||||
if ((pSub->streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) == 0)
|
||||
{
|
||||
framesPerLatency /= WASAPI_PACKETS_PER_INPUT_BUFFER;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate aligned period
|
||||
|
@ -3460,7 +3466,7 @@ static PaError ReadStream( PaStream* s, void *_buffer, unsigned long frames )
|
|||
|
||||
// Limit desired to amount of requested frames
|
||||
desired = available;
|
||||
if (desired > frames)
|
||||
if ((UINT32)desired > frames)
|
||||
desired = frames;
|
||||
|
||||
// Get pointers to read regions
|
||||
|
@ -4795,13 +4801,15 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
|
|||
// output
|
||||
if (stream->bufferMode == paUtilFixedHostBufferSize)
|
||||
{
|
||||
if (frames >= stream->out.framesPerBuffer)
|
||||
while (frames >= stream->out.framesPerBuffer)
|
||||
{
|
||||
if ((hr = ProcessOutputBuffer(stream, processor, stream->out.framesPerBuffer)) != S_OK)
|
||||
{
|
||||
LogHostError(hr);
|
||||
goto thread_error;
|
||||
}
|
||||
|
||||
frames -= stream->out.framesPerBuffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,12 +3,15 @@ Notes about WDM-KS host API
|
|||
|
||||
Status history
|
||||
--------------
|
||||
16th January 2011:
|
||||
Added support for WaveRT device API (Vista and later) for even lesser
|
||||
latency support.
|
||||
|
||||
10th November 2005:
|
||||
Made following changes:
|
||||
* OpenStream: Try all PaSampleFormats internally if the the chosen
|
||||
format is not supported natively. This fixed several problems
|
||||
with soundcards that soundcards that did not take kindly to
|
||||
using 24-bit 3-byte formats.
|
||||
with soundcards that did not take kindly to using 24-bit 3-byte formats.
|
||||
* OpenStream: Make the minimum framesPerHostIBuffer (and framesPerHostOBuffer)
|
||||
the default frameSize for the playback/recording pin.
|
||||
* ProcessingThread: Added a switch to only call PaUtil_EndBufferProcessing
|
||||
|
@ -71,7 +74,7 @@ In PortAudio terms, this means having a stream Open on a WDMKS device.
|
|||
Usage
|
||||
-----
|
||||
To add the WDMKS backend to your program which is already using
|
||||
PortAudio, you must undefine PA_NO_WDMKS from your build file,
|
||||
PortAudio, you must define PA_USE_WDMKS=1 in your build file,
|
||||
and include the pa_win_wdmks\pa_win_wdmks.c into your build.
|
||||
The file should compile in both C and C++.
|
||||
You will need a DirectX SDK installed on your system for the
|
||||
|
|
Loading…
Reference in New Issue