Externals: remove PortAudio

This commit is contained in:
Michael Maltese 2017-03-22 15:58:57 -07:00
parent 48d6168c99
commit 34ad1eb547
110 changed files with 2 additions and 82506 deletions

View File

@ -491,32 +491,6 @@ if(ENCODE_FRAMEDUMPS)
endif() endif()
endif() endif()
if(NOT ANDROID)
set(PORTAUDIO_FOUND TRUE)
add_definitions(-DHAVE_PORTAUDIO=1)
if(NOT APPLE)
set(CMAKE_REQUIRED_LIBRARIES portaudio)
CHECK_CXX_SOURCE_RUNS(
"#include <portaudio.h>
int main(int argc, char **argv)
{ if(Pa_GetVersion() >= 1890) return 0; else return 1; }"
SYSTEM_PORTAUDIO)
unset(CMAKE_REQUIRED_LIBRARIES)
endif()
if(SYSTEM_PORTAUDIO AND NOT APPLE)
message(STATUS "Using shared PortAudio for mic support")
set(PORTAUDIO_LIBRARIES portaudio)
else()
message(STATUS "Using static PortAudio from Externals for mic support")
option(PA_USE_ASIO "Enable PortAudio support for ASIO" OFF)
option(PA_USE_DS "Enable PortAudio support for DirectSound" OFF)
option(PA_USE_WDMKS "Enable PortAudio support for WDMKS" OFF)
add_subdirectory(Externals/portaudio EXCLUDE_FROM_ALL)
set(PORTAUDIO_LIBRARIES portaudio_static)
endif()
endif()
if(OPROFILING) if(OPROFILING)
find_package(OProfile) find_package(OProfile)
if(OPROFILE_FOUND) if(OPROFILE_FOUND)

View File

@ -46,8 +46,6 @@ Dolphin includes or links code of the following third-party software projects:
[GPLv2](http://pearpc.cvs.sourceforge.net/viewvc/pearpc/pearpc/COPYING?view=markup) (with permission by the author to license under GPLv2+) [GPLv2](http://pearpc.cvs.sourceforge.net/viewvc/pearpc/pearpc/COPYING?view=markup) (with permission by the author to license under GPLv2+)
- [mbed TLS](https://tls.mbed.org/): - [mbed TLS](https://tls.mbed.org/):
[Apache 2.0](https://github.com/ARMmbed/mbedtls/blob/development/LICENSE) [Apache 2.0](https://github.com/ARMmbed/mbedtls/blob/development/LICENSE)
- [PortAudio](http://www.portaudio.com/):
[MIT](http://www.portaudio.com/license.html)
- [PulseAudio](http://www.freedesktop.org/wiki/Software/PulseAudio/): - [PulseAudio](http://www.freedesktop.org/wiki/Software/PulseAudio/):
[LGPLv2.1+](http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/LICENSE) [LGPLv2.1+](http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/LICENSE)
- [Qt5](http://qt-project.org/): - [Qt5](http://qt-project.org/):

View File

@ -1,409 +0,0 @@
# $Id: $
#
# For a "How-To" please refer to the Portaudio documentation at:
# http://www.portaudio.com/trac/wiki/TutorialDir/Compile/CMake
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# Check if the user is building PortAudio stand-alone or as part of a larger
# project. If this is part of a larger project (i.e. the CMakeLists.txt has
# been imported by some other CMakeLists.txt), we don't want to trump over
# the top of that project's global settings.
IF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_LIST_DIR})
IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
MESSAGE(STATUS "Setting CMAKE_BUILD_TYPE type to 'Debug' as none was specified.")
SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
ENDIF()
PROJECT(portaudio)
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
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()
ENDFOREACH()
ENDIF()
ENDIF()
ENDIF()
SET(PA_PKGCONFIG_VERSION 19)
# Most of the code from this point onwards is related to populating the
# following variables:
# PA_PUBLIC_INCLUDES - This contains the list of public PortAudio header
# files. These files will be copied into /include paths on Unix'y
# systems when "make install" is invoked.
# PA_PRIVATE_INCLUDES - This contains the list of header files which
# are not part of PortAudio, but are required by the various hostapis.
# It is only used by CMake IDE generators (like Visual Studio) to
# provide quick-links to useful headers. It has no impact on build
# output.
# PA_PRIVATE_INCLUDE_PATHS - This contains the list of include paths which
# will be passed to the compiler while PortAudio is being built which
# are not required by applications using the PortAudio API.
# PA_PRIVATE_COMPILE_DEFINITIONS - This contains a list of preprocessor
# macro definitions which will be set when compiling PortAudio source
# files.
# PA_SOURCES - This contains the list of source files which will be built
# into the static and shared PortAudio libraries.
# PA_NON_UNICODE_SOURCES - This also contains a list of source files which
# will be build into the static and shared PortAudio libraries. However,
# these sources will not have any unicode compiler definitions added
# to them. This list should only contain external source dependencies.
# PA_EXTRA_SHARED_SOURCES - Contains a list of extra files which will be
# associated only with the shared PortAudio library. This only seems
# relevant for Windows shared libraries which require a list of export
# symbols.
# Where other PA_* variables are set, these are almost always only used to
# preserve the historic SOURCE_GROUP behavior (which again only has an impact
# on IDE-style generators for visual appearance) or store the output of
# find_library() calls.
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})
SET(PA_PUBLIC_INCLUDES include/portaudio.h)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake_support)
SET(PA_SKELETON_SOURCES src/hostapi/skeleton/pa_hostapi_skeleton.c)
SOURCE_GROUP("hostapi\\skeleton" ${PA_SKELETON_SOURCES})
SET(PA_SOURCES ${PA_COMMON_SOURCES} ${PA_SKELETON_SOURCES})
SET(PA_PRIVATE_INCLUDE_PATHS src/common ${CMAKE_CURRENT_BINARY_DIR})
IF(WIN32)
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} _CRT_SECURE_NO_WARNINGS)
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)
SET(PA_PLATFORM_INCLUDES
src/os/win/pa_win_coinitialize.h
src/os/win/pa_win_wdmks_utils.h)
IF(MSVC)
SET(PA_PLATFORM_SOURCES ${PA_PLATFORM_SOURCES} src/os/win/pa_x86_plain_converters.c)
SET(PA_PLATFORM_INCLUDES ${PA_PLATFORM_INCLUDES} src/os/win/pa_x86_plain_converters.h)
ELSE()
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} _WIN32_WINNT=0x0501 WINVER=0x0501)
SET(DEF_EXCLUDE_X86_PLAIN_CONVERTERS ";")
ENDIF()
SOURCE_GROUP("os\\win" FILES ${PA_PLATFORM_SOURCES} ${PA_PLATFORM_INCLUDES})
SET(PA_SOURCES ${PA_SOURCES} ${PA_PLATFORM_SOURCES})
SET(PA_PRIVATE_INCLUDES ${PA_PRIVATE_INCLUDES} ${PA_PLATFORM_INCLUDES})
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} src/os/win)
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} winmm)
# 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()
OPTION(PA_USE_ASIO "Enable support for ASIO" OFF)
ENDIF()
IF(PA_USE_ASIO)
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} ${ASIOSDK_ROOT_DIR}/common)
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} ${ASIOSDK_ROOT_DIR}/host)
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} ${ASIOSDK_ROOT_DIR}/host/pc)
SET(PA_ASIO_SOURCES src/hostapi/asio/pa_asio.cpp src/hostapi/asio/iasiothiscallresolver.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})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_asio.h)
SET(PA_SOURCES ${PA_SOURCES} ${PA_ASIO_SOURCES})
SET(PA_NON_UNICODE_SOURCES ${PA_NON_UNICODE_SOURCES} ${PA_ASIOSDK_SOURCES})
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ole32 uuid)
ELSE()
# Set variables for DEF file expansion
SET(DEF_EXCLUDE_ASIO_SYMBOLS ";")
ENDIF()
# Try to find DirectX SDK
FIND_PACKAGE(DXSDK)
IF(DXSDK_FOUND)
OPTION(PA_USE_DS "Enable support for DirectSound" ON)
ELSE()
OPTION(PA_USE_DS "Enable support for DirectSound" OFF)
ENDIF()
IF(PA_USE_DS)
OPTION(PA_USE_DIRECTSOUNDFULLDUPLEXCREATE "Use DirectSound full duplex create" ON)
MARK_AS_ADVANCED(PA_USE_DIRECTSOUNDFULLDUPLEXCREATE)
IF(PA_USE_DIRECTSOUNDFULLDUPLEXCREATE)
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE)
ENDIF()
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} ${DXSDK_INCLUDE_DIR})
SET(PA_DS_INCLUDES 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})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_win_ds.h)
SET(PA_PRIVATE_INCLUDES ${PA_PRIVATE_INCLUDES} ${PA_DS_INCLUDES})
SET(PA_SOURCES ${PA_SOURCES} ${PA_DS_SOURCES})
# If we use DirectSound, we need this for the library to be found (if not in VS project settings)
IF(DXSDK_FOUND)
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ${DXSDK_DSOUND_LIBRARY})
ENDIF()
ENDIF()
OPTION(PA_USE_WMME "Enable support for MME" ON)
IF(PA_USE_WMME)
SET(PA_WMME_SOURCES src/hostapi/wmme/pa_win_wmme.c)
SOURCE_GROUP("hostapi\\wmme" FILES ${PA_WMME_SOURCES})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_win_wmme.h)
SET(PA_SOURCES ${PA_SOURCES} ${PA_WMME_SOURCES})
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ole32 uuid)
ENDIF()
IF(MSVS)
OPTION(PA_USE_WASAPI "Enable support for WASAPI" ON)
ELSE()
# I was unable to get WASAPI to compile outside of Visual Studio. If
# anyone can figure out how to make this work with MinGW, please fix me.
SET(PA_USE_WASAPI OFF)
ENDIF()
IF(PA_USE_WASAPI)
SET(PA_WASAPI_SOURCES src/hostapi/wasapi/pa_win_wasapi.c)
SOURCE_GROUP("hostapi\\wasapi" FILES ${PA_WASAPI_SOURCES})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_win_wasapi.h)
SET(PA_SOURCES ${PA_SOURCES} ${PA_WASAPI_SOURCES})
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ole32 uuid)
IF(NOT MSVC)
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} src/hostapi/wasapi/mingw-include)
ENDIF()
ELSE()
SET(DEF_EXCLUDE_WASAPI_SYMBOLS ";")
ENDIF()
OPTION(PA_USE_WDMKS "Enable support for WDMKS" ON)
IF(PA_USE_WDMKS)
SET(PA_WDMKS_SOURCES src/hostapi/wdmks/pa_win_wdmks.c)
SOURCE_GROUP("hostapi\\wdmks" FILES ${PA_WDMKS_SOURCES})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_win_wdmks.h)
SET(PA_SOURCES ${PA_SOURCES} ${PA_WDMKS_SOURCES})
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} setupapi ole32 uuid)
ENDIF()
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_WDMKS_DEVICE_INFO)
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PAWIN_USE_WDMKS_DEVICE_INFO)
ENDIF()
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_FILE(cmake_support/options_cmake.h.in ${CMAKE_CURRENT_BINARY_DIR}/options_cmake.h @ONLY)
SET(PA_PRIVATE_INCLUDES ${PA_PRIVATE_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}/options_cmake.h)
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PORTAUDIO_CMAKE_GENERATED)
SOURCE_GROUP("cmake_generated" FILES ${CMAKE_CURRENT_BINARY_DIR}/portaudio_cmake.def ${CMAKE_CURRENT_BINARY_DIR}/options_cmake.h)
SET(PA_EXTRA_SHARED_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/portaudio_cmake.def)
ELSE()
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} src/os/unix)
SET(PA_PLATFORM_SOURCES src/os/unix/pa_unix_hostapis.c src/os/unix/pa_unix_util.c)
SOURCE_GROUP("os\\unix" FILES ${PA_PLATFORM_SOURCES})
SET(PA_SOURCES ${PA_SOURCES} ${PA_PLATFORM_SOURCES})
IF(APPLE)
SET(CMAKE_MACOSX_RPATH 1)
OPTION(PA_USE_COREAUDIO "Enable support for CoreAudio" ON)
IF(PA_USE_COREAUDIO)
SET(PA_COREAUDIO_SOURCES
src/hostapi/coreaudio/pa_mac_core.c
src/hostapi/coreaudio/pa_mac_core_blocking.c
src/hostapi/coreaudio/pa_mac_core_utilities.c)
SET(PA_COREAUDIO_INCLUDES
src/hostapi/coreaudio/pa_mac_core_blocking.h
src/hostapi/coreaudio/pa_mac_core_utilities.h)
SOURCE_GROUP("hostapi\\coreaudio" FILES ${PA_COREAUDIO_SOURCES} ${PA_COREAUDIO_INCLUDES})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_mac_core.h)
SET(PA_PRIVATE_INCLUDES ${PA_PRIVATE_INCLUDES} ${PA_COREAUDIO_INCLUDES})
SET(PA_SOURCES ${PA_SOURCES} ${PA_COREAUDIO_SOURCES})
FIND_LIBRARY(COREAUDIO_LIBRARY CoreAudio REQUIRED)
FIND_LIBRARY(AUDIOTOOLBOX_LIBRARY AudioToolbox REQUIRED)
FIND_LIBRARY(AUDIOUNIT_LIBRARY AudioUnit REQUIRED)
FIND_LIBRARY(CARBON_LIBRARY Carbon REQUIRED)
MARK_AS_ADVANCED(COREAUDIO_LIBRARY AUDIOTOOLBOX_LIBRARY AUDIOUNIT_LIBRARY CARBON_LIBRARY)
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ${COREAUDIO_LIBRARY} ${AUDIOTOOLBOX_LIBRARY} ${AUDIOUNIT_LIBRARY} ${CARBON_LIBRARY})
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PA_USE_COREAUDIO)
SET(PA_PKGCONFIG_LDFLAGS "${PA_PKGCONFIG_LDFLAGS} -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon")
ENDIF()
ELSEIF(UNIX)
FIND_PACKAGE(Jack)
IF(JACK_FOUND)
OPTION(PA_USE_JACK "Enable support for Jack" ON)
ELSE()
OPTION(PA_USE_JACK "Enable support for Jack" OFF)
ENDIF()
IF(PA_USE_JACK)
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} ${JACK_INCLUDE_DIRS})
SET(PA_JACK_SOURCES src/hostapi/jack/pa_jack.c)
SOURCE_GROUP("hostapi\\JACK" FILES ${PA_JACK_SOURCES})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_jack.h)
SET(PA_SOURCES ${PA_SOURCES} ${PA_JACK_SOURCES})
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PA_USE_JACK)
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ${JACK_LIBRARIES})
SET(PA_PKGCONFIG_LDFLAGS "${PA_PKGCONFIG_LDFLAGS} -ljack")
ENDIF()
FIND_PACKAGE(ALSA)
IF(ALSA_FOUND)
OPTION(PA_USE_ALSA "Enable support for ALSA" ON)
ELSE()
OPTION(PA_USE_ALSA "Enable support for ALSA" OFF)
ENDIF()
IF(PA_USE_ALSA)
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} ${ALSA_INCLUDE_DIRS})
SET(PA_ALSA_SOURCES src/hostapi/alsa/pa_linux_alsa.c)
SOURCE_GROUP("hostapi\\ALSA" FILES ${PA_ALSA_SOURCES})
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_linux_alsa.h)
SET(PA_SOURCES ${PA_SOURCES} ${PA_ALSA_SOURCES})
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PA_USE_ALSA)
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ${ALSA_LIBRARIES})
SET(PA_PKGCONFIG_LDFLAGS "${PA_PKGCONFIG_LDFLAGS} -lasound")
ENDIF()
ENDIF()
find_package(Threads)
SET(PA_PKGCONFIG_LDFLAGS "${PA_PKGCONFIG_LDFLAGS} -lm")
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} m Threads::Threads)
ENDIF()
SOURCE_GROUP("include" FILES ${PA_PUBLIC_INCLUDES})
SET(PA_INCLUDES ${PA_PRIVATE_INCLUDES} ${PA_PUBLIC_INCLUDES})
IF(WIN32)
OPTION(PA_UNICODE_BUILD "Enable Portaudio Unicode build" ON)
IF(PA_UNICODE_BUILD)
SET_SOURCE_FILES_PROPERTIES(${PA_SOURCES} PROPERTIES COMPILE_DEFINITIONS "UNICODE;_UNICODE")
ENDIF()
ENDIF()
OPTION(PA_ENABLE_DEBUG_OUTPUT "Enable debug output for Portaudio" OFF)
IF(PA_ENABLE_DEBUG_OUTPUT)
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PA_ENABLE_DEBUG_OUTPUT)
ENDIF()
INCLUDE(TestBigEndian)
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
IF(IS_BIG_ENDIAN)
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PA_BIG_ENDIAN)
ELSE()
SET(PA_PRIVATE_COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS} PA_LITTLE_ENDIAN)
ENDIF()
#ADD_LIBRARY(portaudio SHARED ${PA_INCLUDES} ${PA_COMMON_INCLUDES} ${PA_SOURCES} ${PA_NON_UNICODE_SOURCES} ${PA_EXTRA_SHARED_SOURCES})
#SET_PROPERTY(TARGET portaudio APPEND_STRING PROPERTY COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS})
#TARGET_INCLUDE_DIRECTORIES(portaudio BEFORE PRIVATE ${PA_PRIVATE_INCLUDE_PATHS})
#TARGET_INCLUDE_DIRECTORIES(portaudio BEFORE PUBLIC include)
#TARGET_LINK_LIBRARIES(portaudio ${PA_LIBRARY_DEPENDENCIES})
ADD_LIBRARY(portaudio_static STATIC ${PA_INCLUDES} ${PA_COMMON_INCLUDES} ${PA_SOURCES} ${PA_NON_UNICODE_SOURCES})
SET_PROPERTY(TARGET portaudio_static APPEND_STRING PROPERTY COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS})
TARGET_INCLUDE_DIRECTORIES(portaudio_static BEFORE PRIVATE ${PA_PRIVATE_INCLUDE_PATHS})
TARGET_INCLUDE_DIRECTORIES(portaudio_static BEFORE PUBLIC include)
TARGET_LINK_LIBRARIES(portaudio_static ${PA_LIBRARY_DEPENDENCIES})
IF(WIN32 AND MSVC)
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()
ELSE()
SET(TARGET_POSTFIX x86)
IF(PA_CONFIG_LIB_OUTPUT_PATH)
SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin/Win32)
ENDIF()
ENDIF()
#SET_TARGET_PROPERTIES(portaudio PROPERTIES OUTPUT_NAME portaudio_${TARGET_POSTFIX} FOLDER "Portaudio")
SET_TARGET_PROPERTIES(portaudio_static PROPERTIES OUTPUT_NAME portaudio_static_${TARGET_POSTFIX} FOLDER "Portaudio")
ELSE()
IF(APPLE AND CMAKE_VERSION VERSION_GREATER 3.4.2)
OPTION(PA_OUTPUT_OSX_FRAMEWORK "Generate an OS X framework instead of the simple library" OFF)
IF(PA_OUTPUT_OSX_FRAMEWORK)
SET_TARGET_PROPERTIES(portaudio PROPERTIES
FRAMEWORK TRUE
MACOSX_FRAMEWORK_IDENTIFIER com.portaudio
FRAMEWORK_VERSION A
PUBLIC_HEADER "${PA_PUBLIC_INCLUDES}"
VERSION 19.0
SOVERSION 19.0)
ENDIF()
ENDIF()
IF(NOT PA_OUTPUT_OSX_FRAMEWORK)
CONFIGURE_FILE(cmake_support/portaudio-2.0.pc.in ${CMAKE_CURRENT_BINARY_DIR}/portaudio-2.0.pc @ONLY)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/portaudio-2.0.pc DESTINATION lib/pkgconfig)
INSTALL(FILES ${PA_PUBLIC_INCLUDES} DESTINATION include)
#INSTALL(TARGETS portaudio DESTINATION lib)
ENDIF()
ENDIF()
# Prepared for inclusion of test files
OPTION(PA_BUILD_TESTS "Include test projects" OFF)
IF(PA_BUILD_TESTS)
SUBDIRS(test)
ENDIF()
# Prepared for inclusion of test files
OPTION(PA_BUILD_EXAMPLES "Include example projects" OFF)
IF(PA_BUILD_EXAMPLES)
SUBDIRS(examples)
ENDIF()

View File

@ -1,6 +0,0 @@
This directory contains the Visual Studio project files which are used to build portaudio.
* portaudio's files were very old and messy
* Makes it easier to update portaudio in the future
* Uses dolphin's VSProps, so we know it's properly compatible
See full portaudio distribution for instructions about building and using portaudio.

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0A18A071-125E-442F-AFF7-A3F68ABECF99}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\Source\VSProps\Base.props" />
<Import Project="..\..\..\Source\VSProps\ClDisableAllWarnings.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\src\common;..\include;.\;..\src\os\win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>PA_ENABLE_DEBUG_OUTPUT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\common\pa_allocation.c" />
<ClCompile Include="..\src\common\pa_converters.c" />
<ClCompile Include="..\src\common\pa_cpuload.c" />
<ClCompile Include="..\src\common\pa_debugprint.c" />
<ClCompile Include="..\src\common\pa_dither.c" />
<ClCompile Include="..\src\common\pa_front.c" />
<ClCompile Include="..\src\hostapi\skeleton\pa_hostapi_skeleton.c" />
<ClCompile Include="..\src\common\pa_process.c" />
<ClCompile Include="..\src\common\pa_ringbuffer.c" />
<ClCompile Include="..\src\common\pa_stream.c" />
<ClCompile Include="..\src\common\pa_trace.c" />
<ClCompile Include="..\src\hostapi\wmme\pa_win_wmme.c" />
<ClCompile Include="..\src\hostapi\wasapi\pa_win_wasapi.c" />
<ClCompile Include="..\src\os\win\pa_win_coinitialize.c" />
<ClCompile Include="..\src\os\win\pa_win_hostapis.c" />
<ClCompile Include="..\src\os\win\pa_win_util.c" />
<ClCompile Include="..\src\os\win\pa_win_waveformat.c" />
<ClCompile Include="..\src\os\win\pa_win_wdmks_utils.c" />
<ClCompile Include="..\src\os\win\pa_x86_plain_converters.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pa_win_wasapi.h" />
<ClInclude Include="..\include\pa_win_waveformat.h" />
<ClInclude Include="..\include\pa_win_wmme.h" />
<ClInclude Include="..\include\portaudio.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,110 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{69112e69-92e4-40c1-aa5b-e4c4780ade42}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Source Files\common">
<UniqueIdentifier>{ddf0cf9b-f2df-4549-a447-8d7c4c2128d7}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\hostapi">
<UniqueIdentifier>{219121eb-0c81-4948-a94c-6802cf152776}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\hostapi\dsound">
<UniqueIdentifier>{17688226-7728-4556-83a7-8e85b561ccca}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\hostapi\wmme">
<UniqueIdentifier>{520ee766-8582-402e-a935-bdbcaa0d44de}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\hostapi\wasapi">
<UniqueIdentifier>{3891bf2e-9681-4394-be07-88e0a3fd2a68}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\hostapi\wdmks">
<UniqueIdentifier>{16791044-a8a5-4f21-b032-08245e52777a}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\os">
<UniqueIdentifier>{bde5e4fb-71f2-4cdf-8879-5370d0e12697}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\os\win">
<UniqueIdentifier>{f1e8b583-742d-46a2-ac7f-060aabdc3a2c}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{d8832c7e-2dd0-48e7-8227-23b0d04c1879}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\common\pa_allocation.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_converters.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_cpuload.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_debugprint.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_dither.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_front.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\hostapi\skeleton\pa_hostapi_skeleton.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_process.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_ringbuffer.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_stream.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\common\pa_trace.c">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\src\hostapi\wmme\pa_win_wmme.c">
<Filter>Source Files\hostapi\wmme</Filter>
</ClCompile>
<ClCompile Include="..\src\hostapi\wasapi\pa_win_wasapi.c">
<Filter>Source Files\hostapi\wasapi</Filter>
</ClCompile>
<ClCompile Include="..\src\os\win\pa_win_coinitialize.c">
<Filter>Source Files\os\win</Filter>
</ClCompile>
<ClCompile Include="..\src\os\win\pa_win_hostapis.c">
<Filter>Source Files\os\win</Filter>
</ClCompile>
<ClCompile Include="..\src\os\win\pa_win_util.c">
<Filter>Source Files\os\win</Filter>
</ClCompile>
<ClCompile Include="..\src\os\win\pa_win_waveformat.c">
<Filter>Source Files\os\win</Filter>
</ClCompile>
<ClCompile Include="..\src\os\win\pa_win_wdmks_utils.c">
<Filter>Source Files\os\win</Filter>
</ClCompile>
<ClCompile Include="..\src\os\win\pa_x86_plain_converters.c">
<Filter>Source Files\os\win</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pa_win_wasapi.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\pa_win_waveformat.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\pa_win_wmme.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\portaudio.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,41 +0,0 @@
# $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
)

View File

@ -1,59 +0,0 @@
# $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
)

View File

@ -1,41 +0,0 @@
# - Try to find jack
# Once done this will define
# JACK_FOUND - System has jack
# JACK_INCLUDE_DIRS - The jack include directories
# JACK_LIBRARIES - The libraries needed to use jack
# JACK_DEFINITIONS - Compiler switches required for using jack
if (JACK_LIBRARIES AND JACK_INCLUDE_DIRS)
# in cache already
set(JACK_FOUND TRUE)
else (JACK_LIBRARIES AND JACK_INCLUDE_DIRS)
set(JACK_DEFINITIONS "")
# Look for pkg-config and use it (if available) to find package
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_search_module(JACK QUIET jack)
endif (PKG_CONFIG_FOUND)
if (NOT JACK_FOUND)
find_path(JACK_INCLUDE_DIR jack/jack.h HINTS ${JACK_INCLUDEDIR} ${JACK_INCLUDE_DIRS} PATH_SUFFIXES jack)
find_library(JACK_LIBRARY NAMES jack HINTS ${JACK_LIBDIR} ${JACK_LIBRARY_DIRS})
set(JACK_LIBRARIES ${JACK_LIBRARY})
set(JACK_INCLUDE_DIRS ${JACK_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
# Set JACK_FOUND if the library and include paths were found
find_package_handle_standard_args(jack DEFAULT_MSG JACK_LIBRARY JACK_INCLUDE_DIR)
# Don't show include/library paths in cmake GUI
mark_as_advanced(JACK_INCLUDE_DIR JACK_LIBRARY)
endif (NOT JACK_FOUND)
endif (JACK_LIBRARIES AND JACK_INCLUDE_DIRS)

View File

@ -1,31 +0,0 @@
/* $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

View File

@ -1,12 +0,0 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: PortAudio
Description: Portable audio I/O
Requires:
Version: @PA_PKGCONFIG_VERSION@
Libs: -L${libdir} -lportaudio @PA_PKGCONFIG_LDFLAGS@
Cflags: -I${includedir} @PA_PKGCONFIG_CFLAGS@

View File

@ -1,53 +0,0 @@
; $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
@DEF_EXCLUDE_X86_PLAIN_CONVERTERS@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

View File

@ -1,150 +0,0 @@
#ifndef PA_ASIO_H
#define PA_ASIO_H
/*
* $Id$
* PortAudio Portable Real-Time Audio Library
* ASIO specific extensions
*
* Copyright (c) 1999-2000 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 ASIO-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/** Retrieve legal native buffer sizes for the specificed device, in sample frames.
@param device The global index of the 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.
@param preferredBufferSizeFrames A pointer to the location which will receive the preferred buffer size value.
@param granularity A pointer to the location which will receive the "granularity". This value determines
the step size used to compute the legal values between minBufferSizeFrames and maxBufferSizeFrames.
If granularity is -1 then available buffer size values are powers of two.
@see ASIOGetBufferSize in the ASIO SDK.
@note: this function used to be called PaAsio_GetAvailableLatencyValues. There is a
#define that maps PaAsio_GetAvailableLatencyValues to this function for backwards compatibility.
*/
PaError PaAsio_GetAvailableBufferSizes( PaDeviceIndex device,
long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity );
/** Backwards compatibility alias for PaAsio_GetAvailableBufferSizes
@see PaAsio_GetAvailableBufferSizes
*/
#define PaAsio_GetAvailableLatencyValues PaAsio_GetAvailableBufferSizes
/** Display the ASIO control panel for the specified device.
@param device The global index of the device whose control panel is to be displayed.
@param systemSpecific On Windows, the calling application's main window handle,
on Macintosh this value should be zero.
*/
PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific );
/** Retrieve a pointer to a string containing the name of the specified
input channel. The string is valid until Pa_Terminate is called.
The string will be no longer than 32 characters including the null terminator.
*/
PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
const char** channelName );
/** Retrieve a pointer to a string containing the name of the specified
input channel. The string is valid until Pa_Terminate is called.
The string will be no longer than 32 characters including the null terminator.
*/
PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
const char** channelName );
/** Set the sample rate of an open paASIO stream.
@param stream The stream to operate on.
@param sampleRate The new sample rate.
Note that this function may fail if the stream is alredy running and the
ASIO driver does not support switching the sample rate of a running stream.
Returns paIncompatibleStreamHostApi if stream is not a paASIO stream.
*/
PaError PaAsio_SetStreamSampleRate( PaStream* stream, double sampleRate );
#define paAsioUseChannelSelectors (0x01)
typedef struct PaAsioStreamInfo{
unsigned long size; /**< sizeof(PaAsioStreamInfo) */
PaHostApiTypeId hostApiType; /**< paASIO */
unsigned long version; /**< 1 */
unsigned long flags;
/* Support for opening only specific channels of an ASIO device.
If the paAsioUseChannelSelectors flag is set, channelSelectors is a
pointer to an array of integers specifying the device channels to use.
When used, the length of the channelSelectors array must match the
corresponding channelCount parameter to Pa_OpenStream() otherwise a
crash may result.
The values in the selectors array must specify channels within the
range of supported channels for the device or paInvalidChannelCount will
result.
*/
int *channelSelectors;
}PaAsioStreamInfo;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_ASIO_H */

View File

@ -1,77 +0,0 @@
#ifndef PA_JACK_H
#define PA_JACK_H
/*
* $Id:
* PortAudio Portable Real-Time Audio Library
* JACK-specific extensions
*
* Copyright (c) 1999-2000 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 JACK-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Set the JACK client name.
*
* During Pa_Initialize, When PA JACK connects as a client of the JACK server, it requests a certain
* name, which is for instance prepended to port names. By default this name is "PortAudio". The
* JACK server may append a suffix to the client name, in order to avoid clashes among clients that
* try to connect with the same name (e.g., different PA JACK clients).
*
* This function must be called before Pa_Initialize, otherwise it won't have any effect. Note that
* the string is not copied, but instead referenced directly, so it must not be freed for as long as
* PA might need it.
* @sa PaJack_GetClientName
*/
PaError PaJack_SetClientName( const char* name );
/** Get the JACK client name used by PA JACK.
*
* The caller is responsible for freeing the returned pointer.
*/
PaError PaJack_GetClientName(const char** clientName);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,107 +0,0 @@
#ifndef PA_LINUX_ALSA_H
#define PA_LINUX_ALSA_H
/*
* $Id$
* PortAudio Portable Real-Time Audio Library
* ALSA-specific extensions
*
* Copyright (c) 1999-2000 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 ALSA-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct PaAlsaStreamInfo
{
unsigned long size;
PaHostApiTypeId hostApiType;
unsigned long version;
const char *deviceString;
}
PaAlsaStreamInfo;
/** Initialize host API specific structure, call this before setting relevant attributes. */
void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info );
/** Instruct whether to enable real-time priority when starting the audio thread.
*
* If this is turned on by the stream is started, the audio callback thread will be created
* with the FIFO scheduling policy, which is suitable for realtime operation.
**/
void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable );
#if 0
void PaAlsa_EnableWatchdog( PaStream *s, int enable );
#endif
/** Get the ALSA-lib card index of this stream's input device. */
PaError PaAlsa_GetStreamInputCard( PaStream *s, int *card );
/** Get the ALSA-lib card index of this stream's output device. */
PaError PaAlsa_GetStreamOutputCard( PaStream *s, int *card );
/** Set the number of periods (buffer fragments) to configure devices with.
*
* By default the number of periods is 4, this is the lowest number of periods that works well on
* the author's soundcard.
* @param numPeriods The number of periods.
*/
PaError PaAlsa_SetNumPeriods( int numPeriods );
/** Set the maximum number of times to retry opening busy device (sleeping for a
* short interval inbetween).
*/
PaError PaAlsa_SetRetriesBusy( int retries );
/** Set the path and name of ALSA library file if PortAudio is configured to load it dynamically (see
* PA_ALSA_DYNAMIC). This setting will overwrite the default name set by PA_ALSA_PATHNAME define.
* @param pathName Full path with filename. Only filename can be used, but dlopen() will lookup default
* searchable directories (/usr/lib;/usr/local/lib) then.
*/
void PaAlsa_SetLibraryPathName( const char *pathName );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,191 +0,0 @@
#ifndef PA_MAC_CORE_H
#define PA_MAC_CORE_H
/*
* PortAudio Portable Real-Time Audio Library
* Macintosh Core Audio specific extensions
* portaudio.h should be included before this file.
*
* Copyright (c) 2005-2006 Bjorn Roche
*
* 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 CoreAudio-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* A pointer to a paMacCoreStreamInfo may be passed as
* the hostApiSpecificStreamInfo in the PaStreamParameters struct
* when opening a stream or querying the format. Use NULL, for the
* defaults. Note that for duplex streams, flags for input and output
* should be the same or behaviour is undefined.
*/
typedef struct
{
unsigned long size; /**size of whole structure including this header */
PaHostApiTypeId hostApiType; /**host API for which this data is intended */
unsigned long version; /**structure version */
unsigned long flags; /** flags to modify behaviour */
SInt32 const * channelMap; /** Channel map for HAL channel mapping , if not needed, use NULL;*/
unsigned long channelMapSize; /** Channel map size for HAL channel mapping , if not needed, use 0;*/
} PaMacCoreStreamInfo;
/**
* Functions
*/
/** Use this function to initialize a paMacCoreStreamInfo struct
* using the requested flags. Note that channel mapping is turned
* off after a call to this function.
* @param data The datastructure to initialize
* @param flags The flags to initialize the datastructure with.
*/
void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, unsigned long flags );
/** call this after pa_SetupMacCoreStreamInfo to use channel mapping as described in notes.txt.
* @param data The stream info structure to assign a channel mapping to
* @param channelMap The channel map array, as described in notes.txt. This array pointer will be used directly (ie the underlying data will not be copied), so the caller should not free the array until after the stream has been opened.
* @param channelMapSize The size of the channel map array.
*/
void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, unsigned long channelMapSize );
/**
* Retrieve the AudioDeviceID of the input device assigned to an open stream
*
* @param s The stream to query.
*
* @return A valid AudioDeviceID, or NULL if an error occurred.
*/
AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s );
/**
* Retrieve the AudioDeviceID of the output device assigned to an open stream
*
* @param s The stream to query.
*
* @return A valid AudioDeviceID, or NULL if an error occurred.
*/
AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s );
/**
* Returns a statically allocated string with the device's name
* for the given channel. NULL will be returned on failure.
*
* This function's implemenation is not complete!
*
* @param device The PortAudio device index.
* @param channel The channel number who's name is requested.
* @return a statically allocated string with the name of the device.
* Because this string is statically allocated, it must be
* coppied if it is to be saved and used by the user after
* another call to this function.
*
*/
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
*/
/**
* The following flags alter the behaviour of PA on the mac platform.
* they can be ORed together. These should work both for opening and
* checking a device.
*/
/** Allows PortAudio to change things like the device's frame size,
* which allows for much lower latency, but might disrupt the device
* if other programs are using it, even when you are just Querying
* the device. */
#define paMacCoreChangeDeviceParameters (0x01)
/** In combination with the above flag,
* causes the stream opening to fail, unless the exact sample rates
* are supported by the device. */
#define paMacCoreFailIfConversionRequired (0x02)
/** These flags set the SR conversion quality, if required. The wierd ordering
* allows Maximum Quality to be the default.*/
#define paMacCoreConversionQualityMin (0x0100)
#define paMacCoreConversionQualityMedium (0x0200)
#define paMacCoreConversionQualityLow (0x0300)
#define paMacCoreConversionQualityHigh (0x0400)
#define paMacCoreConversionQualityMax (0x0000)
/**
* Here are some "preset" combinations of flags (above) to get to some
* common configurations. THIS IS OVERKILL, but if more flags are added
* it won't be.
*/
/**This is the default setting: do as much sample rate conversion as possible
* and as little mucking with the device as possible. */
#define paMacCorePlayNice (0x00)
/**This setting is tuned for pro audio apps. It allows SR conversion on input
and output, but it tries to set the appropriate SR on the device.*/
#define paMacCorePro (0x01)
/**This is a setting to minimize CPU usage and still play nice.*/
#define paMacCoreMinimizeCPUButPlayNice (0x0100)
/**This is a setting to minimize CPU usage, even if that means interrupting the device. */
#define paMacCoreMinimizeCPU (0x0101)
#ifdef __cplusplus
}
#endif /** __cplusplus */
#endif /** PA_MAC_CORE_H */

View File

@ -1,95 +0,0 @@
#ifndef PA_WIN_DS_H
#define PA_WIN_DS_H
/*
* $Id: $
* PortAudio Portable Real-Time Audio Library
* DirectSound 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 DirectSound-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include "pa_win_waveformat.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define paWinDirectSoundUseLowLevelLatencyParameters (0x01)
#define paWinDirectSoundUseChannelMask (0x04)
typedef struct PaWinDirectSoundStreamInfo{
unsigned long size; /**< sizeof(PaWinDirectSoundStreamInfo) */
PaHostApiTypeId hostApiType; /**< paDirectSound */
unsigned long version; /**< 2 */
unsigned long flags; /**< enable other features of this struct */
/**
low-level latency setting support
Sets the size of the DirectSound host buffer.
When flags contains the paWinDirectSoundUseLowLevelLatencyParameters
this size will be used instead of interpreting the generic latency
parameters to Pa_OpenStream(). If the flag is not set this value is ignored.
If the stream is a full duplex stream the implementation requires that
the values of framesPerBuffer for input and output match (if both are specified).
*/
unsigned long framesPerBuffer;
/**
support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinDirectSoundUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h
*/
PaWinWaveFormatChannelMask channelMask;
}PaWinDirectSoundStreamInfo;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_DS_H */

View File

@ -1,443 +0,0 @@
#ifndef PA_WIN_WASAPI_H
#define PA_WIN_WASAPI_H
/*
* $Id: $
* PortAudio Portable Real-Time Audio Library
* DirectSound 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 WASAPI-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include "pa_win_waveformat.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* Setup flags */
typedef enum PaWasapiFlags
{
/* puts WASAPI into exclusive mode */
paWinWasapiExclusive = (1 << 0),
/* allows to skip internal PA processing completely */
paWinWasapiRedirectHostProcessor = (1 << 1),
/* assigns custom channel mask */
paWinWasapiUseChannelMask = (1 << 2),
/* selects non-Event driven method of data read/write
Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling
method can only provide 15-20ms latency. */
paWinWasapiPolling = (1 << 3),
/* forces custom thread priority setting, must be used if PaWasapiStreamInfo::threadPriority
is set to a custom value */
paWinWasapiThreadPriority = (1 << 4)
}
PaWasapiFlags;
#define paWinWasapiExclusive (paWinWasapiExclusive)
#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor)
#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask)
#define paWinWasapiPolling (paWinWasapiPolling)
#define paWinWasapiThreadPriority (paWinWasapiThreadPriority)
/* Host processor. Allows to skip internal PA processing completely.
You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member
in order to have host processor redirected to your callback.
Use with caution! inputFrames and outputFrames depend solely on final device setup.
To query maximal values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer.
*/
typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames,
void *outputBuffer, long outputFrames,
void *userData);
/* Device role. */
typedef enum PaWasapiDeviceRole
{
eRoleRemoteNetworkDevice = 0,
eRoleSpeakers,
eRoleLineLevel,
eRoleHeadphones,
eRoleMicrophone,
eRoleHeadset,
eRoleHandset,
eRoleUnknownDigitalPassthrough,
eRoleSPDIF,
eRoleHDMI,
eRoleUnknownFormFactor
}
PaWasapiDeviceRole;
/* Jack connection type. */
typedef enum PaWasapiJackConnectionType
{
eJackConnTypeUnknown,
eJackConnType3Point5mm,
eJackConnTypeQuarter,
eJackConnTypeAtapiInternal,
eJackConnTypeRCA,
eJackConnTypeOptical,
eJackConnTypeOtherDigital,
eJackConnTypeOtherAnalog,
eJackConnTypeMultichannelAnalogDIN,
eJackConnTypeXlrProfessional,
eJackConnTypeRJ11Modem,
eJackConnTypeCombination
}
PaWasapiJackConnectionType;
/* Jack geometric location. */
typedef enum PaWasapiJackGeoLocation
{
eJackGeoLocUnk = 0,
eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */
eJackGeoLocFront,
eJackGeoLocLeft,
eJackGeoLocRight,
eJackGeoLocTop,
eJackGeoLocBottom,
eJackGeoLocRearPanel,
eJackGeoLocRiser,
eJackGeoLocInsideMobileLid,
eJackGeoLocDrivebay,
eJackGeoLocHDMI,
eJackGeoLocOutsideMobileLid,
eJackGeoLocATAPI,
eJackGeoLocReserved5,
eJackGeoLocReserved6,
}
PaWasapiJackGeoLocation;
/* Jack general location. */
typedef enum PaWasapiJackGenLocation
{
eJackGenLocPrimaryBox = 0,
eJackGenLocInternal,
eJackGenLocSeparate,
eJackGenLocOther
}
PaWasapiJackGenLocation;
/* Jack's type of port. */
typedef enum PaWasapiJackPortConnection
{
eJackPortConnJack = 0,
eJackPortConnIntegratedDevice,
eJackPortConnBothIntegratedAndJack,
eJackPortConnUnknown
}
PaWasapiJackPortConnection;
/* Thread priority. */
typedef enum PaWasapiThreadPriority
{
eThreadPriorityNone = 0,
eThreadPriorityAudio, //!< Default for Shared mode.
eThreadPriorityCapture,
eThreadPriorityDistribution,
eThreadPriorityGames,
eThreadPriorityPlayback,
eThreadPriorityProAudio, //!< Default for Exclusive mode.
eThreadPriorityWindowManager
}
PaWasapiThreadPriority;
/* Stream descriptor. */
typedef struct PaWasapiJackDescription
{
unsigned long channelMapping;
unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */
PaWasapiJackConnectionType connectionType;
PaWasapiJackGeoLocation geoLocation;
PaWasapiJackGenLocation genLocation;
PaWasapiJackPortConnection portConnection;
unsigned int isConnected;
}
PaWasapiJackDescription;
/** Stream category.
Note:
- values are equal to WASAPI AUDIO_STREAM_CATEGORY enum
- supported since Windows 8.0, noop on earler versions
- values 1,2 are deprecated on Windows 10 and not included into enumeration
@version Available as of 19.6.0
*/
typedef enum PaWasapiStreamCategory
{
eAudioCategoryOther = 0,
eAudioCategoryCommunications = 3,
eAudioCategoryAlerts = 4,
eAudioCategorySoundEffects = 5,
eAudioCategoryGameEffects = 6,
eAudioCategoryGameMedia = 7,
eAudioCategoryGameChat = 8,
eAudioCategorySpeech = 9,
eAudioCategoryMovie = 10,
eAudioCategoryMedia = 11
}
PaWasapiStreamCategory;
/** Stream option.
Note:
- values are equal to WASAPI AUDCLNT_STREAMOPTIONS enum
- supported since Windows 8.1, noop on earler versions
@version Available as of 19.6.0
*/
typedef enum PaWasapiStreamOption
{
eStreamOptionNone = 0, //!< default
eStreamOptionRaw = 1, //!< bypass WASAPI Audio Engine DSP effects, supported since Windows 8.1
eStreamOptionMatchFormat = 2 //!< force WASAPI Audio Engine into a stream format, supported since Windows 10
}
PaWasapiStreamOption;
/* Stream descriptor. */
typedef struct PaWasapiStreamInfo
{
unsigned long size; /**< sizeof(PaWasapiStreamInfo) */
PaHostApiTypeId hostApiType; /**< paWASAPI */
unsigned long version; /**< 1 */
unsigned long flags; /**< collection of PaWasapiFlags */
/** Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinWasapiUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h. Will be used only if
paWinWasapiUseChannelMask flag is specified.
*/
PaWinWaveFormatChannelMask channelMask;
/** Delivers raw data to callback obtained from GetBuffer() methods skipping
internal PortAudio processing inventory completely. userData parameter will
be the same that was passed to Pa_OpenStream method. Will be used only if
paWinWasapiRedirectHostProcessor flag is specified.
*/
PaWasapiHostProcessorCallback hostProcessorOutput;
PaWasapiHostProcessorCallback hostProcessorInput;
/** Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag
is specified.
Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode)
you shall specify same value for threadPriority or othervise one of the values will be used
to setup thread priority.
*/
PaWasapiThreadPriority threadPriority;
/** Stream category.
@see PaWasapiStreamCategory
@version Available as of 19.6.0
*/
PaWasapiStreamCategory streamCategory;
/** Stream option.
@see PaWasapiStreamOption
@version Available as of 19.6.0
*/
PaWasapiStreamOption streamOption;
}
PaWasapiStreamInfo;
/** Returns default sound format for device. Format is represented by PaWinWaveFormat or
WAVEFORMATEXTENSIBLE structure.
@param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure.
@param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes.
@param nDevice Device index.
@return Non-negative value indicating the number of bytes copied into format decriptor
or, a PaErrorCode (which are always negative) if PortAudio is not initialized
or an error is encountered.
*/
int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice );
/** Returns device role (PaWasapiDeviceRole enum).
@param nDevice device index.
@return Non-negative value indicating device role or, a PaErrorCode (which are always negative)
if PortAudio is not initialized or an error is encountered.
*/
int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice );
/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread
which makes calls to Pa_WriteStream/Pa_ReadStream.
@param hTask Handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority
method to revert thread priority to initial state.
@param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying
eThreadPriorityNone does nothing.
@return Error code indicating success or failure.
@see PaWasapi_RevertThreadPriority
*/
PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass );
/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread
which makes calls to Pa_WriteStream/Pa_ReadStream.
@param hTask Task handle obtained by PaWasapi_BoostThreadPriority method.
@return Error code indicating success or failure.
@see PaWasapi_BoostThreadPriority
*/
PaError PaWasapi_ThreadPriorityRevert( void *hTask );
/** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which
can be locked for operations. Use this method as helper to findout maximal values of
inputFrames/outputFrames of PaWasapiHostProcessorCallback.
@param pStream Pointer to PaStream to query.
@param nInput Pointer to variable to receive number of input frames. Can be NULL.
@param nOutput Pointer to variable to receive number of output frames. Can be NULL.
@return Error code indicating success or failure.
@see PaWasapiHostProcessorCallback
*/
PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput );
/** Get number of jacks associated with a WASAPI device. Use this method to determine if
there are any jacks associated with the provided WASAPI device. Not all audio devices
will support this capability. This is valid for both input and output devices.
@param nDevice device index.
@param jcount Number of jacks is returned in this variable
@return Error code indicating success or failure
@see PaWasapi_GetJackDescription
*/
PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount);
/** Get the jack description associated with a WASAPI device and jack number
Before this function is called, use PaWasapi_GetJackCount to determine the
number of jacks associated with device. If jcount is greater than zero, then
each jack from 0 to jcount can be queried with this function to get the jack
description.
@param nDevice device index.
@param jindex Which jack to return information
@param KSJACK_DESCRIPTION This structure filled in on success.
@return Error code indicating success or failure
@see PaWasapi_GetJackCount
*/
PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription);
/*
IMPORTANT:
WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive
share modes.
Exclusive Mode:
Exclusive mode allows to deliver audio data directly to hardware bypassing
software mixing.
Exclusive mode is specified by 'paWinWasapiExclusive' flag.
Callback Interface:
Provides best audio quality with low latency. Callback interface is implemented in
two versions:
1) Event-Driven:
This is the most powerful WASAPI implementation which provides glitch-free
audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is
3 ms for HD Audio class audio chips. For the Shared mode latency can not be
lower than 20 ms.
2) Poll-Driven:
Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
and provides latency at around 10-13ms. Polling must be used to overcome a system bug
under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply
times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug
does not exist in Vista x86 or Windows 7.
Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects
WOW64 bug and sets 'paWinWasapiPolling' automatically.
Thread priority:
Normally thread priority is set automatically and does not require modification. Although
if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority'
flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority
enum.
Blocking Interface:
Blocking interface is implemented but due to above described Poll-Driven method can not
deliver lowest possible latency. Specifying too low latency in Shared mode will result in
distorted audio although Exclusive mode adds stability.
Pa_IsFormatSupported:
To check format with correct Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
Pa_OpenStream:
To set desired Share Mode (Exclusive/Shared) you must supply
PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
PaStreamParameters::hostApiSpecificStreamInfo structure.
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_WASAPI_H */

View File

@ -1,199 +0,0 @@
#ifndef PA_WIN_WAVEFORMAT_H
#define PA_WIN_WAVEFORMAT_H
/*
* PortAudio Portable Real-Time Audio Library
* Windows WAVEFORMAT* data structure utilities
* portaudio.h should be included before this file.
*
* Copyright (c) 2007 Ross Bencina
*
* 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 Windows specific PortAudio API extension and utilities header file.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
The following #defines for speaker channel masks are the same
as those in ksmedia.h, except with PAWIN_ prepended, KSAUDIO_ removed
in some cases, and casts to PaWinWaveFormatChannelMask added.
*/
typedef unsigned long PaWinWaveFormatChannelMask;
/* Speaker Positions: */
#define PAWIN_SPEAKER_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1)
#define PAWIN_SPEAKER_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x2)
#define PAWIN_SPEAKER_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x4)
#define PAWIN_SPEAKER_LOW_FREQUENCY ((PaWinWaveFormatChannelMask)0x8)
#define PAWIN_SPEAKER_BACK_LEFT ((PaWinWaveFormatChannelMask)0x10)
#define PAWIN_SPEAKER_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20)
#define PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER ((PaWinWaveFormatChannelMask)0x40)
#define PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER ((PaWinWaveFormatChannelMask)0x80)
#define PAWIN_SPEAKER_BACK_CENTER ((PaWinWaveFormatChannelMask)0x100)
#define PAWIN_SPEAKER_SIDE_LEFT ((PaWinWaveFormatChannelMask)0x200)
#define PAWIN_SPEAKER_SIDE_RIGHT ((PaWinWaveFormatChannelMask)0x400)
#define PAWIN_SPEAKER_TOP_CENTER ((PaWinWaveFormatChannelMask)0x800)
#define PAWIN_SPEAKER_TOP_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1000)
#define PAWIN_SPEAKER_TOP_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x2000)
#define PAWIN_SPEAKER_TOP_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x4000)
#define PAWIN_SPEAKER_TOP_BACK_LEFT ((PaWinWaveFormatChannelMask)0x8000)
#define PAWIN_SPEAKER_TOP_BACK_CENTER ((PaWinWaveFormatChannelMask)0x10000)
#define PAWIN_SPEAKER_TOP_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20000)
/* Bit mask locations reserved for future use */
#define PAWIN_SPEAKER_RESERVED ((PaWinWaveFormatChannelMask)0x7FFC0000)
/* Used to specify that any possible permutation of speaker configurations */
#define PAWIN_SPEAKER_ALL ((PaWinWaveFormatChannelMask)0x80000000)
/* DirectSound Speaker Config */
#define PAWIN_SPEAKER_DIRECTOUT 0
#define PAWIN_SPEAKER_MONO (PAWIN_SPEAKER_FRONT_CENTER)
#define PAWIN_SPEAKER_STEREO (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT)
#define PAWIN_SPEAKER_QUAD (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT)
#define PAWIN_SPEAKER_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_BACK_CENTER)
#define PAWIN_SPEAKER_5POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT)
#define PAWIN_SPEAKER_7POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \
PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER | PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER)
#define PAWIN_SPEAKER_5POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT)
#define PAWIN_SPEAKER_7POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \
PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \
PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \
PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT)
/*
According to the Microsoft documentation:
The following are obsolete 5.1 and 7.1 settings (they lack side speakers). Note this means
that the default 5.1 and 7.1 settings (KSAUDIO_SPEAKER_5POINT1 and KSAUDIO_SPEAKER_7POINT1 are
similarly obsolete but are unchanged for compatibility reasons).
*/
#define PAWIN_SPEAKER_5POINT1_BACK PAWIN_SPEAKER_5POINT1
#define PAWIN_SPEAKER_7POINT1_WIDE PAWIN_SPEAKER_7POINT1
/* DVD Speaker Positions */
#define PAWIN_SPEAKER_GROUND_FRONT_LEFT PAWIN_SPEAKER_FRONT_LEFT
#define PAWIN_SPEAKER_GROUND_FRONT_CENTER PAWIN_SPEAKER_FRONT_CENTER
#define PAWIN_SPEAKER_GROUND_FRONT_RIGHT PAWIN_SPEAKER_FRONT_RIGHT
#define PAWIN_SPEAKER_GROUND_REAR_LEFT PAWIN_SPEAKER_BACK_LEFT
#define PAWIN_SPEAKER_GROUND_REAR_RIGHT PAWIN_SPEAKER_BACK_RIGHT
#define PAWIN_SPEAKER_TOP_MIDDLE PAWIN_SPEAKER_TOP_CENTER
#define PAWIN_SPEAKER_SUPER_WOOFER PAWIN_SPEAKER_LOW_FREQUENCY
/*
PaWinWaveFormat is defined here to provide compatibility with
compilation environments which don't have headers defining
WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc.
The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an
unsigned char array here to avoid clients who include this file having
a dependency on windows.h and mmsystem.h, and also to to avoid having
to write separate packing pragmas for each compiler.
*/
#define PAWIN_SIZEOF_WAVEFORMATEX 18
#define PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE (PAWIN_SIZEOF_WAVEFORMATEX + 22)
typedef struct{
unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ];
unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */
} PaWinWaveFormat;
/*
WAVEFORMATEXTENSIBLE fields:
union {
WORD wValidBitsPerSample;
WORD wSamplesPerBlock;
WORD wReserved;
} Samples;
DWORD dwChannelMask;
GUID SubFormat;
*/
#define PAWIN_INDEXOF_WVALIDBITSPERSAMPLE (PAWIN_SIZEOF_WAVEFORMATEX+0)
#define PAWIN_INDEXOF_DWCHANNELMASK (PAWIN_SIZEOF_WAVEFORMATEX+2)
#define PAWIN_INDEXOF_SUBFORMAT (PAWIN_SIZEOF_WAVEFORMATEX+6)
/*
Valid values to pass for the waveFormatTag PaWin_InitializeWaveFormatEx and
PaWin_InitializeWaveFormatExtensible functions below. These must match
the standard Windows WAVE_FORMAT_* values.
*/
#define PAWIN_WAVE_FORMAT_PCM (1)
#define PAWIN_WAVE_FORMAT_IEEE_FLOAT (3)
#define PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF (0x0092)
#define PAWIN_WAVE_FORMAT_WMA_SPDIF (0x0164)
/*
returns PAWIN_WAVE_FORMAT_PCM or PAWIN_WAVE_FORMAT_IEEE_FLOAT
depending on the sampleFormat parameter.
*/
int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat );
/*
Use the following two functions to initialize the waveformat structure.
*/
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate );
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
PaWinWaveFormatChannelMask channelMask );
/* Map a channel count to a speaker channel mask */
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_WAVEFORMAT_H */

View File

@ -1,137 +0,0 @@
#ifndef PA_WIN_WDMKS_H
#define PA_WIN_WDMKS_H
/*
* $Id$
* 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 */
/** Flags to indicate valid fields in PaWinWDMKSInfo.
@see PaWinWDMKSInfo
@version Available as of 19.5.0.
*/
typedef enum PaWinWDMKSFlags
{
/** Makes WDMKS use the supplied latency figures instead of relying on the frame size reported
by the WaveCyclic device. Use at own risk!
*/
paWinWDMKSOverrideFramesize = (1 << 0),
/** Makes WDMKS (output stream) use the given channelMask instead of the default.
@version Available as of 19.5.0.
*/
paWinWDMKSUseGivenChannelMask = (1 << 1),
} PaWinWDMKSFlags;
typedef struct PaWinWDMKSInfo{
unsigned long size; /**< sizeof(PaWinWDMKSInfo) */
PaHostApiTypeId hostApiType; /**< paWDMKS */
unsigned long version; /**< 1 */
/** Flags indicate which fields are valid.
@see PaWinWDMKSFlags
@version Available as of 19.5.0.
*/
unsigned long flags;
/** The number of packets to use for WaveCyclic devices, range is [2, 8]. Set to zero for default value of 2. */
unsigned noOfPackets;
/** If paWinWDMKSUseGivenChannelMask bit is set in flags, use this as channelMask instead of default.
@see PaWinWDMKSFlags
@version Available as of 19.5.0.
*/
unsigned channelMask;
} 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 */

View File

@ -1,185 +0,0 @@
#ifndef PA_WIN_WMME_H
#define PA_WIN_WMME_H
/*
* $Id$
* PortAudio Portable Real-Time Audio Library
* MME specific extensions
*
* Copyright (c) 1999-2000 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 WMME-specific PortAudio API extension header file.
*/
#include "portaudio.h"
#include "pa_win_waveformat.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* The following are flags which can be set in
PaWinMmeStreamInfo's flags field.
*/
#define paWinMmeUseLowLevelLatencyParameters (0x01)
#define paWinMmeUseMultipleDevices (0x02) /* use mme specific multiple device feature */
#define paWinMmeUseChannelMask (0x04)
/* By default, the mme implementation drops the processing thread's priority
to THREAD_PRIORITY_NORMAL and sleeps the thread if the CPU load exceeds 100%
This flag disables any priority throttling. The processing thread will always
run at THREAD_PRIORITY_TIME_CRITICAL.
*/
#define paWinMmeDontThrottleOverloadedProcessingThread (0x08)
/* Flags for non-PCM spdif passthrough.
*/
#define paWinMmeWaveFormatDolbyAc3Spdif (0x10)
#define paWinMmeWaveFormatWmaSpdif (0x20)
typedef struct PaWinMmeDeviceAndChannelCount{
PaDeviceIndex device;
int channelCount;
}PaWinMmeDeviceAndChannelCount;
typedef struct PaWinMmeStreamInfo{
unsigned long size; /**< sizeof(PaWinMmeStreamInfo) */
PaHostApiTypeId hostApiType; /**< paMME */
unsigned long version; /**< 1 */
unsigned long flags;
/* low-level latency setting support
These settings control the number and size of host buffers in order
to set latency. They will be used instead of the generic parameters
to Pa_OpenStream() if flags contains the PaWinMmeUseLowLevelLatencyParameters
flag.
If PaWinMmeStreamInfo structures with PaWinMmeUseLowLevelLatencyParameters
are supplied for both input and output in a full duplex stream, then the
input and output framesPerBuffer must be the same, or the larger of the
two must be a multiple of the smaller, otherwise a
paIncompatibleHostApiSpecificStreamInfo error will be returned from
Pa_OpenStream().
*/
unsigned long framesPerBuffer;
unsigned long bufferCount; /* formerly numBuffers */
/* multiple devices per direction support
If flags contains the PaWinMmeUseMultipleDevices flag,
this functionality will be used, otherwise the device parameter to
Pa_OpenStream() will be used instead.
If devices are specified here, the corresponding device parameter
to Pa_OpenStream() should be set to paUseHostApiSpecificDeviceSpecification,
otherwise an paInvalidDevice error will result.
The total number of channels accross all specified devices
must agree with the corresponding channelCount parameter to
Pa_OpenStream() otherwise a paInvalidChannelCount error will result.
*/
PaWinMmeDeviceAndChannelCount *devices;
unsigned long deviceCount;
/*
support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
paWinMmeUseChannelMask this allows you to specify which speakers
to address in a multichannel stream. Constants for channelMask
are specified in pa_win_waveformat.h
*/
PaWinWaveFormatChannelMask channelMask;
}PaWinMmeStreamInfo;
/** Retrieve the number of wave in handles used by a PortAudio WinMME stream.
Returns zero if the stream is output only.
@return A non-negative value indicating the number of wave in handles
or, a PaErrorCode (which are always negative) if PortAudio is not initialized
or an error is encountered.
@see PaWinMME_GetStreamInputHandle
*/
int PaWinMME_GetStreamInputHandleCount( PaStream* stream );
/** Retrieve a wave in handle used by a PortAudio WinMME stream.
@param stream The stream to query.
@param handleIndex The zero based index of the wave in handle to retrieve. This
should be in the range [0, PaWinMME_GetStreamInputHandleCount(stream)-1].
@return A valid wave in handle, or NULL if an error occurred.
@see PaWinMME_GetStreamInputHandle
*/
HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex );
/** Retrieve the number of wave out handles used by a PortAudio WinMME stream.
Returns zero if the stream is input only.
@return A non-negative value indicating the number of wave out handles
or, a PaErrorCode (which are always negative) if PortAudio is not initialized
or an error is encountered.
@see PaWinMME_GetStreamOutputHandle
*/
int PaWinMME_GetStreamOutputHandleCount( PaStream* stream );
/** Retrieve a wave out handle used by a PortAudio WinMME stream.
@param stream The stream to query.
@param handleIndex The zero based index of the wave out handle to retrieve.
This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1].
@return A valid wave out handle, or NULL if an error occurred.
@see PaWinMME_GetStreamOutputHandleCount
*/
HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_WMME_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,220 +0,0 @@
import os.path, copy, sys
def checkSymbol(conf, header, library=None, symbol=None, autoAdd=True, critical=False, pkgName=None):
""" Check for symbol in library, optionally look only for header.
@param conf: Configure instance.
@param header: The header file where the symbol is declared.
@param library: The library in which the symbol exists, if None it is taken to be the standard C library.
@param symbol: The symbol to look for, if None only the header will be looked up.
@param autoAdd: Automatically link with this library if check is positive.
@param critical: Raise on error?
@param pkgName: Optional name of pkg-config entry for library, to determine build parameters.
@return: True/False
"""
origEnv = conf.env.Copy() # Copy unmodified environment so we can restore it upon error
env = conf.env
if library is None:
library = "c" # Standard library
autoAdd = False
if pkgName is not None:
origLibs = copy.copy(env.get("LIBS", None))
try: env.ParseConfig("pkg-config --silence-errors %s --cflags --libs" % pkgName)
except: pass
else:
# I see no other way of checking that the parsing succeeded, if it did add no more linking parameters
if env.get("LIBS", None) != origLibs:
autoAdd = False
try:
if not conf.CheckCHeader(header, include_quotes="<>"):
raise ConfigurationError("missing header %s" % header)
if symbol is not None and not conf.CheckLib(library, symbol, language="C", autoadd=autoAdd):
raise ConfigurationError("missing symbol %s in library %s" % (symbol, library))
except ConfigurationError:
conf.env = origEnv
if not critical:
return False
raise
return True
import SCons.Errors
# Import common variables
# Could use '#' to refer to top-level SConstruct directory, but looks like env.SConsignFile doesn't interpret this at least :(
sconsDir = os.path.abspath(os.path.join("build", "scons"))
try:
Import("Platform", "Posix", "ConfigurationError", "ApiVer")
except SCons.Errors.UserError:
# The common objects must be exported first
SConscript(os.path.join(sconsDir, "SConscript_common"))
Import("Platform", "Posix", "ConfigurationError", "ApiVer")
Import("env")
# This will be manipulated
env = env.Copy()
# We operate with a set of needed libraries and optional libraries, the latter stemming from host API implementations.
# For libraries of both types we record a set of values that is used to look for the library in question, during
# configuration. If the corresponding library for a host API implementation isn't found, the implementation is left out.
neededLibs = []
optionalImpls = {}
if Platform in Posix:
env.Append(CPPPATH=os.path.join("os", "unix"))
neededLibs += [("pthread", "pthread.h", "pthread_create"), ("m", "math.h", "sin")]
if env["useALSA"]:
optionalImpls["ALSA"] = ("asound", "alsa/asoundlib.h", "snd_pcm_open")
if env["useJACK"]:
optionalImpls["JACK"] = ("jack", "jack/jack.h", "jack_client_new")
if env["useOSS"]:
# TODO: It looks like the prefix for soundcard.h depends on the platform
optionalImpls["OSS"] = ("oss", "sys/soundcard.h", None)
if Platform == 'netbsd':
optionalImpls["OSS"] = ("ossaudio", "sys/soundcard.h", "_oss_ioctl")
if env["useASIHPI"]:
optionalImpls["ASIHPI"] = ("hpi", "asihpi/hpi.h", "HPI_SubSysCreate")
if env["useCOREAUDIO"]:
optionalImpls["COREAUDIO"] = ("CoreAudio", "CoreAudio/CoreAudio.h", None)
else:
raise ConfigurationError("unknown platform %s" % Platform)
if Platform == "darwin":
env.Append(LINKFLAGS="-framework CoreFoundation -framework CoreServices -framework CoreAudio -framework AudioToolBox -framework AudioUnit")
elif Platform == "cygwin":
env.Append(LIBS=["winmm"])
elif Platform == "irix":
neededLibs += [("audio", "dmedia/audio.h", "alOpenPort"), ("dmedia", "dmedia/dmedia.h", "dmGetUST")]
env.Append(CPPDEFINES=["PA_USE_SGI"])
def CheckCTypeSize(context, tp):
""" Check size of C type.
@param context: A configuration context.
@param tp: The type to check.
@return: Size of type, in bytes.
"""
context.Message("Checking the size of C type %s..." % tp)
ret = context.TryRun("""
#include <stdio.h>
int main() {
printf("%%d", sizeof(%s));
return 0;
}
""" % tp, ".c")
if not ret[0]:
context.Result(" Couldn't obtain size of type %s!" % tp)
return None
assert ret[1]
sz = int(ret[1])
context.Result("%d" % sz)
return sz
"""
if sys.byteorder == "little":
env.Append(CPPDEFINES=["PA_LITTLE_ENDIAN"])
elif sys.byteorder == "big":
env.Append(CPPDEFINES=["PA_BIG_ENDIAN"])
else:
raise ConfigurationError("unknown byte order: %s" % sys.byteorder)
"""
if env["enableDebugOutput"]:
env.Append(CPPDEFINES=["PA_ENABLE_DEBUG_OUTPUT"])
# Start configuration
# Use an absolute path for conf_dir, otherwise it gets created both relative to current directory and build directory
conf = env.Configure(log_file=os.path.join(sconsDir, "sconf.log"), custom_tests={"CheckCTypeSize": CheckCTypeSize},
conf_dir=os.path.join(sconsDir, ".sconf_temp"))
conf.env.Append(CPPDEFINES=["SIZEOF_SHORT=%d" % conf.CheckCTypeSize("short")])
conf.env.Append(CPPDEFINES=["SIZEOF_INT=%d" % conf.CheckCTypeSize("int")])
conf.env.Append(CPPDEFINES=["SIZEOF_LONG=%d" % conf.CheckCTypeSize("long")])
if checkSymbol(conf, "time.h", "rt", "clock_gettime"):
conf.env.Append(CPPDEFINES=["HAVE_CLOCK_GETTIME"])
if checkSymbol(conf, "time.h", symbol="nanosleep"):
conf.env.Append(CPPDEFINES=["HAVE_NANOSLEEP"])
if conf.CheckCHeader("sys/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_SYS_SOUNDCARD_H"])
if conf.CheckCHeader("linux/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_LINUX_SOUNDCARD_H"])
if conf.CheckCHeader("machine/soundcard.h"):
conf.env.Append(CPPDEFINES=["HAVE_MACHINE_SOUNDCARD_H"])
# Look for needed libraries and link with them
for lib, hdr, sym in neededLibs:
checkSymbol(conf, hdr, lib, sym, critical=True)
# Look for host API libraries, if a library isn't found disable corresponding host API implementation.
for name, val in optionalImpls.items():
lib, hdr, sym = val
if checkSymbol(conf, hdr, lib, sym, critical=False, pkgName=name.lower()):
conf.env.Append(CPPDEFINES=["PA_USE_%s=1" % name.upper()])
else:
del optionalImpls[name]
# Configuration finished
env = conf.Finish()
# PA infrastructure
CommonSources = [os.path.join("common", f) for f in "pa_allocation.c pa_converters.c pa_cpuload.c pa_dither.c pa_front.c \
pa_process.c pa_stream.c pa_trace.c pa_debugprint.c pa_ringbuffer.c".split()]
CommonSources.append(os.path.join("hostapi", "skeleton", "pa_hostapi_skeleton.c"))
# Host APIs implementations
ImplSources = []
if Platform in Posix:
ImplSources += [os.path.join("os", "unix", f) for f in "pa_unix_hostapis.c pa_unix_util.c".split()]
if "ALSA" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "alsa", "pa_linux_alsa.c"))
if "JACK" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "jack", "pa_jack.c"))
if "OSS" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "oss", "pa_unix_oss.c"))
if "ASIHPI" in optionalImpls:
ImplSources.append(os.path.join("hostapi", "asihpi", "pa_linux_asihpi.c"))
if "COREAUDIO" in optionalImpls:
ImplSources.append([os.path.join("hostapi", "coreaudio", f) for f in """
pa_mac_core.c pa_mac_core_blocking.c pa_mac_core_utilities.c
""".split()])
sources = CommonSources + ImplSources
sharedLibEnv = env.Copy()
if Platform in Posix:
# Add soname to library, this is so a reference is made to the versioned library in programs linking against libportaudio.so
if Platform != 'darwin':
sharedLibEnv.AppendUnique(SHLINKFLAGS="-Wl,-soname=libportaudio.so.%d" % int(ApiVer.split(".")[0]))
sharedLib = sharedLibEnv.SharedLibrary(target="portaudio", source=sources)
staticLib = env.StaticLibrary(target="portaudio", source=sources)
if Platform in Posix:
prefix = env["prefix"]
includeDir = os.path.join(prefix, "include")
libDir = os.path.join(prefix, "lib")
testNames = ["patest_sine", "paqa_devs", "paqa_errs", "patest1", "patest_buffer", "patest_callbackstop", "patest_clip", \
"patest_dither", "patest_hang", "patest_in_overflow", "patest_latency", "patest_leftright", "patest_longsine", \
"patest_many", "patest_maxsines", "patest_multi_sine", "patest_out_underflow", "patest_pink", "patest_prime", \
"patest_read_record", "patest_record", "patest_ringmix", "patest_saw", "patest_sine8", "patest_sine", \
"patest_sine_time", "patest_start_stop", "patest_stop", "patest_sync", "patest_toomanysines", \
"patest_underflow", "patest_wire", "patest_write_sine", "pa_devs", "pa_fuzz", "pa_minlat", \
"patest_sine_channelmaps",]
# The test directory ("bin") should be in the top-level PA directory
tests = [env.Program(target=os.path.join("#", "bin", name), source=[os.path.join("#", "test", name + ".c"),
staticLib]) for name in testNames]
# Detect host APIs
hostApis = []
for cppdef in env["CPPDEFINES"]:
if cppdef.startswith("PA_USE_"):
hostApis.append(cppdef[7:-2])
Return("sources", "sharedLib", "staticLib", "tests", "env", "hostApis")

View File

@ -1,243 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library allocation group implementation
* memory allocation group for tracking allocation groups
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 common_src
@brief Allocation Group implementation.
*/
#include "pa_allocation.h"
#include "pa_util.h"
/*
Maintain 3 singly linked lists...
linkBlocks: the buffers used to allocate the links
spareLinks: links available for use in the allocations list
allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory()
Link block size is doubled every time new links are allocated.
*/
#define PA_INITIAL_LINK_COUNT_ 16
struct PaUtilAllocationGroupLink
{
struct PaUtilAllocationGroupLink *next;
void *buffer;
};
/*
Allocate a block of links. The first link will have it's buffer member
pointing to the block, and it's next member set to <nextBlock>. The remaining
links will have NULL buffer members, and each link will point to
the next link except the last, which will point to <nextSpare>
*/
static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
struct PaUtilAllocationGroupLink *nextBlock,
struct PaUtilAllocationGroupLink *nextSpare )
{
struct PaUtilAllocationGroupLink *result;
int i;
result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
sizeof(struct PaUtilAllocationGroupLink) * count );
if( result )
{
/* the block link */
result[0].buffer = result;
result[0].next = nextBlock;
/* the spare links */
for( i=1; i<count; ++i )
{
result[i].buffer = 0;
result[i].next = &result[i+1];
}
result[count-1].next = nextSpare;
}
return result;
}
PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void )
{
PaUtilAllocationGroup* result = 0;
struct PaUtilAllocationGroupLink *links;
links = AllocateLinks( PA_INITIAL_LINK_COUNT_, 0, 0 );
if( links != 0 )
{
result = (PaUtilAllocationGroup*)PaUtil_AllocateMemory( sizeof(PaUtilAllocationGroup) );
if( result )
{
result->linkCount = PA_INITIAL_LINK_COUNT_;
result->linkBlocks = &links[0];
result->spareLinks = &links[1];
result->allocations = 0;
}
else
{
PaUtil_FreeMemory( links );
}
}
return result;
}
void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group )
{
struct PaUtilAllocationGroupLink *current = group->linkBlocks;
struct PaUtilAllocationGroupLink *next;
while( current )
{
next = current->next;
PaUtil_FreeMemory( current->buffer );
current = next;
}
PaUtil_FreeMemory( group );
}
void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
{
struct PaUtilAllocationGroupLink *links, *link;
void *result = 0;
/* allocate more links if necessary */
if( !group->spareLinks )
{
/* double the link count on each block allocation */
links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks );
if( links )
{
group->linkCount += group->linkCount;
group->linkBlocks = &links[0];
group->spareLinks = &links[1];
}
}
if( group->spareLinks )
{
result = PaUtil_AllocateMemory( size );
if( result )
{
link = group->spareLinks;
group->spareLinks = link->next;
link->buffer = result;
link->next = group->allocations;
group->allocations = link;
}
}
return result;
}
void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer )
{
struct PaUtilAllocationGroupLink *current = group->allocations;
struct PaUtilAllocationGroupLink *previous = 0;
if( buffer == 0 )
return;
/* find the right link and remove it */
while( current )
{
if( current->buffer == buffer )
{
if( previous )
{
previous->next = current->next;
}
else
{
group->allocations = current->next;
}
current->buffer = 0;
current->next = group->spareLinks;
group->spareLinks = current;
break;
}
previous = current;
current = current->next;
}
PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */
}
void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group )
{
struct PaUtilAllocationGroupLink *current = group->allocations;
struct PaUtilAllocationGroupLink *previous = 0;
/* free all buffers in the allocations list */
while( current )
{
PaUtil_FreeMemory( current->buffer );
current->buffer = 0;
previous = current;
current = current->next;
}
/* link the former allocations list onto the front of the spareLinks list */
if( previous )
{
previous->next = group->spareLinks;
group->spareLinks = group->allocations;
group->allocations = 0;
}
}

View File

@ -1,104 +0,0 @@
#ifndef PA_ALLOCATION_H
#define PA_ALLOCATION_H
/*
* $Id$
* Portable Audio I/O Library allocation context header
* memory allocation context for tracking allocation groups
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2008 Ross Bencina, 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 common_src
@brief Allocation Group prototypes. An Allocation Group makes it easy to
allocate multiple blocks of memory and free them all at once.
An allocation group is useful for keeping track of multiple blocks
of memory which are allocated at the same time (such as during initialization)
and need to be deallocated at the same time. The allocation group maintains
a list of allocated blocks, and can free all allocations at once. This
can be usefull for cleaning up after a partially initialized object fails.
The allocation group implementation is built on top of the lower
level allocation functions defined in pa_util.h
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
typedef struct
{
long linkCount;
struct PaUtilAllocationGroupLink *linkBlocks;
struct PaUtilAllocationGroupLink *spareLinks;
struct PaUtilAllocationGroupLink *allocations;
}PaUtilAllocationGroup;
/** Create an allocation group.
*/
PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void );
/** Destroy an allocation group, but not the memory allocated through the group.
*/
void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group );
/** Allocate a block of memory though an allocation group.
*/
void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size );
/** Free a block of memory that was previously allocated though an allocation
group. Calling this function is a relatively time consuming operation.
Under normal circumstances clients should call PaUtil_FreeAllAllocations to
free all allocated blocks simultaneously.
@see PaUtil_FreeAllAllocations
*/
void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer );
/** Free all blocks of memory which have been allocated through the allocation
group. This function doesn't destroy the group itself.
*/
void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_ALLOCATION_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,263 +0,0 @@
#ifndef PA_CONVERTERS_H
#define PA_CONVERTERS_H
/*
* $Id$
* Portable Audio I/O Library sample conversion mechanism
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
*
* 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 common_src
@brief Conversion functions used to convert buffers of samples from one
format to another.
*/
#include "portaudio.h" /* for PaSampleFormat */
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
struct PaUtilTriangularDitherGenerator;
/** Choose an available sample format which is most appropriate for
representing the requested format. If the requested format is not available
higher quality formats are considered before lower quality formates.
@param availableFormats A variable containing the logical OR of all available
formats.
@param format The desired format.
@return The most appropriate available format for representing the requested
format.
*/
PaSampleFormat PaUtil_SelectClosestAvailableFormat(
PaSampleFormat availableFormats, PaSampleFormat format );
/* high level conversions functions for use by implementations */
/** The generic sample converter prototype. Sample converters convert count
samples from sourceBuffer to destinationBuffer. The actual type of the data
pointed to by these parameters varys for different converter functions.
@param destinationBuffer A pointer to the first sample of the destination.
@param destinationStride An offset between successive destination samples
expressed in samples (not bytes.) It may be negative.
@param sourceBuffer A pointer to the first sample of the source.
@param sourceStride An offset between successive source samples
expressed in samples (not bytes.) It may be negative.
@param count The number of samples to convert.
@param ditherState State information used to calculate dither. Converters
that do not perform dithering will ignore this parameter, in which case
NULL or invalid dither state may be passed.
*/
typedef void PaUtilConverter(
void *destinationBuffer, signed int destinationStride,
void *sourceBuffer, signed int sourceStride,
unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator );
/** Find a sample converter function for the given source and destinations
formats and flags (clip and dither.)
@return
A pointer to a PaUtilConverter which will perform the requested
conversion, or NULL if the given format conversion is not supported.
For conversions where clipping or dithering is not necessary, the
clip and dither flags are ignored and a non-clipping or dithering
version is returned.
If the source and destination formats are the same, a function which
copies data of the appropriate size will be returned.
*/
PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat,
PaSampleFormat destinationFormat, PaStreamFlags flags );
/** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to
destinationBuffer. The actual type of the data pointed to varys for
different zeroer functions.
@param destinationBuffer A pointer to the first sample of the destination.
@param destinationStride An offset between successive destination samples
expressed in samples (not bytes.) It may be negative.
@param count The number of samples to zero.
*/
typedef void PaUtilZeroer(
void *destinationBuffer, signed int destinationStride, unsigned int count );
/** Find a buffer zeroer function for the given destination format.
@return
A pointer to a PaUtilZeroer which will perform the requested
zeroing.
*/
PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat );
/*----------------------------------------------------------------------------*/
/* low level functions and data structures which may be used for
substituting conversion functions */
/** The type used to store all sample conversion functions.
@see paConverters;
*/
typedef struct{
PaUtilConverter *Float32_To_Int32;
PaUtilConverter *Float32_To_Int32_Dither;
PaUtilConverter *Float32_To_Int32_Clip;
PaUtilConverter *Float32_To_Int32_DitherClip;
PaUtilConverter *Float32_To_Int24;
PaUtilConverter *Float32_To_Int24_Dither;
PaUtilConverter *Float32_To_Int24_Clip;
PaUtilConverter *Float32_To_Int24_DitherClip;
PaUtilConverter *Float32_To_Int16;
PaUtilConverter *Float32_To_Int16_Dither;
PaUtilConverter *Float32_To_Int16_Clip;
PaUtilConverter *Float32_To_Int16_DitherClip;
PaUtilConverter *Float32_To_Int8;
PaUtilConverter *Float32_To_Int8_Dither;
PaUtilConverter *Float32_To_Int8_Clip;
PaUtilConverter *Float32_To_Int8_DitherClip;
PaUtilConverter *Float32_To_UInt8;
PaUtilConverter *Float32_To_UInt8_Dither;
PaUtilConverter *Float32_To_UInt8_Clip;
PaUtilConverter *Float32_To_UInt8_DitherClip;
PaUtilConverter *Int32_To_Float32;
PaUtilConverter *Int32_To_Int24;
PaUtilConverter *Int32_To_Int24_Dither;
PaUtilConverter *Int32_To_Int16;
PaUtilConverter *Int32_To_Int16_Dither;
PaUtilConverter *Int32_To_Int8;
PaUtilConverter *Int32_To_Int8_Dither;
PaUtilConverter *Int32_To_UInt8;
PaUtilConverter *Int32_To_UInt8_Dither;
PaUtilConverter *Int24_To_Float32;
PaUtilConverter *Int24_To_Int32;
PaUtilConverter *Int24_To_Int16;
PaUtilConverter *Int24_To_Int16_Dither;
PaUtilConverter *Int24_To_Int8;
PaUtilConverter *Int24_To_Int8_Dither;
PaUtilConverter *Int24_To_UInt8;
PaUtilConverter *Int24_To_UInt8_Dither;
PaUtilConverter *Int16_To_Float32;
PaUtilConverter *Int16_To_Int32;
PaUtilConverter *Int16_To_Int24;
PaUtilConverter *Int16_To_Int8;
PaUtilConverter *Int16_To_Int8_Dither;
PaUtilConverter *Int16_To_UInt8;
PaUtilConverter *Int16_To_UInt8_Dither;
PaUtilConverter *Int8_To_Float32;
PaUtilConverter *Int8_To_Int32;
PaUtilConverter *Int8_To_Int24;
PaUtilConverter *Int8_To_Int16;
PaUtilConverter *Int8_To_UInt8;
PaUtilConverter *UInt8_To_Float32;
PaUtilConverter *UInt8_To_Int32;
PaUtilConverter *UInt8_To_Int24;
PaUtilConverter *UInt8_To_Int16;
PaUtilConverter *UInt8_To_Int8;
PaUtilConverter *Copy_8_To_8; /* copy without any conversion */
PaUtilConverter *Copy_16_To_16; /* copy without any conversion */
PaUtilConverter *Copy_24_To_24; /* copy without any conversion */
PaUtilConverter *Copy_32_To_32; /* copy without any conversion */
} PaUtilConverterTable;
/** A table of pointers to all required converter functions.
PaUtil_SelectConverter() uses this table to lookup the appropriate
conversion functions. The fields of this structure are initialized
with default conversion functions. Fields may be NULL, indicating that
no conversion function is available. User code may substitue optimised
conversion functions by assigning different function pointers to
these fields.
@note
If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined,
PortAudio's standard converters will not be compiled, and all fields
of this structure will be initialized to NULL. In such cases, users
should supply their own conversion functions if the require PortAudio
to open a stream that requires sample conversion.
@see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter
*/
extern PaUtilConverterTable paConverters;
/** The type used to store all buffer zeroing functions.
@see paZeroers;
*/
typedef struct{
PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */
PaUtilZeroer *Zero8;
PaUtilZeroer *Zero16;
PaUtilZeroer *Zero24;
PaUtilZeroer *Zero32;
} PaUtilZeroerTable;
/** A table of pointers to all required zeroer functions.
PaUtil_SelectZeroer() uses this table to lookup the appropriate
conversion functions. The fields of this structure are initialized
with default conversion functions. User code may substitue optimised
conversion functions by assigning different function pointers to
these fields.
@note
If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined,
PortAudio's standard zeroers will not be compiled, and all fields
of this structure will be initialized to NULL. In such cases, users
should supply their own zeroing functions for the sample sizes which
they intend to use.
@see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer
*/
extern PaUtilZeroerTable paZeroers;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_CONVERTERS_H */

View File

@ -1,105 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library CPU Load measurement functions
* Portable CPU load measurement facility.
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 2002 Ross Bencina
*
* 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 common_src
@brief Functions to assist in measuring the CPU utilization of a callback
stream. Used to implement the Pa_GetStreamCpuLoad() function.
@todo Dynamically calculate the coefficients used to smooth the CPU Load
Measurements over time to provide a uniform characterisation of CPU Load
independent of rate at which PaUtil_BeginCpuLoadMeasurement /
PaUtil_EndCpuLoadMeasurement are called. see http://www.portaudio.com/trac/ticket/113
*/
#include "pa_cpuload.h"
#include <assert.h>
#include "pa_util.h" /* for PaUtil_GetTime() */
void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate )
{
assert( sampleRate > 0 );
measurer->samplingPeriod = 1. / sampleRate;
measurer->averageLoad = 0.;
}
void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer )
{
measurer->averageLoad = 0.;
}
void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer )
{
measurer->measurementStartTime = PaUtil_GetTime();
}
void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed )
{
double measurementEndTime, secondsFor100Percent, measuredLoad;
if( framesProcessed > 0 ){
measurementEndTime = PaUtil_GetTime();
assert( framesProcessed > 0 );
secondsFor100Percent = framesProcessed * measurer->samplingPeriod;
measuredLoad = (measurementEndTime - measurer->measurementStartTime) / secondsFor100Percent;
/* Low pass filter the calculated CPU load to reduce jitter using a simple IIR low pass filter. */
/** FIXME @todo these coefficients shouldn't be hardwired see: http://www.portaudio.com/trac/ticket/113 */
#define LOWPASS_COEFFICIENT_0 (0.9)
#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)
measurer->averageLoad = (LOWPASS_COEFFICIENT_0 * measurer->averageLoad) +
(LOWPASS_COEFFICIENT_1 * measuredLoad);
}
}
double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer )
{
return measurer->averageLoad;
}

View File

@ -1,72 +0,0 @@
#ifndef PA_CPULOAD_H
#define PA_CPULOAD_H
/*
* $Id$
* Portable Audio I/O Library CPU Load measurement functions
* Portable CPU load measurement facility.
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 2002 Ross Bencina
*
* 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 common_src
@brief Functions to assist in measuring the CPU utilization of a callback
stream. Used to implement the Pa_GetStreamCpuLoad() function.
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
typedef struct {
double samplingPeriod;
double measurementStartTime;
double averageLoad;
} PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */
void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate );
void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer );
void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed );
void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer );
double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_CPULOAD_H */

View File

@ -1,123 +0,0 @@
/*
* $Id: pa_log.c $
* Portable Audio I/O Library Multi-Host API front end
* Validate function parameters and manage multiple host APIs.
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2006 Ross Bencina, 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 common_src
@brief Implements log function.
PaUtil_SetLogPrintFunction can be user called to replace the provided
DefaultLogPrint function, which writes to stderr.
One can NOT pass var_args across compiler/dll boundaries as it is not
"byte code/abi portable". So the technique used here is to allocate a local
a static array, write in it, then callback the user with a pointer to its
start.
*/
#include <stdio.h>
#include <stdarg.h>
#include "pa_debugprint.h"
// for OutputDebugStringA
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
#define WIN32_LEAN_AND_MEAN // exclude rare headers
#include "windows.h"
#endif
// User callback
static PaUtilLogCallback userCB = NULL;
// Sets user callback
void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb)
{
userCB = cb;
}
/*
If your platform doesnt have vsnprintf, you are stuck with a
VERY dangerous alternative, vsprintf (with no n)
*/
#if _MSC_VER
/* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully).
According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC.
*/
#define VSNPRINTF _vsnprintf
#else
#define VSNPRINTF vsnprintf
#endif
#define PA_LOG_BUF_SIZE 2048
void PaUtil_DebugPrint( const char *format, ... )
{
// Optional logging into Output console of Visual Studio
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
{
char buf[PA_LOG_BUF_SIZE];
va_list ap;
va_start(ap, format);
VSNPRINTF(buf, sizeof(buf), format, ap);
buf[sizeof(buf)-1] = 0;
OutputDebugStringA(buf);
va_end(ap);
}
#endif
// Output to User-Callback
if (userCB != NULL)
{
char strdump[PA_LOG_BUF_SIZE];
va_list ap;
va_start(ap, format);
VSNPRINTF(strdump, sizeof(strdump), format, ap);
strdump[sizeof(strdump)-1] = 0;
userCB(strdump);
va_end(ap);
}
else
// Standard output to stderr
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fflush(stderr);
}
}

View File

@ -1,149 +0,0 @@
#ifndef PA_LOG_H
#define PA_LOG_H
/*
* Log file redirector function
* Copyright (c) 1999-2006 Ross Bencina, 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 common_src
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void PaUtil_DebugPrint( const char *format, ... );
/*
The basic format for log messages is described below. If you need to
add any log messages, please follow this format.
Function entry (void function):
"FunctionName called.\n"
Function entry (non void function):
"FunctionName called:\n"
"\tParam1Type param1: param1Value\n"
"\tParam2Type param2: param2Value\n" (etc...)
Function exit (no return value):
"FunctionName returned.\n"
Function exit (simple return value):
"FunctionName returned:\n"
"\tReturnType: returnValue\n"
If the return type is an error code, the error text is displayed in ()
If the return type is not an error code, but has taken a special value
because an error occurred, then the reason for the error is shown in []
If the return type is a struct ptr, the struct is dumped.
See the code below for examples
*/
/** PA_DEBUG() provides a simple debug message printing facility. The macro
passes it's argument to a printf-like function called PaUtil_DebugPrint()
which prints to stderr and always flushes the stream after printing.
Because preprocessor macros cannot directly accept variable length argument
lists, calls to the macro must include an additional set of parenthesis, eg:
PA_DEBUG(("errorno: %d", 1001 ));
*/
#ifdef PA_ENABLE_DEBUG_OUTPUT
#define PA_DEBUG(x) PaUtil_DebugPrint x ;
#else
#define PA_DEBUG(x)
#endif
#ifdef PA_LOG_API_CALLS
#define PA_LOGAPI(x) PaUtil_DebugPrint x
#define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" )
#define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" )
#define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" )
#define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
PaUtil_DebugPrint("\t" resultFormatString "\n", result )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \
PaUtil_DebugPrint( functionName " returned:\n" ); \
if( result > 0 ) \
PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \
else \
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#else
#define PA_LOGAPI(x)
#define PA_LOGAPI_ENTER(functionName)
#define PA_LOGAPI_ENTER_PARAMS(functionName)
#define PA_LOGAPI_EXIT(functionName)
#define PA_LOGAPI_EXIT_PAERROR( functionName, result )
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result )
#endif
typedef void (*PaUtilLogCallback ) (const char *log);
/**
Install user provided log function
*/
void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_LOG_H */

View File

@ -1,218 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library triangular dither generator
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
*
* 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 common_src
@brief Functions for generating dither noise
*/
#include "pa_types.h"
#include "pa_dither.h"
/* Note that the linear congruential algorithm requires 32 bit integers
* because it uses arithmetic overflow. So use PaUint32 instead of
* unsigned long so it will work on 64 bit systems.
*/
#define PA_DITHER_BITS_ (15)
void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *state )
{
state->previous = 0;
state->randSeed1 = 22222;
state->randSeed2 = 5555555;
}
PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *state )
{
PaInt32 current, highPass;
/* Generate two random numbers. */
state->randSeed1 = (state->randSeed1 * 196314165) + 907633515;
state->randSeed2 = (state->randSeed2 * 196314165) + 907633515;
/* Generate triangular distribution about 0.
* Shift before adding to prevent overflow which would skew the distribution.
* Also shift an extra bit for the high pass filter.
*/
#define DITHER_SHIFT_ ((sizeof(PaInt32)*8 - PA_DITHER_BITS_) + 1)
current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) +
(((PaInt32)state->randSeed2)>>DITHER_SHIFT_);
/* High pass filter to reduce audibility. */
highPass = current - state->previous;
state->previous = current;
return highPass;
}
/* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */
#define PA_FLOAT_DITHER_SCALE_ (1.0f / ((1<<PA_DITHER_BITS_)-1))
static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *state )
{
PaInt32 current, highPass;
/* Generate two random numbers. */
state->randSeed1 = (state->randSeed1 * 196314165) + 907633515;
state->randSeed2 = (state->randSeed2 * 196314165) + 907633515;
/* Generate triangular distribution about 0.
* Shift before adding to prevent overflow which would skew the distribution.
* Also shift an extra bit for the high pass filter.
*/
current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) +
(((PaInt32)state->randSeed2)>>DITHER_SHIFT_);
/* High pass filter to reduce audibility. */
highPass = current - state->previous;
state->previous = current;
return ((float)highPass) * const_float_dither_scale_;
}
/*
The following alternate dither algorithms (from musicdsp.org) could be
considered
*/
/*Noise shaped dither (March 2000)
-------------------
This is a simple implementation of highpass triangular-PDF dither with
2nd-order noise shaping, for use when truncating floating point audio
data to fixed point.
The noise shaping lowers the noise floor by 11dB below 5kHz (@ 44100Hz
sample rate) compared to triangular-PDF dither. The code below assumes
input data is in the range +1 to -1 and doesn't check for overloads!
To save time when generating dither for multiple channels you can do
things like this: r3=(r1 & 0x7F)<<8; instead of calling rand() again.
int r1, r2; //rectangular-PDF random numbers
float s1, s2; //error feedback buffers
float s = 0.5f; //set to 0.0f for no noise shaping
float w = pow(2.0,bits-1); //word length (usually bits=16)
float wi= 1.0f/w;
float d = wi / RAND_MAX; //dither amplitude (2 lsb)
float o = wi * 0.5f; //remove dc offset
float in, tmp;
int out;
//for each sample...
r2=r1; //can make HP-TRI dither by
r1=rand(); //subtracting previous rand()
in += s * (s1 + s1 - s2); //error feedback
tmp = in + o + d * (float)(r1 - r2); //dc offset and dither
out = (int)(w * tmp); //truncate downwards
if(tmp<0.0f) out--; //this is faster than floor()
s2 = s1;
s1 = in - wi * (float)out; //error
--
paul.kellett@maxim.abel.co.uk
http://www.maxim.abel.co.uk
*/
/*
16-to-8-bit first-order dither
Type : First order error feedforward dithering code
References : Posted by Jon Watte
Notes :
This is about as simple a dithering algorithm as you can implement, but it's
likely to sound better than just truncating to N bits.
Note that you might not want to carry forward the full difference for infinity.
It's probably likely that the worst performance hit comes from the saturation
conditionals, which can be avoided with appropriate instructions on many DSPs
and integer SIMD type instructions, or CMOV.
Last, if sound quality is paramount (such as when going from > 16 bits to 16
bits) you probably want to use a higher-order dither function found elsewhere
on this site.
Code :
// This code will down-convert and dither a 16-bit signed short
// mono signal into an 8-bit unsigned char signal, using a first
// order forward-feeding error term dither.
#define uchar unsigned char
void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory )
{
int m = *memory;
while( count-- > 0 ) {
int i = *input++;
i += m;
int j = i + 32768 - 128;
uchar o;
if( j < 0 ) {
o = 0;
}
else if( j > 65535 ) {
o = 255;
}
else {
o = (uchar)((j>>8)&0xff);
}
m = ((j-32768+128)-i);
*output++ = o;
}
*memory = m;
}
*/

View File

@ -1,106 +0,0 @@
#ifndef PA_DITHER_H
#define PA_DITHER_H
/*
* $Id$
* Portable Audio I/O Library triangular dither generator
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
*
* 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 common_src
@brief Functions for generating dither noise
*/
#include "pa_types.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* Note that the linear congruential algorithm requires 32 bit integers
* because it uses arithmetic overflow. So use PaUint32 instead of
* unsigned long so it will work on 64 bit systems.
*/
/** @brief State needed to generate a dither signal */
typedef struct PaUtilTriangularDitherGenerator{
PaUint32 previous;
PaUint32 randSeed1;
PaUint32 randSeed2;
} PaUtilTriangularDitherGenerator;
/** @brief Initialize dither state */
void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState );
/**
@brief Calculate 2 LSB dither signal with a triangular distribution.
Ranged for adding to a 1 bit right-shifted 32 bit integer
prior to >>15. eg:
<pre>
signed long in = *
signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
signed short out = (signed short)(((in>>1) + dither) >> 15);
</pre>
@return
A signed 32-bit integer with a range of +32767 to -32768
*/
PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
/**
@brief Calculate 2 LSB dither signal with a triangular distribution.
Ranged for adding to a pre-scaled float.
<pre>
float in = *
float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
// use smaller scaler to prevent overflow when we add the dither
signed short out = (signed short)(in*(32766.0f) + dither );
</pre>
@return
A float with a range of -2.0 to +1.99999.
*/
float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_DITHER_H */

View File

@ -1,145 +0,0 @@
#ifndef PA_ENDIANNESS_H
#define PA_ENDIANNESS_H
/*
* $Id$
* Portable Audio I/O Library current platform endianness macros
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
*
* 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 common_src
@brief Configure endianness symbols for the target processor.
Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols
to be defined. The one that is defined reflects the endianness of the target
platform and may be used to implement conditional compilation of byte-order
dependent code.
If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt
is made to override that setting. This may be useful if you have a better way
of determining the platform's endianness. The autoconf mechanism uses this for
example.
A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time
and runtime endiannes and raise an assertion if they don't match.
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* If this is an apple, we need to do detect endianness this way */
#if defined(__APPLE__)
/* we need to do some endian detection that is sensitive to harware arch */
#if defined(__LITTLE_ENDIAN__)
#if !defined( PA_LITTLE_ENDIAN )
#define PA_LITTLE_ENDIAN
#endif
#if defined( PA_BIG_ENDIAN )
#undef PA_BIG_ENDIAN
#endif
#else
#if !defined( PA_BIG_ENDIAN )
#define PA_BIG_ENDIAN
#endif
#if defined( PA_LITTLE_ENDIAN )
#undef PA_LITTLE_ENDIAN
#endif
#endif
#else
/* this is not an apple, so first check the existing defines, and, failing that,
detect well-known architechtures. */
#if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN)
/* endianness define has been set externally, such as by autoconf */
#if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN)
#error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please
#endif
#else
/* endianness define has not been set externally */
/* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__)
#define PA_LITTLE_ENDIAN /* win32, assume intel byte order */
#else
#define PA_BIG_ENDIAN
#endif
#endif
#if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN)
/*
If the following error is raised, you either need to modify the code above
to automatically determine the endianness from other symbols defined on your
platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally.
*/
#error pa_endianness.h was unable to automatically determine the endianness of the target platform
#endif
#endif
/* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness,
and raises an assertion if they don't match. <assert.h> must be included in
the context in which this macro is used.
*/
#if defined(NDEBUG)
#define PA_VALIDATE_ENDIANNESS
#else
#if defined(PA_LITTLE_ENDIAN)
#define PA_VALIDATE_ENDIANNESS \
{ \
const long nativeOne = 1; \
assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \
}
#elif defined(PA_BIG_ENDIAN)
#define PA_VALIDATE_ENDIANNESS \
{ \
const long nativeOne = 1; \
assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \
}
#endif
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_ENDIANNESS_H */

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
#define PA_GIT_REVISION 396fe4b6699ae929d3a685b3ef8a7e97396139a4

View File

@ -1,362 +0,0 @@
#ifndef PA_HOSTAPI_H
#define PA_HOSTAPI_H
/*
* $Id$
* Portable Audio I/O Library
* host api representation
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2008 Ross Bencina, 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 common_src
@brief Interfaces and representation structures used by pa_front.c
to manage and communicate with host API implementations.
*/
#include "portaudio.h"
/**
The PA_NO_* host API macros are now deprecated in favor of PA_USE_* macros.
PA_USE_* indicates whether a particular host API will be initialized by PortAudio.
An undefined or 0 value indicates that the host API will not be used. A value of 1
indicates that the host API will be used. PA_USE_* macros should be left undefined
or defined to either 0 or 1.
The code below ensures that PA_USE_* macros are always defined and have value
0 or 1. Undefined symbols are defaulted to 0. Symbols that are neither 0 nor 1
are defaulted to 1.
*/
#ifndef PA_USE_SKELETON
#define PA_USE_SKELETON 0
#elif (PA_USE_SKELETON != 0) && (PA_USE_SKELETON != 1)
#undef PA_USE_SKELETON
#define PA_USE_SKELETON 1
#endif
#if defined(PA_NO_ASIO) || defined(PA_NO_DS) || defined(PA_NO_WMME) || defined(PA_NO_WASAPI) || defined(PA_NO_WDMKS)
#error "Portaudio: PA_NO_<APINAME> is no longer supported, please remove definition and use PA_USE_<APINAME> instead"
#endif
#ifndef PA_USE_ASIO
#define PA_USE_ASIO 0
#elif (PA_USE_ASIO != 0) && (PA_USE_ASIO != 1)
#undef PA_USE_ASIO
#define PA_USE_ASIO 1
#endif
#ifndef PA_USE_DS
#define PA_USE_DS 0
#elif (PA_USE_DS != 0) && (PA_USE_DS != 1)
#undef PA_USE_DS
#define PA_USE_DS 1
#endif
#ifndef PA_USE_WMME
#define PA_USE_WMME 0
#elif (PA_USE_WMME != 0) && (PA_USE_WMME != 1)
#undef PA_USE_WMME
#define PA_USE_WMME 1
#endif
#ifndef PA_USE_WASAPI
#define PA_USE_WASAPI 0
#elif (PA_USE_WASAPI != 0) && (PA_USE_WASAPI != 1)
#undef PA_USE_WASAPI
#define PA_USE_WASAPI 1
#endif
#ifndef PA_USE_WDMKS
#define PA_USE_WDMKS 0
#elif (PA_USE_WDMKS != 0) && (PA_USE_WDMKS != 1)
#undef PA_USE_WDMKS
#define PA_USE_WDMKS 1
#endif
/* Set default values for Unix based APIs. */
#if defined(PA_NO_OSS) || defined(PA_NO_ALSA) || defined(PA_NO_JACK) || defined(PA_NO_COREAUDIO) || defined(PA_NO_SGI) || defined(PA_NO_ASIHPI)
#error "Portaudio: PA_NO_<APINAME> is no longer supported, please remove definition and use PA_USE_<APINAME> instead"
#endif
#ifndef PA_USE_OSS
#define PA_USE_OSS 0
#elif (PA_USE_OSS != 0) && (PA_USE_OSS != 1)
#undef PA_USE_OSS
#define PA_USE_OSS 1
#endif
#ifndef PA_USE_ALSA
#define PA_USE_ALSA 0
#elif (PA_USE_ALSA != 0) && (PA_USE_ALSA != 1)
#undef PA_USE_ALSA
#define PA_USE_ALSA 1
#endif
#ifndef PA_USE_JACK
#define PA_USE_JACK 0
#elif (PA_USE_JACK != 0) && (PA_USE_JACK != 1)
#undef PA_USE_JACK
#define PA_USE_JACK 1
#endif
#ifndef PA_USE_SGI
#define PA_USE_SGI 0
#elif (PA_USE_SGI != 0) && (PA_USE_SGI != 1)
#undef PA_USE_SGI
#define PA_USE_SGI 1
#endif
#ifndef PA_USE_COREAUDIO
#define PA_USE_COREAUDIO 0
#elif (PA_USE_COREAUDIO != 0) && (PA_USE_COREAUDIO != 1)
#undef PA_USE_COREAUDIO
#define PA_USE_COREAUDIO 1
#endif
#ifndef PA_USE_ASIHPI
#define PA_USE_ASIHPI 0
#elif (PA_USE_ASIHPI != 0) && (PA_USE_ASIHPI != 1)
#undef PA_USE_ASIHPI
#define PA_USE_ASIHPI 1
#endif
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/** **FOR THE USE OF pa_front.c ONLY**
Do NOT use fields in this structure, they my change at any time.
Use functions defined in pa_util.h if you think you need functionality
which can be derived from here.
*/
typedef struct PaUtilPrivatePaFrontHostApiInfo {
unsigned long baseDeviceIndex;
}PaUtilPrivatePaFrontHostApiInfo;
/** The common header for all data structures whose pointers are passed through
the hostApiSpecificStreamInfo field of the PaStreamParameters structure.
Note that in order to keep the public PortAudio interface clean, this structure
is not used explicitly when declaring hostApiSpecificStreamInfo data structures.
However, some code in pa_front depends on the first 3 members being equivalent
with this structure.
@see PaStreamParameters
*/
typedef struct PaUtilHostApiSpecificStreamInfoHeader
{
unsigned long size; /**< size of whole structure including this header */
PaHostApiTypeId hostApiType; /**< host API for which this data is intended */
unsigned long version; /**< structure version */
} PaUtilHostApiSpecificStreamInfoHeader;
/** A structure representing the interface to a host API. Contains both
concrete data and pointers to functions which implement the interface.
*/
typedef struct PaUtilHostApiRepresentation {
PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo;
/** The host api implementation should populate the info field. In the
case of info.defaultInputDevice and info.defaultOutputDevice the
values stored should be 0 based indices within the host api's own
device index range (0 to deviceCount). These values will be converted
to global device indices by pa_front after PaUtilHostApiInitializer()
returns.
*/
PaHostApiInfo info;
PaDeviceInfo** deviceInfos;
/**
(*Terminate)() is guaranteed to be called with a valid <hostApi>
parameter, which was previously returned from the same implementation's
initializer.
*/
void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi );
/**
The inputParameters and outputParameters pointers should not be saved
as they will not remain valid after OpenStream is called.
The following guarantees are made about parameters to (*OpenStream)():
[NOTE: the following list up to *END PA FRONT VALIDATIONS* should be
kept in sync with the one for ValidateOpenStreamParameters and
Pa_OpenStream in pa_front.c]
PaHostApiRepresentation *hostApi
- is valid for this implementation
PaStream** stream
- is non-null
- at least one of inputParameters & outputParmeters is valid (not NULL)
- if inputParameters & outputParmeters are both valid, that
inputParameters->device & outputParmeters->device both use the same host api
PaDeviceIndex inputParameters->device
- is within range (0 to Pa_CountDevices-1) Or:
- is paUseHostApiSpecificDeviceSpecification and
inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
to a valid host api
int inputParameters->numChannels
- if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0
- upper bound is NOT validated against device capabilities
PaSampleFormat inputParameters->sampleFormat
- is one of the sample formats defined in portaudio.h
void *inputParameters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the input device's host Api
PaDeviceIndex outputParmeters->device
- is within range (0 to Pa_CountDevices-1)
int outputParmeters->numChannels
- if inputDevice is valid, numInputChannels is > 0
- upper bound is NOT validated against device capabilities
PaSampleFormat outputParmeters->sampleFormat
- is one of the sample formats defined in portaudio.h
void *outputParmeters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the output device's host Api
double sampleRate
- is not an 'absurd' rate (less than 1000. or greater than 384000.)
- sampleRate is NOT validated against device capabilities
PaStreamFlags streamFlags
- unused platform neutral flags are zero
- paNeverDropInput is only used for full-duplex callback streams
with variable buffer size (paFramesPerBufferUnspecified)
[*END PA FRONT VALIDATIONS*]
The following validations MUST be performed by (*OpenStream)():
- check that input device can support numInputChannels
- check that input device can support inputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
- if inputStreamInfo is supplied, validate its contents,
or return an error if no inputStreamInfo is expected
- check that output device can support numOutputChannels
- check that output device can support outputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
- if outputStreamInfo is supplied, validate its contents,
or return an error if no outputStreamInfo is expected
- if a full duplex stream is requested, check that the combination
of input and output parameters is supported
- check that the device supports sampleRate
- alter sampleRate to a close allowable rate if necessary
- validate inputLatency and outputLatency
- validate any platform specific flags, if flags are supplied they
must be valid.
*/
PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi,
PaStream** stream,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate,
unsigned long framesPerCallback,
PaStreamFlags streamFlags,
PaStreamCallback *streamCallback,
void *userData );
PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate );
} PaUtilHostApiRepresentation;
/** Prototype for the initialization function which must be implemented by every
host API.
This function should only return an error other than paNoError if it encounters
an unexpected and fatal error (memory allocation error for example). In general,
there may be conditions under which it returns a NULL interface pointer and also
returns paNoError. For example, if the ASIO implementation detects that ASIO is
not installed, it should return a NULL interface, and paNoError.
@see paHostApiInitializers
*/
typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex );
/** paHostApiInitializers is a NULL-terminated array of host API initialization
functions. These functions are called by pa_front.c to initialize the host APIs
when the client calls Pa_Initialize().
The initialization functions are invoked in order.
The first successfully initialized host API that has a default input *or* output
device is used as the default PortAudio host API. This is based on the logic that
there is only one default host API, and it must contain the default input and output
devices (if defined).
There is a platform specific file that defines paHostApiInitializers for that
platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example.
*/
extern PaUtilHostApiInitializer *paHostApiInitializers[];
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_HOSTAPI_H */

View File

@ -1,128 +0,0 @@
/*
* $Id: pa_memorybarrier.h 1240 2007-07-17 13:05:07Z bjornroche $
* Portable Audio I/O Library
* Memory barrier utilities
*
* Author: Bjorn Roche, XO Audio, LLC
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 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 pa_memorybarrier.h
@ingroup common_src
*/
/****************
* Some memory barrier primitives based on the system.
* right now only OS X, FreeBSD, and Linux are supported. In addition to providing
* memory barriers, these functions should ensure that data cached in registers
* is written out to cache where it can be snooped by other CPUs. (ie, the volatile
* keyword should not be required)
*
* the primitives that must be defined are:
*
* PaUtil_FullMemoryBarrier()
* PaUtil_ReadMemoryBarrier()
* PaUtil_WriteMemoryBarrier()
*
****************/
#if defined(__APPLE__)
# include <libkern/OSAtomic.h>
/* Here are the memory barrier functions. Mac OS X only provides
full memory barriers, so the three types of barriers are the same,
however, these barriers are superior to compiler-based ones. */
# define PaUtil_FullMemoryBarrier() OSMemoryBarrier()
# define PaUtil_ReadMemoryBarrier() OSMemoryBarrier()
# define PaUtil_WriteMemoryBarrier() OSMemoryBarrier()
#elif defined(__GNUC__)
/* GCC >= 4.1 has built-in intrinsics. We'll use those */
# if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
# define PaUtil_FullMemoryBarrier() __sync_synchronize()
# define PaUtil_ReadMemoryBarrier() __sync_synchronize()
# define PaUtil_WriteMemoryBarrier() __sync_synchronize()
/* as a fallback, GCC understands volatile asm and "memory" to mean it
* should not reorder memory read/writes */
/* Note that it is not clear that any compiler actually defines __PPC__,
* it can probably removed safely. */
# elif defined( __ppc__ ) || defined( __powerpc__) || defined( __PPC__ )
# define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory")
# define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory")
# define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory")
# elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \
defined( __i686__ ) || defined( __x86_64__ )
# define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory")
# define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory")
# define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory")
# else
# ifdef ALLOW_SMP_DANGERS
# warning Memory barriers not defined on this system or system unknown
# warning For SMP safety, you should fix this.
# define PaUtil_FullMemoryBarrier()
# define PaUtil_ReadMemoryBarrier()
# define PaUtil_WriteMemoryBarrier()
# else
# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
# endif
# endif
#elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE)
# include <intrin.h>
# pragma intrinsic(_ReadWriteBarrier)
# pragma intrinsic(_ReadBarrier)
# pragma intrinsic(_WriteBarrier)
/* note that MSVC intrinsics _ReadWriteBarrier(), _ReadBarrier(), _WriteBarrier() are just compiler barriers *not* memory barriers */
# define PaUtil_FullMemoryBarrier() _ReadWriteBarrier()
# define PaUtil_ReadMemoryBarrier() _ReadBarrier()
# define PaUtil_WriteMemoryBarrier() _WriteBarrier()
#elif defined(_WIN32_WCE)
# define PaUtil_FullMemoryBarrier()
# define PaUtil_ReadMemoryBarrier()
# define PaUtil_WriteMemoryBarrier()
#elif defined(_MSC_VER) || defined(__BORLANDC__)
# define PaUtil_FullMemoryBarrier() _asm { lock add [esp], 0 }
# define PaUtil_ReadMemoryBarrier() _asm { lock add [esp], 0 }
# define PaUtil_WriteMemoryBarrier() _asm { lock add [esp], 0 }
#else
# ifdef ALLOW_SMP_DANGERS
# warning Memory barriers not defined on this system or system unknown
# warning For SMP safety, you should fix this.
# define PaUtil_FullMemoryBarrier()
# define PaUtil_ReadMemoryBarrier()
# define PaUtil_WriteMemoryBarrier()
# else
# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
# endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,754 +0,0 @@
#ifndef PA_PROCESS_H
#define PA_PROCESS_H
/*
* $Id$
* Portable Audio I/O Library callback buffer processing adapters
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
*
* 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 common_src
@brief Buffer Processor prototypes. A Buffer Processor performs buffer length
adaption, coordinates sample format conversion, and interleaves/deinterleaves
channels.
<h3>Overview</h3>
The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio
data from host buffers to user buffers and back again. Where required, the
buffer processor takes care of converting between host and user sample formats,
interleaving and deinterleaving multichannel buffers, and adapting between host
and user buffers with different lengths. The buffer processor may be used with
full and half duplex streams, for both callback streams and blocking read/write
streams.
One of the important capabilities provided by the buffer processor is
the ability to adapt between user and host buffer sizes of different lengths
with minimum latency. Although this task is relatively easy to perform when
the host buffer size is an integer multiple of the user buffer size, the
problem is more complicated when this is not the case - especially for
full-duplex callback streams. Where necessary the adaption is implemented by
internally buffering some input and/or output data. The buffer adation
algorithm used by the buffer processor was originally implemented by
Stephan Letz for the ASIO version of PortAudio, and is described in his
Callback_adaption_.pdf which is included in the distribution.
The buffer processor performs sample conversion using the functions provided
by pa_converters.c.
The following sections provide an overview of how to use the buffer processor.
Interested readers are advised to consult the host API implementations for
examples of buffer processor usage.
<h4>Initialization, resetting and termination</h4>
When a stream is opened, the buffer processor should be initialized using
PaUtil_InitializeBufferProcessor. This function initializes internal state
and allocates temporary buffers as neccesary according to the supplied
configuration parameters. Some of the parameters correspond to those requested
by the user in their call to Pa_OpenStream(), others reflect the requirements
of the host API implementation - they indicate host buffer sizes, formats,
and the type of buffering which the Host API uses. The buffer processor should
be initialized for callback streams and blocking read/write streams.
Call PaUtil_ResetBufferProcessor to clear any sample data which is present
in the buffer processor before starting to use it (for example when
Pa_StartStream is called).
When the buffer processor is no longer used call
PaUtil_TerminateBufferProcessor.
<h4>Using the buffer processor for a callback stream</h4>
The buffer processor's role in a callback stream is to take host input buffers
process them with the stream callback, and fill host output buffers. For a
full duplex stream, the buffer processor handles input and output simultaneously
due to the requirements of the minimum-latency buffer adation algorithm.
When a host buffer becomes available, the implementation should call
the buffer processor to process the buffer. The buffer processor calls the
stream callback to consume and/or produce audio data as necessary. The buffer
processor will convert sample formats, interleave/deinterleave channels,
and slice or chunk the data to the appropriate buffer lengths according to
the requirements of the stream callback and the host API.
To process a host buffer (or a pair of host buffers for a full-duplex stream)
use the following calling sequence:
-# Call PaUtil_BeginBufferProcessing
-# For a stream which takes input:
- Call PaUtil_SetInputFrameCount with the number of frames in the host input
buffer.
- Call one of the following functions one or more times to tell the
buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
Which function you call will depend on whether the host buffer(s) are
interleaved or not.
- If the available host data is split accross two buffers (for example a
data range at the end of a circular buffer and another range at the
beginning of the circular buffer), also call
PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel,
PaUtil_Set2ndInterleavedInputChannels,
PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer
processor about the second buffer.
-# For a stream which generates output:
- Call PaUtil_SetOutputFrameCount with the number of frames in the host
output buffer.
- Call one of the following functions one or more times to tell the
buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
Which function you call will depend on whether the host buffer(s) are
interleaved or not.
- If the available host output buffer space is split accross two buffers
(for example a data range at the end of a circular buffer and another
range at the beginning of the circular buffer), call
PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel,
PaUtil_Set2ndInterleavedOutputChannels,
PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer
processor about the second buffer.
-# Call PaUtil_EndBufferProcessing, this function performs the actual data
conversion and processing.
<h4>Using the buffer processor for a blocking read/write stream</h4>
Blocking read/write streams use the buffer processor to convert and copy user
output data to a host buffer, and to convert and copy host input data to
the user's buffer. The buffer processor does not perform any buffer adaption.
When using the buffer processor in a blocking read/write stream the input and
output conversion are performed separately by the PaUtil_CopyInput and
PaUtil_CopyOutput functions.
To copy data from a host input buffer to the buffer(s) which the user supplies
to Pa_ReadStream, use the following calling sequence.
- Repeat the following three steps until the user buffer(s) have been filled
with samples from the host input buffers:
-# Call PaUtil_SetInputFrameCount with the number of frames in the host
input buffer.
-# Call one of the following functions one or more times to tell the
buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
Which function you call will depend on whether the host buffer(s) are
interleaved or not.
-# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the
array of buffer pointers for a non-interleaved stream) passed to
Pa_ReadStream, along with the number of frames in the user buffer(s).
Be careful to pass a <i>copy</i> of the user buffer pointers to
PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to
the start of the next region to copy.
- PaUtil_CopyInput will not copy more data than is available in the
host buffer(s), so the above steps need to be repeated until the user
buffer(s) are full.
To copy data to the host output buffer from the user buffers(s) supplied
to Pa_WriteStream use the following calling sequence.
- Repeat the following three steps until all frames from the user buffer(s)
have been copied to the host API:
-# Call PaUtil_SetOutputFrameCount with the number of frames in the host
output buffer.
-# Call one of the following functions one or more times to tell the
buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
Which function you call will depend on whether the host buffer(s) are
interleaved or not.
-# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the
array of buffer pointers for a non-interleaved stream) passed to
Pa_WriteStream, along with the number of frames in the user buffer(s).
Be careful to pass a <i>copy</i> of the user buffer pointers to
PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to
the start of the next region to copy.
- PaUtil_CopyOutput will not copy more data than fits in the host buffer(s),
so the above steps need to be repeated until all user data is copied.
*/
#include "portaudio.h"
#include "pa_converters.h"
#include "pa_dither.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type
of buffering that the host API uses.
The mode used depends on whether the host API or the implementation manages
the buffers, and how these buffers are used (scatter gather, circular buffer).
*/
typedef enum {
/** The host buffer size is a fixed known size. */
paUtilFixedHostBufferSize,
/** The host buffer size may vary, but has a known maximum size. */
paUtilBoundedHostBufferSize,
/** Nothing is known about the host buffer size. */
paUtilUnknownHostBufferSize,
/** The host buffer size varies, and the client does not require the buffer
processor to consume all of the input and fill all of the output buffer. This
is useful when the implementation has access to the host API's circular buffer
and only needs to consume/fill some of it, not necessarily all of it, with each
call to the buffer processor. This is the only mode where
PaUtil_EndBufferProcessing() may not consume the whole buffer.
*/
paUtilVariableHostBufferSizePartialUsageAllowed
}PaUtilHostBufferSizeMode;
/** @brief An auxilliary data structure used internally by the buffer processor
to represent host input and output buffers. */
typedef struct PaUtilChannelDescriptor{
void *data;
unsigned int stride; /**< stride in samples, not bytes */
}PaUtilChannelDescriptor;
/** @brief The main buffer processor data structure.
Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor
and terminate it with PaUtil_TerminateBufferProcessor.
*/
typedef struct {
unsigned long framesPerUserBuffer;
unsigned long framesPerHostBuffer;
PaUtilHostBufferSizeMode hostBufferSizeMode;
int useNonAdaptingProcess;
int userOutputSampleFormatIsEqualToHost;
int userInputSampleFormatIsEqualToHost;
unsigned long framesPerTempBuffer;
unsigned int inputChannelCount;
unsigned int bytesPerHostInputSample;
unsigned int bytesPerUserInputSample;
int userInputIsInterleaved;
PaUtilConverter *inputConverter;
PaUtilZeroer *inputZeroer;
unsigned int outputChannelCount;
unsigned int bytesPerHostOutputSample;
unsigned int bytesPerUserOutputSample;
int userOutputIsInterleaved;
PaUtilConverter *outputConverter;
PaUtilZeroer *outputZeroer;
unsigned long initialFramesInTempInputBuffer;
unsigned long initialFramesInTempOutputBuffer;
void *tempInputBuffer; /**< used for slips, block adaption, and conversion. */
void **tempInputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */
unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
void *tempOutputBuffer; /**< used for slips, block adaption, and conversion. */
void **tempOutputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */
unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
PaStreamCallbackTimeInfo *timeInfo;
PaStreamCallbackFlags callbackStatusFlags;
int hostInputIsInterleaved;
unsigned long hostInputFrameCount[2];
PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors.
pointers are NULL for half-duplex output processing.
hostInputChannels[i].data is NULL when the caller
calls PaUtil_SetNoInput()
*/
int hostOutputIsInterleaved;
unsigned long hostOutputFrameCount[2];
PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors.
pointers are NULL for half-duplex input processing.
hostOutputChannels[i].data is NULL when the caller
calls PaUtil_SetNoOutput()
*/
PaUtilTriangularDitherGenerator ditherGenerator;
double samplePeriod;
PaStreamCallback *streamCallback;
void *userData;
} PaUtilBufferProcessor;
/** @name Initialization, termination, resetting and info */
/*@{*/
/** Initialize a buffer processor's representation stored in a
PaUtilBufferProcessor structure. Be sure to call
PaUtil_TerminateBufferProcessor after finishing with a buffer processor.
@param bufferProcessor The buffer processor structure to initialize.
@param inputChannelCount The number of input channels as passed to
Pa_OpenStream or 0 for an output-only stream.
@param userInputSampleFormat Format of user input samples, as passed to
Pa_OpenStream. This parameter is ignored for ouput-only streams.
@param hostInputSampleFormat Format of host input samples. This parameter is
ignored for output-only streams. See note about host buffer interleave below.
@param outputChannelCount The number of output channels as passed to
Pa_OpenStream or 0 for an input-only stream.
@param userOutputSampleFormat Format of user output samples, as passed to
Pa_OpenStream. This parameter is ignored for input-only streams.
@param hostOutputSampleFormat Format of host output samples. This parameter is
ignored for input-only streams. See note about host buffer interleave below.
@param sampleRate Sample rate of the stream. The more accurate this is the
better - it is used for updating time stamps when adapting buffers.
@param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is
used for selecting special sample conversion options such as clipping and
dithering.
@param framesPerUserBuffer Number of frames per user buffer, as requested
by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be
zero to indicate that the user will accept any (and varying) buffer sizes.
@param framesPerHostBuffer Specifies the number of frames per host buffer
for the fixed buffer size mode, and the maximum number of frames
per host buffer for the bounded host buffer size mode. It is ignored for
the other modes.
@param hostBufferSizeMode A mode flag indicating the size variability of
host buffers that will be passed to the buffer processor. See
PaUtilHostBufferSizeMode for further details.
@param streamCallback The user stream callback passed to Pa_OpenStream.
@param userData The user data field passed to Pa_OpenStream.
@note The interleave flag is ignored for host buffer formats. Host
interleave is determined by the use of different SetInput and SetOutput
functions.
@return An error code indicating whether the initialization was successful.
If the error code is not PaNoError, the buffer processor was not initialized
and should not be used.
@see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor
*/
PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor,
int inputChannelCount, PaSampleFormat userInputSampleFormat,
PaSampleFormat hostInputSampleFormat,
int outputChannelCount, PaSampleFormat userOutputSampleFormat,
PaSampleFormat hostOutputSampleFormat,
double sampleRate,
PaStreamFlags streamFlags,
unsigned long framesPerUserBuffer, /* 0 indicates don't care */
unsigned long framesPerHostBuffer,
PaUtilHostBufferSizeMode hostBufferSizeMode,
PaStreamCallback *streamCallback, void *userData );
/** Terminate a buffer processor's representation. Deallocates any temporary
buffers allocated by PaUtil_InitializeBufferProcessor.
@param bufferProcessor The buffer processor structure to terminate.
@see PaUtil_InitializeBufferProcessor.
*/
void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
/** Clear any internally buffered data. If you call
PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you
call PaUtil_ResetBufferProcessor in your StartStream call.
@param bufferProcessor The buffer processor to reset.
*/
void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
/** Retrieve the input latency of a buffer processor, in frames.
@param bufferProcessor The buffer processor examine.
@return The input latency introduced by the buffer processor, in frames.
@see PaUtil_GetBufferProcessorOutputLatencyFrames
*/
unsigned long PaUtil_GetBufferProcessorInputLatencyFrames( PaUtilBufferProcessor* bufferProcessor );
/** Retrieve the output latency of a buffer processor, in frames.
@param bufferProcessor The buffer processor examine.
@return The output latency introduced by the buffer processor, in frames.
@see PaUtil_GetBufferProcessorInputLatencyFrames
*/
unsigned long PaUtil_GetBufferProcessorOutputLatencyFrames( PaUtilBufferProcessor* bufferProcessor );
/*@}*/
/** @name Host buffer pointer configuration
Functions to set host input and output buffers, used by both callback streams
and blocking read/write streams.
*/
/*@{*/
/** Set the number of frames in the input host buffer(s) specified by the
PaUtil_Set*InputChannel functions.
@param bufferProcessor The buffer processor.
@param frameCount The number of host input frames. A 0 frameCount indicates to
use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
@see PaUtil_SetNoInput, PaUtil_SetInputChannel,
PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel
*/
void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
unsigned long frameCount );
/** Indicate that no input is avalable. This function should be used when
priming the output of a full-duplex stream opened with the
paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary
to call this or any othe PaUtil_Set*Input* functions for ouput-only streams.
@param bufferProcessor The buffer processor.
*/
void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor );
/** Provide the buffer processor with a pointer to a host input channel.
@param bufferProcessor The buffer processor.
@param channel The channel number.
@param data The buffer.
@param stride The stride from one sample to the next, in samples. For
interleaved host buffers, the stride will usually be the same as the number of
channels in the buffer.
*/
void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data, unsigned int stride );
/** Provide the buffer processor with a pointer to an number of interleaved
host input channels.
@param bufferProcessor The buffer processor.
@param firstChannel The first channel number.
@param data The buffer.
@param channelCount The number of interleaved channels in the buffer. If
channelCount is zero, the number of channels specified to
PaUtil_InitializeBufferProcessor will be used.
*/
void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
unsigned int firstChannel, void *data, unsigned int channelCount );
/** Provide the buffer processor with a pointer to one non-interleaved host
output channel.
@param bufferProcessor The buffer processor.
@param channel The channel number.
@param data The buffer.
*/
void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data );
/** Use for the second buffer half when the input buffer is split in two halves.
@see PaUtil_SetInputFrameCount
*/
void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
unsigned long frameCount );
/** Use for the second buffer half when the input buffer is split in two halves.
@see PaUtil_SetInputChannel
*/
void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data, unsigned int stride );
/** Use for the second buffer half when the input buffer is split in two halves.
@see PaUtil_SetInterleavedInputChannels
*/
void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
unsigned int firstChannel, void *data, unsigned int channelCount );
/** Use for the second buffer half when the input buffer is split in two halves.
@see PaUtil_SetNonInterleavedInputChannel
*/
void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data );
/** Set the number of frames in the output host buffer(s) specified by the
PaUtil_Set*OutputChannel functions.
@param bufferProcessor The buffer processor.
@param frameCount The number of host output frames. A 0 frameCount indicates to
use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
@see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels,
PaUtil_SetNonInterleavedOutputChannel
*/
void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
unsigned long frameCount );
/** Indicate that the output will be discarded. This function should be used
when implementing the paNeverDropInput mode for full duplex streams.
@param bufferProcessor The buffer processor.
*/
void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor );
/** Provide the buffer processor with a pointer to a host output channel.
@param bufferProcessor The buffer processor.
@param channel The channel number.
@param data The buffer.
@param stride The stride from one sample to the next, in samples. For
interleaved host buffers, the stride will usually be the same as the number of
channels in the buffer.
*/
void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data, unsigned int stride );
/** Provide the buffer processor with a pointer to a number of interleaved
host output channels.
@param bufferProcessor The buffer processor.
@param firstChannel The first channel number.
@param data The buffer.
@param channelCount The number of interleaved channels in the buffer. If
channelCount is zero, the number of channels specified to
PaUtil_InitializeBufferProcessor will be used.
*/
void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
unsigned int firstChannel, void *data, unsigned int channelCount );
/** Provide the buffer processor with a pointer to one non-interleaved host
output channel.
@param bufferProcessor The buffer processor.
@param channel The channel number.
@param data The buffer.
*/
void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data );
/** Use for the second buffer half when the output buffer is split in two halves.
@see PaUtil_SetOutputFrameCount
*/
void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
unsigned long frameCount );
/** Use for the second buffer half when the output buffer is split in two halves.
@see PaUtil_SetOutputChannel
*/
void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data, unsigned int stride );
/** Use for the second buffer half when the output buffer is split in two halves.
@see PaUtil_SetInterleavedOutputChannels
*/
void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
unsigned int firstChannel, void *data, unsigned int channelCount );
/** Use for the second buffer half when the output buffer is split in two halves.
@see PaUtil_SetNonInterleavedOutputChannel
*/
void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data );
/*@}*/
/** @name Buffer processing functions for callback streams
*/
/*@{*/
/** Commence processing a host buffer (or a pair of host buffers in the
full-duplex case) for a callback stream.
@param bufferProcessor The buffer processor.
@param timeInfo Timing information for the first sample of the host
buffer(s). This information may be adjusted when buffer adaption is being
performed.
@param callbackStatusFlags Flags indicating whether underruns and overruns
have occurred since the last time the buffer processor was called.
*/
void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags );
/** Finish processing a host buffer (or a pair of host buffers in the
full-duplex case) for a callback stream.
@param bufferProcessor The buffer processor.
@param callbackResult On input, indicates a previous callback result, and on
exit, the result of the user stream callback, if it is called.
On entry callbackResult should contain one of { paContinue, paComplete, or
paAbort}. If paComplete is passed, the stream callback will not be called
but any audio that was generated by previous stream callbacks will be copied
to the output buffer(s). You can check whether the buffer processor's internal
buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty.
If the stream callback is called its result is stored in *callbackResult. If
the stream callback returns paComplete or paAbort, all output buffers will be
full of valid data - some of which may be zeros to acount for data that
wasn't generated by the terminating callback.
@return The number of frames processed. This usually corresponds to the
number of frames specified by the PaUtil_Set*FrameCount functions, exept in
the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a
smaller value may be returned.
*/
unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
int *callbackResult );
/** Determine whether any callback generated output remains in the bufffer
processor's internal buffers. This method may be used to determine when to
continue calling PaUtil_EndBufferProcessing() after the callback has returned
a callbackResult of paComplete.
@param bufferProcessor The buffer processor.
@return Returns non-zero when callback generated output remains in the internal
buffer and zero (0) when there internal buffer contains no callback generated
data.
*/
int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor );
/*@}*/
/** @name Buffer processing functions for blocking read/write streams
*/
/*@{*/
/** Copy samples from host input channels set up by the PaUtil_Set*InputChannels
functions to a user supplied buffer. This function is intended for use with
blocking read/write streams. Copies the minimum of the number of
user frames (specified by the frameCount parameter) and the number of available
host frames (specified in a previous call to SetInputFrameCount()).
@param bufferProcessor The buffer processor.
@param buffer A pointer to the user buffer pointer, or a pointer to a pointer
to an array of user buffer pointers for a non-interleaved stream. It is
important that this parameter points to a copy of the user buffer pointers,
not to the actual user buffer pointers, because this function updates the
pointers before returning.
@param frameCount The number of frames of data in the buffer(s) pointed to by
the buffer parameter.
@return The number of frames copied. The buffer pointer(s) pointed to by the
buffer parameter are advanced to point to the frame(s) following the last one
filled.
*/
unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor,
void **buffer, unsigned long frameCount );
/* Copy samples from a user supplied buffer to host output channels set up by
the PaUtil_Set*OutputChannels functions. This function is intended for use with
blocking read/write streams. Copies the minimum of the number of
user frames (specified by the frameCount parameter) and the number of
host frames (specified in a previous call to SetOutputFrameCount()).
@param bufferProcessor The buffer processor.
@param buffer A pointer to the user buffer pointer, or a pointer to a pointer
to an array of user buffer pointers for a non-interleaved stream. It is
important that this parameter points to a copy of the user buffer pointers,
not to the actual user buffer pointers, because this function updates the
pointers before returning.
@param frameCount The number of frames of data in the buffer(s) pointed to by
the buffer parameter.
@return The number of frames copied. The buffer pointer(s) pointed to by the
buffer parameter are advanced to point to the frame(s) following the last one
copied.
*/
unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor,
const void ** buffer, unsigned long frameCount );
/* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels
functions. This function is useful for flushing streams.
Zeros the minimum of frameCount and the number of host frames specified in a
previous call to SetOutputFrameCount().
@param bufferProcessor The buffer processor.
@param frameCount The maximum number of frames to zero.
@return The number of frames zeroed.
*/
unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor,
unsigned long frameCount );
/*@}*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_PROCESS_H */

View File

@ -1,237 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library
* Ring Buffer utility.
*
* Author: Phil Burk, http://www.softsynth.com
* modified for SMP safety on Mac OS X by Bjorn Roche
* modified for SMP safety on Linux by Leland Lucius
* also, allowed for const where possible
* modified for multiple-byte-sized data elements by Sven Fischer
*
* Note that this is safe only for a single-thread reader and a
* single-thread writer.
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 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 common_src
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "pa_ringbuffer.h"
#include <string.h>
#include "pa_memorybarrier.h"
/***************************************************************************
* Initialize FIFO.
* elementCount must be power of 2, returns -1 if not.
*/
ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr )
{
if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */
rbuf->bufferSize = elementCount;
rbuf->buffer = (char *)dataPtr;
PaUtil_FlushRingBuffer( rbuf );
rbuf->bigMask = (elementCount*2)-1;
rbuf->smallMask = (elementCount)-1;
rbuf->elementSizeBytes = elementSizeBytes;
return 0;
}
/***************************************************************************
** Return number of elements available for reading. */
ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf )
{
return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
}
/***************************************************************************
** Return number of elements available for writing. */
ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf )
{
return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
}
/***************************************************************************
** Clear buffer. Should only be called when buffer is NOT being read or written. */
void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
{
rbuf->writeIndex = rbuf->readIndex = 0;
}
/***************************************************************************
** Get address of region(s) to which we can write data.
** If the region is contiguous, size2 will be zero.
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or elementCount, whichever is smaller.
*/
ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 )
{
ring_buffer_size_t index;
ring_buffer_size_t available = PaUtil_GetRingBufferWriteAvailable( rbuf );
if( elementCount > available ) elementCount = available;
/* Check to see if write is not contiguous. */
index = rbuf->writeIndex & rbuf->smallMask;
if( (index + elementCount) > rbuf->bufferSize )
{
/* Write data in two blocks that wrap the buffer. */
ring_buffer_size_t firstHalf = rbuf->bufferSize - index;
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = firstHalf;
*dataPtr2 = &rbuf->buffer[0];
*sizePtr2 = elementCount - firstHalf;
}
else
{
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = elementCount;
*dataPtr2 = NULL;
*sizePtr2 = 0;
}
if( available )
PaUtil_FullMemoryBarrier(); /* (write-after-read) => full barrier */
return elementCount;
}
/***************************************************************************
*/
ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
{
/* ensure that previous writes are seen before we update the write index
(write after write)
*/
PaUtil_WriteMemoryBarrier();
return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask;
}
/***************************************************************************
** Get address of region(s) from which we can read data.
** If the region is contiguous, size2 will be zero.
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be read or elementCount, whichever is smaller.
*/
ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 )
{
ring_buffer_size_t index;
ring_buffer_size_t available = PaUtil_GetRingBufferReadAvailable( rbuf ); /* doesn't use memory barrier */
if( elementCount > available ) elementCount = available;
/* Check to see if read is not contiguous. */
index = rbuf->readIndex & rbuf->smallMask;
if( (index + elementCount) > rbuf->bufferSize )
{
/* Write data in two blocks that wrap the buffer. */
ring_buffer_size_t firstHalf = rbuf->bufferSize - index;
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = firstHalf;
*dataPtr2 = &rbuf->buffer[0];
*sizePtr2 = elementCount - firstHalf;
}
else
{
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = elementCount;
*dataPtr2 = NULL;
*sizePtr2 = 0;
}
if( available )
PaUtil_ReadMemoryBarrier(); /* (read-after-read) => read barrier */
return elementCount;
}
/***************************************************************************
*/
ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
{
/* ensure that previous reads (copies out of the ring buffer) are always completed before updating (writing) the read index.
(write-after-read) => full barrier
*/
PaUtil_FullMemoryBarrier();
return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask;
}
/***************************************************************************
** Return elements written. */
ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount )
{
ring_buffer_size_t size1, size2, numWritten;
void *data1, *data2;
numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
if( size2 > 0 )
{
memcpy( data1, data, size1*rbuf->elementSizeBytes );
data = ((char *)data) + size1*rbuf->elementSizeBytes;
memcpy( data2, data, size2*rbuf->elementSizeBytes );
}
else
{
memcpy( data1, data, size1*rbuf->elementSizeBytes );
}
PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten );
return numWritten;
}
/***************************************************************************
** Return elements read. */
ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount )
{
ring_buffer_size_t size1, size2, numRead;
void *data1, *data2;
numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
if( size2 > 0 )
{
memcpy( data, data1, size1*rbuf->elementSizeBytes );
data = ((char *)data) + size1*rbuf->elementSizeBytes;
memcpy( data, data2, size2*rbuf->elementSizeBytes );
}
else
{
memcpy( data, data1, size1*rbuf->elementSizeBytes );
}
PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead );
return numRead;
}

View File

@ -1,236 +0,0 @@
#ifndef PA_RINGBUFFER_H
#define PA_RINGBUFFER_H
/*
* $Id$
* Portable Audio I/O Library
* Ring Buffer utility.
*
* Author: Phil Burk, http://www.softsynth.com
* modified for SMP safety on OS X by Bjorn Roche.
* also allowed for const where possible.
* modified for multiple-byte-sized data elements by Sven Fischer
*
* Note that this is safe only for a single-thread reader
* and a single-thread writer.
*
* This program is distributed with the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 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 common_src
@brief Single-reader single-writer lock-free ring buffer
PaUtilRingBuffer is a ring buffer used to transport samples between
different execution contexts (threads, OS callbacks, interrupt handlers)
without requiring the use of any locks. This only works when there is
a single reader and a single writer (ie. one thread or callback writes
to the ring buffer, another thread or callback reads from it).
The PaUtilRingBuffer structure manages a ring buffer containing N
elements, where N must be a power of two. An element may be any size
(specified in bytes).
The memory area used to store the buffer elements must be allocated by
the client prior to calling PaUtil_InitializeRingBuffer() and must outlive
the use of the ring buffer.
@note The ring buffer functions are not normally exposed in the PortAudio libraries.
If you want to call them then you will need to add pa_ringbuffer.c to your application source code.
*/
#if defined(__APPLE__)
#include <sys/types.h>
typedef int32_t ring_buffer_size_t;
#elif defined( __GNUC__ )
typedef long ring_buffer_size_t;
#elif (_MSC_VER >= 1400)
typedef long ring_buffer_size_t;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef long ring_buffer_size_t;
#else
typedef long ring_buffer_size_t;
#endif
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
typedef struct PaUtilRingBuffer
{
ring_buffer_size_t bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
volatile ring_buffer_size_t writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */
volatile ring_buffer_size_t readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */
ring_buffer_size_t bigMask; /**< Used for wrapping indices with extra bit to distinguish full/empty. */
ring_buffer_size_t smallMask; /**< Used for fitting indices to buffer. */
ring_buffer_size_t elementSizeBytes; /**< Number of bytes per element. */
char *buffer; /**< Pointer to the buffer containing the actual data. */
}PaUtilRingBuffer;
/** Initialize Ring Buffer to empty state ready to have elements written to it.
@param rbuf The ring buffer.
@param elementSizeBytes The size of a single data element in bytes.
@param elementCount The number of elements in the buffer (must be a power of 2).
@param dataPtr A pointer to a previously allocated area where the data
will be maintained. It must be elementCount*elementSizeBytes long.
@return -1 if elementCount is not a power of 2, otherwise 0.
*/
ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr );
/** Reset buffer to empty. Should only be called when buffer is NOT being read or written.
@param rbuf The ring buffer.
*/
void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf );
/** Retrieve the number of elements available in the ring buffer for writing.
@param rbuf The ring buffer.
@return The number of elements available for writing.
*/
ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf );
/** Retrieve the number of elements available in the ring buffer for reading.
@param rbuf The ring buffer.
@return The number of elements available for reading.
*/
ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf );
/** Write data to the ring buffer.
@param rbuf The ring buffer.
@param data The address of new data to write to the buffer.
@param elementCount The number of elements to be written.
@return The number of elements written.
*/
ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount );
/** Read data from the ring buffer.
@param rbuf The ring buffer.
@param data The address where the data should be stored.
@param elementCount The number of elements to be read.
@return The number of elements read.
*/
ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount );
/** Get address of region(s) to which we can write data.
@param rbuf The ring buffer.
@param elementCount The number of elements desired.
@param dataPtr1 The address where the first (or only) region pointer will be
stored.
@param sizePtr1 The address where the first (or only) region length will be
stored.
@param dataPtr2 The address where the second region pointer will be stored if
the first region is too small to satisfy elementCount.
@param sizePtr2 The address where the second region length will be stored if
the first region is too small to satisfy elementCount.
@return The room available to be written or elementCount, whichever is smaller.
*/
ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 );
/** Advance the write index to the next location to be written.
@param rbuf The ring buffer.
@param elementCount The number of elements to advance.
@return The new position.
*/
ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount );
/** Get address of region(s) from which we can read data.
@param rbuf The ring buffer.
@param elementCount The number of elements desired.
@param dataPtr1 The address where the first (or only) region pointer will be
stored.
@param sizePtr1 The address where the first (or only) region length will be
stored.
@param dataPtr2 The address where the second region pointer will be stored if
the first region is too small to satisfy elementCount.
@param sizePtr2 The address where the second region length will be stored if
the first region is too small to satisfy elementCount.
@return The number of elements available for reading.
*/
ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 );
/** Advance the read index to the next location to be read.
@param rbuf The ring buffer.
@param elementCount The number of elements to advance.
@return The new position.
*/
ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_RINGBUFFER_H */

View File

@ -1,150 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library
* stream interface
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 2008 Ross Bencina
*
* 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 common_src
@brief Stream interfaces, representation structures and helper functions
used to interface between pa_front.c host API implementations.
*/
#include "pa_stream.h"
void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface,
PaError (*Close)( PaStream* ),
PaError (*Start)( PaStream* ),
PaError (*Stop)( PaStream* ),
PaError (*Abort)( PaStream* ),
PaError (*IsStopped)( PaStream* ),
PaError (*IsActive)( PaStream* ),
PaTime (*GetTime)( PaStream* ),
double (*GetCpuLoad)( PaStream* ),
PaError (*Read)( PaStream*, void *, unsigned long ),
PaError (*Write)( PaStream*, const void *, unsigned long ),
signed long (*GetReadAvailable)( PaStream* ),
signed long (*GetWriteAvailable)( PaStream* ) )
{
streamInterface->Close = Close;
streamInterface->Start = Start;
streamInterface->Stop = Stop;
streamInterface->Abort = Abort;
streamInterface->IsStopped = IsStopped;
streamInterface->IsActive = IsActive;
streamInterface->GetTime = GetTime;
streamInterface->GetCpuLoad = GetCpuLoad;
streamInterface->Read = Read;
streamInterface->Write = Write;
streamInterface->GetReadAvailable = GetReadAvailable;
streamInterface->GetWriteAvailable = GetWriteAvailable;
}
void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation,
PaUtilStreamInterface *streamInterface,
PaStreamCallback *streamCallback,
void *userData )
{
streamRepresentation->magic = PA_STREAM_MAGIC;
streamRepresentation->nextOpenStream = 0;
streamRepresentation->streamInterface = streamInterface;
streamRepresentation->streamCallback = streamCallback;
streamRepresentation->streamFinishedCallback = 0;
streamRepresentation->userData = userData;
streamRepresentation->streamInfo.inputLatency = 0.;
streamRepresentation->streamInfo.outputLatency = 0.;
streamRepresentation->streamInfo.sampleRate = 0.;
}
void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation )
{
streamRepresentation->magic = 0;
}
PaError PaUtil_DummyRead( PaStream* stream,
void *buffer,
unsigned long frames )
{
(void)stream; /* unused parameter */
(void)buffer; /* unused parameter */
(void)frames; /* unused parameter */
return paCanNotReadFromACallbackStream;
}
PaError PaUtil_DummyWrite( PaStream* stream,
const void *buffer,
unsigned long frames )
{
(void)stream; /* unused parameter */
(void)buffer; /* unused parameter */
(void)frames; /* unused parameter */
return paCanNotWriteToACallbackStream;
}
signed long PaUtil_DummyGetReadAvailable( PaStream* stream )
{
(void)stream; /* unused parameter */
return paCanNotReadFromACallbackStream;
}
signed long PaUtil_DummyGetWriteAvailable( PaStream* stream )
{
(void)stream; /* unused parameter */
return paCanNotWriteToACallbackStream;
}
double PaUtil_DummyGetCpuLoad( PaStream* stream )
{
(void)stream; /* unused parameter */
return 0.0;
}

View File

@ -1,205 +0,0 @@
#ifndef PA_STREAM_H
#define PA_STREAM_H
/*
* $Id$
* Portable Audio I/O Library
* stream interface
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2008 Ross Bencina, 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 common_src
@brief Stream interfaces, representation structures and helper functions
used to interface between pa_front.c host API implementations.
*/
#include "portaudio.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define PA_STREAM_MAGIC (0x18273645)
/** A structure representing an (abstract) interface to a host API. Contains
pointers to functions which implement the interface.
All PaStreamInterface functions are guaranteed to be called with a non-null,
valid stream parameter.
*/
typedef struct {
PaError (*Close)( PaStream* stream );
PaError (*Start)( PaStream *stream );
PaError (*Stop)( PaStream *stream );
PaError (*Abort)( PaStream *stream );
PaError (*IsStopped)( PaStream *stream );
PaError (*IsActive)( PaStream *stream );
PaTime (*GetTime)( PaStream *stream );
double (*GetCpuLoad)( PaStream* stream );
PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames );
PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames );
signed long (*GetReadAvailable)( PaStream* stream );
signed long (*GetWriteAvailable)( PaStream* stream );
} PaUtilStreamInterface;
/** Initialize the fields of a PaUtilStreamInterface structure.
*/
void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface,
PaError (*Close)( PaStream* ),
PaError (*Start)( PaStream* ),
PaError (*Stop)( PaStream* ),
PaError (*Abort)( PaStream* ),
PaError (*IsStopped)( PaStream* ),
PaError (*IsActive)( PaStream* ),
PaTime (*GetTime)( PaStream* ),
double (*GetCpuLoad)( PaStream* ),
PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ),
PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ),
signed long (*GetReadAvailable)( PaStream* stream ),
signed long (*GetWriteAvailable)( PaStream* stream ) );
/** Dummy Read function for use in interfaces to a callback based streams.
Pass to the Read parameter of PaUtil_InitializeStreamInterface.
@return An error code indicating that the function has no effect
because the stream is a callback stream.
*/
PaError PaUtil_DummyRead( PaStream* stream,
void *buffer,
unsigned long frames );
/** Dummy Write function for use in an interfaces to callback based streams.
Pass to the Write parameter of PaUtil_InitializeStreamInterface.
@return An error code indicating that the function has no effect
because the stream is a callback stream.
*/
PaError PaUtil_DummyWrite( PaStream* stream,
const void *buffer,
unsigned long frames );
/** Dummy GetReadAvailable function for use in interfaces to callback based
streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface.
@return An error code indicating that the function has no effect
because the stream is a callback stream.
*/
signed long PaUtil_DummyGetReadAvailable( PaStream* stream );
/** Dummy GetWriteAvailable function for use in interfaces to callback based
streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface.
@return An error code indicating that the function has no effect
because the stream is a callback stream.
*/
signed long PaUtil_DummyGetWriteAvailable( PaStream* stream );
/** Dummy GetCpuLoad function for use in an interface to a read/write stream.
Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface.
@return Returns 0.
*/
double PaUtil_DummyGetCpuLoad( PaStream* stream );
/** Non host specific data for a stream. This data is used by pa_front to
forward to the appropriate functions in the streamInterface structure.
*/
typedef struct PaUtilStreamRepresentation {
unsigned long magic; /**< set to PA_STREAM_MAGIC */
struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */
PaUtilStreamInterface *streamInterface;
PaStreamCallback *streamCallback;
PaStreamFinishedCallback *streamFinishedCallback;
void *userData;
PaStreamInfo streamInfo;
} PaUtilStreamRepresentation;
/** Initialize a PaUtilStreamRepresentation structure.
@see PaUtil_InitializeStreamRepresentation
*/
void PaUtil_InitializeStreamRepresentation(
PaUtilStreamRepresentation *streamRepresentation,
PaUtilStreamInterface *streamInterface,
PaStreamCallback *streamCallback,
void *userData );
/** Clean up a PaUtilStreamRepresentation structure previously initialized
by a call to PaUtil_InitializeStreamRepresentation.
@see PaUtil_InitializeStreamRepresentation
*/
void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation );
/** Check that the stream pointer is valid.
@return Returns paNoError if the stream pointer appears to be OK, otherwise
returns an error indicating the cause of failure.
*/
PaError PaUtil_ValidateStreamPointer( PaStream *stream );
/** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation.
@see PaUtilStreamRepresentation
*/
#define PA_STREAM_REP( stream )\
((PaUtilStreamRepresentation*) (stream) )
/** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface.
@see PaUtilStreamRepresentation, PaUtilStreamInterface
*/
#define PA_STREAM_INTERFACE( stream )\
PA_STREAM_REP( (stream) )->streamInterface
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_STREAM_H */

View File

@ -1,238 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library Trace Facility
* Store trace information in real-time for later printing.
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2000 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 common_src
@brief Real-time safe event trace logging facility for debugging.
*/
#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 const *traceTextArray[PA_MAX_TRACE_RECORDS];
static int traceIntArray[PA_MAX_TRACE_RECORDS];
static int traceIndex = 0;
static int traceBlock = 0;
/*********************************************************************/
void PaUtil_ResetTraceMessages()
{
traceIndex = 0;
}
/*********************************************************************/
void PaUtil_DumpTraceMessages()
{
int i;
int messageCount = (traceIndex < PA_MAX_TRACE_RECORDS) ? traceIndex : PA_MAX_TRACE_RECORDS;
printf("DumpTraceMessages: traceIndex = %d\n", traceIndex );
for( i=0; i<messageCount; i++ )
{
printf("%3d: %s = 0x%08X\n",
i, traceTextArray[i], traceIntArray[i] );
}
PaUtil_ResetTraceMessages();
fflush(stdout);
}
/*********************************************************************/
void PaUtil_AddTraceMessage( const char *msg, int data )
{
if( (traceIndex == PA_MAX_TRACE_RECORDS) && (traceBlock == 0) )
{
traceBlock = 1;
/* PaUtil_DumpTraceMessages(); */
}
else if( traceIndex < PA_MAX_TRACE_RECORDS )
{
traceTextArray[traceIndex] = msg;
traceIntArray[traceIndex] = data;
traceIndex++;
}
}
/************************************************************************/
/* 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);
}
#else
/* This stub was added so that this file will generate a symbol.
* Otherwise linker/archiver programs will complain.
*/
int PaUtil_TraceStubToSatisfyLinker(void)
{
return 0;
}
#endif /* TRACE_REALTIME_EVENTS */

View File

@ -1,117 +0,0 @@
#ifndef PA_TRACE_H
#define PA_TRACE_H
/*
* $Id$
* Portable Audio I/O Library Trace Facility
* Store trace information in real-time for later printing.
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2000 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 common_src
@brief Real-time safe event trace logging facility for debugging.
Allows data to be logged to a fixed size trace buffer in a real-time
execution context (such as at interrupt time). Each log entry consists
of a message comprising a string pointer and an int. The trace buffer
may be dumped to stdout later.
This facility is only active if PA_TRACE_REALTIME_EVENTS is set to 1,
otherwise the trace functions expand to no-ops.
@fn PaUtil_ResetTraceMessages
@brief Clear the trace buffer.
@fn PaUtil_AddTraceMessage
@brief Add a message to the trace buffer. A message consists of string and an int.
@param msg The string pointer must remain valid until PaUtil_DumpTraceMessages
is called. As a result, usually only string literals should be passed as
the msg parameter.
@fn PaUtil_DumpTraceMessages
@brief Print all messages in the trace buffer to stdout and clear the trace buffer.
*/
#ifndef PA_TRACE_REALTIME_EVENTS
#define PA_TRACE_REALTIME_EVENTS (0) /**< Set to 1 to enable logging using the trace functions defined below */
#endif
#ifndef PA_MAX_TRACE_RECORDS
#define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */
#endif
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#if PA_TRACE_REALTIME_EVENTS
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
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_TRACE_H */

View File

@ -1,107 +0,0 @@
#ifndef PA_TYPES_H
#define PA_TYPES_H
/*
* Portable Audio I/O Library
* integer type definitions
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2006 Ross Bencina, 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 common_src
@brief Definition of 16 and 32 bit integer types (PaInt16, PaInt32 etc)
SIZEOF_SHORT, SIZEOF_INT and SIZEOF_LONG are set by the configure script
when it is used. Otherwise we default to the common 32 bit values, if your
platform doesn't use configure, and doesn't use the default values below
you will need to explicitly define these symbols in your make file.
A PA_VALIDATE_SIZES macro is provided to assert that the values set in this
file are correct.
*/
#ifndef SIZEOF_SHORT
#define SIZEOF_SHORT 2
#endif
#ifndef SIZEOF_INT
#define SIZEOF_INT 4
#endif
#ifndef SIZEOF_LONG
#define SIZEOF_LONG 4
#endif
#if SIZEOF_SHORT == 2
typedef signed short PaInt16;
typedef unsigned short PaUint16;
#elif SIZEOF_INT == 2
typedef signed int PaInt16;
typedef unsigned int PaUint16;
#else
#error pa_types.h was unable to determine which type to use for 16bit integers on the target platform
#endif
#if SIZEOF_SHORT == 4
typedef signed short PaInt32;
typedef unsigned short PaUint32;
#elif SIZEOF_INT == 4
typedef signed int PaInt32;
typedef unsigned int PaUint32;
#elif SIZEOF_LONG == 4
typedef signed long PaInt32;
typedef unsigned long PaUint32;
#else
#error pa_types.h was unable to determine which type to use for 32bit integers on the target platform
#endif
/* PA_VALIDATE_TYPE_SIZES compares the size of the integer types at runtime to
ensure that PortAudio was configured correctly, and raises an assertion if
they don't match the expected values. <assert.h> must be included in the
context in which this macro is used.
*/
#define PA_VALIDATE_TYPE_SIZES \
{ \
assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint16 ) == 2 ); \
assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt16 ) == 2 ); \
assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint32 ) == 4 ); \
assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt32 ) == 4 ); \
}
#endif /* PA_TYPES_H */

View File

@ -1,159 +0,0 @@
#ifndef PA_UTIL_H
#define PA_UTIL_H
/*
* $Id$
* Portable Audio I/O Library implementation utilities header
* common implementation utilities and interfaces
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2008 Ross Bencina, 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 common_src
@brief Prototypes for utility functions used by PortAudio implementations.
Some functions declared here are defined in pa_front.c while others
are implemented separately for each platform.
*/
#include "portaudio.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
struct PaUtilHostApiRepresentation;
/** Retrieve a specific host API representation. This function can be used
by implementations to retrieve a pointer to their representation in
host api specific extension functions which aren't passed a rep pointer
by pa_front.c.
@param hostApi A pointer to a host API represenation pointer. Apon success
this will receive the requested representation pointer.
@param type A valid host API type identifier.
@returns An error code. If the result is PaNoError then a pointer to the
requested host API representation will be stored in *hostApi. If the host API
specified by type is not found, this function returns paHostApiNotFound.
*/
PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
PaHostApiTypeId type );
/** Convert a PortAudio device index into a host API specific device index.
@param hostApiDevice Pointer to a device index, on success this will recieve the
converted device index value.
@param device The PortAudio device index to convert.
@param hostApi The host api which the index should be converted for.
@returns On success returns PaNoError and places the converted index in the
hostApiDevice parameter.
*/
PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
PaDeviceIndex *hostApiDevice, PaDeviceIndex device,
struct PaUtilHostApiRepresentation *hostApi );
/** Set the host error information returned by Pa_GetLastHostErrorInfo. This
function and the paUnanticipatedHostError error code should be used as a
last resort. Implementors should use existing PA error codes where possible,
or nominate new ones. Note that at it is always better to use
PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an
ambiguous or inaccurate PaError code.
@param hostApiType The host API which encountered the error (ie of the caller)
@param errorCode The error code returned by the native API function.
@param errorText A string describing the error. PaUtil_SetLastHostErrorInfo
makes a copy of the string, so it is not necessary for the pointer to remain
valid after the call to PaUtil_SetLastHostErrorInfo() returns.
*/
void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
const char *errorText );
/* the following functions are implemented in a platform platform specific
.c file
*/
/** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */
void *PaUtil_AllocateMemory( long size );
/** Realease block if non-NULL. block may be NULL */
void PaUtil_FreeMemory( void *block );
/** Return the number of currently allocated blocks. This function can be
used for detecting memory leaks.
@note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If
it isn't, this function will always return 0.
*/
int PaUtil_CountCurrentlyAllocatedBlocks( void );
/** Initialize the clock used by PaUtil_GetTime(). Call this before calling
PaUtil_GetTime.
@see PaUtil_GetTime
*/
void PaUtil_InitializeClock( void );
/** Return the system time in seconds. Used to implement CPU load functions
@see PaUtil_InitializeClock
*/
double PaUtil_GetTime( void );
/* void Pa_Sleep( long msec ); must also be implemented in per-platform .c file */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_UTIL_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +0,0 @@
ASIO-README.txt
This document contains information to help you compile PortAudio with
ASIO support. If you find any omissions or errors in this document
please notify us on the PortAudio mailing list.
NOTE: The Macintosh sections of this document are provided for historical
reference. They refer to pre-OS X Macintosh. PortAudio no longer
supports pre-OS X Macintosh. Steinberg does not support ASIO on Mac OS X.
Building PortAudio with ASIO support
------------------------------------
To build PortAudio with ASIO support you need to compile and link with
pa_asio.c, and files from the ASIO SDK (see below), along with the common
PortAudio files from src/common/ and platform specific files from
src/os/win/ (for Win32).
If you are compiling with a non-Microsoft compiler on Windows, also
compile and link with iasiothiscallresolver.cpp (see below for
an explanation).
For some platforms (MingW, Cygwin/MingW), you may simply
be able to type:
./configure --with-host_os=mingw --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
make
and life will be good. Make sure you update the above with the correct local
path to the ASIO SDK.
For Microsoft Visual C++ there is an build tutorial here:
http://www.portaudio.com/trac/wiki/TutorialDir/Compile/WindowsASIOMSVC
Obtaining the ASIO SDK
----------------------
In order to build PortAudio with ASIO support, you need to download
the ASIO SDK (version 2.0 or later) from Steinberg. Steinberg makes the ASIO
SDK available to anyone free of charge, however they do not permit its
source code to be distributed.
NOTE: In some cases the ASIO SDK may require patching, see below
for further details.
http://www.steinberg.net/en/company/developer.html
If the above link is broken search Google for:
"download steinberg ASIO SDK"
Building the ASIO SDK on Windows
--------------------------------
To build the ASIO SDK on Windows you need to compile and link with the
following files from the ASIO SDK:
asio_sdk\common\asio.cpp
asio_sdk\host\asiodrivers.cpp
asio_sdk\host\pc\asiolist.cpp
You may also need to adjust your include paths to support inclusion of
header files from the above directories.
The ASIO SDK depends on the following COM API functions:
CoInitialize, CoUninitialize, CoCreateInstance, CLSIDFromString
For compilation with MinGW you will need to link with -lole32, for
Borland compilers link with Import32.lib.
Non-Microsoft (MSVC) Compilers on Windows including Borland and GCC
-------------------------------------------------------------------
Steinberg did not specify a calling convention in the IASIO interface
definition. This causes the Microsoft compiler to use the proprietary
thiscall convention which is not compatible with other compilers, such
as compilers from Borland (BCC and C++Builder) and GNU (gcc).
Steinberg's ASIO SDK will compile but crash on initialization if
compiled with a non-Microsoft compiler on Windows.
PortAudio solves this problem using the iasiothiscallresolver library
which is included in the distribution. When building ASIO support for
non-Microsoft compilers, be sure to compile and link with
iasiothiscallresolver.cpp. Note that iasiothiscallresolver includes
conditional directives which cause it to have no effect if it is
compiled with a Microsoft compiler, or on the Macintosh.
If you use configure and make (see above), this should be handled
automatically for you.
For further information about the IASIO thiscall problem see this page:
http://www.rossbencina.com/code/iasio-thiscall-resolver
Building the ASIO SDK on (Pre-OS X) Macintosh
---------------------------------------------
To build the ASIO SDK on Macintosh you need to compile and link with the
following files from the ASIO SDK:
host/asiodrivers.cpp
host/mac/asioshlib.cpp
host/mac/codefragements.cpp
You may also need to adjust your include paths to support inclusion of
header files from the above directories.
(Pre-OS X) Macintosh ASIO SDK Bug Patch
---------------------------------------
There is a bug in the ASIO SDK that causes the Macintosh version to
often fail during initialization. Below is a patch that you can apply.
In codefragments.cpp replace getFrontProcessDirectory function with
the following one (GetFrontProcess replaced by GetCurrentProcess).
bool CodeFragments::getFrontProcessDirectory(void *specs)
{
FSSpec *fss = (FSSpec *)specs;
ProcessInfoRec pif;
ProcessSerialNumber psn;
memset(&psn,0,(long)sizeof(ProcessSerialNumber));
// if(GetFrontProcess(&psn) == noErr) // wrong !!!
if(GetCurrentProcess(&psn) == noErr) // correct !!!
{
pif.processName = 0;
pif.processAppSpec = fss;
pif.processInfoLength = sizeof(ProcessInfoRec);
if(GetProcessInformation(&psn, &pif) == noErr)
return true;
}
return false;
}
###

Binary file not shown.

View File

@ -1,572 +0,0 @@
/*
IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for
the top level description - this comment describes the technical details of
the implementation.
The latest version of this file is available from:
http://www.audiomulch.com/~rossb/code/calliasio
please email comments to Ross Bencina <rossb@audiomulch.com>
BACKGROUND
The IASIO interface declared in the Steinberg ASIO 2 SDK declares
functions with no explicit calling convention. This causes MSVC++ to default
to using the thiscall convention, which is a proprietary convention not
implemented by some non-microsoft compilers - notably borland BCC,
C++Builder, and gcc. MSVC++ is the defacto standard compiler used by
Steinberg. As a result of this situation, the ASIO sdk will compile with
any compiler, however attempting to execute the compiled code will cause a
crash due to different default calling conventions on non-Microsoft
compilers.
IASIOThiscallResolver solves the problem by providing an adapter class that
delegates to the IASIO interface using the correct calling convention
(thiscall). Due to the lack of support for thiscall in the Borland and GCC
compilers, the calls have been implemented in assembly language.
A number of macros are defined for thiscall function calls with different
numbers of parameters, with and without return values - it may be possible
to modify the format of these macros to make them work with other inline
assemblers.
THISCALL DEFINITION
A number of definitions of the thiscall calling convention are floating
around the internet. The following definition has been validated against
output from the MSVC++ compiler:
For non-vararg functions, thiscall works as follows: the object (this)
pointer is passed in ECX. All arguments are passed on the stack in
right to left order. The return value is placed in EAX. The callee
clears the passed arguments from the stack.
FINDING FUNCTION POINTERS FROM AN IASIO POINTER
The first field of a COM object is a pointer to its vtble. Thus a pointer
to an object implementing the IASIO interface also points to a pointer to
that object's vtbl. The vtble is a table of function pointers for all of
the virtual functions exposed by the implemented interfaces.
If we consider a variable declared as a pointer to IASO:
IASIO *theAsioDriver
theAsioDriver points to:
object implementing IASIO
{
IASIOvtbl *vtbl
other data
}
in other words, theAsioDriver points to a pointer to an IASIOvtbl
vtbl points to a table of function pointers:
IASIOvtbl ( interface IASIO : public IUnknown )
{
(IUnknown functions)
0 virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0;
4 virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0;
8 virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;
(IASIO functions)
12 virtual ASIOBool (*init)(void *sysHandle) = 0;
16 virtual void (*getDriverName)(char *name) = 0;
20 virtual long (*getDriverVersion)() = 0;
24 virtual void (*getErrorMessage)(char *string) = 0;
28 virtual ASIOError (*start)() = 0;
32 virtual ASIOError (*stop)() = 0;
36 virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0;
40 virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0;
44 virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize,
long *preferredSize, long *granularity) = 0;
48 virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0;
52 virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0;
56 virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0;
60 virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0;
64 virtual ASIOError (*setClockSource)(long reference) = 0;
68 virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
72 virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0;
76 virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels,
long bufferSize, ASIOCallbacks *callbacks) = 0;
80 virtual ASIOError (*disposeBuffers)() = 0;
84 virtual ASIOError (*controlPanel)() = 0;
88 virtual ASIOError (*future)(long selector,void *opt) = 0;
92 virtual ASIOError (*outputReady)() = 0;
};
The numbers in the left column show the byte offset of each function ptr
from the beginning of the vtbl. These numbers are used in the code below
to select different functions.
In order to find the address of a particular function, theAsioDriver
must first be dereferenced to find the value of the vtbl pointer:
mov eax, theAsioDriver
mov edx, [theAsioDriver] // edx now points to vtbl[0]
Then an offset must be added to the vtbl pointer to select a
particular function, for example vtbl+44 points to the slot containing
a pointer to the getBufferSize function.
Finally vtbl+x must be dereferenced to obtain the value of the function
pointer stored in that address:
call [edx+44] // call the function pointed to by
// the value in the getBufferSize field of the vtbl
SEE ALSO
Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same
problem by providing a new COM interface which wraps IASIO with an
interface that uses portable calling conventions. OpenASIO must be compiled
with MSVC, and requires that you ship the OpenASIO DLL with your
application.
ACKNOWLEDGEMENTS
Ross Bencina: worked out the thiscall details above, wrote the original
Borland asm macros, and a patch for asio.cpp (which is no longer needed).
Thanks to Martin Fay for introducing me to the issues discussed here,
and to Rene G. Ceballos for assisting with asm dumps from MSVC++.
Antti Silvast: converted the original calliasio to work with gcc and NASM
by implementing the asm code in a separate file.
Fraser Adams: modified the original calliasio containing the Borland inline
asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax
for gcc. This seems a neater approach for gcc than to have a separate .asm
file and it means that we only need one version of the thiscall patch.
Fraser Adams: rewrote the original calliasio patch in the form of the
IASIOThiscallResolver class in order to avoid modifications to files from
the Steinberg SDK, which may have had potential licence issues.
Andrew Baldwin: contributed fixes for compatibility problems with more
recent versions of the gcc assembler.
*/
// We only need IASIOThiscallResolver at all if we are on Win32. For other
// platforms we simply bypass the IASIOThiscallResolver definition to allow us
// to be safely #include'd whatever the platform to keep client code portable
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64)
// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
// is not used.
#if !defined(_MSC_VER)
#include <new>
#include <assert.h>
// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is
// #include'd before it in client code, we do NOT want to do this test here.
#define iasiothiscallresolver_sourcefile 1
#include "iasiothiscallresolver.h"
#undef iasiothiscallresolver_sourcefile
// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want
// this macro defined in this translation unit.
#undef ASIOInit
// theAsioDriver is a global pointer to the current IASIO instance which the
// ASIO SDK uses to perform all actions on the IASIO interface. We substitute
// our own forwarding interface into this pointer.
extern IASIO* theAsioDriver;
// The following macros define the inline assembler for BORLAND first then gcc
#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)
#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\
void *this_ = (thisPtr); \
__asm { \
mov ecx, this_ ; \
mov eax, [ecx] ; \
call [eax+funcOffset] ; \
mov resultName, eax ; \
}
#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\
void *this_ = (thisPtr); \
__asm { \
mov eax, param1 ; \
push eax ; \
mov ecx, this_ ; \
mov eax, [ecx] ; \
call [eax+funcOffset] ; \
}
#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\
void *this_ = (thisPtr); \
__asm { \
mov eax, param1 ; \
push eax ; \
mov ecx, this_ ; \
mov eax, [ecx] ; \
call [eax+funcOffset] ; \
mov resultName, eax ; \
}
#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\
void *this_ = (thisPtr); \
void *doubleParamPtr_ (&param1); \
__asm { \
mov eax, doubleParamPtr_ ; \
push [eax+4] ; \
push [eax] ; \
mov ecx, this_ ; \
mov eax, [ecx] ; \
call [eax+funcOffset] ; \
mov resultName, eax ; \
}
#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\
void *this_ = (thisPtr); \
__asm { \
mov eax, param2 ; \
push eax ; \
mov eax, param1 ; \
push eax ; \
mov ecx, this_ ; \
mov eax, [ecx] ; \
call [eax+funcOffset] ; \
mov resultName, eax ; \
}
#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
void *this_ = (thisPtr); \
__asm { \
mov eax, param4 ; \
push eax ; \
mov eax, param3 ; \
push eax ; \
mov eax, param2 ; \
push eax ; \
mov eax, param1 ; \
push eax ; \
mov ecx, this_ ; \
mov eax, [ecx] ; \
call [eax+funcOffset] ; \
mov resultName, eax ; \
}
#elif defined(__GNUC__)
#define CALL_THISCALL_0( resultName, thisPtr, funcOffset ) \
__asm__ __volatile__ ("movl (%1), %%edx\n\t" \
"call *"#funcOffset"(%%edx)\n\t" \
:"=a"(resultName) /* Output Operands */ \
:"c"(thisPtr) /* Input Operands */ \
: "%edx" /* Clobbered Registers */ \
); \
#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 ) \
__asm__ __volatile__ ("pushl %0\n\t" \
"movl (%1), %%edx\n\t" \
"call *"#funcOffset"(%%edx)\n\t" \
: /* Output Operands */ \
:"r"(param1), /* Input Operands */ \
"c"(thisPtr) \
: "%edx" /* Clobbered Registers */ \
); \
#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 ) \
__asm__ __volatile__ ("pushl %1\n\t" \
"movl (%2), %%edx\n\t" \
"call *"#funcOffset"(%%edx)\n\t" \
:"=a"(resultName) /* Output Operands */ \
:"r"(param1), /* Input Operands */ \
"c"(thisPtr) \
: "%edx" /* Clobbered Registers */ \
); \
#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 ) \
do { \
double param1f64 = param1; /* Cast explicitly to double */ \
double *param1f64Ptr = &param1f64; /* Make pointer to address */ \
__asm__ __volatile__ ("pushl 4(%1)\n\t" \
"pushl (%1)\n\t" \
"movl (%2), %%edx\n\t" \
"call *"#funcOffset"(%%edx);\n\t" \
: "=a"(resultName) /* Output Operands */ \
: "r"(param1f64Ptr), /* Input Operands */ \
"c"(thisPtr), \
"m"(*param1f64Ptr) /* Using address */ \
: "%edx" /* Clobbered Registers */ \
); \
} while (0); \
#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 ) \
__asm__ __volatile__ ("pushl %1\n\t" \
"pushl %2\n\t" \
"movl (%3), %%edx\n\t" \
"call *"#funcOffset"(%%edx)\n\t" \
:"=a"(resultName) /* Output Operands */ \
:"r"(param2), /* Input Operands */ \
"r"(param1), \
"c"(thisPtr) \
: "%edx" /* Clobbered Registers */ \
); \
#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
__asm__ __volatile__ ("pushl %1\n\t" \
"pushl %2\n\t" \
"pushl %3\n\t" \
"pushl %4\n\t" \
"movl (%5), %%edx\n\t" \
"call *"#funcOffset"(%%edx)\n\t" \
:"=a"(resultName) /* Output Operands */ \
:"r"(param4), /* Input Operands */ \
"r"(param3), \
"r"(param2), \
"r"(param1), \
"c"(thisPtr) \
: "%edx" /* Clobbered Registers */ \
); \
#endif
// Our static singleton instance.
IASIOThiscallResolver IASIOThiscallResolver::instance;
// Constructor called to initialize static Singleton instance above. Note that
// it is important not to clear that_ incase it has already been set by the call
// to placement new in ASIOInit().
IASIOThiscallResolver::IASIOThiscallResolver()
{
}
// Constructor called from ASIOInit() below
IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that)
: that_( that )
{
}
// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not
// really a COM object, just a wrapper which will work with the ASIO SDK.
// If you wanted to use ASIO without the SDK you might want to implement COM
// aggregation in these methods.
HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv)
{
(void)riid; // suppress unused variable warning
assert( false ); // this function should never be called by the ASIO SDK.
*ppv = NULL;
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef()
{
assert( false ); // this function should never be called by the ASIO SDK.
return 1;
}
ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release()
{
assert( false ); // this function should never be called by the ASIO SDK.
return 1;
}
// Implement the IASIO interface methods by performing the vptr manipulation
// described above then delegating to the real implementation.
ASIOBool IASIOThiscallResolver::init(void *sysHandle)
{
ASIOBool result;
CALL_THISCALL_1( result, that_, 12, sysHandle );
return result;
}
void IASIOThiscallResolver::getDriverName(char *name)
{
CALL_VOID_THISCALL_1( that_, 16, name );
}
long IASIOThiscallResolver::getDriverVersion()
{
ASIOBool result;
CALL_THISCALL_0( result, that_, 20 );
return result;
}
void IASIOThiscallResolver::getErrorMessage(char *string)
{
CALL_VOID_THISCALL_1( that_, 24, string );
}
ASIOError IASIOThiscallResolver::start()
{
ASIOBool result;
CALL_THISCALL_0( result, that_, 28 );
return result;
}
ASIOError IASIOThiscallResolver::stop()
{
ASIOBool result;
CALL_THISCALL_0( result, that_, 32 );
return result;
}
ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels)
{
ASIOBool result;
CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels );
return result;
}
ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency)
{
ASIOBool result;
CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency );
return result;
}
ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize,
long *preferredSize, long *granularity)
{
ASIOBool result;
CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity );
return result;
}
ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate)
{
ASIOBool result;
CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate );
return result;
}
ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate)
{
ASIOBool result;
CALL_THISCALL_1( result, that_, 52, sampleRate );
return result;
}
ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate)
{
ASIOBool result;
CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate );
return result;
}
ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources)
{
ASIOBool result;
CALL_THISCALL_2( result, that_, 60, clocks, numSources );
return result;
}
ASIOError IASIOThiscallResolver::setClockSource(long reference)
{
ASIOBool result;
CALL_THISCALL_1( result, that_, 64, reference );
return result;
}
ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
{
ASIOBool result;
CALL_THISCALL_2( result, that_, 68, sPos, tStamp );
return result;
}
ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info)
{
ASIOBool result;
CALL_THISCALL_1( result, that_, 72, info );
return result;
}
ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos,
long numChannels, long bufferSize, ASIOCallbacks *callbacks)
{
ASIOBool result;
CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks );
return result;
}
ASIOError IASIOThiscallResolver::disposeBuffers()
{
ASIOBool result;
CALL_THISCALL_0( result, that_, 80 );
return result;
}
ASIOError IASIOThiscallResolver::controlPanel()
{
ASIOBool result;
CALL_THISCALL_0( result, that_, 84 );
return result;
}
ASIOError IASIOThiscallResolver::future(long selector,void *opt)
{
ASIOBool result;
CALL_THISCALL_2( result, that_, 88, selector, opt );
return result;
}
ASIOError IASIOThiscallResolver::outputReady()
{
ASIOBool result;
CALL_THISCALL_0( result, that_, 92 );
return result;
}
// Implement our substitute ASIOInit() method
ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info)
{
// To ensure that our instance's vptr is correctly constructed, even if
// ASIOInit is called prior to main(), we explicitly call its constructor
// (potentially over the top of an existing instance). Note that this is
// pretty ugly, and is only safe because IASIOThiscallResolver has no
// destructor and contains no objects with destructors.
new((void*)&instance) IASIOThiscallResolver( theAsioDriver );
// Interpose between ASIO client code and the real driver.
theAsioDriver = &instance;
// Note that we never need to switch theAsioDriver back to point to the
// real driver because theAsioDriver is reset to zero in ASIOExit().
// Delegate to the real ASIOInit
return ::ASIOInit(info);
}
#endif /* !defined(_MSC_VER) */
#endif /* Win32 */

View File

@ -1,197 +0,0 @@
// ****************************************************************************
// File: IASIOThiscallResolver.h
// Description: The IASIOThiscallResolver class implements the IASIO
// interface and acts as a proxy to the real IASIO interface by
// calling through its vptr table using the thiscall calling
// convention. To put it another way, we interpose
// IASIOThiscallResolver between ASIO SDK code and the driver.
// This is necessary because most non-Microsoft compilers don't
// implement the thiscall calling convention used by IASIO.
//
// iasiothiscallresolver.cpp contains the background of this
// problem plus a technical description of the vptr
// manipulations.
//
// In order to use this mechanism one simply has to add
// iasiothiscallresolver.cpp to the list of files to compile
// and #include <iasiothiscallresolver.h>
//
// Note that this #include must come after the other ASIO SDK
// #includes, for example:
//
// #include <windows.h>
// #include <asiosys.h>
// #include <asio.h>
// #include <asiodrivers.h>
// #include <iasiothiscallresolver.h>
//
// Actually the important thing is to #include
// <iasiothiscallresolver.h> after <asio.h>. We have
// incorporated a test to enforce this ordering.
//
// The code transparently takes care of the interposition by
// using macro substitution to intercept calls to ASIOInit()
// and ASIOExit(). We save the original ASIO global
// "theAsioDriver" in our "that" variable, and then set
// "theAsioDriver" to equal our IASIOThiscallResolver instance.
//
// Whilst this method of resolving the thiscall problem requires
// the addition of #include <iasiothiscallresolver.h> to client
// code it has the advantage that it does not break the terms
// of the ASIO licence by publishing it. We are NOT modifying
// any Steinberg code here, we are merely implementing the IASIO
// interface in the same way that we would need to do if we
// wished to provide an open source ASIO driver.
//
// For compilation with MinGW -lole32 needs to be added to the
// linker options. For BORLAND, linking with Import32.lib is
// sufficient.
//
// The dependencies are with: CoInitialize, CoUninitialize,
// CoCreateInstance, CLSIDFromString - used by asiolist.cpp
// and are required on Windows whether ThiscallResolver is used
// or not.
//
// Searching for the above strings in the root library path
// of your compiler should enable the correct libraries to be
// identified if they aren't immediately obvious.
//
// Note that the current implementation of IASIOThiscallResolver
// is not COM compliant - it does not correctly implement the
// IUnknown interface. Implementing it is not necessary because
// it is not called by parts of the ASIO SDK which call through
// theAsioDriver ptr. The IUnknown methods are implemented as
// assert(false) to ensure that the code fails if they are
// ever called.
// Restrictions: None. Public Domain & Open Source distribute freely
// You may use IASIOThiscallResolver commercially as well as
// privately.
// You the user assume the responsibility for the use of the
// files, binary or text, and there is no guarantee or warranty,
// expressed or implied, including but not limited to the
// implied warranties of merchantability and fitness for a
// particular purpose. You assume all responsibility and agree
// to hold no entity, copyright holder or distributors liable
// for any loss of data or inaccurate representations of data
// as a result of using IASIOThiscallResolver.
// Version: 1.4 Added separate macro CALL_THISCALL_1_DOUBLE from
// Andrew Baldwin, and volatile for whole gcc asm blocks,
// both for compatibility with newer gcc versions. Cleaned up
// Borland asm to use one less register.
// 1.3 Switched to including assert.h for better compatibility.
// Wrapped entire .h and .cpp contents with a check for
// _MSC_VER to provide better compatibility with MS compilers.
// Changed Singleton implementation to use static instance
// instead of freestore allocated instance. Removed ASIOExit
// macro as it is no longer needed.
// 1.2 Removed semicolons from ASIOInit and ASIOExit macros to
// allow them to be embedded in expressions (if statements).
// Cleaned up some comments. Removed combase.c dependency (it
// doesn't compile with BCB anyway) by stubbing IUnknown.
// 1.1 Incorporated comments from Ross Bencina including things
// such as changing name from ThiscallResolver to
// IASIOThiscallResolver, tidying up the constructor, fixing
// a bug in IASIOThiscallResolver::ASIOExit() and improving
// portability through the use of conditional compilation
// 1.0 Initial working version.
// Created: 6/09/2003
// Authors: Fraser Adams
// Ross Bencina
// Rene G. Ceballos
// Martin Fay
// Antti Silvast
// Andrew Baldwin
//
// ****************************************************************************
#ifndef included_iasiothiscallresolver_h
#define included_iasiothiscallresolver_h
// We only need IASIOThiscallResolver at all if we are on Win32. For other
// platforms we simply bypass the IASIOThiscallResolver definition to allow us
// to be safely #include'd whatever the platform to keep client code portable
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64)
// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
// is not used.
#if !defined(_MSC_VER)
// The following is in order to ensure that this header is only included after
// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).
// We need to do this because IASIOThiscallResolver works by eclipsing the
// original definition of ASIOInit() with a macro (see below).
#if !defined(iasiothiscallresolver_sourcefile)
#if !defined(__ASIO_H)
#error iasiothiscallresolver.h must be included AFTER asio.h
#endif
#endif
#include <windows.h>
#include <asiodrvr.h> /* From ASIO SDK */
class IASIOThiscallResolver : public IASIO {
private:
IASIO* that_; // Points to the real IASIO
static IASIOThiscallResolver instance; // Singleton instance
// Constructors - declared private so construction is limited to
// our Singleton instance
IASIOThiscallResolver();
IASIOThiscallResolver(IASIO* that);
public:
// Methods from the IUnknown interface. We don't fully implement IUnknown
// because the ASIO SDK never calls these methods through theAsioDriver ptr.
// These methods are implemented as assert(false).
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
// Methods from the IASIO interface, implemented as forwarning calls to that.
virtual ASIOBool init(void *sysHandle);
virtual void getDriverName(char *name);
virtual long getDriverVersion();
virtual void getErrorMessage(char *string);
virtual ASIOError start();
virtual ASIOError stop();
virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);
virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);
virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);
virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);
virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);
virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);
virtual ASIOError setClockSource(long reference);
virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);
virtual ASIOError getChannelInfo(ASIOChannelInfo *info);
virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);
virtual ASIOError disposeBuffers();
virtual ASIOError controlPanel();
virtual ASIOError future(long selector,void *opt);
virtual ASIOError outputReady();
// Class method, see ASIOInit() macro below.
static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit
};
// Replace calls to ASIOInit with our interposing version.
// This macro enables us to perform thiscall resolution simply by #including
// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be
// included _after_ the asio #includes)
#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))
#endif /* !defined(_MSC_VER) */
#endif /* Win32 */
#endif /* included_iasiothiscallresolver_h */

File diff suppressed because it is too large Load Diff

View File

@ -1,196 +0,0 @@
Notes on status of CoreAudio Implementation of PortAudio
Document Last Updated December 9, 2005
There are currently two implementations of PortAudio for Mac Core Audio.
The original is in pa_mac_core_old.c, and the newer, default implementation
is in pa_mac_core.c.
Only pa_mac_core.c is currently developed and supported as it uses apple's
current core audio technology. To select use the old implementation, replace
pa_mac_core.c with pa_mac_core_old.c (eg. "cp pa_mac_core_auhal.c
pa_mac_core.c"), then run configure and make as usual.
-------------------------------------------
Notes on Newer/Default AUHAL implementation:
by Bjorn Roche
Last Updated December 9, 2005
Principle of Operation:
This implementation uses AUHAL for audio I/O. To some extent, it also
operates at the "HAL" Layer, though this behavior can be limited by
platform specific flags (see pa_mac_core.h for details). The default
settings should be reasonable: they don't change the SR of the device and
don't cause interruptions if other devices are using the device.
Major Software Elements Used: Apple's HAL AUs provide output SR
conversion transparently, however, only on output, so this
implementation uses AudioConverters to convert the sample rate on input.
A PortAudio ring buffer is used to buffer input when sample rate
conversion is required or when separate audio units are used for duplex
IO. Finally, a PortAudio buffer processor is used to convert formats and
provide additional buffers if needed. Internally, interleaved floating
point data streams are used exclusively - the audio unit converts from
the audio hardware's native format to interleaved float PCM and
PortAudio's Buffer processor is used for conversion to user formats.
Simplex Input: Simplex input uses a single callback. If sample rate
conversion is required, a ring buffer and AudioConverter are used as
well.
Simplex output: Simplex output uses a single callback. No ring buffer or
audio converter is used because AUHAL does its own output SR conversion.
Duplex, one device (no SR conversion): When one device is used, a single
callback is used. This achieves very low latency.
Duplex, separate devices or SR conversion: When SR conversion is
required, data must be buffered before it is converted and data is not
always available at the same times on input and output, so SR conversion
requires the same treatment as separate devices. The input callback
reads data and puts it in the ring buffer. The output callback reads the
data off the ring buffer, into an audio converter and finally to the
buffer processor.
Platform Specific Options:
By using the flags in pa_mac_core.h, the user may specify several options.
For example, the user can specify the sample-rate conversion quality, and
the extent to which PA will attempt to "play nice" and to what extent it
will interrupt other apps to improve performance. For example, if 44100 Hz
sample rate is requested but the device is set at 48000 Hz, PA can either
change the device for optimal playback ("Pro" mode), which may interrupt
other programs playing back audio, or simple use a sample-rate coversion,
which allows for friendlier sharing of the device ("Play Nice" mode).
Additionally, the user may define a "channel mapping" by calling
paSetupMacCoreChannelMap() on their stream info structure before opening
the stream with it. See below for creating a channel map.
Known issues:
- Buffering: No buffering beyond that provided by core audio is provided
except where absolutely needed for the implementation to work. This may cause
issues with large framesPerBuffer settings and it also means that no additional
latency will be provided even if a large latency setting is selected.
- Latency: Latency settings are generally ignored. They may be used as a
hint for buffer size in paHostFramesPerBufferUnspecified, or the value may
be used in cases where additional buffering is needed, such as doing input and
output on seperate devices. Latency settings are always automatically bound
to "safe" values, however, so setting extreme values here should not be
an issue.
- Buffer Size: paHostFramesPerBufferUnspecified and specific host buffer sizes
are supported. paHostFramesPerBufferUnspecified works best in "pro" mode,
where the buffer size and sample rate of the audio device is most likely
to match the expected values. In the case of paHostFramesPerBuffer, an
appropriate framesPerBuffer value will be used that guarantees minimum
requested latency if that's possible.
- Timing info. It reports on stream time, but I'm probably doing something
wrong since patest_sine_time often reports negative latency numbers. Also,
there are currently issues with some devices whehn plugging/unplugging
devices.
- xrun detection: The only xrun detection performed is when reading
and writing the ring buffer. There is probably more that can be done.
- abort/stop issues: stopping a stream is always a complete operation,
but latency should be low enough to make the lack of a separate abort
unnecessary. Apple clarifies its AudioOutputUnitStop() call here:
http://lists.apple.com/archives/coreaudio-api/2005/Dec/msg00055.html
- blocking interface: should work fine.
- multichannel: It has been tested successfully on multichannel hardware
from MOTU: traveler and 896HD. Also Presonus firepod and others. It is
believed to work with all Core Audio devices, including virtual devices
such as soundflower.
- sample rate conversion quality: By default, SR conversion is the maximum
available. This can be tweaked using flags pa_mac_core.h. Note that the AU
render quyality property is used to set the sample rate conversion quality
as "documented" here:
http://lists.apple.com/archives/coreaudio-api/2004/Jan/msg00141.html
- x86/Universal Binary: Universal binaries can be build.
Creating a channel map:
How to create the map array - Text taken From AUHAL.rtfd :
[3] Channel Maps
Clients can tell the AUHAL units which channels of the device they are interested in. For example, the client may be processing stereo data, but outputting to a six-channel device. This is done by using the kAudioOutputUnitProperty_ChannelMap property. To use this property:
For Output:
Create an array of SInt32 that is the size of the number of channels of the device (Get the Format of the AUHAL's output Element == 0)
Initialize each of the array's values to -1 (-1 indicates that that channel is NOT to be presented in the conversion.)
Next, for each channel of your app's output, set:
channelMapArray[deviceOutputChannel] = desiredAppOutputChannel.
For example: we have a 6 channel output device and our application has a stereo source it wants to provide to the device. Suppose we want that stereo source to go to the 3rd and 4th channels of the device. The channel map would look like this: { -1, -1, 0, 1, -1, -1 }
Where the formats are:
Input Element == 0: 2 channels (- client format - settable)
Output Element == 0: 6 channels (- device format - NOT settable)
So channel 2 (zero-based) of the device will take the first channel of output and channel 3 will take the second channel of output. (This translates to the 3rd and 4th plugs of the 6 output plugs of the device of course!)
For Input:
Create an array of SInt32 that is the size of the number of channels of the format you require for input. Get (or Set in this case as needed) the AUHAL's output Element == 1.
Next, for each channel of input you require, set:
channelMapArray[desiredAppInputChannel] = deviceOutputChannel;
For example: we have a 6 channel input device from which we wish to receive stereo input from the 3rd and 4th channels. The channel map looks like this: { 2, 3 }
Where the formats are:
Input Element == 0: 2 channels (- device format - NOT settable)
Output Element == 0: 6 channels (- client format - settable)
----------------------------------------
Notes on Original implementation:
by Phil Burk and Darren Gibbs
Last updated March 20, 2002
WHAT WORKS
Output with very low latency, <10 msec.
Half duplex input or output.
Full duplex on the same CoreAudio device.
The paFLoat32, paInt16, paInt8, paUInt8 sample formats.
Pa_GetCPULoad()
Pa_StreamTime()
KNOWN BUGS OR LIMITATIONS
We do not yet support simultaneous input and output on different
devices. Note that some CoreAudio devices like the Roland UH30 look
like one device but are actually two different CoreAudio devices. The
Built-In audio is typically one CoreAudio device.
Mono doesn't work.
DEVICE MAPPING
CoreAudio devices can support both input and output. But the sample
rates supported may be different. So we have map one or two PortAudio
device to each CoreAudio device depending on whether it supports
input, output or both.
When we query devices, we first get a list of CoreAudio devices. Then
we scan the list and add a PortAudio device for each CoreAudio device
that supports input. Then we make a scan for output devices.

File diff suppressed because it is too large Load Diff

View File

@ -1,637 +0,0 @@
/*
* Implementation of the PortAudio API for Apple AUHAL
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
* Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
*
* Dominic's code was based on code by Phil Burk, Darren Gibbs,
* Gord Peters, Stephane Letz, and Greg Pfiel.
*
* The following people also deserve acknowledgements:
*
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 hostapi_src
This file contains the implementation
required for blocking I/O. It is separated from pa_mac_core.c simply to ease
development.
*/
#include "pa_mac_core_blocking.h"
#include "pa_mac_core_internal.h"
#include <assert.h>
#ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS
# define OSAtomicOr32( a, b ) ( (*(b)) |= (a) )
# define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) )
#else
# include <libkern/OSAtomic.h>
#endif
/*
* This function determines the size of a particular sample format.
* if the format is not recognized, this returns zero.
*/
static size_t computeSampleSizeFromFormat( PaSampleFormat format )
{
switch( format & (~paNonInterleaved) ) {
case paFloat32: return 4;
case paInt32: return 4;
case paInt24: return 3;
case paInt16: return 2;
case paInt8: case paUInt8: return 1;
default: return 0;
}
}
/*
* Same as computeSampleSizeFromFormat, except that if
* the size is not a power of two, it returns the next power of two up
*/
static size_t computeSampleSizeFromFormatPow2( PaSampleFormat format )
{
switch( format & (~paNonInterleaved) ) {
case paFloat32: return 4;
case paInt32: return 4;
case paInt24: return 4;
case paInt16: return 2;
case paInt8: case paUInt8: return 1;
default: return 0;
}
}
/*
* Functions for initializing, resetting, and destroying BLIO structures.
*
*/
/**
* This should be called with the relevant info when initializing a stream for callback.
*
* @param ringBufferSizeInFrames must be a power of 2
*/
PaError initializeBlioRingBuffers(
PaMacBlio *blio,
PaSampleFormat inputSampleFormat,
PaSampleFormat outputSampleFormat,
long ringBufferSizeInFrames,
int inChan,
int outChan )
{
void *data;
int result;
OSStatus err;
/* zeroify things */
bzero( blio, sizeof( PaMacBlio ) );
/* this is redundant, but the buffers are used to check
if the buffers have been initialized, so we do it explicitly. */
blio->inputRingBuffer.buffer = NULL;
blio->outputRingBuffer.buffer = NULL;
/* initialize simple data */
blio->ringBufferFrames = ringBufferSizeInFrames;
blio->inputSampleFormat = inputSampleFormat;
blio->inputSampleSizeActual = computeSampleSizeFromFormat(inputSampleFormat);
blio->inputSampleSizePow2 = computeSampleSizeFromFormatPow2(inputSampleFormat); // FIXME: WHY?
blio->outputSampleFormat = outputSampleFormat;
blio->outputSampleSizeActual = computeSampleSizeFromFormat(outputSampleFormat);
blio->outputSampleSizePow2 = computeSampleSizeFromFormatPow2(outputSampleFormat);
blio->inChan = inChan;
blio->outChan = outChan;
blio->statusFlags = 0;
blio->errors = paNoError;
#ifdef PA_MAC_BLIO_MUTEX
blio->isInputEmpty = false;
blio->isOutputFull = false;
#endif
/* setup ring buffers */
#ifdef PA_MAC_BLIO_MUTEX
result = PaMacCore_SetUnixError( pthread_mutex_init(&(blio->inputMutex),NULL), 0 );
if( result )
goto error;
result = UNIX_ERR( pthread_cond_init( &(blio->inputCond), NULL ) );
if( result )
goto error;
result = UNIX_ERR( pthread_mutex_init(&(blio->outputMutex),NULL) );
if( result )
goto error;
result = UNIX_ERR( pthread_cond_init( &(blio->outputCond), NULL ) );
#endif
if( inChan ) {
data = calloc( ringBufferSizeInFrames, blio->inputSampleSizePow2 * inChan );
if( !data )
{
result = paInsufficientMemory;
goto error;
}
err = PaUtil_InitializeRingBuffer(
&blio->inputRingBuffer,
blio->inputSampleSizePow2 * inChan,
ringBufferSizeInFrames,
data );
assert( !err );
}
if( outChan ) {
data = calloc( ringBufferSizeInFrames, blio->outputSampleSizePow2 * outChan );
if( !data )
{
result = paInsufficientMemory;
goto error;
}
err = PaUtil_InitializeRingBuffer(
&blio->outputRingBuffer,
blio->outputSampleSizePow2 * outChan,
ringBufferSizeInFrames,
data );
assert( !err );
}
result = resetBlioRingBuffers( blio );
if( result )
goto error;
return 0;
error:
destroyBlioRingBuffers( blio );
return result;
}
#ifdef PA_MAC_BLIO_MUTEX
PaError blioSetIsInputEmpty( PaMacBlio *blio, bool isEmpty )
{
PaError result = paNoError;
if( isEmpty == blio->isInputEmpty )
goto done;
/* we need to update the value. Here's what we do:
* - Lock the mutex, so noone else can write.
* - update the value.
* - unlock.
* - broadcast to all listeners.
*/
result = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
if( result )
goto done;
blio->isInputEmpty = isEmpty;
result = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
if( result )
goto done;
result = UNIX_ERR( pthread_cond_broadcast( &blio->inputCond ) );
if( result )
goto done;
done:
return result;
}
PaError blioSetIsOutputFull( PaMacBlio *blio, bool isFull )
{
PaError result = paNoError;
if( isFull == blio->isOutputFull )
goto done;
/* we need to update the value. Here's what we do:
* - Lock the mutex, so noone else can write.
* - update the value.
* - unlock.
* - broadcast to all listeners.
*/
result = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
if( result )
goto done;
blio->isOutputFull = isFull;
result = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
if( result )
goto done;
result = UNIX_ERR( pthread_cond_broadcast( &blio->outputCond ) );
if( result )
goto done;
done:
return result;
}
#endif
/* This should be called after stopping or aborting the stream, so that on next
start, the buffers will be ready. */
PaError resetBlioRingBuffers( PaMacBlio *blio )
{
#ifdef PA_MAC__BLIO_MUTEX
int result;
#endif
blio->statusFlags = 0;
if( blio->outputRingBuffer.buffer ) {
PaUtil_FlushRingBuffer( &blio->outputRingBuffer );
/* Fill the buffer with zeros. */
bzero( blio->outputRingBuffer.buffer,
blio->outputRingBuffer.bufferSize * blio->outputRingBuffer.elementSizeBytes );
PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->ringBufferFrames );
/* Update isOutputFull. */
#ifdef PA_MAC__BLIO_MUTEX
result = blioSetIsOutputFull( blio, toAdvance == blio->outputRingBuffer.bufferSize );
if( result )
goto error;
#endif
/*
printf( "------%d\n" , blio->outChan );
printf( "------%d\n" , blio->outputSampleSize );
*/
}
if( blio->inputRingBuffer.buffer ) {
PaUtil_FlushRingBuffer( &blio->inputRingBuffer );
bzero( blio->inputRingBuffer.buffer,
blio->inputRingBuffer.bufferSize * blio->inputRingBuffer.elementSizeBytes );
/* Update isInputEmpty. */
#ifdef PA_MAC__BLIO_MUTEX
result = blioSetIsInputEmpty( blio, true );
if( result )
goto error;
#endif
}
return paNoError;
#ifdef PA_MAC__BLIO_MUTEX
error:
return result;
#endif
}
/*This should be called when you are done with the blio. It can safely be called
multiple times if there are no exceptions. */
PaError destroyBlioRingBuffers( PaMacBlio *blio )
{
PaError result = paNoError;
if( blio->inputRingBuffer.buffer ) {
free( blio->inputRingBuffer.buffer );
#ifdef PA_MAC__BLIO_MUTEX
result = UNIX_ERR( pthread_mutex_destroy( & blio->inputMutex ) );
if( result ) return result;
result = UNIX_ERR( pthread_cond_destroy( & blio->inputCond ) );
if( result ) return result;
#endif
}
blio->inputRingBuffer.buffer = NULL;
if( blio->outputRingBuffer.buffer ) {
free( blio->outputRingBuffer.buffer );
#ifdef PA_MAC__BLIO_MUTEX
result = UNIX_ERR( pthread_mutex_destroy( & blio->outputMutex ) );
if( result ) return result;
result = UNIX_ERR( pthread_cond_destroy( & blio->outputCond ) );
if( result ) return result;
#endif
}
blio->outputRingBuffer.buffer = NULL;
return result;
}
/*
* this is the BlioCallback function. It expects to recieve a PaMacBlio Object
* pointer as userData.
*
*/
int BlioCallback( const void *input, void *output, unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
PaMacBlio *blio = (PaMacBlio*)userData;
ring_buffer_size_t framesAvailable;
ring_buffer_size_t framesToTransfer;
ring_buffer_size_t framesTransferred;
/* set flags returned by OS: */
OSAtomicOr32( statusFlags, &blio->statusFlags ) ;
/* --- Handle Input Buffer --- */
if( blio->inChan ) {
framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->inputRingBuffer );
/* check for underflow */
if( framesAvailable < frameCount )
{
OSAtomicOr32( paInputOverflow, &blio->statusFlags );
framesToTransfer = framesAvailable;
}
else
{
framesToTransfer = (ring_buffer_size_t)frameCount;
}
/* Copy the data from the audio input to the application ring buffer. */
/*printf( "reading %d\n", toRead );*/
framesTransferred = PaUtil_WriteRingBuffer( &blio->inputRingBuffer, input, framesToTransfer );
assert( framesToTransfer == framesTransferred );
#ifdef PA_MAC__BLIO_MUTEX
/* Priority inversion. See notes below. */
blioSetIsInputEmpty( blio, false );
#endif
}
/* --- Handle Output Buffer --- */
if( blio->outChan ) {
framesAvailable = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
/* check for underflow */
if( framesAvailable < frameCount )
{
/* zero out the end of the output buffer that we do not have data for */
framesToTransfer = framesAvailable;
size_t bytesPerFrame = blio->outputSampleSizeActual * blio->outChan;
size_t offsetInBytes = framesToTransfer * bytesPerFrame;
size_t countInBytes = (frameCount - framesToTransfer) * bytesPerFrame;
bzero( ((char *)output) + offsetInBytes, countInBytes );
OSAtomicOr32( paOutputUnderflow, &blio->statusFlags );
framesToTransfer = framesAvailable;
}
else
{
framesToTransfer = (ring_buffer_size_t)frameCount;
}
/* copy the data */
/*printf( "writing %d\n", toWrite );*/
framesTransferred = PaUtil_ReadRingBuffer( &blio->outputRingBuffer, output, framesToTransfer );
assert( framesToTransfer == framesTransferred );
#ifdef PA_MAC__BLIO_MUTEX
/* We have a priority inversion here. However, we will only have to
wait if this was true and is now false, which means we've got
some room in the buffer.
Hopefully problems will be minimized. */
blioSetIsOutputFull( blio, false );
#endif
}
return paContinue;
}
PaError ReadStream( PaStream* stream,
void *buffer,
unsigned long framesRequested )
{
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
char *cbuf = (char *) buffer;
PaError ret = paNoError;
VVDBUG(("ReadStream()\n"));
while( framesRequested > 0 ) {
ring_buffer_size_t framesAvailable;
ring_buffer_size_t framesToTransfer;
ring_buffer_size_t framesTransferred;
do {
framesAvailable = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
/*
printf( "Read Buffer is %%%g full: %ld of %ld.\n",
100 * (float)avail / (float) blio->inputRingBuffer.bufferSize,
framesAvailable, blio->inputRingBuffer.bufferSize );
*/
if( framesAvailable == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
/**block when empty*/
ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
if( ret )
return ret;
while( blio->isInputEmpty ) {
ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) );
if( ret )
return ret;
}
ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
if( ret )
return ret;
#else
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
}
} while( framesAvailable == 0 );
framesToTransfer = (ring_buffer_size_t) MIN( framesAvailable, framesRequested );
framesTransferred = PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, framesToTransfer );
cbuf += framesTransferred * blio->inputSampleSizeActual * blio->inChan;
framesRequested -= framesTransferred;
if( framesToTransfer == framesAvailable ) {
#ifdef PA_MAC_BLIO_MUTEX
/* we just emptied the buffer, so we need to mark it as empty. */
ret = blioSetIsInputEmpty( blio, true );
if( ret )
return ret;
/* of course, in the meantime, the callback may have put some sats
in, so
so check for that, too, to avoid a race condition. */
/* FIXME - this does not seem to fix any race condition. */
if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) {
blioSetIsInputEmpty( blio, false );
/* FIXME - why check? ret has not been set? */
if( ret )
return ret;
}
#endif
}
}
/* Report either paNoError or paInputOverflowed. */
/* may also want to report other errors, but this is non-standard. */
/* FIXME should not clobber ret, use if(blio->statusFlags & paInputOverflow) */
ret = blio->statusFlags & paInputOverflow;
/* report underflow only once: */
if( ret ) {
OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags );
ret = paInputOverflowed;
}
return ret;
}
PaError WriteStream( PaStream* stream,
const void *buffer,
unsigned long framesRequested )
{
PaMacCoreStream *macStream = (PaMacCoreStream*)stream;
PaMacBlio *blio = &macStream->blio;
char *cbuf = (char *) buffer;
PaError ret = paNoError;
VVDBUG(("WriteStream()\n"));
while( framesRequested > 0 && macStream->state != STOPPING ) {
ring_buffer_size_t framesAvailable;
ring_buffer_size_t framesToTransfer;
ring_buffer_size_t framesTransferred;
do {
framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
/*
printf( "Write Buffer is %%%g full: %ld of %ld.\n",
100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
framesAvailable, blio->outputRingBuffer.bufferSize );
*/
if( framesAvailable == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
/*block while full*/
ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
if( ret )
return ret;
while( blio->isOutputFull ) {
ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) );
if( ret )
return ret;
}
ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
if( ret )
return ret;
#else
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
}
} while( framesAvailable == 0 && macStream->state != STOPPING );
if( macStream->state == STOPPING )
{
break;
}
framesToTransfer = MIN( framesAvailable, framesRequested );
framesTransferred = PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, framesToTransfer );
cbuf += framesTransferred * blio->outputSampleSizeActual * blio->outChan;
framesRequested -= framesTransferred;
#ifdef PA_MAC_BLIO_MUTEX
if( framesToTransfer == framesAvailable ) {
/* we just filled up the buffer, so we need to mark it as filled. */
ret = blioSetIsOutputFull( blio, true );
if( ret )
return ret;
/* of course, in the meantime, we may have emptied the buffer, so
so check for that, too, to avoid a race condition. */
if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) {
blioSetIsOutputFull( blio, false );
/* FIXME remove or review this code, does not fix race, ret not set! */
if( ret )
return ret;
}
}
#endif
}
if ( macStream->state == STOPPING )
{
ret = paInternalError;
}
else if (ret == paNoError )
{
/* Test for underflow. */
ret = blio->statusFlags & paOutputUnderflow;
/* report underflow only once: */
if( ret )
{
OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags );
ret = paOutputUnderflowed;
}
}
return ret;
}
/*
* Wait until the data in the buffer has finished playing.
*/
PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate,
size_t framesPerBuffer )
{
PaError result = paNoError;
if( blio->outputRingBuffer.buffer ) {
ring_buffer_size_t framesLeft = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
/* Calculate when we should give up waiting. To be safe wait for two extra periods. */
PaTime now = PaUtil_GetTime();
PaTime startTime = now;
PaTime timeoutTime = startTime + (framesLeft + (2 * framesPerBuffer)) / sampleRate;
long msecPerBuffer = 1 + (long)( 1000.0 * framesPerBuffer / sampleRate);
while( framesLeft > 0 && now < timeoutTime ) {
VDBUG(( "waitUntilBlioWriteBufferIsFlushed: framesLeft = %d, framesPerBuffer = %ld\n",
framesLeft, framesPerBuffer ));
Pa_Sleep( msecPerBuffer );
framesLeft = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
now = PaUtil_GetTime();
}
if( framesLeft > 0 )
{
VDBUG(( "waitUntilBlioWriteBufferIsFlushed: TIMED OUT - framesLeft = %d\n", framesLeft ));
result = paTimedOut;
}
}
return result;
}
signed long GetStreamReadAvailable( PaStream* stream )
{
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
VVDBUG(("GetStreamReadAvailable()\n"));
return PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
}
signed long GetStreamWriteAvailable( PaStream* stream )
{
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
VVDBUG(("GetStreamWriteAvailable()\n"));
return PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
}

View File

@ -1,134 +0,0 @@
/*
* Internal blocking interfaces for PortAudio Apple AUHAL implementation
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
* Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
*
* Dominic's code was based on code by Phil Burk, Darren Gibbs,
* Gord Peters, Stephane Letz, and Greg Pfiel.
*
* The following people also deserve acknowledgements:
*
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 hostapi_src
*/
#ifndef PA_MAC_CORE_BLOCKING_H_
#define PA_MAC_CORE_BLOCKING_H_
#include "pa_ringbuffer.h"
#include "portaudio.h"
#include "pa_mac_core_utilities.h"
/*
* Number of milliseconds to busy wait while waiting for data in blocking calls.
*/
#define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5)
/*
* Define exactly one of these blocking methods
* PA_MAC_BLIO_MUTEX is not actively maintained.
*/
#define PA_MAC_BLIO_BUSY_WAIT
/*
#define PA_MAC_BLIO_MUTEX
*/
typedef struct {
PaUtilRingBuffer inputRingBuffer;
PaUtilRingBuffer outputRingBuffer;
ring_buffer_size_t ringBufferFrames;
PaSampleFormat inputSampleFormat;
size_t inputSampleSizeActual;
size_t inputSampleSizePow2;
PaSampleFormat outputSampleFormat;
size_t outputSampleSizeActual;
size_t outputSampleSizePow2;
int inChan;
int outChan;
//PaStreamCallbackFlags statusFlags;
uint32_t statusFlags;
PaError errors;
/* Here we handle blocking, using condition variables. */
#ifdef PA_MAC_BLIO_MUTEX
volatile bool isInputEmpty;
pthread_mutex_t inputMutex;
pthread_cond_t inputCond;
volatile bool isOutputFull;
pthread_mutex_t outputMutex;
pthread_cond_t outputCond;
#endif
}
PaMacBlio;
/*
* These functions operate on condition and related variables.
*/
PaError initializeBlioRingBuffers(
PaMacBlio *blio,
PaSampleFormat inputSampleFormat,
PaSampleFormat outputSampleFormat,
long ringBufferSizeInFrames,
int inChan,
int outChan );
PaError destroyBlioRingBuffers( PaMacBlio *blio );
PaError resetBlioRingBuffers( PaMacBlio *blio );
int BlioCallback(
const void *input, void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );
PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate,
size_t framesPerBuffer );
#endif /*PA_MAC_CORE_BLOCKING_H_*/

View File

@ -1,194 +0,0 @@
/*
* Internal interfaces for PortAudio Apple AUHAL implementation
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
* Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
*
* Dominic's code was based on code by Phil Burk, Darren Gibbs,
* Gord Peters, Stephane Letz, and Greg Pfiel.
*
* The following people also deserve acknowledgements:
*
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 pa_mac_core
@ingroup hostapi_src
@author Bjorn Roche
@brief AUHAL implementation of PortAudio
*/
#ifndef PA_MAC_CORE_INTERNAL_H__
#define PA_MAC_CORE_INTERNAL_H__
#include <CoreAudio/CoreAudio.h>
#include <CoreServices/CoreServices.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#include "portaudio.h"
#include "pa_util.h"
#include "pa_hostapi.h"
#include "pa_stream.h"
#include "pa_allocation.h"
#include "pa_cpuload.h"
#include "pa_process.h"
#include "pa_ringbuffer.h"
#include "pa_mac_core_blocking.h"
/* function prototypes */
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#define RING_BUFFER_ADVANCE_DENOMINATOR (4)
PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
signed long GetStreamReadAvailable( PaStream* stream );
signed long GetStreamWriteAvailable( PaStream* stream );
/* PaMacAUHAL - host api datastructure specific to this implementation */
typedef struct
{
PaUtilHostApiRepresentation inheritedHostApiRep;
PaUtilStreamInterface callbackStreamInterface;
PaUtilStreamInterface blockingStreamInterface;
PaUtilAllocationGroup *allocations;
/* implementation specific data goes here */
long devCount;
AudioDeviceID *devIds; /*array of all audio devices*/
AudioDeviceID defaultIn;
AudioDeviceID defaultOut;
}
PaMacAUHAL;
typedef struct PaMacCoreDeviceProperties
{
/* Values in Frames from property queries. */
UInt32 safetyOffset;
UInt32 bufferFrameSize;
// UInt32 streamLatency; // Seems to be the same as deviceLatency!?
UInt32 deviceLatency;
/* Current device sample rate. May change!
These are initialized to the nominal device sample rate,
and updated with the actual sample rate, when/where available.
Note that these are the *device* sample rates, prior to any required
SR conversion. */
Float64 sampleRate;
Float64 samplePeriod; // reciprocal
}
PaMacCoreDeviceProperties;
/* stream data structure specifically for this implementation */
typedef struct PaMacCoreStream
{
PaUtilStreamRepresentation streamRepresentation;
PaUtilCpuLoadMeasurer cpuLoadMeasurer;
PaUtilBufferProcessor bufferProcessor;
/* implementation specific data goes here */
bool bufferProcessorIsInitialized;
AudioUnit inputUnit;
AudioUnit outputUnit;
AudioDeviceID inputDevice;
AudioDeviceID outputDevice;
size_t userInChan;
size_t userOutChan;
size_t inputFramesPerBuffer;
size_t outputFramesPerBuffer;
PaMacBlio blio;
/* We use this ring buffer when input and out devs are different. */
PaUtilRingBuffer inputRingBuffer;
/* We may need to do SR conversion on input. */
AudioConverterRef inputSRConverter;
/* We need to preallocate an inputBuffer for reading data. */
AudioBufferList inputAudioBufferList;
AudioTimeStamp startTime;
/* FIXME: instead of volatile, these should be properly memory barriered */
volatile uint32_t xrunFlags; /*PaStreamCallbackFlags*/
volatile enum {
STOPPED = 0, /* playback is completely stopped,
and the user has called StopStream(). */
CALLBACK_STOPPED = 1, /* callback has requested stop,
but user has not yet called StopStream(). */
STOPPING = 2, /* The stream is in the process of closing
because the user has called StopStream.
This state is just used internally;
externally it is indistinguishable from
ACTIVE.*/
ACTIVE = 3 /* The stream is active and running. */
} state;
double sampleRate;
PaMacCoreDeviceProperties inputProperties;
PaMacCoreDeviceProperties outputProperties;
/* data updated by main thread and notifications, protected by timingInformationMutex */
int timingInformationMutexIsInitialized;
pthread_mutex_t timingInformationMutex;
/* These are written by the PA thread or from CoreAudio callbacks. Protected by the mutex. */
Float64 timestampOffsetCombined;
Float64 timestampOffsetInputDevice;
Float64 timestampOffsetOutputDevice;
/* Offsets in seconds to be applied to Apple timestamps to convert them to PA timestamps.
* While the io proc is active, the following values are only accessed and manipulated by the ioproc */
Float64 timestampOffsetCombined_ioProcCopy;
Float64 timestampOffsetInputDevice_ioProcCopy;
Float64 timestampOffsetOutputDevice_ioProcCopy;
}
PaMacCoreStream;
#endif /* PA_MAC_CORE_INTERNAL_H__ */

View File

@ -1,913 +0,0 @@
/*
* $Id$
* pa_mac_core.c
* Implementation of PortAudio for Mac OS X CoreAudio
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Authors: Ross Bencina and Phil Burk
* Copyright (c) 1999-2000 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.
*/
#include <CoreAudio/CoreAudio.h>
#include <AudioToolbox/AudioToolbox.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "portaudio.h"
#include "pa_trace.h"
#include "pa_util.h"
#include "pa_allocation.h"
#include "pa_hostapi.h"
#include "pa_stream.h"
#include "pa_cpuload.h"
#include "pa_process.h"
// ===== constants =====
// ===== structs =====
#pragma mark structs
// PaMacCoreHostApiRepresentation - host api datastructure specific to this implementation
typedef struct PaMacCore_HAR
{
PaUtilHostApiRepresentation inheritedHostApiRep;
PaUtilStreamInterface callbackStreamInterface;
PaUtilStreamInterface blockingStreamInterface;
PaUtilAllocationGroup *allocations;
AudioDeviceID *macCoreDeviceIds;
}
PaMacCoreHostApiRepresentation;
typedef struct PaMacCore_DI
{
PaDeviceInfo inheritedDeviceInfo;
}
PaMacCoreDeviceInfo;
// PaMacCoreStream - a stream data structure specifically for this implementation
typedef struct PaMacCore_S
{
PaUtilStreamRepresentation streamRepresentation;
PaUtilCpuLoadMeasurer cpuLoadMeasurer;
PaUtilBufferProcessor bufferProcessor;
int primeStreamUsingCallback;
AudioDeviceID inputDevice;
AudioDeviceID outputDevice;
// Processing thread management --------------
// HANDLE abortEvent;
// HANDLE processingThread;
// DWORD processingThreadId;
char throttleProcessingThreadOnOverload; // 0 -> don't throtte, non-0 -> throttle
int processingThreadPriority;
int highThreadPriority;
int throttledThreadPriority;
unsigned long throttledSleepMsecs;
int isStopped;
volatile int isActive;
volatile int stopProcessing; // stop thread once existing buffers have been returned
volatile int abortProcessing; // stop thread immediately
// DWORD allBuffersDurationMs; // used to calculate timeouts
}
PaMacCoreStream;
// Data needed by the CoreAudio callback functions
typedef struct PaMacCore_CD
{
PaMacCoreStream *stream;
PaStreamCallback *callback;
void *userData;
PaUtilConverter *inputConverter;
PaUtilConverter *outputConverter;
void *inputBuffer;
void *outputBuffer;
int inputChannelCount;
int outputChannelCount;
PaSampleFormat inputSampleFormat;
PaSampleFormat outputSampleFormat;
PaUtilTriangularDitherGenerator *ditherGenerator;
}
PaMacClientData;
// ===== CoreAudio-PortAudio bridge functions =====
#pragma mark CoreAudio-PortAudio bridge functions
// Maps CoreAudio OSStatus codes to PortAudio PaError codes
static PaError conv_err(OSStatus error)
{
PaError result;
switch (error) {
case kAudioHardwareNoError:
result = paNoError; break;
case kAudioHardwareNotRunningError:
result = paInternalError; break;
case kAudioHardwareUnspecifiedError:
result = paInternalError; break;
case kAudioHardwareUnknownPropertyError:
result = paInternalError; break;
case kAudioHardwareBadPropertySizeError:
result = paInternalError; break;
case kAudioHardwareIllegalOperationError:
result = paInternalError; break;
case kAudioHardwareBadDeviceError:
result = paInvalidDevice; break;
case kAudioHardwareBadStreamError:
result = paBadStreamPtr; break;
case kAudioHardwareUnsupportedOperationError:
result = paInternalError; break;
case kAudioDeviceUnsupportedFormatError:
result = paSampleFormatNotSupported; break;
case kAudioDevicePermissionsError:
result = paDeviceUnavailable; break;
default:
result = paInternalError;
}
return result;
}
/* This function is unused
static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamParameters *parameters, double sampleRate)
{
struct AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(sizeof(AudioStreamBasicDescription));
streamDescription->mSampleRate = sampleRate;
streamDescription->mFormatID = kAudioFormatLinearPCM;
streamDescription->mFormatFlags = 0;
streamDescription->mFramesPerPacket = 1;
if (parameters->sampleFormat & paNonInterleaved) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsNonInterleaved;
streamDescription->mChannelsPerFrame = 1;
streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat);
streamDescription->mBytesPerPacket = Pa_GetSampleSize(parameters->sampleFormat);
}
else {
streamDescription->mChannelsPerFrame = parameters->channelCount;
}
streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat) * streamDescription->mChannelsPerFrame;
streamDescription->mBytesPerPacket = streamDescription->mBytesPerFrame * streamDescription->mFramesPerPacket;
if (parameters->sampleFormat & paFloat32) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
streamDescription->mBitsPerChannel = 32;
}
else if (parameters->sampleFormat & paInt32) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamDescription->mBitsPerChannel = 32;
}
else if (parameters->sampleFormat & paInt24) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamDescription->mBitsPerChannel = 24;
}
else if (parameters->sampleFormat & paInt16) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamDescription->mBitsPerChannel = 16;
}
else if (parameters->sampleFormat & paInt8) {
streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamDescription->mBitsPerChannel = 8;
}
else if (parameters->sampleFormat & paInt32) {
streamDescription->mBitsPerChannel = 8;
}
return streamDescription;
}
*/
static PaStreamCallbackTimeInfo *InitializeTimeInfo(const AudioTimeStamp* now, const AudioTimeStamp* inputTime, const AudioTimeStamp* outputTime)
{
PaStreamCallbackTimeInfo *timeInfo = PaUtil_AllocateMemory(sizeof(PaStreamCallbackTimeInfo));
timeInfo->inputBufferAdcTime = inputTime->mSampleTime;
timeInfo->currentTime = now->mSampleTime;
timeInfo->outputBufferDacTime = outputTime->mSampleTime;
return timeInfo;
}
// ===== support functions =====
#pragma mark support functions
static void CleanUp(PaMacCoreHostApiRepresentation *macCoreHostApi)
{
if( macCoreHostApi->allocations )
{
PaUtil_FreeAllAllocations( macCoreHostApi->allocations );
PaUtil_DestroyAllocationGroup( macCoreHostApi->allocations );
}
PaUtil_FreeMemory( macCoreHostApi );
}
static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput)
{
UInt32 propSize;
PaError err = paNoError;
UInt32 i;
int numChannels = 0;
AudioBufferList *buflist;
err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL));
buflist = PaUtil_AllocateMemory(propSize);
err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist));
if (!err) {
for (i = 0; i < buflist->mNumberBuffers; ++i) {
numChannels += buflist->mBuffers[i].mNumberChannels;
}
if (isInput)
deviceInfo->maxInputChannels = numChannels;
else
deviceInfo->maxOutputChannels = numChannels;
int frameLatency;
propSize = sizeof(UInt32);
err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency));
if (!err) {
double secondLatency = frameLatency / deviceInfo->defaultSampleRate;
if (isInput) {
deviceInfo->defaultLowInputLatency = secondLatency;
deviceInfo->defaultHighInputLatency = secondLatency;
}
else {
deviceInfo->defaultLowOutputLatency = secondLatency;
deviceInfo->defaultHighOutputLatency = secondLatency;
}
}
}
PaUtil_FreeMemory(buflist);
return err;
}
static PaError InitializeDeviceInfo(PaMacCoreDeviceInfo *macCoreDeviceInfo, AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex )
{
PaDeviceInfo *deviceInfo = &macCoreDeviceInfo->inheritedDeviceInfo;
deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex;
PaError err = paNoError;
UInt32 propSize;
err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
// FIXME: this allocation should be part of the allocations group
char *name = PaUtil_AllocateMemory(propSize);
err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
if (!err) {
deviceInfo->name = name;
}
Float64 sampleRate;
propSize = sizeof(Float64);
err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate));
if (!err) {
deviceInfo->defaultSampleRate = sampleRate;
}
// Get channel info
err = GetChannelInfo(deviceInfo, macCoreDeviceId, 1);
err = GetChannelInfo(deviceInfo, macCoreDeviceId, 0);
return err;
}
static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHostApi, PaHostApiIndex hostApiIndex )
{
PaError result = paNoError;
PaUtilHostApiRepresentation *hostApi;
PaMacCoreDeviceInfo *deviceInfoArray;
// initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized.
hostApi = &macCoreHostApi->inheritedHostApiRep;
hostApi->info.deviceCount = 0;
hostApi->info.defaultInputDevice = paNoDevice;
hostApi->info.defaultOutputDevice = paNoDevice;
UInt32 propsize;
AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propsize, NULL);
int numDevices = propsize / sizeof(AudioDeviceID);
hostApi->info.deviceCount = numDevices;
if (numDevices > 0) {
hostApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
macCoreHostApi->allocations, sizeof(PaDeviceInfo*) * numDevices );
if( !hostApi->deviceInfos )
{
return paInsufficientMemory;
}
// allocate all device info structs in a contiguous block
deviceInfoArray = (PaMacCoreDeviceInfo*)PaUtil_GroupAllocateMemory(
macCoreHostApi->allocations, sizeof(PaMacCoreDeviceInfo) * numDevices );
if( !deviceInfoArray )
{
return paInsufficientMemory;
}
macCoreHostApi->macCoreDeviceIds = PaUtil_GroupAllocateMemory(macCoreHostApi->allocations, propsize);
AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propsize, macCoreHostApi->macCoreDeviceIds);
AudioDeviceID defaultInputDevice, defaultOutputDevice;
propsize = sizeof(AudioDeviceID);
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propsize, &defaultInputDevice);
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propsize, &defaultOutputDevice);
UInt32 i;
for (i = 0; i < numDevices; ++i) {
if (macCoreHostApi->macCoreDeviceIds[i] == defaultInputDevice) {
hostApi->info.defaultInputDevice = i;
}
if (macCoreHostApi->macCoreDeviceIds[i] == defaultOutputDevice) {
hostApi->info.defaultOutputDevice = i;
}
InitializeDeviceInfo(&deviceInfoArray[i], macCoreHostApi->macCoreDeviceIds[i], hostApiIndex);
hostApi->deviceInfos[i] = &(deviceInfoArray[i].inheritedDeviceInfo);
}
}
return result;
}
static OSStatus CheckFormat(AudioDeviceID macCoreDeviceId, const PaStreamParameters *parameters, double sampleRate, int isInput)
{
UInt32 propSize = sizeof(AudioStreamBasicDescription);
AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(propSize);
streamDescription->mSampleRate = sampleRate;
streamDescription->mFormatID = 0;
streamDescription->mFormatFlags = 0;
streamDescription->mBytesPerPacket = 0;
streamDescription->mFramesPerPacket = 0;
streamDescription->mBytesPerFrame = 0;
streamDescription->mChannelsPerFrame = 0;
streamDescription->mBitsPerChannel = 0;
streamDescription->mReserved = 0;
OSStatus result = AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamFormatSupported, &propSize, streamDescription);
PaUtil_FreeMemory(streamDescription);
return result;
}
static OSStatus CopyInputData(PaMacClientData* destination, const AudioBufferList *source, unsigned long frameCount)
{
int frameSpacing, channelSpacing;
if (destination->inputSampleFormat & paNonInterleaved) {
frameSpacing = 1;
channelSpacing = destination->inputChannelCount;
}
else {
frameSpacing = destination->inputChannelCount;
channelSpacing = 1;
}
AudioBuffer const *inputBuffer = &source->mBuffers[0];
void *coreAudioBuffer = inputBuffer->mData;
void *portAudioBuffer = destination->inputBuffer;
UInt32 i, streamNumber, streamChannel;
for (i = streamNumber = streamChannel = 0; i < destination->inputChannelCount; ++i, ++streamChannel) {
if (streamChannel >= inputBuffer->mNumberChannels) {
++streamNumber;
inputBuffer = &source->mBuffers[streamNumber];
coreAudioBuffer = inputBuffer->mData;
streamChannel = 0;
}
destination->inputConverter(portAudioBuffer, frameSpacing, coreAudioBuffer, inputBuffer->mNumberChannels, frameCount, destination->ditherGenerator);
coreAudioBuffer += sizeof(Float32);
portAudioBuffer += Pa_GetSampleSize(destination->inputSampleFormat) * channelSpacing;
}
return noErr;
}
static OSStatus CopyOutputData(AudioBufferList* destination, PaMacClientData *source, unsigned long frameCount)
{
int frameSpacing, channelSpacing;
if (source->outputSampleFormat & paNonInterleaved) {
frameSpacing = 1;
channelSpacing = source->outputChannelCount;
}
else {
frameSpacing = source->outputChannelCount;
channelSpacing = 1;
}
AudioBuffer *outputBuffer = &destination->mBuffers[0];
void *coreAudioBuffer = outputBuffer->mData;
void *portAudioBuffer = source->outputBuffer;
UInt32 i, streamNumber, streamChannel;
for (i = streamNumber = streamChannel = 0; i < source->outputChannelCount; ++i, ++streamChannel) {
if (streamChannel >= outputBuffer->mNumberChannels) {
++streamNumber;
outputBuffer = &destination->mBuffers[streamNumber];
coreAudioBuffer = outputBuffer->mData;
streamChannel = 0;
}
source->outputConverter(coreAudioBuffer, outputBuffer->mNumberChannels, portAudioBuffer, frameSpacing, frameCount, NULL);
coreAudioBuffer += sizeof(Float32);
portAudioBuffer += Pa_GetSampleSize(source->outputSampleFormat) * channelSpacing;
}
return noErr;
}
static OSStatus AudioIOProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
PaMacClientData *clientData = (PaMacClientData *)inClientData;
PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));
if (clientData->inputBuffer) {
CopyInputData(clientData, inInputData, frameCount);
}
PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
if (clientData->outputBuffer) {
CopyOutputData(outOutputData, clientData, frameCount);
}
PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
if (result == paComplete || result == paAbort) {
Pa_StopStream(clientData->stream);
}
PaUtil_FreeMemory( timeInfo );
return noErr;
}
// This is not for input-only streams, this is for streams where the input device is different from the output device
static OSStatus AudioInputProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
PaMacClientData *clientData = (PaMacClientData *)inClientData;
PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
AudioBuffer const *inputBuffer = &inInputData->mBuffers[0];
unsigned long frameCount = inputBuffer->mDataByteSize / (inputBuffer->mNumberChannels * sizeof(Float32));
CopyInputData(clientData, inInputData, frameCount);
PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
if( result == paComplete || result == paAbort )
Pa_StopStream(clientData->stream);
PaUtil_FreeMemory( timeInfo );
return noErr;
}
// This is not for output-only streams, this is for streams where the input device is different from the output device
static OSStatus AudioOutputProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
PaMacClientData *clientData = (PaMacClientData *)inClientData;
//PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));
//clientData->callback(NULL, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
CopyOutputData(outOutputData, clientData, frameCount);
PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
return noErr;
}
static PaError SetSampleRate(AudioDeviceID device, double sampleRate, int isInput)
{
PaError result = paNoError;
double actualSampleRate;
UInt32 propSize = sizeof(double);
result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyNominalSampleRate, propSize, &sampleRate));
result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyNominalSampleRate, &propSize, &actualSampleRate));
if (result == paNoError && actualSampleRate != sampleRate) {
result = paInvalidSampleRate;
}
return result;
}
static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerBuffer, int isInput)
{
PaError result = paNoError;
UInt32 preferredFramesPerBuffer = framesPerBuffer;
// while (preferredFramesPerBuffer > UINT32_MAX) {
// preferredFramesPerBuffer /= 2;
// }
UInt32 actualFramesPerBuffer;
UInt32 propSize = sizeof(UInt32);
result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propSize, &preferredFramesPerBuffer));
result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &actualFramesPerBuffer));
if (result != paNoError) {
// do nothing
}
else if (actualFramesPerBuffer > framesPerBuffer) {
result = paBufferTooSmall;
}
else if (actualFramesPerBuffer < framesPerBuffer) {
result = paBufferTooBig;
}
return result;
}
static PaError SetUpUnidirectionalStream(AudioDeviceID device, double sampleRate, unsigned long framesPerBuffer, int isInput)
{
PaError err = paNoError;
err = SetSampleRate(device, sampleRate, isInput);
if( err == paNoError )
err = SetFramesPerBuffer(device, framesPerBuffer, isInput);
return err;
}
// ===== PortAudio functions =====
#pragma mark PortAudio functions
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
#ifdef __cplusplus
}
#endif // __cplusplus
static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
{
PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
CleanUp(macCoreHostApi);
}
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate )
{
PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
PaDeviceInfo *deviceInfo;
PaError result = paNoError;
if (inputParameters) {
deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device];
if (inputParameters->channelCount > deviceInfo->maxInputChannels)
result = paInvalidChannelCount;
else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[inputParameters->device], inputParameters, sampleRate, 1) != kAudioHardwareNoError) {
result = paInvalidSampleRate;
}
}
if (outputParameters && result == paNoError) {
deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[outputParameters->device];
if (outputParameters->channelCount > deviceInfo->maxOutputChannels)
result = paInvalidChannelCount;
else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[outputParameters->device], outputParameters, sampleRate, 0) != kAudioHardwareNoError) {
result = paInvalidSampleRate;
}
}
return result;
}
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaStream** s,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate,
unsigned long framesPerBuffer,
PaStreamFlags streamFlags,
PaStreamCallback *streamCallback,
void *userData )
{
PaError err = paNoError;
PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)hostApi;
PaMacCoreStream *stream = PaUtil_AllocateMemory(sizeof(PaMacCoreStream));
stream->isActive = 0;
stream->isStopped = 1;
stream->inputDevice = kAudioDeviceUnknown;
stream->outputDevice = kAudioDeviceUnknown;
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
( (streamCallback)
? &macCoreHostApi->callbackStreamInterface
: &macCoreHostApi->blockingStreamInterface ),
streamCallback, userData );
PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
*s = (PaStream*)stream;
PaMacClientData *clientData = PaUtil_AllocateMemory(sizeof(PaMacClientData));
clientData->stream = stream;
clientData->callback = streamCallback;
clientData->userData = userData;
clientData->inputBuffer = 0;
clientData->outputBuffer = 0;
clientData->ditherGenerator = PaUtil_AllocateMemory(sizeof(PaUtilTriangularDitherGenerator));
PaUtil_InitializeTriangularDitherState(clientData->ditherGenerator);
if (inputParameters != NULL) {
stream->inputDevice = macCoreHostApi->macCoreDeviceIds[inputParameters->device];
clientData->inputConverter = PaUtil_SelectConverter(paFloat32, inputParameters->sampleFormat, streamFlags);
clientData->inputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(inputParameters->sampleFormat) * framesPerBuffer * inputParameters->channelCount);
clientData->inputChannelCount = inputParameters->channelCount;
clientData->inputSampleFormat = inputParameters->sampleFormat;
err = SetUpUnidirectionalStream(stream->inputDevice, sampleRate, framesPerBuffer, 1);
}
if (err == paNoError && outputParameters != NULL) {
stream->outputDevice = macCoreHostApi->macCoreDeviceIds[outputParameters->device];
clientData->outputConverter = PaUtil_SelectConverter(outputParameters->sampleFormat, paFloat32, streamFlags);
clientData->outputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(outputParameters->sampleFormat) * framesPerBuffer * outputParameters->channelCount);
clientData->outputChannelCount = outputParameters->channelCount;
clientData->outputSampleFormat = outputParameters->sampleFormat;
err = SetUpUnidirectionalStream(stream->outputDevice, sampleRate, framesPerBuffer, 0);
}
if (inputParameters == NULL || outputParameters == NULL || stream->inputDevice == stream->outputDevice) {
AudioDeviceID device = (inputParameters == NULL) ? stream->outputDevice : stream->inputDevice;
AudioDeviceAddIOProc(device, AudioIOProc, clientData);
}
else {
// using different devices for input and output
AudioDeviceAddIOProc(stream->inputDevice, AudioInputProc, clientData);
AudioDeviceAddIOProc(stream->outputDevice, AudioOutputProc, clientData);
}
return err;
}
// Note: When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted.
static PaError CloseStream( PaStream* s )
{
PaError err = paNoError;
PaMacCoreStream *stream = (PaMacCoreStream*)s;
PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
if (stream->inputDevice != kAudioDeviceUnknown) {
if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioIOProc));
}
else {
err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioInputProc));
err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioOutputProc));
}
}
else {
err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioIOProc));
}
return err;
}
static PaError StartStream( PaStream *s )
{
PaError err = paNoError;
PaMacCoreStream *stream = (PaMacCoreStream*)s;
if (stream->inputDevice != kAudioDeviceUnknown) {
if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
err = conv_err(AudioDeviceStart(stream->inputDevice, AudioIOProc));
}
else {
err = conv_err(AudioDeviceStart(stream->inputDevice, AudioInputProc));
err = conv_err(AudioDeviceStart(stream->outputDevice, AudioOutputProc));
}
}
else {
err = conv_err(AudioDeviceStart(stream->outputDevice, AudioIOProc));
}
stream->isActive = 1;
stream->isStopped = 0;
return err;
}
static PaError AbortStream( PaStream *s )
{
PaError err = paNoError;
PaMacCoreStream *stream = (PaMacCoreStream*)s;
if (stream->inputDevice != kAudioDeviceUnknown) {
if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
err = conv_err(AudioDeviceStop(stream->inputDevice, AudioIOProc));
}
else {
err = conv_err(AudioDeviceStop(stream->inputDevice, AudioInputProc));
err = conv_err(AudioDeviceStop(stream->outputDevice, AudioOutputProc));
}
}
else {
err = conv_err(AudioDeviceStop(stream->outputDevice, AudioIOProc));
}
stream->isActive = 0;
stream->isStopped = 1;
return err;
}
static PaError StopStream( PaStream *s )
{
// TODO: this should be nicer than abort
return AbortStream(s);
}
static PaError IsStreamStopped( PaStream *s )
{
PaMacCoreStream *stream = (PaMacCoreStream*)s;
return stream->isStopped;
}
static PaError IsStreamActive( PaStream *s )
{
PaMacCoreStream *stream = (PaMacCoreStream*)s;
return stream->isActive;
}
static PaTime GetStreamTime( PaStream *s )
{
OSStatus err;
PaTime result;
PaMacCoreStream *stream = (PaMacCoreStream*)s;
AudioTimeStamp *timeStamp = PaUtil_AllocateMemory(sizeof(AudioTimeStamp));
if (stream->inputDevice != kAudioDeviceUnknown) {
err = AudioDeviceGetCurrentTime(stream->inputDevice, timeStamp);
}
else {
err = AudioDeviceGetCurrentTime(stream->outputDevice, timeStamp);
}
result = err ? 0 : timeStamp->mSampleTime;
PaUtil_FreeMemory(timeStamp);
return result;
}
static double GetStreamCpuLoad( PaStream* s )
{
PaMacCoreStream *stream = (PaMacCoreStream*)s;
return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
}
// As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams.
static PaError ReadStream( PaStream* s,
void *buffer,
unsigned long frames )
{
return paInternalError;
}
static PaError WriteStream( PaStream* s,
const void *buffer,
unsigned long frames )
{
return paInternalError;
}
static signed long GetStreamReadAvailable( PaStream* s )
{
return paInternalError;
}
static signed long GetStreamWriteAvailable( PaStream* s )
{
return paInternalError;
}
// HostAPI-specific initialization function
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
{
PaError result = paNoError;
PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaMacCoreHostApiRepresentation) );
if( !macCoreHostApi )
{
result = paInsufficientMemory;
goto error;
}
macCoreHostApi->allocations = PaUtil_CreateAllocationGroup();
if( !macCoreHostApi->allocations )
{
result = paInsufficientMemory;
goto error;
}
*hostApi = &macCoreHostApi->inheritedHostApiRep;
(*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paCoreAudio;
(*hostApi)->info.name = "CoreAudio";
result = InitializeDeviceInfos(macCoreHostApi, hostApiIndex);
if (result != paNoError) {
goto error;
}
// Set up the proper callbacks to this HostApi's functions
(*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported;
PaUtil_InitializeStreamInterface( &macCoreHostApi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, GetStreamCpuLoad,
PaUtil_DummyRead, PaUtil_DummyWrite,
PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
PaUtil_InitializeStreamInterface( &macCoreHostApi->blockingStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, PaUtil_DummyGetCpuLoad,
ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
return result;
error:
if( macCoreHostApi ) {
CleanUp(macCoreHostApi);
}
return result;
}

View File

@ -1,701 +0,0 @@
/*
* Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation)
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
* Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
*
* Dominic's code was based on code by Phil Burk, Darren Gibbs,
* Gord Peters, Stephane Letz, and Greg Pfiel.
*
* The following people also deserve acknowledgements:
*
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 hostapi_src
*/
#include "pa_mac_core_utilities.h"
#include "pa_mac_core_internal.h"
#include <libkern/OSAtomic.h>
#include <strings.h>
#include <pthread.h>
#include <sys/time.h>
PaError PaMacCore_SetUnixError( int err, int line )
{
PaError ret;
const char *errorText;
if( err == 0 )
{
return paNoError;
}
ret = paNoError;
errorText = strerror( err );
/** Map Unix error to PaError. Pretty much the only one that maps
is ENOMEM. */
if( err == ENOMEM )
ret = paInsufficientMemory;
else
ret = paInternalError;
DBUG(("%d on line %d: msg='%s'\n", err, line, errorText));
PaUtil_SetLastHostErrorInfo( paCoreAudio, err, errorText );
return ret;
}
/*
* Translates MacOS generated errors into PaErrors
*/
PaError PaMacCore_SetError(OSStatus error, int line, int isError)
{
/*FIXME: still need to handle possible ComponentResult values.*/
/* unfortunately, they don't seem to be documented anywhere.*/
PaError result;
const char *errorType;
const char *errorText;
switch (error) {
case kAudioHardwareNoError:
return paNoError;
case kAudioHardwareNotRunningError:
errorText = "Audio Hardware Not Running";
result = paInternalError; break;
case kAudioHardwareUnspecifiedError:
errorText = "Unspecified Audio Hardware Error";
result = paInternalError; break;
case kAudioHardwareUnknownPropertyError:
errorText = "Audio Hardware: Unknown Property";
result = paInternalError; break;
case kAudioHardwareBadPropertySizeError:
errorText = "Audio Hardware: Bad Property Size";
result = paInternalError; break;
case kAudioHardwareIllegalOperationError:
errorText = "Audio Hardware: Illegal Operation";
result = paInternalError; break;
case kAudioHardwareBadDeviceError:
errorText = "Audio Hardware: Bad Device";
result = paInvalidDevice; break;
case kAudioHardwareBadStreamError:
errorText = "Audio Hardware: BadStream";
result = paBadStreamPtr; break;
case kAudioHardwareUnsupportedOperationError:
errorText = "Audio Hardware: Unsupported Operation";
result = paInternalError; break;
case kAudioDeviceUnsupportedFormatError:
errorText = "Audio Device: Unsupported Format";
result = paSampleFormatNotSupported; break;
case kAudioDevicePermissionsError:
errorText = "Audio Device: Permissions Error";
result = paDeviceUnavailable; break;
/* Audio Unit Errors: http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/audio_units/chapter_5_section_3.html */
case kAudioUnitErr_InvalidProperty:
errorText = "Audio Unit: Invalid Property";
result = paInternalError; break;
case kAudioUnitErr_InvalidParameter:
errorText = "Audio Unit: Invalid Parameter";
result = paInternalError; break;
case kAudioUnitErr_NoConnection:
errorText = "Audio Unit: No Connection";
result = paInternalError; break;
case kAudioUnitErr_FailedInitialization:
errorText = "Audio Unit: Initialization Failed";
result = paInternalError; break;
case kAudioUnitErr_TooManyFramesToProcess:
errorText = "Audio Unit: Too Many Frames";
result = paInternalError; break;
case kAudioUnitErr_IllegalInstrument:
errorText = "Audio Unit: Illegal Instrument";
result = paInternalError; break;
case kAudioUnitErr_InstrumentTypeNotFound:
errorText = "Audio Unit: Instrument Type Not Found";
result = paInternalError; break;
case kAudioUnitErr_InvalidFile:
errorText = "Audio Unit: Invalid File";
result = paInternalError; break;
case kAudioUnitErr_UnknownFileType:
errorText = "Audio Unit: Unknown File Type";
result = paInternalError; break;
case kAudioUnitErr_FileNotSpecified:
errorText = "Audio Unit: File Not Specified";
result = paInternalError; break;
case kAudioUnitErr_FormatNotSupported:
errorText = "Audio Unit: Format Not Supported";
result = paInternalError; break;
case kAudioUnitErr_Uninitialized:
errorText = "Audio Unit: Unitialized";
result = paInternalError; break;
case kAudioUnitErr_InvalidScope:
errorText = "Audio Unit: Invalid Scope";
result = paInternalError; break;
case kAudioUnitErr_PropertyNotWritable:
errorText = "Audio Unit: PropertyNotWritable";
result = paInternalError; break;
case kAudioUnitErr_InvalidPropertyValue:
errorText = "Audio Unit: Invalid Property Value";
result = paInternalError; break;
case kAudioUnitErr_PropertyNotInUse:
errorText = "Audio Unit: Property Not In Use";
result = paInternalError; break;
case kAudioUnitErr_Initialized:
errorText = "Audio Unit: Initialized";
result = paInternalError; break;
case kAudioUnitErr_InvalidOfflineRender:
errorText = "Audio Unit: Invalid Offline Render";
result = paInternalError; break;
case kAudioUnitErr_Unauthorized:
errorText = "Audio Unit: Unauthorized";
result = paInternalError; break;
case kAudioUnitErr_CannotDoInCurrentContext:
errorText = "Audio Unit: cannot do in current context";
result = paInternalError; break;
default:
errorText = "Unknown Error";
result = paInternalError;
}
if (isError)
errorType = "Error";
else
errorType = "Warning";
char str[20];
// see if it appears to be a 4-char-code
*(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error);
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4]))
{
str[0] = str[5] = '\'';
str[6] = '\0';
} else {
// no, format it as an integer
sprintf(str, "%d", (int)error);
}
DBUG(("%s on line %d: err='%s', msg=%s\n", errorType, line, str, errorText));
PaUtil_SetLastHostErrorInfo( paCoreAudio, error, errorText );
return result;
}
/*
* This function computes an appropriate ring buffer size given
* a requested latency (in seconds), sample rate and framesPerBuffer.
*
* The returned ringBufferSize is computed using the following
* constraints:
* - it must be at least 4.
* - it must be at least 3x framesPerBuffer.
* - it must be at least 2x the suggestedLatency.
* - it must be a power of 2.
* This function attempts to compute the minimum such size.
*
* FEEDBACK: too liberal/conservative/another way?
*/
long computeRingBufferSize( const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
long inputFramesPerBuffer,
long outputFramesPerBuffer,
double sampleRate )
{
long ringSize;
int index;
int i;
double latency ;
long framesPerBuffer ;
VVDBUG(( "computeRingBufferSize()\n" ));
assert( inputParameters || outputParameters );
if( outputParameters && inputParameters )
{
latency = MAX( inputParameters->suggestedLatency, outputParameters->suggestedLatency );
framesPerBuffer = MAX( inputFramesPerBuffer, outputFramesPerBuffer );
}
else if( outputParameters )
{
latency = outputParameters->suggestedLatency;
framesPerBuffer = outputFramesPerBuffer ;
}
else /* we have inputParameters */
{
latency = inputParameters->suggestedLatency;
framesPerBuffer = inputFramesPerBuffer ;
}
ringSize = (long) ( latency * sampleRate * 2 + .5);
VDBUG( ( "suggested latency : %d\n", (int) (latency*sampleRate) ) );
if( ringSize < framesPerBuffer * 3 )
ringSize = framesPerBuffer * 3 ;
VDBUG(("framesPerBuffer:%d\n",(int)framesPerBuffer));
VDBUG(("Ringbuffer size (1): %d\n", (int)ringSize ));
/* make sure it's at least 4 */
ringSize = MAX( ringSize, 4 );
/* round up to the next power of 2 */
index = -1;
for( i=0; i<sizeof(long)*8; ++i )
if( ringSize >> i & 0x01 )
index = i;
assert( index > 0 );
if( ringSize <= ( 0x01 << index ) )
ringSize = 0x01 << index ;
else
ringSize = 0x01 << ( index + 1 );
VDBUG(( "Final Ringbuffer size (2): %d\n", (int)ringSize ));
return ringSize;
}
/*
* Durring testing of core audio, I found that serious crashes could occur
* if properties such as sample rate were changed multiple times in rapid
* succession. The function below could be used to with a condition variable.
* to prevent propertychanges from happening until the last property
* change is acknowledged. Instead, I implemented a busy-wait, which is simpler
* to implement b/c in second round of testing (nov '09) property changes occured
* quickly and so there was no real way to test the condition variable implementation.
* therefore, this function is not used, but it is aluded to in commented code below,
* since it represents a theoretically better implementation.
*/
OSStatus propertyProc(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData )
{
// this is where we would set the condition variable
return noErr;
}
/* sets the value of the given property and waits for the change to
be acknowledged, and returns the final value, which is not guaranteed
by this function to be the same as the desired value. Obviously, this
function can only be used for data whose input and output are the
same size and format, and their size and format are known in advance.
whether or not the call succeeds, if the data is successfully read,
it is returned in outPropertyData. If it is not read successfully,
outPropertyData is zeroed, which may or may not be useful in
determining if the property was read. */
PaError AudioDeviceSetPropertyNowAndWaitForChange(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
UInt32 inPropertyDataSize,
const void *inPropertyData,
void *outPropertyData )
{
OSStatus macErr;
UInt32 outPropertyDataSize = inPropertyDataSize;
/* First, see if it already has that value. If so, return. */
macErr = AudioDeviceGetProperty( inDevice, inChannel,
isInput, inPropertyID,
&outPropertyDataSize, outPropertyData );
if( macErr ) {
memset( outPropertyData, 0, inPropertyDataSize );
goto failMac;
}
if( inPropertyDataSize!=outPropertyDataSize )
return paInternalError;
if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) )
return paNoError;
/* Ideally, we'd use a condition variable to determine changes.
we could set that up here. */
/* If we were using a cond variable, we'd do something useful here,
but for now, this is just to make 10.6 happy. */
macErr = AudioDeviceAddPropertyListener( inDevice, inChannel, isInput,
inPropertyID, propertyProc,
NULL );
if( macErr )
/* we couldn't add a listener. */
goto failMac;
/* set property */
macErr = AudioDeviceSetProperty( inDevice, NULL, inChannel,
isInput, inPropertyID,
inPropertyDataSize, inPropertyData );
if( macErr )
goto failMac;
/* busy-wait up to 30 seconds for the property to change */
/* busy-wait is justified here only because the correct alternative (condition variable)
was hard to test, since most of the waiting ended up being for setting rather than
getting in OS X 10.5. This was not the case in earlier OS versions. */
struct timeval tv1, tv2;
gettimeofday( &tv1, NULL );
memcpy( &tv2, &tv1, sizeof( struct timeval ) );
while( tv2.tv_sec - tv1.tv_sec < 30 ) {
/* now read the property back out */
macErr = AudioDeviceGetProperty( inDevice, inChannel,
isInput, inPropertyID,
&outPropertyDataSize, outPropertyData );
if( macErr ) {
memset( outPropertyData, 0, inPropertyDataSize );
goto failMac;
}
/* and compare... */
if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) ) {
AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc );
return paNoError;
}
/* No match yet, so let's sleep and try again. */
Pa_Sleep( 100 );
gettimeofday( &tv2, NULL );
}
DBUG( ("Timeout waiting for device setting.\n" ) );
AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc );
return paNoError;
failMac:
AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc );
return ERR( macErr );
}
/*
* Sets the sample rate the HAL device.
* if requireExact: set the sample rate or fail.
*
* otherwise : set the exact sample rate.
* If that fails, check for available sample rates, and choose one
* higher than the requested rate. If there isn't a higher one,
* just use the highest available.
*/
PaError setBestSampleRateForDevice( const AudioDeviceID device,
const bool isOutput,
const bool requireExact,
const Float64 desiredSrate )
{
const bool isInput = isOutput ? 0 : 1;
Float64 srate;
UInt32 propsize = sizeof( Float64 );
OSErr err;
AudioValueRange *ranges;
int i=0;
Float64 max = -1; /*the maximum rate available*/
Float64 best = -1; /*the lowest sample rate still greater than desired rate*/
VDBUG(("Setting sample rate for device %ld to %g.\n",device,(float)desiredSrate));
/* -- try setting the sample rate -- */
srate = 0;
err = AudioDeviceSetPropertyNowAndWaitForChange(
device, 0, isInput,
kAudioDevicePropertyNominalSampleRate,
propsize, &desiredSrate, &srate );
/* -- if the rate agrees, and was changed, we are done -- */
if( srate != 0 && srate == desiredSrate )
return paNoError;
/* -- if the rate agrees, and we got no errors, we are done -- */
if( !err && srate == desiredSrate )
return paNoError;
/* -- we've failed if the rates disagree and we are setting input -- */
if( requireExact )
return paInvalidSampleRate;
/* -- generate a list of available sample rates -- */
err = AudioDeviceGetPropertyInfo( device, 0, isInput,
kAudioDevicePropertyAvailableNominalSampleRates,
&propsize, NULL );
if( err )
return ERR( err );
ranges = (AudioValueRange *)calloc( 1, propsize );
if( !ranges )
return paInsufficientMemory;
err = AudioDeviceGetProperty( device, 0, isInput,
kAudioDevicePropertyAvailableNominalSampleRates,
&propsize, ranges );
if( err )
{
free( ranges );
return ERR( err );
}
VDBUG(("Requested sample rate of %g was not available.\n", (float)desiredSrate));
VDBUG(("%lu Available Sample Rates are:\n",propsize/sizeof(AudioValueRange)));
#ifdef MAC_CORE_VERBOSE_DEBUG
for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
VDBUG( ("\t%g-%g\n",
(float) ranges[i].mMinimum,
(float) ranges[i].mMaximum ) );
#endif
VDBUG(("-----\n"));
/* -- now pick the best available sample rate -- */
for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
{
if( ranges[i].mMaximum > max ) max = ranges[i].mMaximum;
if( ranges[i].mMinimum > desiredSrate ) {
if( best < 0 )
best = ranges[i].mMinimum;
else if( ranges[i].mMinimum < best )
best = ranges[i].mMinimum;
}
}
if( best < 0 )
best = max;
VDBUG( ("Maximum Rate %g. best is %g.\n", max, best ) );
free( ranges );
/* -- set the sample rate -- */
propsize = sizeof( best );
srate = 0;
err = AudioDeviceSetPropertyNowAndWaitForChange(
device, 0, isInput,
kAudioDevicePropertyNominalSampleRate,
propsize, &best, &srate );
/* -- if the set rate matches, we are done -- */
if( srate != 0 && srate == best )
return paNoError;
if( err )
return ERR( err );
/* -- otherwise, something wierd happened: we didn't set the rate, and we got no errors. Just bail. */
return paInternalError;
}
/*
Attempts to set the requestedFramesPerBuffer. If it can't set the exact
value, it settles for something smaller if available. If nothing smaller
is available, it uses the smallest available size.
actualFramesPerBuffer will be set to the actual value on successful return.
OK to pass NULL to actualFramesPerBuffer.
The logic is very simmilar too setBestSampleRate only failure here is
not usually catastrophic.
*/
PaError setBestFramesPerBuffer( const AudioDeviceID device,
const bool isOutput,
UInt32 requestedFramesPerBuffer,
UInt32 *actualFramesPerBuffer )
{
UInt32 afpb;
const bool isInput = !isOutput;
UInt32 propsize = sizeof(UInt32);
OSErr err;
AudioValueRange range;
if( actualFramesPerBuffer == NULL )
{
actualFramesPerBuffer = &afpb;
}
/* -- try and set exact FPB -- */
err = AudioDeviceSetProperty( device, NULL, 0, isInput,
kAudioDevicePropertyBufferFrameSize,
propsize, &requestedFramesPerBuffer);
err = AudioDeviceGetProperty( device, 0, isInput,
kAudioDevicePropertyBufferFrameSize,
&propsize, actualFramesPerBuffer);
if( err )
{
return ERR( err );
}
// Did we get the size we asked for?
if( *actualFramesPerBuffer == requestedFramesPerBuffer )
{
return paNoError; /* we are done */
}
// Clip requested value against legal range for the device.
propsize = sizeof(AudioValueRange);
err = AudioDeviceGetProperty( device, 0, isInput,
kAudioDevicePropertyBufferFrameSizeRange,
&propsize, &range );
if( err )
{
return ERR( err );
}
if( requestedFramesPerBuffer < range.mMinimum )
{
requestedFramesPerBuffer = range.mMinimum;
}
else if( requestedFramesPerBuffer > range.mMaximum )
{
requestedFramesPerBuffer = range.mMaximum;
}
/* --- set the buffer size (ignore errors) -- */
propsize = sizeof( UInt32 );
err = AudioDeviceSetProperty( device, NULL, 0, isInput,
kAudioDevicePropertyBufferFrameSize,
propsize, &requestedFramesPerBuffer );
/* --- read the property to check that it was set -- */
err = AudioDeviceGetProperty( device, 0, isInput,
kAudioDevicePropertyBufferFrameSize,
&propsize, actualFramesPerBuffer );
if( err )
return ERR( err );
return paNoError;
}
/**********************
*
* XRun stuff
*
**********************/
struct PaMacXRunListNode_s {
PaMacCoreStream *stream;
struct PaMacXRunListNode_s *next;
} ;
typedef struct PaMacXRunListNode_s PaMacXRunListNode;
/** Always empty, so that it can always be the one returned by
addToXRunListenerList. note that it's not a pointer. */
static PaMacXRunListNode firstXRunListNode;
static int xRunListSize;
static pthread_mutex_t xrunMutex;
OSStatus xrunCallback(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData)
{
PaMacXRunListNode *node = (PaMacXRunListNode *) inClientData;
int ret = pthread_mutex_trylock( &xrunMutex ) ;
if( ret == 0 ) {
node = node->next ; //skip the first node
for( ; node; node=node->next ) {
PaMacCoreStream *stream = node->stream;
if( stream->state != ACTIVE )
continue; //if the stream isn't active, we don't care if the device is dropping
if( isInput ) {
if( stream->inputDevice == inDevice )
OSAtomicOr32( paInputOverflow, &stream->xrunFlags );
} else {
if( stream->outputDevice == inDevice )
OSAtomicOr32( paOutputUnderflow, &stream->xrunFlags );
}
}
pthread_mutex_unlock( &xrunMutex );
}
return 0;
}
int initializeXRunListenerList()
{
xRunListSize = 0;
bzero( (void *) &firstXRunListNode, sizeof(firstXRunListNode) );
return pthread_mutex_init( &xrunMutex, NULL );
}
int destroyXRunListenerList()
{
PaMacXRunListNode *node;
node = firstXRunListNode.next;
while( node ) {
PaMacXRunListNode *tmp = node;
node = node->next;
free( tmp );
}
xRunListSize = 0;
return pthread_mutex_destroy( &xrunMutex );
}
void *addToXRunListenerList( void *stream )
{
pthread_mutex_lock( &xrunMutex );
PaMacXRunListNode *newNode;
// setup new node:
newNode = (PaMacXRunListNode *) malloc( sizeof( PaMacXRunListNode ) );
newNode->stream = (PaMacCoreStream *) stream;
newNode->next = firstXRunListNode.next;
// insert:
firstXRunListNode.next = newNode;
pthread_mutex_unlock( &xrunMutex );
return &firstXRunListNode;
}
int removeFromXRunListenerList( void *stream )
{
pthread_mutex_lock( &xrunMutex );
PaMacXRunListNode *node, *prev;
prev = &firstXRunListNode;
node = firstXRunListNode.next;
while( node ) {
if( node->stream == stream ) {
//found it:
--xRunListSize;
prev->next = node->next;
free( node );
pthread_mutex_unlock( &xrunMutex );
return xRunListSize;
}
prev = prev->next;
node = node->next;
}
pthread_mutex_unlock( &xrunMutex );
// failure
return xRunListSize;
}

View File

@ -1,218 +0,0 @@
/*
* Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation)
*
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
*
* Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
* Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
*
* Dominic's code was based on code by Phil Burk, Darren Gibbs,
* Gord Peters, Stephane Letz, and Greg Pfiel.
*
* The following people also deserve acknowledgements:
*
* Olivier Tristan for feedback and testing
* Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
* interface.
*
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 hostapi_src
*/
#ifndef PA_MAC_CORE_UTILITIES_H__
#define PA_MAC_CORE_UTILITIES_H__
#include <pthread.h>
#include "portaudio.h"
#include "pa_util.h"
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#ifndef MIN
#define MIN(a, b) (((a)<(b))?(a):(b))
#endif
#ifndef MAX
#define MAX(a, b) (((a)<(b))?(b):(a))
#endif
#define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 )
#define WARNING(mac_error) PaMacCore_SetError(mac_error, __LINE__, 0 )
/* Help keep track of AUHAL element numbers */
#define INPUT_ELEMENT (1)
#define OUTPUT_ELEMENT (0)
/* Normal level of debugging: fine for most apps that don't mind the occational warning being printf'ed */
/*
*/
#define MAC_CORE_DEBUG
#ifdef MAC_CORE_DEBUG
# define DBUG(MSG) do { printf("||PaMacCore (AUHAL)|| "); printf MSG ; fflush(stdout); } while(0)
#else
# define DBUG(MSG)
#endif
/* Verbose Debugging: useful for developement */
/*
#define MAC_CORE_VERBOSE_DEBUG
*/
#ifdef MAC_CORE_VERBOSE_DEBUG
# define VDBUG(MSG) do { printf("||PaMacCore (v )|| "); printf MSG ; fflush(stdout); } while(0)
#else
# define VDBUG(MSG)
#endif
/* Very Verbose Debugging: Traces every call. */
/*
#define MAC_CORE_VERY_VERBOSE_DEBUG
*/
#ifdef MAC_CORE_VERY_VERBOSE_DEBUG
# define VVDBUG(MSG) do { printf("||PaMacCore (vv)|| "); printf MSG ; fflush(stdout); } while(0)
#else
# define VVDBUG(MSG)
#endif
#define UNIX_ERR(err) PaMacCore_SetUnixError( err, __LINE__ )
PaError PaMacCore_SetUnixError( int err, int line );
/*
* Translates MacOS generated errors into PaErrors
*/
PaError PaMacCore_SetError(OSStatus error, int line, int isError);
/*
* This function computes an appropriate ring buffer size given
* a requested latency (in seconds), sample rate and framesPerBuffer.
*
* The returned ringBufferSize is computed using the following
* constraints:
* - it must be at least 4.
* - it must be at least 3x framesPerBuffer.
* - it must be at least 2x the suggestedLatency.
* - it must be a power of 2.
* This function attempts to compute the minimum such size.
*
*/
long computeRingBufferSize( const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
long inputFramesPerBuffer,
long outputFramesPerBuffer,
double sampleRate );
OSStatus propertyProc(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData );
/* sets the value of the given property and waits for the change to
be acknowledged, and returns the final value, which is not guaranteed
by this function to be the same as the desired value. Obviously, this
function can only be used for data whose input and output are the
same size and format, and their size and format are known in advance.*/
PaError AudioDeviceSetPropertyNowAndWaitForChange(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
UInt32 inPropertyDataSize,
const void *inPropertyData,
void *outPropertyData );
/*
* Sets the sample rate the HAL device.
* if requireExact: set the sample rate or fail.
*
* otherwise : set the exact sample rate.
* If that fails, check for available sample rates, and choose one
* higher than the requested rate. If there isn't a higher one,
* just use the highest available.
*/
PaError setBestSampleRateForDevice( const AudioDeviceID device,
const bool isOutput,
const bool requireExact,
const Float64 desiredSrate );
/*
Attempts to set the requestedFramesPerBuffer. If it can't set the exact
value, it settles for something smaller if available. If nothing smaller
is available, it uses the smallest available size.
actualFramesPerBuffer will be set to the actual value on successful return.
OK to pass NULL to actualFramesPerBuffer.
The logic is very simmilar too setBestSampleRate only failure here is
not usually catastrophic.
*/
PaError setBestFramesPerBuffer( const AudioDeviceID device,
const bool isOutput,
UInt32 requestedFramesPerBuffer,
UInt32 *actualFramesPerBuffer );
/*********************
*
* xrun handling
*
*********************/
OSStatus xrunCallback(
AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData ) ;
/** returns zero on success or a unix style error code. */
int initializeXRunListenerList();
/** returns zero on success or a unix style error code. */
int destroyXRunListenerList();
/**Returns the list, so that it can be passed to CorAudio.*/
void *addToXRunListenerList( void *stream );
/**Returns the number of Listeners in the list remaining.*/
int removeFromXRunListenerList( void *stream );
#endif /* PA_MAC_CORE_UTILITIES_H__*/

File diff suppressed because it is too large Load Diff

View File

@ -1,224 +0,0 @@
/*
* Interface for dynamically loading directsound and providing a dummy
* implementation if it isn't present.
*
* Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi)
*
* For PortAudio Portable Real-Time Audio Library
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina
*
* 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 hostapi_src
*/
#include "pa_win_ds_dynlink.h"
#include "pa_debugprint.h"
PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints = { 0, 0, 0, 0, 0, 0, 0 };
static HRESULT WINAPI DummyDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
(void)rclsid; /* unused parameter */
(void)riid; /* unused parameter */
(void)ppv; /* unused parameter */
return CLASS_E_CLASSNOTAVAILABLE;
}
static HRESULT WINAPI DummyDirectSoundCreate(LPGUID lpcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter)
{
(void)lpcGuidDevice; /* unused parameter */
(void)ppDS; /* unused parameter */
(void)pUnkOuter; /* unused parameter */
return E_NOTIMPL;
}
static HRESULT WINAPI DummyDirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext)
{
(void)lpDSEnumCallback; /* unused parameter */
(void)lpContext; /* unused parameter */
return E_NOTIMPL;
}
static HRESULT WINAPI DummyDirectSoundEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext)
{
(void)lpDSEnumCallback; /* unused parameter */
(void)lpContext; /* unused parameter */
return E_NOTIMPL;
}
static HRESULT WINAPI DummyDirectSoundCaptureCreate(LPGUID lpcGUID, LPDIRECTSOUNDCAPTURE *lplpDSC, LPUNKNOWN pUnkOuter)
{
(void)lpcGUID; /* unused parameter */
(void)lplpDSC; /* unused parameter */
(void)pUnkOuter; /* unused parameter */
return E_NOTIMPL;
}
static HRESULT WINAPI DummyDirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpDSCEnumCallback, LPVOID lpContext)
{
(void)lpDSCEnumCallback; /* unused parameter */
(void)lpContext; /* unused parameter */
return E_NOTIMPL;
}
static HRESULT WINAPI DummyDirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpDSCEnumCallback, LPVOID lpContext)
{
(void)lpDSCEnumCallback; /* unused parameter */
(void)lpContext; /* unused parameter */
return E_NOTIMPL;
}
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
static HRESULT WINAPI DummyDirectSoundFullDuplexCreate8(
LPCGUID pcGuidCaptureDevice,
LPCGUID pcGuidRenderDevice,
LPCDSCBUFFERDESC pcDSCBufferDesc,
LPCDSBUFFERDESC pcDSBufferDesc,
HWND hWnd,
DWORD dwLevel,
LPDIRECTSOUNDFULLDUPLEX * ppDSFD,
LPDIRECTSOUNDCAPTUREBUFFER8 * ppDSCBuffer8,
LPDIRECTSOUNDBUFFER8 * ppDSBuffer8,
LPUNKNOWN pUnkOuter)
{
(void)pcGuidCaptureDevice; /* unused parameter */
(void)pcGuidRenderDevice; /* unused parameter */
(void)pcDSCBufferDesc; /* unused parameter */
(void)pcDSBufferDesc; /* unused parameter */
(void)hWnd; /* unused parameter */
(void)dwLevel; /* unused parameter */
(void)ppDSFD; /* unused parameter */
(void)ppDSCBuffer8; /* unused parameter */
(void)ppDSBuffer8; /* unused parameter */
(void)pUnkOuter; /* unused parameter */
return E_NOTIMPL;
}
#endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */
void PaWinDs_InitializeDSoundEntryPoints(void)
{
paWinDsDSoundEntryPoints.hInstance_ = LoadLibraryA("dsound.dll");
if( paWinDsDSoundEntryPoints.hInstance_ != NULL )
{
paWinDsDSoundEntryPoints.DllGetClassObject =
(HRESULT (WINAPI *)(REFCLSID, REFIID , LPVOID *))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DllGetClassObject" );
if( paWinDsDSoundEntryPoints.DllGetClassObject == NULL )
paWinDsDSoundEntryPoints.DllGetClassObject = DummyDllGetClassObject;
paWinDsDSoundEntryPoints.DirectSoundCreate =
(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCreate" );
if( paWinDsDSoundEntryPoints.DirectSoundCreate == NULL )
paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate;
paWinDsDSoundEntryPoints.DirectSoundEnumerateW =
(HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateW" );
if( paWinDsDSoundEntryPoints.DirectSoundEnumerateW == NULL )
paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW;
paWinDsDSoundEntryPoints.DirectSoundEnumerateA =
(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateA" );
if( paWinDsDSoundEntryPoints.DirectSoundEnumerateA == NULL )
paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA;
paWinDsDSoundEntryPoints.DirectSoundCaptureCreate =
(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureCreate" );
if( paWinDsDSoundEntryPoints.DirectSoundCaptureCreate == NULL )
paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate;
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW =
(HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateW" );
if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW == NULL )
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW;
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA =
(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateA" );
if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA == NULL )
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA;
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 =
(HRESULT (WINAPI *)(LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN))
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundFullDuplexCreate" );
if( paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 == NULL )
paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = DummyDirectSoundFullDuplexCreate8;
#endif
}
else
{
DWORD errorCode = GetLastError(); // 126 (0x7E) == ERROR_MOD_NOT_FOUND
PA_DEBUG(("Couldn't load dsound.dll error code: %d \n",errorCode));
/* initialize with dummy entry points to make live easy when ds isn't present */
paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate;
paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW;
paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA;
paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate;
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW;
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA;
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = DummyDirectSoundFullDuplexCreate8;
#endif
}
}
void PaWinDs_TerminateDSoundEntryPoints(void)
{
if( paWinDsDSoundEntryPoints.hInstance_ != NULL )
{
/* ensure that we crash reliably if the entry points arent initialised */
paWinDsDSoundEntryPoints.DirectSoundCreate = 0;
paWinDsDSoundEntryPoints.DirectSoundEnumerateW = 0;
paWinDsDSoundEntryPoints.DirectSoundEnumerateA = 0;
paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = 0;
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = 0;
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = 0;
FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ );
paWinDsDSoundEntryPoints.hInstance_ = NULL;
}
}

View File

@ -1,106 +0,0 @@
/*
* Interface for dynamically loading directsound and providing a dummy
* implementation if it isn't present.
*
* Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi)
*
* For PortAudio Portable Real-Time Audio Library
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina
*
* 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 hostapi_src
*/
#ifndef INCLUDED_PA_DSOUND_DYNLINK_H
#define INCLUDED_PA_DSOUND_DYNLINK_H
/* on Borland compilers, WIN32 doesn't seem to be defined by default, which
breaks dsound.h. Adding the define here fixes the problem. - rossb. */
#ifdef __BORLANDC__
#if !defined(WIN32)
#define WIN32
#endif
#endif
/*
Use the earliest version of DX required, no need to polute the namespace
*/
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
#define DIRECTSOUND_VERSION 0x0800
#else
#define DIRECTSOUND_VERSION 0x0300
#endif
#include <dsound.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
typedef struct
{
HINSTANCE hInstance_;
HRESULT (WINAPI *DllGetClassObject)(REFCLSID , REFIID , LPVOID *);
HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
HRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
HRESULT (WINAPI *DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
HRESULT (WINAPI *DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);
HRESULT (WINAPI *DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
HRESULT (WINAPI *DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
HRESULT (WINAPI *DirectSoundFullDuplexCreate8)(
LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN );
#endif
}PaWinDsDSoundEntryPoints;
extern PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints;
void PaWinDs_InitializeDSoundEntryPoints(void);
void PaWinDs_TerminateDSoundEntryPoints(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* INCLUDED_PA_DSOUND_DYNLINK_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
/*
* recplay.c
* Phil Burk
* Minimal record and playback test.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#ifndef __STDC__
/* #include <getopt.h> */
#endif /* __STDC__ */
#include <fcntl.h>
#ifdef __STDC__
#include <string.h>
#else /* __STDC__ */
#include <strings.h>
#endif /* __STDC__ */
#include <sys/soundcard.h>
#define NUM_BYTES (64*1024)
#define BLOCK_SIZE (4*1024)
#define AUDIO "/dev/dsp"
char buffer[NUM_BYTES];
int audioDev = 0;
main (int argc, char *argv[])
{
int numLeft;
char *ptr;
int num;
int samplesize;
/********** RECORD ********************/
/* Open audio device. */
audioDev = open (AUDIO, O_RDONLY, 0);
if (audioDev == -1)
{
perror (AUDIO);
exit (-1);
}
/* Set to 16 bit samples. */
samplesize = 16;
ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
if (samplesize != 16)
{
perror("Unable to set the sample size.");
exit(-1);
}
/* Record in blocks */
printf("Begin recording.\n");
numLeft = NUM_BYTES;
ptr = buffer;
while( numLeft >= BLOCK_SIZE )
{
if ( (num = read (audioDev, ptr, BLOCK_SIZE)) < 0 )
{
perror (AUDIO);
exit (-1);
}
else
{
printf("Read %d bytes\n", num);
ptr += num;
numLeft -= num;
}
}
close( audioDev );
/********** PLAYBACK ********************/
/* Open audio device for writing. */
audioDev = open (AUDIO, O_WRONLY, 0);
if (audioDev == -1)
{
perror (AUDIO);
exit (-1);
}
/* Set to 16 bit samples. */
samplesize = 16;
ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
if (samplesize != 16)
{
perror("Unable to set the sample size.");
exit(-1);
}
/* Play in blocks */
printf("Begin playing.\n");
numLeft = NUM_BYTES;
ptr = buffer;
while( numLeft >= BLOCK_SIZE )
{
if ( (num = write (audioDev, ptr, BLOCK_SIZE)) < 0 )
{
perror (AUDIO);
exit (-1);
}
else
{
printf("Wrote %d bytes\n", num);
ptr += num;
numLeft -= num;
}
}
close( audioDev );
}

View File

@ -1 +0,0 @@
pa_hostapi_skeleton.c provides a starting point for implementing support for a new host API with PortAudio. The idea is that you copy it to a new directory inside /hostapi and start editing.

View File

@ -1,818 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library skeleton implementation
* demonstrates how to use the common functions to implement support
* for a host API
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 common_src
@brief Skeleton implementation of support for a host API.
This file is provided as a starting point for implementing support for
a new host API. It provides examples of how the common code can be used.
@note IMPLEMENT ME comments are used to indicate functionality
which much be customised for each implementation.
*/
#include <string.h> /* strlen() */
#include "pa_util.h"
#include "pa_allocation.h"
#include "pa_hostapi.h"
#include "pa_stream.h"
#include "pa_cpuload.h"
#include "pa_process.h"
/* prototypes for functions declared in this file */
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
#ifdef __cplusplus
}
#endif /* __cplusplus */
static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate );
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaStream** s,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate,
unsigned long framesPerBuffer,
PaStreamFlags streamFlags,
PaStreamCallback *streamCallback,
void *userData );
static PaError CloseStream( PaStream* stream );
static PaError StartStream( PaStream *stream );
static PaError StopStream( PaStream *stream );
static PaError AbortStream( PaStream *stream );
static PaError IsStreamStopped( PaStream *s );
static PaError IsStreamActive( PaStream *stream );
static PaTime GetStreamTime( PaStream *stream );
static double GetStreamCpuLoad( PaStream* stream );
static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
static signed long GetStreamReadAvailable( PaStream* stream );
static signed long GetStreamWriteAvailable( PaStream* stream );
/* IMPLEMENT ME: a macro like the following one should be used for reporting
host errors */
#define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \
PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )
/* PaSkeletonHostApiRepresentation - host api datastructure specific to this implementation */
typedef struct
{
PaUtilHostApiRepresentation inheritedHostApiRep;
PaUtilStreamInterface callbackStreamInterface;
PaUtilStreamInterface blockingStreamInterface;
PaUtilAllocationGroup *allocations;
/* implementation specific data goes here */
}
PaSkeletonHostApiRepresentation; /* IMPLEMENT ME: rename this */
PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
{
PaError result = paNoError;
int i, deviceCount;
PaSkeletonHostApiRepresentation *skeletonHostApi;
PaDeviceInfo *deviceInfoArray;
skeletonHostApi = (PaSkeletonHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaSkeletonHostApiRepresentation) );
if( !skeletonHostApi )
{
result = paInsufficientMemory;
goto error;
}
skeletonHostApi->allocations = PaUtil_CreateAllocationGroup();
if( !skeletonHostApi->allocations )
{
result = paInsufficientMemory;
goto error;
}
*hostApi = &skeletonHostApi->inheritedHostApiRep;
(*hostApi)->info.structVersion = 1;
(*hostApi)->info.type = paInDevelopment; /* IMPLEMENT ME: change to correct type id */
(*hostApi)->info.name = "skeleton implementation"; /* IMPLEMENT ME: change to correct name */
(*hostApi)->info.defaultInputDevice = paNoDevice; /* IMPLEMENT ME */
(*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */
(*hostApi)->info.deviceCount = 0;
deviceCount = 0; /* IMPLEMENT ME */
if( deviceCount > 0 )
{
(*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
skeletonHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount );
if( !(*hostApi)->deviceInfos )
{
result = paInsufficientMemory;
goto error;
}
/* allocate all device info structs in a contiguous block */
deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
skeletonHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount );
if( !deviceInfoArray )
{
result = paInsufficientMemory;
goto error;
}
for( i=0; i < deviceCount; ++i )
{
PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
deviceInfo->structVersion = 2;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = 0; /* IMPLEMENT ME: allocate block and copy name eg:
deviceName = (char*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, strlen(srcName) + 1 );
if( !deviceName )
{
result = paInsufficientMemory;
goto error;
}
strcpy( deviceName, srcName );
deviceInfo->name = deviceName;
*/
deviceInfo->maxInputChannels = 0; /* IMPLEMENT ME */
deviceInfo->maxOutputChannels = 0; /* IMPLEMENT ME */
deviceInfo->defaultLowInputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultLowOutputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultHighInputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultHighOutputLatency = 0.; /* IMPLEMENT ME */
deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */
(*hostApi)->deviceInfos[i] = deviceInfo;
++(*hostApi)->info.deviceCount;
}
}
(*hostApi)->Terminate = Terminate;
(*hostApi)->OpenStream = OpenStream;
(*hostApi)->IsFormatSupported = IsFormatSupported;
PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, GetStreamCpuLoad,
PaUtil_DummyRead, PaUtil_DummyWrite,
PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
PaUtil_InitializeStreamInterface( &skeletonHostApi->blockingStreamInterface, CloseStream, StartStream,
StopStream, AbortStream, IsStreamStopped, IsStreamActive,
GetStreamTime, PaUtil_DummyGetCpuLoad,
ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
return result;
error:
if( skeletonHostApi )
{
if( skeletonHostApi->allocations )
{
PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
}
PaUtil_FreeMemory( skeletonHostApi );
}
return result;
}
static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
{
PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
/*
IMPLEMENT ME:
- clean up any resources not handled by the allocation group
*/
if( skeletonHostApi->allocations )
{
PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
}
PaUtil_FreeMemory( skeletonHostApi );
}
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate )
{
int inputChannelCount, outputChannelCount;
PaSampleFormat inputSampleFormat, outputSampleFormat;
if( inputParameters )
{
inputChannelCount = inputParameters->channelCount;
inputSampleFormat = inputParameters->sampleFormat;
/* all standard sample formats are supported by the buffer adapter,
this implementation doesn't support any custom sample formats */
if( inputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
return paInvalidDevice;
/* check that input device can support inputChannelCount */
if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
return paInvalidChannelCount;
/* validate inputStreamInfo */
if( inputParameters->hostApiSpecificStreamInfo )
return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
}
else
{
inputChannelCount = 0;
}
if( outputParameters )
{
outputChannelCount = outputParameters->channelCount;
outputSampleFormat = outputParameters->sampleFormat;
/* all standard sample formats are supported by the buffer adapter,
this implementation doesn't support any custom sample formats */
if( outputSampleFormat & paCustomFormat )
return paSampleFormatNotSupported;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
return paInvalidDevice;
/* check that output device can support outputChannelCount */
if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
return paInvalidChannelCount;
/* validate outputStreamInfo */
if( outputParameters->hostApiSpecificStreamInfo )
return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
}
else
{
outputChannelCount = 0;
}
/*
IMPLEMENT ME:
- if a full duplex stream is requested, check that the combination
of input and output parameters is supported if necessary
- check that the device supports sampleRate
Because the buffer adapter handles conversion between all standard
sample formats, the following checks are only required if paCustomFormat
is implemented, or under some other unusual conditions.
- check that input device can support inputSampleFormat, or that
we have the capability to convert from inputSampleFormat to
a native format
- check that output device can support outputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
*/
/* suppress unused variable warnings */
(void) sampleRate;
return paFormatIsSupported;
}
/* PaSkeletonStream - a stream data structure specifically for this implementation */
typedef struct PaSkeletonStream
{ /* IMPLEMENT ME: rename this */
PaUtilStreamRepresentation streamRepresentation;
PaUtilCpuLoadMeasurer cpuLoadMeasurer;
PaUtilBufferProcessor bufferProcessor;
/* IMPLEMENT ME:
- implementation specific data goes here
*/
unsigned long framesPerHostCallback; /* just an example */
}
PaSkeletonStream;
/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaStream** s,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate,
unsigned long framesPerBuffer,
PaStreamFlags streamFlags,
PaStreamCallback *streamCallback,
void *userData )
{
PaError result = paNoError;
PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
PaSkeletonStream *stream = 0;
unsigned long framesPerHostBuffer = framesPerBuffer; /* these may not be equivalent for all implementations */
int inputChannelCount, outputChannelCount;
PaSampleFormat inputSampleFormat, outputSampleFormat;
PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
if( inputParameters )
{
inputChannelCount = inputParameters->channelCount;
inputSampleFormat = inputParameters->sampleFormat;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
return paInvalidDevice;
/* check that input device can support inputChannelCount */
if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
return paInvalidChannelCount;
/* validate inputStreamInfo */
if( inputParameters->hostApiSpecificStreamInfo )
return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
/* IMPLEMENT ME - establish which host formats are available */
hostInputSampleFormat =
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
}
else
{
inputChannelCount = 0;
inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */
}
if( outputParameters )
{
outputChannelCount = outputParameters->channelCount;
outputSampleFormat = outputParameters->sampleFormat;
/* unless alternate device specification is supported, reject the use of
paUseHostApiSpecificDeviceSpecification */
if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
return paInvalidDevice;
/* check that output device can support inputChannelCount */
if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
return paInvalidChannelCount;
/* validate outputStreamInfo */
if( outputParameters->hostApiSpecificStreamInfo )
return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
/* IMPLEMENT ME - establish which host formats are available */
hostOutputSampleFormat =
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
}
else
{
outputChannelCount = 0;
outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */
}
/*
IMPLEMENT ME:
( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? )
- check that input device can support inputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
- check that output device can support outputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
- if a full duplex stream is requested, check that the combination
of input and output parameters is supported
- check that the device supports sampleRate
- alter sampleRate to a close allowable rate if possible / necessary
- validate suggestedInputLatency and suggestedOutputLatency parameters,
use default values where necessary
*/
/* validate platform specific flags */
if( (streamFlags & paPlatformSpecificFlags) != 0 )
return paInvalidFlag; /* unexpected platform specific flag */
stream = (PaSkeletonStream*)PaUtil_AllocateMemory( sizeof(PaSkeletonStream) );
if( !stream )
{
result = paInsufficientMemory;
goto error;
}
if( streamCallback )
{
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
&skeletonHostApi->callbackStreamInterface, streamCallback, userData );
}
else
{
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
&skeletonHostApi->blockingStreamInterface, streamCallback, userData );
}
PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
/* we assume a fixed host buffer size in this example, but the buffer processor
can also support bounded and unknown host buffer sizes by passing
paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of
paUtilFixedHostBufferSize below. */
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
inputChannelCount, inputSampleFormat, hostInputSampleFormat,
outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
sampleRate, streamFlags, framesPerBuffer,
framesPerHostBuffer, paUtilFixedHostBufferSize,
streamCallback, userData );
if( result != paNoError )
goto error;
/*
IMPLEMENT ME: initialise the following fields with estimated or actual
values.
*/
stream->streamRepresentation.streamInfo.inputLatency =
(PaTime)PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) / sampleRate; /* inputLatency is specified in _seconds_ */
stream->streamRepresentation.streamInfo.outputLatency =
(PaTime)PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) / sampleRate; /* outputLatency is specified in _seconds_ */
stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
/*
IMPLEMENT ME:
- additional stream setup + opening
*/
stream->framesPerHostCallback = framesPerHostBuffer;
*s = (PaStream*)stream;
return result;
error:
if( stream )
PaUtil_FreeMemory( stream );
return result;
}
/*
ExampleHostProcessingLoop() illustrates the kind of processing which may
occur in a host implementation.
*/
static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData )
{
PaSkeletonStream *stream = (PaSkeletonStream*)userData;
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */
int callbackResult;
unsigned long framesProcessed;
PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
/*
IMPLEMENT ME:
- generate timing information
- handle buffer slips
*/
/*
If you need to byte swap or shift inputBuffer to convert it into a
portaudio format, do it here.
*/
PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ );
/*
depending on whether the host buffers are interleaved, non-interleaved
or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),
PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.
*/
PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
0, /* first channel of inputBuffer is channel 0 */
inputBuffer,
0 ); /* 0 - use inputChannelCount passed to init buffer processor */
PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,
0, /* first channel of outputBuffer is channel 0 */
outputBuffer,
0 ); /* 0 - use outputChannelCount passed to init buffer processor */
/* you must pass a valid value of callback result to PaUtil_EndBufferProcessing()
in general you would pass paContinue for normal operation, and
paComplete to drain the buffer processor's internal output buffer.
You can check whether the buffer processor's output buffer is empty
using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor )
*/
callbackResult = paContinue;
framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
/*
If you need to byte swap or shift outputBuffer to convert it to
host format, do it here.
*/
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
if( callbackResult == paContinue )
{
/* nothing special to do */
}
else if( callbackResult == paAbort )
{
/* IMPLEMENT ME - finish playback immediately */
/* once finished, call the finished callback */
if( stream->streamRepresentation.streamFinishedCallback != 0 )
stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
}
else
{
/* User callback has asked us to stop with paComplete or other non-zero value */
/* IMPLEMENT ME - finish playback once currently queued audio has completed */
/* once finished, call the finished callback */
if( stream->streamRepresentation.streamFinishedCallback != 0 )
stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
}
}
/*
When CloseStream() is called, the multi-api layer ensures that
the stream has already been stopped or aborted.
*/
static PaError CloseStream( PaStream* s )
{
PaError result = paNoError;
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/*
IMPLEMENT ME:
- additional stream closing + cleanup
*/
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
PaUtil_FreeMemory( stream );
return result;
}
static PaError StartStream( PaStream *s )
{
PaError result = paNoError;
PaSkeletonStream *stream = (PaSkeletonStream*)s;
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
/* IMPLEMENT ME, see portaudio.h for required behavior */
/* suppress unused function warning. the code in ExampleHostProcessingLoop or
something similar should be implemented to feed samples to and from the
host after StartStream() is called.
*/
(void) ExampleHostProcessingLoop;
return result;
}
static PaError StopStream( PaStream *s )
{
PaError result = paNoError;
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior */
return result;
}
static PaError AbortStream( PaStream *s )
{
PaError result = paNoError;
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior */
return result;
}
static PaError IsStreamStopped( PaStream *s )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior */
return 0;
}
static PaError IsStreamActive( PaStream *s )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior */
return 0;
}
static PaTime GetStreamTime( PaStream *s )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return 0;
}
static double GetStreamCpuLoad( PaStream* s )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
}
/*
As separate stream interfaces are used for blocking and callback
streams, the following functions can be guaranteed to only be called
for blocking streams.
*/
static PaError ReadStream( PaStream* s,
void *buffer,
unsigned long frames )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) buffer;
(void) frames;
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return paNoError;
}
static PaError WriteStream( PaStream* s,
const void *buffer,
unsigned long frames )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) buffer;
(void) frames;
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return paNoError;
}
static signed long GetStreamReadAvailable( PaStream* s )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return 0;
}
static signed long GetStreamWriteAvailable( PaStream* s )
{
PaSkeletonStream *stream = (PaSkeletonStream*)s;
/* suppress unused variable warnings */
(void) stream;
/* IMPLEMENT ME, see portaudio.h for required behavior*/
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,620 +0,0 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 7.00.0499 */
/* Compiler settings for endpointvolume.idl:
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//@@MIDL_FILE_HEADING( )
#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 500
#endif
/* verify that the <rpcsal.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCSAL_H_VERSION__
#define __REQUIRED_RPCSAL_H_VERSION__ 100
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
#ifndef __endpointvolume_h__
#define __endpointvolume_h__
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
/* Forward Declarations */
#ifndef __IAudioEndpointVolumeCallback_FWD_DEFINED__
#define __IAudioEndpointVolumeCallback_FWD_DEFINED__
typedef interface IAudioEndpointVolumeCallback IAudioEndpointVolumeCallback;
#endif /* __IAudioEndpointVolumeCallback_FWD_DEFINED__ */
#ifndef __IAudioEndpointVolume_FWD_DEFINED__
#define __IAudioEndpointVolume_FWD_DEFINED__
typedef interface IAudioEndpointVolume IAudioEndpointVolume;
#endif /* __IAudioEndpointVolume_FWD_DEFINED__ */
#ifndef __IAudioMeterInformation_FWD_DEFINED__
#define __IAudioMeterInformation_FWD_DEFINED__
typedef interface IAudioMeterInformation IAudioMeterInformation;
#endif /* __IAudioMeterInformation_FWD_DEFINED__ */
/* header files for imported files */
#include "unknwn.h"
#include "devicetopology.h"
#ifdef __cplusplus
extern "C"{
#endif
/* interface __MIDL_itf_endpointvolume_0000_0000 */
/* [local] */
typedef struct AUDIO_VOLUME_NOTIFICATION_DATA
{
GUID guidEventContext;
BOOL bMuted;
float fMasterVolume;
UINT nChannels;
float afChannelVolumes[ 1 ];
} AUDIO_VOLUME_NOTIFICATION_DATA;
typedef struct AUDIO_VOLUME_NOTIFICATION_DATA *PAUDIO_VOLUME_NOTIFICATION_DATA;
#define ENDPOINT_HARDWARE_SUPPORT_VOLUME 0x00000001
#define ENDPOINT_HARDWARE_SUPPORT_MUTE 0x00000002
#define ENDPOINT_HARDWARE_SUPPORT_METER 0x00000004
extern RPC_IF_HANDLE __MIDL_itf_endpointvolume_0000_0000_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_endpointvolume_0000_0000_v0_0_s_ifspec;
#ifndef __IAudioEndpointVolumeCallback_INTERFACE_DEFINED__
#define __IAudioEndpointVolumeCallback_INTERFACE_DEFINED__
/* interface IAudioEndpointVolumeCallback */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IAudioEndpointVolumeCallback;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("657804FA-D6AD-4496-8A60-352752AF4F89")
IAudioEndpointVolumeCallback : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE OnNotify(
PAUDIO_VOLUME_NOTIFICATION_DATA pNotify) = 0;
};
#else /* C style interface */
typedef struct IAudioEndpointVolumeCallbackVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IAudioEndpointVolumeCallback * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IAudioEndpointVolumeCallback * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IAudioEndpointVolumeCallback * This);
HRESULT ( STDMETHODCALLTYPE *OnNotify )(
IAudioEndpointVolumeCallback * This,
PAUDIO_VOLUME_NOTIFICATION_DATA pNotify);
END_INTERFACE
} IAudioEndpointVolumeCallbackVtbl;
interface IAudioEndpointVolumeCallback
{
CONST_VTBL struct IAudioEndpointVolumeCallbackVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IAudioEndpointVolumeCallback_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IAudioEndpointVolumeCallback_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IAudioEndpointVolumeCallback_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IAudioEndpointVolumeCallback_OnNotify(This,pNotify) \
( (This)->lpVtbl -> OnNotify(This,pNotify) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IAudioEndpointVolumeCallback_INTERFACE_DEFINED__ */
#ifndef __IAudioEndpointVolume_INTERFACE_DEFINED__
#define __IAudioEndpointVolume_INTERFACE_DEFINED__
/* interface IAudioEndpointVolume */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IAudioEndpointVolume;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("5CDF2C82-841E-4546-9722-0CF74078229A")
IAudioEndpointVolume : public IUnknown
{
public:
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE RegisterControlChangeNotify(
/* [in] */
__in IAudioEndpointVolumeCallback *pNotify) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UnregisterControlChangeNotify(
/* [in] */
__in IAudioEndpointVolumeCallback *pNotify) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelCount(
/* [out] */
__out UINT *pnChannelCount) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevel(
/* [in] */
__in float fLevelDB,
/* [unique][in] */ LPCGUID pguidEventContext) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevelScalar(
/* [in] */
__in float fLevel,
/* [unique][in] */ LPCGUID pguidEventContext) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevel(
/* [out] */
__out float *pfLevelDB) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevelScalar(
/* [out] */
__out float *pfLevel) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetChannelVolumeLevel(
/* [in] */
__in UINT nChannel,
float fLevelDB,
/* [unique][in] */ LPCGUID pguidEventContext) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetChannelVolumeLevelScalar(
/* [in] */
__in UINT nChannel,
float fLevel,
/* [unique][in] */ LPCGUID pguidEventContext) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelVolumeLevel(
/* [in] */
__in UINT nChannel,
/* [out] */
__out float *pfLevelDB) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelVolumeLevelScalar(
/* [in] */
__in UINT nChannel,
/* [out] */
__out float *pfLevel) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMute(
/* [in] */
__in BOOL bMute,
/* [unique][in] */ LPCGUID pguidEventContext) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMute(
/* [out] */
__out BOOL *pbMute) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVolumeStepInfo(
/* [out] */
__out UINT *pnStep,
/* [out] */
__out UINT *pnStepCount) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VolumeStepUp(
/* [unique][in] */ LPCGUID pguidEventContext) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VolumeStepDown(
/* [unique][in] */ LPCGUID pguidEventContext) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE QueryHardwareSupport(
/* [out] */
__out DWORD *pdwHardwareSupportMask) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVolumeRange(
/* [out] */
__out float *pflVolumeMindB,
/* [out] */
__out float *pflVolumeMaxdB,
/* [out] */
__out float *pflVolumeIncrementdB) = 0;
};
#else /* C style interface */
typedef struct IAudioEndpointVolumeVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IAudioEndpointVolume * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IAudioEndpointVolume * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IAudioEndpointVolume * This);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *RegisterControlChangeNotify )(
IAudioEndpointVolume * This,
/* [in] */
__in IAudioEndpointVolumeCallback *pNotify);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *UnregisterControlChangeNotify )(
IAudioEndpointVolume * This,
/* [in] */
__in IAudioEndpointVolumeCallback *pNotify);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetChannelCount )(
IAudioEndpointVolume * This,
/* [out] */
__out UINT *pnChannelCount);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMasterVolumeLevel )(
IAudioEndpointVolume * This,
/* [in] */
__in float fLevelDB,
/* [unique][in] */ LPCGUID pguidEventContext);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMasterVolumeLevelScalar )(
IAudioEndpointVolume * This,
/* [in] */
__in float fLevel,
/* [unique][in] */ LPCGUID pguidEventContext);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMasterVolumeLevel )(
IAudioEndpointVolume * This,
/* [out] */
__out float *pfLevelDB);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMasterVolumeLevelScalar )(
IAudioEndpointVolume * This,
/* [out] */
__out float *pfLevel);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetChannelVolumeLevel )(
IAudioEndpointVolume * This,
/* [in] */
__in UINT nChannel,
float fLevelDB,
/* [unique][in] */ LPCGUID pguidEventContext);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetChannelVolumeLevelScalar )(
IAudioEndpointVolume * This,
/* [in] */
__in UINT nChannel,
float fLevel,
/* [unique][in] */ LPCGUID pguidEventContext);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetChannelVolumeLevel )(
IAudioEndpointVolume * This,
/* [in] */
__in UINT nChannel,
/* [out] */
__out float *pfLevelDB);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetChannelVolumeLevelScalar )(
IAudioEndpointVolume * This,
/* [in] */
__in UINT nChannel,
/* [out] */
__out float *pfLevel);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetMute )(
IAudioEndpointVolume * This,
/* [in] */
__in BOOL bMute,
/* [unique][in] */ LPCGUID pguidEventContext);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMute )(
IAudioEndpointVolume * This,
/* [out] */
__out BOOL *pbMute);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetVolumeStepInfo )(
IAudioEndpointVolume * This,
/* [out] */
__out UINT *pnStep,
/* [out] */
__out UINT *pnStepCount);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *VolumeStepUp )(
IAudioEndpointVolume * This,
/* [unique][in] */ LPCGUID pguidEventContext);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *VolumeStepDown )(
IAudioEndpointVolume * This,
/* [unique][in] */ LPCGUID pguidEventContext);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *QueryHardwareSupport )(
IAudioEndpointVolume * This,
/* [out] */
__out DWORD *pdwHardwareSupportMask);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetVolumeRange )(
IAudioEndpointVolume * This,
/* [out] */
__out float *pflVolumeMindB,
/* [out] */
__out float *pflVolumeMaxdB,
/* [out] */
__out float *pflVolumeIncrementdB);
END_INTERFACE
} IAudioEndpointVolumeVtbl;
interface IAudioEndpointVolume
{
CONST_VTBL struct IAudioEndpointVolumeVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IAudioEndpointVolume_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IAudioEndpointVolume_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IAudioEndpointVolume_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IAudioEndpointVolume_RegisterControlChangeNotify(This,pNotify) \
( (This)->lpVtbl -> RegisterControlChangeNotify(This,pNotify) )
#define IAudioEndpointVolume_UnregisterControlChangeNotify(This,pNotify) \
( (This)->lpVtbl -> UnregisterControlChangeNotify(This,pNotify) )
#define IAudioEndpointVolume_GetChannelCount(This,pnChannelCount) \
( (This)->lpVtbl -> GetChannelCount(This,pnChannelCount) )
#define IAudioEndpointVolume_SetMasterVolumeLevel(This,fLevelDB,pguidEventContext) \
( (This)->lpVtbl -> SetMasterVolumeLevel(This,fLevelDB,pguidEventContext) )
#define IAudioEndpointVolume_SetMasterVolumeLevelScalar(This,fLevel,pguidEventContext) \
( (This)->lpVtbl -> SetMasterVolumeLevelScalar(This,fLevel,pguidEventContext) )
#define IAudioEndpointVolume_GetMasterVolumeLevel(This,pfLevelDB) \
( (This)->lpVtbl -> GetMasterVolumeLevel(This,pfLevelDB) )
#define IAudioEndpointVolume_GetMasterVolumeLevelScalar(This,pfLevel) \
( (This)->lpVtbl -> GetMasterVolumeLevelScalar(This,pfLevel) )
#define IAudioEndpointVolume_SetChannelVolumeLevel(This,nChannel,fLevelDB,pguidEventContext) \
( (This)->lpVtbl -> SetChannelVolumeLevel(This,nChannel,fLevelDB,pguidEventContext) )
#define IAudioEndpointVolume_SetChannelVolumeLevelScalar(This,nChannel,fLevel,pguidEventContext) \
( (This)->lpVtbl -> SetChannelVolumeLevelScalar(This,nChannel,fLevel,pguidEventContext) )
#define IAudioEndpointVolume_GetChannelVolumeLevel(This,nChannel,pfLevelDB) \
( (This)->lpVtbl -> GetChannelVolumeLevel(This,nChannel,pfLevelDB) )
#define IAudioEndpointVolume_GetChannelVolumeLevelScalar(This,nChannel,pfLevel) \
( (This)->lpVtbl -> GetChannelVolumeLevelScalar(This,nChannel,pfLevel) )
#define IAudioEndpointVolume_SetMute(This,bMute,pguidEventContext) \
( (This)->lpVtbl -> SetMute(This,bMute,pguidEventContext) )
#define IAudioEndpointVolume_GetMute(This,pbMute) \
( (This)->lpVtbl -> GetMute(This,pbMute) )
#define IAudioEndpointVolume_GetVolumeStepInfo(This,pnStep,pnStepCount) \
( (This)->lpVtbl -> GetVolumeStepInfo(This,pnStep,pnStepCount) )
#define IAudioEndpointVolume_VolumeStepUp(This,pguidEventContext) \
( (This)->lpVtbl -> VolumeStepUp(This,pguidEventContext) )
#define IAudioEndpointVolume_VolumeStepDown(This,pguidEventContext) \
( (This)->lpVtbl -> VolumeStepDown(This,pguidEventContext) )
#define IAudioEndpointVolume_QueryHardwareSupport(This,pdwHardwareSupportMask) \
( (This)->lpVtbl -> QueryHardwareSupport(This,pdwHardwareSupportMask) )
#define IAudioEndpointVolume_GetVolumeRange(This,pflVolumeMindB,pflVolumeMaxdB,pflVolumeIncrementdB) \
( (This)->lpVtbl -> GetVolumeRange(This,pflVolumeMindB,pflVolumeMaxdB,pflVolumeIncrementdB) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IAudioEndpointVolume_INTERFACE_DEFINED__ */
#ifndef __IAudioMeterInformation_INTERFACE_DEFINED__
#define __IAudioMeterInformation_INTERFACE_DEFINED__
/* interface IAudioMeterInformation */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IAudioMeterInformation;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("C02216F6-8C67-4B5B-9D00-D008E73E0064")
IAudioMeterInformation : public IUnknown
{
public:
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPeakValue(
/* [out] */ float *pfPeak) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMeteringChannelCount(
/* [out] */
__out UINT *pnChannelCount) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelsPeakValues(
/* [in] */ UINT32 u32ChannelCount,
/* [size_is][out] */ float *afPeakValues) = 0;
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE QueryHardwareSupport(
/* [out] */
__out DWORD *pdwHardwareSupportMask) = 0;
};
#else /* C style interface */
typedef struct IAudioMeterInformationVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IAudioMeterInformation * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IAudioMeterInformation * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IAudioMeterInformation * This);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPeakValue )(
IAudioMeterInformation * This,
/* [out] */ float *pfPeak);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMeteringChannelCount )(
IAudioMeterInformation * This,
/* [out] */
__out UINT *pnChannelCount);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetChannelsPeakValues )(
IAudioMeterInformation * This,
/* [in] */ UINT32 u32ChannelCount,
/* [size_is][out] */ float *afPeakValues);
/* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *QueryHardwareSupport )(
IAudioMeterInformation * This,
/* [out] */
__out DWORD *pdwHardwareSupportMask);
END_INTERFACE
} IAudioMeterInformationVtbl;
interface IAudioMeterInformation
{
CONST_VTBL struct IAudioMeterInformationVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IAudioMeterInformation_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IAudioMeterInformation_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IAudioMeterInformation_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IAudioMeterInformation_GetPeakValue(This,pfPeak) \
( (This)->lpVtbl -> GetPeakValue(This,pfPeak) )
#define IAudioMeterInformation_GetMeteringChannelCount(This,pnChannelCount) \
( (This)->lpVtbl -> GetMeteringChannelCount(This,pnChannelCount) )
#define IAudioMeterInformation_GetChannelsPeakValues(This,u32ChannelCount,afPeakValues) \
( (This)->lpVtbl -> GetChannelsPeakValues(This,u32ChannelCount,afPeakValues) )
#define IAudioMeterInformation_QueryHardwareSupport(This,pdwHardwareSupportMask) \
( (This)->lpVtbl -> QueryHardwareSupport(This,pdwHardwareSupportMask) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IAudioMeterInformation_INTERFACE_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,255 +0,0 @@
#pragma once
#if __GNUC__ >=3
#pragma GCC system_header
#endif
#ifndef DEFINE_API_PKEY
#include <propkey.h>
#endif
#include <FunctionDiscoveryKeys_devpkey.h>
// FMTID_FD = {904b03a2-471d-423c-a584-f3483238a146}
DEFINE_GUID(FMTID_FD, 0x904b03a2, 0x471d, 0x423c, 0xa5, 0x84, 0xf3, 0x48, 0x32, 0x38, 0xa1, 0x46);
DEFINE_API_PKEY(PKEY_FD_Visibility, VisibilityFlags, 0x904b03a2, 0x471d, 0x423c, 0xa5, 0x84, 0xf3, 0x48, 0x32, 0x38, 0xa1, 0x46, 0x00000001); // VT_UINT
#define FD_Visibility_Default 0
#define FD_Visibility_Hidden 1
// FMTID_Device = {78C34FC8-104A-4aca-9EA4-524D52996E57}
DEFINE_GUID(FMTID_Device, 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57);
DEFINE_API_PKEY(PKEY_Device_NotPresent, DeviceNotPresent , 0x904b03a2, 0x471d, 0x423c, 0xa5, 0x84, 0xf3, 0x48, 0x32, 0x38, 0xa1, 0x46, 0x00000002); // VT_UINT
DEFINE_API_PKEY(PKEY_Device_QueueSize, DeviceQueueSize , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00000024); // VT_UI4
DEFINE_API_PKEY(PKEY_Device_Status, DeviceStatus , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00000025); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_Device_Comment, DeviceComment , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00000026); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_Device_Model, DeviceModel , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00000027); // VT_LPWSTR
// Name: System.Device.BIOSVersion -- PKEY_Device_BIOSVersion
// Type: String -- VT_LPWSTR (For variants: VT_BSTR) Legacy code may treat this as VT_BSTR.
// FormatID: EAEE7F1D-6A33-44D1-9441-5F46DEF23198, 9
DEFINE_PROPERTYKEY(PKEY_Device_BIOSVersion, 0xEAEE7F1D, 0x6A33, 0x44D1, 0x94, 0x41, 0x5F, 0x46, 0xDE, 0xF2, 0x31, 0x98, 9);
DEFINE_API_PKEY(PKEY_Write_Time, WriteTime , 0xf53b7e1c, 0x77e0, 0x4450, 0x8c, 0x5f, 0xa7, 0x6c, 0xc7, 0xfd, 0xe0, 0x58, 0x00000100); // VT_FILETIME
#ifdef FD_XP
DEFINE_API_PKEY(PKEY_Device_InstanceId, DeviceInstanceId , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00000100); // VT_LPWSTR
#endif
DEFINE_API_PKEY(PKEY_Device_Interface, DeviceInterface , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00000101); // VT_CLSID
DEFINE_API_PKEY(PKEY_ExposedIIDs, ExposedIIDs , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00003002); // VT_VECTOR | VT_CLSID
DEFINE_API_PKEY(PKEY_ExposedCLSIDs, ExposedCLSIDs , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00003003); // VT_VECTOR | VT_CLSID
DEFINE_API_PKEY(PKEY_InstanceValidatorClsid,InstanceValidator , 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x00003004); // VT_CLSID
// FMTID_WSD = {92506491-FF95-4724-A05A-5B81885A7C92}
DEFINE_GUID(FMTID_WSD, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92);
DEFINE_API_PKEY(PKEY_WSD_AddressURI, WSD_AddressURI, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00001000); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_WSD_Types, WSD_Types, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00001001); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_WSD_Scopes, WSD_Scopes, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00001002); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_WSD_MetadataVersion, WSD_MetadataVersion, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00001003); //VT_UI8
DEFINE_API_PKEY(PKEY_WSD_AppSeqInstanceID, WSD_AppSeqInstanceID, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00001004); // VT_UI8
DEFINE_API_PKEY(PKEY_WSD_AppSeqSessionID, WSD_AppSeqSessionID, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00001005); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_WSD_AppSeqMessageNumber, WSD_AppSeqMessageNumber, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00001006); // VT_UI8
DEFINE_API_PKEY(PKEY_WSD_XAddrs, WSD_XAddrs, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00002000); // VT_LPWSTR or VT_VECTOR | VT_LPWSTR
DEFINE_API_PKEY(PKEY_WSD_MetadataClean, WSD_MetadataClean, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00000001); // VT_BOOL
DEFINE_API_PKEY(PKEY_WSD_ServiceInfo, WSD_ServiceInfo, 0x92506491, 0xFF95, 0x4724, 0xA0, 0x5A, 0x5B, 0x81, 0x88, 0x5A, 0x7C, 0x92, 0x00000002); // VT_VECTOR|VT_VARIANT (variants are VT_UNKNOWN)
DEFINE_API_PKEY(PKEY_PUBSVCS_TYPE, PUBSVCS_TYPE, 0xF1B88AD3, 0x109C, 0x4FD2, 0xBA, 0x3F, 0x53, 0x5A, 0x76, 0x5F, 0x82, 0xF4, 0x00005001); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_PUBSVCS_SCOPE, PUBSVCS_SCOPE, 0x2AE2B567, 0xEECB, 0x4A3E, 0xB7, 0x53, 0x54, 0xC7, 0x25, 0x49, 0x43, 0x66, 0x00005002); // VT_LPWSTR | VT_VECTOR
DEFINE_API_PKEY(PKEY_PUBSVCS_METADATA, PUBSVCS_METADATA, 0x63C6D5B8, 0xF73A, 0x4ACA, 0x96, 0x7E, 0x0C, 0xC7, 0x87, 0xE0, 0xB5, 0x59, 0x00005003); // VT_LPWSTR
DEFINE_API_PKEY(PKEY_PUBSVCS_METADATA_VERSION, PUBSVCS_METADATA_VERSION, 0xC0C96C15, 0x1823, 0x4E5B, 0x93, 0x48, 0xE8, 0x25, 0x19, 0x92, 0x3F, 0x04, 0x00005004); // VT_UI8
DEFINE_API_PKEY(PKEY_PUBSVCS_NETWORK_PROFILES_ALLOWED, PUBSVCS_NETWORK_PROFILES_ALLOWED, 0x63C6D5B8, 0xF73A, 0x4ACA, 0x96, 0x7E, 0x0C, 0xC7, 0x87, 0xE0, 0xB5, 0x59, 0x00005005); // VT_VECTOR | VT_LPWSTR
DEFINE_API_PKEY(PKEY_PUBSVCS_NETWORK_PROFILES_DENIED, PUBSVCS_NETWORK_PROFILES_DENIED, 0x63C6D5B8, 0xF73A, 0x4ACA, 0x96, 0x7E, 0x0C, 0xC7, 0x87, 0xE0, 0xB5, 0x59, 0x00005006); // VT_VECTOR | VT_LPWSTR
DEFINE_API_PKEY(PKEY_PUBSVCS_NETWORK_PROFILES_DEFAULT, PUBSVCS_NETWORK_PROFILES_DEFAULT, 0x63C6D5B8, 0xF73A, 0x4ACA, 0x96, 0x7E, 0x0C, 0xC7, 0x87, 0xE0, 0xB5, 0x59, 0x00005007); // VT_BOOL
// FMTID_PNPX = {656A3BB3-ECC0-43FD-8477-4AE0404A96CD}
DEFINE_GUID(FMTID_PNPX, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD);
// from Discovery messages
DEFINE_PROPERTYKEY(PKEY_PNPX_GlobalIdentity, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001000); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_Types, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001001); // VT_LPWSTR | VT_VECTOR
DEFINE_PROPERTYKEY(PKEY_PNPX_Scopes, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001002); // VT_LPWSTR | VT_VECTOR
DEFINE_PROPERTYKEY(PKEY_PNPX_XAddrs, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001003); // VT_LPWSTR | VT_VECTOR
DEFINE_PROPERTYKEY(PKEY_PNPX_MetadataVersion, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001004); // VT_UI8
DEFINE_PROPERTYKEY(PKEY_PNPX_ID, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001005); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_RootProxy, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001006); // VT_BOOL
// for Directed Discovery
DEFINE_PROPERTYKEY(PKEY_PNPX_RemoteAddress, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00001006); // VT_LPWSTR
// from ThisModel metadata
DEFINE_PROPERTYKEY(PKEY_PNPX_Manufacturer, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00002000); // VT_LPWSTR (localizable)
DEFINE_PROPERTYKEY(PKEY_PNPX_ManufacturerUrl, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00002001); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_ModelName, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00002002); // VT_LPWSTR (localizable)
DEFINE_PROPERTYKEY(PKEY_PNPX_ModelNumber, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00002003); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_ModelUrl, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00002004); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_Upc, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00002005); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_PresentationUrl, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00002006); // VT_LPWSTR
// from ThisDevice metadata
DEFINE_PROPERTYKEY(PKEY_PNPX_FriendlyName, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003000); // VT_LPWSTR (localizable)
DEFINE_PROPERTYKEY(PKEY_PNPX_FirmwareVersion, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003001); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_SerialNumber, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003002); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_DeviceCategory, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003004); // VT_LPWSTR | VT_VECTOR
// DeviceCategory values
#define PNPX_DEVICECATEGORY_COMPUTER L"Computers"
#define PNPX_DEVICECATEGORY_INPUTDEVICE L"Input"
#define PNPX_DEVICECATEGORY_PRINTER L"Printers"
#define PNPX_DEVICECATEGORY_SCANNER L"Scanners"
#define PNPX_DEVICECATEGORY_FAX L"FAX"
#define PNPX_DEVICECATEGORY_MFP L"MFP"
#define PNPX_DEVICECATEGORY_CAMERA L"Cameras"
#define PNPX_DEVICECATEGORY_STORAGE L"Storage"
#define PNPX_DEVICECATEGORY_NETWORK_INFRASTRUCTURE L"NetworkInfrastructure"
#define PNPX_DEVICECATEGORY_DISPLAYS L"Displays"
#define PNPX_DEVICECATEGORY_MULTIMEDIA_DEVICE L"MediaDevices"
#define PNPX_DEVICECATEGORY_GAMING_DEVICE L"Gaming"
#define PNPX_DEVICECATEGORY_TELEPHONE L"Phones"
#define PNPX_DEVICECATEGORY_HOME_AUTOMATION_SYSTEM L"HomeAutomation"
#define PNPX_DEVICECATEGORY_HOME_SECURITY_SYSTEM L"HomeSecurity"
#define PNPX_DEVICECATEGORY_OTHER L"Other"
DEFINE_PROPERTYKEY(PKEY_PNPX_DeviceCategory_Desc, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003005); // VT_LPWSTR | VT_VECTOR
DEFINE_PROPERTYKEY(PKEY_PNPX_PhysicalAddress, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003006); // VT_UI1 | VT_VECTOR
DEFINE_PROPERTYKEY(PKEY_PNPX_NetworkInterfaceLuid, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003007); // VT_UI8
DEFINE_PROPERTYKEY(PKEY_PNPX_NetworkInterfaceGuid, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003008); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_IpAddress, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00003009); // VT_LPWSTR | VT_VECTOR
// from Relationship metadata
DEFINE_PROPERTYKEY(PKEY_PNPX_ServiceAddress, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00004000); // VT_LPWSTR | VT_VECTOR
DEFINE_PROPERTYKEY(PKEY_PNPX_ServiceId, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00004001); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_ServiceTypes, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00004002); // VT_LPWSTR | VT_VECTOR
// Association DB PKEYs
DEFINE_API_PKEY(PKEY_PNPX_Devnode, PnPXDevNode, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00000001); // VT_BOOL
DEFINE_API_PKEY(PKEY_PNPX_AssociationState, AssociationState, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00000002); // VT_UINT
DEFINE_API_PKEY(PKEY_PNPX_AssociatedInstanceId, AssociatedInstanceId, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00000003); // VT_LPWSTR
// for Computer Discovery
DEFINE_PROPERTYKEY(PKEY_PNPX_DomainName, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00005000); // VT_LPWSTR
// Use PKEY_ComputerName (propkey.h) DEFINE_PROPERTYKEY(PKEY_PNPX_MachineName, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00005001); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_PNPX_ShareName, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00005002); // VT_LPWSTR
// SSDP Provider custom properties
DEFINE_PROPERTYKEY(PKEY_SSDP_AltLocationInfo, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00006000); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_SSDP_DevLifeTime, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00006001); // VT_UI4
DEFINE_PROPERTYKEY(PKEY_SSDP_NetworkInterface, 0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 0x00006002); // VT_BOOL
// FMTID_PNPXDynamicProperty = {4FC5077E-B686-44BE-93E3-86CAFE368CCD}
DEFINE_GUID(FMTID_PNPXDynamicProperty, 0x4FC5077E, 0xB686, 0x44BE, 0x93, 0xE3, 0x86, 0xCA, 0xFE, 0x36, 0x8C, 0xCD);
DEFINE_PROPERTYKEY(PKEY_PNPX_Installable, 0x4FC5077E, 0xB686, 0x44BE, 0x93, 0xE3, 0x86, 0xCA, 0xFE, 0x36, 0x8C, 0xCD, 0x00000001); // VT_BOOL
DEFINE_PROPERTYKEY(PKEY_PNPX_Associated, 0x4FC5077E, 0xB686, 0x44BE, 0x93, 0xE3, 0x86, 0xCA, 0xFE, 0x36, 0x8C, 0xCD, 0x00000002); // VT_BOOL
// PKEY_PNPX_Installed to be deprecated in Longhorn Server timeframe
// this PKEY really represents Associated state
#define PKEY_PNPX_Installed PKEY_PNPX_Associated // Deprecated! Please use PKEY_PNPX_Associated
DEFINE_PROPERTYKEY(PKEY_PNPX_CompatibleTypes, 0x4FC5077E, 0xB686, 0x44BE, 0x93, 0xE3, 0x86, 0xCA, 0xFE, 0x36, 0x8C, 0xCD, 0x00000003); // VT_LPWSTR | VT_VECTOR
// WNET Provider properties
DEFINE_PROPERTYKEY(PKEY_WNET_Scope, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000001); // VT_UINT
DEFINE_PROPERTYKEY(PKEY_WNET_Type, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000002); // VT_UINT
DEFINE_PROPERTYKEY(PKEY_WNET_DisplayType, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000003); // VT_UINT
DEFINE_PROPERTYKEY(PKEY_WNET_Usage, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000004); // VT_UINT
DEFINE_PROPERTYKEY(PKEY_WNET_LocalName, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000005); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_WNET_RemoteName, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000006); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_WNET_Comment, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000007); // VT_LPWSTR
DEFINE_PROPERTYKEY(PKEY_WNET_Provider, 0xdebda43a, 0x37b3, 0x4383, 0x91, 0xE7, 0x44, 0x98, 0xda, 0x29, 0x95, 0xab, 0x00000008); // VT_LPWSTR
// WCN Provider properties
DEFINE_PROPERTYKEY(PKEY_WCN_Version, 0x88190b80, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000001); // VT_UI1
DEFINE_PROPERTYKEY(PKEY_WCN_RequestType, 0x88190b81, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000002); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_AuthType, 0x88190b82, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000003); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_EncryptType, 0x88190b83, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000004); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_ConnType, 0x88190b84, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000005); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_ConfigMethods, 0x88190b85, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000006); // VT_INT
// map WCN DeviceType to PKEY_PNPX_DeviceCategory
//DEFINE_PROPERTYKEY(PKEY_WCN_DeviceType, 0x88190b86, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000007); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_RfBand, 0x88190b87, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000008); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_AssocState, 0x88190b88, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x00000009); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_ConfigError, 0x88190b89, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x0000000a); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_ConfigState, 0x88190b89, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x0000000b); // VT_UI1
DEFINE_PROPERTYKEY(PKEY_WCN_DevicePasswordId, 0x88190b89, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x0000000c); // VT_INT
DEFINE_PROPERTYKEY(PKEY_WCN_OSVersion, 0x88190b89, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x0000000d); // VT_UINT
DEFINE_PROPERTYKEY(PKEY_WCN_VendorExtension, 0x88190b8a, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x0000000e); // VT_UI1 | VT_VECTOR
DEFINE_PROPERTYKEY(PKEY_WCN_RegistrarType, 0x88190b8b, 0x4684, 0x11da, 0xa2, 0x6a, 0x00, 0x02, 0xb3, 0x98, 0x8e, 0x81, 0x0000000f); // VT_INT
//-----------------------------------------------------------------------------
// DriverPackage properties
#define PKEY_DriverPackage_Model PKEY_DrvPkg_Model
#define PKEY_DriverPackage_VendorWebSite PKEY_DrvPkg_VendorWebSite
#define PKEY_DriverPackage_DetailedDescription PKEY_DrvPkg_DetailedDescription
#define PKEY_DriverPackage_DocumentationLink PKEY_DrvPkg_DocumentationLink
#define PKEY_DriverPackage_Icon PKEY_DrvPkg_Icon
#define PKEY_DriverPackage_BrandingIcon PKEY_DrvPkg_BrandingIcon
//-----------------------------------------------------------------------------
// Hardware properties
DEFINE_PROPERTYKEY(PKEY_Hardware_Devinst, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 4097);
// Name: System.Hardware.DisplayAttribute -- PKEY_Hardware_DisplayAttribute
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 5
DEFINE_PROPERTYKEY(PKEY_Hardware_DisplayAttribute, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 5);
// Name: System.Hardware.DriverDate -- PKEY_Hardware_DriverDate
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 11
DEFINE_PROPERTYKEY(PKEY_Hardware_DriverDate, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 11);
// Name: System.Hardware.DriverProvider -- PKEY_Hardware_DriverProvider
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 10
DEFINE_PROPERTYKEY(PKEY_Hardware_DriverProvider, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 10);
// Name: System.Hardware.DriverVersion -- PKEY_Hardware_DriverVersion
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 9
DEFINE_PROPERTYKEY(PKEY_Hardware_DriverVersion, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 9);
// Name: System.Hardware.Function -- PKEY_Hardware_Function
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 4099
DEFINE_PROPERTYKEY(PKEY_Hardware_Function, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 4099);
// Name: System.Hardware.Icon -- PKEY_Hardware_Icon
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 3
DEFINE_PROPERTYKEY(PKEY_Hardware_Icon, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 3);
// Name: System.Hardware.Image -- PKEY_Hardware_Image
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 4098
DEFINE_PROPERTYKEY(PKEY_Hardware_Image, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 4098);
// Name: System.Hardware.Manufacturer -- PKEY_Hardware_Manufacturer
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 6
DEFINE_PROPERTYKEY(PKEY_Hardware_Manufacturer, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 6);
// Name: System.Hardware.Model -- PKEY_Hardware_Model
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 7
DEFINE_PROPERTYKEY(PKEY_Hardware_Model, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 7);
// Name: System.Hardware.Name -- PKEY_Hardware_Name
// Type: String -- VT_LPWSTR (For variants: VT_BSTR)
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 2
DEFINE_PROPERTYKEY(PKEY_Hardware_Name, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 2);
// Name: System.Hardware.SerialNumber -- PKEY_Hardware_SerialNumber
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 8
DEFINE_PROPERTYKEY(PKEY_Hardware_SerialNumber, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 8);
// Name: System.Hardware.ShellAttributes -- PKEY_Hardware_ShellAttributes
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 4100
DEFINE_PROPERTYKEY(PKEY_Hardware_ShellAttributes, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 4100);
// Name: System.Hardware.Status -- PKEY_Hardware_Status
// Type: Unspecified -- VT_NULL
// FormatID: 5EAF3EF2-E0CA-4598-BF06-71ED1D9DD953, 4096
DEFINE_PROPERTYKEY(PKEY_Hardware_Status, 0x5EAF3EF2, 0xE0CA, 0x4598, 0xBF, 0x06, 0x71, 0xED, 0x1D, 0x9D, 0xD9, 0x53, 4096);

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define INITGUID
#include <guiddef.h>
#ifndef DECLSPEC_SELECTANY
#define DECLSPEC_SELECTANY __declspec(selectany)
#endif
#ifdef DEFINE_GUIDEX
#undef DEFINE_GUIDEX
#endif
#ifdef __cplusplus
#define DEFINE_GUIDEX(name) EXTERN_C const CDECL GUID DECLSPEC_SELECTANY name = { STATICGUIDOF(name) }
#else
#define DEFINE_GUIDEX(name) const CDECL GUID DECLSPEC_SELECTANY name = { STATICGUIDOF(name) }
#endif
#ifndef STATICGUIDOF
#define STATICGUIDOF(guid) STATIC_##guid
#endif
#ifndef DEFINE_WAVEFORMATEX_GUID
#define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x),0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,639 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#ifndef __KSPROXY__
#define __KSPROXY__
#ifdef __cplusplus
extern "C" {
#endif
#undef KSDDKAPI
#ifdef _KSDDK_
#define KSDDKAPI
#else
#define KSDDKAPI DECLSPEC_IMPORT
#endif
#define STATIC_IID_IKsObject \
0x423c13a2L,0x2070,0x11d0,0x9e,0xf7,0x00,0xaa,0x00,0xa2,0x16,0xa1
#define STATIC_IID_IKsPinEx \
0x7bb38260L,0xd19c,0x11d2,0xb3,0x8a,0x00,0xa0,0xc9,0x5e,0xc2,0x2e
#define STATIC_IID_IKsPin \
0xb61178d1L,0xa2d9,0x11cf,0x9e,0x53,0x00,0xaa,0x00,0xa2,0x16,0xa1
#define STATIC_IID_IKsPinPipe \
0xe539cd90L,0xa8b4,0x11d1,0x81,0x89,0x00,0xa0,0xc9,0x06,0x28,0x02
#define STATIC_IID_IKsDataTypeHandler \
0x5ffbaa02L,0x49a3,0x11d0,0x9f,0x36,0x00,0xaa,0x00,0xa2,0x16,0xa1
#define STATIC_IID_IKsDataTypeCompletion \
0x827D1A0EL,0x0F73,0x11D2,0xB2,0x7A,0x00,0xA0,0xC9,0x22,0x31,0x96
#define STATIC_IID_IKsInterfaceHandler \
0xD3ABC7E0L,0x9A61,0x11D0,0xA4,0x0D,0x00,0xA0,0xC9,0x22,0x31,0x96
#define STATIC_IID_IKsClockPropertySet \
0x5C5CBD84L,0xE755,0x11D0,0xAC,0x18,0x00,0xA0,0xC9,0x22,0x31,0x96
#define STATIC_IID_IKsAllocator \
0x8da64899L,0xc0d9,0x11d0,0x84,0x13,0x00,0x00,0xf8,0x22,0xfe,0x8a
#define STATIC_IID_IKsAllocatorEx \
0x091bb63aL,0x603f,0x11d1,0xb0,0x67,0x00,0xa0,0xc9,0x06,0x28,0x02
#ifndef STATIC_IID_IKsPropertySet
#define STATIC_IID_IKsPropertySet \
0x31EFAC30L,0x515C,0x11d0,0xA9,0xAA,0x00,0xAA,0x00,0x61,0xBE,0x93
#endif
#define STATIC_IID_IKsTopology \
0x28F54683L,0x06FD,0x11D2,0xB2,0x7A,0x00,0xA0,0xC9,0x22,0x31,0x96
#ifndef STATIC_IID_IKsControl
#define STATIC_IID_IKsControl \
0x28F54685L,0x06FD,0x11D2,0xB2,0x7A,0x00,0xA0,0xC9,0x22,0x31,0x96
#endif
#define STATIC_IID_IKsAggregateControl \
0x7F40EAC0L,0x3947,0x11D2,0x87,0x4E,0x00,0xA0,0xC9,0x22,0x31,0x96
#define STATIC_CLSID_Proxy \
0x17CCA71BL,0xECD7,0x11D0,0xB9,0x08,0x00,0xA0,0xC9,0x22,0x31,0x96
#ifdef _KS_
DEFINE_GUIDEX(IID_IKsObject);
DEFINE_GUIDEX(IID_IKsPin);
DEFINE_GUIDEX(IID_IKsPinEx);
DEFINE_GUIDEX(IID_IKsPinPipe);
DEFINE_GUIDEX(IID_IKsDataTypeHandler);
DEFINE_GUIDEX(IID_IKsDataTypeCompletion);
DEFINE_GUIDEX(IID_IKsInterfaceHandler);
DEFINE_GUIDEX(IID_IKsClockPropertySet);
DEFINE_GUIDEX(IID_IKsAllocator);
DEFINE_GUIDEX(IID_IKsAllocatorEx);
#define IID_IKsQualityForwarder KSCATEGORY_QUALITY
#define STATIC_IID_IKsQualityForwarder STATIC_KSCATEGORY_QUALITY
typedef enum {
KsAllocatorMode_User,
KsAllocatorMode_Kernel
} KSALLOCATORMODE;
typedef enum {
FramingProp_Uninitialized,
FramingProp_None,
FramingProp_Old,
FramingProp_Ex
} FRAMING_PROP;
typedef FRAMING_PROP *PFRAMING_PROP;
typedef enum {
Framing_Cache_Update,
Framing_Cache_ReadLast,
Framing_Cache_ReadOrig,
Framing_Cache_Write
} FRAMING_CACHE_OPS;
typedef struct {
LONGLONG MinTotalNominator;
LONGLONG MaxTotalNominator;
LONGLONG TotalDenominator;
} OPTIMAL_WEIGHT_TOTALS;
typedef struct IPin IPin;
typedef struct IKsPin IKsPin;
typedef struct IKsAllocator IKsAllocator;
typedef struct IKsAllocatorEx IKsAllocatorEx;
#define AllocatorStrategy_DontCare 0
#define AllocatorStrategy_MinimizeNumberOfFrames 0x00000001
#define AllocatorStrategy_MinimizeFrameSize 0x00000002
#define AllocatorStrategy_MinimizeNumberOfAllocators 0x00000004
#define AllocatorStrategy_MaximizeSpeed 0x00000008
#define PipeFactor_None 0
#define PipeFactor_UserModeUpstream 0x00000001
#define PipeFactor_UserModeDownstream 0x00000002
#define PipeFactor_MemoryTypes 0x00000004
#define PipeFactor_Flags 0x00000008
#define PipeFactor_PhysicalRanges 0x00000010
#define PipeFactor_OptimalRanges 0x00000020
#define PipeFactor_FixedCompression 0x00000040
#define PipeFactor_UnknownCompression 0x00000080
#define PipeFactor_Buffers 0x00000100
#define PipeFactor_Align 0x00000200
#define PipeFactor_PhysicalEnd 0x00000400
#define PipeFactor_LogicalEnd 0x00000800
typedef enum {
PipeState_DontCare,
PipeState_RangeNotFixed,
PipeState_RangeFixed,
PipeState_CompressionUnknown,
PipeState_Finalized
} PIPE_STATE;
typedef struct _PIPE_DIMENSIONS {
KS_COMPRESSION AllocatorPin;
KS_COMPRESSION MaxExpansionPin;
KS_COMPRESSION EndPin;
} PIPE_DIMENSIONS,*PPIPE_DIMENSIONS;
typedef enum {
Pipe_Allocator_None,
Pipe_Allocator_FirstPin,
Pipe_Allocator_LastPin,
Pipe_Allocator_MiddlePin
} PIPE_ALLOCATOR_PLACE;
typedef PIPE_ALLOCATOR_PLACE *PPIPE_ALLOCATOR_PLACE;
typedef enum {
KS_MemoryTypeDontCare = 0,
KS_MemoryTypeKernelPaged,
KS_MemoryTypeKernelNonPaged,
KS_MemoryTypeDeviceHostMapped,
KS_MemoryTypeDeviceSpecific,
KS_MemoryTypeUser,
KS_MemoryTypeAnyHost
} KS_LogicalMemoryType;
typedef KS_LogicalMemoryType *PKS_LogicalMemoryType;
typedef struct _PIPE_TERMINATION {
ULONG Flags;
ULONG OutsideFactors;
ULONG Weigth;
KS_FRAMING_RANGE PhysicalRange;
KS_FRAMING_RANGE_WEIGHTED OptimalRange;
KS_COMPRESSION Compression;
} PIPE_TERMINATION;
typedef struct _ALLOCATOR_PROPERTIES_EX
{
long cBuffers;
long cbBuffer;
long cbAlign;
long cbPrefix;
GUID MemoryType;
GUID BusType;
PIPE_STATE State;
PIPE_TERMINATION Input;
PIPE_TERMINATION Output;
ULONG Strategy;
ULONG Flags;
ULONG Weight;
KS_LogicalMemoryType LogicalMemoryType;
PIPE_ALLOCATOR_PLACE AllocatorPlace;
PIPE_DIMENSIONS Dimensions;
KS_FRAMING_RANGE PhysicalRange;
IKsAllocatorEx *PrevSegment;
ULONG CountNextSegments;
IKsAllocatorEx **NextSegments;
ULONG InsideFactors;
ULONG NumberPins;
} ALLOCATOR_PROPERTIES_EX;
typedef ALLOCATOR_PROPERTIES_EX *PALLOCATOR_PROPERTIES_EX;
#ifdef __STREAMS__
struct IKsClockPropertySet;
#undef INTERFACE
#define INTERFACE IKsClockPropertySet
DECLARE_INTERFACE_(IKsClockPropertySet,IUnknown)
{
STDMETHOD(KsGetTime) (THIS_
LONGLONG *Time
) PURE;
STDMETHOD(KsSetTime) (THIS_
LONGLONG Time
) PURE;
STDMETHOD(KsGetPhysicalTime) (THIS_
LONGLONG *Time
) PURE;
STDMETHOD(KsSetPhysicalTime) (THIS_
LONGLONG Time
) PURE;
STDMETHOD(KsGetCorrelatedTime) (THIS_
KSCORRELATED_TIME *CorrelatedTime
) PURE;
STDMETHOD(KsSetCorrelatedTime) (THIS_
KSCORRELATED_TIME *CorrelatedTime
) PURE;
STDMETHOD(KsGetCorrelatedPhysicalTime)(THIS_
KSCORRELATED_TIME *CorrelatedTime
) PURE;
STDMETHOD(KsSetCorrelatedPhysicalTime)(THIS_
KSCORRELATED_TIME *CorrelatedTime
) PURE;
STDMETHOD(KsGetResolution) (THIS_
KSRESOLUTION *Resolution
) PURE;
STDMETHOD(KsGetState) (THIS_
KSSTATE *State
) PURE;
};
struct IKsAllocator;
#undef INTERFACE
#define INTERFACE IKsAllocator
DECLARE_INTERFACE_(IKsAllocator,IUnknown)
{
STDMETHOD_(HANDLE,KsGetAllocatorHandle)(THIS) PURE;
STDMETHOD_(KSALLOCATORMODE,KsGetAllocatorMode)(THIS) PURE;
STDMETHOD(KsGetAllocatorStatus) (THIS_
PKSSTREAMALLOCATOR_STATUS AllocatorStatus
) PURE;
STDMETHOD_(VOID,KsSetAllocatorMode) (THIS_
KSALLOCATORMODE Mode
) PURE;
};
struct IKsAllocatorEx;
#undef INTERFACE
#define INTERFACE IKsAllocatorEx
DECLARE_INTERFACE_(IKsAllocatorEx,IKsAllocator)
{
STDMETHOD_(PALLOCATOR_PROPERTIES_EX,KsGetProperties)(THIS) PURE;
STDMETHOD_(VOID,KsSetProperties) (THIS_
PALLOCATOR_PROPERTIES_EX
) PURE;
STDMETHOD_(VOID,KsSetAllocatorHandle) (THIS_
HANDLE AllocatorHandle
) PURE;
STDMETHOD_(HANDLE,KsCreateAllocatorAndGetHandle)(THIS_
IKsPin *KsPin
) PURE;
};
typedef enum {
KsPeekOperation_PeekOnly,
KsPeekOperation_AddRef
} KSPEEKOPERATION;
typedef struct _KSSTREAM_SEGMENT *PKSSTREAM_SEGMENT;
struct IKsPin;
#undef INTERFACE
#define INTERFACE IKsPin
DECLARE_INTERFACE_(IKsPin,IUnknown)
{
STDMETHOD(KsQueryMediums) (THIS_
PKSMULTIPLE_ITEM *MediumList
) PURE;
STDMETHOD(KsQueryInterfaces) (THIS_
PKSMULTIPLE_ITEM *InterfaceList
) PURE;
STDMETHOD(KsCreateSinkPinHandle) (THIS_
KSPIN_INTERFACE& Interface,
KSPIN_MEDIUM& Medium
) PURE;
STDMETHOD(KsGetCurrentCommunication) (THIS_
KSPIN_COMMUNICATION *Communication,
KSPIN_INTERFACE *Interface,
KSPIN_MEDIUM *Medium
) PURE;
STDMETHOD(KsPropagateAcquire) (THIS) PURE;
STDMETHOD(KsDeliver) (THIS_
IMediaSample *Sample,
ULONG Flags
) PURE;
STDMETHOD(KsMediaSamplesCompleted) (THIS_
PKSSTREAM_SEGMENT StreamSegment
) PURE;
STDMETHOD_(IMemAllocator *,KsPeekAllocator)(THIS_
KSPEEKOPERATION Operation
) PURE;
STDMETHOD(KsReceiveAllocator) (THIS_
IMemAllocator *MemAllocator
) PURE;
STDMETHOD(KsRenegotiateAllocator) (THIS) PURE;
STDMETHOD_(LONG,KsIncrementPendingIoCount)(THIS) PURE;
STDMETHOD_(LONG,KsDecrementPendingIoCount)(THIS) PURE;
STDMETHOD(KsQualityNotify) (THIS_
ULONG Proportion,
REFERENCE_TIME TimeDelta
) PURE;
};
struct IKsPinEx;
#undef INTERFACE
#define INTERFACE IKsPinEx
DECLARE_INTERFACE_(IKsPinEx,IKsPin)
{
STDMETHOD_(VOID,KsNotifyError) (THIS_
IMediaSample *Sample,
HRESULT hr
) PURE;
};
struct IKsPinPipe;
#undef INTERFACE
#define INTERFACE IKsPinPipe
DECLARE_INTERFACE_(IKsPinPipe,IUnknown)
{
STDMETHOD(KsGetPinFramingCache) (THIS_
PKSALLOCATOR_FRAMING_EX *FramingEx,
PFRAMING_PROP FramingProp,
FRAMING_CACHE_OPS Option
) PURE;
STDMETHOD(KsSetPinFramingCache) (THIS_
PKSALLOCATOR_FRAMING_EX FramingEx,
PFRAMING_PROP FramingProp,
FRAMING_CACHE_OPS Option
) PURE;
STDMETHOD_(IPin*,KsGetConnectedPin) (THIS) PURE;
STDMETHOD_(IKsAllocatorEx*,KsGetPipe) (THIS_
KSPEEKOPERATION Operation
) PURE;
STDMETHOD(KsSetPipe) (THIS_
IKsAllocatorEx *KsAllocator
) PURE;
STDMETHOD_(ULONG,KsGetPipeAllocatorFlag)(THIS) PURE;
STDMETHOD(KsSetPipeAllocatorFlag) (THIS_
ULONG Flag
) PURE;
STDMETHOD_(GUID,KsGetPinBusCache) (THIS) PURE;
STDMETHOD(KsSetPinBusCache) (THIS_
GUID Bus
) PURE;
STDMETHOD_(PWCHAR,KsGetPinName) (THIS) PURE;
STDMETHOD_(PWCHAR,KsGetFilterName) (THIS) PURE;
};
struct IKsPinFactory;
#undef INTERFACE
#define INTERFACE IKsPinFactory
DECLARE_INTERFACE_(IKsPinFactory,IUnknown)
{
STDMETHOD(KsPinFactory) (THIS_
ULONG *PinFactory
) PURE;
};
typedef enum {
KsIoOperation_Write,
KsIoOperation_Read
} KSIOOPERATION;
struct IKsDataTypeHandler;
#undef INTERFACE
#define INTERFACE IKsDataTypeHandler
DECLARE_INTERFACE_(IKsDataTypeHandler,IUnknown)
{
STDMETHOD(KsCompleteIoOperation) (THIS_
IMediaSample *Sample,
PVOID StreamHeader,
KSIOOPERATION IoOperation,
WINBOOL Cancelled
) PURE;
STDMETHOD(KsIsMediaTypeInRanges) (THIS_
PVOID DataRanges
) PURE;
STDMETHOD(KsPrepareIoOperation) (THIS_
IMediaSample *Sample,
PVOID StreamHeader,
KSIOOPERATION IoOperation
) PURE;
STDMETHOD(KsQueryExtendedSize) (THIS_
ULONG *ExtendedSize
) PURE;
STDMETHOD(KsSetMediaType) (THIS_
const AM_MEDIA_TYPE *AmMediaType
) PURE;
};
struct IKsDataTypeCompletion;
#undef INTERFACE
#define INTERFACE IKsDataTypeCompletion
DECLARE_INTERFACE_(IKsDataTypeCompletion,IUnknown)
{
STDMETHOD(KsCompleteMediaType) (THIS_
HANDLE FilterHandle,
ULONG PinFactoryId,
AM_MEDIA_TYPE *AmMediaType
) PURE;
};
struct IKsInterfaceHandler;
#undef INTERFACE
#define INTERFACE IKsInterfaceHandler
DECLARE_INTERFACE_(IKsInterfaceHandler,IUnknown)
{
STDMETHOD(KsSetPin) (THIS_
IKsPin *KsPin
) PURE;
STDMETHOD(KsProcessMediaSamples) (THIS_
IKsDataTypeHandler *KsDataTypeHandler,
IMediaSample **SampleList,
PLONG SampleCount,
KSIOOPERATION IoOperation,
PKSSTREAM_SEGMENT *StreamSegment
) PURE;
STDMETHOD(KsCompleteIo) (THIS_
PKSSTREAM_SEGMENT StreamSegment
) PURE;
};
typedef struct _KSSTREAM_SEGMENT {
IKsInterfaceHandler *KsInterfaceHandler;
IKsDataTypeHandler *KsDataTypeHandler;
KSIOOPERATION IoOperation;
HANDLE CompletionEvent;
} KSSTREAM_SEGMENT;
struct IKsObject;
#undef INTERFACE
#define INTERFACE IKsObject
DECLARE_INTERFACE_(IKsObject,IUnknown)
{
STDMETHOD_(HANDLE,KsGetObjectHandle) (THIS) PURE;
};
struct IKsQualityForwarder;
#undef INTERFACE
#define INTERFACE IKsQualityForwarder
DECLARE_INTERFACE_(IKsQualityForwarder,IKsObject)
{
STDMETHOD_(VOID,KsFlushClient) (THIS_
IKsPin *Pin
) PURE;
};
struct IKsNotifyEvent;
#undef INTERFACE
#define INTERFACE IKsNotifyEvent
DECLARE_INTERFACE_(IKsNotifyEvent,IUnknown)
{
STDMETHOD(KsNotifyEvent) (THIS_
ULONG Event,
ULONG_PTR lParam1,
ULONG_PTR lParam2
) PURE;
};
KSDDKAPI HRESULT WINAPI KsResolveRequiredAttributes(PKSDATARANGE DataRange,PKSMULTIPLE_ITEM Attributes);
KSDDKAPI HRESULT WINAPI KsOpenDefaultDevice(REFGUID Category,ACCESS_MASK Access,PHANDLE DeviceHandle);
KSDDKAPI HRESULT WINAPI KsSynchronousDeviceControl(HANDLE Handle,ULONG IoControl,PVOID InBuffer,ULONG InLength,PVOID OutBuffer,ULONG OutLength,PULONG BytesReturned);
KSDDKAPI HRESULT WINAPI KsGetMultiplePinFactoryItems(HANDLE FilterHandle,ULONG PinFactoryId,ULONG PropertyId,PVOID *Items);
KSDDKAPI HRESULT WINAPI KsGetMediaTypeCount(HANDLE FilterHandle,ULONG PinFactoryId,ULONG *MediaTypeCount);
KSDDKAPI HRESULT WINAPI KsGetMediaType(int Position,AM_MEDIA_TYPE *AmMediaType,HANDLE FilterHandle,ULONG PinFactoryId);
#endif /* __STREAMS__ */
#ifndef _IKsPropertySet_
DEFINE_GUIDEX(IID_IKsPropertySet);
#endif
#ifndef _IKsControl_
DEFINE_GUIDEX(IID_IKsControl);
#endif
DEFINE_GUIDEX(IID_IKsAggregateControl);
#ifndef _IKsTopology_
DEFINE_GUIDEX(IID_IKsTopology);
#endif
DEFINE_GUIDSTRUCT("17CCA71B-ECD7-11D0-B908-00A0C9223196",CLSID_Proxy);
#define CLSID_Proxy DEFINE_GUIDNAMED(CLSID_Proxy)
#else /* _KS_ */
#ifndef _IKsPropertySet_
DEFINE_GUID(IID_IKsPropertySet,STATIC_IID_IKsPropertySet);
#endif
DEFINE_GUID(CLSID_Proxy,STATIC_CLSID_Proxy);
#endif /* _KS_ */
#ifndef _IKsPropertySet_
#define _IKsPropertySet_
#define KSPROPERTY_SUPPORT_GET 1
#define KSPROPERTY_SUPPORT_SET 2
#ifdef DECLARE_INTERFACE_
struct IKsPropertySet;
#undef INTERFACE
#define INTERFACE IKsPropertySet
DECLARE_INTERFACE_(IKsPropertySet,IUnknown)
{
STDMETHOD(Set) (THIS_
REFGUID PropSet,
ULONG Id,
LPVOID InstanceData,
ULONG InstanceLength,
LPVOID PropertyData,
ULONG DataLength
) PURE;
STDMETHOD(Get) (THIS_
REFGUID PropSet,
ULONG Id,
LPVOID InstanceData,
ULONG InstanceLength,
LPVOID PropertyData,
ULONG DataLength,
ULONG *BytesReturned
) PURE;
STDMETHOD(QuerySupported) (THIS_
REFGUID PropSet,
ULONG Id,
ULONG *TypeSupport
) PURE;
};
#endif /* DECLARE_INTERFACE_ */
#endif /* _IKsPropertySet_ */
#ifndef _IKsControl_
#define _IKsControl_
#ifdef DECLARE_INTERFACE_
struct IKsControl;
#undef INTERFACE
#define INTERFACE IKsControl
DECLARE_INTERFACE_(IKsControl,IUnknown)
{
STDMETHOD(KsProperty) (THIS_
PKSPROPERTY Property,
ULONG PropertyLength,
LPVOID PropertyData,
ULONG DataLength,
ULONG *BytesReturned
) PURE;
STDMETHOD(KsMethod) (THIS_
PKSMETHOD Method,
ULONG MethodLength,
LPVOID MethodData,
ULONG DataLength,
ULONG *BytesReturned
) PURE;
STDMETHOD(KsEvent) (THIS_
PKSEVENT Event,
ULONG EventLength,
LPVOID EventData,
ULONG DataLength,
ULONG *BytesReturned
) PURE;
};
#endif /* DECLARE_INTERFACE_ */
#endif /* _IKsControl_ */
#ifdef DECLARE_INTERFACE_
struct IKsAggregateControl;
#undef INTERFACE
#define INTERFACE IKsAggregateControl
DECLARE_INTERFACE_(IKsAggregateControl,IUnknown)
{
STDMETHOD(KsAddAggregate) (THIS_
REFGUID AggregateClass
) PURE;
STDMETHOD(KsRemoveAggregate) (THIS_
REFGUID AggregateClass
) PURE;
};
#endif /* DECLARE_INTERFACE_ */
#ifndef _IKsTopology_
#define _IKsTopology_
#ifdef DECLARE_INTERFACE_
struct IKsTopology;
#undef INTERFACE
#define INTERFACE IKsTopology
DECLARE_INTERFACE_(IKsTopology,IUnknown)
{
STDMETHOD(CreateNodeInstance) (THIS_
ULONG NodeId,
ULONG Flags,
ACCESS_MASK DesiredAccess,
IUnknown *UnkOuter,
REFGUID InterfaceId,
LPVOID *Interface
) PURE;
};
#endif /* DECLARE_INTERFACE_ */
#endif /* _IKsTopology_ */
#ifdef __cplusplus
}
#endif
#endif /* __KSPROXY__ */

View File

@ -1,159 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
OUR_GUID_ENTRY(MEDIATYPE_MPEG2_PACK,
0x36523B13,0x8EE5,0x11d1,0x8C,0xA3,0x00,0x60,0xB0,0x57,0x66,0x4A)
OUR_GUID_ENTRY(MEDIATYPE_MPEG2_PES,
0xe06d8020,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x5f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIATYPE_MPEG2_SECTIONS,
0x455f176c,0x4b06,0x47ce,0x9a,0xef,0x8c,0xae,0xf7,0x3d,0xf7,0xb5)
OUR_GUID_ENTRY(MEDIASUBTYPE_ATSC_SI,
0xb3c7397c,0xd303,0x414d,0xb3,0x3c,0x4e,0xd2,0xc9,0xd2,0x97,0x33)
OUR_GUID_ENTRY(MEDIASUBTYPE_DVB_SI,
0xe9dd31a3,0x221d,0x4adb,0x85,0x32,0x9a,0xf3,0x9,0xc1,0xa4,0x8)
OUR_GUID_ENTRY(MEDIASUBTYPE_MPEG2DATA,
0xc892e55b,0x252d,0x42b5,0xa3,0x16,0xd9,0x97,0xe7,0xa5,0xd9,0x95)
OUR_GUID_ENTRY(MEDIASUBTYPE_MPEG2_VIDEO,
0xe06d8026,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x5f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(FORMAT_MPEG2_VIDEO,
0xe06d80e3,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x5f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(FORMAT_VIDEOINFO2,
0xf72a76A0L,0xeb0a,0x11d0,0xac,0xe4,0x0,0x0,0xc0,0xcc,0x16,0xba)
OUR_GUID_ENTRY(MEDIASUBTYPE_MPEG2_PROGRAM,
0xe06d8022,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_MPEG2_TRANSPORT,
0xe06d8023,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_MPEG2_TRANSPORT_STRIDE,
0x138aa9a4,0x1ee2,0x4c5b,0x98,0x8e,0x19,0xab,0xfd,0xbc,0x8a,0x11)
OUR_GUID_ENTRY(MEDIASUBTYPE_MPEG2_AUDIO,
0xe06d802b,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_DOLBY_AC3,
0xe06d802c,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_DVD_SUBPICTURE,
0xe06d802d,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_DVD_LPCM_AUDIO,
0xe06d8032,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_DTS,
0xe06d8033,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_SDDS,
0xe06d8034,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIATYPE_DVD_ENCRYPTED_PACK,
0xed0b916a,0x044d,0x11d1,0xaa,0x78,0x00,0xc0,0x04f,0xc3,0x1d,0x60)
OUR_GUID_ENTRY(MEDIATYPE_DVD_NAVIGATION,
0xe06d802e,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_DVD_NAVIGATION_PCI,
0xe06d802f,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_DVD_NAVIGATION_DSI,
0xe06d8030,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(MEDIASUBTYPE_DVD_NAVIGATION_PROVIDER,
0xe06d8031,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(FORMAT_MPEG2Video,
0xe06d80e3,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(FORMAT_DolbyAC3,
0xe06d80e4,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(FORMAT_MPEG2Audio,
0xe06d80e5,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(FORMAT_DVD_LPCMAudio,
0xe06d80e6,0xdb46,0x11cf,0xb4,0xd1,0x00,0x80,0x05f,0x6c,0xbb,0xea)
OUR_GUID_ENTRY(AM_KSPROPSETID_AC3,
0xBFABE720,0x6E1F,0x11D0,0xBC,0xF2,0x44,0x45,0x53,0x54,0x00,0x00)
OUR_GUID_ENTRY(AM_KSPROPSETID_DvdSubPic,
0xac390460,0x43af,0x11d0,0xbd,0x6a,0x00,0x35,0x05,0xc1,0x03,0xa9)
OUR_GUID_ENTRY(AM_KSPROPSETID_CopyProt,
0x0E8A0A40,0x6AEF,0x11D0,0x9E,0xD0,0x00,0xA0,0x24,0xCA,0x19,0xB3)
OUR_GUID_ENTRY(AM_KSPROPSETID_TSRateChange,
0xa503c5c0,0x1d1d,0x11d1,0xad,0x80,0x44,0x45,0x53,0x54,0x0,0x0)
OUR_GUID_ENTRY(AM_KSPROPSETID_DVD_RateChange,
0x3577eb09,0x9582,0x477f,0xb2,0x9c,0xb0,0xc4,0x52,0xa4,0xff,0x9a)
OUR_GUID_ENTRY(AM_KSPROPSETID_DvdKaraoke,
0xae4720ae,0xaa71,0x42d8,0xb8,0x2a,0xff,0xfd,0xf5,0x8b,0x76,0xfd)
OUR_GUID_ENTRY(AM_KSPROPSETID_FrameStep,
0xc830acbd,0xab07,0x492f,0x88,0x52,0x45,0xb6,0x98,0x7c,0x29,0x79)
OUR_GUID_ENTRY(AM_KSCATEGORY_CAPTURE,
0x65E8773DL,0x8F56,0x11D0,0xA3,0xB9,0x00,0xA0,0xC9,0x22,0x31,0x96)
OUR_GUID_ENTRY(AM_KSCATEGORY_RENDER,
0x65E8773EL,0x8F56,0x11D0,0xA3,0xB9,0x00,0xA0,0xC9,0x22,0x31,0x96)
OUR_GUID_ENTRY(AM_KSCATEGORY_DATACOMPRESSOR,
0x1E84C900L,0x7E70,0x11D0,0xA5,0xD6,0x28,0xDB,0x04,0xC1,0x00,0x00)
OUR_GUID_ENTRY(AM_KSCATEGORY_AUDIO,
0x6994AD04L,0x93EF,0x11D0,0xA3,0xCC,0x00,0xA0,0xC9,0x22,0x31,0x96)
OUR_GUID_ENTRY(AM_KSCATEGORY_VIDEO,
0x6994AD05L,0x93EF,0x11D0,0xA3,0xCC,0x00,0xA0,0xC9,0x22,0x31,0x96)
OUR_GUID_ENTRY(AM_KSCATEGORY_TVTUNER,
0xa799a800L,0xa46d,0x11d0,0xa1,0x8c,0x00,0xa0,0x24,0x01,0xdc,0xd4)
OUR_GUID_ENTRY(AM_KSCATEGORY_CROSSBAR,
0xa799a801L,0xa46d,0x11d0,0xa1,0x8c,0x00,0xa0,0x24,0x01,0xdc,0xd4)
OUR_GUID_ENTRY(AM_KSCATEGORY_TVAUDIO,
0xa799a802L,0xa46d,0x11d0,0xa1,0x8c,0x00,0xa0,0x24,0x01,0xdc,0xd4)
OUR_GUID_ENTRY(AM_KSCATEGORY_VBICODEC,
0x07dad660L,0x22f1,0x11d1,0xa9,0xf4,0x00,0xc0,0x4f,0xbb,0xde,0x8f)
OUR_GUID_ENTRY(AM_KSCATEGORY_VBICODEC_MI,
0x9c24a977,0x951,0x451a,0x80,0x6,0xe,0x49,0xbd,0x28,0xcd,0x5f)
OUR_GUID_ENTRY(AM_KSCATEGORY_SPLITTER,
0x0A4252A0L,0x7E70,0x11D0,0xA5,0xD6,0x28,0xDB,0x04,0xC1,0x00,0x00)
OUR_GUID_ENTRY(IID_IKsInterfaceHandler,
0xD3ABC7E0L,0x9A61,0x11D0,0xA4,0x0D,0x00,0xA0,0xC9,0x22,0x31,0x96)
OUR_GUID_ENTRY(IID_IKsDataTypeHandler,
0x5FFBAA02L,0x49A3,0x11D0,0x9F,0x36,0x00,0xAA,0x00,0xA2,0x16,0xA1)
OUR_GUID_ENTRY(IID_IKsPin,
0xb61178d1L,0xa2d9,0x11cf,0x9e,0x53,0x00,0xaa,0x00,0xa2,0x16,0xa1)
OUR_GUID_ENTRY(IID_IKsControl,
0x28F54685L,0x06FD,0x11D2,0xB2,0x7A,0x00,0xA0,0xC9,0x22,0x31,0x96)
OUR_GUID_ENTRY(IID_IKsPinFactory,
0xCD5EBE6BL,0x8B6E,0x11D1,0x8A,0xE0,0x00,0xA0,0xC9,0x22,0x31,0x96)
OUR_GUID_ENTRY(AM_INTERFACESETID_Standard,
0x1A8766A0L,0x62CE,0x11CF,0xA5,0xD6,0x28,0xDB,0x04,0xC1,0x00,0x00)

View File

@ -1,929 +0,0 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 7.00.0499 */
/* Compiler settings for mmdeviceapi.idl:
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//@@MIDL_FILE_HEADING( )
#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 500
#endif
/* verify that the <rpcsal.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCSAL_H_VERSION__
#define __REQUIRED_RPCSAL_H_VERSION__ 100
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
#ifndef __mmdeviceapi_h__
#define __mmdeviceapi_h__
#if __GNUC__ >=3
#pragma GCC system_header
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
/* Forward Declarations */
#ifndef __IMMNotificationClient_FWD_DEFINED__
#define __IMMNotificationClient_FWD_DEFINED__
typedef interface IMMNotificationClient IMMNotificationClient;
#endif /* __IMMNotificationClient_FWD_DEFINED__ */
#ifndef __IMMDevice_FWD_DEFINED__
#define __IMMDevice_FWD_DEFINED__
typedef interface IMMDevice IMMDevice;
#endif /* __IMMDevice_FWD_DEFINED__ */
#ifndef __IMMDeviceCollection_FWD_DEFINED__
#define __IMMDeviceCollection_FWD_DEFINED__
typedef interface IMMDeviceCollection IMMDeviceCollection;
#endif /* __IMMDeviceCollection_FWD_DEFINED__ */
#ifndef __IMMEndpoint_FWD_DEFINED__
#define __IMMEndpoint_FWD_DEFINED__
typedef interface IMMEndpoint IMMEndpoint;
#endif /* __IMMEndpoint_FWD_DEFINED__ */
#ifndef __IMMDeviceEnumerator_FWD_DEFINED__
#define __IMMDeviceEnumerator_FWD_DEFINED__
typedef interface IMMDeviceEnumerator IMMDeviceEnumerator;
#endif /* __IMMDeviceEnumerator_FWD_DEFINED__ */
#ifndef __IMMDeviceActivator_FWD_DEFINED__
#define __IMMDeviceActivator_FWD_DEFINED__
typedef interface IMMDeviceActivator IMMDeviceActivator;
#endif /* __IMMDeviceActivator_FWD_DEFINED__ */
#ifndef __MMDeviceEnumerator_FWD_DEFINED__
#define __MMDeviceEnumerator_FWD_DEFINED__
#ifdef __cplusplus
typedef class MMDeviceEnumerator MMDeviceEnumerator;
#else
typedef struct MMDeviceEnumerator MMDeviceEnumerator;
#endif /* __cplusplus */
#endif /* __MMDeviceEnumerator_FWD_DEFINED__ */
/* header files for imported files */
#include "unknwn.h"
#include "propsys.h"
#ifdef __cplusplus
extern "C"{
#endif
/* interface __MIDL_itf_mmdeviceapi_0000_0000 */
/* [local] */
#define E_NOTFOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND)
#define E_UNSUPPORTED_TYPE HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE)
#define DEVICE_STATE_ACTIVE 0x00000001
#define DEVICE_STATE_DISABLED 0x00000002
#define DEVICE_STATE_NOTPRESENT 0x00000004
#define DEVICE_STATE_UNPLUGGED 0x00000008
#define DEVICE_STATEMASK_ALL 0x0000000f
#ifdef DEFINE_PROPERTYKEY
#undef DEFINE_PROPERTYKEY
#endif
#ifdef INITGUID
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
#else
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY name
#endif // INITGUID
DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_FormFactor, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 0);
DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_ControlPanelPageProvider, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 1);
DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_Association, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 2);
DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_PhysicalSpeakers, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 3);
DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_GUID, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 4);
DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_Disable_SysFx, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 5);
#define ENDPOINT_SYSFX_ENABLED 0x00000000 // System Effects are enabled.
#define ENDPOINT_SYSFX_DISABLED 0x00000001 // System Effects are disabled.
DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_FullRangeSpeakers, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 6);
DEFINE_PROPERTYKEY(PKEY_AudioEngine_DeviceFormat, 0xf19f064d, 0x82c, 0x4e27, 0xbc, 0x73, 0x68, 0x82, 0xa1, 0xbb, 0x8e, 0x4c, 0);
typedef struct tagDIRECTX_AUDIO_ACTIVATION_PARAMS
{
DWORD cbDirectXAudioActivationParams;
GUID guidAudioSession;
DWORD dwAudioStreamFlags;
} DIRECTX_AUDIO_ACTIVATION_PARAMS;
typedef struct tagDIRECTX_AUDIO_ACTIVATION_PARAMS *PDIRECTX_AUDIO_ACTIVATION_PARAMS;
typedef /* [public][public][public][public][public] */
enum __MIDL___MIDL_itf_mmdeviceapi_0000_0000_0001
{ eRender = 0,
eCapture = ( eRender + 1 ) ,
eAll = ( eCapture + 1 ) ,
EDataFlow_enum_count = ( eAll + 1 )
} EDataFlow;
typedef /* [public][public][public] */
enum __MIDL___MIDL_itf_mmdeviceapi_0000_0000_0002
{ eConsole = 0,
eMultimedia = ( eConsole + 1 ) ,
eCommunications = ( eMultimedia + 1 ) ,
ERole_enum_count = ( eCommunications + 1 )
} ERole;
typedef /* [public] */
enum __MIDL___MIDL_itf_mmdeviceapi_0000_0000_0003
{ RemoteNetworkDevice = 0,
Speakers = ( RemoteNetworkDevice + 1 ) ,
LineLevel = ( Speakers + 1 ) ,
Headphones = ( LineLevel + 1 ) ,
Microphone = ( Headphones + 1 ) ,
Headset = ( Microphone + 1 ) ,
Handset = ( Headset + 1 ) ,
UnknownDigitalPassthrough = ( Handset + 1 ) ,
SPDIF = ( UnknownDigitalPassthrough + 1 ) ,
HDMI = ( SPDIF + 1 ) ,
UnknownFormFactor = ( HDMI + 1 )
} EndpointFormFactor;
extern RPC_IF_HANDLE __MIDL_itf_mmdeviceapi_0000_0000_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_mmdeviceapi_0000_0000_v0_0_s_ifspec;
#ifndef __IMMNotificationClient_INTERFACE_DEFINED__
#define __IMMNotificationClient_INTERFACE_DEFINED__
/* interface IMMNotificationClient */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IMMNotificationClient;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("7991EEC9-7E89-4D85-8390-6C703CEC60C0")
IMMNotificationClient : public IUnknown
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(
/* [in] */
__in LPCWSTR pwstrDeviceId,
/* [in] */
__in DWORD dwNewState) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE OnDeviceAdded(
/* [in] */
__in LPCWSTR pwstrDeviceId) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE OnDeviceRemoved(
/* [in] */
__in LPCWSTR pwstrDeviceId) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(
/* [in] */
__in EDataFlow flow,
/* [in] */
__in ERole role,
/* [in] */
__in LPCWSTR pwstrDefaultDeviceId) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(
/* [in] */
__in LPCWSTR pwstrDeviceId,
/* [in] */
__in const PROPERTYKEY key) = 0;
};
#else /* C style interface */
typedef struct IMMNotificationClientVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMMNotificationClient * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMMNotificationClient * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMMNotificationClient * This);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *OnDeviceStateChanged )(
IMMNotificationClient * This,
/* [in] */
__in LPCWSTR pwstrDeviceId,
/* [in] */
__in DWORD dwNewState);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *OnDeviceAdded )(
IMMNotificationClient * This,
/* [in] */
__in LPCWSTR pwstrDeviceId);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *OnDeviceRemoved )(
IMMNotificationClient * This,
/* [in] */
__in LPCWSTR pwstrDeviceId);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *OnDefaultDeviceChanged )(
IMMNotificationClient * This,
/* [in] */
__in EDataFlow flow,
/* [in] */
__in ERole role,
/* [in] */
__in LPCWSTR pwstrDefaultDeviceId);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *OnPropertyValueChanged )(
IMMNotificationClient * This,
/* [in] */
__in LPCWSTR pwstrDeviceId,
/* [in] */
__in const PROPERTYKEY key);
END_INTERFACE
} IMMNotificationClientVtbl;
interface IMMNotificationClient
{
CONST_VTBL struct IMMNotificationClientVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMMNotificationClient_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMMNotificationClient_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMMNotificationClient_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMMNotificationClient_OnDeviceStateChanged(This,pwstrDeviceId,dwNewState) \
( (This)->lpVtbl -> OnDeviceStateChanged(This,pwstrDeviceId,dwNewState) )
#define IMMNotificationClient_OnDeviceAdded(This,pwstrDeviceId) \
( (This)->lpVtbl -> OnDeviceAdded(This,pwstrDeviceId) )
#define IMMNotificationClient_OnDeviceRemoved(This,pwstrDeviceId) \
( (This)->lpVtbl -> OnDeviceRemoved(This,pwstrDeviceId) )
#define IMMNotificationClient_OnDefaultDeviceChanged(This,flow,role,pwstrDefaultDeviceId) \
( (This)->lpVtbl -> OnDefaultDeviceChanged(This,flow,role,pwstrDefaultDeviceId) )
#define IMMNotificationClient_OnPropertyValueChanged(This,pwstrDeviceId,key) \
( (This)->lpVtbl -> OnPropertyValueChanged(This,pwstrDeviceId,key) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMMNotificationClient_INTERFACE_DEFINED__ */
#ifndef __IMMDevice_INTERFACE_DEFINED__
#define __IMMDevice_INTERFACE_DEFINED__
/* interface IMMDevice */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IMMDevice;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("D666063F-1587-4E43-81F1-B948E807363F")
IMMDevice : public IUnknown
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Activate(
/* [in] */
__in REFIID iid,
/* [in] */
__in DWORD dwClsCtx,
/* [unique][in] */
__in_opt PROPVARIANT *pActivationParams,
/* [iid_is][out] */
__out void **ppInterface) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE OpenPropertyStore(
/* [in] */
__in DWORD stgmAccess,
/* [out] */
__out IPropertyStore **ppProperties) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetId(
/* [out] */
__deref_out LPWSTR *ppstrId) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetState(
/* [out] */
__out DWORD *pdwState) = 0;
};
#else /* C style interface */
typedef struct IMMDeviceVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMMDevice * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMMDevice * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMMDevice * This);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Activate )(
IMMDevice * This,
/* [in] */
__in REFIID iid,
/* [in] */
__in DWORD dwClsCtx,
/* [unique][in] */
__in_opt PROPVARIANT *pActivationParams,
/* [iid_is][out] */
__out void **ppInterface);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *OpenPropertyStore )(
IMMDevice * This,
/* [in] */
__in DWORD stgmAccess,
/* [out] */
__out IPropertyStore **ppProperties);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetId )(
IMMDevice * This,
/* [out] */
__deref_out LPWSTR *ppstrId);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetState )(
IMMDevice * This,
/* [out] */
__out DWORD *pdwState);
END_INTERFACE
} IMMDeviceVtbl;
interface IMMDevice
{
CONST_VTBL struct IMMDeviceVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMMDevice_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMMDevice_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMMDevice_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMMDevice_Activate(This,iid,dwClsCtx,pActivationParams,ppInterface) \
( (This)->lpVtbl -> Activate(This,iid,dwClsCtx,pActivationParams,ppInterface) )
#define IMMDevice_OpenPropertyStore(This,stgmAccess,ppProperties) \
( (This)->lpVtbl -> OpenPropertyStore(This,stgmAccess,ppProperties) )
#define IMMDevice_GetId(This,ppstrId) \
( (This)->lpVtbl -> GetId(This,ppstrId) )
#define IMMDevice_GetState(This,pdwState) \
( (This)->lpVtbl -> GetState(This,pdwState) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMMDevice_INTERFACE_DEFINED__ */
#ifndef __IMMDeviceCollection_INTERFACE_DEFINED__
#define __IMMDeviceCollection_INTERFACE_DEFINED__
/* interface IMMDeviceCollection */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IMMDeviceCollection;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E")
IMMDeviceCollection : public IUnknown
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetCount(
/* [out] */
__out UINT *pcDevices) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
/* [in] */
__in UINT nDevice,
/* [out] */
__out IMMDevice **ppDevice) = 0;
};
#else /* C style interface */
typedef struct IMMDeviceCollectionVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMMDeviceCollection * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMMDeviceCollection * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMMDeviceCollection * This);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetCount )(
IMMDeviceCollection * This,
/* [out] */
__out UINT *pcDevices);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
IMMDeviceCollection * This,
/* [in] */
__in UINT nDevice,
/* [out] */
__out IMMDevice **ppDevice);
END_INTERFACE
} IMMDeviceCollectionVtbl;
interface IMMDeviceCollection
{
CONST_VTBL struct IMMDeviceCollectionVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMMDeviceCollection_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMMDeviceCollection_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMMDeviceCollection_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMMDeviceCollection_GetCount(This,pcDevices) \
( (This)->lpVtbl -> GetCount(This,pcDevices) )
#define IMMDeviceCollection_Item(This,nDevice,ppDevice) \
( (This)->lpVtbl -> Item(This,nDevice,ppDevice) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMMDeviceCollection_INTERFACE_DEFINED__ */
#ifndef __IMMEndpoint_INTERFACE_DEFINED__
#define __IMMEndpoint_INTERFACE_DEFINED__
/* interface IMMEndpoint */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IMMEndpoint;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("1BE09788-6894-4089-8586-9A2A6C265AC5")
IMMEndpoint : public IUnknown
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetDataFlow(
/* [out] */
__out EDataFlow *pDataFlow) = 0;
};
#else /* C style interface */
typedef struct IMMEndpointVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMMEndpoint * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMMEndpoint * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMMEndpoint * This);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetDataFlow )(
IMMEndpoint * This,
/* [out] */
__out EDataFlow *pDataFlow);
END_INTERFACE
} IMMEndpointVtbl;
interface IMMEndpoint
{
CONST_VTBL struct IMMEndpointVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMMEndpoint_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMMEndpoint_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMMEndpoint_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMMEndpoint_GetDataFlow(This,pDataFlow) \
( (This)->lpVtbl -> GetDataFlow(This,pDataFlow) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMMEndpoint_INTERFACE_DEFINED__ */
#ifndef __IMMDeviceEnumerator_INTERFACE_DEFINED__
#define __IMMDeviceEnumerator_INTERFACE_DEFINED__
/* interface IMMDeviceEnumerator */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IMMDeviceEnumerator;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("A95664D2-9614-4F35-A746-DE8DB63617E6")
IMMDeviceEnumerator : public IUnknown
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE EnumAudioEndpoints(
/* [in] */
__in EDataFlow dataFlow,
/* [in] */
__in DWORD dwStateMask,
/* [out] */
__out IMMDeviceCollection **ppDevices) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetDefaultAudioEndpoint(
/* [in] */
__in EDataFlow dataFlow,
/* [in] */
__in ERole role,
/* [out] */
__out IMMDevice **ppEndpoint) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetDevice(
/* */
__in LPCWSTR pwstrId,
/* [out] */
__out IMMDevice **ppDevice) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE RegisterEndpointNotificationCallback(
/* [in] */
__in IMMNotificationClient *pClient) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE UnregisterEndpointNotificationCallback(
/* [in] */
__in IMMNotificationClient *pClient) = 0;
};
#else /* C style interface */
typedef struct IMMDeviceEnumeratorVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMMDeviceEnumerator * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMMDeviceEnumerator * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMMDeviceEnumerator * This);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EnumAudioEndpoints )(
IMMDeviceEnumerator * This,
/* [in] */
__in EDataFlow dataFlow,
/* [in] */
__in DWORD dwStateMask,
/* [out] */
__out IMMDeviceCollection **ppDevices);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetDefaultAudioEndpoint )(
IMMDeviceEnumerator * This,
/* [in] */
__in EDataFlow dataFlow,
/* [in] */
__in ERole role,
/* [out] */
__out IMMDevice **ppEndpoint);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetDevice )(
IMMDeviceEnumerator * This,
/* */
__in LPCWSTR pwstrId,
/* [out] */
__out IMMDevice **ppDevice);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *RegisterEndpointNotificationCallback )(
IMMDeviceEnumerator * This,
/* [in] */
__in IMMNotificationClient *pClient);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *UnregisterEndpointNotificationCallback )(
IMMDeviceEnumerator * This,
/* [in] */
__in IMMNotificationClient *pClient);
END_INTERFACE
} IMMDeviceEnumeratorVtbl;
interface IMMDeviceEnumerator
{
CONST_VTBL struct IMMDeviceEnumeratorVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMMDeviceEnumerator_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMMDeviceEnumerator_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMMDeviceEnumerator_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMMDeviceEnumerator_EnumAudioEndpoints(This,dataFlow,dwStateMask,ppDevices) \
( (This)->lpVtbl -> EnumAudioEndpoints(This,dataFlow,dwStateMask,ppDevices) )
#define IMMDeviceEnumerator_GetDefaultAudioEndpoint(This,dataFlow,role,ppEndpoint) \
( (This)->lpVtbl -> GetDefaultAudioEndpoint(This,dataFlow,role,ppEndpoint) )
#define IMMDeviceEnumerator_GetDevice(This,pwstrId,ppDevice) \
( (This)->lpVtbl -> GetDevice(This,pwstrId,ppDevice) )
#define IMMDeviceEnumerator_RegisterEndpointNotificationCallback(This,pClient) \
( (This)->lpVtbl -> RegisterEndpointNotificationCallback(This,pClient) )
#define IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(This,pClient) \
( (This)->lpVtbl -> UnregisterEndpointNotificationCallback(This,pClient) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMMDeviceEnumerator_INTERFACE_DEFINED__ */
#ifndef __IMMDeviceActivator_INTERFACE_DEFINED__
#define __IMMDeviceActivator_INTERFACE_DEFINED__
/* interface IMMDeviceActivator */
/* [unique][helpstring][nonextensible][uuid][local][object] */
EXTERN_C const IID IID_IMMDeviceActivator;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("3B0D0EA4-D0A9-4B0E-935B-09516746FAC0")
IMMDeviceActivator : public IUnknown
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Activate(
/* [in] */
__in REFIID iid,
/* [in] */
__in IMMDevice *pDevice,
/* [in] */
__in_opt PROPVARIANT *pActivationParams,
/* [iid_is][out] */
__out void **ppInterface) = 0;
};
#else /* C style interface */
typedef struct IMMDeviceActivatorVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMMDeviceActivator * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMMDeviceActivator * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMMDeviceActivator * This);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Activate )(
IMMDeviceActivator * This,
/* [in] */
__in REFIID iid,
/* [in] */
__in IMMDevice *pDevice,
/* [in] */
__in_opt PROPVARIANT *pActivationParams,
/* [iid_is][out] */
__out void **ppInterface);
END_INTERFACE
} IMMDeviceActivatorVtbl;
interface IMMDeviceActivator
{
CONST_VTBL struct IMMDeviceActivatorVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMMDeviceActivator_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMMDeviceActivator_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMMDeviceActivator_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMMDeviceActivator_Activate(This,iid,pDevice,pActivationParams,ppInterface) \
( (This)->lpVtbl -> Activate(This,iid,pDevice,pActivationParams,ppInterface) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMMDeviceActivator_INTERFACE_DEFINED__ */
/* interface __MIDL_itf_mmdeviceapi_0000_0006 */
/* [local] */
typedef /* [public] */ struct __MIDL___MIDL_itf_mmdeviceapi_0000_0006_0001
{
LPARAM AddPageParam;
IMMDevice *pEndpoint;
IMMDevice *pPnpInterface;
IMMDevice *pPnpDevnode;
} AudioExtensionParams;
extern RPC_IF_HANDLE __MIDL_itf_mmdeviceapi_0000_0006_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_mmdeviceapi_0000_0006_v0_0_s_ifspec;
#ifndef __MMDeviceAPILib_LIBRARY_DEFINED__
#define __MMDeviceAPILib_LIBRARY_DEFINED__
/* library MMDeviceAPILib */
/* [helpstring][version][uuid] */
EXTERN_C const IID LIBID_MMDeviceAPILib;
EXTERN_C const CLSID CLSID_MMDeviceEnumerator;
#ifdef __cplusplus
class DECLSPEC_UUID("BCDE0395-E52F-467C-8E3D-C4579291692E")
MMDeviceEnumerator;
#endif
#endif /* __MMDeviceAPILib_LIBRARY_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,26 +0,0 @@
#ifndef PID_FIRST_USABLE
#define PID_FIRST_USABLE 2
#endif
#ifndef REFPROPERTYKEY
#ifdef __cplusplus
#define REFPROPERTYKEY const PROPERTYKEY &
#else // !__cplusplus
#define REFPROPERTYKEY const PROPERTYKEY * __MIDL_CONST
#endif // __cplusplus
#endif //REFPROPERTYKEY
#ifdef DEFINE_PROPERTYKEY
#undef DEFINE_PROPERTYKEY
#endif
#ifdef INITGUID
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
#else
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY name
#endif // INITGUID
#ifndef IsEqualPropertyKey
#define IsEqualPropertyKey(a, b) (((a).pid == (b).pid) && IsEqualIID((a).fmtid, (b).fmtid) )
#endif // IsEqualPropertyKey

File diff suppressed because it is too large Load Diff

View File

@ -1,113 +0,0 @@
#pragma once
#if __GNUC__ >=3
#pragma GCC system_header
#endif
#define RPC_range(min,max)
#define __RPC__in
#define __RPC__in_string
#define __RPC__in_opt_string
#define __RPC__deref_opt_in_opt
#define __RPC__opt_in_opt_string
#define __RPC__in_ecount(size)
#define __RPC__in_ecount_full(size)
#define __RPC__in_ecount_full_string(size)
#define __RPC__in_ecount_part(size, length)
#define __RPC__in_ecount_full_opt(size)
#define __RPC__in_ecount_full_opt_string(size)
#define __RPC__inout_ecount_full_opt_string(size)
#define __RPC__in_ecount_part_opt(size, length)
#define __RPC__deref_in
#define __RPC__deref_in_string
#define __RPC__deref_opt_in
#define __RPC__deref_in_opt
#define __RPC__deref_in_ecount(size)
#define __RPC__deref_in_ecount_part(size, length)
#define __RPC__deref_in_ecount_full(size)
#define __RPC__deref_in_ecount_full_opt(size)
#define __RPC__deref_in_ecount_full_string(size)
#define __RPC__deref_in_ecount_full_opt_string(size)
#define __RPC__deref_in_ecount_opt(size)
#define __RPC__deref_in_ecount_opt_string(size)
#define __RPC__deref_in_ecount_part_opt(size, length)
// [out]
#define __RPC__out
#define __RPC__out_ecount(size)
#define __RPC__out_ecount_part(size, length)
#define __RPC__out_ecount_full(size)
#define __RPC__out_ecount_full_string(size)
// [in,out]
#define __RPC__inout
#define __RPC__inout_string
#define __RPC__opt_inout
#define __RPC__inout_ecount(size)
#define __RPC__inout_ecount_part(size, length)
#define __RPC__inout_ecount_full(size)
#define __RPC__inout_ecount_full_string(size)
// [in,unique]
#define __RPC__in_opt
#define __RPC__in_ecount_opt(size)
// [in,out,unique]
#define __RPC__inout_opt
#define __RPC__inout_ecount_opt(size)
#define __RPC__inout_ecount_part_opt(size, length)
#define __RPC__inout_ecount_full_opt(size)
#define __RPC__inout_ecount_full_string(size)
// [out] **
#define __RPC__deref_out
#define __RPC__deref_out_string
#define __RPC__deref_out_opt
#define __RPC__deref_out_opt_string
#define __RPC__deref_out_ecount(size)
#define __RPC__deref_out_ecount_part(size, length)
#define __RPC__deref_out_ecount_full(size)
#define __RPC__deref_out_ecount_full_string(size)
// [in,out] **, second pointer decoration.
#define __RPC__deref_inout
#define __RPC__deref_inout_string
#define __RPC__deref_inout_opt
#define __RPC__deref_inout_opt_string
#define __RPC__deref_inout_ecount_full(size)
#define __RPC__deref_inout_ecount_full_string(size)
#define __RPC__deref_inout_ecount_opt(size)
#define __RPC__deref_inout_ecount_part_opt(size, length)
#define __RPC__deref_inout_ecount_full_opt(size)
#define __RPC__deref_inout_ecount_full_opt_string(size)
// #define __RPC_out_opt out_opt is not allowed in rpc
// [in,out,unique]
#define __RPC__deref_opt_inout
#define __RPC__deref_opt_inout_string
#define __RPC__deref_opt_inout_ecount(size)
#define __RPC__deref_opt_inout_ecount_part(size, length)
#define __RPC__deref_opt_inout_ecount_full(size)
#define __RPC__deref_opt_inout_ecount_full_string(size)
#define __RPC__deref_out_ecount_opt(size)
#define __RPC__deref_out_ecount_part_opt(size, length)
#define __RPC__deref_out_ecount_full_opt(size)
#define __RPC__deref_out_ecount_full_opt_string(size)
#define __RPC__deref_opt_inout_opt
#define __RPC__deref_opt_inout_opt_string
#define __RPC__deref_opt_inout_ecount_opt(size)
#define __RPC__deref_opt_inout_ecount_part_opt(size, length)
#define __RPC__deref_opt_inout_ecount_full_opt(size)
#define __RPC__deref_opt_inout_ecount_full_opt_string(size)
#define __RPC_full_pointer
#define __RPC_unique_pointer
#define __RPC_ref_pointer
#define __RPC_string

View File

@ -1,252 +0,0 @@
#pragma once
#if __GNUC__ >=3
#pragma GCC system_header
#endif
/*#define __null*/ // << Conflicts with GCC internal type __null
#define __notnull
#define __maybenull
#define __readonly
#define __notreadonly
#define __maybereadonly
#define __valid
#define __notvalid
#define __maybevalid
#define __readableTo(extent)
#define __elem_readableTo(size)
#define __byte_readableTo(size)
#define __writableTo(size)
#define __elem_writableTo(size)
#define __byte_writableTo(size)
#define __deref
#define __pre
#define __post
#define __precond(expr)
#define __postcond(expr)
#define __exceptthat
#define __execeptthat
#define __inner_success(expr)
#define __inner_checkReturn
#define __inner_typefix(ctype)
#define __inner_override
#define __inner_callback
#define __inner_blocksOn(resource)
#define __inner_fallthrough_dec
#define __inner_fallthrough
#define __refparam
#define __inner_control_entrypoint(category)
#define __inner_data_entrypoint(category)
#define __ecount(size)
#define __bcount(size)
#define __in
#define __in_ecount(size)
#define __in_bcount(size)
#define __in_z
#define __in_ecount_z(size)
#define __in_bcount_z(size)
#define __in_nz
#define __in_ecount_nz(size)
#define __in_bcount_nz(size)
#define __out
#define __out_ecount(size)
#define __out_bcount(size)
#define __out_ecount_part(size,length)
#define __out_bcount_part(size,length)
#define __out_ecount_full(size)
#define __out_bcount_full(size)
#define __out_z
#define __out_z_opt
#define __out_ecount_z(size)
#define __out_bcount_z(size)
#define __out_ecount_part_z(size,length)
#define __out_bcount_part_z(size,length)
#define __out_ecount_full_z(size)
#define __out_bcount_full_z(size)
#define __out_nz
#define __out_nz_opt
#define __out_ecount_nz(size)
#define __out_bcount_nz(size)
#define __inout
#define __inout_ecount(size)
#define __inout_bcount(size)
#define __inout_ecount_part(size,length)
#define __inout_bcount_part(size,length)
#define __inout_ecount_full(size)
#define __inout_bcount_full(size)
#define __inout_z
#define __inout_ecount_z(size)
#define __inout_bcount_z(size)
#define __inout_nz
#define __inout_ecount_nz(size)
#define __inout_bcount_nz(size)
#define __ecount_opt(size)
#define __bcount_opt(size)
#define __in_opt
#define __in_ecount_opt(size)
#define __in_bcount_opt(size)
#define __in_z_opt
#define __in_ecount_z_opt(size)
#define __in_bcount_z_opt(size)
#define __in_nz_opt
#define __in_ecount_nz_opt(size)
#define __in_bcount_nz_opt(size)
#define __out_opt
#define __out_ecount_opt(size)
#define __out_bcount_opt(size)
#define __out_ecount_part_opt(size,length)
#define __out_bcount_part_opt(size,length)
#define __out_ecount_full_opt(size)
#define __out_bcount_full_opt(size)
#define __out_ecount_z_opt(size)
#define __out_bcount_z_opt(size)
#define __out_ecount_part_z_opt(size,length)
#define __out_bcount_part_z_opt(size,length)
#define __out_ecount_full_z_opt(size)
#define __out_bcount_full_z_opt(size)
#define __out_ecount_nz_opt(size)
#define __out_bcount_nz_opt(size)
#define __inout_opt
#define __inout_ecount_opt(size)
#define __inout_bcount_opt(size)
#define __inout_ecount_part_opt(size,length)
#define __inout_bcount_part_opt(size,length)
#define __inout_ecount_full_opt(size)
#define __inout_bcount_full_opt(size)
#define __inout_z_opt
#define __inout_ecount_z_opt(size)
#define __inout_ecount_z_opt(size)
#define __inout_bcount_z_opt(size)
#define __inout_nz_opt
#define __inout_ecount_nz_opt(size)
#define __inout_bcount_nz_opt(size)
#define __deref_ecount(size)
#define __deref_bcount(size)
#define __deref_out
#define __deref_out_ecount(size)
#define __deref_out_bcount(size)
#define __deref_out_ecount_part(size,length)
#define __deref_out_bcount_part(size,length)
#define __deref_out_ecount_full(size)
#define __deref_out_bcount_full(size)
#define __deref_out_z
#define __deref_out_ecount_z(size)
#define __deref_out_bcount_z(size)
#define __deref_out_nz
#define __deref_out_ecount_nz(size)
#define __deref_out_bcount_nz(size)
#define __deref_inout
#define __deref_inout_z
#define __deref_inout_ecount(size)
#define __deref_inout_bcount(size)
#define __deref_inout_ecount_part(size,length)
#define __deref_inout_bcount_part(size,length)
#define __deref_inout_ecount_full(size)
#define __deref_inout_bcount_full(size)
#define __deref_inout_z
#define __deref_inout_ecount_z(size)
#define __deref_inout_bcount_z(size)
#define __deref_inout_nz
#define __deref_inout_ecount_nz(size)
#define __deref_inout_bcount_nz(size)
#define __deref_ecount_opt(size)
#define __deref_bcount_opt(size)
#define __deref_out_opt
#define __deref_out_ecount_opt(size)
#define __deref_out_bcount_opt(size)
#define __deref_out_ecount_part_opt(size,length)
#define __deref_out_bcount_part_opt(size,length)
#define __deref_out_ecount_full_opt(size)
#define __deref_out_bcount_full_opt(size)
#define __deref_out_z_opt
#define __deref_out_ecount_z_opt(size)
#define __deref_out_bcount_z_opt(size)
#define __deref_out_nz_opt
#define __deref_out_ecount_nz_opt(size)
#define __deref_out_bcount_nz_opt(size)
#define __deref_inout_opt
#define __deref_inout_ecount_opt(size)
#define __deref_inout_bcount_opt(size)
#define __deref_inout_ecount_part_opt(size,length)
#define __deref_inout_bcount_part_opt(size,length)
#define __deref_inout_ecount_full_opt(size)
#define __deref_inout_bcount_full_opt(size)
#define __deref_inout_z_opt
#define __deref_inout_ecount_z_opt(size)
#define __deref_inout_bcount_z_opt(size)
#define __deref_inout_nz_opt
#define __deref_inout_ecount_nz_opt(size)
#define __deref_inout_bcount_nz_opt(size)
#define __deref_opt_ecount(size)
#define __deref_opt_bcount(size)
#define __deref_opt_out
#define __deref_opt_out_z
#define __deref_opt_out_ecount(size)
#define __deref_opt_out_bcount(size)
#define __deref_opt_out_ecount_part(size,length)
#define __deref_opt_out_bcount_part(size,length)
#define __deref_opt_out_ecount_full(size)
#define __deref_opt_out_bcount_full(size)
#define __deref_opt_inout
#define __deref_opt_inout_ecount(size)
#define __deref_opt_inout_bcount(size)
#define __deref_opt_inout_ecount_part(size,length)
#define __deref_opt_inout_bcount_part(size,length)
#define __deref_opt_inout_ecount_full(size)
#define __deref_opt_inout_bcount_full(size)
#define __deref_opt_inout_z
#define __deref_opt_inout_ecount_z(size)
#define __deref_opt_inout_bcount_z(size)
#define __deref_opt_inout_nz
#define __deref_opt_inout_ecount_nz(size)
#define __deref_opt_inout_bcount_nz(size)
#define __deref_opt_ecount_opt(size)
#define __deref_opt_bcount_opt(size)
#define __deref_opt_out_opt
#define __deref_opt_out_ecount_opt(size)
#define __deref_opt_out_bcount_opt(size)
#define __deref_opt_out_ecount_part_opt(size,length)
#define __deref_opt_out_bcount_part_opt(size,length)
#define __deref_opt_out_ecount_full_opt(size)
#define __deref_opt_out_bcount_full_opt(size)
#define __deref_opt_out_z_opt
#define __deref_opt_out_ecount_z_opt(size)
#define __deref_opt_out_bcount_z_opt(size)
#define __deref_opt_out_nz_opt
#define __deref_opt_out_ecount_nz_opt(size)
#define __deref_opt_out_bcount_nz_opt(size)
#define __deref_opt_inout_opt
#define __deref_opt_inout_ecount_opt(size)
#define __deref_opt_inout_bcount_opt(size)
#define __deref_opt_inout_ecount_part_opt(size,length)
#define __deref_opt_inout_bcount_part_opt(size,length)
#define __deref_opt_inout_ecount_full_opt(size)
#define __deref_opt_inout_bcount_full_opt(size)
#define __deref_opt_inout_z_opt
#define __deref_opt_inout_ecount_z_opt(size)
#define __deref_opt_inout_bcount_z_opt(size)
#define __deref_opt_inout_nz_opt
#define __deref_opt_inout_ecount_nz_opt(size)
#define __deref_opt_inout_bcount_nz_opt(size)
#define __success(expr)
#define __nullterminated
#define __nullnullterminated
#define __reserved
#define __checkReturn
#define __typefix(ctype)
#define __override
#define __callback
#define __format_string
#define __blocksOn(resource)
#define __control_entrypoint(category)
#define __data_entrypoint(category)
#ifndef __fallthrough
#define __fallthrough __inner_fallthrough
#endif
#ifndef __analysis_assume
#define __analysis_assume(expr)
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
**************
* WASAPI API *
**************
-------------------------------------------
Microsoft Visual Studio 2005 SP1 and higher
-------------------------------------------
No specific action is required to compile WASAPI API under Visual Studio.
You are only required to install min. Windows Vista SDK (v6.0A) prior
the compilation. To compile with WASAPI specific functionality for Windows 8
and higher the min. Windows 8 SDK is required.
----------------------------------------
MinGW (GCC 32/64-bit)
----------------------------------------
To compile with MinGW you are required to include 'mingw-include' directory
which contains necessary files with WASAPI API. These files are modified
for the compatibility with MinGW compiler. These files are taken from
the Windows Vista SDK (v6.0A). MinGW compilation is tested and proved to be
fully working.
MinGW (32-bit) tested min. version: gcc version 4.4.0 (GCC)
MinGW64 (64-bit) tested min. version: gcc version 4.4.4 20100226 (prerelease) (GCC)

File diff suppressed because it is too large Load Diff

View File

@ -1,85 +0,0 @@
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 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
if the total input frames equals the total output frames
5th September 2004:
This is the first public version of the code. It should be considered
an alpha release with zero guarantee not to crash on any particular
system. So far it has only been tested in the author's development
environment, which means a Win2k/SP2 PIII laptop with integrated
SoundMAX driver and USB Tascam US-428 compiled with both MinGW
(GCC 3.3) and MSVC++6 using the MS DirectX 9 SDK.
It has been most widely tested with the MinGW build, with most of the
test programs (particularly paqa_devs and paqa_errs) passing.
There are some notable failures: patest_out_underflow and both of the
blocking I/O tests (as blocking I/O is not implemented).
At this point the code needs to be tested with a much wider variety
of configurations and feedback provided from testers regarding
both working and failing cases.
What is the WDM-KS host API?
----------------------------
PortAudio for Windows currently has 3 functional host implementations.
MME uses the oldest Windows audio API which does not offer good
play/record latency.
DirectX improves this, but still imposes a penalty
of 10s of milliseconds due to the system mixing of streams from
multiple applications.
ASIO offers very good latency, but requires special drivers which are
not always available for cheaper audio hardware. Also, when ASIO
drivers are available, they are not always so robust because they
bypass all of the standardised Windows device driver architecture
and hit the hardware their own way.
Alternatively there are a couple of free (but closed source) ASIO
implementations which connect to the lower level Windows
"Kernel Streaming" API, but again these require special installation
by the user, and can be limited in functionality or difficult to use.
This is where the PortAudio "WDM-KS" host implementation comes in.
It directly connects PortAudio to the same Kernel Streaming API which
those ASIO bridges use. This avoids the mixing penatly of DirectX,
giving at least as good latency as any ASIO driver, but it has the
advantage of working with ANY Windows audio hardware which is available
through the normal MME/DirectX routes without the user requiring
any additional device drivers to be installed, and allowing all
device selection to be done through the normal PortAudio API.
Note that in general you should only be using this host API if your
application has a real requirement for very low latency audio (<20ms),
either because you are generating sounds in real-time based upon
user input, or you a processing recorded audio in real time.
The only thing to be aware of is that using the KS interface will
block that device from being used by the rest of system through
the higher level APIs, or conversely, if the system is using
a device, the KS API will not be able to use it. MS recommend that
you should keep the device open only when your application has focus.
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 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
ks.h and ksmedia.h header files.
You will need to link to the system "setupapi" library.
Note that if you use MinGW, you will get more warnings from
the DX header files when using GCC(C), and still a few warnings
with G++(CPP).

File diff suppressed because it is too large Load Diff

View File

@ -1,103 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library UNIX initialization table
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, 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 unix_src
*/
#include "pa_hostapi.h"
PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
/* Added for IRIX, Pieter, oct 2, 2003: */
PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
/* Linux AudioScience HPI */
PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
/** Note that on Linux, ALSA is placed before OSS so that the former is preferred over the latter.
*/
PaUtilHostApiInitializer *paHostApiInitializers[] =
{
#ifdef __linux__
#if PA_USE_ALSA
PaAlsa_Initialize,
#endif
#if PA_USE_OSS
PaOSS_Initialize,
#endif
#else /* __linux__ */
#if PA_USE_OSS
PaOSS_Initialize,
#endif
#if PA_USE_ALSA
PaAlsa_Initialize,
#endif
#endif /* __linux__ */
#if PA_USE_JACK
PaJack_Initialize,
#endif
/* Added for IRIX, Pieter, oct 2, 2003: */
#if PA_USE_SGI
PaSGI_Initialize,
#endif
#if PA_USE_ASIHPI
PaAsiHpi_Initialize,
#endif
#if PA_USE_COREAUDIO
PaMacCore_Initialize,
#endif
#if PA_USE_SKELETON
PaSkeleton_Initialize,
#endif
0 /* NULL terminated array */
};

View File

@ -1,710 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library
* UNIX platform-specific support functions
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2000 Ross Bencina
*
* 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 unix_src
*/
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <string.h> /* For memset */
#include <math.h>
#include <errno.h>
#if defined(__APPLE__) && !defined(HAVE_MACH_ABSOLUTE_TIME)
#define HAVE_MACH_ABSOLUTE_TIME
#endif
#ifdef HAVE_MACH_ABSOLUTE_TIME
#include <mach/mach_time.h>
#endif
#include "pa_util.h"
#include "pa_unix_util.h"
#include "pa_debugprint.h"
/*
Track memory allocations to avoid leaks.
*/
#if PA_TRACK_MEMORY
static int numAllocations_ = 0;
#endif
void *PaUtil_AllocateMemory( long size )
{
void *result = malloc( size );
#if PA_TRACK_MEMORY
if( result != NULL ) numAllocations_ += 1;
#endif
return result;
}
void PaUtil_FreeMemory( void *block )
{
if( block != NULL )
{
free( block );
#if PA_TRACK_MEMORY
numAllocations_ -= 1;
#endif
}
}
int PaUtil_CountCurrentlyAllocatedBlocks( void )
{
#if PA_TRACK_MEMORY
return numAllocations_;
#else
return 0;
#endif
}
void Pa_Sleep( long msec )
{
#ifdef HAVE_NANOSLEEP
struct timespec req = {0}, rem = {0};
PaTime time = msec / 1.e3;
req.tv_sec = (time_t)time;
assert(time - req.tv_sec < 1.0);
req.tv_nsec = (long)((time - req.tv_sec) * 1.e9);
nanosleep(&req, &rem);
/* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */
#else
while( msec > 999 ) /* For OpenBSD and IRIX, argument */
{ /* to usleep must be < 1000000. */
usleep( 999000 );
msec -= 999;
}
usleep( msec * 1000 );
#endif
}
#ifdef HAVE_MACH_ABSOLUTE_TIME
/*
Discussion on the CoreAudio mailing list suggests that calling
gettimeofday (or anything else in the BSD layer) is not real-time
safe, so we use mach_absolute_time on OSX. This implementation is
based on these two links:
Technical Q&A QA1398 - Mach Absolute Time Units
http://developer.apple.com/mac/library/qa/qa2004/qa1398.html
Tutorial: Performance and Time.
http://www.macresearch.org/tutorial_performance_and_time
*/
/* Scaler to convert the result of mach_absolute_time to seconds */
static double machSecondsConversionScaler_ = 0.0;
#endif
void PaUtil_InitializeClock( void )
{
#ifdef HAVE_MACH_ABSOLUTE_TIME
mach_timebase_info_data_t info;
kern_return_t err = mach_timebase_info( &info );
if( err == 0 )
machSecondsConversionScaler_ = 1e-9 * (double) info.numer / (double) info.denom;
#endif
}
PaTime PaUtil_GetTime( void )
{
#ifdef HAVE_MACH_ABSOLUTE_TIME
return mach_absolute_time() * machSecondsConversionScaler_;
#elif defined(HAVE_CLOCK_GETTIME)
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return (PaTime)(tp.tv_sec + tp.tv_nsec * 1e-9);
#else
struct timeval tv;
gettimeofday( &tv, NULL );
return (PaTime) tv.tv_usec * 1e-6 + tv.tv_sec;
#endif
}
PaError PaUtil_InitializeThreading( PaUtilThreading *threading )
{
(void) paUtilErr_;
return paNoError;
}
void PaUtil_TerminateThreading( PaUtilThreading *threading )
{
}
PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data )
{
pthread_create( &threading->callbackThread, NULL, threadRoutine, data );
return paNoError;
}
PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult )
{
PaError result = paNoError;
void *pret;
if( exitResult )
*exitResult = paNoError;
/* If pthread_cancel is not supported (Android platform) whole this function can lead to indefinite waiting if
working thread (callbackThread) has'n received any stop signals from outside, please keep
this in mind when considering using PaUtil_CancelThreading
*/
#ifdef PTHREAD_CANCELED
/* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
if( !wait )
pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */
#endif
pthread_join( threading->callbackThread, &pret );
#ifdef PTHREAD_CANCELED
if( pret && PTHREAD_CANCELED != pret )
#else
/* !wait means the thread may have been canceled */
if( pret && wait )
#endif
{
if( exitResult )
*exitResult = *(PaError *) pret;
free( pret );
}
return result;
}
/* Threading */
/* paUnixMainThread
* We have to be a bit careful with defining this global variable,
* as explained below. */
#ifdef __APPLE__
/* apple/gcc has a "problem" with global vars and dynamic libs.
Initializing it seems to fix the problem.
Described a bit in this thread:
http://gcc.gnu.org/ml/gcc/2005-06/msg00179.html
*/
pthread_t paUnixMainThread = 0;
#else
/*pthreads are opaque. We don't know that asigning it an int value
always makes sense, so we don't initialize it unless we have to.*/
pthread_t paUnixMainThread = 0;
#endif
PaError PaUnixThreading_Initialize()
{
paUnixMainThread = pthread_self();
return paNoError;
}
static PaError BoostPriority( PaUnixThread* self )
{
PaError result = paNoError;
struct sched_param spm = { 0 };
/* Priority should only matter between contending FIFO threads? */
spm.sched_priority = 1;
assert( self );
if( pthread_setschedparam( self->thread, SCHED_FIFO, &spm ) != 0 )
{
PA_UNLESS( errno == EPERM, paInternalError ); /* Lack permission to raise priority */
PA_DEBUG(( "Failed bumping priority\n" ));
result = 0;
}
else
{
result = 1; /* Success */
}
error:
return result;
}
PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild,
int rtSched )
{
PaError result = paNoError;
pthread_attr_t attr;
int started = 0;
memset( self, 0, sizeof (PaUnixThread) );
PaUnixMutex_Initialize( &self->mtx );
PA_ASSERT_CALL( pthread_cond_init( &self->cond, NULL ), 0 );
self->parentWaiting = 0 != waitForChild;
/* Spawn thread */
/* Temporarily disabled since we should test during configuration for presence of required mman.h header */
#if 0
#if defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1)
if( rtSched )
{
if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 )
{
int savedErrno = errno; /* In case errno gets overwritten */
assert( savedErrno != EINVAL ); /* Most likely a programmer error */
PA_UNLESS( (savedErrno == EPERM), paInternalError );
PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ ));
}
else
PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ ));
}
#endif
#endif
PA_UNLESS( !pthread_attr_init( &attr ), paInternalError );
/* Priority relative to other processes */
PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );
PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError );
started = 1;
if( rtSched )
{
#if 0
if( self->useWatchdog )
{
int err;
struct sched_param wdSpm = { 0 };
/* Launch watchdog, watchdog sets callback thread priority */
int prio = PA_MIN( self->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) );
wdSpm.sched_priority = prio;
PA_UNLESS( !pthread_attr_init( &attr ), paInternalError );
PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError );
PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );
PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError );
PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError );
if( (err = pthread_create( &self->watchdogThread, &attr, &WatchdogFunc, self )) )
{
PA_UNLESS( err == EPERM, paInternalError );
/* Permission error, go on without realtime privileges */
PA_DEBUG(( "Failed bumping priority\n" ));
}
else
{
int policy;
self->watchdogRunning = 1;
PA_ENSURE_SYSTEM( pthread_getschedparam( self->watchdogThread, &policy, &wdSpm ), 0 );
/* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */
if( wdSpm.sched_priority != prio )
{
PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority ));
PA_ENSURE( paInternalError );
}
}
}
else
#endif
PA_ENSURE( BoostPriority( self ) );
{
int policy;
struct sched_param spm;
pthread_getschedparam(self->thread, &policy, &spm);
}
}
if( self->parentWaiting )
{
PaTime till;
struct timespec ts;
int res = 0;
PaTime now;
PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) );
/* Wait for stream to be started */
now = PaUtil_GetTime();
till = now + waitForChild;
while( self->parentWaiting && !res )
{
if( waitForChild > 0 )
{
ts.tv_sec = (time_t) floor( till );
ts.tv_nsec = (long) ((till - floor( till )) * 1e9);
res = pthread_cond_timedwait( &self->cond, &self->mtx.mtx, &ts );
}
else
{
res = pthread_cond_wait( &self->cond, &self->mtx.mtx );
}
}
PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) );
PA_UNLESS( !res || ETIMEDOUT == res, paInternalError );
PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - now ));
if( ETIMEDOUT == res )
{
PA_ENSURE( paTimedOut );
}
}
end:
return result;
error:
if( started )
{
PaUnixThread_Terminate( self, 0, NULL );
}
goto end;
}
PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult )
{
PaError result = paNoError;
void* pret;
if( exitResult )
{
*exitResult = paNoError;
}
#if 0
if( watchdogExitResult )
*watchdogExitResult = paNoError;
if( th->watchdogRunning )
{
pthread_cancel( th->watchdogThread );
PA_ENSURE_SYSTEM( pthread_join( th->watchdogThread, &pret ), 0 );
if( pret && pret != PTHREAD_CANCELED )
{
if( watchdogExitResult )
*watchdogExitResult = *(PaError *) pret;
free( pret );
}
}
#endif
/* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
/* TODO: Make join time out */
self->stopRequested = wait;
if( !wait )
{
PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread ));
/* XXX: Safe to call this if the thread has exited on its own? */
#ifdef PTHREAD_CANCELED
pthread_cancel( self->thread );
#endif
}
PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread ));
PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 );
#ifdef PTHREAD_CANCELED
if( pret && PTHREAD_CANCELED != pret )
#else
/* !wait means the thread may have been canceled */
if( pret && wait )
#endif
{
if( exitResult )
{
*exitResult = *(PaError*)pret;
}
free( pret );
}
error:
PA_ASSERT_CALL( PaUnixMutex_Terminate( &self->mtx ), paNoError );
PA_ASSERT_CALL( pthread_cond_destroy( &self->cond ), 0 );
return result;
}
PaError PaUnixThread_PrepareNotify( PaUnixThread* self )
{
PaError result = paNoError;
PA_UNLESS( self->parentWaiting, paInternalError );
PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) );
self->locked = 1;
error:
return result;
}
PaError PaUnixThread_NotifyParent( PaUnixThread* self )
{
PaError result = paNoError;
PA_UNLESS( self->parentWaiting, paInternalError );
if( !self->locked )
{
PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) );
self->locked = 1;
}
self->parentWaiting = 0;
pthread_cond_signal( &self->cond );
PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) );
self->locked = 0;
error:
return result;
}
int PaUnixThread_StopRequested( PaUnixThread* self )
{
return self->stopRequested;
}
PaError PaUnixMutex_Initialize( PaUnixMutex* self )
{
PaError result = paNoError;
PA_ASSERT_CALL( pthread_mutex_init( &self->mtx, NULL ), 0 );
return result;
}
PaError PaUnixMutex_Terminate( PaUnixMutex* self )
{
PaError result = paNoError;
PA_ASSERT_CALL( pthread_mutex_destroy( &self->mtx ), 0 );
return result;
}
/** Lock mutex.
*
* We're disabling thread cancellation while the thread is holding a lock, so mutexes are
* properly unlocked at termination time.
*/
PaError PaUnixMutex_Lock( PaUnixMutex* self )
{
PaError result = paNoError;
#ifdef PTHREAD_CANCEL
int oldState;
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 );
#endif
PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 );
error:
return result;
}
/** Unlock mutex.
*
* Thread cancellation is enabled again after the mutex is properly unlocked.
*/
PaError PaUnixMutex_Unlock( PaUnixMutex* self )
{
PaError result = paNoError;
PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 );
#ifdef PTHREAD_CANCEL
int oldState;
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 );
#endif
error:
return result;
}
#if 0
static void OnWatchdogExit( void *userData )
{
PaAlsaThreading *th = (PaAlsaThreading *) userData;
struct sched_param spm = { 0 };
assert( th );
PA_ASSERT_CALL( pthread_setschedparam( th->callbackThread, SCHED_OTHER, &spm ), 0 ); /* Lower before exiting */
PA_DEBUG(( "Watchdog exiting\n" ));
}
static void *WatchdogFunc( void *userData )
{
PaError result = paNoError, *pres = NULL;
int err;
PaAlsaThreading *th = (PaAlsaThreading *) userData;
unsigned intervalMsec = 500;
const PaTime maxSeconds = 3.; /* Max seconds between callbacks */
PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed;
double cpuLoad, avgCpuLoad = 0.;
int throttled = 0;
assert( th );
/* Execute OnWatchdogExit when exiting */
pthread_cleanup_push( &OnWatchdogExit, th );
/* Boost priority of callback thread */
PA_ENSURE( result = BoostPriority( th ) );
if( !result )
{
/* Boost failed, might as well exit */
pthread_exit( NULL );
}
cpuTimeThen = th->callbackCpuTime;
{
int policy;
struct sched_param spm = { 0 };
pthread_getschedparam( pthread_self(), &policy, &spm );
PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority ));
}
while( 1 )
{
double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff;
/* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */
pthread_testcancel();
Pa_Sleep( intervalMsec );
pthread_testcancel();
if( PaUtil_GetTime() - th->callbackTime > maxSeconds )
{
PA_DEBUG(( "Watchdog: Terminating callback thread\n" ));
/* Tell thread to terminate */
err = pthread_kill( th->callbackThread, SIGKILL );
pthread_exit( NULL );
}
PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) ));
/* Check if we should throttle, or unthrottle :P */
cpuTimeNow = th->callbackCpuTime;
cpuTimeElapsed = cpuTimeNow - cpuTimeThen;
cpuTimeThen = cpuTimeNow;
timeNow = PaUtil_GetTime();
timeElapsed = timeNow - timeThen;
timeThen = timeNow;
cpuLoad = cpuTimeElapsed / timeElapsed;
avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1;
/*
if( throttled )
PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed ));
*/
if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 )
{
static int policy;
static struct sched_param spm = { 0 };
static const struct sched_param defaultSpm = { 0 };
PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority ));
pthread_getschedparam( th->callbackThread, &policy, &spm );
if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) )
{
throttled = 1;
}
else
PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) ));
/* Give other processes a go, before raising priority again */
PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime ));
Pa_Sleep( th->throttledSleepTime );
/* Reset callback priority */
if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 )
{
PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) ));
}
if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 )
intervalMsec = 50;
else
intervalMsec = 100;
/*
lowpassCoeff = .97;
lowpassCoeff1 = .99999 - lowpassCoeff;
*/
}
else if( throttled && avgCpuLoad < .8 )
{
intervalMsec = 500;
throttled = 0;
/*
lowpassCoeff = .9;
lowpassCoeff1 = .99999 - lowpassCoeff;
*/
}
}
pthread_cleanup_pop( 1 ); /* Execute cleanup on exit */
error:
/* Shouldn't get here in the normal case */
/* Pass on error code */
pres = malloc( sizeof (PaError) );
*pres = result;
pthread_exit( pres );
}
static void CallbackUpdate( PaAlsaThreading *th )
{
th->callbackTime = PaUtil_GetTime();
th->callbackCpuTime = PaUtil_GetCpuLoad( th->cpuLoadMeasurer );
}
/*
static void *CanaryFunc( void *userData )
{
const unsigned intervalMsec = 1000;
PaUtilThreading *th = (PaUtilThreading *) userData;
while( 1 )
{
th->canaryTime = PaUtil_GetTime();
pthread_testcancel();
Pa_Sleep( intervalMsec );
}
pthread_exit( NULL );
}
*/
#endif

View File

@ -1,224 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library
* UNIX platform-specific support functions
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2000 Ross Bencina
*
* 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 unix_src
*/
#ifndef PA_UNIX_UTIL_H
#define PA_UNIX_UTIL_H
#include "pa_cpuload.h"
#include <assert.h>
#include <pthread.h>
#include <signal.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) )
#define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) )
/* Utilize GCC branch prediction for error tests */
#if defined __GNUC__ && __GNUC__ >= 3
#define UNLIKELY(expr) __builtin_expect( (expr), 0 )
#else
#define UNLIKELY(expr) (expr)
#endif
#define STRINGIZE_HELPER(expr) #expr
#define STRINGIZE(expr) STRINGIZE_HELPER(expr)
#define PA_UNLESS(expr, code) \
do { \
if( UNLIKELY( (expr) == 0 ) ) \
{ \
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
result = (code); \
goto error; \
} \
} while (0);
static PaError paUtilErr_; /* Used with PA_ENSURE */
/* Check PaError */
#define PA_ENSURE(expr) \
do { \
if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \
{ \
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
result = paUtilErr_; \
goto error; \
} \
} while (0);
#define PA_ASSERT_CALL(expr, success) \
paUtilErr_ = (expr); \
assert( success == paUtilErr_ );
#define PA_ENSURE_SYSTEM(expr, success) \
do { \
if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \
{ \
/* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
if( pthread_equal(pthread_self(), paUnixMainThread) ) \
{ \
PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \
} \
PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
result = paUnanticipatedHostError; \
goto error; \
} \
} while( 0 );
typedef struct {
pthread_t callbackThread;
} PaUtilThreading;
PaError PaUtil_InitializeThreading( PaUtilThreading *threading );
void PaUtil_TerminateThreading( PaUtilThreading *threading );
PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data );
PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult );
/* State accessed by utility functions */
/*
void PaUnix_SetRealtimeScheduling( int rt );
void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm );
PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s );
PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult );
void PaUtil_CallbackUpdate( PaUtilThreading *th );
*/
extern pthread_t paUnixMainThread;
typedef struct
{
pthread_mutex_t mtx;
} PaUnixMutex;
PaError PaUnixMutex_Initialize( PaUnixMutex* self );
PaError PaUnixMutex_Terminate( PaUnixMutex* self );
PaError PaUnixMutex_Lock( PaUnixMutex* self );
PaError PaUnixMutex_Unlock( PaUnixMutex* self );
typedef struct
{
pthread_t thread;
int parentWaiting;
int stopRequested;
int locked;
PaUnixMutex mtx;
pthread_cond_t cond;
volatile sig_atomic_t stopRequest;
} PaUnixThread;
/** Initialize global threading state.
*/
PaError PaUnixThreading_Initialize();
/** Perish, passing on eventual error code.
*
* A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread.
* If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically
* allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is
* well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should
* check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it.
* @param result: The error code to pass on to the joining thread.
*/
#define PaUnixThreading_EXIT(result) \
do { \
PaError* pres = NULL; \
if( paNoError != (result) ) \
{ \
pres = malloc( sizeof (PaError) ); \
*pres = (result); \
} \
pthread_exit( pres ); \
} while (0);
/** Spawn a thread.
*
* Intended for spawning the callback thread from the main thread. This function can even block (for a certain
* time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be
* useful in order to make sure that callback has commenced before returning from Pa_StartStream.
* @param threadFunc: The function to be executed in the child thread.
* @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means
* wait for ever, greater than 0 wait for the specified time.
* @param rtSched: Enable realtime scheduling?
* @return: If timed out waiting on child, paTimedOut.
*/
PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild,
int rtSched );
/** Terminate thread.
*
* @param wait: If true, request that background thread stop and wait untill it does, else cancel it.
* @param exitResult: If non-null this will upon return contain the exit status of the thread.
*/
PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult );
/** Prepare to notify waiting parent thread.
*
* An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to
* acquire it beforehand.
* @return: If parent is not waiting, paInternalError.
*/
PaError PaUnixThread_PrepareNotify( PaUnixThread* self );
/** Notify waiting parent thread.
*
* @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError.
*/
PaError PaUnixThread_NotifyParent( PaUnixThread* self );
/** Has the parent thread requested this thread to stop?
*/
int PaUnixThread_StopRequested( PaUnixThread* self );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -1,148 +0,0 @@
/*
* Microsoft COM initialization routines
* Copyright (c) 1999-2011 Ross Bencina, Dmitry Kostjuchenko
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2011 Ross Bencina, 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 win_src
@brief Microsoft COM initialization routines.
*/
#include <windows.h>
#include <objbase.h>
#include "portaudio.h"
#include "pa_util.h"
#include "pa_debugprint.h"
#include "pa_win_coinitialize.h"
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) /* MSC version 6 and above */
#pragma comment( lib, "ole32.lib" )
#endif
/* use some special bit patterns here to try to guard against uninitialized memory errors */
#define PAWINUTIL_COM_INITIALIZED (0xb38f)
#define PAWINUTIL_COM_NOT_INITIALIZED (0xf1cd)
PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
{
HRESULT hr;
comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
/*
If COM is already initialized CoInitialize will either return
FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different
threading mode. In either case we shouldn't consider it an error
but we need to be careful to not call CoUninitialize() if
RPC_E_CHANGED_MODE was returned.
*/
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP)
hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */
#else
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
#endif
if( FAILED(hr) && hr != RPC_E_CHANGED_MODE )
{
PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr));
if( hr == E_OUTOFMEMORY )
return paInsufficientMemory;
{
char *lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
PaUtil_SetLastHostErrorInfo( hostApiType, hr, lpMsgBuf );
LocalFree( lpMsgBuf );
}
return paUnanticipatedHostError;
}
if( hr != RPC_E_CHANGED_MODE )
{
comInitializationResult->state = PAWINUTIL_COM_INITIALIZED;
/*
Memorize calling thread id and report warning on Uninitialize if
calling thread is different as CoInitialize must match CoUninitialize
in the same thread.
*/
comInitializationResult->initializingThreadId = GetCurrentThreadId();
}
return paNoError;
}
void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
{
if( comInitializationResult->state != PAWINUTIL_COM_NOT_INITIALIZED
&& comInitializationResult->state != PAWINUTIL_COM_INITIALIZED ){
PA_DEBUG(("ERROR: PaWinUtil_CoUninitialize called without calling PaWinUtil_CoInitialize\n"));
}
if( comInitializationResult->state == PAWINUTIL_COM_INITIALIZED )
{
DWORD currentThreadId = GetCurrentThreadId();
if( comInitializationResult->initializingThreadId != currentThreadId )
{
PA_DEBUG(("ERROR: failed PaWinUtil_CoUninitialize calling thread[%d] does not match initializing thread[%d]\n",
currentThreadId, comInitializationResult->initializingThreadId));
}
else
{
CoUninitialize();
comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
}
}
}

View File

@ -1,94 +0,0 @@
/*
* Microsoft COM initialization routines
* Copyright (c) 1999-2011 Ross Bencina, 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 win_src
@brief Microsoft COM initialization routines.
*/
#ifndef PA_WIN_COINITIALIZE_H
#define PA_WIN_COINITIALIZE_H
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/**
@brief Data type used to hold the result of an attempt to initialize COM
using PaWinUtil_CoInitialize. Must be retained between a call to
PaWinUtil_CoInitialize and a matching call to PaWinUtil_CoUninitialize.
*/
typedef struct PaWinUtilComInitializationResult{
int state;
int initializingThreadId;
} PaWinUtilComInitializationResult;
/**
@brief Initialize Microsoft COM subsystem on the current thread.
@param hostApiType the host API type id of the caller. Used for error reporting.
@param comInitializationResult An output parameter. The value pointed to by
this parameter stores information required by PaWinUtil_CoUninitialize
to correctly uninitialize COM. The value should be retained and later
passed to PaWinUtil_CoUninitialize.
If PaWinUtil_CoInitialize returns paNoError, the caller must later call
PaWinUtil_CoUninitialize once.
*/
PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult );
/**
@brief Uninitialize the Microsoft COM subsystem on the current thread using
the result of a previous call to PaWinUtil_CoInitialize. Must be called on the same
thread as PaWinUtil_CoInitialize.
@param hostApiType the host API type id of the caller. Used for error reporting.
@param comInitializationResult An input parameter. A pointer to a value previously
initialized by a call to PaWinUtil_CoInitialize.
*/
void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_WIN_COINITIALIZE_H */

View File

@ -1,102 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library Windows initialization table
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2008 Ross Bencina, 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 win_src
@brief Win32 host API initialization function table.
*/
/* This is needed to make this source file depend on CMake option changes
and at the same time make it transparent for clients not using CMake.
*/
#ifdef PORTAUDIO_CMAKE_GENERATED
#include "options_cmake.h"
#endif
#include "pa_hostapi.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
#ifdef __cplusplus
}
#endif /* __cplusplus */
PaUtilHostApiInitializer *paHostApiInitializers[] =
{
#if PA_USE_WMME
PaWinMme_Initialize,
#endif
#if PA_USE_DS
PaWinDs_Initialize,
#endif
#if PA_USE_ASIO
PaAsio_Initialize,
#endif
#if PA_USE_WASAPI
PaWasapi_Initialize,
#endif
#if PA_USE_WDMKS
PaWinWdm_Initialize,
#endif
#if PA_USE_SKELETON
PaSkeleton_Initialize, /* just for testing. last in list so it isn't marked as default. */
#endif
0 /* NULL terminated array */
};

View File

@ -1,160 +0,0 @@
/*
* $Id$
* Portable Audio I/O Library
* Win32 platform-specific support functions
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2008 Ross Bencina
*
* 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 win_src
@brief Win32 implementation of platform-specific PaUtil support functions.
*/
#include <windows.h>
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#include <sys/timeb.h> /* for _ftime_s() */
#else
#include <mmsystem.h> /* for timeGetTime() */
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
#pragma comment( lib, "winmm.lib" )
#endif
#endif
#include "pa_util.h"
/*
Track memory allocations to avoid leaks.
*/
#if PA_TRACK_MEMORY
static int numAllocations_ = 0;
#endif
void *PaUtil_AllocateMemory( long size )
{
void *result = GlobalAlloc( GPTR, size );
#if PA_TRACK_MEMORY
if( result != NULL ) numAllocations_ += 1;
#endif
return result;
}
void PaUtil_FreeMemory( void *block )
{
if( block != NULL )
{
GlobalFree( block );
#if PA_TRACK_MEMORY
numAllocations_ -= 1;
#endif
}
}
int PaUtil_CountCurrentlyAllocatedBlocks( void )
{
#if PA_TRACK_MEMORY
return numAllocations_;
#else
return 0;
#endif
}
void Pa_Sleep( long msec )
{
Sleep( msec );
}
static int usePerformanceCounter_;
static double secondsPerTick_;
void PaUtil_InitializeClock( void )
{
LARGE_INTEGER ticksPerSecond;
if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 )
{
usePerformanceCounter_ = 1;
secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart;
}
else
{
usePerformanceCounter_ = 0;
}
}
double PaUtil_GetTime( void )
{
LARGE_INTEGER time;
if( usePerformanceCounter_ )
{
/*
Note: QueryPerformanceCounter has a known issue where it can skip forward
by a few seconds (!) due to a hardware bug on some PCI-ISA bridge hardware.
This is documented here:
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&
The work-arounds are not very paletable and involve querying GetTickCount
at every time step.
Using rdtsc is not a good option on multi-core systems.
For now we just use QueryPerformanceCounter(). It's good, most of the time.
*/
QueryPerformanceCounter( &time );
return time.QuadPart * secondsPerTick_;
}
else
{
#ifndef UNDER_CE
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
return GetTickCount64() * .001;
#else
return timeGetTime() * .001;
#endif
#else
return GetTickCount() * .001;
#endif
}
}

Some files were not shown because too many files have changed in this diff Show More