Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package fluidsynth for openSUSE:Factory 
checked in at 2021-01-18 11:26:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fluidsynth (Old)
 and      /work/SRC/openSUSE:Factory/.fluidsynth.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fluidsynth"

Mon Jan 18 11:26:31 2021 rev:55 rq:862915 version:2.1.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/fluidsynth/fluidsynth.changes    2020-10-27 
18:58:23.250718905 +0100
+++ /work/SRC/openSUSE:Factory/.fluidsynth.new.28504/fluidsynth.changes 
2021-01-18 11:26:44.084468690 +0100
@@ -1,0 +2,9 @@
+Sat Jan  9 11:37:13 UTC 2021 - Tom Mbrt <tom.m...@googlemail.com>
+
+- Update to version 2.1.6
+  * SoundFonts may never be unloaded correctly, if
+    * polyphony is ever exceeded, or
+    * voices are still playing while their SoundFont is being unloaded.
+  * fix a heap-based use-after-free
+
+-------------------------------------------------------------------

Old:
----
  fluidsynth-2.1.5.tar.gz

New:
----
  fluidsynth-2.1.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fluidsynth.spec ++++++
--- /var/tmp/diff_new_pack.PJEstT/_old  2021-01-18 11:26:44.720470123 +0100
+++ /var/tmp/diff_new_pack.PJEstT/_new  2021-01-18 11:26:44.724470132 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package fluidsynth
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %define sover   2
 Name:           fluidsynth
-Version:        2.1.5
+Version:        2.1.6
 Release:        0
 Summary:        A Real-Time Software Synthesizer That Uses Soundfont(tm)
 License:        LGPL-2.1-or-later

++++++ fluidsynth-2.1.5.tar.gz -> fluidsynth-2.1.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/.appveyor-vcpkg.yml 
new/fluidsynth-2.1.6/.appveyor-vcpkg.yml
--- old/fluidsynth-2.1.5/.appveyor-vcpkg.yml    2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/.appveyor-vcpkg.yml    2021-01-03 20:55:48.000000000 
+0100
@@ -1,58 +1,81 @@
-image:
-  - Visual Studio 2019
 
-build:
-  parallel: true
-  verbosity: detailed
-
-configuration:
-  - Release
-
-environment:
-  # update the vcpkg cache even if build fails
-  APPVEYOR_SAVE_CACHE_ON_ERROR: true
-
-  matrix:
-      - platform: ARM
-      - platform: x86
-      - platform: x64
-
-cache:
-  - c:\Tools\vcpkg\installed
-
-init:
-  - set TARGET_PLATFORM=
-  - if "%platform%"=="x86" ( set TARGET_PLATFORM=Win32)
-  - if "%platform%"=="x64" ( set TARGET_PLATFORM=x64)
-  - if "%platform%"=="ARM" ( set TARGET_PLATFORM=ARM)
-  - echo %TARGET_PLATFORM%
-  - echo %APPVEYOR_BUILD_WORKER_IMAGE%
-  - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" ( set 
"generator=Visual Studio 16 2019" && set "toolset=v142" )
-  - echo %generator%
-  - echo %toolset%
-  
-install:
-# make sure the latest version of git is installed
-  - choco upgrade git ninja -y
-  - ninja --version
-  - cmake --version
-# manually update vcpkg
-  - cd "C:\Tools\vcpkg"
-  - git pull
-  - .\bootstrap-vcpkg.bat
-  - cd %appveyor_build_folder%
-  - vcpkg install glib:%platform%-windows || type 
C:\Tools\vcpkg\buildtrees\libffi\config-arm-windows-out.log
-
-build_script:
-  - mkdir build
-  - cd build
-  - cmake -Werror=dev -G "%generator%" -A %TARGET_PLATFORM% -T "%toolset%" 
-Denable-pkgconfig=0 
-DCMAKE_TOOLCHAIN_FILE=c:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake 
-DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 ..
-  - cmake --build . --config Release # build libfluidsynth and fluidsynth exec
-  - if not "%platform%"=="ARM" ( cmake --build . --config Release --target 
check ) # build and exec unittests, unless when cross-compiling
-
-after_build:
-  - 7z a fluidsynth-vcpkg-%platform%.zip 
%APPVEYOR_BUILD_FOLDER%\build\src\Release\*
-
-artifacts:
-  - path: build/fluidsynth-vcpkg-%platform%.zip
-    name: FluidSynth
+variables:
+  toolset: 'v142'
+  generator: 'Visual Studio 16 2019'
+  VCPKG_DIR: 'C:\vcpkg'
+
+jobs:
+- job: vcpkg
+  workspace:
+    clean: all
+  strategy:
+    matrix:
+      ARM:
+        platform: 'ARM'
+        cmake_platform: 'ARM'
+        configuration: 'Release'
+      x86:
+        platform: 'x86'
+        cmake_platform: 'Win32'
+        configuration: 'Release'
+      x64:
+        platform: 'x64'
+        cmake_platform: 'x64'
+        configuration: 'Release'
+  pool:
+    vmImage: 'windows-2019'
+  steps:
+    - script: |
+        @ECHO ON
+        echo $(generator)
+        echo $(toolset)
+        choco upgrade ninja -y
+        ninja --version
+        cmake --version
+        REM manually update vcpkg
+        REM cd "$(VCPKG_DIR)" || exit -1
+        REM git pull || exit -1
+        REM .\bootstrap-vcpkg.bat || exit -1
+        REM cd $(Build.SourcesDirectory)
+        where vcpkg.exe
+        vcpkg install --only-downloads glib:$(platform)-windows
+      displayName: 'Prerequisites'
+    - task: Cache@2
+      displayName: "Cache vcpkg's packages"
+      inputs:
+        key: $(VCPKG_DIR)\downloads\glib* | "$(platform)"
+        path: "$(VCPKG_DIR)"
+        cacheHitVar: CACHE_RESTORED
+    - script: |
+        @ECHO ON
+        vcpkg install glib:$(platform)-windows
+      displayName: 'vcpkg build glib'
+      condition: ne(variables.CACHE_RESTORED, 'true')
+    - script: |
+        @ECHO ON
+        mkdir build
+        cd build
+        cmake -Werror=dev -G "$(generator)" -A "$(cmake_platform)" -T 
"$(toolset)" -Denable-pkgconfig=0 
-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake 
-DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) 
-DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1
+        REM build libfluidsynth and fluidsynth exec
+        cmake --build . --config $(configuration) || exit -1
+      displayName: 'Compile fluidsynth'
+    - script: |
+        @ECHO ON
+        REM build and exec unittests, unless when cross-compiling
+        if not "%platform%"=="ARM" ( cmake --build build --config 
$(configuration) --target check )
+      displayName: 'Execute Unittests'
+    - script: |
+        @ECHO ON
+        cd build
+        cmake --build . --config $(configuration) --target install || exit -1
+        REM del $(Build.ArtifactStagingDirectory)\bin\concrt*.dll
+        REM del $(Build.ArtifactStagingDirectory)\bin\vcruntime*.dll
+        REM del $(Build.ArtifactStagingDirectory)\bin\msvcp*.dll
+        REM del $(Build.ArtifactStagingDirectory)\lib\instpatch*.lib
+        REM del 
$(Build.ArtifactStagingDirectory)\lib\pkgconfig\libinstpatch*.pc
+        REM rd $(Build.ArtifactStagingDirectory)\include\libinstpatch-2 /s /q
+      displayName: 'Copy Artifacts'
+    - task: PublishBuildArtifacts@1
+      inputs:
+          pathtoPublish: $(Build.ArtifactStagingDirectory)
+          artifactName: fluidsynth-vcpkg-$(platform)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/.azure-pipelines.yml 
new/fluidsynth-2.1.6/.azure-pipelines.yml
--- old/fluidsynth-2.1.5/.azure-pipelines.yml   2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/.azure-pipelines.yml   2021-01-03 20:55:48.000000000 
+0100
@@ -49,6 +49,7 @@
         mv -f * ..
         cd ..
         rmdir $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform)\
+        DEL /F C:\Strawberry\perl\bin\pkg-config.bat
       displayName: 'Prerequisites'
     - script: |
         @ECHO ON
@@ -122,6 +123,7 @@
         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
+        DEL /F C:\Strawberry\perl\bin\pkg-config.bat
       displayName: 'Prerequisites'
     - script: |
         @ECHO ON
@@ -146,12 +148,14 @@
         gtk-bundle: $(gtk-bundle-x86)
         libsndfile-url: $(libsndfile-url-x86)
         mingw-url: $(mingw-url-x86)
+        artifact-prefix: "fluidsynth-mingw"
       x64:
         CMAKE_FLAGS: 
         platform: x64
         gtk-bundle: $(gtk-bundle-x64)
         libsndfile-url: $(libsndfile-url-x64)
         mingw-url: $(mingw-url-x64)
+        artifact-prefix: "fluidsynth-mingw"
   pool:
     vmImage: 'vs2017-win2016'
   steps:
@@ -180,6 +184,7 @@
         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
+        DEL /F C:\Strawberry\perl\bin\pkg-config.bat
       displayName: 'Prerequisites'
     - script: |
         @ECHO ON
@@ -189,8 +194,8 @@
         set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
         pkg-config --list-all
         mkdir build && cd build || exit -1
-        cmake -Werror=dev -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
+        cmake -Werror=dev -G "MinGW Makefiles" 
-DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) $(CMAKE_FLAGS) 
-Denable-readline=0 -Denable-floats=1 -DCMAKE_BUILD_TYPE=Release 
-DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1
+        mingw32-make.exe -j4 all || exit -1
       displayName: 'Compile fluidsynth'
     - script: |
         @ECHO ON
@@ -199,5 +204,22 @@
         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
+        mingw32-make.exe -j4 check || exit -1
       displayName: 'Execute Unittests'
+      continueOnError: 'true'
+    - script: |
+        @ECHO ON
+        cd build
+        mingw32-make.exe install || exit -1
+        REM xcopy test $(Build.ArtifactStagingDirectory)\bin /s
+        del $(Build.ArtifactStagingDirectory)\bin\concrt*.dll
+        del $(Build.ArtifactStagingDirectory)\bin\vcruntime*.dll
+        del $(Build.ArtifactStagingDirectory)\bin\msvcp*.dll
+        del $(Build.ArtifactStagingDirectory)\lib\instpatch*.lib
+        del $(Build.ArtifactStagingDirectory)\lib\pkgconfig\libinstpatch*.pc
+        rd $(Build.ArtifactStagingDirectory)\include\libinstpatch-2 /s /q
+      displayName: 'Copy Artifacts'
+    - task: PublishBuildArtifacts@1
+      inputs:
+          pathtoPublish: $(Build.ArtifactStagingDirectory)
+          artifactName: $(artifact-prefix)-$(platform)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/.travis.yml 
new/fluidsynth-2.1.6/.travis.yml
--- old/fluidsynth-2.1.5/.travis.yml    2020-09-11 22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/.travis.yml    2021-01-03 20:55:48.000000000 +0100
@@ -1,15 +1,18 @@
 language: c
 sudo: false
 os: linux
-dist: bionic
+dist: focal
+git:
+  depth: false # disable shallow fetch, history is needed by SonarQube
 addons:
   apt:
     update: true
     sources:
     - ubuntu-toolchain-r-test
-    - llvm-toolchain-bionic-7
-    - llvm-toolchain-bionic-8
-    - llvm-toolchain-bionic-9
+    - llvm-toolchain-focal-7
+    - llvm-toolchain-focal-8
+    - llvm-toolchain-focal-9
+    - llvm-toolchain-focal-10
     packages:
     - cmake-data
     - cmake
@@ -36,33 +39,61 @@
 
 matrix:
   include:
+    - addons:
+        sonarcloud:
+          organization: "fluidsynth"
+      env:
+        - BW="build-wrapper-linux-x86-64 --out-dir bw-output"
+        - SONARSC="sonar-scanner 
-Dsonar.cfamily.build-wrapper-output=build/bw-output"
+
     - arch: arm64
       env:
-        - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && sudo apt-get install gcc-7"
+        - CC="gcc-7"
+        - CXX="g++-7"
+        - MATRIX_EVAL="sudo apt-get install gcc-7 g++-7"
+
+    - dist: trusty
+      env:
+        - CMAKE_FLAGS=""
 
     - env:
-        - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8 && sudo apt-get install gcc-8"
+        - CC="gcc-8"
+        - CXX="g++-8"
+        - MATRIX_EVAL="sudo apt-get install gcc-8 g++-8"
         - CMAKE_FLAGS="-Denable-debug=1 -DCMAKE_C_FLAGS_DEBUG=-fuse-ld=gold"
 
     - env:
-        - MATRIX_EVAL="CC=clang-7 && CXX=clang++-7 && sudo apt-get install 
clang-7"
+        - CC="clang-7"
+        - CXX="clang++-7"
+        - MATRIX_EVAL="sudo apt-get install clang-7"
 
     - 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"
+        - CC="clang-8"
+        - CXX="clang++-8"
+        - MATRIX_EVAL="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"
 
     - env:
-        - MATRIX_EVAL="CC=clang-9 && CXX=clang++-9 && sudo apt-get install 
clang-9"
+        - CC="clang-9"
+        - CXX="clang++-9"
+        - MATRIX_EVAL="sudo apt-get install clang-9"
+
+    - env:
+        - CC="clang-10"
+        - CXX="clang++-10"
+        - MATRIX_EVAL="sudo apt-get install clang-10"
 
     - os: linux-ppc64le
       env:
         - CMAKE_FLAGS=""
 
 before_install:
-    - eval "${MATRIX_EVAL}"
     - which clang-tidy || true
     - ls -la `which clang-tidy` || true
     - echo $PATH
+    - echo $MATRIX_EVAL
+    - eval "${MATRIX_EVAL}"
+    - echo $SONARSC
 
 before_script:
     - mkdir $HOME/fluidsynth_install/
@@ -70,6 +101,9 @@
 
 script:
     - cmake -Werror=dev -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
+    - ${BW} make -j4
+    - ls -la
     - make check
-    - 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.
+    - make install
+    - cd ..
+    - ${SONARSC}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/CMakeLists.txt 
new/fluidsynth-2.1.6/CMakeLists.txt
--- old/fluidsynth-2.1.5/CMakeLists.txt 2020-09-11 22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/CMakeLists.txt 2021-01-03 20:55:48.000000000 +0100
@@ -29,7 +29,7 @@
 # FluidSynth package version
 set ( FLUIDSYNTH_VERSION_MAJOR 2 )
 set ( FLUIDSYNTH_VERSION_MINOR 1 )
-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 @@
 # 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 3 )
-set ( LIB_VERSION_REVISION 5 )
+set ( LIB_VERSION_REVISION 6 )
 set ( LIB_VERSION_INFO
       "${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/doc/Doxyfile 
new/fluidsynth-2.1.6/doc/Doxyfile
--- old/fluidsynth-2.1.5/doc/Doxyfile   2020-09-11 22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/doc/Doxyfile   2021-01-03 20:55:48.000000000 +0100
@@ -5,7 +5,7 @@
 #---------------------------------------------------------------------------
 DOXYFILE_ENCODING = UTF-8
 PROJECT_NAME = libfluidsynth
-PROJECT_NUMBER = 2.1.5
+PROJECT_NUMBER = 2.1.6
 OUTPUT_DIRECTORY = api
 CREATE_SUBDIRS = NO
 OUTPUT_LANGUAGE = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/doc/fluidsynth-v20-devdoc.txt 
new/fluidsynth-2.1.6/doc/fluidsynth-v20-devdoc.txt
--- old/fluidsynth-2.1.5/doc/fluidsynth-v20-devdoc.txt  2020-09-11 
22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/doc/fluidsynth-v20-devdoc.txt  2021-01-03 
20:55:48.000000000 +0100
@@ -7,9 +7,9 @@
 \author Josh Green
 \author David Henningsson
 \author Tom Moebert
-\author Copyright &copy; 2003-2020 Peter Hanappe, Conrad Berh??rster, Antoine 
Schmitt, Pedro L??pez-Cabanillas, Josh Green, David Henningsson, Tom Moebert
-\version Revision 2.1.5
-\date 2020-09-06
+\author Copyright &copy; 2003-2021 Peter Hanappe, Conrad Berh??rster, Antoine 
Schmitt, Pedro L??pez-Cabanillas, Josh Green, David Henningsson, Tom Moebert
+\version Revision 2.1.6
+\date 2021-01-02
 
 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.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/doc/fluidsynth.1 
new/fluidsynth-2.1.6/doc/fluidsynth.1
--- old/fluidsynth-2.1.5/doc/fluidsynth.1       2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/doc/fluidsynth.1       2021-01-03 20:55:48.000000000 
+0100
@@ -13,7 +13,7 @@
 .\" along with this program; see the file LICENSE.  If not, write to
 .\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 .\"
-.TH FluidSynth 1 "Feb 16, 2020"
+.TH FluidSynth 1 "Jan 1, 2021"
 .\" Please update the above date whenever this man page is modified.
 .\"
 .\" Some roff macros, for reference:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/sonar-project.properties 
new/fluidsynth-2.1.6/sonar-project.properties
--- old/fluidsynth-2.1.5/sonar-project.properties       1970-01-01 
01:00:00.000000000 +0100
+++ new/fluidsynth-2.1.6/sonar-project.properties       2021-01-03 
20:55:48.000000000 +0100
@@ -0,0 +1,16 @@
+sonar.projectKey=FluidSynth_fluidsynth
+sonar.organization=fluidsynth
+
+sonar.cfamily.threads=4
+sonar.cfamily.cache.enabled=false
+
+
+# This is the name and version displayed in the SonarCloud UI.
+#sonar.projectName=fluidsynth
+#sonar.projectVersion=1.0
+
+# Path is relative to the sonar-project.properties file. Replace "\" by "/" on 
Windows.
+#sonar.sources=.
+
+# Encoding of the source code. Default is default system encoding
+#sonar.sourceEncoding=UTF-8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/fluidsynth.c 
new/fluidsynth-2.1.6/src/fluidsynth.c
--- old/fluidsynth-2.1.5/src/fluidsynth.c       2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/src/fluidsynth.c       2021-01-03 20:55:48.000000000 
+0100
@@ -1113,7 +1113,7 @@
 print_welcome()
 {
     printf("FluidSynth runtime version %s\n"
-           "Copyright (C) 2000-2020 Peter Hanappe and others.\n"
+           "Copyright (C) 2000-2021 Peter Hanappe and others.\n"
            "Distributed under the LGPL license.\n"
            "SoundFont(R) is a registered trademark of E-mu Systems, Inc.\n\n",
            fluid_version_str());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/midi/fluid_midi.c 
new/fluidsynth-2.1.6/src/midi/fluid_midi.c
--- old/fluidsynth-2.1.5/src/midi/fluid_midi.c  2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/src/midi/fluid_midi.c  2021-01-03 20:55:48.000000000 
+0100
@@ -1717,6 +1717,9 @@
 
     fluid_return_if_fail(player != NULL);
 
+    fluid_settings_callback_int(player->synth->settings, "player.reset-synth",
+                                NULL, NULL);
+
     fluid_player_stop(player);
     fluid_player_reset(player);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/synth/fluid_synth.c 
new/fluidsynth-2.1.6/src/synth/fluid_synth.c
--- old/fluidsynth-2.1.5/src/synth/fluid_synth.c        2020-09-11 
22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/src/synth/fluid_synth.c        2021-01-03 
20:55:48.000000000 +0100
@@ -597,10 +597,15 @@
  * @param settings Configuration parameters to use (used directly).
  * @return New FluidSynth instance or NULL on error
  *
- * @note The @p settings parameter is used directly and should freed after
- * the synth has been deleted. Further note that you may modify FluidSettings 
of the
+ * @note The @p settings parameter is used directly, but the synth does not 
take ownership of it.
+ * Hence, the caller is responsible for freeing it, when no longer needed.
+ * Further note that you may modify FluidSettings of the
  * @p settings instance. However, only those FluidSettings marked as 
'realtime' will
  * affect the synth immediately.
+ *
+ * @warning The @p settings object should only be used by a single synth at a 
time. I.e. creating
+ * multiple synth instances with a single @p settings object causes undefined 
behavior. Once the
+ * "single synth" has been deleted, you may use the @p settings object again 
for another synth.
  */
 fluid_synth_t *
 new_fluid_synth(fluid_settings_t *settings)
@@ -1006,6 +1011,50 @@
 
     fluid_profiling_print();
 
+    /* unregister all real-time settings callback, to avoid a use-after-free 
when changing those settings after
+     * this synth has been deleted*/
+
+    fluid_settings_callback_num(synth->settings, "synth.gain",
+                                NULL, NULL);
+    fluid_settings_callback_int(synth->settings, "synth.polyphony",
+                                NULL, NULL);
+    fluid_settings_callback_int(synth->settings, "synth.device-id",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.overflow.percussion",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.overflow.sustained",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.overflow.released",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.overflow.age",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.overflow.volume",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.overflow.important",
+                                NULL, NULL);
+    fluid_settings_callback_str(synth->settings, 
"synth.overflow.important-channels",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.reverb.room-size",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.reverb.damp",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.reverb.width",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.reverb.level",
+                                NULL, NULL);
+    fluid_settings_callback_int(synth->settings, "synth.reverb.active",
+                                NULL, NULL);
+    fluid_settings_callback_int(synth->settings, "synth.chorus.active",
+                                NULL, NULL);
+    fluid_settings_callback_int(synth->settings, "synth.chorus.nr",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.chorus.level",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.chorus.depth",
+                                NULL, NULL);
+    fluid_settings_callback_num(synth->settings, "synth.chorus.speed",
+                                NULL, NULL);
+
     /* turn off all voices, needed to unload SoundFont data */
     if(synth->voice != NULL)
     {
@@ -1018,6 +1067,12 @@
                 continue;
             }
 
+            /* WARNING: A this point we must ensure that the reference counter
+               of any soundfont sample owned by any rvoice belonging to the 
voice
+               are correctly decremented. This is the contrary part to
+               to fluid_voice_init() where the sample's reference counter is
+               incremented.
+            */
             fluid_voice_unlock_rvoice(voice);
             fluid_voice_overflow_rvoice_finished(voice);
 
@@ -1070,6 +1125,18 @@
 
     delete_fluid_list(synth->loaders);
 
+    /* wait for and delete all the lazy sfont unloading timers */
+
+    for(list = synth->fonts_to_be_unloaded; list; list = fluid_list_next(list))
+    {
+        fluid_timer_t* timer = fluid_list_get(list);
+        // explicitly join to wait for the unload really to happen
+        fluid_timer_join(timer);
+        // delete_fluid_timer alone would stop the timer, even if it had not 
unloaded the soundfont yet
+        delete_fluid_timer(timer);
+    }
+
+    delete_fluid_list(synth->fonts_to_be_unloaded);
 
     if(synth->channel != NULL)
     {
@@ -4228,7 +4295,21 @@
             }
             else if(synth->voice[j]->overflow_rvoice == fv)
             {
+                /* Unlock the overflow_rvoice of the voice.
+                   Decrement the reference count of the sample owned by this
+                   rvoice.
+                */
                 fluid_voice_overflow_rvoice_finished(synth->voice[j]);
+
+                /* Decrement synth active voice count. Must not be incorporated
+                   in fluid_voice_overflow_rvoice_finished() because
+                   fluid_voice_overflow_rvoice_finished() is called also
+                   at synth destruction and in this case the variable should be
+                   accessed via voice->channel->synth->active_voice_count.
+                   And for certain voices which are not playing, the field
+                   voice->channel is NULL.
+                */
+                synth->active_voice_count--;
                 break;
             }
         }
@@ -4732,11 +4813,25 @@
 }
 
 /**
- * Unload a SoundFont.
+ * Schedule a SoundFont for unloading.
+ *
+ * If the SoundFont isn't used anymore by any playing voices, it will be 
unloaded immediately.
+ *
+ * If any samples of the given SoundFont are still required by active voices,
+ * the SoundFont will be unloaded in a lazy manner, once those voices have 
finished synthesizing.
+ * If you call delete_fluid_synth(), all voices will be destroyed and the 
SoundFont
+ * will be unloaded in any case.
+ * Once this function returned, fluid_synth_sfcount() and similar functions 
will behave as if
+ * the SoundFont has already been unloaded, even though the lazy-unloading is 
still pending.
+ *
+ * @note This lazy-unloading mechanism was broken between FluidSynth 1.1.4 and 
2.1.5 . As a
+ * consequence, SoundFonts scheduled for lazy-unloading may be never freed 
under certain
+ * conditions. Calling delete_fluid_synth() does not recover this situation 
either.
+ *
  * @param synth FluidSynth instance
  * @param id ID of SoundFont to unload
  * @param reset_presets TRUE to re-assign presets for all MIDI channels
- * @return #FLUID_OK on success, #FLUID_FAILED on error
+ * @return #FLUID_OK if the given @p id was found, #FLUID_FAILED otherwise.
  */
 int
 fluid_synth_sfunload(fluid_synth_t *synth, int id, int reset_presets)
@@ -4797,7 +4892,8 @@
         } /* spin off a timer thread to unload the sfont later (SoundFont 
loader blocked unload) */
         else
         {
-            new_fluid_timer(100, fluid_synth_sfunload_callback, sfont, TRUE, 
TRUE, FALSE);
+            fluid_timer_t* timer = new_fluid_timer(100, 
fluid_synth_sfunload_callback, sfont, TRUE, FALSE, FALSE);
+            synth->fonts_to_be_unloaded = 
fluid_list_prepend(synth->fonts_to_be_unloaded, timer);
         }
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/synth/fluid_synth.h 
new/fluidsynth-2.1.6/src/synth/fluid_synth.h
--- old/fluidsynth-2.1.5/src/synth/fluid_synth.h        2020-09-11 
22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/src/synth/fluid_synth.h        2021-01-03 
20:55:48.000000000 +0100
@@ -127,6 +127,7 @@
     fluid_list_t *loaders;             /**< the SoundFont loaders */
     fluid_list_t *sfont;          /**< List of fluid_sfont_info_t for each 
loaded SoundFont (remains until SoundFont is unloaded) */
     int sfont_id;             /**< Incrementing ID assigned to each loaded 
SoundFont */
+    fluid_list_t *fonts_to_be_unloaded; /**< list of timers that try to unload 
a soundfont */
 
     float gain;                        /**< master gain */
     fluid_channel_t **channel;         /**< the channels */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/synth/fluid_voice.c 
new/fluidsynth-2.1.6/src/synth/fluid_voice.c
--- old/fluidsynth-2.1.5/src/synth/fluid_voice.c        2020-09-11 
22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/src/synth/fluid_voice.c        2021-01-03 
20:55:48.000000000 +0100
@@ -174,6 +174,7 @@
     voice->can_access_rvoice = voice->can_access_overflow_rvoice;
     voice->overflow_rvoice = rtemp;
     voice->can_access_overflow_rvoice = ctemp;
+    voice->overflow_sample = voice->sample;
 }
 
 static void fluid_voice_initialize_rvoice(fluid_voice_t *voice, fluid_real_t 
output_rate)
@@ -242,6 +243,7 @@
     voice->eventhandler = handler;
     voice->channel = NULL;
     voice->sample = NULL;
+    voice->overflow_sample = NULL;
     voice->output_rate = output_rate;
 
     /* Initialize both the rvoice and overflow_rvoice */
@@ -321,12 +323,13 @@
     voice->has_noteoff = 0;
     UPDATE_RVOICE0(fluid_rvoice_reset);
 
-    /* Increment the reference count of the sample to prevent the
-       unloading of the soundfont while this voice is playing,
-       once for us and once for the rvoice. */
+    /*
+       We increment the reference count of the sample to indicate that this
+       sample is about to be owned by the rvoice. This will prevent the
+       unloading of the soundfont while this rvoice is playing.
+    */
     fluid_sample_incr_ref(sample);
     fluid_rvoice_eventhandler_push_ptr(voice->eventhandler, 
fluid_rvoice_set_sample, voice->rvoice, sample);
-    fluid_sample_incr_ref(sample);
     voice->sample = sample;
 
     i = fluid_channel_get_interp_method(channel);
@@ -1406,12 +1409,20 @@
 }
 
 /*
- * Called by fluid_synth when the overflow rvoice can be reclaimed.
+ * Unlock the overflow rvoice of the voice.
+ * Decrement the reference count of the sample owned by this rvoice.
+ *
+ * Called by fluid_synth when the overflow rvoice has finished by itself.
+ * Must be called also explicitly at synth destruction to ensure that
+ * the soundfont be unloaded successfully.
  */
 void fluid_voice_overflow_rvoice_finished(fluid_voice_t *voice)
 {
     voice->can_access_overflow_rvoice = 1;
-    fluid_voice_sample_unref(&voice->overflow_rvoice->dsp.sample);
+
+    /* Decrement the reference count of the sample to indicate
+       that this sample isn't owned by the rvoice anymore */
+    fluid_voice_sample_unref(&voice->overflow_sample);
 }
 
 /*
@@ -1439,17 +1450,14 @@
 
     voice->chan = NO_CHANNEL;
 
-    if(voice->can_access_rvoice)
-    {
-        fluid_voice_sample_unref(&voice->rvoice->dsp.sample);
-    }
+    /* Decrement the reference count of the sample, to indicate
+       that this sample isn't owned by the rvoice anymore.
+    */
+    fluid_voice_sample_unref(&voice->sample);
 
     voice->status = FLUID_VOICE_OFF;
     voice->has_noteoff = 1;
 
-    /* Decrement the reference count of the sample. */
-    fluid_voice_sample_unref(&voice->sample);
-
     /* Decrement voice count */
     voice->channel->synth->active_voice_count--;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/synth/fluid_voice.h 
new/fluidsynth-2.1.6/src/synth/fluid_voice.h
--- old/fluidsynth-2.1.5/src/synth/fluid_voice.h        2020-09-11 
22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/src/synth/fluid_voice.h        2021-01-03 
20:55:48.000000000 +0100
@@ -71,7 +71,8 @@
     fluid_channel_t *channel;
     fluid_rvoice_eventhandler_t *eventhandler;
     fluid_zone_range_t *zone_range;  /* instrument zone range*/
-    fluid_sample_t *sample;         /* Pointer to sample (dupe in rvoice) */
+    fluid_sample_t *sample;          /* Pointer to sample (dupe in rvoice) */
+    fluid_sample_t *overflow_sample; /* Pointer to sample (dupe in 
overflow_rvoice) */
 
     unsigned int start_time;
     int mod_count;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/utils/fluid_settings.c 
new/fluidsynth-2.1.6/src/utils/fluid_settings.c
--- old/fluidsynth-2.1.5/src/utils/fluid_settings.c     2020-09-11 
22:22:35.000000000 +0200
+++ new/fluidsynth-2.1.6/src/utils/fluid_settings.c     2021-01-03 
20:55:48.000000000 +0100
@@ -907,6 +907,10 @@
  * @param settings a settings object
  * @param name a setting's name
  * @return TRUE if the setting is changeable in real-time, FALSE otherwise
+ *
+ * @note Before using this function, make sure the @p settings object has 
already been used to create
+ * a synthesizer, a MIDI driver, an audio driver, a MIDI player, or a command 
handler (depending on
+ * which settings you want to query).
  */
 int
 fluid_settings_is_realtime(fluid_settings_t *settings, const char *name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/utils/fluid_sys.c 
new/fluidsynth-2.1.6/src/utils/fluid_sys.c
--- old/fluidsynth-2.1.5/src/utils/fluid_sys.c  2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/src/utils/fluid_sys.c  2021-01-03 20:55:48.000000000 
+0100
@@ -60,6 +60,10 @@
 struct _fluid_timer_t
 {
     long msec;
+
+    // Pointer to a function to be executed by the timer.
+    // This field is set to NULL once the timer is finished to indicate 
completion.
+    // This allows for timed waits, rather than waiting forever as 
fluid_timer_join() does.
     fluid_timer_callback_t callback;
     void *data;
     fluid_thread_t *thread;
@@ -1096,6 +1100,7 @@
     }
 
     FLUID_LOG(FLUID_DBG, "Timer thread finished");
+    timer->callback = NULL;
 
     if(timer->auto_destroy)
     {
@@ -1189,6 +1194,19 @@
     return FLUID_OK;
 }
 
+int
+fluid_timer_is_running(const fluid_timer_t *timer)
+{
+    // for unit test usage only
+    return timer->callback != NULL;
+}
+
+long fluid_timer_get_interval(const fluid_timer_t * timer)
+{
+    // for unit test usage only
+    return timer->msec;
+}
+
 
 /***************************************************************
  *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/src/utils/fluid_sys.h 
new/fluidsynth-2.1.6/src/utils/fluid_sys.h
--- old/fluidsynth-2.1.5/src/utils/fluid_sys.h  2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/src/utils/fluid_sys.h  2021-01-03 20:55:48.000000000 
+0100
@@ -232,6 +232,8 @@
 void delete_fluid_timer(fluid_timer_t *timer);
 int fluid_timer_join(fluid_timer_t *timer);
 int fluid_timer_stop(fluid_timer_t *timer);
+int fluid_timer_is_running(const fluid_timer_t *timer);
+long fluid_timer_get_interval(const fluid_timer_t * timer);
 
 // Macros to use for pre-processor if statements to test which Glib thread API 
we have (pre or post 2.32)
 #define NEW_GLIB_THREAD_API   GLIB_CHECK_VERSION(2,32,0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/test/CMakeLists.txt 
new/fluidsynth-2.1.6/test/CMakeLists.txt
--- old/fluidsynth-2.1.5/test/CMakeLists.txt    2020-09-11 22:22:35.000000000 
+0200
+++ new/fluidsynth-2.1.6/test/CMakeLists.txt    2021-01-03 20:55:48.000000000 
+0100
@@ -12,6 +12,7 @@
 ADD_FLUID_TEST(test_sample_rate_change)
 ADD_FLUID_TEST(test_preset_sample_loading)
 ADD_FLUID_TEST(test_bug_635)
+ADD_FLUID_TEST(test_settings_unregister_callback)
 ADD_FLUID_TEST(test_pointer_alignment)
 ADD_FLUID_TEST(test_seqbind_unregister)
 ADD_FLUID_TEST(test_synth_chorus_reverb)
@@ -19,9 +20,10 @@
 ADD_FLUID_TEST(test_synth_process)
 ADD_FLUID_TEST(test_ct2hz)
 ADD_FLUID_TEST(test_sample_validate)
-ADD_FLUID_TEST(test_seq_event_queue_sort)
-ADD_FLUID_TEST(test_seq_scale)
 ADD_FLUID_TEST(test_jack_obtaining_synth)
+ADD_FLUID_TEST(test_sfont_unloading)
+ADD_FLUID_TEST(test_seq_scale)
+ADD_FLUID_TEST(test_seq_event_queue_sort)
 
 # if ( LIBSNDFILE_HASVORBIS )
 #     ADD_FLUID_TEST(test_sf3_sfont_loading)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/fluidsynth-2.1.5/test/test_settings_unregister_callback.c 
new/fluidsynth-2.1.6/test/test_settings_unregister_callback.c
--- old/fluidsynth-2.1.5/test/test_settings_unregister_callback.c       
1970-01-01 01:00:00.000000000 +0100
+++ new/fluidsynth-2.1.6/test/test_settings_unregister_callback.c       
2021-01-03 20:55:48.000000000 +0100
@@ -0,0 +1,95 @@
+
+#include "test.h"
+#include "fluidsynth.h"
+#include "fluidsynth_priv.h"
+#include "fluid_synth.h"
+#include <string.h>
+
+static fluid_list_t* realtime_int_settings = NULL;
+static fluid_list_t* realtime_str_settings = NULL;
+static fluid_list_t* realtime_num_settings = NULL;
+
+void iter_func (void *data, const char *name, int type)
+{
+    if(fluid_settings_is_realtime(data, name))
+    {
+        switch(type)
+        {
+            case FLUID_INT_TYPE:
+                realtime_int_settings = 
fluid_list_prepend(realtime_int_settings, FLUID_STRDUP(name));
+                break;
+            case FLUID_STR_TYPE:
+                realtime_str_settings = 
fluid_list_prepend(realtime_str_settings, FLUID_STRDUP(name));
+                break;
+            case FLUID_NUM_TYPE:
+                realtime_num_settings = 
fluid_list_prepend(realtime_num_settings, FLUID_STRDUP(name));
+                break;
+            case FLUID_SET_TYPE:
+                break;
+            default:
+                TEST_ASSERT(FALSE);
+        }
+    }
+}
+
+// this test should make sure that sample rate changed are handled correctly
+int main(void)
+{
+    fluid_list_t* list;
+    fluid_player_t* player;
+    fluid_synth_t *synth;
+    fluid_settings_t *settings = new_fluid_settings();
+    TEST_ASSERT(settings != NULL);
+
+    synth = new_fluid_synth(settings);
+    TEST_ASSERT(synth != NULL);
+
+    player = new_fluid_player(synth);
+    TEST_ASSERT(player != NULL);
+    
+    // see which of the objects above has registered a realtime setting
+    fluid_settings_foreach(settings, settings, iter_func);
+    
+    // delete the objects
+    delete_fluid_player(player);
+    delete_fluid_synth(synth);
+    
+    // and now, start making changes to those realtime settings
+    // Anything below fluidsynth 2.1.5 will crash
+    
+    for(list = realtime_int_settings; list; list = fluid_list_next(list))
+    {
+        int min, max;
+        char* name = fluid_list_get(list);
+        TEST_SUCCESS(fluid_settings_getint_range(settings, name, &min, &max));
+        TEST_SUCCESS(fluid_settings_setint(settings, name, min));
+        FLUID_FREE(name);
+    }
+
+    delete_fluid_list(realtime_int_settings);
+    
+    for(list = realtime_num_settings; list; list = fluid_list_next(list))
+    {
+        double min, max;
+        char* name = fluid_list_get(list);
+        TEST_SUCCESS(fluid_settings_getnum_range(settings, name, &min, &max));
+        TEST_SUCCESS(fluid_settings_setnum(settings, name, min));
+        FLUID_FREE(name);
+    }
+
+    delete_fluid_list(realtime_num_settings);
+    
+    
+    for(list = realtime_str_settings; list; list = fluid_list_next(list))
+    {
+        char* name = fluid_list_get(list);
+        TEST_SUCCESS(fluid_settings_setstr(settings, name, "ABCDEFG"));
+        FLUID_FREE(name);
+    }
+
+    delete_fluid_list(realtime_str_settings);
+
+    delete_fluid_settings(settings);
+
+    return EXIT_SUCCESS;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fluidsynth-2.1.5/test/test_sfont_unloading.c 
new/fluidsynth-2.1.6/test/test_sfont_unloading.c
--- old/fluidsynth-2.1.5/test/test_sfont_unloading.c    1970-01-01 
01:00:00.000000000 +0100
+++ new/fluidsynth-2.1.6/test/test_sfont_unloading.c    2021-01-03 
20:55:48.000000000 +0100
@@ -0,0 +1,229 @@
+
+#include "test.h"
+#include "fluidsynth.h"
+#include "synth/fluid_synth.h"
+#include "utils/fluid_sys.h"
+
+void wait_and_free(fluid_synth_t* synth, int id, const char* calling_func)
+{
+    fluid_list_t *list, *list_orig;
+    list_orig = list = synth->fonts_to_be_unloaded;
+    synth->fonts_to_be_unloaded = NULL;
+    delete_fluid_synth(synth);
+    
+    for(; list; list = fluid_list_next(list))
+    {
+        fluid_timer_t* timer = fluid_list_get(list);
+        FLUID_LOG(FLUID_INFO, "%s(): Start waiting for soundfont %d to 
unload", calling_func, id);
+        if(fluid_timer_is_running(timer))
+        {
+            /* timer still running, wait a bit*/
+            fluid_msleep(50 * fluid_timer_get_interval(timer));
+            TEST_ASSERT(!fluid_timer_is_running(timer));
+        }
+        delete_fluid_timer(timer);
+        FLUID_LOG(FLUID_INFO, "%s(): End waiting for soundfont %d to unload", 
calling_func, id);
+    }
+    delete_fluid_list(list_orig);
+}
+
+static void test_without_rendering(fluid_settings_t* settings)
+{
+    int id;
+    fluid_synth_t *synth = new_fluid_synth(settings);
+    TEST_ASSERT(synth != NULL);
+
+    TEST_ASSERT(fluid_is_soundfont(TEST_SOUNDFONT) == TRUE);
+
+    // load a sfont to synth
+    TEST_SUCCESS(id = fluid_synth_sfload(synth, TEST_SOUNDFONT, 1));
+    // one sfont loaded
+    TEST_ASSERT(fluid_synth_sfcount(synth) == 1);
+    
+    TEST_SUCCESS(fluid_synth_noteon(synth, 0, 60, 127));
+    
+    TEST_SUCCESS(fluid_synth_sfunload(synth, id, 1));
+    
+    TEST_SUCCESS(fluid_synth_noteoff(synth, 0, 60));
+    
+    // there must be one font scheduled for lazy unloading
+    TEST_ASSERT(synth->fonts_to_be_unloaded != NULL);
+    
+    wait_and_free(synth, id, __func__);
+}
+
+// this should work fine after applying JJCs fix 
a4ac56502fec5f0c20a60187d965c94ba1dc81c2
+static void test_after_polyphony_exceeded(fluid_settings_t* settings)
+{
+    int id;
+    fluid_synth_t *synth = new_fluid_synth(settings);
+    TEST_ASSERT(synth != NULL);
+
+    TEST_ASSERT(fluid_is_soundfont(TEST_SOUNDFONT) == TRUE);
+
+    // load a sfont to synth
+    TEST_SUCCESS(id = fluid_synth_sfload(synth, TEST_SOUNDFONT, 1));
+    // one sfont loaded
+    TEST_ASSERT(fluid_synth_sfcount(synth) == 1);
+    
+    TEST_SUCCESS(fluid_synth_noteon(synth, 0, 60, 127));
+    FLUID_LOG(FLUID_INFO, "test_after_polyphony_exceeded(): note on C4, voice 
count=%d",
+                           fluid_synth_get_active_voice_count(synth));
+    
+    // need to render a bit to make synth->ticks_since_start advance, to make 
the previous voice "killable"
+    TEST_SUCCESS(fluid_synth_process(synth, 2048, 0, NULL, 0, NULL));
+    
+    // polyphony exceeded - killing the killable voice from above
+    TEST_SUCCESS(fluid_synth_noteon(synth, 0, 61, 127));
+    
+    // need to render again, to make the synth thread assign 
rvoice->dsp.sample, so that sample_unref() later really unrefs
+    TEST_SUCCESS(fluid_synth_process(synth, 2048, 0, NULL, 0, NULL));
+    FLUID_LOG(FLUID_INFO, "test_after_polyphony_exceeded(): note on C#4, voice 
count=%d",
+                           fluid_synth_get_active_voice_count(synth));
+
+    FLUID_LOG(FLUID_INFO, "test_after_polyphony_exceeded(): unload sounfont");
+    TEST_SUCCESS(fluid_synth_sfunload(synth, id, 1));
+    
+    TEST_SUCCESS(fluid_synth_noteoff(synth, 0, 61));
+    
+    // need to render yet again, to make the synth thread release the rvoice 
so it can be reclaimed by
+    // fluid_synth_check_finished_voices()
+    // need to render may more samples this time, so the voice makes it pass 
the release phase...
+    TEST_SUCCESS(fluid_synth_process(synth, 204800, 0, NULL, 0, NULL));
+    
+    // make any API call to execute fluid_synth_check_finished_voices()
+    FLUID_LOG(FLUID_INFO, "test_after_polyphony_exceeded(): note off C#4, 
voice count=%d",
+                           fluid_synth_get_active_voice_count(synth));
+    
+    // there must be one font scheduled for lazy unloading
+    TEST_ASSERT(synth->fonts_to_be_unloaded != NULL);
+    
+    wait_and_free(synth, id, __func__);
+}
+
+static void test_default_polyphony(fluid_settings_t* settings, int 
with_rendering)
+{
+    enum { BUFSIZE = 128 };
+    fluid_voice_t* buf[BUFSIZE];
+    
+    int id;
+    fluid_synth_t *synth = new_fluid_synth(settings);
+    TEST_ASSERT(synth != NULL);
+
+    TEST_ASSERT(fluid_is_soundfont(TEST_SOUNDFONT) == TRUE);
+
+    // load a sfont to synth
+    TEST_SUCCESS(id = fluid_synth_sfload(synth, TEST_SOUNDFONT, 1));
+    // one sfont loaded
+    TEST_ASSERT(fluid_synth_sfcount(synth) == 1);
+    
+    TEST_SUCCESS(fluid_synth_noteon(synth, 0, 60, 127));
+    
+    if(with_rendering)
+    {
+        TEST_SUCCESS(fluid_synth_process(synth, 
fluid_synth_get_internal_bufsize(synth), 0, NULL, 0, NULL));
+    }
+    
+    TEST_SUCCESS(fluid_synth_noteon(synth, 0, 61, 127));
+    
+    fluid_synth_get_voicelist(synth, buf, BUFSIZE, -1);
+    
+    TEST_ASSERT(fluid_synth_get_active_voice_count(synth) == 4);
+    
+    if(with_rendering)
+    {
+        // make the synth thread assign rvoice->dsp.sample
+        TEST_SUCCESS(fluid_synth_process(synth, 2 * 
fluid_synth_get_internal_bufsize(synth), 0, NULL, 0, NULL));
+        
+        TEST_ASSERT(fluid_synth_get_active_voice_count(synth) == 4);
+    }
+    
+    TEST_ASSERT(synth->fonts_to_be_unloaded == NULL);
+    
+    TEST_SUCCESS(fluid_synth_sfunload(synth, id, 1));
+    
+    // now, there must be one font scheduled for lazy unloading
+    TEST_ASSERT(synth->fonts_to_be_unloaded != NULL);
+    
TEST_ASSERT(fluid_timer_is_running(fluid_list_get(synth->fonts_to_be_unloaded)));
+    
+    // noteoff the second note and render something
+    TEST_SUCCESS(fluid_synth_noteoff(synth, 0, 61));
+    if(with_rendering)
+    {
+        TEST_SUCCESS(fluid_synth_process(synth, 
fluid_synth_get_internal_bufsize(synth), 0, NULL, 0, NULL));
+    }
+    
+    // still 4 because key 61 is playing in release phase now
+    TEST_ASSERT(fluid_synth_get_active_voice_count(synth) == 4);
+    // must be still running
+    TEST_ASSERT(synth->fonts_to_be_unloaded != NULL);
+    
TEST_ASSERT(fluid_timer_is_running(fluid_list_get(synth->fonts_to_be_unloaded)));
+    
+    // noteoff the first note and render something
+    TEST_SUCCESS(fluid_synth_noteoff(synth, 0, 60));
+    if(with_rendering)
+    {
+        TEST_SUCCESS(fluid_synth_process(synth, 
fluid_synth_get_internal_bufsize(synth), 0, NULL, 0, NULL));
+    }
+    
+    // still 4 because keys 60 + 61 are playing in release phase now
+    TEST_ASSERT(fluid_synth_get_active_voice_count(synth) == 4);
+    // must be still running
+    TEST_ASSERT(synth->fonts_to_be_unloaded != NULL);
+    
TEST_ASSERT(fluid_timer_is_running(fluid_list_get(synth->fonts_to_be_unloaded)));
+    
+    if(with_rendering)
+    {
+        // render enough, to make the synth thread release the rvoice so it 
can be reclaimed by
+        // fluid_synth_check_finished_voices()
+        TEST_SUCCESS(fluid_synth_process(synth, 2048000, 0, NULL, 0, NULL));
+        
+        // this API call should reclaim the rvoices and call fluid_voice_stop()
+        TEST_ASSERT(fluid_synth_get_active_voice_count(synth) == 0);
+    }
+
+    TEST_ASSERT(synth->fonts_to_be_unloaded != NULL);
+    if(with_rendering)
+    {
+        // We want to see that the timer thread unloads the soundfont before 
we call delete_fluid_synth().
+        // Wait to give the timer thread a chance to unload and finish.
+        fluid_msleep(10 * 
fluid_timer_get_interval(fluid_list_get(synth->fonts_to_be_unloaded)));
+        
TEST_ASSERT(!fluid_timer_is_running(fluid_list_get(synth->fonts_to_be_unloaded)));
+    }
+    else
+    {
+        
TEST_ASSERT(fluid_timer_is_running(fluid_list_get(synth->fonts_to_be_unloaded)));
+    }
+    
+    wait_and_free(synth, id, __func__);
+}
+
+// this tests the soundfont loading API of the synth.
+// might be expanded to test the soundfont loader as well...
+int main(void)
+{
+    fluid_settings_t *settings = new_fluid_settings();
+    TEST_ASSERT(settings != NULL);
+    
+    FLUID_LOG(FLUID_INFO, "Begin test_default_polyphony() with rendering");
+    test_default_polyphony(settings, TRUE);
+    FLUID_LOG(FLUID_INFO, "End test_default_polyphony()\n");
+    
+    FLUID_LOG(FLUID_INFO, "Begin test_default_polyphony() without rendering");
+    test_default_polyphony(settings, FALSE);
+    FLUID_LOG(FLUID_INFO, "End test_default_polyphony()\n");
+    
+    fluid_settings_setint(settings, "synth.polyphony", 2);
+    
+    FLUID_LOG(FLUID_INFO, "Begin test_after_polyphony_exceeded()");
+    test_after_polyphony_exceeded(settings);
+    FLUID_LOG(FLUID_INFO, "End test_after_polyphony_exceeded()\n");
+
+    FLUID_LOG(FLUID_INFO, "Begin test_without_rendering()");
+    test_without_rendering(settings);
+    FLUID_LOG(FLUID_INFO, "End test_without_rendering()");
+    
+    delete_fluid_settings(settings);
+
+    return EXIT_SUCCESS;
+}

Reply via email to