Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PortAudio: sync to upstream #11604

Merged
merged 3 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 54 additions & 11 deletions 3rdparty/portaudio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,33 @@ else()
set(LIBRARY_BUILD_TYPE STATIC)
endif()

option(PA_WARNINGS_ARE_ERRORS "Turn compiler warnings into errors" OFF)
if(PA_WARNINGS_ARE_ERRORS)
if(MSVC)
add_compile_options(/WX
# "Grandfathered" warnings that existed before we started enforcement.
# Do *NOT* add warnings to this list. Instead, fix your code so that it doesn't produce the warning.
# TODO: fix the offending code so that we don't have to exclude specific warnings anymore.
/wd4244 # W2 conversion possible loss of data
/wd4267 # W3 conversion possible loss of data
/wd4996 # W3 unsafe/deprecated
)
else()
add_compile_options(-Werror
# "Grandfathered" warnings that existed before we started enforcement.
# Do *NOT* add warnings to this list. Instead, fix your code so that it doesn't produce the warning.
# TODO: fix the offending code so that we don't have to exclude specific warnings anymore.
-Wno-error=deprecated-declarations # https://github.com/PortAudio/portaudio/issues/213 https://github.com/PortAudio/portaudio/issues/641
-Wno-error=stringop-overflow
)
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
# Don't fail on older clang versions that don't recognize the latest warnings in the list above.
# Note that unrecognized warning options are not a fatal error on GCC, and in fact, GCC will choke on this option. Hence the conditional.
add_compile_options(-Wno-error=unknown-warning-option)
endif()
endif()
endif()

add_library(PortAudio
${LIBRARY_BUILD_TYPE}
src/common/pa_allocation.c
Expand Down Expand Up @@ -130,6 +157,8 @@ if(WIN32)
src/os/win/pa_win_hostapis.c
src/os/win/pa_win_util.c
src/os/win/pa_win_util.h
src/os/win/pa_win_version.c
src/os/win/pa_win_version.h
src/os/win/pa_win_waveformat.c
src/os/win/pa_win_wdmks_utils.h
src/os/win/pa_x86_plain_converters.h
Expand Down Expand Up @@ -278,17 +307,13 @@ elseif(UNIX)
target_include_directories(PortAudio PRIVATE src/hostapi/coreaudio)
set(PORTAUDIO_PUBLIC_HEADERS "${PORTAUDIO_PUBLIC_HEADERS}" include/pa_mac_core.h)

find_library(COREAUDIO_LIBRARY CoreAudio REQUIRED)
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox REQUIRED)
find_library(AUDIOUNIT_LIBRARY AudioUnit REQUIRED)
find_library(COREFOUNDATION_LIBRARY CoreFoundation REQUIRED)
find_library(CORESERVICES_LIBRARY CoreServices REQUIRED)
target_link_libraries(PortAudio PRIVATE
"${COREAUDIO_LIBRARY}"
"${AUDIOTOOLBOX_LIBRARY}"
"${AUDIOUNIT_LIBRARY}"
"${COREFOUNDATION_LIBRARY}"
"${CORESERVICES_LIBRARY}"
target_link_libraries(PortAudio
PRIVATE
-Wl,-framework,CoreAudio
-Wl,-framework,AudioToolbox
-Wl,-framework,AudioUnit
-Wl,-framework,CoreFoundation
-Wl,-framework,CoreServices
)
target_compile_definitions(PortAudio PUBLIC PA_USE_COREAUDIO=1)
set(PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS} -DPA_USE_COREAUDIO=1")
Expand Down Expand Up @@ -340,6 +365,24 @@ elseif(UNIX)
target_compile_definitions(PortAudio PUBLIC PA_USE_AUDIOIO=1)
set(PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS} -DPA_USE_AUDIOIO=1")
endif()

find_package(PulseAudio)
cmake_dependent_option(PA_USE_PULSEAUDIO "Enable support for PulseAudio general purpose sound server" ON PulseAudio_FOUND OFF)
if(PA_USE_PULSEAUDIO)
target_link_libraries(PortAudio PRIVATE PulseAudio::PulseAudio)
target_sources(PortAudio PRIVATE
src/hostapi/pulseaudio/pa_linux_pulseaudio_block.c
src/hostapi/pulseaudio/pa_linux_pulseaudio.c
src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c)

target_compile_definitions(PortAudio PUBLIC PA_USE_PULSEAUDIO=1)
set(PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS} -DPA_USE_PULSEAUDIO=1")
set(PKGCONFIG_REQUIRES_PRIVATE "${PKGCONFIG_REQUIRES_PRIVATE} libpulse")

# needed for PortAudioConfig.cmake so `find_package(PortAudio)` works in downstream projects
install(FILES cmake/modules/FindPulseAudio.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/portaudio/modules")
endif()

endif()
endif()

Expand Down
7 changes: 4 additions & 3 deletions 3rdparty/portaudio/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ PALIB = libportaudio.la
PAINC = include/portaudio.h

PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined \
-export-symbols-regex "(Pa|PaMacCore|PaJack|PaAlsa|PaAsio|PaOSS|PaWasapi|PaWasapiWinrt|PaWinMME)_.*" \
-export-symbols-regex "(Pa|PaMacCore|PaPulseAudio|PaJack|PaAlsa|PaAsio|PaOSS|PaWasapi|PaWasapiWinrt|PaWinMME)_.*" \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)

COMMON_OBJS = \
Expand All @@ -66,7 +66,7 @@ LOOPBACK_OBJS = \
qa/loopback/src/test_audio_analyzer.o \
qa/loopback/src/write_wav.o \
qa/loopback/src/paqa.o

EXAMPLES = \
bin/pa_devs \
bin/pa_fuzz \
Expand All @@ -82,7 +82,7 @@ SELFTESTS = \
bin/paqa_devs \
bin/paqa_errs \
bin/paqa_latency

TESTS = \
bin/patest1 \
bin/patest_buffer \
Expand Down Expand Up @@ -146,6 +146,7 @@ SRC_DIRS = \
src/hostapi/coreaudio \
src/hostapi/dsound \
src/hostapi/jack \
src/hostapi/pulseaudio \
src/hostapi/oss \
src/hostapi/skeleton \
src/hostapi/wasapi \
Expand Down
1 change: 1 addition & 0 deletions 3rdparty/portaudio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Please feel free to join. See http://www.portaudio.com for details.
src/hostapi/dsound = Windows Direct Sound
src/hostapi/jack = JACK Audio Connection Kit
src/hostapi/oss = Unix Open Sound System (OSS)
src/hostapi/pulseaudio = Sound system for POSIX OSes
src/hostapi/wasapi = Windows Vista WASAPI
src/hostapi/wdmks = Windows WDM Kernel Streaming
src/hostapi/wmme = Windows MultiMedia Extensions (MME)
Expand Down
122 changes: 122 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
cmake_minimum_required(VERSION 3.13)
cmake_policy(VERSION 3.13)

project(PortAudioCpp VERSION 19.8 LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

# Todo (multi-generator): Add support for multiple generators like: - {Debug,
# Release} x {Static, Dynamic} x {MT, MD (Windows only)}

# ##############################################################################
# sources and headers
# ##############################################################################

set(portaudiocpp-sources
source/portaudiocpp/BlockingStream.cxx
source/portaudiocpp/CFunCallbackStream.cxx
source/portaudiocpp/CallbackInterface.cxx
source/portaudiocpp/CallbackStream.cxx
source/portaudiocpp/CppFunCallbackStream.cxx
source/portaudiocpp/Device.cxx
source/portaudiocpp/DirectionSpecificStreamParameters.cxx
source/portaudiocpp/Exception.cxx
source/portaudiocpp/HostApi.cxx
source/portaudiocpp/InterfaceCallbackStream.cxx
source/portaudiocpp/MemFunCallbackStream.cxx
source/portaudiocpp/Stream.cxx
source/portaudiocpp/StreamParameters.cxx
source/portaudiocpp/System.cxx
source/portaudiocpp/SystemDeviceIterator.cxx
source/portaudiocpp/SystemHostApiIterator.cxx)

# since we don't GLOBing this variable must be kept up to date otherwise user
# installations are broken.
set(portaudiocpp-header-files
include/portaudiocpp/AutoSystem.hxx
include/portaudiocpp/BlockingStream.hxx
include/portaudiocpp/CFunCallbackStream.hxx
include/portaudiocpp/CallbackInterface.hxx
include/portaudiocpp/CallbackStream.hxx
include/portaudiocpp/CppFunCallbackStream.hxx
include/portaudiocpp/Device.hxx
include/portaudiocpp/DirectionSpecificStreamParameters.hxx
include/portaudiocpp/Exception.hxx
include/portaudiocpp/HostApi.hxx
include/portaudiocpp/InterfaceCallbackStream.hxx
include/portaudiocpp/MemFunCallbackStream.hxx
include/portaudiocpp/PortAudioCpp.hxx
include/portaudiocpp/SampleDataFormat.hxx
include/portaudiocpp/Stream.hxx
include/portaudiocpp/StreamParameters.hxx
include/portaudiocpp/System.hxx
include/portaudiocpp/SystemDeviceIterator.hxx
include/portaudiocpp/SystemHostApiIterator.hxx)

if(WIN32)
find_package(ASIO MODULE)
if(ASIO_FOUND)
list(APPEND portaudiocpp-sources source/portaudiocpp/AsioDeviceAdapter.cxx)
list(APPEND portaudiocpp-header-files
include/portaudiocpp/AsioDeviceAdapter.hxx)
endif()
endif()

# ##############################################################################
# portaudiocpp-targets
# ##############################################################################

add_library(portaudiocpp ${portaudiocpp-sources})
add_library(PortAudio::portaudiocpp ALIAS portaudiocpp) # For subdirectory build

find_package(PortAudio MODULE REQUIRED)

target_link_libraries(portaudiocpp PUBLIC PortAudio::portaudio)
target_include_directories(
portaudiocpp PUBLIC $<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
set_target_properties(portaudiocpp PROPERTIES SOVERSION 2)
# Todo (modernize): update the code at least to c++14
# target_compile_features(portaudiocpp PUBLIC cxx_std_14)

# ## Export ###
include(GNUInstallDirs)

install(
TARGETS portaudiocpp
EXPORT PortAudioCppTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/portaudiocpp)

install(FILES ${portaudiocpp-header-files}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/portaudiocpp)

install(
EXPORT PortAudioCppTargets
FILE PortAudioCppTargets.cmake
NAMESPACE PortAudio::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PortAudio)

include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/PortAudioCppConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PortAudio)

write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/PortAudioCppConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PortAudio)

#use relative path, since CMAKE can't reconfigure on install with different prefix path
set(PC_PREFIX "\${pcfiledir}/../..")
configure_file(cmake/portaudiocpp.pc.in "${CMAKE_CURRENT_BINARY_DIR}/portaudiocpp.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/portaudiocpp.pc"
CONFIGURATIONS Release RelWithDebInfo
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/PortAudioCppTargets.cmake")

check_required_components(PortAudioCpp)
81 changes: 81 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/cmake/modules/FindASIO.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#[=======================================================================[.rst:
FindASIO
--------

Finds the ASIO SDK by searching for the SDK ZIP in CMAKE_PREFIX_PATH and
CMAKE_CURRENT_BINARY_DIR. Alternatively, you may manually specify the path of
the SDK ZIP with the ASIO_SDK_ZIP_PATH variable, which can be used for caching
in CI scripts.

If the ZIP is found, this module extracts it.
The ZIP extraction is skipped if the unzipped SDK is found.

This module provides an `ASIO::host` IMPORT library target for building host
applications which use ASIO drivers. If you want to build an ASIO driver, this
module may serve as a useful start but you will need to modify it.

#]=======================================================================]

if(NOT WIN32)
message(WARNING "ASIO is only supported on Windows.")
set(ASIO_FOUND OFF)
return()
endif()

file(GLOB HEADER_FILE
"${CMAKE_CURRENT_BINARY_DIR}/asiosdk*/common/asio.h"
"${CMAKE_PREFIX_PATH}/asiosdk*/common/asio.h"
# The old build systems before PortAudio 19.8 used to look for the ASIO SDK
# in the same parent directory as the source code repository. This is no
# longer advised or documented but kept for backwards compatibility.
"${CMAKE_CURRENT_SOURCE_DIR}/../asiosdk*/common/asio.h"
)
if(NOT EXISTS "${HEADER_FILE}")
# The file(ARCHIVE_EXTRACT) command was added in CMake 3.18, so if using an
# older version of CMake, the user needs to extract it themselves.
if(CMAKE_VERSION VERSION_LESS 3.18)
message(STATUS "ASIO SDK NOT found. Download the ASIO SDK ZIP from "
"https://www.steinberg.net/asiosdk and extract it to "
"${CMAKE_PREFIX_PATH} or ${CMAKE_CURRENT_BINARY_DIR}"
)
return()
endif()
file(GLOB results
"${ASIO_SDK_ZIP_PATH}"
"${CMAKE_CURRENT_BINARY_DIR}/asiosdk*.zip"
"${CMAKE_PREFIX_PATH}/asiosdk*.zip"
"${CMAKE_CURRENT_SOURCE_DIR}/../asiosdk*.zip"
)
foreach(f ${results})
if(EXISTS "${f}")
message(STATUS "Extracting ASIO SDK ZIP archive: ${f}")
file(ARCHIVE_EXTRACT INPUT "${f}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif()
endforeach()
file(GLOB HEADER_FILE "${CMAKE_CURRENT_BINARY_DIR}/asiosdk*/common/asio.h")
endif()

get_filename_component(HEADER_DIR "${HEADER_FILE}" DIRECTORY)
get_filename_component(ASIO_ROOT "${HEADER_DIR}" DIRECTORY)

if(ASIO_ROOT)
set(ASIO_FOUND TRUE)
message(STATUS "Found ASIO SDK: ${ASIO_ROOT}")

if(ASIO_FOUND AND NOT TARGET ASIO::host)
add_library(ASIO::host INTERFACE IMPORTED)
target_sources(ASIO::host INTERFACE
"${ASIO_ROOT}/common/asio.cpp"
"${ASIO_ROOT}/host/asiodrivers.cpp"
"${ASIO_ROOT}/host/pc/asiolist.cpp"
)
target_include_directories(ASIO::host INTERFACE
"${ASIO_ROOT}/common"
"${ASIO_ROOT}/host"
"${ASIO_ROOT}/host/pc"
)
target_link_libraries(ASIO::host INTERFACE ole32 uuid)
endif()
else()
message(STATUS "ASIO SDK NOT found")
endif()
39 changes: 39 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/cmake/modules/FindPortAudio.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

macro(handle_default)

endmacro()

if(TARGET PortAudio::portaudio)
# nothing to do
return()
endif()
# search for portaudio as cmake module
find_package(PortAudio CONFIG QUIET)
if(PortAudio_FOUND)
if(TARGET PortAudio::portaudio)
return()
elseif(TARGET portaudio)
# vcpkg and old portaudio installations do not provide the same targets
add_library(PortAudio::portaudio ALIAS portaudio)
return()
else()
message(FATAL_ERROR "PortAudio_FOUND but not target PortAudio::portaudio")
endif()
endif()

# search for portaudio via pkg-config

message(STATUS "portaudio could not be found via cmake, specify PortAudio_DIR.\n Searching for it via pkg-config")
find_package(PkgConfig REQUIRED)
pkg_check_modules(portaudio REQUIRED QUIET IMPORTED_TARGET GLOBAL portaudio-2.0)
add_library(PortAudio::portaudio ALIAS PkgConfig::portaudio)
return()

# include(FindPackageHandleStandardArgs)
# find_package_handle_standard_args(Foo
# FOUND_VAR Foo_FOUND
# REQUIRED_VARS
# Foo_LIBRARY
# Foo_INCLUDE_DIR
# VERSION_VAR Foo_VERSION
# )
12 changes: 12 additions & 0 deletions 3rdparty/portaudio/bindings/cpp/cmake/portaudiocpp.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
prefix=@PC_PREFIX@
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include

Name: PortAudioCpp
Description: Portable audio I/O C++ bindings
Version: 12
Requires: portaudio-2.0

Libs: -L${libdir} -lportaudiocpp
Cflags: -I${includedir}
Loading