From 685177d5ca60041e15dd6628292f4fd65877ded3 Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 15 Jul 2021 07:18:26 +0100 Subject: [PATCH 01/31] Remove WIP comment Signed-off-by: falkTX --- ChangeLog.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index df7d68316..59341c6ab 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -3,7 +3,6 @@ ChangeLog * 1.9.19 (2021-07-15) - * WIP (note to write asking CI help) * Add jack_position_t::tick_double, and flags around it * Add zalsa "-w" argument to wait for soundcard to be available * Bump internal protocol version to 9 (due to struct alignment) From caf336a6bc68ad0a8414ce1b6e40d40707cbc873 Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 28 Jul 2021 20:23:17 +0100 Subject: [PATCH 02/31] Fix custom win32 detection, fixes missing HAVE_ASIO macro Signed-off-by: falkTX --- wscript | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index e4494ffe3..174e81c0b 100644 --- a/wscript +++ b/wscript @@ -218,7 +218,7 @@ def configure(conf): if conf.env['IS_WINDOWS']: conf.env.append_unique('CCDEFINES', '_POSIX') conf.env.append_unique('CXXDEFINES', '_POSIX') - if Options.options.platform == 'msys': + if Options.options.platform in ('msys', 'win32'): conf.env.append_value('INCLUDES', ['/mingw64/include']) conf.check( header_name='asio.h', @@ -388,7 +388,7 @@ def configure(conf): # existing install paths that use ADDON_DIR rather than have to # have special cases for windows each time. conf.env['ADDON_DIR'] = conf.env['LIBDIR'] + '/jack' - if Options.options.platform == 'msys': + if Options.options.platform in ('msys', 'win32'): conf.define('ADDON_DIR', 'jack') conf.define('__STDC_FORMAT_MACROS', 1) # for PRIu64 else: From 70488cf2d0f66e7507732a6d8064d7890e674ec7 Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 28 Jul 2021 20:34:51 +0100 Subject: [PATCH 03/31] Better handling of optional asio Signed-off-by: falkTX --- windows/JackTypes_os.h | 4 ---- windows/portaudio/JackPortAudioDevices.h | 3 +++ wscript | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/windows/JackTypes_os.h b/windows/JackTypes_os.h index 3a5f4dc43..903274933 100644 --- a/windows/JackTypes_os.h +++ b/windows/JackTypes_os.h @@ -31,9 +31,5 @@ typedef UInt64 uint64_t; typedef unsigned short uint16_t; typedef DWORD jack_tls_key; -#if defined(__MINGW32__) -#define PRIu64 "llu" -#endif - #endif diff --git a/windows/portaudio/JackPortAudioDevices.h b/windows/portaudio/JackPortAudioDevices.h index 93af2541d..fa1fd3bb8 100644 --- a/windows/portaudio/JackPortAudioDevices.h +++ b/windows/portaudio/JackPortAudioDevices.h @@ -24,7 +24,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include + +#if defined(HAVE_ASIO) #include +#endif /*! \brief A PortAudio Devices manager. diff --git a/wscript b/wscript index 174e81c0b..f0c10b4ac 100644 --- a/wscript +++ b/wscript @@ -221,9 +221,8 @@ def configure(conf): if Options.options.platform in ('msys', 'win32'): conf.env.append_value('INCLUDES', ['/mingw64/include']) conf.check( - header_name='asio.h', - includes='/opt/asiosdk/common', - msg='Checking for ASIO SDK', + header_name='pa_asio.h', + msg='Checking for PortAudio ASIO support', define_name='HAVE_ASIO', mandatory=False) From 8d41e4357b39358d101198087cf2b23ef47c7ba6 Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 28 Jul 2021 20:42:41 +0100 Subject: [PATCH 04/31] Start of v1.9.20 Signed-off-by: falkTX --- ChangeLog.rst | 5 +++++ common/JackConstants.h | 2 +- wscript | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index 59341c6ab..cb67a8538 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,6 +1,11 @@ ChangeLog ######### +* 1.9.20 (2021-10-15) + + * WIP + * Fix incomplete ASIO support on Windows + * 1.9.19 (2021-07-15) * Add jack_position_t::tick_double, and flags around it diff --git a/common/JackConstants.h b/common/JackConstants.h index 0cf62ebc6..a0b94a579 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.19" +#define VERSION "1.9.20" #define BUFFER_SIZE_MAX 8192 diff --git a/wscript b/wscript index f0c10b4ac..e0d32c8de 100644 --- a/wscript +++ b/wscript @@ -11,7 +11,7 @@ import sys from waflib import Logs, Options, Task, Utils from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext -VERSION='1.9.19' +VERSION='1.9.20' APPNAME='jack' JACK_API_VERSION = '0.1.0' From 48558c054199d19659a04a1793f5f46217f51030 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Wed, 15 Jan 2020 20:21:58 -0800 Subject: [PATCH 05/31] example-clients: Use c++ compiler for jack_simdtests It uses c++ sources and runtime therefore its best to use c++ compiler to build it so it can find the correct runtime, cross compiling with clang fails x86_64-yoe-linux-ld: example-clients/simdtests.cpp.28.o: undefined reference to symbol '__cxa_call_unexpected@@CXXABI_1.3' Signed-off-by: Khem Raj --- example-clients/wscript | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/example-clients/wscript b/example-clients/wscript index 7e0b9931b..c452b6880 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -49,10 +49,15 @@ def build(bld): else: use = ['clientlib'] + if example_program == 'jack_simdtests': + ftrs = 'cxx cxxprogram' + else: + ftrs = 'c cprogram' + if bld.env['IS_MACOSX']: - prog = bld(features='c cprogram', framework = ['Foundation']) + prog = bld(features = ftrs, framework = ['Foundation']) else: - prog = bld(features='c cprogram') + prog = bld(features = ftrs) prog.includes = os_incdir + ['../common/jack', '../common'] prog.source = example_program_source prog.use = use From 0ba8607c7c5492cd2e4d053c822f5bee2a5651e0 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 13:04:30 +0100 Subject: [PATCH 06/31] First step towards automated builds Signed-off-by: falkTX --- .github/workflows/build.yml | 156 ++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..559cfb4ae --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,156 @@ +name: build + +on: + push: + branches: + - '*' + pull_request: + branches: + - '*' +env: + DEBIAN_FRONTEND: noninteractive + HOMEBREW_NO_AUTO_UPDATE: 1 + PAWPAW_VERSION: 8c69660ab10b75cd7a488f41386dbcb4c8802c5a + +jobs: + # macOS native intel build + macos: + runs-on: macos-10.15 + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Set up cache + uses: actions/cache@v2 + with: + path: | + ~/PawPawBuilds/builds + ~/PawPawBuilds/downloads + ~/PawPawBuilds/targets + key: cache-macos + - name: Set up dependencies + run: | + brew install cmake jq meson + - name: Bootstrap macOS intel + shell: bash + run: | + if [ ! -d PawPaw ]; then + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} + fi + ./PawPaw/bootstrap-jack2.sh macos && ./PawPaw/.cleanup.sh macos + + # macOS native universal build + macos_universal: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Set up cache + uses: actions/cache@v2 + with: + path: | + ~/PawPawBuilds/builds + ~/PawPawBuilds/downloads + ~/PawPawBuilds/targets + key: cache-macos-universal + - name: Set up dependencies + run: | + brew install cmake jq meson + - name: Fix up Xcode + run: | + sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/* + sudo xcode-select -s "/Applications/Xcode_12.3.app" + - name: Bootstrap macOS universal + shell: bash + run: | + if [ ! -d PawPaw ]; then + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} + fi + ./PawPaw/bootstrap-jack2.sh macos-universal && ./PawPaw/.cleanup.sh macos-universal + + # linux with win32 cross-compilation + win32: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Set up cache + uses: actions/cache@v2 + with: + path: | + ~/PawPawBuilds/builds + ~/PawPawBuilds/debs + ~/PawPawBuilds/downloads + ~/PawPawBuilds/targets + /var/cache/apt/archives + key: cache-win32 + #- name: Restore debian packages cache + #run: | + #if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ + #sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ + #fi + - name: Set up dependencies + run: | + wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - && \ + sudo dpkg --add-architecture i386 && \ + sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \ + sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ + binutils-mingw-w64-i686 g++-mingw-w64-i686 + #- name: Cache debian packages + #run: | + #mkdir -p ~/PawPawBuilds/debs && \ + #sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ + - name: Bootstrap win32 cross-compiled + shell: bash + run: | + if [ ! -d PawPaw ]; then + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} + fi + ./PawPaw/bootstrap-jack2.sh win32 && ./PawPaw/.cleanup.sh win32 + + # linux with win64 cross-compilation + win64: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Set up cache + uses: actions/cache@v2 + with: + path: | + ~/PawPawBuilds/builds + ~/PawPawBuilds/debs + ~/PawPawBuilds/downloads + ~/PawPawBuilds/targets + /var/cache/apt/archives + key: cache-win64 + #- name: Restore debian packages cache + #run: | + #if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ + #sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ + #fi + - name: Set up dependencies + run: | + wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - && \ + sudo dpkg --add-architecture i386 && \ + sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \ + sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ + binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 + #- name: Cache debian packages + #run: | + #mkdir -p ~/PawPawBuilds/debs && \ + #sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ + - name: Bootstrap win64 cross-compiled + shell: bash + run: | + if [ ! -d PawPaw ]; then + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} + fi + ./PawPaw/bootstrap-jack2.sh win64 && ./PawPaw/.cleanup.sh win64 From 8340794aff817e72f473d4bc097b705a50ada79a Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 13:31:39 +0100 Subject: [PATCH 07/31] CI: Add build jack2 step Signed-off-by: falkTX --- .github/workflows/build.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 559cfb4ae..c9f568b2b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,10 +39,17 @@ jobs: git -C PawPaw checkout ${PAWPAW_VERSION} fi ./PawPaw/bootstrap-jack2.sh macos && ./PawPaw/.cleanup.sh macos + - name: Build jack2 + shell: bash + run: | + pushd PawPaw && source local.env macos && popd + ~/PawPawBuilds/targets/macos/bin/python3 ./waf configure --platform=darwin --prefix=/usr/local + ~/PawPawBuilds/targets/macos/bin/python3 ./waf build -j $(sysctl -n hw.logicalcpu) + ~/PawPawBuilds/targets/macos/bin/python3 ./waf install --destdir="$(pwd)/destdir" # macOS native universal build macos_universal: - runs-on: macos-latest + runs-on: macos-10.15 steps: - uses: actions/checkout@v2 with: @@ -112,6 +119,13 @@ jobs: git -C PawPaw checkout ${PAWPAW_VERSION} fi ./PawPaw/bootstrap-jack2.sh win32 && ./PawPaw/.cleanup.sh win32 + - name: Build jack2 + shell: bash + run: | + pushd PawPaw && source local.env win32 && popd + wine ~/PawPawBuilds/targets/win32/bin/python3.exe ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static + wine ~/PawPawBuilds/targets/macos/bin/python3.exe ./waf build -j $(nproc) + wine ~/PawPawBuilds/targets/macos/bin/python3.exe ./waf install # linux with win64 cross-compilation win64: From 745796692c4c0a8929d3c3dd14cebbd56efc96d9 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 13:36:06 +0100 Subject: [PATCH 08/31] Cleanup Signed-off-by: falkTX --- .github/workflows/build.yml | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c9f568b2b..58d714a4d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,9 +43,9 @@ jobs: shell: bash run: | pushd PawPaw && source local.env macos && popd - ~/PawPawBuilds/targets/macos/bin/python3 ./waf configure --platform=darwin --prefix=/usr/local - ~/PawPawBuilds/targets/macos/bin/python3 ./waf build -j $(sysctl -n hw.logicalcpu) - ~/PawPawBuilds/targets/macos/bin/python3 ./waf install --destdir="$(pwd)/destdir" + python ./waf configure --platform=darwin --prefix=/usr/local + python ./waf build -j $(sysctl -n hw.logicalcpu) + python ./waf install --destdir="$(pwd)/destdir" # macOS native universal build macos_universal: @@ -90,16 +90,10 @@ jobs: with: path: | ~/PawPawBuilds/builds - ~/PawPawBuilds/debs ~/PawPawBuilds/downloads ~/PawPawBuilds/targets /var/cache/apt/archives key: cache-win32 - #- name: Restore debian packages cache - #run: | - #if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ - #sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ - #fi - name: Set up dependencies run: | wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - && \ @@ -107,10 +101,6 @@ jobs: sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \ sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ binutils-mingw-w64-i686 g++-mingw-w64-i686 - #- name: Cache debian packages - #run: | - #mkdir -p ~/PawPawBuilds/debs && \ - #sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ - name: Bootstrap win32 cross-compiled shell: bash run: | @@ -139,16 +129,10 @@ jobs: with: path: | ~/PawPawBuilds/builds - ~/PawPawBuilds/debs ~/PawPawBuilds/downloads ~/PawPawBuilds/targets /var/cache/apt/archives key: cache-win64 - #- name: Restore debian packages cache - #run: | - #if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ - #sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ - #fi - name: Set up dependencies run: | wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - && \ @@ -156,10 +140,6 @@ jobs: sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \ sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 - #- name: Cache debian packages - #run: | - #mkdir -p ~/PawPawBuilds/debs && \ - #sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ - name: Bootstrap win64 cross-compiled shell: bash run: | From d4a1c7b49b904e7f9e047dc4f858fefcc05d7320 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 13:43:56 +0100 Subject: [PATCH 09/31] Correct win32 build commands Signed-off-by: falkTX --- .github/workflows/build.yml | 48 ++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58d714a4d..b40ad03e5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,8 +35,8 @@ jobs: shell: bash run: | if [ ! -d PawPaw ]; then - git clone https://github.com/DISTRHO/PawPaw.git - git -C PawPaw checkout ${PAWPAW_VERSION} + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} fi ./PawPaw/bootstrap-jack2.sh macos && ./PawPaw/.cleanup.sh macos - name: Build jack2 @@ -73,10 +73,17 @@ jobs: shell: bash run: | if [ ! -d PawPaw ]; then - git clone https://github.com/DISTRHO/PawPaw.git - git -C PawPaw checkout ${PAWPAW_VERSION} + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} fi ./PawPaw/bootstrap-jack2.sh macos-universal && ./PawPaw/.cleanup.sh macos-universal + - name: Build jack2 + shell: bash + run: | + pushd PawPaw && source local.env macos-universal && popd + python ./waf configure --platform=darwin --prefix=/usr/local + python ./waf build -j $(sysctl -n hw.logicalcpu) + python ./waf install --destdir="$(pwd)/destdir" # linux with win32 cross-compilation win32: @@ -96,26 +103,26 @@ jobs: key: cache-win32 - name: Set up dependencies run: | - wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - && \ - sudo dpkg --add-architecture i386 && \ - sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \ + wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - + sudo dpkg --add-architecture i386 + sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ binutils-mingw-w64-i686 g++-mingw-w64-i686 - name: Bootstrap win32 cross-compiled shell: bash run: | if [ ! -d PawPaw ]; then - git clone https://github.com/DISTRHO/PawPaw.git - git -C PawPaw checkout ${PAWPAW_VERSION} + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} fi ./PawPaw/bootstrap-jack2.sh win32 && ./PawPaw/.cleanup.sh win32 - name: Build jack2 shell: bash run: | pushd PawPaw && source local.env win32 && popd - wine ~/PawPawBuilds/targets/win32/bin/python3.exe ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static - wine ~/PawPawBuilds/targets/macos/bin/python3.exe ./waf build -j $(nproc) - wine ~/PawPawBuilds/targets/macos/bin/python3.exe ./waf install + ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static + ./waf build -j $(nproc) + ./waf install # linux with win64 cross-compilation win64: @@ -135,16 +142,23 @@ jobs: key: cache-win64 - name: Set up dependencies run: | - wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - && \ - sudo dpkg --add-architecture i386 && \ - sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \ + wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - + sudo dpkg --add-architecture i386 + sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 - name: Bootstrap win64 cross-compiled shell: bash run: | if [ ! -d PawPaw ]; then - git clone https://github.com/DISTRHO/PawPaw.git - git -C PawPaw checkout ${PAWPAW_VERSION} + git clone https://github.com/DISTRHO/PawPaw.git + git -C PawPaw checkout ${PAWPAW_VERSION} fi ./PawPaw/bootstrap-jack2.sh win64 && ./PawPaw/.cleanup.sh win64 + - name: Build jack2 + shell: bash + run: | + pushd PawPaw && source local.env win32 && popd + ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static + ./waf build -j $(nproc) + ./waf install From 5a776bca216a5bc41f00fcc57cdfe5d224e796fb Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 13:53:08 +0100 Subject: [PATCH 10/31] Fix cache; Generate MSVC lib files Signed-off-by: falkTX --- .github/workflows/build.yml | 43 +++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b40ad03e5..c23fc81c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: ~/PawPawBuilds/builds ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - key: cache-macos + key: macos-${PAWPAW_VERSION} - name: Set up dependencies run: | brew install cmake jq meson @@ -61,7 +61,7 @@ jobs: ~/PawPawBuilds/builds ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - key: cache-macos-universal + key: macos-universal-${PAWPAW_VERSION} - name: Set up dependencies run: | brew install cmake jq meson @@ -97,10 +97,15 @@ jobs: with: path: | ~/PawPawBuilds/builds + ~/PawPawBuilds/debs ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - /var/cache/apt/archives - key: cache-win32 + key: win32-${PAWPAW_VERSION} + - name: Restore debian packages cache + run: | + if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ + sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ + fi - name: Set up dependencies run: | wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - @@ -108,6 +113,10 @@ jobs: sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ binutils-mingw-w64-i686 g++-mingw-w64-i686 + - name: Cache debian packages + run: | + mkdir -p ~/PawPawBuilds/debs && \ + sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ - name: Bootstrap win32 cross-compiled shell: bash run: | @@ -123,6 +132,12 @@ jobs: ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static ./waf build -j $(nproc) ./waf install + - name: Generate MSVC lib files + shell: bash + run: | + llvm-dlltool -m i386 -D libjack.dll -d $(pwd)/destdir/lib/libjack.def -l $(pwd)/destdir/lib/libjack.lib + llvm-dlltool -m i386 -D libjacknet.dll -d $(pwd)/destdir/lib/libjacknet.def -l $(pwd)/destdir/lib/libjacknet.lib + llvm-dlltool -m i386 -D libjackserver.dll -d $(pwd)/destdir/lib/libjackserver.def -l $(pwd)/destdir/lib/libjackserver.lib # linux with win64 cross-compilation win64: @@ -136,10 +151,15 @@ jobs: with: path: | ~/PawPawBuilds/builds + ~/PawPawBuilds/debs ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - /var/cache/apt/archives - key: cache-win64 + key: win64-${PAWPAW_VERSION} + - name: Restore debian packages cache + run: | + if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ + sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ + fi - name: Set up dependencies run: | wget -qO- https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - @@ -147,6 +167,10 @@ jobs: sudo apt-add-repository -y 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' sudo apt-get install -y autopoint build-essential curl cmake jq llvm mingw-w64 qttools5-dev-tools winehq-stable xvfb \ binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 + - name: Cache debian packages + run: | + mkdir -p ~/PawPawBuilds/debs && \ + sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ - name: Bootstrap win64 cross-compiled shell: bash run: | @@ -162,3 +186,10 @@ jobs: ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static ./waf build -j $(nproc) ./waf install + - name: Generate MSVC lib files + shell: bash + run: | + llvm-dlltool -m i386 -D libjack.dll -d $(pwd)/destdir/lib32/libjack.def -l $(pwd)/destdir/lib32/libjack.lib + llvm-dlltool -m i386:x86-64 -D libjack64.dll -d $(pwd)/destdir/lib/libjack64.def -l $(pwd)/destdir/lib/libjack64.lib + llvm-dlltool -m i386:x86-64 -D libjacknet64.dll -d $(pwd)/destdir/lib/libjacknet64.def -l $(pwd)/destdir/lib/libjacknet64.lib + llvm-dlltool -m i386:x86-64 -D libjackserver64.dll -d $(pwd)/destdir/lib/libjackserver64.def -l $(pwd)/destdir/lib/libjackserver64.lib From 2d64d65804c7dc8a37b642c4c7c3e9e4181acba2 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 14:05:26 +0100 Subject: [PATCH 11/31] Generate macOS package Signed-off-by: falkTX --- .github/workflows/build.yml | 40 ++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c23fc81c5..ee29a7674 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: ~/PawPawBuilds/builds ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - key: macos-${PAWPAW_VERSION} + key: macos - name: Set up dependencies run: | brew install cmake jq meson @@ -46,6 +46,17 @@ jobs: python ./waf configure --platform=darwin --prefix=/usr/local python ./waf build -j $(sysctl -n hw.logicalcpu) python ./waf install --destdir="$(pwd)/destdir" + - name: Generate macOS package + shell: bash + run: | + ./macosx/generate-pkg.sh $(pwd)/destdir + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" + - uses: actions/upload-artifact@v2 + with: + name: jack2-macOS-intel-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} + path: macosx/jack2-osx-*.pkg # macOS native universal build macos_universal: @@ -61,7 +72,7 @@ jobs: ~/PawPawBuilds/builds ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - key: macos-universal-${PAWPAW_VERSION} + key: macos-universal - name: Set up dependencies run: | brew install cmake jq meson @@ -83,7 +94,26 @@ jobs: pushd PawPaw && source local.env macos-universal && popd python ./waf configure --platform=darwin --prefix=/usr/local python ./waf build -j $(sysctl -n hw.logicalcpu) - python ./waf install --destdir="$(pwd)/destdir" + python ./waf install --destdir=$(pwd)/destdir + #- name: Patch binaries + #shell: bash + #run: | + #pushd $(pwd)/destdir + #for f in $(ls bin/* lib/*.dylib lib/jack/*); do + #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjack.0.dylib" "/usr/local/lib/libjack.0.dylib" "${f}" + #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjacknet.0.dylib" "/usr/local/lib/libjacknet.0.dylib" "${f}" + #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjackserver.0.dylib" "/usr/local/lib/libjackserver.0.dylib" "${f}" + - name: Generate macOS package + shell: bash + run: | + ./macosx/generate-pkg.sh $(pwd)/destdir + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" + - uses: actions/upload-artifact@v2 + with: + name: jack2-macOS-universal-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} + path: macosx/jack2-osx-*.pkg # linux with win32 cross-compilation win32: @@ -100,7 +130,7 @@ jobs: ~/PawPawBuilds/debs ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - key: win32-${PAWPAW_VERSION} + key: win32 - name: Restore debian packages cache run: | if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ @@ -154,7 +184,7 @@ jobs: ~/PawPawBuilds/debs ~/PawPawBuilds/downloads ~/PawPawBuilds/targets - key: win64-${PAWPAW_VERSION} + key: win64 - name: Restore debian packages cache run: | if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ From 79916357c478ca1de6fe9c8151f04a5745591094 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 14:17:39 +0100 Subject: [PATCH 12/31] CI: Fix win64 build, no mixed just yet Signed-off-by: falkTX --- .github/workflows/build.yml | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ee29a7674..fba483e7a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -165,9 +165,11 @@ jobs: - name: Generate MSVC lib files shell: bash run: | - llvm-dlltool -m i386 -D libjack.dll -d $(pwd)/destdir/lib/libjack.def -l $(pwd)/destdir/lib/libjack.lib - llvm-dlltool -m i386 -D libjacknet.dll -d $(pwd)/destdir/lib/libjacknet.def -l $(pwd)/destdir/lib/libjacknet.lib - llvm-dlltool -m i386 -D libjackserver.dll -d $(pwd)/destdir/lib/libjackserver.def -l $(pwd)/destdir/lib/libjackserver.lib + pushd $(pwd)/destdir/lib + llvm-dlltool -m i386 -D libjack.dll -d libjack.def -l libjack.lib + llvm-dlltool -m i386 -D libjacknet.dll -d libjacknet.def -l libjacknet.lib + llvm-dlltool -m i386 -D libjackserver.dll -d libjackserver.def -l libjackserver.lib + popd # linux with win64 cross-compilation win64: @@ -212,14 +214,23 @@ jobs: - name: Build jack2 shell: bash run: | - pushd PawPaw && source local.env win32 && popd + pushd PawPaw && source local.env win64 && popd + #export PATH+=":/usr/i686-w64-mingw32/bin" + #export LDFLAGS+="-L~/PawPawBuilds/targets/win64/lib32" + #--mixed ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static ./waf build -j $(nproc) ./waf install - name: Generate MSVC lib files shell: bash run: | - llvm-dlltool -m i386 -D libjack.dll -d $(pwd)/destdir/lib32/libjack.def -l $(pwd)/destdir/lib32/libjack.lib - llvm-dlltool -m i386:x86-64 -D libjack64.dll -d $(pwd)/destdir/lib/libjack64.def -l $(pwd)/destdir/lib/libjack64.lib - llvm-dlltool -m i386:x86-64 -D libjacknet64.dll -d $(pwd)/destdir/lib/libjacknet64.def -l $(pwd)/destdir/lib/libjacknet64.lib - llvm-dlltool -m i386:x86-64 -D libjackserver64.dll -d $(pwd)/destdir/lib/libjackserver64.def -l $(pwd)/destdir/lib/libjackserver64.lib + # 32bit + #pushd $(pwd)/destdir/lib32 + #llvm-dlltool -m i386 -D libjack.dll -d libjack.def -l libjack.lib + #popd + # 64bit + pushd $(pwd)/destdir/lib + llvm-dlltool -m i386:x86-64 -D libjack64.dll -d libjack64.def -l libjack64.lib + llvm-dlltool -m i386:x86-64 -D libjacknet64.dll -d libjacknet64.def -l libjacknet64.lib + llvm-dlltool -m i386:x86-64 -D libjackserver64.dll -d libjackserver64.def -l libjackserver64.lib + popd From 37d048847052941e9a537b6ad8b7f865be68d7aa Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 14:29:42 +0100 Subject: [PATCH 13/31] CI: Now try win64 mixed mode Signed-off-by: falkTX --- .github/workflows/build.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fba483e7a..4e331648b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: pushd PawPaw && source local.env macos && popd python ./waf configure --platform=darwin --prefix=/usr/local python ./waf build -j $(sysctl -n hw.logicalcpu) - python ./waf install --destdir="$(pwd)/destdir" + python ./waf install --destdir=$(pwd)/destdir - name: Generate macOS package shell: bash run: | @@ -79,7 +79,7 @@ jobs: - name: Fix up Xcode run: | sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/* - sudo xcode-select -s "/Applications/Xcode_12.3.app" + sudo xcode-select -s /Applications/Xcode_12.3.app - name: Bootstrap macOS universal shell: bash run: | @@ -159,7 +159,7 @@ jobs: shell: bash run: | pushd PawPaw && source local.env win32 && popd - ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static + ./waf configure --platform=win32 --prefix=$(pwd)/destdir --static ./waf build -j $(nproc) ./waf install - name: Generate MSVC lib files @@ -215,19 +215,18 @@ jobs: shell: bash run: | pushd PawPaw && source local.env win64 && popd - #export PATH+=":/usr/i686-w64-mingw32/bin" - #export LDFLAGS+="-L~/PawPawBuilds/targets/win64/lib32" - #--mixed - ./waf configure --platform=win32 --prefix="$(pwd)/destdir" --static + export PATH+=":/usr/i686-w64-mingw32/bin" + export LDFLAGS+="-L~/PawPawBuilds/targets/win64/lib32" + ./waf configure --platform=win32 --prefix=$(pwd)/destdir --static --mixed ./waf build -j $(nproc) ./waf install - name: Generate MSVC lib files shell: bash run: | # 32bit - #pushd $(pwd)/destdir/lib32 - #llvm-dlltool -m i386 -D libjack.dll -d libjack.def -l libjack.lib - #popd + pushd $(pwd)/destdir/lib32 + llvm-dlltool -m i386 -D libjack.dll -d libjack.def -l libjack.lib + popd # 64bit pushd $(pwd)/destdir/lib llvm-dlltool -m i386:x86-64 -D libjack64.dll -d libjack64.def -l libjack64.lib From 116007cec8f2a2e790a846ad8ddb9830dc1d7323 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 14:48:50 +0100 Subject: [PATCH 14/31] Allow custom version on macOS generate-pkg script Signed-off-by: falkTX --- .github/workflows/build.yml | 16 ++++++++-------- macosx/generate-pkg.sh | 6 +++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4e331648b..5f9423ec5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,13 +46,13 @@ jobs: python ./waf configure --platform=darwin --prefix=/usr/local python ./waf build -j $(sysctl -n hw.logicalcpu) python ./waf install --destdir=$(pwd)/destdir - - name: Generate macOS package - shell: bash - run: | - ./macosx/generate-pkg.sh $(pwd)/destdir - name: Set sha8 id: slug run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" + - name: Generate macOS package + shell: bash + run: | + ./macosx/generate-pkg.sh $(pwd)/destdir ${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} - uses: actions/upload-artifact@v2 with: name: jack2-macOS-intel-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} @@ -103,13 +103,13 @@ jobs: #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjack.0.dylib" "/usr/local/lib/libjack.0.dylib" "${f}" #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjacknet.0.dylib" "/usr/local/lib/libjacknet.0.dylib" "${f}" #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjackserver.0.dylib" "/usr/local/lib/libjackserver.0.dylib" "${f}" - - name: Generate macOS package - shell: bash - run: | - ./macosx/generate-pkg.sh $(pwd)/destdir - name: Set sha8 id: slug run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" + - name: Generate macOS package + shell: bash + run: | + ./macosx/generate-pkg.sh $(pwd)/destdir ${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} - uses: actions/upload-artifact@v2 with: name: jack2-macOS-universal-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} diff --git a/macosx/generate-pkg.sh b/macosx/generate-pkg.sh index a64a5ea0e..79647cd2b 100755 --- a/macosx/generate-pkg.sh +++ b/macosx/generate-pkg.sh @@ -15,7 +15,11 @@ fi # --------------------------------------------------------------------------------------------------------------------- -VERSION=$(cat ../wscript | awk 'sub("VERSION=","")' | tr -d "'") +if [ -n "${2}" ]; then + VERSION="${2}" +else + VERSION=$(cat ../wscript | awk 'sub("VERSION=","")' | tr -d "'") +fi rm -f jack2-osx-root.pkg rm -f jack2-osx-${VERSION}.pkg From ea6933571b93eaf0fd9098fcb777bd9205c1e1c8 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 15:15:14 +0100 Subject: [PATCH 15/31] CI: Generate windows installers Signed-off-by: falkTX --- .github/workflows/build.yml | 36 +++++++++++++++++++++++ .gitignore | 23 +++++++++------ windows/inno/win32-mini.iss | 49 +++++++++++++++++++++++++++++++ windows/inno/win64-mini.iss | 58 +++++++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 9 deletions(-) create mode 100644 windows/inno/win32-mini.iss create mode 100644 windows/inno/win64-mini.iss diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f9423ec5..2a19cc76d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -170,6 +170,24 @@ jobs: llvm-dlltool -m i386 -D libjacknet.dll -d libjacknet.def -l libjacknet.lib llvm-dlltool -m i386 -D libjackserver.dll -d libjackserver.def -l libjackserver.lib popd + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" + - name: Generate Windows installer + shell: bash + run: | + # Setup wine + export WINEPREFIX=$(pwd)/innosetup + wineboot -u + # Download and install innosetup + curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe + wine is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent + # create installer + ln -sf $(pwd)/destdir windows/inno/win32 + pushd windows/inno + echo "#define VERSION \"${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}\"" > version.iss + wine ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win32-mini.iss + popd # linux with win64 cross-compilation win64: @@ -233,3 +251,21 @@ jobs: llvm-dlltool -m i386:x86-64 -D libjacknet64.dll -d libjacknet64.def -l libjacknet64.lib llvm-dlltool -m i386:x86-64 -D libjackserver64.dll -d libjackserver64.def -l libjackserver64.lib popd + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" + - name: Generate Windows installer + shell: bash + run: | + # Setup wine + export WINEPREFIX=$(pwd)/innosetup + wineboot -u + # Download and install innosetup + curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe + wine64 is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent + # create installer + ln -sf $(pwd)/destdir windows/inno/win64 + pushd windows/inno + echo "#define VERSION \"${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}\"" > version.iss + wine64 ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win64-mini.iss + popd diff --git a/.gitignore b/.gitignore index 143396fe5..45bbd237b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -build/ -man/*.1 .lock* .stamp_* .DS_Store @@ -7,15 +5,22 @@ __pycache__ *.dll *.pyc *.pkg -android/.server/ -android/.client/ codeBlocks +/android/.server/ +/android/.client/ +/build/ +/man/*.1 + +# common release files +/destdir/ # macos release files -macos/package.xml -macos/package-welcome.txt +/macos/package.xml +/macos/package-welcome.txt # windows release files -windows/inno/version.iss -windows/inno/win32 -windows/inno/win64 +/innosetup/ +/is.exe +/windows/inno/version.iss +/windows/inno/win32 +/windows/inno/win64 diff --git a/windows/inno/win32-mini.iss b/windows/inno/win32-mini.iss new file mode 100644 index 000000000..d5ae49c3d --- /dev/null +++ b/windows/inno/win32-mini.iss @@ -0,0 +1,49 @@ +#include "version.iss" + +[Setup] +AppName=JACK2 +AppPublisher=jackaudio.org +AppPublisherURL=https://github.com/jackaudio/jack2/ +AppSupportURL=https://github.com/jackaudio/jack2/issues/ +AppUpdatesURL=https://github.com/jackaudio/jack2-releases/releases/ +AppVersion={#VERSION} +DefaultDirName={commonpf32}\JACK2 +DisableDirPage=yes +DisableWelcomePage=no +LicenseFile=..\..\COPYING +OutputBaseFilename=jack2-win32-{#VERSION} +OutputDir=. +UsePreviousAppDir=no + +[Types] +Name: "full"; Description: "Full installation"; +Name: "custom"; Description: "Custom installation"; Flags: iscustom; + +[Components] +Name: jackserver; Description: "JACK Server and tools"; Types: full custom; Flags: fixed; +Name: dev; Description: "Developer resources"; Types: full; + +[Files] +; icon +Source: "jack.ico"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +; jackd and server libs +Source: "win32\bin\jackd.exe"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +Source: "win32\lib\libjacknet.dll"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +Source: "win32\lib\libjackserver.dll"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +; drivers +Source: "win32\lib\jack\*.dll"; DestDir: "{app}\jack"; Components: jackserver; Flags: ignoreversion; +; tools +Source: "win32\bin\jack_*.exe"; DestDir: "{app}\tools"; Components: jackserver; Flags: ignoreversion; +; jack client lib (NOTE goes into windir) +Source: "win32\lib\libjack.dll"; DestDir: "{win}"; Components: jackserver; Flags: ignoreversion; +; dev +Source: "win32\include\jack\*.h"; DestDir: "{app}\include\jack"; Components: dev; Flags: ignoreversion; +Source: "win32\lib\*.a"; DestDir: "{app}\lib"; Components: dev; Flags: ignoreversion; +Source: "win32\lib\*.def"; DestDir: "{app}\lib"; Components: dev; Flags: ignoreversion; +Source: "win32\lib\*.lib"; DestDir: "{app}\lib"; Components: dev; Flags: ignoreversion; +Source: "win32\lib\jack\*.a"; DestDir: "{app}\lib\jack"; Components: dev; Flags: ignoreversion; + +[Registry] +Root: HKLM; Subkey: "Software\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "ServerExecutable"; ValueData: "{app}\jackd.exe" +Root: HKLM; Subkey: "Software\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" +Root: HKLM; Subkey: "Software\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "Version"; ValueData: "{#VERSION}" diff --git a/windows/inno/win64-mini.iss b/windows/inno/win64-mini.iss new file mode 100644 index 000000000..b089d5f07 --- /dev/null +++ b/windows/inno/win64-mini.iss @@ -0,0 +1,58 @@ +#include "version.iss" + +[Setup] +ArchitecturesInstallIn64BitMode=x64 +AppName=JACK2 +AppPublisher=jackaudio.org +AppPublisherURL=https://github.com/jackaudio/jack2/ +AppSupportURL=https://github.com/jackaudio/jack2/issues/ +AppUpdatesURL=https://github.com/jackaudio/jack2-releases/releases/ +AppVersion={#VERSION} +DefaultDirName={commonpf64}\JACK2 +DisableDirPage=yes +DisableWelcomePage=no +LicenseFile=..\..\COPYING +OutputBaseFilename=jack2-win64-{#VERSION} +OutputDir=. +UsePreviousAppDir=no + +[Types] +Name: "full"; Description: "Full installation"; +Name: "custom"; Description: "Custom installation"; Flags: iscustom; + +[Components] +Name: jackserver; Description: "JACK Server and tools"; Types: full custom; Flags: fixed; +Name: dev; Description: "Developer resources"; Types: full; + +[Files] +; icon +Source: "jack.ico"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +; jackd and server libs +Source: "win64\bin\jackd.exe"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +Source: "win64\lib\libjacknet64.dll"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +Source: "win64\lib\libjackserver64.dll"; DestDir: "{app}"; Components: jackserver; Flags: ignoreversion; +; drivers +Source: "win64\lib\jack\*.dll"; DestDir: "{app}\jack"; Components: jackserver; Flags: ignoreversion; +; tools +Source: "win64\bin\jack_*.exe"; DestDir: "{app}\tools"; Components: jackserver; Flags: ignoreversion; +; jack client lib (NOTE goes into windir) +Source: "win64\lib\libjack64.dll"; DestDir: "{win}"; Components: jackserver; Flags: ignoreversion; +Source: "win64\lib32\libjack.dll"; DestDir: "{win}"; Components: jackserver; Flags: ignoreversion; +; dev +Source: "win64\include\jack\*.h"; DestDir: "{app}\include\jack"; Components: dev; Flags: ignoreversion; +Source: "win64\lib\*.a"; DestDir: "{app}\lib"; Components: dev; Flags: ignoreversion; +Source: "win64\lib\*.def"; DestDir: "{app}\lib"; Components: dev; Flags: ignoreversion; +Source: "win64\lib\*.lib"; DestDir: "{app}\lib"; Components: dev; Flags: ignoreversion; +Source: "win64\lib32\*.a"; DestDir: "{app}\lib32"; Components: dev; Flags: ignoreversion; +Source: "win64\lib32\*.def"; DestDir: "{app}\lib32"; Components: dev; Flags: ignoreversion; +Source: "win64\lib32\*.lib"; DestDir: "{app}\lib32"; Components: dev; Flags: ignoreversion; +Source: "win64\lib\jack\*.a"; DestDir: "{app}\lib\jack"; Components: dev; Flags: ignoreversion; + +[Registry] +Root: HKLM; Subkey: "Software\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "ServerExecutable"; ValueData: "{app}\jackd.exe" +Root: HKLM; Subkey: "Software\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" +Root: HKLM; Subkey: "Software\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "Version"; ValueData: "{#VERSION}" +; 32bit compat keys +Root: HKLM; Subkey: "Software\WOW6432Node\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "ServerExecutable"; ValueData: "{app}\jackd.exe" +Root: HKLM; Subkey: "Software\WOW6432Node\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" +Root: HKLM; Subkey: "Software\WOW6432Node\JACK"; Flags: deletevalue uninsdeletekeyifempty uninsdeletevalue; ValueType: string; ValueName: "Version"; ValueData: "{#VERSION}" From ee3eeea91bceb8898ae643a33fe1fc6eb20f1aca Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 15:17:44 +0100 Subject: [PATCH 16/31] Update windows installers as artifacts Signed-off-by: falkTX --- .github/workflows/build.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a19cc76d..14c88fdb6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -188,6 +188,10 @@ jobs: echo "#define VERSION \"${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}\"" > version.iss wine ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win32-mini.iss popd + - uses: actions/upload-artifact@v2 + with: + name: jack2-win32-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} + path: windows/inno/jack2-*.exe # linux with win64 cross-compilation win64: @@ -269,3 +273,7 @@ jobs: echo "#define VERSION \"${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}\"" > version.iss wine64 ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win64-mini.iss popd + - uses: actions/upload-artifact@v2 + with: + name: jack2-win64-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} + path: windows/inno/jack2-*.exe From 8e753dc918b179d180edb6f25fa6d2fd6442d766 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 15:23:33 +0100 Subject: [PATCH 17/31] CI: Use xvfb-run for wine stuff Signed-off-by: falkTX --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 14c88fdb6..168c23d71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -181,12 +181,12 @@ jobs: wineboot -u # Download and install innosetup curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe - wine is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent + xvfb-run wine is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent # create installer ln -sf $(pwd)/destdir windows/inno/win32 pushd windows/inno echo "#define VERSION \"${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}\"" > version.iss - wine ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win32-mini.iss + xvfb-run wine ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win32-mini.iss popd - uses: actions/upload-artifact@v2 with: @@ -266,12 +266,12 @@ jobs: wineboot -u # Download and install innosetup curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe - wine64 is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent + xvfb-run wine64 is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent # create installer ln -sf $(pwd)/destdir windows/inno/win64 pushd windows/inno echo "#define VERSION \"${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}\"" > version.iss - wine64 ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win64-mini.iss + xvfb-run wine64 ${WINEPREFIX}/drive_c/InnoSeup/ISCC.exe win64-mini.iss popd - uses: actions/upload-artifact@v2 with: From 9a33cc254c49c0c96c4dbe0552caade1583fb1e2 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 15:28:52 +0100 Subject: [PATCH 18/31] CI: Use xvfb-run for wineboot too Signed-off-by: falkTX --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 168c23d71..e70d7b993 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -178,7 +178,7 @@ jobs: run: | # Setup wine export WINEPREFIX=$(pwd)/innosetup - wineboot -u + xvfb-run wineboot -u # Download and install innosetup curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe xvfb-run wine is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent @@ -263,7 +263,7 @@ jobs: run: | # Setup wine export WINEPREFIX=$(pwd)/innosetup - wineboot -u + xvfb-run wineboot -u # Download and install innosetup curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe xvfb-run wine64 is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent From 8333ea57cfadf8a82e83e24e075ff18ca98f569e Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 31 Jul 2021 15:44:10 +0100 Subject: [PATCH 19/31] Revert "CI: Use xvfb-run for wineboot too" This reverts commit 9a33cc254c49c0c96c4dbe0552caade1583fb1e2. --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e70d7b993..168c23d71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -178,7 +178,7 @@ jobs: run: | # Setup wine export WINEPREFIX=$(pwd)/innosetup - xvfb-run wineboot -u + wineboot -u # Download and install innosetup curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe xvfb-run wine is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent @@ -263,7 +263,7 @@ jobs: run: | # Setup wine export WINEPREFIX=$(pwd)/innosetup - xvfb-run wineboot -u + wineboot -u # Download and install innosetup curl -L https://jrsoftware.org/download.php/is.exe?site=2 -o is.exe xvfb-run wine64 is.exe /allusers /dir=C:\\InnoSeup /nocancel /norestart /verysilent From b3dd666c66db87e7e8e0b71a24ba2f28355a87d6 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 2 Aug 2021 12:15:08 +0100 Subject: [PATCH 20/31] CI: Fix macOS package path Signed-off-by: falkTX --- .github/workflows/build.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 168c23d71..b4afcfbae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,7 +52,7 @@ jobs: - name: Generate macOS package shell: bash run: | - ./macosx/generate-pkg.sh $(pwd)/destdir ${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} + ./macosx/generate-pkg.sh $(pwd)/destdir/usr/local ${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} - uses: actions/upload-artifact@v2 with: name: jack2-macOS-intel-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} @@ -95,21 +95,13 @@ jobs: python ./waf configure --platform=darwin --prefix=/usr/local python ./waf build -j $(sysctl -n hw.logicalcpu) python ./waf install --destdir=$(pwd)/destdir - #- name: Patch binaries - #shell: bash - #run: | - #pushd $(pwd)/destdir - #for f in $(ls bin/* lib/*.dylib lib/jack/*); do - #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjack.0.dylib" "/usr/local/lib/libjack.0.dylib" "${f}" - #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjacknet.0.dylib" "/usr/local/lib/libjacknet.0.dylib" "${f}" - #install_name_tool -change "${PAWPAW_PREFIX}/jack2/lib/libjackserver.0.dylib" "/usr/local/lib/libjackserver.0.dylib" "${f}" - name: Set sha8 id: slug run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" - name: Generate macOS package shell: bash run: | - ./macosx/generate-pkg.sh $(pwd)/destdir ${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} + ./macosx/generate-pkg.sh $(pwd)/destdir/usr/local ${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} - uses: actions/upload-artifact@v2 with: name: jack2-macOS-universal-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} From 8820482d5aabf6f6be90593d253176f25e7ab79b Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 2 Aug 2021 12:24:57 +0100 Subject: [PATCH 21/31] Begin ubuntu-20.04 automated deb packaging Signed-off-by: falkTX --- .github/workflows/build.yml | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b4afcfbae..d88beb032 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -269,3 +269,44 @@ jobs: with: name: jack2-win64-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} path: windows/inno/jack2-*.exe + + # ubuntu-20.04 + ubuntu-20.04: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Set up cache + uses: actions/cache@v2 + with: + path: | + ~/debs + key: ubuntu-20.04 + - name: Restore debian packages cache + run: | + if [ -d ~/debs ] && [ "$(ls ~/debs | wc -l)" -ne 0 ]; then \ + sudo cp ~/debs/*.deb /var/cache/apt/archives/; \ + fi + - name: Set up dependencies + run: | + sudo add-apt-repository -y ppa:ubuntustudio-ppa/backports + sudo sed -i "s/# deb-src/deb-src/" /etc/apt/sources.list /etc/apt/sources.list.d/*.list + sudo apt-get update -qq + sudo apt-get build-dep jackd2 + sudo apt-get install devscripts + - name: Cache debian packages + run: | + mkdir -p ~/debs && \ + sudo mv /var/cache/apt/archives/*.deb ~/debs/ + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" + - name: Build jack2 packages + shell: bash + run: | + apt-get source jackd2 + - uses: actions/upload-artifact@v2 + with: + name: jack2-ubuntu-20.04-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} + path: *.deb From da28e12934d18ba493a24a0c506908cd779b65d4 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 2 Aug 2021 12:26:13 +0100 Subject: [PATCH 22/31] Fix syntax error Signed-off-by: falkTX --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d88beb032..07a5e77d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -309,4 +309,4 @@ jobs: - uses: actions/upload-artifact@v2 with: name: jack2-ubuntu-20.04-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} - path: *.deb + path: ./*.deb From 50e0b9e7099ce5aa6a1b5cd4f1fb44bea092d7c5 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 2 Aug 2021 12:28:36 +0100 Subject: [PATCH 23/31] Another syntax fix Signed-off-by: falkTX --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 07a5e77d7..58343b76b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -271,7 +271,7 @@ jobs: path: windows/inno/jack2-*.exe # ubuntu-20.04 - ubuntu-20.04: + ubuntu_20_04: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 From 721e50237fcb6b68a0779e5231c73872b6ddd9aa Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 2 Aug 2021 12:44:48 +0100 Subject: [PATCH 24/31] Build deb packages Signed-off-by: falkTX --- .github/workflows/build.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58343b76b..dd766654e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -305,7 +305,11 @@ jobs: - name: Build jack2 packages shell: bash run: | - apt-get source jackd2 + apt-get source -d jackd2 + tar xf *.debian.tar.xz + rm -rf debian/source + dch -M -b -v "$(cat wscript | awk 'sub("VERSION=","")' | tr -d "'")~$(date +"%Y%m%d")git${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}" -D focal "automated build" + debuild -rfakeroot --no-lintian || true - uses: actions/upload-artifact@v2 with: name: jack2-ubuntu-20.04-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} From 5ff97c80f27cba9ebc346315545237373578acd0 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 2 Aug 2021 12:50:17 +0100 Subject: [PATCH 25/31] Fix path to deb packages Signed-off-by: falkTX --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd766654e..60545b27e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -313,4 +313,4 @@ jobs: - uses: actions/upload-artifact@v2 with: name: jack2-ubuntu-20.04-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} - path: ./*.deb + path: ../*.deb From ef2af6821f5318a50e5a642139a7d8f2fe95144f Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 2 Aug 2021 12:58:15 +0100 Subject: [PATCH 26/31] Fix deb path Signed-off-by: falkTX --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60545b27e..699672521 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -313,4 +313,4 @@ jobs: - uses: actions/upload-artifact@v2 with: name: jack2-ubuntu-20.04-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }} - path: ../*.deb + path: ~/work/jack2/*.deb From c742b430fb3414694eaf323be1b27a8b56f611cd Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 10 Aug 2021 09:01:50 +0100 Subject: [PATCH 27/31] Build netsource tool when celt or opus are available Signed-off-by: falkTX --- tools/wscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/wscript b/tools/wscript index a6a60f5c6..4192a4c8e 100644 --- a/tools/wscript +++ b/tools/wscript @@ -21,6 +21,7 @@ example_tools = { def configure(conf): conf.env['BUILD_TOOL_ALSA_IO'] = conf.env['SAMPLERATE'] and conf.env['BUILD_DRIVER_ALSA'] conf.env['BUILD_TOOL_CLIENT_TRANSPORT'] = conf.env['READLINE'] + conf.env['BUILD_TOOL_CLIENT_NETSOURCE'] = conf.env['CELT'] or conf.env['OPUS'] conf.env['BUILD_TOOL_ZALSA'] = conf.env['ZALSA'] def build(bld): @@ -66,7 +67,7 @@ def build(bld): prog.env['LIB_PTHREAD'] = [':libwinpthread.a'] prog.target = 'jack_transport' - if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']: + if bld.env['BUILD_TOOL_CLIENT_NETSOURCE']: prog = bld(features = 'c cprogram') prog.includes = os_incdir + ['.', '..', '../common/jack', '../common'] prog.source = ['netsource.c', '../common/netjack_packet.c'] From 1ab3445e65ec2bfc1ba8562984822616e03fb9fe Mon Sep 17 00:00:00 2001 From: Peter Bridgman Date: Sat, 14 Aug 2021 16:24:41 +0100 Subject: [PATCH 28/31] macOS: Pass JackMachSemaphore send right via mach_msg IPC (#788) * macOS: Pass JackMachSemaphore send right via mach_msg IPC Previously, JackMachSemaphore would communicate the send right for the semaphore object from the server to a client via a named service registered via `bootstrap_register`. However, to do this, it would register the semaphore's port as the service port directly. In theory this ought to be fine, however in practice, macOS `launchd`, which provides the `bootstrap_register` interface, does not correctly detect when such a port becomes dead, and incorrectly believes that the service that it provides is forever alive, even past the end of the `jackd` process' (and therefore the semaphore's) existence. This seems to be *specific* to semaphore ports, as `launchd` is expecting a standard IPC port, owned by the task, not the kernel. This prevents `jackd` from later registering another service with the same name, as `launchd` rejects the registration as conflicting with an active service. To get around this, `jackd` previously added a counter to the end of the named service registrations, allowing old services to remain in the system until the end of the session. To prevent things getting out of hand, this was capped at 98 service registrations for a given semaphore name. This led to #784, in which running a client for the 99th time resulted in the semaphore creation failing and the client failing to connect. As `launchd` outlives multiple runs of `jackd`, this situation persisted across restarts of `jackd`, requiring a restart of the user's session (i.e. a reboot) to fix. An initial attempt at fixing this (see #785) tried passing the port rights directly via shared memory, however mach is too clever for us and foils that plan by having port names be looked up in a per-task table (sensible when you think about it). In this commit, we use mach IPC messages to transfer the send right for the semaphore from the server to the client. By registering a standard IPC port with the bootstrap server, the service registrations are correctly torn down when the ports are destroyed. It works something like this: * Server creates IPC port and registers it globally via `bootstrap_register` * Server listens on IPC port for messages * Client looks up IPC port via `bootstrap_look_up` * Client sends it a message * Server replies with a message containing a send right to the semaphore's port * Client is then free to use the semaphore port as before. This resolves #784. * Improve error handling * Add myself to Authors --- AUTHORS.rst | 1 + common/wscript | 1 + macosx/JackMachSemaphore.h | 29 ++- macosx/JackMachSemaphore.mm | 317 ++++++++++++++++++++---------- macosx/JackMachSemaphoreServer.h | 56 ++++++ macosx/JackMachSemaphoreServer.mm | 87 ++++++++ macosx/JackMachUtils.h | 36 ++++ 7 files changed, 414 insertions(+), 113 deletions(-) create mode 100644 macosx/JackMachSemaphoreServer.h create mode 100644 macosx/JackMachSemaphoreServer.mm create mode 100644 macosx/JackMachUtils.h diff --git a/AUTHORS.rst b/AUTHORS.rst index 7266fd003..7b7185ec0 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -72,6 +72,7 @@ Nedko Arnaudov Olaf Hering Olivier Humbert Paul Davis +Peter Bridgman Peter L Jones Pieter Palmers Ricardo Crudo diff --git a/common/wscript b/common/wscript index 114eb0a2b..24f024ec2 100644 --- a/common/wscript +++ b/common/wscript @@ -117,6 +117,7 @@ def build(bld): '../posix/JackPosixMutex.cpp', '../macosx/JackMachThread.mm', '../macosx/JackMachSemaphore.mm', + '../macosx/JackMachSemaphoreServer.mm', '../posix/JackSocket.cpp', '../macosx/JackMachTime.c', ] diff --git a/macosx/JackMachSemaphore.h b/macosx/JackMachSemaphore.h index 10406847a..20465a096 100644 --- a/macosx/JackMachSemaphore.h +++ b/macosx/JackMachSemaphore.h @@ -22,6 +22,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackCompilerDeps.h" #include "JackSynchro.h" + +#include "JackMachThread.h" +#include "JackMachSemaphoreServer.h" + #include #include #include @@ -38,13 +42,24 @@ class SERVER_EXPORT JackMachSemaphore : public detail::JackSynchro private: + /*! \brief A mach send right to the mach semaphore, or MACH_PORT_NULL if not yet Allocate()d + * (server) or Connect()ed (client). */ semaphore_t fSemaphore; + + /*! \brief The bootstrap port for this task, or MACH_PORT_NULL if not yet obtained. */ mach_port_t fBootPort; - int fSharedMem; - char* fSharedName; + /*! \brief The IPC port used to pass the semaphore port from the server to the client, and + * for the client to request that this occurs. MACH_PORT_NULL if not yet created (server) or + * looked up (client). */ + mach_port_t fServicePort; + + /*! \brief On the server, if allocated, a runnable semaphore server which listens for IPC + * messages and replies with a send right for a semaphore port. */ + JackMachSemaphoreServer* fSemServer; - bool recursiveBootstrapRegister(int counter); + /*! \brief On the server, if allocated, a thread that runs \ref fSemServer. */ + JackMachThread* fThreadSemServer; protected: @@ -52,7 +67,13 @@ class SERVER_EXPORT JackMachSemaphore : public detail::JackSynchro public: - JackMachSemaphore():JackSynchro(), fSemaphore(0), fBootPort(0), fSharedMem(0), fSharedName(NULL) + JackMachSemaphore(): + JackSynchro(), + fSemaphore(MACH_PORT_NULL), + fBootPort(MACH_PORT_NULL), + fServicePort(MACH_PORT_NULL), + fSemServer(NULL), + fThreadSemServer(NULL) {} bool Signal(); diff --git a/macosx/JackMachSemaphore.mm b/macosx/JackMachSemaphore.mm index 7b7f4e2e2..1905e04cb 100644 --- a/macosx/JackMachSemaphore.mm +++ b/macosx/JackMachSemaphore.mm @@ -18,12 +18,18 @@ */ #include "JackMachSemaphore.h" +#include "JackMachUtils.h" #include "JackConstants.h" #include "JackTools.h" #include "JackError.h" -#include -#include -#include + +#include + +#define jack_mach_error(kern_result, message) \ + jack_mach_error_uncurried("JackMachSemaphore", kern_result, message) + +#define jack_mach_bootstrap_err(kern_result, message, name) \ + jack_mach_bootstrap_err_uncurried("JackMachSemaphore", kern_result, message, name) namespace Jack { @@ -42,7 +48,7 @@ bool JackMachSemaphore::Signal() { - if (!fSemaphore) { + if (fSemaphore == MACH_PORT_NULL) { jack_error("JackMachSemaphore::Signal name = %s already deallocated!!", fName); return false; } @@ -60,7 +66,7 @@ bool JackMachSemaphore::SignalAll() { - if (!fSemaphore) { + if (fSemaphore == MACH_PORT_NULL) { jack_error("JackMachSemaphore::SignalAll name = %s already deallocated!!", fName); return false; } @@ -79,7 +85,7 @@ bool JackMachSemaphore::Wait() { - if (!fSemaphore) { + if (fSemaphore == MACH_PORT_NULL) { jack_error("JackMachSemaphore::Wait name = %s already deallocated!!", fName); return false; } @@ -93,7 +99,7 @@ bool JackMachSemaphore::TimedWait(long usec) { - if (!fSemaphore) { + if (fSemaphore == MACH_PORT_NULL) { jack_error("JackMachSemaphore::TimedWait name = %s already deallocated!!", fName); return false; } @@ -109,132 +115,199 @@ return (res == KERN_SUCCESS); } -bool JackMachSemaphore::recursiveBootstrapRegister(int counter) +/*! \brief Server side: create semaphore and publish IPC primitives to make it accessible. + * + * This method; + * - Allocates a mach semaphore + * - Allocates a new mach IPC port and obtains a send right for it + * - Publishes IPC port send right to the bootstrap server + * - Starts a new JackMachSemaphoreServer thread, which listens for messages on the IPC port and + * replies with a send right to the mach semaphore. + * + * \returns false if any of the above steps fails, or true otherwise. + */ +bool JackMachSemaphore::Allocate(const char* client_name, const char* server_name, int value) { - if (counter == 99) - return false; - - kern_return_t res; - - if ((res = bootstrap_register(fBootPort, fSharedName, fSemaphore)) != KERN_SUCCESS) { - switch (res) { - case BOOTSTRAP_SUCCESS : - break; - - case BOOTSTRAP_NOT_PRIVILEGED : - case BOOTSTRAP_NAME_IN_USE : - case BOOTSTRAP_UNKNOWN_SERVICE : - case BOOTSTRAP_SERVICE_ACTIVE : - // try again with next suffix - snprintf(fSharedName, sizeof(fName), "%s-%d", fName, ++counter); - return recursiveBootstrapRegister(counter); - break; - - default : - jack_log("bootstrap_register() err = %i:%s", res, bootstrap_strerror(res)); - break; - } - - jack_error("Allocate: can't check in mach semaphore name = %s err = %i:%s", fName, res, bootstrap_strerror(res)); + if (fSemaphore != MACH_PORT_NULL) { + jack_error("JackMachSemaphore::Allocate: Semaphore already allocated; called twice? [%s]", fName); return false; } - return true; -} + BuildName(client_name, server_name, fName, sizeof(fName)); -// Server side : publish the semaphore in the global namespace -bool JackMachSemaphore::Allocate(const char* name, const char* server_name, int value) -{ - BuildName(name, server_name, fName, sizeof(fName)); mach_port_t task = mach_task_self(); kern_return_t res; - if (fBootPort == 0) { + if (fBootPort == MACH_PORT_NULL) { if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { - jack_error("Allocate: Can't find bootstrap mach port err = %s", mach_error_string(res)); + jack_mach_error(res, "can't find bootstrap mach port"); return false; } } - if ((fSharedMem = shm_open(fName, O_CREAT | O_RDWR, 0777)) < 0) { - jack_error("Allocate: can't check in mach shared name = %s err = %s", fName, strerror(errno)); + if ((res = semaphore_create(task, &fSemaphore, SYNC_POLICY_FIFO, value)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to create semaphore"); return false; } - struct stat st; - if (fstat(fSharedMem, &st) != -1 && st.st_size == 0) { - if (ftruncate(fSharedMem, SYNC_MAX_NAME_SIZE+1) != 0) { - jack_error("Allocate: can't set shared memory size in mach shared name = %s err = %s", fName, strerror(errno)); - return false; - } + if ((res = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &fServicePort)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to allocate IPC port"); + + // Cleanup created semaphore + this->Destroy(); + + return false; } - char* const sharedName = (char*)mmap(NULL, SYNC_MAX_NAME_SIZE+1, PROT_READ|PROT_WRITE, MAP_SHARED, fSharedMem, 0); + if ((res = mach_port_insert_right(mach_task_self(), fServicePort, fServicePort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to obtain send right for IPC port"); + + // Cleanup created semaphore & mach port + this->Destroy(); - if (sharedName == NULL || sharedName == MAP_FAILED) { - jack_error("Allocate: can't check in mach shared name = %s err = %s", fName, strerror(errno)); - close(fSharedMem); - fSharedMem = -1; - shm_unlink(fName); return false; } - fSharedName = sharedName; - strcpy(fSharedName, fName); + if ((res = bootstrap_register(fBootPort, fName, fServicePort)) != KERN_SUCCESS) { + jack_mach_bootstrap_err(res, "can't register IPC port with bootstrap server", fName); + + // Cleanup created semaphore & mach port + this->Destroy(); + + return false; + } + + fSemServer = new JackMachSemaphoreServer(fSemaphore, fServicePort, fName); + fThreadSemServer = new JackMachThread(fSemServer); + + if (fThreadSemServer->Start() < 0) { + jack_error("JackMachSemaphore::Allocate: failed to start semaphore IPC server thread [%s]", fName); + + // Cleanup created semaphore, mach port (incl. service registration), and server + this->Destroy(); - if ((res = semaphore_create(task, &fSemaphore, SYNC_POLICY_FIFO, value)) != KERN_SUCCESS) { - jack_error("Allocate: can create semaphore err = %i:%s", res, mach_error_string(res)); return false; } - jack_log("JackMachSemaphore::Allocate name = %s", fName); - return recursiveBootstrapRegister(1); + jack_log("JackMachSemaphore::Allocate: OK, name = %s", fName); + return true; } -// Client side : get the published semaphore from server -bool JackMachSemaphore::ConnectInput(const char* name, const char* server_name) +/*! \brief Client side: Obtain semaphore from server via published IPC port. + * + * This method; + * - Looks up the service port for the jackd semaphore server for this client by name + * - Sends a message to that server asking for a semaphore port send right + * - Receives a semaphore send right in return and stores it locally + * + * \returns False if any of the above steps fails, or true otherwise. + */ +bool JackMachSemaphore::ConnectInput(const char* client_name, const char* server_name) { - BuildName(name, server_name, fName, sizeof(fName)); + BuildName(client_name, server_name, fName, sizeof(fName)); + + mach_port_t task = mach_task_self(); kern_return_t res; - // Temporary... - if (fSharedName) { - jack_log("Already connected name = %s", name); + if (fSemaphore != MACH_PORT_NULL) { + jack_log("JackMachSemaphore::Connect: Already connected name = %s", fName); return true; } - if (fBootPort == 0) { - if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) { - jack_error("Connect: can't find bootstrap port err = %s", mach_error_string(res)); + if (fBootPort == MACH_PORT_NULL) { + if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { + jack_mach_error(res, "can't find bootstrap port"); return false; } } - if ((fSharedMem = shm_open(fName, O_RDWR, 0)) < 0) { - jack_error("Connect: can't connect mach shared name = %s err = %s", fName, strerror(errno)); + if ((res = bootstrap_look_up(fBootPort, fName, &fServicePort)) != KERN_SUCCESS) { + jack_mach_bootstrap_err(res, "can't find IPC service port to request semaphore", fName); return false; } - char* const sharedName = (char*)mmap(NULL, SYNC_MAX_NAME_SIZE+1, PROT_READ|PROT_WRITE, MAP_SHARED, fSharedMem, 0); + mach_port_t semaphore_req_port; + + if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &semaphore_req_port)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to allocate request port"); + + if ((res = mach_port_deallocate(task, fServicePort)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to deallocate IPC service port during cleanup"); + } else { + fServicePort = MACH_PORT_NULL; + } - if (sharedName == NULL || sharedName == MAP_FAILED) { - jack_error("Connect: can't connect mach shared name = %s err = %s", fName, strerror(errno)); - close(fSharedMem); - fSharedMem = -1; return false; } - if ((res = bootstrap_look_up(fBootPort, sharedName, &fSemaphore)) != KERN_SUCCESS) { - jack_error("Connect: can't find mach semaphore name = %s, sname = %s, err = %s", fName, sharedName, bootstrap_strerror(res)); - close(fSharedMem); - fSharedMem = -1; + // Prepare a message buffer on the stack. We'll use it for both sending and receiving a message. + struct { + mach_msg_header_t hdr; + mach_msg_trailer_t trailer; + } msg; + + /* + * Configure the message to consume the destination port we give it (_MOVE_SEND), and to + * transmute the local port receive right we give it into a send_once right at the destination. + * The server will use that send_once right to reply to us. + */ + msg.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); + msg.hdr.msgh_local_port = semaphore_req_port; + msg.hdr.msgh_remote_port = fServicePort; + + mach_msg_return_t send_err = mach_msg( + &msg.hdr, + MACH_SEND_MSG, + sizeof(msg.hdr), // no trailer on send + 0, + MACH_PORT_NULL, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); + + if (send_err != MACH_MSG_SUCCESS) { + jack_mach_error(send_err, "failed to send semaphore port request IPC"); + + if ((res = mach_port_deallocate(task, fServicePort)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to deallocate IPC service port during cleanup"); + } else { + fServicePort = MACH_PORT_NULL; + } + + if ((res = mach_port_destroy(task, semaphore_req_port)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to destroy IPC request port during cleanup"); + } + return false; + } else { + fServicePort = MACH_PORT_NULL; // We moved it into the message and away to the destination } - fSharedName = sharedName; + mach_msg_return_t recv_err = mach_msg( + &msg.hdr, + MACH_RCV_MSG, + 0, + sizeof(msg), + semaphore_req_port, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL + ); + + /* Don't leak ports: irrespective of if we succeeded to read or not, destroy the port we created + * to send/receive the request as we have no further use for it either way. */ + if ((res = mach_port_destroy(task, semaphore_req_port)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to destroy semaphore_req_port"); + // This isn't good, but doesn't actually stop the semaphore from working... don't bail + } - jack_log("JackMachSemaphore::Connect name = %s ", fName); - return true; + if (recv_err != MACH_MSG_SUCCESS) { + jack_mach_error(recv_err, "failed to receive semaphore port"); + return false; + } else { + fSemaphore = msg.hdr.msgh_remote_port; + + jack_log("JackMachSemaphore::Connect: OK, name = %s ", fName); + return true; + } } bool JackMachSemaphore::Connect(const char* name, const char* server_name) @@ -249,49 +322,75 @@ bool JackMachSemaphore::Disconnect() { - if (fSemaphore > 0) { - jack_log("JackMachSemaphore::Disconnect name = %s", fName); - fSemaphore = 0; - } - - if (!fSharedName) { + if (fSemaphore == MACH_PORT_NULL) { return true; } - munmap(fSharedName, SYNC_MAX_NAME_SIZE+1); - fSharedName = NULL; + mach_port_t task = mach_task_self(); + kern_return_t res; - close(fSharedMem); - fSharedMem = -1; - return true; + jack_log("JackMachSemaphore::Disconnect name = %s", fName); + + if (fServicePort != MACH_PORT_NULL) { + // If we're still holding onto a service port send right for some reason, deallocate it + if ((res = mach_port_deallocate(task, fServicePort)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to deallocate stray service port"); + // Continue cleanup even if this fails; don't bail + } else { + fServicePort = MACH_PORT_NULL; + } + } + + if ((res = mach_port_deallocate(task, fSemaphore)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to deallocate semaphore port"); + return false; + } else { + fSemaphore = MACH_PORT_NULL; + return true; + } } // Server side : destroy the JackGlobals void JackMachSemaphore::Destroy() { kern_return_t res; + mach_port_t task = mach_task_self(); - if (fSemaphore > 0) { - jack_log("JackMachSemaphore::Destroy name = %s", fName); - if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) { - jack_error("JackMachSemaphore::Destroy can't destroy semaphore err = %s", mach_error_string(res)); + if (fSemaphore == MACH_PORT_NULL) { + jack_error("JackMachSemaphore::Destroy semaphore is MACH_PORT_NULL; already destroyed?"); + return; + } + + if (fThreadSemServer) { + if (fThreadSemServer->Kill() < 0) { + jack_error("JackMachSemaphore::Destroy failed to kill semaphore server thread..."); + // Oh dear. How sad. Never mind. } - fSemaphore = 0; - } else { - jack_error("JackMachSemaphore::Destroy semaphore < 0"); + + JackMachThread* thread = fThreadSemServer; + fThreadSemServer = NULL; + delete thread; } - if (!fSharedName) { - return; + if (fSemServer) { + JackMachSemaphoreServer* server = fSemServer; + fSemServer = NULL; + delete server; } - munmap(fSharedName, SYNC_MAX_NAME_SIZE+1); - fSharedName = NULL; + if ((res = mach_port_destroy(task, fServicePort)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to destroy IPC port"); + } else { + fServicePort = MACH_PORT_NULL; + } - close(fSharedMem); - fSharedMem = -1; + if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) { + jack_mach_error(res, "failed to destroy semaphore"); + } else { + fSemaphore = MACH_PORT_NULL; + } - shm_unlink(fName); + jack_log("JackMachSemaphore::Destroy: OK, name = %s", fName); } } // end of namespace diff --git a/macosx/JackMachSemaphoreServer.h b/macosx/JackMachSemaphoreServer.h new file mode 100644 index 000000000..85f3522fb --- /dev/null +++ b/macosx/JackMachSemaphoreServer.h @@ -0,0 +1,56 @@ +/* +Copyright (C) 2021 Peter Bridgman + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMachSemaphoreServer__ +#define __JackMachSemaphoreServer__ + +#include "JackCompilerDeps.h" +#include "JackMachThread.h" + +#include +#include + +namespace Jack +{ + +/*! \brief A runnable thread which listens for IPC messages and replies with a semaphore send right. */ +class SERVER_EXPORT JackMachSemaphoreServer : public JackRunnableInterface +{ + private: + /*! \brief The semaphore send right that will be dispatched to clients. */ + semaphore_t fSemaphore; + + /*! \brief The port on which we will listen for IPC messages. */ + mach_port_t fServerReceive; + + /*! \brief A pointer to a null-terminated string buffer that will be read to obtain the + * server name for reporting purposes. Not managed at all by this type. */ + char* fName; + + public: + JackMachSemaphoreServer(semaphore_t semaphore, mach_port_t server_recv, char* name): + fSemaphore(semaphore), fServerReceive(server_recv), fName(name) + {} + + bool Execute() override; +}; + +} // end of namespace + +#endif diff --git a/macosx/JackMachSemaphoreServer.mm b/macosx/JackMachSemaphoreServer.mm new file mode 100644 index 000000000..21f159b06 --- /dev/null +++ b/macosx/JackMachSemaphoreServer.mm @@ -0,0 +1,87 @@ +/* +Copyright (C) 2021 Peter Bridgman + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackMachSemaphoreServer.h" +#include "JackMachUtils.h" +#include "JackConstants.h" +#include "JackTools.h" +#include "JackError.h" + +#include + +#define jack_mach_error(kern_result, message) \ + jack_mach_error_uncurried("JackMachSemaphoreServer", kern_result, message) + +namespace Jack +{ + +bool JackMachSemaphoreServer::Execute() { + jack_log("JackMachSemaphoreServer::Execute: %s", fName); + + /* Setup a message struct in our local stack frame which we can receive messages into and send + * messages from. */ + struct { + mach_msg_header_t hdr; + mach_msg_trailer_t trailer; + } msg; + + // Block until we receive a message on the fServerReceive port. + mach_msg_return_t recv_err = mach_msg( + &msg.hdr, + MACH_RCV_MSG, + 0, + sizeof(msg), + fServerReceive, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL + ); + + if (recv_err != MACH_MSG_SUCCESS) { + jack_mach_error(recv_err, "receive error"); + return true; // Continue processing more connections + } + + /* We're going to reuse the message struct that we received the message into to send a reply. + * Setup the semaphore send port that we want to give to the client as the local port... */ + msg.hdr.msgh_local_port = fSemaphore; + + /* + * ... to be returned by copy (_COPY_SEND), to a destination that is _SEND_ONCE that we no + * longer require. That destination will have been set by the client as their local_port, so + * will now already be the remote_port in the message we received (nifty, eh?). + */ + msg.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSG_TYPE_COPY_SEND); + + mach_msg_return_t send_err = mach_msg( + &msg.hdr, + MACH_SEND_MSG, + sizeof(msg.hdr), // no trailer on send + 0, + MACH_PORT_NULL, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); + + if (send_err != MACH_MSG_SUCCESS) { + jack_mach_error(send_err, "send error"); + } + + return true; +} + +} // end of namespace diff --git a/macosx/JackMachUtils.h b/macosx/JackMachUtils.h new file mode 100644 index 000000000..b9cbf59ff --- /dev/null +++ b/macosx/JackMachUtils.h @@ -0,0 +1,36 @@ +/* +Copyright (C) 2021 Peter Bridgman + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMachUtils__ +#define __JackMachUtils__ + +#define jack_mach_error_uncurried(type_name, kern_return, message) \ + jack_error(type_name "::%s: " message " - %i:%s", \ + __FUNCTION__, \ + kern_return, \ + mach_error_string(kern_return)) + +#define jack_mach_bootstrap_err_uncurried(type_name, kern_return, message, service_name) \ + jack_error(type_name "::%s: " message " [%s] - %i:%s", \ + __FUNCTION__, \ + service_name, \ + kern_return, \ + bootstrap_strerror(kern_return)) + +#endif From 596b140d6738901020ff1fc38889753ac6f0e52f Mon Sep 17 00:00:00 2001 From: ihsinme Date: Mon, 27 Sep 2021 18:10:27 +0300 Subject: [PATCH 29/31] Update JackNetUnixSocket.cpp --- posix/JackNetUnixSocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix/JackNetUnixSocket.cpp b/posix/JackNetUnixSocket.cpp index 528c95880..af7bf8802 100644 --- a/posix/JackNetUnixSocket.cpp +++ b/posix/JackNetUnixSocket.cpp @@ -143,7 +143,7 @@ namespace Jack } char host_name[32]; - gethostname(host_name, sizeof(host_name)); + GetHostName(host_name, sizeof(host_name)); struct hostent* host = gethostbyname(host_name); if (host) { From 0727bbc386288f6ff5cb6876d2321836d562221e Mon Sep 17 00:00:00 2001 From: Camille Gonnet Date: Fri, 1 Oct 2021 08:35:58 +0200 Subject: [PATCH 30/31] ALSA: convert properly S24_LE --- common/memops.c | 279 +++++++++++++++++++++++++++++++++- common/memops.h | 4 + example-clients/simdtests.cpp | 23 ++- linux/alsa/alsa_driver.c | 8 +- tools/alsa_in.c | 2 +- tools/alsa_out.c | 2 +- 6 files changed, 310 insertions(+), 8 deletions(-) diff --git a/common/memops.c b/common/memops.c index 6c5ad2f9b..725c49e17 100644 --- a/common/memops.c +++ b/common/memops.c @@ -137,6 +137,15 @@ (d) = f_round ((s) * SAMPLE_24BIT_SCALING) << 8;\ } +#define float_24l32(s, d) \ + if ((s) <= NORMALIZED_FLOAT_MIN) {\ + (d) = SAMPLE_24BIT_MIN; \ + } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ + (d) = SAMPLE_24BIT_MAX; \ + } else {\ + (d) = f_round ((s) * SAMPLE_24BIT_SCALING); \ + } + /* call this when "s" has already been scaled (e.g. when dithering) */ @@ -267,6 +276,8 @@ void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsign Ss - like S but reverse endian from the host CPU 32u24 - sample is an signed 32 bit integer value, but data is in upper 24 bits only 32u24s - like 32u24 but reverse endian from the host CPU + 32l24 - sample is an signed 32 bit integer value, but data is in lower 24 bits only + 32l24s - like 32l24 but reverse endian from the host CPU 24 - sample is an signed 24 bit integer value 24s - like 24 but reverse endian from the host CPU 16 - sample is an signed 16 bit integer value @@ -546,6 +557,273 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne } } +void sample_move_d32l24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) +{ +#if defined (__ARM_NEON__) || defined (__ARM_NEON) + unsigned long unrolled = nsamples / 4; + nsamples = nsamples & 3; + + while (unrolled--) { + float32x4_t samples = vld1q_f32(src); + int32x4_t converted = float_24_neon(samples); + converted = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(converted))); + + switch(dst_skip) { + case 4: + vst1q_s32((int32_t*)dst, converted); + break; + default: + vst1q_lane_s32((int32_t*)(dst), converted, 0); + vst1q_lane_s32((int32_t*)(dst+dst_skip), converted, 1); + vst1q_lane_s32((int32_t*)(dst+2*dst_skip), converted, 2); + vst1q_lane_s32((int32_t*)(dst+3*dst_skip), converted, 3); + break; + } + dst += 4*dst_skip; + src+= 4; + } +#endif + + int32_t z; + + while (nsamples--) { + + float_24l32 (*src, z); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + dst[0]=(char)(z>>24); + dst[1]=(char)(z>>16); + dst[2]=(char)(z>>8); + dst[3]=(char)(z); +#elif __BYTE_ORDER == __BIG_ENDIAN + dst[0]=(char)(z); + dst[1]=(char)(z>>8); + dst[2]=(char)(z>>16); + dst[3]=(char)(z>>24); +#endif + dst += dst_skip; + src++; + } +} + +void sample_move_d32l24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) +{ +#if defined (__SSE2__) && !defined (__sun__) + __m128 int_max = _mm_set1_ps(SAMPLE_24BIT_MAX_F); + __m128 int_min = _mm_sub_ps(_mm_setzero_ps(), int_max); + __m128 factor = int_max; + + unsigned long unrolled = nsamples / 4; + nsamples = nsamples & 3; + + while (unrolled--) { + __m128 in = _mm_load_ps(src); + __m128 scaled = _mm_mul_ps(in, factor); + __m128 clipped = clip(scaled, int_min, int_max); + + __m128i shifted = _mm_cvttps_epi32(clipped); + +#ifdef __SSE4_1__ + *(int32_t*)dst = _mm_extract_epi32(shifted, 0); + *(int32_t*)(dst+dst_skip) = _mm_extract_epi32(shifted, 1); + *(int32_t*)(dst+2*dst_skip) = _mm_extract_epi32(shifted, 2); + *(int32_t*)(dst+3*dst_skip) = _mm_extract_epi32(shifted, 3); +#else + __m128i shuffled1 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(0, 3, 2, 1)); + __m128i shuffled2 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(1, 0, 3, 2)); + __m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); + + _mm_store_ss((float*)dst, (__m128)shifted); + + _mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1); + _mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2); + _mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3); +#endif + dst += 4*dst_skip; + + src+= 4; + } + + while (nsamples--) { + __m128 in = _mm_load_ss(src); + __m128 scaled = _mm_mul_ss(in, factor); + __m128 clipped = _mm_min_ss(int_max, _mm_max_ss(scaled, int_min)); + + int y = _mm_cvttss_si32(clipped); + *((int *) dst) = y<<8; + + dst += dst_skip; + src++; + } +#elif defined (__ARM_NEON__) || defined (__ARM_NEON) + unsigned long unrolled = nsamples / 4; + nsamples = nsamples & 3; + + while (unrolled--) { + float32x4_t samples = vld1q_f32(src); + int32x4_t converted = float_24_neon(samples); + + switch(dst_skip) { + case 4: + vst1q_s32((int32_t*)dst, converted); + break; + default: + vst1q_lane_s32((int32_t*)(dst), converted, 0); + vst1q_lane_s32((int32_t*)(dst+dst_skip), converted, 1); + vst1q_lane_s32((int32_t*)(dst+2*dst_skip), converted, 2); + vst1q_lane_s32((int32_t*)(dst+3*dst_skip), converted, 3); + break; + } + dst += 4*dst_skip; + + src+= 4; + } +#endif + +#if !defined (__SSE2__) + while (nsamples--) { + float_24l32 (*src, *((int32_t*) dst)); + dst += dst_skip; + src++; + } +#endif +} + +void sample_move_dS_s32l24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) +{ +#if defined (__ARM_NEON__) || defined (__ARM_NEON) + float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING); + unsigned long unrolled = nsamples / 4; + while (unrolled--) { + uint32x4_t src128; + switch(src_skip) + { + case 4: + src128 = vld1q_u32((uint32_t*)src); + break; + case 8: + src128 = vld2q_u32((uint32_t*)src).val[0]; + break; + default: + src128 = vld1q_lane_u32((uint32_t*)src, src128, 0); + src128 = vld1q_lane_u32((uint32_t*)(src+src_skip), src128, 1); + src128 = vld1q_lane_u32((uint32_t*)(src+2*src_skip), src128, 2); + src128 = vld1q_lane_u32((uint32_t*)(src+3*src_skip), src128, 3); + break; + } + src128 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(src128))); + uint32x4_t toupper = vshlq_n_u32(src128, 8); + int32x4_t shifted = vshrq_n_s32((int32x4_t)toupper, 8); + float32x4_t as_float = vcvtq_f32_s32(shifted); + float32x4_t divided = vmulq_f32(as_float, factor); + vst1q_f32(dst, divided); + + src += 4*src_skip; + dst += 4; + } + nsamples = nsamples & 3; +#endif + + /* ALERT: signed sign-extension portability !!! */ + + const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; + + while (nsamples--) { + int32_t x; +#if __BYTE_ORDER == __LITTLE_ENDIAN + x = (unsigned char)(src[0]); + x <<= 8; + x |= (unsigned char)(src[1]); + x <<= 8; + x |= (unsigned char)(src[2]); + x <<= 8; + x |= (unsigned char)(src[3]); +#elif __BYTE_ORDER == __BIG_ENDIAN + x = (unsigned char)(src[3]); + x <<= 8; + x |= (unsigned char)(src[2]); + x <<= 8; + x |= (unsigned char)(src[1]); + x <<= 8; + x |= (unsigned char)(src[0]); +#endif + *dst = (x >> 0) * scaling; + dst++; + src += src_skip; + } +} + +void sample_move_dS_s32l24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) +{ +#if defined (__SSE2__) && !defined (__sun__) + unsigned long unrolled = nsamples / 4; + static float inv_sample_max_24bit = 1.0 / SAMPLE_24BIT_SCALING; + __m128 factor = _mm_set1_ps(inv_sample_max_24bit); + while (unrolled--) + { + int i1 = *((int *) src); + src+= src_skip; + int i2 = *((int *) src); + src+= src_skip; + int i3 = *((int *) src); + src+= src_skip; + int i4 = *((int *) src); + src+= src_skip; + + __m128i shifted = _mm_set_epi32(i4, i3, i2, i1); + + __m128 as_float = _mm_cvtepi32_ps(shifted); + __m128 divided = _mm_mul_ps(as_float, factor); + + _mm_storeu_ps(dst, divided); + + dst += 4; + } + nsamples = nsamples & 3; +#elif defined (__ARM_NEON__) || defined (__ARM_NEON) + unsigned long unrolled = nsamples / 4; + float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING); + while (unrolled--) { + uint32x4_t src128; + switch(src_skip) { + case 4: + src128 = vld1q_u32((uint32_t*)src); + break; + case 8: + src128 = vld2q_u32((uint32_t*)src).val[0]; + break; + default: + src128 = vld1q_lane_u32((uint32_t*)src, src128, 0); + src128 = vld1q_lane_u32((uint32_t*)(src+src_skip), src128, 1); + src128 = vld1q_lane_u32((uint32_t*)(src+2*src_skip), src128, 2); + src128 = vld1q_lane_u32((uint32_t*)(src+3*src_skip), src128, 3); + break; + } + // Sign extension by moving to upper as unsigned, then down + uint32x4_t toupper = vshlq_n_u32(src128, 8); + int32x4_t shifted = vshrq_n_s32((int32x4_t)toupper, 8); + float32x4_t as_float = vcvtq_f32_s32(shifted); + float32x4_t divided = vmulq_f32(as_float, factor); + vst1q_f32(dst, divided); + + src += 4*src_skip; + dst += 4; + } + nsamples = nsamples & 3; +#endif + + /* ALERT: signed sign-extension portability !!! */ + + const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; + while (nsamples--) { + uint32_t val=(*((uint32_t*)src)); + if (val & 0x800000u) val|=0xFF000000u; + *dst = (*((int32_t *) &val)) * scaling; + dst++; + src += src_skip; + } +} + void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { #if defined (__ARM_NEON__) || defined (__ARM_NEON) @@ -1189,4 +1467,3 @@ memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, src_bytes -= 4; } } - diff --git a/common/memops.h b/common/memops.h index c027e4d6f..a69087ff4 100644 --- a/common/memops.h +++ b/common/memops.h @@ -55,6 +55,8 @@ void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsign /* integer functions */ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_d32l24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_d32l24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); @@ -81,6 +83,8 @@ void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); +void sample_move_dS_s32l24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); +void sample_move_dS_s32l24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); diff --git a/example-clients/simdtests.cpp b/example-clients/simdtests.cpp index dc50be625..40b30e90d 100644 --- a/example-clients/simdtests.cpp +++ b/example-clients/simdtests.cpp @@ -118,6 +118,26 @@ test_case_data_t test_cases[] = { origerated::sample_move_dS_s32u24, NULL, "32u24" }, + { + 4, + 3, + true, + accelerated::sample_move_d32l24_sSs, + origerated::sample_move_d32l24_sSs, + accelerated::sample_move_dS_s32l24s, + origerated::sample_move_dS_s32l24s, + NULL, + "32l24s" }, + { + 4, + 3, + false, + accelerated::sample_move_d32l24_sS, + origerated::sample_move_d32l24_sS, + accelerated::sample_move_dS_s32l24, + origerated::sample_move_dS_s32l24, + NULL, + "32l24" }, { 3, 3, @@ -283,7 +303,8 @@ int main(int argc, char *argv[]) #else test_cases[testcase].reverse); #endif - if(intval_accel != intval_orig) { + // allow a deviation of 1 + if(intval_accel>intval_orig+1 || intval_orig>intval_accel+1) { if(int_error_countwrite_via_copy = driver->quirk_bswap? - sample_move_d32u24_sSs: - sample_move_d32u24_sS; + sample_move_d32l24_sSs: + sample_move_d32l24_sS; break; default: @@ -344,8 +344,8 @@ alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) break; case 4: driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s32u24s: - sample_move_dS_s32u24; + sample_move_dS_s32l24s: + sample_move_dS_s32l24; break; } } diff --git a/tools/alsa_in.c b/tools/alsa_in.c index 99d27d13d..a52f06e4d 100644 --- a/tools/alsa_in.c +++ b/tools/alsa_in.c @@ -97,7 +97,7 @@ alsa_format_t formats[] = { { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, - { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, + { SND_PCM_FORMAT_S24, 4, sample_move_d32l24_sS, sample_move_dS_s32l24, "24bit" }, { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } #ifdef __ANDROID__ ,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" } diff --git a/tools/alsa_out.c b/tools/alsa_out.c index 0c9a8b26c..40cdce3cc 100644 --- a/tools/alsa_out.c +++ b/tools/alsa_out.c @@ -98,7 +98,7 @@ alsa_format_t formats[] = { { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, - { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, + { SND_PCM_FORMAT_S24, 4, sample_move_d32l24_sS, sample_move_dS_s32l24, "24bit" }, { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } #ifdef __ANDROID__ ,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" } From b3175e772071313627d22083f719ca64f6f62909 Mon Sep 17 00:00:00 2001 From: PavelAtr Date: Sat, 27 Nov 2021 08:13:36 +0300 Subject: [PATCH 31/31] OpenSL ES driver. Changing the queue processing strategy. --- android/JackOpenSLESDriver.cpp | 1 - android/opensl_io.c | 104 ++++++++++++++++++++++++--------- android/opensl_io.h | 4 +- 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/android/JackOpenSLESDriver.cpp b/android/JackOpenSLESDriver.cpp index f4e8608a5..8f863a46e 100644 --- a/android/JackOpenSLESDriver.cpp +++ b/android/JackOpenSLESDriver.cpp @@ -30,7 +30,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include -#include #include "opensl_io.h" #define JACK_OPENSLES_DEFAULT_SAMPLERATE 48000 diff --git a/android/opensl_io.c b/android/opensl_io.c index 38b6ec0ce..4a2c7ad83 100644 --- a/android/opensl_io.c +++ b/android/opensl_io.c @@ -28,6 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "opensl_io.h" +#include +#include //#define CONV16BIT 32768 //#define CONVMYFLT (1./32768.) #define CONV16BIT 32640 @@ -116,12 +118,12 @@ static SLresult openSLPlayOpen(OPENSL_STREAM *p) const SLInterfaceID ids[] = {SL_IID_VOLUME}; const SLboolean req[] = {SL_BOOLEAN_FALSE}; result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; + if(result != SL_RESULT_SUCCESS) return result; // realize the output mix result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); - int speakers; + SLuint32 speakers; if(channels > 1) speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else speakers = SL_SPEAKER_FRONT_CENTER; @@ -225,7 +227,7 @@ static SLresult openSLRecOpen(OPENSL_STREAM *p){ SLDataSource audioSrc = {&loc_dev, NULL}; // configure audio sink - int speakers; + SLuint32 speakers; if(channels > 1) speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else speakers = SL_SPEAKER_FRONT_CENTER; @@ -316,7 +318,11 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, p->outchannels = outchannels; p->sr = sr; p->inlock = createThreadLock(); + if (p->inlock == NULL) + return NULL; p->outlock = createThreadLock(); + if (p->outlock == NULL) + return NULL; if((p->outBufSamples = bufferframes*outchannels) != 0) { if((p->outputBuffer[0] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL || @@ -336,6 +342,10 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, p->currentInputIndex = 0; p->currentOutputBuffer = 0; + p->outputBufferSize[0] = 0; + p->outputBufferSize[1] = 0; + p->inputBufferSize[0] = 0; + p->inputBufferSize[1] = 0; p->currentInputIndex = p->inBufSamples; p->currentInputBuffer = 0; @@ -358,6 +368,17 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, notifyThreadLock(p->inlock); p->time = 0.; + + if (p->bqPlayerBufferQueue) + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, + p->outputBuffer[0], p->outBufSamples*sizeof(short)); + + if (p->recorderBufferQueue) + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + p->inputBuffer[0], p->inBufSamples*sizeof(short)); + + + return p; } @@ -414,39 +435,66 @@ double android_GetTimestamp(OPENSL_STREAM *p){ void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { OPENSL_STREAM *p = (OPENSL_STREAM *) context; + + while ((p->inputBufferSize[0] > 0) && (p->inputBufferSize[1] > 0)) + usleep(1000); + + p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1); + int queueInputBuffer = (p->currentInputBuffer ? 0 : 1); + int size = p->inBufSamples; + short *inBuffer = p->inputBuffer[queueInputBuffer]; + + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + inBuffer, size * sizeof(short)); + + p->inputBufferSize[queueInputBuffer] = size; notifyThreadLock(p->inlock); } // gets a buffer of size samples from the device int android_AudioIn(OPENSL_STREAM *p,float *buffer,int size){ + short *inBuffer; int i, bufsamps, index; if(p == NULL) return 0; bufsamps = p->inBufSamples; + if(bufsamps == 0) return 0; - index = p->currentInputIndex; + if (size > bufsamps) return 0; + if (p->inputBufferSize[p->currentInputBuffer] == 0) + waitThreadLock(p->inlock); + + index = 0; inBuffer = p->inputBuffer[p->currentInputBuffer]; + for(i=0; i < size; i++){ - if (index >= bufsamps) { - waitThreadLock(p->inlock); - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - inBuffer,bufsamps*sizeof(short)); - p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1); - index = 0; - inBuffer = p->inputBuffer[p->currentInputBuffer]; - } buffer[i] = (float) inBuffer[index++]*CONVMYFLT; } - p->currentInputIndex = index; + + p->inputBufferSize[p->currentInputBuffer] = 0; if(p->outchannels == 0) p->time += (double) size/(p->sr*p->inchannels); - return i; + + return size; } // this callback handler is called every time a buffer finishes playing void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { OPENSL_STREAM *p = (OPENSL_STREAM *) context; + + while ((p->outputBufferSize[0] == 0) && (p->outputBufferSize[1] == 0)) + usleep(1000); + + p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1); + int queueOutputBuffer = (p->currentOutputBuffer ? 0 : 1); + int size = p->outputBufferSize[queueOutputBuffer]; + short *outBuffer = p->outputBuffer[queueOutputBuffer]; + + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, + outBuffer, size * sizeof(short)); + + p->outputBufferSize[queueOutputBuffer] = 0; notifyThreadLock(p->outlock); } @@ -457,24 +505,26 @@ int android_AudioOut(OPENSL_STREAM *p, float *buffer,int size){ int i, bufsamps, index; if(p == NULL) return 0; bufsamps = p->outBufSamples; + if(bufsamps == 0) return 0; - index = p->currentOutputIndex; + if (size > bufsamps) return 0; + + + if (p->outputBufferSize[p->currentOutputBuffer] != 0) + waitThreadLock(p->outlock); + + index = 0; outBuffer = p->outputBuffer[p->currentOutputBuffer]; + for(i=0; i < size; i++){ outBuffer[index++] = (short) (buffer[i]*CONV16BIT); - if (index >= p->outBufSamples) { - waitThreadLock(p->outlock); - (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, - outBuffer,bufsamps*sizeof(short)); - p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1); - index = 0; - outBuffer = p->outputBuffer[p->currentOutputBuffer]; - } } - p->currentOutputIndex = index; + + p->outputBufferSize[p->currentOutputBuffer] = size; + p->time += (double) size/(p->sr*p->outchannels); - return i; + return size; } //---------------------------------------------------------------------- @@ -507,12 +557,12 @@ int waitThreadLock(void *lock) int retval = 0; p = (threadLock*) lock; pthread_mutex_lock(&(p->m)); + p->s = (unsigned char) 0; while (!p->s) { pthread_cond_wait(&(p->c), &(p->m)); } - p->s = (unsigned char) 0; pthread_mutex_unlock(&(p->m)); - return NULL; + return retval; } void notifyThreadLock(void *lock) diff --git a/android/opensl_io.h b/android/opensl_io.h index 501f0361c..fcb7c6a7c 100644 --- a/android/opensl_io.h +++ b/android/opensl_io.h @@ -72,10 +72,12 @@ typedef struct opensl_stream { // current buffer half (0, 1) int currentOutputBuffer; int currentInputBuffer; - + // buffers short *outputBuffer[2]; short *inputBuffer[2]; + int outputBufferSize[2]; + int inputBufferSize[2]; // size of buffers int outBufSamples;