From ac6becea14ec7f8b1df3c3060a992696f39a91c5 Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 8 Aug 2019 21:57:20 +0200 Subject: [PATCH 01/11] Import CI build scripts from master --- .appveyor-mingw.yml | 63 ------------ .appveyor-vcpkg.yml | 19 +--- .appveyor.yml | 83 ---------------- .azure-pipelines.yml | 222 +++++++++++++++++++++++++++++++++++++++++++ .cirrus.yml | 4 +- .travis.yml | 43 ++++----- 6 files changed, 244 insertions(+), 190 deletions(-) delete mode 100644 .appveyor-mingw.yml delete mode 100644 .appveyor.yml create mode 100644 .azure-pipelines.yml diff --git a/.appveyor-mingw.yml b/.appveyor-mingw.yml deleted file mode 100644 index fed226b0..00000000 --- a/.appveyor-mingw.yml +++ /dev/null @@ -1,63 +0,0 @@ -image: - - Visual Studio 2013 - -build: - parallel: true - verbosity: detailed - -environment: - matrix: - - platform: x86 - glib-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib_2.28.8-1_win32.zip - glib-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib-dev_2.28.8-1_win32.zip - pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/pkg-config_0.26-1_win32.zip - gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime_0.18.1.1-2_win32.zip - proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/proxy-libintl-dev_20100902_win32.zip - - - platform: x64 - glib-url: http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib_2.26.1-1_win64.zip - glib-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib-dev_2.26.1-1_win64.zip - pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/pkg-config_0.23-2_win64.zip - gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip - proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/proxy-libintl-dev_20100902_win64.zip - -init: - - echo %APPVEYOR_BUILD_WORKER_IMAGE% - -install: -# make sure the latest version of git is installed - - choco upgrade git -y - - mkdir c:\deps - - cd c:\deps - - curl -fsS -o glib.zip %glib-url% - - curl -fsS -o glib-dev.zip %glib-dev-url% - - curl -fsS -o pkg-config.zip %pkg-config-url% - - curl -fsS -o gettext.zip %gettext-url% - - curl -fsS -o libintl-dev.zip %proxy-libintl-dev-url% - - 7z x glib.zip > NUL - - 7z x glib-dev.zip > NUL - - 7z x pkg-config.zip > NUL - - 7z x gettext.zip > NUL - - 7z x libintl-dev.zip > NUL - - SET PATH=C:\deps\bin;%PATH% - - if "%platform%"=="x64" ( SET "PATH=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%" ) else ( SET "PATH=C:\MinGW\bin;%PATH%" ) - -build_script: -# - call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 -# - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 - - cd C:\projects\fluidsynth-rjimi - - mkdir build - - cd build -# remove that path from PATH to make sure sh.exe is not found (cmake will complain otherwise) - - set PATH=%PATH:C:\Program Files\Git\usr\bin;=% - - echo %PATH% - - echo %CFLAGS% - - cmake -G "MinGW Makefiles" -DCMAKE_VERBOSE_MAKEFILE=1 .. - - mingw32-make.exe check - -after_build: - - 7z a fluidsynth-%platform%.zip %APPVEYOR_BUILD_FOLDER%\build\src\* c:\deps\bin\libglib*.dll c:\deps\bin\libgthread*.dll c:\deps\bin\*intl*.dll - -artifacts: - - path: build/fluidsynth-%platform%.zip - name: FluidSynth diff --git a/.appveyor-vcpkg.yml b/.appveyor-vcpkg.yml index 1025f579..b579ac20 100644 --- a/.appveyor-vcpkg.yml +++ b/.appveyor-vcpkg.yml @@ -14,24 +14,8 @@ environment: matrix: - platform: x86 - CMAKE_FLAGS: - - platform: x86 - CMAKE_FLAGS: -Denable-network=0 - - - platform: x86 - CMAKE_FLAGS: -DBUILD_SHARED_LIBS=0 - - platform: x64 - CMAKE_FLAGS: - - - platform: x64 - CMAKE_FLAGS: -Denable-network=0 - - - platform: x64 - CMAKE_FLAGS: -DBUILD_SHARED_LIBS=0 - -# - platform: ARM ## currently fails to build pcre:arm-windows cache: - c:\Tools\vcpkg\installed @@ -43,7 +27,6 @@ init: - echo %TARGET_PLATFORM% - echo %APPVEYOR_BUILD_WORKER_IMAGE% - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" ( set "generator=Visual Studio 15 2017%TARGET_PLATFORM%" && set "toolset=v141_xp" ) - - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" ( set "generator=Visual Studio 14 2015%TARGET_PLATFORM%" && set "toolset=v140_xp" ) - echo %generator% - echo %toolset% @@ -55,7 +38,7 @@ install: build_script: - mkdir build - cd build - - cmake -G "%generator%" -T "%toolset%" %CMAKE_FLAGS% -Denable-pkgconfig=0 -DCMAKE_TOOLCHAIN_FILE=c:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake .. + - cmake -G "%generator%" -T "%toolset%" -Denable-pkgconfig=0 -DCMAKE_TOOLCHAIN_FILE=c:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DNO_GUI=1 .. - cmake --build . --config Release # build libfluidsynth and fluidsynth exec - cmake --build . --config Release --target check # build and exec unittests diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 7281373e..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,83 +0,0 @@ -image: - - Visual Studio 2015 - -build: - parallel: true - verbosity: detailed - -configuration: - - Release - -environment: - matrix: - - platform: x86 - glib-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib_2.28.8-1_win32.zip - glib-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib-dev_2.28.8-1_win32.zip - pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/pkg-config_0.26-1_win32.zip - gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime_0.18.1.1-2_win32.zip - proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/proxy-libintl-dev_20100902_win32.zip - - - platform: x64 - glib-url: http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib_2.26.1-1_win64.zip - glib-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib-dev_2.26.1-1_win64.zip - pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/pkg-config_0.23-2_win64.zip - gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip - proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/proxy-libintl-dev_20100902_win64.zip - - - platform: x86 - glib-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.16/glib_2.16.6-1_win32.zip - glib-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.16/glib-dev_2.16.6-1_win32.zip - pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/pkg-config_0.26-1_win32.zip - gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime_0.18.1.1-2_win32.zip - proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/proxy-libintl-dev_20100902_win32.zip - - - platform: x64 - glib-url: http://ftp.acc.umu.se/pub/gnome/binaries/win64/glib/2.24/glib_2.24.2-2_win64.zip - glib-dev-url: http://ftp.acc.umu.se/pub/gnome/binaries/win64/glib/2.24/glib-dev_2.24.0-1_win64.zip - pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/pkg-config_0.23-2_win64.zip - gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip - proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/proxy-libintl-dev_20100902_win64.zip - -init: - - set TARGET_PLATFORM= - - if "%platform%"=="x64" ( set TARGET_PLATFORM= Win64) - - echo %TARGET_PLATFORM% - - echo %APPVEYOR_BUILD_WORKER_IMAGE% - - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" ( set "generator=Visual Studio 15 2017%TARGET_PLATFORM%" && set "toolset=v141_xp" ) - - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" ( set "generator=Visual Studio 14 2015%TARGET_PLATFORM%" && set "toolset=v140_xp" ) - - echo %generator% - - echo %toolset% - -install: -# make sure the latest version of git is installed - - choco upgrade git -y - - mkdir c:\deps - - cd c:\deps - - curl -fsS -o glib.zip %glib-url% - - curl -fsS -o glib-dev.zip %glib-dev-url% - - curl -fsS -o pkg-config.zip %pkg-config-url% - - curl -fsS -o gettext.zip %gettext-url% - - curl -fsS -o libintl-dev.zip %proxy-libintl-dev-url% - - 7z x glib.zip > NUL - - 7z x glib-dev.zip > NUL - - 7z x pkg-config.zip > NUL - - 7z x gettext.zip > NUL - - 7z x libintl-dev.zip > NUL - - SET "PATH=C:\deps\bin;%PATH%" - -build_script: -# - call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 -# - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 - - cd C:\projects\fluidsynth - - mkdir build - - cd build - - cmake -G "%generator%" -T "%toolset%" .. - - cmake --build . --config Release - - cmake --build . --config Release --target check # build and exec unittests - -after_build: - - 7z a fluidsynth-%platform%.zip %APPVEYOR_BUILD_FOLDER%\build\src\Release\* c:\deps\bin\libglib*.dll c:\deps\bin\libgthread*.dll c:\deps\bin\*intl*.dll - -artifacts: - - path: build/fluidsynth-%platform%.zip - name: FluidSynth diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml new file mode 100644 index 00000000..b28c8ac8 --- /dev/null +++ b/.azure-pipelines.yml @@ -0,0 +1,222 @@ +# C/C++ with GCC +# Build your C/C++ project with GCC using make. +# Add steps that publish test results, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/apps/c-cpp/gcc + +jobs: +- job: macOS + pool: + vmImage: 'macOS-10.14' + steps: + - script: | + brew update + brew install glib gobject-introspection libsndfile pkg-config jack dbus-glib pulseaudio portaudio sdl2 + displayName: 'Prerequisites' + - script: | + mkdir build && cd build + export PKG_CONFIG_PATH="/usr/local/opt/libffi/lib/pkgconfig" + cmake -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. + make + displayName: 'Compile fluidsynth' + - script: | + cd build || exit -1 + make check || exit -1 + displayName: 'Execute Unittests' + +- job: Windows + strategy: + matrix: + XP_x86: + platform: Win32 + toolset: v141_xp + gtk-bundle: $(gtk-bundle-x86) + libsndfile-url: $(libsndfile-url-x86) + artifact-prefix: "fluidsynth" + imageName: 'vs2017-win2016' + XP_x64: + platform: x64 + toolset: v141_xp + gtk-bundle: $(gtk-bundle-x64) + libsndfile-url: $(libsndfile-url-x64) + artifact-prefix: "fluidsynth" + imageName: 'vs2017-win2016' + pool: + vmImage: $(imageName) + steps: + - task: DownloadBuildArtifacts@0 + inputs: + buildType: specific + # https://dev.azure.com/tommbrt/_apis/projects?api-version=5.0 + project: 'd3638885-de4a-4ce7-afe7-f237ae461c07' + pipeline: 1 + artifactName: libinstpatch-$(platform) + downloadPath: '$(Build.ArtifactStagingDirectory)' + displayName: 'Get libinstpatch' + - script: | + @ECHO ON + mkdir d:\deps || exit -1 + cd d:\deps || exit -1 + curl -LfsS -o gtk-bundle-dev.zip $(gtk-bundle) || exit -1 + curl -LfsS -o libsndfile-dev.zip $(libsndfile-url) || exit -1 + 7z x -aos -- gtk-bundle-dev.zip > NUL || exit -1 + 7z x -aos -- libsndfile-dev.zip > NUL || exit -1 + REM need to fix the naming of libsndfile otherwise the linker won't find it + mv lib\libsndfile-1.lib lib\sndfile.lib || exit -1 + mv lib\libsndfile-1.def lib\sndfile.def || exit -1 + cd $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform) + cp -rf * d:\deps\ + mv -f * .. + cd .. + rmdir $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform)\ + displayName: 'Prerequisites' + - script: | + @ECHO ON + SET "PATH=d:\deps\bin;%PATH%" + pkg-config --list-all + mkdir build && cd build || exit -1 + cmake -A $(platform) -T $(toolset) -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) -Denable-readline=0 -Denable-floats=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1 + cmake --build . --config Release || exit -1 + displayName: 'Compile fluidsynth' + - script: | + @ECHO ON + SET "PATH=d:\deps\bin;%PATH%" + cd build || exit -1 + cmake --build . --config Release --target check || exit -1 + displayName: 'Execute Unittests' + - script: | + @ECHO ON + cd build + cmake --build . --config Release --target install || exit -1 + del $(Build.ArtifactStagingDirectory)\bin\concrt*.dll + del $(Build.ArtifactStagingDirectory)\bin\vcruntime*.dll + del $(Build.ArtifactStagingDirectory)\bin\msvcp*.dll + del $(Build.ArtifactStagingDirectory)\lib\libinstpatch*.lib + del $(Build.ArtifactStagingDirectory)\lib\pkgconfig\libinstpatch*.pc + rd $(Build.ArtifactStagingDirectory)\include\libinstpatch-0 /s /q + displayName: 'Copy Artifacts' + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: $(Build.ArtifactStagingDirectory) + artifactName: $(artifact-prefix)-$(platform) + +- job: WindowsCI + strategy: + matrix: + default: + CMAKE_FLAGS: + CMAKE_CONFIG: Release + gtk-bundle: $(gtk-bundle-x64) + libsndfile-url: $(libsndfile-url-x64) + debug_prof: + CMAKE_FLAGS: -Denable-profiling=1 -Denable-trap-on-fpe=1 -Denable-fpe-check=1 + CMAKE_CONFIG: Debug + gtk-bundle: $(gtk-bundle-x64) + libsndfile-url: $(libsndfile-url-x64) + no_network: + CMAKE_FLAGS: -Denable-network=0 + CMAKE_CONFIG: Release + gtk-bundle: $(gtk-bundle-x64) + libsndfile-url: $(libsndfile-url-x64) + static_lib: + CMAKE_FLAGS: -DBUILD_SHARED_LIBS=0 + CMAKE_CONFIG: Release + gtk-bundle: $(gtk-bundle-x64) + libsndfile-url: $(libsndfile-url-x64) + minimal: + CMAKE_FLAGS: -Denable-ipv6=0 -Denable-network=0 -Denable-aufile=0 -Denable-dbus=0 -Denable-threads=0 -Denable-winmidi=0 -Denable-waveout=0 -Denable-dsound=0 -Denable-libsndfile=0 -Denable-floats=1 + CMAKE_CONFIG: Release + gtk-bundle: $(gtk-bundle-x64) + libsndfile-url: $(libsndfile-url-x64) + pool: + vmImage: 'windows-2019' + steps: + - script: | + @ECHO ON + mkdir d:\deps || exit -1 + cd d:\deps || exit -1 + curl -LfsS -o gtk-bundle-dev.zip $(gtk-bundle) || exit -1 + curl -LfsS -o libsndfile-dev.zip $(libsndfile-url) || exit -1 + 7z x -aos -- gtk-bundle-dev.zip > NUL || exit -1 + 7z x -aos -- libsndfile-dev.zip > NUL || exit -1 + REM need to fix the naming of libsndfile otherwise the linker won't find it + mv lib\libsndfile-1.lib lib\sndfile.lib || exit -1 + mv lib\libsndfile-1.def lib\sndfile.def || exit -1 + displayName: 'Prerequisites' + - script: | + @ECHO ON + SET "PATH=d:\deps\bin;%PATH%" + mkdir build && cd build || exit -1 + cmake -A x64 -DCMAKE_BUILD_TYPE=$(CMAKE_CONFIG) -DCMAKE_VERBOSE_MAKEFILE=1 $(CMAKE_FLAGS) -DNO_GUI=1 .. || exit -1 + cmake --build . --config $(CMAKE_CONFIG) || exit -1 + displayName: 'Compile fluidsynth' + - script: | + @ECHO ON + SET "PATH=d:\deps\bin;%PATH%" + cd build || exit -1 + cmake --build . --config $(CMAKE_CONFIG) --target check || exit -1 + displayName: 'Execute Unittests' + +- job: WindowsMinGW + strategy: + matrix: + x86: + CMAKE_FLAGS: -DCMAKE_C_FLAGS="-m32" + platform: Win32 + gtk-bundle: $(gtk-bundle-x86) + libsndfile-url: $(libsndfile-url-x86) + mingw-url: $(mingw-url-x86) + x64: + CMAKE_FLAGS: + platform: x64 + gtk-bundle: $(gtk-bundle-x64) + libsndfile-url: $(libsndfile-url-x64) + mingw-url: $(mingw-url-x64) + pool: + vmImage: 'vs2017-win2016' + steps: + - task: DownloadBuildArtifacts@0 + inputs: + buildType: specific + # https://dev.azure.com/tommbrt/_apis/projects?api-version=5.0 + project: 'd3638885-de4a-4ce7-afe7-f237ae461c07' + pipeline: 1 + artifactName: libinstpatch-$(platform) + downloadPath: '$(Build.ArtifactStagingDirectory)' + displayName: 'Get libinstpatch' + - script: | + @ECHO ON + mkdir d:\deps || exit -1 + cd d:\deps || exit -1 + curl -LfsS -o gtk-bundle-dev.zip $(gtk-bundle) || exit -1 + curl -LfsS -o libsndfile-dev.zip $(libsndfile-url) || exit -1 + curl -LfsS -o mingw.zip $(mingw-url) || exit -1 + 7z x -aos -- gtk-bundle-dev.zip > NUL || exit -1 + 7z x -aos -- libsndfile-dev.zip > NUL || exit -1 + 7z x -aos -- mingw.zip > NUL || exit -1 + rm *.zip + REM need to fix the naming of libsndfile otherwise the linker won't find it + mv lib\libsndfile-1.lib lib\sndfile.lib || exit -1 + mv lib\libsndfile-1.def lib\sndfile.def || exit -1 + cd mingw*\ && cp -rf * .. && cd .. && rm -rf mingw* || exit -1 + cd $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform) && cp -rf * d:\deps\ && mv -f * .. && cd .. && rmdir $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform)\ || exit -1 + displayName: 'Prerequisites' + - script: | + @ECHO ON + SET "PATH=d:\deps\bin;%PATH%" + REM remove that path from PATH to make sure sh.exe is not found (cmake will complain otherwise) + set PATH=%PATH:C:\Program Files\Git\bin;=% + set PATH=%PATH:C:\Program Files\Git\usr\bin;=% + pkg-config --list-all + mkdir build && cd build || exit -1 + cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) $(CMAKE_FLAGS) -Denable-readline=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1 + mingw32-make.exe all || exit -1 + displayName: 'Compile fluidsynth' + - script: | + @ECHO ON + SET "PATH=d:\deps\bin;%PATH%" + REM remove that path from PATH to make sure sh.exe is not found (cmake will complain otherwise) + set PATH=%PATH:C:\Program Files\Git\bin;=% + set PATH=%PATH:C:\Program Files\Git\usr\bin;=% + cd build || exit -1 + mingw32-make.exe check || exit -1 + displayName: 'Execute Unittests' diff --git a/.cirrus.yml b/.cirrus.yml index 2d8c5ed5..3fbb355c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,9 +2,9 @@ freebsd_instance: image: freebsd-12-0-release-amd64 task: - install_script: pwd && ls -la && pkg install -y cmake glib alsa-lib ladspa portaudio pulseaudio pkgconf + install_script: pwd && ls -la && pkg install -y cmake glib alsa-lib ladspa portaudio pulseaudio pkgconf sdl2 - compile_script: pwd && ls -la && mkdir $HOME/fluidsynth_install/ && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=$HOME/fluidsynth_install -Denable-portaudio=1 -Denable-ladspa=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=0 .. && make -j4 && make check && make install + compile_script: pwd && ls -la && mkdir $HOME/fluidsynth_install/ && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=$HOME/fluidsynth_install -Denable-portaudio=1 -Denable-ladspa=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=0 -DNO_GUI=1 .. && make -j4 && make check && make install diff --git a/.travis.yml b/.travis.yml index e32b0a85..4ddcd226 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,14 @@ language: c sudo: false os: linux -dist: trusty +dist: bionic addons: apt: + update: true sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-6.0 - - llvm-toolchain-trusty-7 + - llvm-toolchain-bionic-7 + - llvm-toolchain-bionic-8 packages: - cmake-data - cmake @@ -19,6 +20,7 @@ addons: - libpulse-dev - libdbus-glib-1-dev - ladspa-sdk + - libsdl2-dev env: - CMAKE_FLAGS="-Denable-profiling=1" - CMAKE_FLAGS="-Denable-floats=1 -Denable-profiling=1" @@ -32,41 +34,34 @@ env: matrix: include: - - os: osx - osx_image: xcode10 - - - os: linux - env: + - env: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && sudo apt-get install gcc-7" - - os: linux - env: + - env: - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8 && sudo apt-get install gcc-8" - CMAKE_FLAGS="-Denable-debug=1 -DCMAKE_C_FLAGS_DEBUG=-fuse-ld=gold" - - os: linux - env: - - MATRIX_EVAL="CC=clang-3.8 && CXX=clang++-3.8 && sudo apt-get install clang-3.8" - - - os: linux - env: - - MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0 && sudo apt-get install clang-6.0" - - os: linux env: - MATRIX_EVAL="CC=clang-7 && CXX=clang++-7 && sudo apt-get install clang-7" + - os: linux + env: + - MATRIX_EVAL="CC=clang-8 && CXX=clang++-8 && sudo rm -f /usr/local/clang-7.0.0/bin/clang-tidy && sudo ln -s /usr/bin/clang-tidy-8 /usr/bin/clang-tidy && sudo apt-get install clang-8 clang-tidy-8" + - CMAKE_FLAGS="-Denable-profiling=1 -DCMAKE_C_FLAGS_DEBUG=-fuse-ld=gold" + before_install: - - if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get update; else brew update; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install glib gettext libsndfile jack dbus-glib pulseaudio portaudio; fi # && brew link gettext - eval "${MATRIX_EVAL}" - + - which clang-tidy + - ls -la `which clang-tidy` + - echo $PATH + before_script: - mkdir $HOME/fluidsynth_install/ - mkdir build && cd build - + script: - - cmake -DCMAKE_INSTALL_PREFIX=$HOME/fluidsynth_install ${CMAKE_FLAGS} -Denable-portaudio=1 -Denable-ladspa=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=0 .. + - cmake -DCMAKE_INSTALL_PREFIX=$HOME/fluidsynth_install ${CMAKE_FLAGS} -Denable-portaudio=1 -Denable-ladspa=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. - make -j4 - make check - - if [ $TRAVIS_OS_NAME = linux ]; then make install; fi # install only on linux, as CMAKE_INSTALL_PREFIX is ignored for frameworks on macosx and I cant tell whether that's correct or a bug. + - make install # install only on linux, as CMAKE_INSTALL_PREFIX is ignored for frameworks on macosx and I cant tell whether that's correct or a bug. From 8dae1eebcf2c569626584a46ef2f210b966120ce Mon Sep 17 00:00:00 2001 From: Tom M Date: Wed, 5 Jun 2019 20:04:33 +0300 Subject: [PATCH 02/11] enable readline support if header and lib found --- cmake_admin/FindReadline.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake_admin/FindReadline.cmake b/cmake_admin/FindReadline.cmake index e41a8605..839c797f 100644 --- a/cmake_admin/FindReadline.cmake +++ b/cmake_admin/FindReadline.cmake @@ -10,9 +10,9 @@ endif ( READLINE_INCLUDE_DIR AND READLINE_LIBRARIES ) find_path ( READLINE_INCLUDE_DIR NAMES history.h readline/history.h ) find_library ( READLINE_LIBRARIES NAMES readline ) -if ( READLINE_INCLUDE_DIR ) - set ( HAVE_READLINE TRUE CACHE TYPE BOOL ) -endif ( READLINE_INCLUDE_DIR ) +if ( READLINE_INCLUDE_DIR AND READLINE_LIBRARIES ) + set ( HAVE_READLINE TRUE CACHE BOOL ) +endif ( READLINE_INCLUDE_DIR AND READLINE_LIBRARIES ) include ( FindPackageHandleStandardArgs ) FIND_PACKAGE_HANDLE_STANDARD_ARGS( READLINE DEFAULT_MSG From f70a6321c595e10a6290974a0b6b8a3dc2d82236 Mon Sep 17 00:00:00 2001 From: Tom M Date: Wed, 5 Jun 2019 20:26:47 +0300 Subject: [PATCH 03/11] fix build --- cmake_admin/FindReadline.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_admin/FindReadline.cmake b/cmake_admin/FindReadline.cmake index 839c797f..33e2e871 100644 --- a/cmake_admin/FindReadline.cmake +++ b/cmake_admin/FindReadline.cmake @@ -11,7 +11,7 @@ find_path ( READLINE_INCLUDE_DIR NAMES history.h readline/history.h ) find_library ( READLINE_LIBRARIES NAMES readline ) if ( READLINE_INCLUDE_DIR AND READLINE_LIBRARIES ) - set ( HAVE_READLINE TRUE CACHE BOOL ) + set ( HAVE_READLINE TRUE CACHE BOOL "Found readline header and lib" FORCE ) endif ( READLINE_INCLUDE_DIR AND READLINE_LIBRARIES ) include ( FindPackageHandleStandardArgs ) From df893bbfa4629542ad0fc8cef867013367dc268b Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 15 Aug 2019 15:54:00 +0200 Subject: [PATCH 04/11] Fix use-after-free in fluid_player_stop() Previously, sample timers were deleted in fluid_player_stop() which caused a use-after-free when at the same time the sample timers were advanced by the synthesizer thread. This was incorrectly addressed in 5d3f727547219b6e84b7c421d6f7f21c237d739b . Deleting sample timers is now done in delete_fluid_player(). A broken application could still crash if it does not respect the order of object creation though. At least now, this issue is properly documented. --- src/drivers/fluid_adriver.c | 20 ++++++-- src/midi/fluid_midi.c | 96 +++++++++++++++++-------------------- src/synth/fluid_synth.c | 13 ++--- src/synth/fluid_synth.h | 2 +- 4 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/drivers/fluid_adriver.c b/src/drivers/fluid_adriver.c index 4311c46f..b789ac08 100644 --- a/src/drivers/fluid_adriver.c +++ b/src/drivers/fluid_adriver.c @@ -253,8 +253,14 @@ find_fluid_audio_driver(fluid_settings_t *settings) * @param synth Synthesizer instance for which the audio driver is created for. * @return The new audio driver instance. * - * Creates a new audio driver for a given 'synth' instance with a defined set - * of configuration 'settings'. + * Creates a new audio driver for a given \p synth instance with a defined set + * of configuration \p settings. + * + * @note As soon as an audio driver is created, the \p synth starts rendering audio. + * This means that all necessary sound-setup should be completed after this point, + * thus of all object types in use (synth, midi player, sequencer, etc.) the audio + * driver should always be the last one to be created and the first one to be deleted! + * Also refer to the order of object creation in the code examples. */ fluid_audio_driver_t * new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth) @@ -286,9 +292,15 @@ new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth) * * Like new_fluid_audio_driver() but allows for custom audio processing before * audio is sent to audio driver. It is the responsibility of the callback - * 'func' to render the audio into the buffers. + * \p func to render the audio into the buffers. * - * NOTE: Not as efficient as new_fluid_audio_driver(). + * @note Not as efficient as new_fluid_audio_driver(). + * + * @note As soon as an audio driver is created, the \p synth starts rendering audio. + * This means that all necessary sound-setup should be completed after this point, + * thus of all object types in use (synth, midi player, sequencer, etc.) the audio + * driver should always be the last one to be created and the first one to be deleted! + * Also refer to the order of object creation in the code examples. */ fluid_audio_driver_t * new_fluid_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data) diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index 262a82cb..b6cb2bac 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -48,7 +48,7 @@ static fluid_midi_event_t *fluid_track_next_event(fluid_track_t *track); static int fluid_track_get_duration(fluid_track_t *track); static int fluid_track_reset(fluid_track_t *track); -static int fluid_track_send_events(fluid_track_t *track, +static void fluid_track_send_events(fluid_track_t *track, fluid_synth_t *synth, fluid_player_t *player, unsigned int ticks); @@ -1552,13 +1552,12 @@ fluid_track_reset(fluid_track_t *track) /* * fluid_track_send_events */ -int +void fluid_track_send_events(fluid_track_t *track, fluid_synth_t *synth, fluid_player_t *player, unsigned int ticks) { - int status = FLUID_OK; fluid_midi_event_t *event; int seeking = player->seek_ticks >= 0; @@ -1579,7 +1578,7 @@ fluid_track_send_events(fluid_track_t *track, if(event == NULL) { - return status; + return; } /* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */ @@ -1591,7 +1590,7 @@ fluid_track_send_events(fluid_track_t *track, if(track->ticks + event->dtime > ticks) { - return status; + return; } track->ticks += event->dtime; @@ -1619,8 +1618,6 @@ fluid_track_send_events(fluid_track_t *track, fluid_track_next_event(track); } - - return status; } /****************************************************** @@ -1678,6 +1675,26 @@ new_fluid_player(fluid_synth_t *synth) fluid_player_set_playback_callback(player, fluid_synth_handle_midi_event, synth); player->use_system_timer = fluid_settings_str_equal(synth->settings, "player.timing-source", "system"); + if(player->use_system_timer) + { + player->system_timer = new_fluid_timer((int) player->deltatime, + fluid_player_callback, player, TRUE, FALSE, TRUE); + + if(player->system_timer == NULL) + { + goto err; + } + } + else + { + player->sample_timer = new_fluid_sample_timer(player->synth, + fluid_player_callback, player); + + if(player->sample_timer == NULL) + { + goto err; + } + } fluid_settings_getint(synth->settings, "player.reset-synth", &i); fluid_player_handle_reset_synth(player, NULL, i); @@ -1686,11 +1703,16 @@ new_fluid_player(fluid_synth_t *synth) fluid_player_handle_reset_synth, player); return player; + +err: + delete_fluid_player(player); + return NULL; } /** * Delete a MIDI player instance. * @param player MIDI player instance + * @warning Do not call while the \p synth renders audio, i.e. an audio driver is running or any other synthesizer thread calls fluid_synth_process() or fluid_synth_nwrite_float() or fluid_synth_write_*() ! */ void delete_fluid_player(fluid_player_t *player) @@ -1703,6 +1725,9 @@ delete_fluid_player(fluid_player_t *player) fluid_player_stop(player); fluid_player_reset(player); + delete_fluid_timer(player->system_timer); + delete_fluid_sample_timer(player->synth, player->sample_timer); + while(player->playlist != NULL) { q = player->playlist->next; @@ -2030,6 +2055,11 @@ fluid_player_callback(void *data, unsigned int msec) loadnextfile = player->currentfile == NULL ? 1 : 0; + if(player->status == FLUID_PLAYER_READY) + { + fluid_synth_all_notes_off(synth, -1); + return 1; + } do { if(loadnextfile) @@ -2058,12 +2088,7 @@ fluid_player_callback(void *data, unsigned int msec) if(!fluid_track_eot(player->track[i])) { status = FLUID_PLAYER_PLAYING; - - if(fluid_track_send_events(player->track[i], synth, player, - player->cur_ticks) != FLUID_OK) - { - /* */ - } + fluid_track_send_events(player->track[i], synth, player, player->cur_ticks); } } @@ -2098,42 +2123,21 @@ fluid_player_callback(void *data, unsigned int msec) int fluid_player_play(fluid_player_t *player) { - if(player->status == FLUID_PLAYER_PLAYING) + if(player->status == FLUID_PLAYER_PLAYING || + player->playlist == NULL) { return FLUID_OK; } - if(player->playlist == NULL) + if(!player->use_system_timer) { - return FLUID_OK; + fluid_sample_timer_reset(player->synth, player->sample_timer); } player->status = FLUID_PLAYER_PLAYING; - if(player->use_system_timer) - { - player->system_timer = new_fluid_timer((int) player->deltatime, - fluid_player_callback, (void *) player, TRUE, FALSE, TRUE); - - if(player->system_timer == NULL) - { - return FLUID_FAILED; - } - } - else - { - player->sample_timer = new_fluid_sample_timer(player->synth, - fluid_player_callback, (void *) player); - - if(player->sample_timer == NULL) - { - return FLUID_FAILED; - } - } - return FLUID_OK; } - /** * Stops a MIDI player. * @param player MIDI player instance @@ -2142,19 +2146,7 @@ fluid_player_play(fluid_player_t *player) int fluid_player_stop(fluid_player_t *player) { - if(player->system_timer != NULL) - { - delete_fluid_timer(player->system_timer); - } - - if(player->sample_timer != NULL) - { - delete_fluid_sample_timer(player->synth, player->sample_timer); - } - - player->status = FLUID_PLAYER_DONE; - player->sample_timer = NULL; - player->system_timer = NULL; + player->status = FLUID_PLAYER_READY; return FLUID_OK; } @@ -2254,7 +2246,7 @@ fluid_player_join(fluid_player_t *player) else if(player->sample_timer) { /* Busy-wait loop, since there's no thread to wait for... */ - while(player->status != FLUID_PLAYER_DONE) + while(player->status == FLUID_PLAYER_PLAYING) { fluid_msleep(10); } diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index cf3b4c64..c6225640 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -494,16 +494,13 @@ struct _fluid_sample_timer_t */ static void fluid_sample_timer_process(fluid_synth_t *synth) { - fluid_sample_timer_t *st, *stnext; + fluid_sample_timer_t *st; long msec; int cont; unsigned int ticks = fluid_synth_get_ticks(synth); - for(st = synth->sample_timers; st; st = stnext) + for(st = synth->sample_timers; st; st = st->next) { - /* st may be freed in the callback below. cache it's successor now to avoid use after free */ - stnext = st->next; - if(st->isfinished) { continue; @@ -529,7 +526,7 @@ fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_c return NULL; } - result->starttick = fluid_synth_get_ticks(synth); + fluid_sample_timer_reset(synth, result); result->isfinished = 0; result->data = data; result->callback = callback; @@ -559,6 +556,10 @@ void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer } } +void fluid_sample_timer_reset(fluid_synth_t *synth, fluid_sample_timer_t *timer) +{ + timer->starttick = fluid_synth_get_ticks(synth); +} /*************************************************************** * diff --git a/src/synth/fluid_synth.h b/src/synth/fluid_synth.h index c22e61fb..891c812a 100644 --- a/src/synth/fluid_synth.h +++ b/src/synth/fluid_synth.h @@ -205,7 +205,7 @@ int fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double le fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_callback_t callback, void *data); void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer); - +void fluid_sample_timer_reset(fluid_synth_t *synth, fluid_sample_timer_t *timer); void fluid_synth_process_event_queue(fluid_synth_t *synth); From 81a86e33ab8a8cb110fe5d44c14721ae29f2a432 Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 15 Aug 2019 16:12:55 +0200 Subject: [PATCH 05/11] Correctly restart playback after fluid_player_stop() Fixes #550 --- src/midi/fluid_midi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index b6cb2bac..4eec622b 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -2147,6 +2147,7 @@ int fluid_player_stop(fluid_player_t *player) { player->status = FLUID_PLAYER_READY; + fluid_player_seek(player, fluid_player_get_current_tick(player)); return FLUID_OK; } From 5351d9dcb96c670bea8548250fac4a76ef4ee024 Mon Sep 17 00:00:00 2001 From: Tom M Date: Sat, 17 Aug 2019 14:36:35 +0200 Subject: [PATCH 06/11] Fix various memory leaks in the fluidsynth binary (#555) --- src/fluidsynth.c | 71 ++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/src/fluidsynth.c b/src/fluidsynth.c index 704b33ee..30b050e3 100644 --- a/src/fluidsynth.c +++ b/src/fluidsynth.c @@ -48,7 +48,7 @@ int option_help = 0; /* set to 1 if "-o help" is specified */ /* Process a command line option -o setting=value, for example: -o synth.polyhony=16 */ -void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg) +int process_o_cmd_line_option(fluid_settings_t *settings, char *optarg) { char *val; int hints; @@ -67,13 +67,13 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg) if(FLUID_STRCMP(optarg, "help") == 0) { option_help = 1; - return; + return FLUID_OK; } if(FLUID_STRCMP(optarg, "") == 0) { fprintf(stderr, "Invalid -o option (name part is empty)\n"); - return; + return FLUID_FAILED; } switch(fluid_settings_get_type(settings, optarg)) @@ -82,7 +82,7 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg) if(fluid_settings_setnum(settings, optarg, atof(val)) != FLUID_OK) { fprintf(stderr, "Failed to set floating point parameter '%s'\n", optarg); - exit(1); + return FLUID_FAILED; } break; @@ -110,7 +110,7 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg) if(fluid_settings_setint(settings, optarg, ival) != FLUID_OK) { fprintf(stderr, "Failed to set integer parameter '%s'\n", optarg); - exit(1); + return FLUID_FAILED; } break; @@ -119,15 +119,17 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg) if(fluid_settings_setstr(settings, optarg, val) != FLUID_OK) { fprintf(stderr, "Failed to set string parameter '%s'\n", optarg); - exit(1); + return FLUID_FAILED; } break; default: fprintf(stderr, "Setting parameter '%s' not found\n", optarg); - exit(1); + return FLUID_FAILED; } + + return FLUID_OK; } static void @@ -317,6 +319,7 @@ fast_render_loop(fluid_settings_t *settings, fluid_synth_t *synth, fluid_player_ int main(int argc, char **argv) { fluid_settings_t *settings; + int result = -1; int arg1 = 1; char buf[512]; int c, i; @@ -324,7 +327,6 @@ int main(int argc, char **argv) int midi_in = 1; fluid_player_t *player = NULL; fluid_midi_router_t *router = NULL; - //fluid_sequencer_t* sequencer = NULL; fluid_midi_driver_t *mdriver = NULL; fluid_audio_driver_t *adriver = NULL; fluid_synth_t *synth = NULL; @@ -420,7 +422,7 @@ int main(int argc, char **argv) { printf("Option -%c requires an argument\n", c); print_usage(); - exit(0); + goto cleanup; } else { @@ -430,7 +432,7 @@ int main(int argc, char **argv) { printf("Expected argument to option -%c found switch instead\n", c); print_usage(); - exit(0); + goto cleanup; } } } @@ -462,7 +464,8 @@ int main(int argc, char **argv) { printf("-a options (audio driver):\n "); show_settings_str_options(settings, "audio.driver"); - exit(0); + result = 0; + goto cleanup; } else { @@ -504,7 +507,8 @@ int main(int argc, char **argv) printf("\nNOTE: No libsndfile support!\n" "cpu: Use CPU native byte order\n"); #endif - exit(0); + result = 0; + goto cleanup; } else { @@ -532,6 +536,8 @@ int main(int argc, char **argv) case 'h': print_help(settings); + result = 0; + goto cleanup; break; case 'i': @@ -562,7 +568,8 @@ int main(int argc, char **argv) { printf("-m options (MIDI driver):\n "); show_settings_str_options(settings, "midi.driver"); - exit(0); + result = 0; + goto cleanup; } else { @@ -588,7 +595,8 @@ int main(int argc, char **argv) #else printf("\nNOTE: No libsndfile support!\n"); #endif - exit(0); + result = 0; + goto cleanup; } else { @@ -598,7 +606,10 @@ int main(int argc, char **argv) break; case 'o': - process_o_cmd_line_option(settings, optarg); + if(process_o_cmd_line_option(settings, optarg) != FLUID_OK) + { + goto cleanup; + } break; case 'p' : @@ -640,7 +651,8 @@ int main(int argc, char **argv) #else printf("\nNOTE: No libsndfile support!\n"); #endif - exit(0); + result = 0; + goto cleanup; } else { @@ -651,7 +663,8 @@ int main(int argc, char **argv) case 'V': print_configure(); - exit(0); + result = 0; + goto cleanup; break; case 'v': @@ -666,7 +679,7 @@ int main(int argc, char **argv) case '?': printf("Unknown option %c\n", optopt); print_usage(); - exit(0); + goto cleanup; break; default: @@ -677,7 +690,7 @@ int main(int argc, char **argv) default: printf("Unknown switch '%c'\n", c); print_usage(); - exit(0); + goto cleanup; break; #endif } /* end of switch statement */ @@ -694,7 +707,8 @@ int main(int argc, char **argv) { printf("FluidSynth settings:\n"); fluid_settings_foreach(settings, settings, settings_foreach_func); - exit(0); + result = 0; + goto cleanup; } #ifdef WIN32 @@ -744,7 +758,7 @@ int main(int argc, char **argv) if(synth == NULL) { fprintf(stderr, "Failed to create the synthesizer\n"); - exit(-1); + goto cleanup; } /* load the soundfonts (check that all non options are SoundFont or MIDI files) */ @@ -793,7 +807,6 @@ int main(int argc, char **argv) /* In dump mode, text output is generated for events going into and out of the router. * The example dump functions are put into the chain before and after the router.. */ - //sequencer = new_fluid_sequencer2(0); mdriver = new_fluid_midi_driver( settings, dump ? fluid_midi_dump_prerouter : fluid_midi_router_handle_midi_event, @@ -812,7 +825,6 @@ int main(int argc, char **argv) { if((argv[i][0] != '-') && fluid_is_midifile(argv[i])) { - if(player == NULL) { player = new_fluid_player(synth); @@ -951,6 +963,8 @@ int main(int argc, char **argv) fast_render_loop(settings, synth, player); } + result = 0; + cleanup: #ifdef NETWORK_SUPPORT @@ -1003,10 +1017,6 @@ cleanup: delete_fluid_midi_router(router); } - /*if (sequencer) { - delete_fluid_sequencer(sequencer); - }*/ - if(adriver) { delete_fluid_audio_driver(adriver); @@ -1022,7 +1032,7 @@ cleanup: delete_fluid_settings(settings); } - return 0; + return result; } /* @@ -1033,7 +1043,6 @@ print_usage() { fprintf(stderr, "Usage: fluidsynth [options] [soundfonts]\n"); fprintf(stderr, "Try -h for help.\n"); - exit(0); } void @@ -1141,8 +1150,4 @@ print_help(fluid_settings_t *settings) { FLUID_FREE(midi_options); } - - delete_fluid_settings(settings); - - exit(0); } From 58022a11fac148dc3f37e41229385660d74cc7e9 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 17 Aug 2019 15:07:23 +0200 Subject: [PATCH 07/11] Regression fix for fluid_player_join() df893bbfa4629542ad0fc8cef867013367dc268b caused to wait for the system timer thread to join for ever. --- src/midi/fluid_midi.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index 4eec622b..7544c398 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -2055,7 +2055,7 @@ fluid_player_callback(void *data, unsigned int msec) loadnextfile = player->currentfile == NULL ? 1 : 0; - if(player->status == FLUID_PLAYER_READY) + if(player->status == FLUID_PLAYER_DONE) { fluid_synth_all_notes_off(synth, -1); return 1; @@ -2146,7 +2146,7 @@ fluid_player_play(fluid_player_t *player) int fluid_player_stop(fluid_player_t *player) { - player->status = FLUID_PLAYER_READY; + player->status = FLUID_PLAYER_DONE; fluid_player_seek(player, fluid_player_get_current_tick(player)); return FLUID_OK; } @@ -2233,26 +2233,17 @@ int fluid_player_set_bpm(fluid_player_t *player, int bpm) } /** - * Wait for a MIDI player to terminate (when done playing). + * Wait for a MIDI player until the playback has been stopped. * @param player MIDI player instance - * @return #FLUID_OK on success, #FLUID_FAILED otherwise + * @return Always #FLUID_OK */ int fluid_player_join(fluid_player_t *player) { - if(player->system_timer) + while(player->status != FLUID_PLAYER_DONE) { - return fluid_timer_join(player->system_timer); + fluid_msleep(10); } - else if(player->sample_timer) - { - /* Busy-wait loop, since there's no thread to wait for... */ - while(player->status == FLUID_PLAYER_PLAYING) - { - fluid_msleep(10); - } - } - return FLUID_OK; } From 686556decc954d3469e5062fe55d0fd800fc4fd2 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 17 Aug 2019 15:10:58 +0200 Subject: [PATCH 08/11] Fix documentation of fluid_player_stop() Addresses #550 --- src/midi/fluid_midi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index 7544c398..03aae21e 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -2139,7 +2139,9 @@ fluid_player_play(fluid_player_t *player) return FLUID_OK; } /** - * Stops a MIDI player. + * Stops a MIDI player, i.e. pauses the playback. + * + * It will not rewind to the beginning of the file, use fluid_player_seek() for this purpose. * @param player MIDI player instance * @return Always returns #FLUID_OK */ From 6d8f338d42a3f2b62a580e964290c67bdf20e092 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 17 Aug 2019 16:01:07 +0200 Subject: [PATCH 09/11] Fix order of object creation in fluidsynth binary Fixes a use-after-free when the MIDI player is deleted before the audio driver, because the synthesis thread is still actively making callbacks on the sample timer, which is deleted by the player though. --- src/fluidsynth.c | 84 ++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/src/fluidsynth.c b/src/fluidsynth.c index 30b050e3..cb92d3ba 100644 --- a/src/fluidsynth.c +++ b/src/fluidsynth.c @@ -777,18 +777,6 @@ int main(int argc, char **argv) } } - /* start the synthesis thread */ - if(!fast_render) - { - adriver = new_fluid_audio_driver(settings, synth); - - if(adriver == NULL) - { - fprintf(stderr, "Failed to create the audio driver\n"); - goto cleanup; - } - } - router = new_fluid_midi_router( settings, dump ? fluid_midi_dump_postrouter : fluid_synth_handle_midi_event, @@ -926,21 +914,6 @@ int main(int argc, char **argv) #endif - /* run the shell */ - if(interactive) - { - printf("Type 'help' for help topics.\n\n"); - - /* In dump mode we set the prompt to "". The UI cannot easily - * handle lines, which don't end with CR. Changing the prompt - * cannot be done through a command, because the current shell - * does not handle empty arguments. The ordinary case is dump == - * 0. - */ - fluid_settings_setstr(settings, "shell.prompt", dump ? "" : "> "); - fluid_usershell(settings, cmd_handler); /* this is a synchronous shell */ - } - /* fast rendering audio file, if requested */ if(fast_render) { @@ -962,6 +935,31 @@ int main(int argc, char **argv) fast_render_loop(settings, synth, player); } + else /* start the synthesis thread */ + { + adriver = new_fluid_audio_driver(settings, synth); + + if(adriver == NULL) + { + fprintf(stderr, "Failed to create the audio driver\n"); + goto cleanup; + } + + /* run the shell */ + if(interactive) + { + printf("Type 'help' for help topics.\n\n"); + + /* In dump mode we set the prompt to "". The UI cannot easily + * handle lines, which don't end with CR. Changing the prompt + * cannot be done through a command, because the current shell + * does not handle empty arguments. The ordinary case is dump == + * 0. + */ + fluid_settings_setstr(settings, "shell.prompt", dump ? "" : "> "); + fluid_usershell(settings, cmd_handler); /* this is a synchronous shell */ + } + } result = 0; @@ -1003,34 +1001,14 @@ cleanup: /* if no audio driver and sample timers are used, nothing makes the player advance */ fluid_player_join(player); } - - delete_fluid_player(player); } - if(mdriver) - { - delete_fluid_midi_driver(mdriver); - } - - if(router) - { - delete_fluid_midi_router(router); - } - - if(adriver) - { - delete_fluid_audio_driver(adriver); - } - - if(synth) - { - delete_fluid_synth(synth); - } - - if(settings) - { - delete_fluid_settings(settings); - } + delete_fluid_audio_driver(adriver); + delete_fluid_player(player); + delete_fluid_midi_driver(mdriver); + delete_fluid_midi_router(router); + delete_fluid_synth(synth); + delete_fluid_settings(settings); return result; } From dec5e98f23a9f0fb1e9421be37000d53d0a82e73 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 17 Aug 2019 18:00:29 +0200 Subject: [PATCH 10/11] Bump version to 2.0.6 --- CMakeLists.txt | 4 ++-- doc/Doxyfile | 2 +- doc/fluidsynth-v20-devdoc.txt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bb0cb20..49a2a340 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ set ( PACKAGE "fluidsynth" ) # FluidSynth package version set ( FLUIDSYNTH_VERSION_MAJOR 2 ) set ( FLUIDSYNTH_VERSION_MINOR 0 ) -set ( FLUIDSYNTH_VERSION_MICRO 5 ) +set ( FLUIDSYNTH_VERSION_MICRO 6 ) set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" ) set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" ) @@ -44,7 +44,7 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" ) # This is not exactly the same algorithm as the libtool one, but the results are the same. set ( LIB_VERSION_CURRENT 2 ) set ( LIB_VERSION_AGE 1 ) -set ( LIB_VERSION_REVISION 2 ) +set ( LIB_VERSION_REVISION 3 ) set ( LIB_VERSION_INFO "${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" ) diff --git a/doc/Doxyfile b/doc/Doxyfile index 6e09cb84..a46ee88a 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = libfluidsynth -PROJECT_NUMBER = 2.0.5 +PROJECT_NUMBER = 2.0.6 OUTPUT_DIRECTORY = api CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/doc/fluidsynth-v20-devdoc.txt b/doc/fluidsynth-v20-devdoc.txt index 997739c1..25241367 100644 --- a/doc/fluidsynth-v20-devdoc.txt +++ b/doc/fluidsynth-v20-devdoc.txt @@ -8,8 +8,8 @@ \author David Henningsson \author Tom Moebert \author Copyright © 2003-2019 Peter Hanappe, Conrad Berhörster, Antoine Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert -\version Revision 2.0.5 -\date 2019-04-17 +\version Revision 2.0.6 +\date 2019-08-17 All the source code examples in this document are in the public domain; you can use them as you please. This document is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ . The FluidSynth library is distributed under the GNU Lesser General Public License. A copy of the GNU Lesser General Public License is contained in the FluidSynth package; if not, visit http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. From f78486a50bd785200412ea16434b38edc4a45a6c Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 17 Aug 2019 18:01:01 +0200 Subject: [PATCH 11/11] Update developer docs --- doc/fluidsynth-v20-devdoc.txt | 6 +++++- src/midi/fluid_midi.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/fluidsynth-v20-devdoc.txt b/doc/fluidsynth-v20-devdoc.txt index 25241367..ae8865f6 100644 --- a/doc/fluidsynth-v20-devdoc.txt +++ b/doc/fluidsynth-v20-devdoc.txt @@ -21,6 +21,7 @@ All the source code examples in this document are in the public domain; you can - \ref Disclaimer - \ref Introduction +- \ref NewIn2_0_6 - \ref NewIn2_0_5 - \ref NewIn2_0_3 - \ref NewIn2_0_2 @@ -63,6 +64,10 @@ What is FluidSynth? - FluidSynth is open source, in active development. For more details, take a look at http://www.fluidsynth.org +\section NewIn2_0_6 Whats new in 2.0.6? + +- the MIDI player did not emit any audio when calling fluid_player_play() after fluid_player_stop() + \section NewIn2_0_5 Whats new in 2.0.5? - fluid_synth_process() omitted audio samples when called with arbitrary sample counts that were not a multiple of fluid_synth_get_internal_bufsize() @@ -75,7 +80,6 @@ What is FluidSynth? - fluid_midi_event_get_text() - fluid_midi_event_get_lyrics() - \section NewIn2_0_2 Whats new in 2.0.2? - fluid_synth_error() has been deprecated, use fluid_set_log_function() to interfere log messages diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index 03aae21e..04a4be5a 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -2139,7 +2139,7 @@ fluid_player_play(fluid_player_t *player) return FLUID_OK; } /** - * Stops a MIDI player, i.e. pauses the playback. + * Pauses the MIDI playback. * * It will not rewind to the beginning of the file, use fluid_player_seek() for this purpose. * @param player MIDI player instance