Compare commits

..

No commits in common. "native_win32" and "v2.2.1" have entirely different histories.

165 changed files with 1355 additions and 5279 deletions

81
.appveyor-vcpkg.yml Normal file
View file

@ -0,0 +1,81 @@
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)

27
.azure-pipelines-mac.yml Normal file
View file

@ -0,0 +1,27 @@
# 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'
# recommended by https://github.com/Homebrew/brew/issues/2491#issuecomment-294207661
# brew update || brew update
# brew upgrade $PACKAGES
steps:
- script: |
PACKAGES="glib gobject-introspection libsndfile pkg-config jack dbus-glib pulseaudio portaudio sdl2"
brew install $PACKAGES
displayName: 'Prerequisites'
- script: |
mkdir build && cd build
export PKG_CONFIG_PATH="/usr/local/opt/libffi/lib/pkgconfig"
cmake -Werror=dev -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 ..
make -j`nproc`
displayName: 'Compile fluidsynth'
- script: |
cd build || exit -1
make -j`nproc` check || exit -1
displayName: 'Execute Unittests'

View file

@ -1,17 +1,7 @@
trigger:
paths:
include:
- '*'
exclude:
- '.azure/azure-pipelines-android.yml'
- '.azure/azure-pipelines-mac.yml'
- '.azure/azure-pipelines-vcpkg.yml'
- '.circleci/config.yml'
- '.github/workflows/linux.yml'
- '.github/workflows/sonarcloud.yml'
- '.cirrus.yml'
- 'README.md'
# 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: WindowsXP
@ -24,15 +14,11 @@ jobs:
gtk-bundle: $(gtk-bundle-x86)
libsndfile-url: $(libsndfile-url-x86)
artifact-prefix: "fluidsynth"
CFLAGS: "/arch:IA32"
CXXFLAGS: "/arch:IA32"
x64:
platform: x64
gtk-bundle: $(gtk-bundle-x64)
libsndfile-url: $(libsndfile-url-x64)
artifact-prefix: "fluidsynth"
CFLAGS: ""
CXXFLAGS: ""
pool:
vmImage: 'windows-2019'
steps:
@ -42,7 +28,7 @@ jobs:
# https://dev.azure.com/tommbrt/_apis/projects?api-version=5.0
project: 'd3638885-de4a-4ce7-afe7-f237ae461c07'
pipeline: 1
artifactName: libinstpatch-XP-$(platform)
artifactName: libinstpatch-$(platform)
downloadPath: '$(Build.ArtifactStagingDirectory)'
displayName: 'Get libinstpatch'
- script: |
@ -56,11 +42,11 @@ jobs:
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-XP-$(platform)
cd $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform)
cp -rf * d:\deps\
mv -f * ..
cd ..
rmdir $(Build.ArtifactStagingDirectory)\libinstpatch-XP-$(platform)\
rmdir $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform)\
DEL /F C:\Strawberry\perl\bin\pkg-config.bat
displayName: 'Prerequisites'
- script: |
@ -68,8 +54,8 @@ jobs:
SET "PATH=d:\deps\bin;%PATH%"
pkg-config --list-all
mkdir build && cd build || exit -1
cmake -Werror=dev -A $(platform) -T $(toolset) -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) -Denable-readline=0 -Denable-floats=1 -Denable-jack=0 -Denable-sdl2=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 -Dwindows-version=0x0501 .. || exit -1
cmake --build . --config Release --parallel 3 || exit -1
cmake -Werror=dev -A $(platform) -T $(toolset) -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) -Denable-readline=0 -Denable-floats=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 -Dwindows-version=0x0501 .. || exit -1
cmake --build . --config Release || exit -1
displayName: 'Compile fluidsynth'
- script: |
@ECHO ON
@ -77,12 +63,6 @@ jobs:
cd build || exit -1
cmake --build . --config Release --target check || exit -1
displayName: 'Execute Unittests'
- script: |
@ECHO ON
SET "PATH=d:\deps\bin;%PATH%"
cd build || exit -1
cmake --build . --config Release --target demo || exit -1
displayName: 'Compile demos'
- script: |
@ECHO ON
cd build
@ -119,7 +99,7 @@ jobs:
CMAKE_FLAGS: -DBUILD_SHARED_LIBS=0
CMAKE_CONFIG: Release
minimal:
CMAKE_FLAGS: -Denable-ipv6=0 -Denable-network=0 -Denable-aufile=0 -Denable-threads=0 -Denable-winmidi=0 -Denable-waveout=0 -Denable-dsound=0 -Denable-libsndfile=0 -Denable-floats=1
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
pool:
vmImage: 'windows-2019'
@ -141,8 +121,8 @@ jobs:
@ECHO ON
SET "PATH=d:\deps\bin;%PATH%"
mkdir build && cd build || exit -1
cmake -Werror=dev -A x64 -T $(toolset) -DCMAKE_BUILD_TYPE=$(CMAKE_CONFIG) -DCMAKE_VERBOSE_MAKEFILE=1 $(CMAKE_FLAGS) -DNO_GUI=1 -Dwindows-version=0x0A00 -Denable-jack=0 -Denable-pulseaudio=0 -Denable-ladspa=0 -Denable-dbus=0 -Denable-readline=0 -Denable-sdl2=0 -Denable-libinstpatch=0 .. || exit -1
cmake --build . --config $(CMAKE_CONFIG) --parallel 3 || exit -1
cmake -Werror=dev -A x64 -T $(toolset) -DCMAKE_BUILD_TYPE=$(CMAKE_CONFIG) -DCMAKE_VERBOSE_MAKEFILE=1 $(CMAKE_FLAGS) -DNO_GUI=1 -Dwindows-version=0x0A00 .. || exit -1
cmake --build . --config $(CMAKE_CONFIG) || exit -1
displayName: 'Compile fluidsynth'
- script: |
@ECHO ON
@ -150,30 +130,24 @@ jobs:
cd build || exit -1
cmake --build . --config $(CMAKE_CONFIG) --target check || exit -1
displayName: 'Execute Unittests'
- script: |
@ECHO ON
SET "PATH=d:\deps\bin;%PATH%"
cd build || exit -1
cmake --build . --config $(CMAKE_CONFIG) --target demo || exit -1
displayName: 'Compile demos'
- job: WindowsMinGW
variables:
artifact-prefix: "fluidsynth-mingw"
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)
x64-static:
CMAKE_FLAGS: '-DBUILD_SHARED_LIBS=0'
platform: x64
gtk-bundle: $(gtk-bundle-x64)
libsndfile-url: $(libsndfile-url-x64)
mingw-url: $(mingw-url-x64)
pool:
vmImage: 'windows-2019'
steps:
@ -212,8 +186,8 @@ jobs:
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 -Denable-floats=1 -Denable-jack=0 -Denable-pulseaudio=0 -Denable-ladspa=0 -Denable-dbus=0 -Denable-sdl2=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1
mingw32-make.exe -j3 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
@ -224,15 +198,7 @@ jobs:
cd build || exit -1
mingw32-make.exe -j4 check || exit -1
displayName: 'Execute Unittests'
- 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 -j4 demo || exit -1
displayName: 'Compile demos'
continueOnError: 'true'
- script: |
@ECHO ON
cd build

View file

@ -1,18 +1,3 @@
trigger:
paths:
include:
- '*'
exclude:
- '.azure/azure-pipelines-mac.yml'
- '.azure/azure-pipelines-vcpkg.yml'
- '.azure/azure-pipelines-win.yml'
- '.circleci/config.yml'
- '.github/workflows/linux.yml'
- '.github/workflows/sonarcloud.yml'
- '.cirrus.yml'
- 'README.md'
parameters:
- name: UseCache
displayName: Use Dependency Cache
@ -33,19 +18,18 @@ schedules:
variables:
ICONV_VERSION: '1.16'
# Use recent master libffi, because 3.3 is broken: checking host system type... Invalid configuration `arm-none-linux-eabi': machine `arm-none-linux' not recognized
FFI_VERSION: '3.4.2'
FFI_VERSION: 'dd5bd03075149d7cf8441875c1a344e8beb57dde'
GETTEXT_VERSION: '0.21'
#need to switch to meson build system to use a more recent version
GLIB_VERSION: '2.71'
GLIB_EXTRAVERSION: '2'
GLIB_VERSION: '2.58'
GLIB_EXTRAVERSION: '3'
OBOE_VERSION: '1.5.0'
SNDFILE_VERSION: '1.0.31'
INSTPATCH_VERSION: '1.1.6'
VORBIS_VERSION: '1.3.7'
OGG_VERSION: '1.3.5'
OPUS_VERSION: '1.3.1'
FLAC_VERSION: '1.3.4'
PCRE_VERSION: '8.45'
OGG_VERSION: '1.3.4'
# flac 1.3.3 is completely broken: pkgconfig is incorrectly installed, compilation failure, etc.; use recent master instead
FLAC_VERSION: '27c615706cedd252a206dd77e3910dfa395dcc49'
# Android NDK sources and standalone toolchain is put here
DEV: '$(System.DefaultWorkingDirectory)/android-build-root'
@ -53,22 +37,17 @@ variables:
# This is a symlink pointing to the real Android NDK
# Must be the same as $ANDROID_NDK_HOME see:
# https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md
# We cannot use $ANDROID_NDK_HOME because this is an environment variable, but here, we need a compile-time constant.
NDK: '/usr/local/lib/android/sdk/ndk-bundle'
# All the built binaries, libs and their headers will be installed here
PREFIX: '$(DEV)/opt/android'
# Prevent installing to lib64/
# This becomes important, if you would build on e.g. openSUSE
LIBPATH0: '$(PREFIX)/lib'
# The path of standalone NDK toolchain
# Refer to https://developer.android.com/ndk/guides/standalone_toolchain.html
NDK_TOOLCHAIN: '$(NDK)/toolchains/llvm/prebuilt/linux-x86_64/'
# Don't mix up .pc files from your host and build target
PKG_CONFIG_PATH: '$(LIBPATH0)/pkgconfig'
PKG_CONFIG_PATH: '$(PREFIX)/lib/pkgconfig'
# setting PKG_CONFIG_PATH alone does not seem to be enough to avoid mixing up with the host, also set PKG_CONFIG_LIBDIR
PKG_CONFIG_LIBDIR: '$(PKG_CONFIG_PATH)'
@ -82,10 +61,9 @@ variables:
# Tell configure what flags Android requires.
# Turn Wimplicit-function-declaration into errors. Else autotools will be fooled when checking for available functions (that in fact are NOT available) and compilation will fail later on.
# Also disable clangs integrated assembler, as the hand written assembly of libffi is not recognized by it, cf. https://crbug.com/801303
CFLAGS: "-fPIE -fPIC -I$(PREFIX)/include --sysroot=$(NDK_TOOLCHAIN)/sysroot -I$(NDK_TOOLCHAIN)/sysroot/usr/include -Werror=implicit-function-declaration"
CFLAGS: "-fPIE -fPIC -I$(PREFIX)/include --sysroot=$(NDK_TOOLCHAIN)/sysroot -I$(NDK_TOOLCHAIN)/sysroot/usr/include -Werror=implicit-function-declaration -fno-integrated-as"
CXXFLAGS: $(CFLAGS)
CPPFLAGS: $(CXXFLAGS)
DEBIAN_FRONTEND: 'noninteractive'
ARTIFACT_NAME: 'fluidsynth-android$(ANDROID_API)'
@ -98,30 +76,30 @@ jobs:
ANDROID_ARCH: 'armv7a'
ANDROID_ABI_CMAKE: 'armeabi-v7a'
ANDROID_TARGET_ABI: "eabi"
ANDROID_ABI_MESON: 'arm'
# the --target to be used by autotools
AUTOTOOLS_TARGET: "$(ARCH)-linux-android$(ANDROID_TARGET_ABI)"
#AUTOTOOLS_TARGET: "$(ARCH)-linux-android$(ANDROID_TARGET_ABI)"
AUTOTOOLS_TARGET: "$(ARCH)-none-linux-$(ANDROID_TARGET_ABI)"
AARCH64:
ARCH: 'aarch64'
ANDROID_ARCH: 'aarch64'
ANDROID_ABI_CMAKE: 'arm64-v8a'
ANDROID_TARGET_ABI:
ANDROID_ABI_MESON: 'aarch64'
AUTOTOOLS_TARGET: "$(ARCH)-none-linux-android"
#AUTOTOOLS_TARGET: "$(ARCH)-none-linux-android"
AUTOTOOLS_TARGET: "$(ARCH)-none-linux"
i686:
ARCH: 'i686'
ANDROID_ARCH: 'i686'
ANDROID_ABI_CMAKE: 'x86'
ANDROID_TARGET_ABI:
ANDROID_ABI_MESON: 'x86'
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
#AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux"
x86_64:
ARCH: 'x86_64'
ANDROID_ARCH: 'x86_64'
ANDROID_ABI_CMAKE: 'x86_64'
ANDROID_TARGET_ABI:
ANDROID_ABI_MESON: 'x86_64'
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
#AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux"
pool:
vmImage: 'ubuntu-20.04'
@ -132,22 +110,13 @@ jobs:
mkdir -p $(DEV)
displayName: 'mkdir $(DEV)'
- script: |
sudo apt-get update -y
displayName: 'Update apt'
- script: |
set -ex
sudo -E apt-get -y --no-install-suggests --no-install-recommends install wget tar bzip2 xz-utils ca-certificates
displayName: 'apt-get install wget tar'
- script: |
set -ex
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz
tar zxf libiconv-${ICONV_VERSION}.tar.gz
wget -O libffi-${FFI_VERSION}.tar.gz https://github.com/libffi/libffi/releases/download/v${FFI_VERSION}/libffi-${FFI_VERSION}.tar.gz
wget -O libffi-${FFI_VERSION}.tar.gz https://github.com/libffi/libffi/archive/${FFI_VERSION}.tar.gz
tar zxf libffi-${FFI_VERSION}.tar.gz
wget http://ftp.gnu.org/pub/gnu/gettext/gettext-${GETTEXT_VERSION}.tar.gz
@ -171,25 +140,15 @@ jobs:
wget https://github.com/xiph/ogg/releases/download/v${OGG_VERSION}/libogg-${OGG_VERSION}.tar.gz
tar zxf libogg-${OGG_VERSION}.tar.gz
wget -O flac-${FLAC_VERSION}.tar.gz https://github.com/xiph/flac/archive/refs/tags/${FLAC_VERSION}.tar.gz
wget -O flac-${FLAC_VERSION}.tar.gz https://github.com/xiph/flac/archive/${FLAC_VERSION}.tar.gz
tar xf flac-${FLAC_VERSION}.tar.gz
wget -O opus-${OPUS_VERSION}.tar.gz https://github.com/xiph/opus/archive/refs/tags/v${OPUS_VERSION}.tar.gz
tar xf opus-${OPUS_VERSION}.tar.gz
wget -O pcre-${PCRE_VERSION}.tar.bz2 https://sourceforge.net/projects/pcre/files/pcre/${PCRE_VERSION}/pcre-${PCRE_VERSION}.tar.bz2/download
tar jxf pcre-${PCRE_VERSION}.tar.bz2
cd pcre-${PCRE_VERSION}
# CMake checks for existence of strtoq() using the C compiler - and yes, it does exist!
# Later on, it's actually used by the C++ compiler, where it does not exist.
# Rename the function so CMake won't find it.
sed -i 's/strtoq/strtoqqqq/g' CMakeLists.txt
displayName: 'Download Dependencies'
workingDirectory: $(DEV)
- task: Cache@2
inputs:
key: '$(ARCH) | $(DEV)/*.tar.*'
key: '$(ARCH) | $(DEV)/*.tar.gz | cacheVersion1'
path: '$(PREFIX)'
cacheHitVar: 'CACHE_RESTORED'
displayName: 'Cache fluidsynth dependency libraries'
@ -202,19 +161,19 @@ jobs:
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main'
displayName: 'Use recent CMake Version'
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
condition: ne(variables.CACHE_RESTORED, 'true')
enabled: 'false'
- script: |
set -ex
sudo -E apt-get -y --no-install-suggests --no-install-recommends install gettext cmake zlib1g-dev autogen automake autoconf libtool pkg-config autotools-dev build-essential meson ninja-build python3-distutils
displayName: 'apt-get install build-tools'
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
sudo apt-get update -y
displayName: 'Update apt'
condition: ne(variables.CACHE_RESTORED, 'true')
- script: |
set -ex
ln -sfn $ANDROID_SDK_ROOT/ndk/21.4.7075529 $ANDROID_NDK_ROOT
displayName: 'Use NDK r22'
sudo -E apt-get -yq --no-install-suggests --no-install-recommends install gettext cmake zlib1g-dev autogen automake autoconf libtool pkg-config autotools-dev build-essential meson ninja-build
displayName: 'apt-get install'
condition: ne(variables.CACHE_RESTORED, 'true')
- script: |
set -e
@ -230,6 +189,7 @@ jobs:
export PATH=$PATH:${PREFIX}/bin:${PREFIX}/lib:${PREFIX}/include:${NDK_TOOLCHAIN}/bin
echo "##vso[task.setvariable variable=PATH]$PATH"
LIBPATH0=$(PREFIX)/lib
LIBPATH1=$(NDK_TOOLCHAIN)/sysroot/usr/lib
LIBPATH2=$(NDK_TOOLCHAIN)/sysroot/usr/lib/$(ARCH)-linux-android$(ANDROID_TARGET_ABI)/$(ANDROID_API)
LIBPATH3=$(NDK_TOOLCHAIN)/sysroot/usr/lib/$(ARCH)-linux-android$(ANDROID_TARGET_ABI)
@ -262,10 +222,9 @@ jobs:
./configure \
--host=${AUTOTOOLS_TARGET} \
--prefix=${PREFIX} \
--libdir=${LIBPATH0} \
--disable-rpath \
--enable-static \
--disable-shared \
--disable-static \
--enable-shared \
--with-pic \
--disable-maintainer-mode \
--disable-silent-rules \
@ -278,15 +237,7 @@ jobs:
displayName: 'Compile libiconv'
workingDirectory: $(DEV)
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
- script: |
set -ex
pushd libiconv-${ICONV_VERSION}
cat config.log
displayName: 'libiconv config.log'
workingDirectory: $(DEV)
condition: and(failed(), ne(variables.CACHE_RESTORED, 'true'))
condition: ne(variables.CACHE_RESTORED, 'true')
- script: |
set -ex
@ -296,13 +247,109 @@ jobs:
# install headers into the conventional ${PREFIX}/include rather than ${PREFIX}/lib/libffi-3.2.1/include.
#sed -e '/^includesdir/ s/$(libdir).*$/$(includedir)/' -i include/Makefile.in
#sed -e '/^includedir/ s/=.*$/=@includedir@/' -e 's/^Cflags: -I${includedir}/Cflags:/' -i libffi.pc.in
./configure --host=${AUTOTOOLS_TARGET} --prefix=${PREFIX} --libdir=${LIBPATH0} --enable-static --disable-shared
./configure --host=${AUTOTOOLS_TARGET} --prefix=${PREFIX} --enable-shared --disable-static
make -j$((`nproc`+1))
make install
popd
displayName: 'Compile libffi'
workingDirectory: $(DEV)
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
condition: ne(variables.CACHE_RESTORED, 'true')
- script: |
set -ex
export PKGCFG=`which pkg-config`
pushd glib-${GLIB_VERSION}.${GLIB_EXTRAVERSION}
cat << EOF > cross-file.txt
[host_machine]
system = 'android'
cpu_family = 'arm'
cpu = 'arm'
endian = 'little'
[binaries]
c = '${CC}'
cpp = '${CXX}'
ar = '${AR}'
ld = '${LD}'
strip = '${STRIP}'
pkgconfig = '${PKGCFG}'
[built-in options]
c_std = 'c11'
c_args = ['-fPIC','-I/home/git/work/ndk/builddir/out/include']
cpp_args = ['-fPIC','-I/home/git/work/ndk/builddir/out/include']
c_link_args = ['-fPIE','-L/home/git/work/ndk/builddir/out/lib']
pkg_config_path = '${PKG_CONFIG_PATH}'
EOF
cat << EOF > native-file.txt
[host_machine]
system = 'linux'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
[properties]
[binaries]
c = ['false']
cpp = ['false']
objc = ['false']
objcpp = ['false']
ar = ['false']
pkgconfig = ['false']
cmake = ['false']
EOF
cat native-file.txt
cat cross-file.txt
unset AR
unset AS
unset CC
unset CFLAGS
unset CPPFLAGS
unset CPP
unset CXXFLAGS
unset CXX
unset LDFLAGS
unset LD
unset STRIP
meson \
--cross-file cross-file.txt \
--native-file native-file.txt \
--prefix=${PREFIX} \
--libdir=lib \
-Ddebug=false \
--default-library=both \
-Doptimization=s \
--backend=ninja \
--wrap-mode=nodownload \
-Dinternal_pcre=true \
-Dlibmount=false \
-Ddtrace=false \
-Diconv=auto \
-Dxattr=false \
-Dgtk_doc=false \
_builddir \
.
ninja
popd
displayName: 'Compile glib (meson)'
workingDirectory: $(DEV)
enabled: 'false'
- script: |
pushd glib-${GLIB_VERSION}.${GLIB_EXTRAVERSION}
cat _builddir/meson-logs/meson-log.txt
popd
displayName: 'Meson LOG'
workingDirectory: $(DEV)
condition: failed()
enabled: 'false'
- script: |
set -ex
@ -311,15 +358,14 @@ jobs:
./configure \
--host=${AUTOTOOLS_TARGET} \
--prefix=${PREFIX} \
--libdir=${LIBPATH0} \
--disable-rpath \
--disable-libasprintf \
--disable-java \
--disable-native-java \
--disable-openmp \
--disable-curses \
--enable-static \
--disable-shared \
--disable-static \
--enable-shared \
--with-pic \
--disable-maintainer-mode \
--disable-silent-rules \
@ -330,85 +376,95 @@ jobs:
popd
displayName: 'Compile gettext'
workingDirectory: $(DEV)
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
- template: cmake-android.yml
parameters:
sourceDir: 'pcre-$(PCRE_VERSION)'
cmakeArgs: '-DPCRE_SUPPORT_UNICODE_PROPERTIES=1 -DPCRE_SUPPORT_UTF=1 -DPCRE_BUILD_PCRECPP=0 -DPCRE_BUILD_TESTS=0'
condition: ne(variables.CACHE_RESTORED, 'true')
- script: |
set -ex
export PKGCFG=`which pkg-config`
pushd glib-${GLIB_VERSION}.${GLIB_EXTRAVERSION}
cat << EOF > cross_file.ini
[host_machine]
system = 'android'
cpu_family = '${ANDROID_ABI_MESON}'
cpu = '${ANDROID_ARCH}'
endian = 'little'
[binaries]
c = '${NDK_TOOLCHAIN}/bin/${CC}'
cpp = '${NDK_TOOLCHAIN}/bin/${CXX}'
ar = '${NDK_TOOLCHAIN}/bin/${AR}'
as = '${NDK_TOOLCHAIN}/bin/${AS}'
ld = '${NDK_TOOLCHAIN}/bin/${LD}'
strip = '${NDK_TOOLCHAIN}/bin/${STRIP}'
ranlib = '${NDK_TOOLCHAIN}/bin/${RANLIB}'
pkgconfig = '${PKGCFG}'
[properties]
prefix = '${PREFIX}'
c_args = '${CFLAGS}'
cpp_args = '${CXXFLAGS}'
pkg_config_libdir = '${PKG_CONFIG_LIBDIR}'
c_link_args = '${LDFLAGS}'
[project options]
libmount = 'disabled'
xattr = false
selinux = 'disabled'
nls = 'disabled'
glib_debug = 'disabled'
glib_assert = false
glib_checks = false
libelf = 'disabled'
cat << EOF > android.cache
glib_cv_long_long_format=ll
glib_cv_stack_grows=no
glib_cv_sane_realloc=yes
glib_cv_have_strlcpy=no
glib_cv_va_val_copy=yes
glib_cv_rtldglobal_broken=no
glib_cv_uscore=no
glib_cv_monotonic_clock=no
ac_cv_func_nonposix_getpwuid_r=no
ac_cv_func_posix_getpwuid_r=no
ac_cv_func_posix_getgrgid_r=no
glib_cv_use_pid_surrogate=yes
ac_cv_func_printf_unix98=no
ac_cv_func_vsnprintf_c99=yes
ac_cv_func_realloc_0_nonnull=yes
ac_cv_func_realloc_works=yes
EOF
cat cross_file.ini
# Unfortunately, libffi is not linked against libgobject when compiling for aarch64, leading to the following error:
#
# /bin/bash ../libtool --tag=CC --mode=link aarch64-linux-android23-clang -Wall -Wstrict-prototypes -Wno-bad-function-cast -Werror=declaration-after-statement -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=pointer-arith -Werror=init-self -Werror=format=2 -Werror=missing-include-dirs -fPIE -fPIC -I/home/vsts/work/1/s/android-build-root/opt/android/include --sysroot=/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot -I/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot/include -Werror=implicit-function-declaration -fno-integrated-as -fno-strict-aliasing -pie -Wl,-rpath-link=-I/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot/usr/lib -L/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot/usr/lib -L/home/vsts/work/1/s/android-build-root/opt/android/lib -L/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//lib -o gobject-query gobject-query.o ./libgobject-2.0.la ../glib/libglib-2.0.la -lintl -liconv
# libtool: link: aarch64-linux-android23-clang -Wall -Wstrict-prototypes -Wno-bad-function-cast -Werror=declaration-after-statement -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=pointer-arith -Werror=init-self -Werror=format=2 -Werror=missing-include-dirs -fPIE -fPIC -I/home/vsts/work/1/s/android-build-root/opt/android/include --sysroot=/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot -I/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot/include -Werror=implicit-function-declaration -fno-integrated-as -fno-strict-aliasing -pie -Wl,-rpath-link=-I/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot/usr/lib -o .libs/gobject-query gobject-query.o -L/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//sysroot/usr/lib -L/home/vsts/work/1/s/android-build-root/opt/android/lib -L/usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//lib ./.libs/libgobject-2.0.so ../glib/.libs/libglib-2.0.so /home/vsts/work/1/s/android-build-root/opt/android/lib/libintl.so /home/vsts/work/1/s/android-build-root/opt/android/lib/libiconv.so -pthread -L/home/vsts/work/1/s/android-build-root/opt/android/lib
# /usr/local/lib/android/sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64//bin/../lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld: warning: libffi.so, needed by ./.libs/libgobject-2.0.so, not found (try using -rpath or -rpath-link)
# ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint32@LIBFFI_BASE_8.0'
# ./.libs/libgobject-2.0.so: undefined reference to `ffi_prep_cif@LIBFFI_BASE_8.0'
#
# So, just add it to LDFLAGS to make sure it's always linked.
# libz.so is also missing...
#FFILIB=`pkg-config --libs libffi`
#echo ${FFILIB}
#export LDFLAGS="${LDFLAGS} ${FFILIB} -lz"
#unset FFILIB
# When CC and CXX are set, then meson detects them as host compiler (not cross compiler),
# so they tries to run arm binaries in x86. That's why sanity check is failing, and that's
# why we have to use env -i.
# And we must explicitly set PKG_CONFIG_LIBDIR, because pkg_config_libdir is only recognized by meson >= 0.54
env -i bash -c "export PATH && export PKG_CONFIG_LIBDIR=$(PKG_CONFIG_LIBDIR) && meson setup build --cross-file cross_file.ini --prefix=$(PREFIX)"
ninja -C build
ninja -C build install
chmod a-x android.cache
NOCONFIGURE=true ./autogen.sh
./configure \
--host=${ANDROID_TARGET} \
--prefix=${PREFIX} \
--disable-dependency-tracking \
--cache-file=android.cache \
--enable-included-printf \
--with-pcre=no \
--enable-libmount=no \
--enable-xattr=no \
--with-libiconv=gnu \
--disable-static \
--enable-shared \
--with-pic \
--disable-maintainer-mode \
--disable-silent-rules
make -j$((`nproc`+1))
make install
popd
displayName: 'Compile glib (meson)'
displayName: 'Compile glib'
workingDirectory: $(DEV)
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
- script: |
pushd glib-${GLIB_VERSION}.${GLIB_EXTRAVERSION}
ls -la build
cat build/meson-logs/meson-log.txt
popd
displayName: 'Meson LOG'
workingDirectory: $(DEV)
condition: and(succeededOrFailed(), ne(variables.CACHE_RESTORED, 'true'))
condition: ne(variables.CACHE_RESTORED, 'true')
- template: cmake-android.yml
parameters:
sourceDir: 'libogg-$(OGG_VERSION)'
cmakeArgs: '-DINSTALL_DOCS=0'
- script: |
ls -la libogg-${OGG_VERSION}/build/CMakeFiles/
cat libogg-${OGG_VERSION}/build/CMakeFiles/CMakeError.log
true
displayName: 'Print OGG Cmake Error Log'
condition: always()
workingDirectory: $(DEV)
- template: cmake-android.yml
parameters:
sourceDir: 'libvorbis-$(VORBIS_VERSION)'
- script: |
ls -la libvorbis-${VORBIS_VERSION}/build/CMakeFiles/
cat libvorbis-${VORBIS_VERSION}/build/CMakeFiles/CMakeError.log
true
displayName: 'Print Vorbis Cmake Error Log'
condition: always()
workingDirectory: $(DEV)
# flac uses c99 macros, but doesnt specify a standard, so we need to do it explicitly.
# On i686, they invoke yasm with -fstack-protector-strong flag... turn off asm optimizations.
- template: cmake-android.yml
@ -416,17 +472,27 @@ jobs:
sourceDir: 'flac-$(FLAC_VERSION)'
cmakeArgs: '-DCMAKE_C_STANDARD=99 -DCMAKE_C_STANDARD_REQUIRED=1 -DWITH_ASM=0 -DBUILD_CXXLIBS=0 -DBUILD_PROGRAMS=0 -DBUILD_EXAMPLES=0 -DBUILD_DOCS=0 -DINSTALL_MANPAGES=0'
# another broken xiph project that doesn't specify the C standard and keeps complaining of you don't have C99
- template: cmake-android.yml
parameters:
sourceDir: 'opus-$(OPUS_VERSION)'
cmakeArgs: '-DBUILD_PROGRAMS=0 -DOPUS_MAY_HAVE_NEON=1 -DCMAKE_C_STANDARD=99 -DCMAKE_C_STANDARD_REQUIRED=1'
- script: |
ls -la flac-${FLAC_VERSION}/build/CMakeFiles/
cat flac-${FLAC_VERSION}/build/CMakeFiles/CMakeError.log
true
displayName: 'Print FLAC Cmake Error Log'
condition: always()
workingDirectory: $(DEV)
- template: cmake-android.yml
parameters:
sourceDir: 'libsndfile-$(SNDFILE_VERSION)'
cmakeArgs: '-DBUILD_PROGRAMS=0 -DBUILD_EXAMPLES=0'
- script: |
ls -la libsndfile-${SNDFILE_VERSION}/build/CMakeFiles/
cat libsndfile-${SNDFILE_VERSION}/build/CMakeFiles/CMakeError.log
true
displayName: 'Print libsndfile Cmake Error Log'
condition: always()
workingDirectory: $(DEV)
- template: cmake-android.yml
parameters:
sourceDir: 'oboe-$(OBOE_VERSION)'
@ -453,7 +519,7 @@ jobs:
displayName: 'Create fake oboe.pc'
workingDirectory: $(DEV)
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
condition: ne(variables.CACHE_RESTORED, 'true')
- template: cmake-android.yml
parameters:
@ -492,29 +558,27 @@ jobs:
sourceDir: '.'
condition: succeeded()
installCommand: 'cp *.so ${PREFIX}/lib/'
- script: |
ls -Rg $(PREFIX)
displayName: 'Show cross-compiled files in $(PREFIX)'
condition: or(succeeded(), failed())
condition: always()
- script: |
set -ex
# use ANDROID_ABI_CMAKE so libs can be simply copied to the archive contents in src/main/jniLibs
mkdir -p $(Build.ArtifactStagingDirectory)/lib/$(ANDROID_ABI_CMAKE)
cd $(Build.ArtifactStagingDirectory)/lib/$(ANDROID_ABI_CMAKE)
cp -LR $(PREFIX)/lib/* .
mkdir -p $(Build.ArtifactStagingDirectory)/$(ARCH)
cd $(Build.ArtifactStagingDirectory)/$(ARCH)
cp -a $(PREFIX)/lib/* .
ls -Rg .
rm -rf *.dll *.alias gettext/ libtextstyle.* *.a *.la
rm -f *.so.*
mkdir -p $(Build.ArtifactStagingDirectory)/include
cd $(Build.ArtifactStagingDirectory)/include
cp -a $(PREFIX)/include/fluidsynth* .
displayName: 'Collecting artifacts'
- script: |
set -ex
ls libFLAC.so
ls libcharset.so
ls libffi.so
ls libfluidsynth-assetloader.so
ls libfluidsynth.so
ls libgio-2.0.so
@ -522,21 +586,20 @@ jobs:
ls libgmodule-2.0.so
ls libgobject-2.0.so
ls libgthread-2.0.so
ls libiconv.so
ls libinstpatch-1.0.so
ls libintl.so
ls liboboe.so
ls libogg.so
ls libopus.so
ls libsndfile.so
ls libvorbis.so
ls libvorbisenc.so
ls libvorbisfile.so
ls libpcre.so
ls libpcreposix.so
displayName: 'Verify all libs exist'
workingDirectory: '$(PREFIX)/lib'
- task: PublishBuildArtifacts@1
displayName: 'Publishing Artefacts for Android API$(ANDROID_API) $(ANDROID_ABI_CMAKE)'
displayName: 'Publishing Artefacts for Android API$(ANDROID_API) $(ARCH)'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: '$(ARTIFACT_NAME)'
@ -548,4 +611,4 @@ jobs:
pushd build
make uninstall
popd
displayName: 'Uninstall fluidsynth'
displayName: 'Uninstall fluidsynth'

View file

@ -1,199 +0,0 @@
trigger:
paths:
include:
- '*'
exclude:
- '.azure/azure-pipelines-android.yml'
- '.azure/azure-pipelines-vcpkg.yml'
- '.azure/azure-pipelines-win.yml'
- '.circleci/config.yml'
- '.github/workflows/linux.yml'
- '.github/workflows/sonarcloud.yml'
- '.cirrus.yml'
- 'README.md'
parameters:
- name: UseCache
displayName: Use Dependency Cache
type: boolean
default: true
jobs:
- job: macOS_brew
strategy:
matrix:
UnixLibs:
imageName: 'macos-11'
CMakeFlags: '-Denable-framework=0'
10_15:
imageName: 'macOS-10.15'
CMakeFlags: ''
11_0:
imageName: 'macos-11'
CMakeFlags: ''
12_0:
imageName: 'macos-12'
CMakeFlags: ''
pool:
vmImage: $(imageName)
# recommended by https://github.com/Homebrew/brew/issues/2491#issuecomment-294207661
# brew update || brew update
# brew upgrade $PACKAGES
steps:
- script: |
set -ex
PACKAGES="glib gobject-introspection libsndfile pkg-config jack dbus-glib pulseaudio portaudio sdl2 libomp"
brew install $PACKAGES
displayName: 'Prerequisites'
- script: |
set -ex
mkdir build && cd build
export PKG_CONFIG_PATH="/usr/local/opt/libffi/lib/pkgconfig"
cmake -Werror=dev $(CMakeFlags) -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 ..
make -j3
displayName: 'Compile fluidsynth'
- script: |
set -ex
cd build
make -j3 check
displayName: 'Execute Unittests'
- script: |
set -ex
cd build
make -j3 demo
displayName: 'Compile demos'
- script: |
set -ex
cd build
sudo make install
rm -f install_manifest.txt
displayName: 'Install fluidsynth to default location'
- script: |
set -ex
cd build
cmake -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) ..
make install
displayName: 'Install fluidsynth to artifact dir'
- job: macOS_ports
timeoutInMinutes: 300
strategy:
matrix:
# SDL2/SDL_cpuinfo.h includes some x86 specific headers, which ofc doesn't work when cross compiling for arm64
# And this universal build thingy doesn't work on Mac10.15 for some reason...
# Furthermore, there is a problem when restoring the cache on Mac11, so disable this job as well
#11_0_universal_unixlibs:
# macPortsUrl: 'https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-11-BigSur.pkg'
# imageName: 'macos-11'
# CMakeFlags: '-Denable-sdl2=0 -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -Denable-framework=0 -DLIB_SUFFIX=""'
12_0_universal_unixlibs:
macPortsUrl: 'https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-12-Monterey.pkg'
imageName: 'macos-12'
CMakeFlags: '-Denable-sdl2=0 -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -Denable-framework=0 -DLIB_SUFFIX=""'
pool:
vmImage: $(imageName)
steps:
- script: |
set -ex
brew install wget pkg-config
wget $(macPortsUrl)
sudo installer -pkg *.pkg -target /
rm -f *.pkg
sudo chown -R $(id -u):$(id -g) /opt/local
sudo chflags nouchg /opt/local
displayName: 'Prerequisites'
workingDirectory: $(Agent.TempDirectory)
- task: Cache@2
continueOnError: true
displayName: "Cache macPort packages"
condition: and(not(in(variables['Build.Reason'], 'Schedule')), ${{ parameters.useCache }})
inputs:
key: '"$(Agent.OS)" | "$(imageName)" | "$(macPortsUrl)" | "versionalways"'
path: '/opt/local'
cacheHitVar: CACHE_RESTORED
- script: |
set -ex
export PATH=$PATH:/opt/local/bin
echo $PATH
which codesign
which port
cmake --version || true
echo "+universal" | sudo tee -a /opt/local/etc/macports/variants.conf
sudo sh -c 'cat << EOF >> /opt/local/etc/macports/macports.conf
buildfromsource always
universal_archs arm64 x86_64
ui_interactive no
EOF'
sudo port install glib2-devel libsndfile dbus-glib readline
# fixup permissions to allow non-priv pipeline user access every directory, to make the caching step succeed at the end
sudo chown -R $(id -u):$(id -g) /opt/local
# remove all extended attributes, as they cannot be restored when restoring the pipeline cache
#sudo xattr -rcv /opt/local
displayName: 'Port install universal'
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
- script: |
set -ex
export PATH=$PATH:/opt/local/bin
export PKG_CONFIG_PATH="/opt/local/lib/pkgconfig"
mkdir build && cd build
cmake -Werror=dev $(CMakeFlags) -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 ..
make -j3
displayName: 'Compile fluidsynth'
- script: |
export PATH=$PATH:/opt/local/bin
sudo port -v install fluidsynth +universal
displayName: 'port install fluidsynth +universal'
condition: failed()
enabled: false
- script: |
set -x
cat /opt/local/var/macports/logs/*cmake-bootstrap/cmake-bootstrap/main.log
cat /opt/local/var/macports/build/*cmake-bootstrap/cmake-bootstrap/work/cmake-3.9.4-arm64/Bootstrap.cmk/*.log
cat /opt/local/var/macports/logs/*_fluidsynth/fluidsynth/main.log
condition: failed()
displayName: 'Print fluidsynth error log'
- script: |
set -ex
cd build
make -j3 check
displayName: 'Execute Unittests'
- script: |
set -ex
cd build
make -j3 demo
displayName: 'Compile demos'
- script: |
set -ex
cd build
sudo make install
rm -f install_manifest.txt
displayName: 'Install fluidsynth to default location'
- script: |
set -ex
cd build
cmake -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) ..
make install
cd /opt/local/lib/
cp -a libgthread*.dylib libglib*.dylib libintl*.dylib libsndfile*.dylib libdbus-*.dylib libreadline*.dylib $(Build.ArtifactStagingDirectory)/lib
file /opt/local/lib/libglib-2.0.dylib $(Build.ArtifactStagingDirectory)/bin/fluidsynth $(Build.ArtifactStagingDirectory)/lib/libfluidsynth*.dylib
displayName: 'Install fluidsynth to artifact dir'
- task: PublishBuildArtifacts@1
displayName: 'Publish fluidsynth artifacts'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'fluidsynth-$(imageName)'
publishLocation: 'Container'
- task: PublishBuildArtifacts@1
displayName: 'Publish macPorts deps'
enabled: false
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
inputs:
PathtoPublish: '/opt/local/lib'
ArtifactName: 'macports-$(imageName)'
publishLocation: 'Container'

View file

@ -1,154 +0,0 @@
trigger:
paths:
include:
- '*'
exclude:
- '.azure/azure-pipelines-android.yml'
- '.azure/azure-pipelines-mac.yml'
- '.azure/azure-pipelines-win.yml'
- '.circleci/config.yml'
- '.github/workflows/linux.yml'
- '.github/workflows/sonarcloud.yml'
- '.cirrus.yml'
- 'README.md'
parameters:
- name: UseCache
displayName: Use Dependency Cache
type: boolean
default: true
schedules:
- cron: "0 0 * * 1"
displayName: 'Weekly Monday Midnight build without caching'
branches:
include:
- master
always: true
variables:
toolset: 'v142'
generator: 'Visual Studio 16 2019'
configuration: 'RelWithDebInfo'
VCPKG_REVISION: 'e809a42f87565e803b2178a0c11263f462d1800a'
jobs:
- job: vcpkg
workspace:
clean: all
strategy:
matrix:
ARM:
platform: 'arm'
cmake_platform: 'ARM'
ARM64:
platform: 'arm64'
cmake_platform: 'ARM64'
x86:
platform: 'x86'
cmake_platform: 'Win32'
x64:
platform: 'x64'
cmake_platform: 'x64'
pool:
vmImage: 'windows-2019'
steps:
- task: Cache@2
displayName: "Cache vcpkg's packages"
condition: and(not(in(variables['Build.Reason'], 'Schedule')), ${{ parameters.useCache }})
inputs:
key: $(VCPKG_REVISION) | "$(platform)"
path: '$(VCPKG_INSTALLATION_ROOT)\installed'
cacheHitVar: CACHE_RESTORED
- bash: |
set -ex
echo $(generator)
echo $(toolset)
# choco upgrade ninja -y
# ninja --version
cmake --version
rm -rf C:/Strawberry/perl/bin/pkg-config*
choco install --svc --sdc -i pkgconfiglite
# chocoTask=$!
# manually update vcpkg
cd $VCPKG_INSTALLATION_ROOT
# git checkout master
git remote -v
git fetch --tags --prune --progress origin
git checkout --force $(VCPKG_REVISION)
sed -i 's/arm64/arm/g' ports/glib/portfile.cmake
./bootstrap-vcpkg.sh
# wait $chocoTask
which pkg-config
displayName: 'Update vcpkg'
- 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-$(cmake_platform)
downloadPath: '$(Agent.TempDirectory)'
displayName: 'Get libinstpatch'
condition: and(succeeded(), and(ne(variables['platform'], 'arm'), ne(variables['platform'], 'arm64')))
- task: CopyFiles@2
inputs:
SourceFolder: '$(Agent.TempDirectory)\libinstpatch-$(cmake_platform)'
Contents: '**'
TargetFolder: '$(VCPKG_INSTALLATION_ROOT)\installed\$(platform)-windows'
displayName: 'Install libinstpatch'
condition: and(succeeded(), and(ne(variables['platform'], 'arm'), ne(variables['platform'], 'arm64')))
- bash: |
set -ex
vcpkg install glib:$(platform)-windows libsndfile:$(platform)-windows
displayName: 'vcpkg build Dependencies'
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
- bash: |
set -ex
cd $VCPKG_INSTALLATION_ROOT/installed/$(platform)-windows/
pwd
rm -rf include/FLAC* include/ffi* include/iconv* include/opus tools share
ls -Rg .
pkg-config --list-all
pkg-config --cflags libinstpatch-1.0 || true
displayName: 'Cleanup dependencies'
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
- bash: |
set -ex
mkdir build
cd build
cmake -Werror=dev -G "$(generator)" -A "$(cmake_platform)" -T "$(toolset)" -Denable-readline=0 -DCMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake -DCMAKE_INSTALL_PREFIX=$VCPKG_INSTALLATION_ROOT/installed/$(platform)-windows -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 ..
cmake --build . --config $(configuration) --parallel 3
displayName: 'Compile fluidsynth'
- bash: |
set -ex
cmake --build build --config $(configuration) --target check --parallel 3
displayName: 'Execute Unittests'
condition: and(succeeded(), and(ne(variables['platform'], 'arm'), ne(variables['platform'], 'arm64')))
- bash: |
set -ex
cmake --build build --config $(configuration) --target demo --parallel 3
displayName: 'Compile demos'
- script: |
@ECHO ON
cd build
cmake --build . --config $(configuration) --target install || exit -1
REM del 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: 'fluidsynth install'
- task: CopyFiles@2
inputs:
SourceFolder: '$(VCPKG_INSTALLATION_ROOT)/installed/$(platform)-windows/'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
displayName: 'Copy Binaries to Artifact Dir'
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: $(Build.ArtifactStagingDirectory)
artifactName: fluidsynth-vcpkg-$(platform)

View file

@ -11,7 +11,7 @@ parameters:
default: $(DEV)
- name: condition
type: string
default: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
default: ne(variables.CACHE_RESTORED, 'true')
- name: installCommand
type: string
default: 'make install'
@ -33,7 +33,6 @@ steps:
cmake -G "Unix Makefiles" \
-DCMAKE_MAKE_PROGRAM=make \
-DCMAKE_TOOLCHAIN_FILE=${NDK}/build/cmake/android.toolchain.cmake \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DANDROID_NATIVE_API_LEVEL=${ANDROID_API} \
-DANDROID_ABI=${ANDROID_ABI_CMAKE} \
-DANDROID_TOOLCHAIN=${CC} \
@ -56,12 +55,3 @@ steps:
displayName: 'Compile ${{ parameters.sourceDir }}'
workingDirectory: ${{ parameters.workDir }}
condition: ${{ parameters.condition }}
- script: |
ls -la ${{ parameters.sourceDir }}/build/CMakeFiles/
cat ${{ parameters.sourceDir }}/build/CMakeFiles/CMakeError.log
cat ${{ parameters.sourceDir }}/build/CMakeFiles/CMakeOutput.log
true
displayName: 'Print ${{ parameters.sourceDir }} Cmake Error Log'
condition: or(${{ parameters.condition }}, failed())
workingDirectory: ${{ parameters.workDir }}

View file

@ -1,71 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '17 18 * * 4'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View file

@ -1,14 +1,6 @@
name: FluidSynth Linux
on:
pull_request:
push:
paths-ignore:
- '.azure/**'
- '.circleci/**'
- '.github/workflows/sonarcloud.yml'
- '.cirrus.yml'
- 'README.md'
on: [push, pull_request]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
@ -25,22 +17,26 @@ jobs:
matrix:
CC: [""]
CXX: [""]
CMAKE_FLAGS: ["-Denable-profiling=1","-Denable-floats=1 -Denable-profiling=1","-Denable-floats=1","-Denable-trap-on-fpe=1","-Denable-fpe-check=1","-Denable-ipv6=0","-Denable-network=0","-Denable-aufile=0","-DBUILD_SHARED_LIBS=0","-Denable-ubsan=1 -Denable-debug=1", "-Denable-debug=1 -DCMAKE_C_FLAGS_DEBUG=-fuse-ld=gold"]
CMAKE_FLAGS: ["-Denable-profiling=1","-Denable-floats=1 -Denable-profiling=1","-Denable-floats=1","-Denable-trap-on-fpe=1","-Denable-fpe-check=1","-Denable-ipv6=0","-Denable-network=0","-Denable-aufile=0","-DBUILD_SHARED_LIBS=0","-Denable-ubsan=1 -Denable-debug=1"]
include:
- CC: "gcc-7"
CXX: "g++-7"
CMAKE_FLAGS: ""
- CC: "gcc-8"
CXX: "g++-8"
CMAKE_FLAGS: "-Denable-debug=1 -DCMAKE_C_FLAGS_DEBUG=-fuse-ld=gold"
- CC: "clang-7"
CXX: "clang++-7"
CMAKE_FLAGS: ""
- CC: "clang-8"
CXX: "clang++-8"
CMAKE_FLAGS: ""
- CC: "clang-9"
CXX: "clang++-9"
CMAKE_FLAGS: ""
- CC: "clang-10"
CXX: "clang++-10"
CMAKE_FLAGS: ""
- CC: "clang-12"
CXX: "clang++-12"
CMAKE_FLAGS: ""
# clang9 is covered by openSUSE Leap 15.2
# clang11 is covered by openSUSE Leap 15.3
steps:
- uses: actions/checkout@v2
@ -62,6 +58,7 @@ jobs:
echo Can execute `nproc` make jobs in parallel
cmake --version
cmake -E make_directory ${{github.workspace}}/build
sudo ln -s /usr/bin/clang-tidy-10 /usr/bin/clang-tidy
which clang-tidy || true
ls -la `which clang-tidy` || true
echo $PATH
@ -92,11 +89,6 @@ jobs:
# Execute tests defined by the CMake configuration.
run: make -j`nproc` check
- name: Demo
working-directory: ${{github.workspace}}/build
shell: bash
run: make -j`nproc` demo
- name: Install
working-directory: ${{github.workspace}}/build
run: make install

View file

@ -4,15 +4,9 @@ on:
push:
branches:
- master
paths-ignore:
- '.azure/**'
- '.circleci/**'
- '.github/workflows/linux.yml'
- '.cirrus.yml'
- 'README.md'
pull_request:
types: [opened, synchronize, reopened]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
# Use Debug build for better code coverage results
@ -85,7 +79,7 @@ jobs:
ls -la ${{ github.workspace }}/build
ls -la ${{ github.workspace }}/build/coverage
# The official sonarsource/sonarcloud-github-action@v1.5 action does not work properly.
# The offical sonarsource/sonarcloud-github-action@v1.5 action does not work properly.
# It keeps complaining that the build-wrapper.json cannot be found.
# Hence, use a third party action to download and add sonar-scanner to PATH and then run it manually.
- name: Setup sonarqube

1
.gitignore vendored
View file

@ -1,5 +1,4 @@
build/
.vs/
CMakeCache.txt
CMakeFiles

View file

@ -1,6 +0,0 @@
workflow:
steps:
- branch_package:
source_project: home:derselbst:anmp
source_package: fluidsynth
target_project: home:derselbst:anmp:github-ci

View file

@ -151,5 +151,3 @@ Sven Meier
Marcus Weseloh
Jean-jacques Ceresa
Vladimir Davidovich
Tamás Korodi
Evan Miller

View file

@ -1,6 +1,6 @@
# FluidSynth - A Software Synthesizer
#
# Copyright (C) 2003-2022 Peter Hanappe and others.
# Copyright (C) 2003-2021 Peter Hanappe and others.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
@ -19,21 +19,18 @@
# CMake based build system. Pedro Lopez-Cabanillas <plcl@users.sf.net>
cmake_minimum_required ( VERSION 3.13 )
# 3.1 because of CMAKE_C_STANDARD
# 3.11 because COMPATIBILITY SameMinorVersion in CMakePackageConfigHelpers
# 3.13.5 because it is the latest supported in Windows XP
cmake_minimum_required ( VERSION 3.1.0 ) # because of CMAKE_C_STANDARD
if(POLICY CMP0075) # CMake version 3.13.5 warns when the policy is not set or value is OLD
if(POLICY CMP0075)
cmake_policy(SET CMP0075 NEW)
endif()
if(POLICY CMP0091) # new in CMake 3.15, defaults to OLD
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif()
project ( FluidSynth C CXX )
list( APPEND CMAKE_MODULE_PATH ${FluidSynth_SOURCE_DIR}/cmake_admin )
set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_admin )
# FluidSynth package name
set ( PACKAGE "fluidsynth" )
@ -41,7 +38,7 @@ set ( PACKAGE "fluidsynth" )
# FluidSynth package version
set ( FLUIDSYNTH_VERSION_MAJOR 2 )
set ( FLUIDSYNTH_VERSION_MINOR 2 )
set ( FLUIDSYNTH_VERSION_MICRO 8 )
set ( FLUIDSYNTH_VERSION_MICRO 1 )
set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" )
set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
@ -55,22 +52,20 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
# if any interfaces have been removed/changed (compatibility broken): AGE=0
# This is not exactly the same algorithm as the libtool one, but the results are the same.
set ( LIB_VERSION_CURRENT 3 )
set ( LIB_VERSION_AGE 1 )
set ( LIB_VERSION_AGE 0 )
set ( LIB_VERSION_REVISION 1 )
set ( LIB_VERSION_INFO
"${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
# Options disabled by default
option ( enable-coverage "enable gcov code coverage" off )
option ( enable-debug "enable debugging (default=no)" off )
option ( enable-floats "enable type float instead of double for DSP samples" off )
option ( enable-fpe-check "enable Floating Point Exception checks and debug messages" off )
option ( enable-portaudio "compile PortAudio support" off )
option ( enable-profiling "profile the dsp code" off )
option ( enable-trap-on-fpe "enable SIGFPE trap on Floating Point Exceptions" off )
option ( enable-ubsan "compile and link against UBSan (for debugging fluidsynth internals)" off )
if ( MSVC )
option ( enable-static-mscrt "use static MS Visual C++ runtime" off )
endif ( MSVC )
# Options enabled by default
option ( enable-aufile "compile support for sound file output" on )
@ -91,11 +86,10 @@ option ( enable-wasapi "compile Windows WASAPI support (if it is available)" on
option ( enable-waveout "compile Windows WaveOut support (if it is available)" on )
option ( enable-winmidi "compile Windows MIDI support (if it is available)" on )
option ( enable-sdl2 "compile SDL2 audio support (if it is available)" on )
option ( enable-pkgconfig "use pkg-config to locate fluidsynth's (mostly optional) dependencies" on )
option ( enable-pulseaudio "compile PulseAudio support (if it is available)" on )
option ( enable-pipewire "compile PipeWire support (if it is available)" on )
option ( enable-readline "compile readline lib line editing (if it is available)" on )
option ( enable-threads "enable multi-threading support (such as parallel voice synthesis)" on )
option ( enable-openmp "enable OpenMP support (parallelization of soundfont decoding, vectorization of voice mixing, etc.)" on )
# Platform specific options
if ( CMAKE_SYSTEM MATCHES "Linux|FreeBSD|DragonFly" )
@ -118,6 +112,20 @@ if ( CMAKE_SYSTEM MATCHES "OS2" )
set ( enable-ipv6 off )
endif ( CMAKE_SYSTEM MATCHES "OS2" )
# Initialize the library directory name suffix.
if (NOT MINGW AND NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD|DragonFly")
if ( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set ( _init_lib_suffix "64" )
else ( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set ( _init_lib_suffix "" )
endif ( CMAKE_SIZEOF_VOID_P EQUAL 8 )
else ()
set ( _init_lib_suffix "" )
endif()
set ( LIB_SUFFIX ${_init_lib_suffix} CACHE STRING
"library directory name suffix (32/64/nothing)" )
mark_as_advanced ( LIB_SUFFIX )
# the default C standard to use for all targets
set(CMAKE_C_STANDARD 90)
@ -125,7 +133,6 @@ set(CMAKE_C_STANDARD 90)
set(CMAKE_CXX_STANDARD 98)
# whether to use gnu extensions
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Compile with position independent code if the user requested a shared lib, i.e. no PIC if static requested.
@ -142,11 +149,11 @@ if ( NOT OS2 )
endif ( NOT OS2 )
# enforce visibility control for all types of cmake targets
if ( POLICY CMP0063 ) # since version 3.3, CMake version 3.21.2 warns when the policy is not set and uses OLD behavior.
if ( POLICY CMP0063 )
cmake_policy ( SET CMP0063 NEW )
endif ( POLICY CMP0063 )
# Default install directory names, some provided by GNUInstallDirs
# Default install directory names
include ( DefaultDirs )
# Basic C library checks
@ -181,7 +188,6 @@ if ( NOT HAVE_LONG_LONG AND NOT MSVC)
message ( FATAL_ERROR "Your compiler does not support intrinsic type 'long long'. Unable to compile fluidsynth." )
endif ()
include ( CMakePrintHelpers ) # for cmake_print_properties() and cmake_print_variables()
include ( TestInline )
include ( TestVLA )
include ( TestBigEndian )
@ -194,12 +200,12 @@ unset ( FLUID_LIBS CACHE )
unset ( ENABLE_UBSAN CACHE )
if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "Intel" )
if ( NOT APPLE AND NOT OS2 AND NOT EMSCRIPTEN )
if ( NOT APPLE AND NOT OS2 )
set ( CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed" )
set ( CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" )
endif ( NOT APPLE AND NOT OS2 AND NOT EMSCRIPTEN )
endif ( NOT APPLE AND NOT OS2 )
# define some warning flags
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wno-unused-parameter -Wdeclaration-after-statement -Werror=implicit-function-declaration" )
@ -261,23 +267,23 @@ if ( WIN32 )
# windows-version is supposed to be non-official variable that can be used to tweak the Windows target version.
# Its value defaults to the Windows Version we are compiling for.
if ( NOT windows-version )
if(CMAKE_SYSTEM_VERSION EQUAL 10) # Windows 10
if(${CMAKE_SYSTEM_VERSION} EQUAL 10) # Windows 10
set ( windows-version "0x0A00" )
elseif(CMAKE_SYSTEM_VERSION EQUAL 6.3) # Windows 8.1
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.3) # Windows 8.1
set ( windows-version "0x0603" )
elseif(CMAKE_SYSTEM_VERSION EQUAL 6.2) # Windows 8
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.2) # Windows 8
set ( windows-version "0x0602" )
elseif(CMAKE_SYSTEM_VERSION EQUAL 6.1) # Windows 7
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.1) # Windows 7
set ( windows-version "0x0601" )
elseif(CMAKE_SYSTEM_VERSION EQUAL 6.0) # Windows Vista
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.0) # Windows Vista
set ( windows-version "0x0600" )
elseif(CMAKE_SYSTEM_VERSION EQUAL 5.1) # Windows XP
elseif(${CMAKE_SYSTEM_VERSION} EQUAL 5.1) # Windows XP
set ( windows-version "0x0501" )
else()
set ( windows-version "0x0400" )
endif()
endif ()
message ( STATUS "Targeting Windows Version ${windows-version}" )
message ( STATUS "Targetting Windows Version ${windows-version}" )
add_definitions ( -D _WIN32_WINNT=${windows-version} )
add_definitions ( -D WINVER=${windows-version} )
list ( APPEND CMAKE_REQUIRED_DEFINITIONS "-DWINVER=${windows-version}" )
@ -322,18 +328,10 @@ if ( WIN32 )
set ( CMAKE_DEBUG_POSTFIX "_debug" )
endif ( NOT MSVC )
if ( enable-static-msvcrt )
set ( CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" )
endif ( enable-static-msvcrt )
# MinGW compiler (a Windows GCC port)
if ( MINGW )
set ( MINGW32 1 )
add_compile_options ( -mms-bitfields )
# mman-win32
if ( HAVE_SYS_MMAN_H )
set ( WINDOWS_LIBS "${WINDOWS_LIBS};mman" )
endif ()
endif ( MINGW )
else ( WIN32 )
# Check PThreads, but not in Windows
@ -371,7 +369,7 @@ unset ( MACOSX_FRAMEWORK CACHE )
if ( CMAKE_SYSTEM MATCHES "Darwin" )
set ( DARWIN 1 )
set ( CMAKE_INSTALL_NAME_DIR
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} )
${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR} )
if ( enable-coreaudio )
check_include_file ( CoreAudio/AudioHardware.h COREAUDIO_FOUND )
if ( COREAUDIO_FOUND )
@ -414,15 +412,17 @@ if ( enable-profiling )
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPT_FLAGS}" )
find_program( CLANG_TIDY
NAMES "clang-tidy"
DOC "Path to clang-tidy executable" )
if ( CMAKE_VERSION VERSION_GREATER "3.6.0" )
find_program( CLANG_TIDY
NAMES "clang-tidy"
DOC "Path to clang-tidy executable" )
if ( CLANG_TIDY )
message ( STATUS "Found clang-tidy at ${CLANG_TIDY}" )
execute_process ( COMMAND ${CLANG_TIDY} "--version" )
set ( CMAKE_C_CLANG_TIDY ${CLANG_TIDY} )
endif ( CLANG_TIDY )
if ( CLANG_TIDY )
message ( STATUS "Found clang-tidy at ${CLANG_TIDY}" )
execute_process ( COMMAND ${CLANG_TIDY} "--version" )
set ( CMAKE_C_CLANG_TIDY ${CLANG_TIDY} )
endif ( CLANG_TIDY )
endif ( CMAKE_VERSION VERSION_GREATER "3.6.0" )
endif ( enable-profiling )
@ -440,6 +440,11 @@ if ( enable-fpe-check AND NOT APPLE AND NOT WIN32 )
set ( FPE_CHECK 1 )
endif ( enable-fpe-check AND NOT APPLE AND NOT WIN32 )
if ( enable-debug )
set ( CMAKE_BUILD_TYPE "Debug" CACHE STRING
"Choose the build type, options: Debug Release RelWithDebInfo MinSizeRel" FORCE )
endif ( enable-debug )
if ( NOT CMAKE_BUILD_TYPE )
set ( CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the build type, options: Debug Release RelWithDebInfo MinSizeRel" FORCE )
@ -456,13 +461,13 @@ endif ( CMAKE_BUILD_TYPE MATCHES "Debug" )
file(GLOB_RECURSE
ALL_SOURCE_FILES
LIST_DIRECTORIES false
${FluidSynth_SOURCE_DIR}/*.[chi]
${FluidSynth_SOURCE_DIR}/*.[chi]pp
${FluidSynth_SOURCE_DIR}/*.[chi]xx
${FluidSynth_SOURCE_DIR}/*.cc
${FluidSynth_SOURCE_DIR}/*.hh
${FluidSynth_SOURCE_DIR}/*.ii
${FluidSynth_SOURCE_DIR}/*.[CHI]
${CMAKE_SOURCE_DIR}/*.[chi]
${CMAKE_SOURCE_DIR}/*.[chi]pp
${CMAKE_SOURCE_DIR}/*.[chi]xx
${CMAKE_SOURCE_DIR}/*.cc
${CMAKE_SOURCE_DIR}/*.hh
${CMAKE_SOURCE_DIR}/*.ii
${CMAKE_SOURCE_DIR}/*.[CHI]
)
find_program ( ASTYLE "astyle" )
@ -482,236 +487,164 @@ if ( ASTYLE )
)
endif(ASTYLE)
if ( NOT WIN32 )
find_package ( PkgConfig REQUIRED )
if(NOT enable-pkgconfig)
# Mandatory libraries: glib and gthread
pkg_check_modules ( GLIB REQUIRED glib-2.0>=2.6.5 gthread-2.0>=2.6.5 IMPORTED_TARGET )
list( APPEND PC_REQUIRES_PRIV "glib-2.0" "gthread-2.0")
FIND_LIBRARY( GLIB_LIB NAMES glib glib-2.0 PATH GLIB_LIBRARY_DIR )
FIND_LIBRARY( GTHREAD_LIB NAMES gthread gthread-2.0 PATH GTHREAD_LIBRARY_DIR )
FIND_PATH( GLIBH_DIR glib.h PATH GLIB_INCLUDE_DIR )
FIND_PATH( GLIBCONF_DIR glibconfig.h PATH GLIBCONF_INCLUDE_DIR )
if ( GLIB_glib-2.0_VERSION AND GLIB_glib-2.0_VERSION VERSION_LESS "2.26.0" )
message ( WARNING "Your version of glib is very old. This may cause problems with fluidsynth's sample cache on Windows. Consider updating to glib 2.26 or newer!" )
endif ( GLIB_glib-2.0_VERSION AND GLIB_glib-2.0_VERSION VERSION_LESS "2.26.0" )
set ( WIN32_GLIBSTUBS OFF )
set ( WITH_GLIB_STUBS 0 )
else ( NOT WIN32 )
set ( WIN32_GLIBSTUBS ON )
set ( WITH_GLIB_STUBS 1 )
endif ( NOT WIN32 )
IF( GLIB_LIB MATCHES "GLIB_LIB-NOTFOUND" OR
GTHREAD_LIB MATCHES "GTHREAD_LIB-NOTFOUND" OR
GLIBH_DIR MATCHES "GLIBH_DIR-NOTFOUND" OR
GLIBCONF_DIR MATCHES "GLIBCONF_DIR-NOTFOUND")
message( WARNING "Not sure if I found GLIB, continuing anyway.")
ENDIF()
include ( PkgConfigHelpers ) # has unset_pkg_config()
SET( GLIB_INCLUDE_DIRS ${GLIBH_DIR} ${GLIBCONF_DIR} )
SET( GLIB_LIBRARIES ${GLIB_LIB} ${GTHREAD_LIB} )
if ( NOT PkgConfig_FOUND )
set ( enable-pulseaudio OFF )
set ( enable-alsa OFF )
set ( enable-portaudio OFF )
set ( enable-jack OFF )
set ( enable-pipewire OFF )
set ( enable-lash OFF )
set ( enable-systemd OFF )
set ( enable-dbus OFF )
set ( enable-ladspa OFF )
set ( enable-libinstpatch OFF )
set ( enable-sdl2 OFF )
set ( enable-oboe OFF )
set ( enable-readline OFF )
endif ( NOT PkgConfig_FOUND )
message( STATUS "GLIB_INCLUDE_DIRS: " ${GLIB_INCLUDE_DIRS} )
message( STATUS "GLIB_LIBRARIES: " ${GLIB_LIBRARIES} )
# Optional features
unset ( LIBSNDFILE_SUPPORT CACHE )
unset ( LIBSNDFILE_HASVORBIS CACHE )
if ( enable-libsndfile )
if ( PkgConfig_FOUND )
pkg_check_modules ( LIBSNDFILE sndfile>=1.0.0 IMPORTED_TARGET )
set ( LIBSNDFILE_SUPPORT ${LIBSNDFILE_FOUND} )
else ( PkgConfig_FOUND )
find_package(SndFile CONFIG)
set ( LIBSNDFILE_SUPPORT ${SNDFILE_FOUND} )
endif ( PkgConfig_FOUND)
if ( LIBSNDFILE_SUPPORT )
#[[ cmake_print_variables (
LIBSNDFILE_STATIC_LIBRARIES
LIBSNDFILE_STATIC_LINK_LIBRARIES
LIBSNDFILE_STATIC_LDFLAGS
LIBSNDFILE_STATIC_LDFLAGS_OTHER ) ]]
list( APPEND PC_REQUIRES_PRIV "sndfile")
if ( LIBSNDFILE_STATIC_LIBRARIES MATCHES "vorbis" OR
SndFile_WITH_EXTERNAL_LIBS OR
LIBSNDFILE_STATIC_LDFLAGS MATCHES "vorbis" OR
LIBSNDFILE_STATIC_LDFLAGS_OTHER MATCHES "vorbis" )
set ( LIBSNDFILE_HASVORBIS 1 )
else ()
message ( NOTICE "Seems like libsndfile was compiled without OGG/Vorbis support." )
endif ()
#[[ cmake_print_properties( TARGETS PkgConfig::LIBSNDFILE
PROPERTIES
INTERFACE_COMPILE_OPTIONS
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_LINK_OPTIONS
INTERFACE_LINK_LIBRARIES ) ]]
sanitize_target_dirs(PkgConfig::LIBSNDFILE)
endif ( LIBSNDFILE_SUPPORT )
else ( enable-libsndfile )
else(NOT enable-pkgconfig)
find_package ( PkgConfig REQUIRED )
# Mandatory libraries: glib and gthread
pkg_check_modules ( GLIB REQUIRED glib-2.0>=2.6.5 gthread-2.0>=2.6.5 )
if ( GLIB_glib-2.0_VERSION AND GLIB_glib-2.0_VERSION VERSION_LESS "2.26.0" )
message ( WARNING "Your version of glib is very old. This may cause problems with fluidsynth's sample cache on Windows. Consider updating to glib 2.26 or newer!" )
endif ( GLIB_glib-2.0_VERSION AND GLIB_glib-2.0_VERSION VERSION_LESS "2.26.0" )
include ( UnsetPkgConfig )
# Optional features
unset ( LIBSNDFILE_SUPPORT CACHE )
unset ( LIBSNDFILE_HASVORBIS CACHE )
if ( enable-libsndfile )
pkg_check_modules ( LIBSNDFILE sndfile>=1.0.0 )
set ( LIBSNDFILE_SUPPORT ${LIBSNDFILE_FOUND} )
if ( LIBSNDFILE_SUPPORT )
pkg_check_modules ( LIBSNDFILE_VORBIS sndfile>=1.0.18 )
set ( LIBSNDFILE_HASVORBIS ${LIBSNDFILE_VORBIS_FOUND} )
endif ( LIBSNDFILE_SUPPORT )
else ( enable-libsndfile )
unset_pkg_config ( LIBSNDFILE )
unset_pkg_config ( LIBSNDFILE_VORBIS )
endif ( enable-libsndfile )
endif ( enable-libsndfile )
unset ( PULSE_SUPPORT CACHE )
if ( enable-pulseaudio )
pkg_check_modules ( PULSE libpulse-simple>=0.9.8 IMPORTED_TARGET )
unset ( PULSE_SUPPORT CACHE )
if ( enable-pulseaudio )
pkg_check_modules ( PULSE libpulse-simple>=0.9.8 )
set ( PULSE_SUPPORT ${PULSE_FOUND} )
if ( PULSE_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "libpulse-simple")
endif ( PULSE_SUPPORT )
else ( enable-pulseaudio )
else ( enable-pulseaudio )
unset_pkg_config ( PULSE )
endif ( enable-pulseaudio )
endif ( enable-pulseaudio )
unset ( ALSA_SUPPORT CACHE )
if ( enable-alsa )
pkg_check_modules ( ALSA alsa>=0.9.1 IMPORTED_TARGET )
unset ( ALSA_SUPPORT CACHE )
if ( enable-alsa )
pkg_check_modules ( ALSA alsa>=0.9.1 )
set ( ALSA_SUPPORT ${ALSA_FOUND} )
if ( ALSA_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "alsa")
endif ( ALSA_SUPPORT )
else ( enable-alsa )
else ( enable-alsa )
unset_pkg_config ( ALSA )
endif ( enable-alsa )
endif ( enable-alsa )
unset ( PORTAUDIO_SUPPORT CACHE )
if ( enable-portaudio )
pkg_check_modules ( PORTAUDIO portaudio-2.0>=19 IMPORTED_TARGET )
unset ( PORTAUDIO_SUPPORT CACHE )
if ( enable-portaudio )
pkg_check_modules ( PORTAUDIO portaudio-2.0>=19 )
set ( PORTAUDIO_SUPPORT ${PORTAUDIO_FOUND} )
if ( PORTAUDIO_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "portaudio-2.0")
endif ()
else ( enable-portaudio )
else ( enable-portaudio )
unset_pkg_config ( PORTAUDIO )
endif ( enable-portaudio )
endif ( enable-portaudio )
unset ( JACK_SUPPORT CACHE )
if ( enable-jack )
pkg_check_modules ( JACK jack IMPORTED_TARGET )
unset ( JACK_SUPPORT CACHE )
if ( enable-jack )
pkg_check_modules ( JACK jack )
set ( JACK_SUPPORT ${JACK_FOUND} )
if (JACK_SUPPORT)
sanitize_target_dirs(PkgConfig::JACK)
list( APPEND PC_REQUIRES_PRIV "jack")
endif()
else ( enable-jack )
else ( enable-jack )
unset_pkg_config ( JACK )
endif ( enable-jack )
endif ( enable-jack )
unset ( PIPEWIRE_SUPPORT CACHE )
if ( enable-pipewire )
pkg_check_modules ( PIPEWIRE libpipewire-0.3 IMPORTED_TARGET )
set ( PIPEWIRE_SUPPORT ${PIPEWIRE_FOUND} )
if ( PIPEWIRE_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "libpipewire-0.3")
endif()
else ( enable-pipewire )
unset_pkg_config ( PIPEWIRE )
endif ( enable-pipewire )
unset ( LASH_SUPPORT CACHE )
if ( enable-lash )
pkg_check_modules ( LASH lash-1.0>=0.3 IMPORTED_TARGET )
unset ( LASH_SUPPORT CACHE )
if ( enable-lash )
pkg_check_modules ( LASH lash-1.0>=0.3 )
if ( LASH_FOUND )
set ( LASH_SUPPORT 1 )
add_definitions ( -DHAVE_LASH )
sanitize_target_dirs(PkgConfig::LASH)
list( APPEND PC_REQUIRES_PRIV "lash-1.0")
endif ( LASH_FOUND )
else ( enable-lash )
else ( enable-lash )
unset_pkg_config ( LASH )
remove_definitions( -DHAVE_LASH )
endif ( enable-lash )
endif ( enable-lash )
unset ( SYSTEMD_SUPPORT CACHE )
if ( enable-systemd )
pkg_check_modules ( SYSTEMD libsystemd IMPORTED_TARGET )
set ( SYSTEMD_SUPPORT ${SYSTEMD_FOUND} )
if ( SYSTEMD_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "libsystemd")
endif ( SYSTEMD_SUPPORT )
else ( enable-systemd )
unset_pkg_config ( SYSTEMD )
endif ( enable-systemd )
unset ( SYSTEMD_SUPPORT CACHE )
if ( enable-systemd )
pkg_check_modules ( SYSTEMD libsystemd )
set ( SYSTEMD_SUPPORT ${SYSTEMD_FOUND} )
else ( enable-systemd )
unset_pkg_config ( SYSTEMD )
endif ( enable-systemd )
unset ( DBUS_SUPPORT CACHE )
if ( enable-dbus )
pkg_check_modules ( DBUS dbus-1>=1.0.0 IMPORTED_TARGET )
set ( DBUS_SUPPORT ${DBUS_FOUND} )
if ( DBUS_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "dbus-1")
endif ()
else ( enable-dbus )
unset ( DBUS_SUPPORT CACHE )
if ( enable-dbus )
pkg_check_modules ( DBUS dbus-1>=1.0.0 )
set ( DBUS_SUPPORT ${DBUS_FOUND} )
else ( enable-dbus )
unset_pkg_config ( DBUS )
endif ( enable-dbus )
endif ( enable-dbus )
unset ( LADSPA_SUPPORT CACHE )
if ( enable-ladspa )
check_include_file ( ladspa.h LADSPA_SUPPORT )
if ( LADSPA_SUPPORT )
pkg_check_modules ( GMODULE REQUIRED gmodule-2.0>=2.6.5 IMPORTED_TARGET )
set ( LADSPA 1 )
list( APPEND PC_REQUIRES_PRIV "gmodule-2.0")
endif ( LADSPA_SUPPORT )
endif ( enable-ladspa )
unset ( LADSPA_SUPPORT CACHE )
if ( enable-ladspa )
check_include_file ( ladspa.h LADSPA_SUPPORT )
if ( LADSPA_SUPPORT )
pkg_check_modules ( GMODULE REQUIRED gmodule-2.0>=2.6.5 )
set ( LADSPA 1 )
endif ( LADSPA_SUPPORT )
endif ( enable-ladspa )
unset ( LIBINSTPATCH_SUPPORT CACHE )
if ( enable-libinstpatch )
pkg_check_modules ( LIBINSTPATCH libinstpatch-1.0>=1.1.0 IMPORTED_TARGET )
set ( LIBINSTPATCH_SUPPORT ${LIBINSTPATCH_FOUND} )
if ( LIBINSTPATCH_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "libinstpatch-1.0")
#[[ cmake_print_properties( TARGETS PkgConfig::LIBINSTPATCH
PROPERTIES
INTERFACE_COMPILE_OPTIONS
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_LINK_DIRECTORIES
INTERFACE_LINK_OPTIONS
INTERFACE_LINK_LIBRARIES ) ]]
sanitize_target_dirs(PkgConfig::LIBINSTPATCH)
endif (LIBINSTPATCH_SUPPORT )
endif ( enable-libinstpatch )
unset ( LIBINSTPATCH_SUPPORT CACHE )
if ( enable-libinstpatch )
pkg_check_modules ( LIBINSTPATCH libinstpatch-1.0>=1.1.0 )
set ( LIBINSTPATCH_SUPPORT ${LIBINSTPATCH_FOUND} )
endif ( enable-libinstpatch )
unset ( SDL2_SUPPORT CACHE )
if ( enable-sdl2 )
pkg_check_modules ( SDL2 sdl2>=2.0.4 IMPORTED_TARGET )
set ( SDL2_SUPPORT ${SDL2_FOUND} )
if ( SDL2_SUPPORT )
list( APPEND PC_REQUIRES_PRIV "sdl2")
endif ( SDL2_SUPPORT )
else ( enable-sdl2 )
unset_pkg_config ( SDL2 )
endif ( enable-sdl2 )
unset ( SDL2_SUPPORT CACHE )
if ( enable-sdl2 )
pkg_check_modules ( SDL2 sdl2 )
set ( SDL2_SUPPORT ${SDL2_FOUND} )
else ( enable-sdl2 )
unset_pkg_config ( SDL2 )
endif ( enable-sdl2 )
unset ( OBOE_SUPPORT CACHE )
if ( enable-oboe )
pkg_check_modules ( OBOE oboe-1.0 IMPORTED_TARGET )
if ( OBOE_FOUND )
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set ( OBOE_SUPPORT 1 )
list( APPEND PC_REQUIRES_PRIV "oboe-1.0")
endif ( OBOE_FOUND )
endif ( enable-oboe )
unset ( OBOE_SUPPORT CACHE )
unset ( OBOE_LIBS CACHE )
if ( enable-oboe )
pkg_check_modules ( OBOE oboe-1.0 )
if ( OBOE_FOUND )
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set ( OBOE_SUPPORT 1 )
set ( OBOE_LIBS ${OBOE_LIBRARIES} )
endif ( OBOE_FOUND )
endif ( enable-oboe )
unset ( WITH_READLINE CACHE )
unset ( READLINE_LIBS CACHE )
if ( enable-readline )
pkg_check_modules ( READLINE readline QUIET IMPORTED_TARGET )
if ( READLINE_FOUND )
list( APPEND PC_REQUIRES_PRIV "readline")
else ( READLINE_FOUND )
find_package ( READLINE )
set ( READLINE_FOUND ${HAVE_READLINE} )
endif ( READLINE_FOUND )
if ( READLINE_FOUND )
set ( WITH_READLINE 1 )
set ( READLINE_LIBS ${READLINE_LIBRARIES} )
endif ( READLINE_FOUND )
endif ( enable-readline )
unset ( WITH_READLINE CACHE )
unset ( READLINE_LIBS CACHE )
if ( enable-readline )
pkg_check_modules ( READLINE readline )
if ( NOT READLINE_FOUND )
find_package ( READLINE )
set ( READLINE_FOUND ${HAVE_READLINE} )
endif ( NOT READLINE_FOUND )
if ( READLINE_FOUND )
set ( WITH_READLINE 1 )
set ( READLINE_LIBS ${READLINE_LIBRARIES} )
endif ( READLINE_FOUND )
endif ( enable-readline )
endif(NOT enable-pkgconfig)
unset ( AUFILE_SUPPORT CACHE )
if ( enable-aufile )
@ -756,27 +689,24 @@ endif ( enable-threads )
unset ( HAVE_OPENMP CACHE )
find_package ( OpenMP QUIET )
if (enable-openmp AND ( OpenMP_FOUND OR OpenMP_C_FOUND ) )
message(STATUS "Found OpenMP version: ${OpenMP_C_VERSION} date: ${OpenMP_C_SPEC_DATE}")
if ( TARGET OpenMP::OpenMP_C AND (( NOT OpenMP_C_SPEC_DATE LESS "201307" ) OR NOT ( OpenMP_C_VERSION VERSION_LESS "4.0" )) )
#[[ cmake_print_properties( TARGETS OpenMP::OpenMP_C
PROPERTIES
INTERFACE_COMPILE_OPTIONS
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_LINK_OPTIONS
INTERFACE_LINK_LIBRARIES ) ]]
set ( HAVE_OPENMP 1 )
else()
message(STATUS " OpenMP version is not supported. Feature disabled.")
if ( OpenMP_FOUND OR OpenMP_C_FOUND )
message(STATUS "Found OpenMP ${OpenMP_C_SPEC_DATE}")
# require at least OMP 4.0
if ( ( NOT OpenMP_C_SPEC_DATE LESS "201307" ) OR NOT ( OpenMP_C_VERSION VERSION_LESS "4.0" ) )
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" )
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" )
# currently no need to link against openMP runtime lib(s). If need be, uncomment below.
# set ( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}" )
# set ( LIBFLUID_LIBS "${OpenMP_C_LIBRARIES};${LIBFLUID_LIBS}" )
set ( HAVE_OPENMP 1 )
endif()
endif()
# manipulate some variables to setup a proper test env
set(TEST_SOUNDFONT "${FluidSynth_SOURCE_DIR}/sf2/VintageDreamsWaves-v2.sf2")
set(TEST_SOUNDFONT_UTF8_1 "${FluidSynth_SOURCE_DIR}/sf2/\\xE2\\x96\\xA0VintageDreamsWaves-v2\\xE2\\x96\\xA0.sf2")
set(TEST_SOUNDFONT_UTF8_2 "${FluidSynth_SOURCE_DIR}/sf2/VìntàgèDrèàmsWàvès-v2.sf2")
set(TEST_SOUNDFONT_SF3 "${FluidSynth_SOURCE_DIR}/sf2/VintageDreamsWaves-v2.sf3")
set(TEST_MIDI_UTF8 "${FluidSynth_SOURCE_DIR}/test/èmpty.mid")
set(TEST_SOUNDFONT "${CMAKE_SOURCE_DIR}/sf2/VintageDreamsWaves-v2.sf2")
set(TEST_SOUNDFONT_UTF8 "${CMAKE_SOURCE_DIR}/sf2/\\xE2\\x96\\xA0VintageDreamsWaves-v2\\xE2\\x96\\xA0.sf2")
set(TEST_SOUNDFONT_SF3 "${CMAKE_SOURCE_DIR}/sf2/VintageDreamsWaves-v2.sf3")
# Make sure to link against libm before checking for math functions below
set ( CMAKE_REQUIRED_LIBRARIES "${LIBFLUID_LIBS};${WINDOWS_LIBS}" )
@ -832,22 +762,25 @@ if ( enable-ipv6 )
endif ( HAVE_INETNTOP )
endif ( enable-ipv6 )
unset ( HAVE_SOCKLEN_T CACHE )
set ( CMAKE_EXTRA_INCLUDE_FILES_SAVE ${CMAKE_EXTRA_INCLUDE_FILES} )
if ( WIN32 )
set ( CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;ws2tcpip.h" )
else ( WIN32 )
set ( CMAKE_EXTRA_INCLUDE_FILES sys/socket.h )
endif ( WIN32 )
check_type_size ( socklen_t SOCKLEN_T )
set ( CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES_SAVE} )
if ( HAVE_SOCKLEN_T )
set ( HAVE_SOCKLEN_T 1 )
endif ( HAVE_SOCKLEN_T )
# General configuration file
configure_file ( ${FluidSynth_SOURCE_DIR}/src/config.cmake
${FluidSynth_BINARY_DIR}/config.h )
configure_file ( ${CMAKE_SOURCE_DIR}/src/config.cmake
${CMAKE_BINARY_DIR}/config.h )
# Setup linker directories NOW, as the command will apply only to targets created after it has been called.
link_directories (
${GLIB_LIBRARY_DIRS}
${LASH_LIBRARY_DIRS}
${JACK_LIBRARY_DIRS}
${ALSA_LIBRARY_DIRS}
${PULSE_LIBRARY_DIRS}
${PORTAUDIO_LIBRARY_DIRS}
${LIBSNDFILE_LIBRARY_DIRS}
${DBUS_LIBRARY_DIRS}
${SDL2_LIBRARY_DIRS}
${OBOE_LIBRARY_DIRS}
${LIBINSTPATCH_LIBRARY_DIRS}
)
# required to allow ctest to be called from top-level build directory
ENABLE_TESTING()
@ -860,66 +793,61 @@ add_subdirectory ( doc )
# pkg-config support
set ( prefix "${CMAKE_INSTALL_PREFIX}" )
set ( exec_prefix "\${prefix}" )
if ( IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}" )
set ( libdir "${CMAKE_INSTALL_LIBDIR}" )
if ( IS_ABSOLUTE "${LIB_INSTALL_DIR}" )
set ( libdir "${LIB_INSTALL_DIR}" )
else ()
set ( libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}" )
set ( libdir "\${exec_prefix}/${LIB_INSTALL_DIR}" )
endif ()
if ( IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}" )
set ( includedir "${CMAKE_INSTALL_INCLUDEDIR}" )
if ( IS_ABSOLUTE "${INCLUDE_INSTALL_DIR}" )
set ( includedir "${INCLUDE_INSTALL_DIR}" )
else ()
set ( includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}" )
set ( includedir "\${prefix}/${INCLUDE_INSTALL_DIR}" )
endif ()
if ( PkgConfig_FOUND )
generate_pkgconfig_spec(fluidsynth.pc.in ${FluidSynth_BINARY_DIR}/fluidsynth.pc libfluidsynth-OBJ)
install ( FILES ${FluidSynth_BINARY_DIR}/fluidsynth.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig )
endif(PkgConfig_FOUND)
# Exported targets for cmake: find_package(FluidSynth)
# when installed, use CMAKE_PREFIX_PATH=fluidsynth-prefix;...
# to use the build directory directly set the FluidSynth_DIR variable instead.
# targets in the build directory
export(EXPORT FluidSynthTargets
FILE "${FluidSynth_BINARY_DIR}/FluidSynthTargets.cmake"
NAMESPACE FluidSynth::
)
include(CMakePackageConfigHelpers) # SameMinorVersion requires CMake 3.11
write_basic_package_version_file(
FluidSynthConfigVersion.cmake
VERSION ${VERSION}
COMPATIBILITY SameMinorVersion
)
# Here, configure_file() is used instead of the more orthodox macro
# configure_package_config_file() because the latter does not
# support generating a config.cmake file for both the installed
# package and for using the build directory directly.
configure_file(FluidSynthConfig.cmake.in FluidSynthConfig.cmake @ONLY)
install(FILES "${FluidSynth_BINARY_DIR}/FluidSynthConfig.cmake"
"${FluidSynth_BINARY_DIR}/FluidSynthConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/fluidsynth
)
configure_file ( fluidsynth.pc.in
${CMAKE_BINARY_DIR}/fluidsynth.pc IMMEDIATE @ONLY )
install ( FILES ${CMAKE_BINARY_DIR}/fluidsynth.pc
DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
# Extra targets for Unix build environments
if ( UNIX )
# RPM spec
configure_file ( fluidsynth.spec.in
${CMAKE_BINARY_DIR}/fluidsynth.spec IMMEDIATE @ONLY )
if ( DEFINED FLUID_DAEMON_ENV_FILE)
configure_file ( fluidsynth.service.in
${FluidSynth_BINARY_DIR}/fluidsynth.service @ONLY )
${CMAKE_BINARY_DIR}/fluidsynth.service @ONLY )
configure_file ( fluidsynth.conf.in
${FluidSynth_BINARY_DIR}/fluidsynth.conf @ONLY )
${CMAKE_BINARY_DIR}/fluidsynth.conf @ONLY )
endif ( DEFINED FLUID_DAEMON_ENV_FILE )
# uninstall custom target
configure_file ( "${FluidSynth_SOURCE_DIR}/cmake_admin/cmake_uninstall.cmake.in"
"${FluidSynth_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
configure_file ( "${CMAKE_SOURCE_DIR}/cmake_admin/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
add_custom_target ( uninstall
"${CMAKE_COMMAND}" -P "${FluidSynth_BINARY_DIR}/cmake_uninstall.cmake")
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
# tarball custom target
add_custom_target ( tarball
COMMAND mkdir -p ${PACKAGE}-${VERSION}
COMMAND cp -r bindings ${PACKAGE}-${VERSION}
COMMAND cp -r cmake_admin ${PACKAGE}-${VERSION}
COMMAND cp -r doc ${PACKAGE}-${VERSION}
COMMAND cp -r include ${PACKAGE}-${VERSION}
COMMAND cp -r src ${PACKAGE}-${VERSION}
COMMAND cp AUTHORS ChangeLog CMakeLists.txt LICENSE ${PACKAGE}.* INSTALL NEWS README* THANKS TODO ${PACKAGE}-${VERSION}
# COMMAND tar -cj --exclude .svn --exclude Makefile.am -f ${PACKAGE}-${VERSION}.tar.bz2 ${PACKAGE}-${VERSION}
# COMMAND tar -cz --exclude .svn --exclude Makefile.am -f ${PACKAGE}-${VERSION}.tar.gz ${PACKAGE}-${VERSION}
# COMMAND zip -qr ${PACKAGE}-${VERSION}.zip ${PACKAGE}-${VERSION} -x '*.svn*' -x '*Makefile.am'
COMMAND tar -cj --exclude .svn -f ${PACKAGE}-${VERSION}.tar.bz2 ${PACKAGE}-${VERSION}
COMMAND tar -cz --exclude .svn -f ${PACKAGE}-${VERSION}.tar.gz ${PACKAGE}-${VERSION}
COMMAND zip -qr ${PACKAGE}-${VERSION}.zip ${PACKAGE}-${VERSION} -x '*.svn*'
COMMAND rm -rf ${PACKAGE}-${VERSION}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif ( UNIX )
include ( report )
@ -927,8 +855,8 @@ include ( report )
# CPack support
set ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "FluidSynth real-time synthesizer" )
set ( CPACK_PACKAGE_VENDOR "fluidsynth.org" )
set ( CPACK_PACKAGE_DESCRIPTION_FILE "${FluidSynth_SOURCE_DIR}/README.md" )
set ( CPACK_RESOURCE_FILE_LICENSE "${FluidSynth_SOURCE_DIR}/LICENSE" )
set ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" )
set ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE" )
set ( CPACK_PACKAGE_VERSION_MAJOR ${FLUIDSYNTH_VERSION_MAJOR} )
set ( CPACK_PACKAGE_VERSION_MINOR ${FLUIDSYNTH_VERSION_MINOR} )
set ( CPACK_PACKAGE_VERSION_PATCH ${FLUIDSYNTH_VERSION_MICRO} )

View file

@ -1,10 +0,0 @@
# for the find_dependency() macro:
# include(CMakeFindDependencyMacro)
# it has the same syntax as find_package:
# find_dependency(MYDEP REQUIRED)
# define variables for configuration options:
# set(network-enabled @enable-network@)
# finally, include the targets file
include("${CMAKE_CURRENT_LIST_DIR}/FluidSynthTargets.cmake")

View file

@ -8,6 +8,8 @@
| <img src="https://www.microsoft.com/windows/favicon.ico" height="25" alt=""> **Windows (vcpkg)** | [![Build Status](https://dev.azure.com/tommbrt/tommbrt/_apis/build/status/FluidSynth.fluidsynth.vcpkg?branchName=master)](https://dev.azure.com/tommbrt/tommbrt/_build/latest?definitionId=6&branchName=master) |
| <img src="https://www.apple.com/favicon.ico" height="30" alt=""> **MacOSX** | [![Build Status](https://dev.azure.com/tommbrt/tommbrt/_apis/build/status/FluidSynth.fluidsynth.macOS?branchName=master)](https://dev.azure.com/tommbrt/tommbrt/_build/latest?definitionId=5&branchName=master) |
| <img src="https://www.android.com/favicon.ico" height="30" alt=""> **Android** | [![Build Status](https://dev.azure.com/tommbrt/tommbrt/_apis/build/status/FluidSynth.fluidsynth.Android?branchName=master)](https://dev.azure.com/tommbrt/tommbrt/_build/latest?definitionId=4&branchName=master) |
| <img src="https://www.android.com/favicon.ico" height="30" alt=""> **Android** (legacy Cerbero) | [![CircleCI](https://circleci.com/gh/FluidSynth/fluidsynth/tree/master.svg?style=shield)](https://circleci.com/gh/FluidSynth/fluidsynth) |
#### FluidSynth is a cross-platform, real-time software synthesizer based on the Soundfont 2 specification.

View file

@ -1,56 +1,92 @@
# Provides install directory variables as defined by the GNU Coding Standards
include ( GNUInstallDirs )
# Several directory names used by FluidSynth to install files
# the variable names are similar to the KDE4 build system
# DEFAULT_SOUNDFONT - automatically loaded in some use cases
if ( WIN32 )
set (DEFAULT_SOUNDFONT "C:\\\\ProgramData\\\\soundfonts\\\\default.sf2" CACHE STRING
set (DEFAULT_SOUNDFONT "C:\\\\soundfonts\\\\default.sf2" CACHE STRING
"Default soundfont file")
else ( WIN32 )
set (DEFAULT_SOUNDFONT "${CMAKE_INSTALL_FULL_DATADIR}/soundfonts/default.sf2" CACHE STRING
set (DEFAULT_SOUNDFONT "${CMAKE_INSTALL_PREFIX}/share/soundfonts/default.sf2" CACHE STRING
"Default soundfont file")
endif ( WIN32 )
mark_as_advanced (DEFAULT_SOUNDFONT)
set(FRAMEWORK_INSTALL_PREFIX "")
if ( CMAKE_VERSION VERSION_GREATER "3.7.0" AND NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT )
set(FRAMEWORK_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
endif()
# BUNDLE_INSTALL_DIR - Mac only: the directory for application bundles
set (BUNDLE_INSTALL_DIR "Applications" CACHE STRING
set (BUNDLE_INSTALL_DIR "/Applications" CACHE STRING
"The install dir for application bundles")
mark_as_advanced (BUNDLE_INSTALL_DIR)
# FRAMEWORK_INSTALL_DIR - Mac only: the directory for framework bundles
set (FRAMEWORK_INSTALL_DIR "Library/Frameworks" CACHE STRING
set (FRAMEWORK_INSTALL_DIR "/Library/Frameworks" CACHE STRING
"The install dir for framework bundles")
mark_as_advanced (FRAMEWORK_INSTALL_DIR)
mark_as_advanced (FRAMEWORK_INSTALL_DIR)
# BIN_INSTALL_DIR - the directory where executables will be installed
set (BIN_INSTALL_DIR "bin" CACHE STRING "The install dir for executables")
mark_as_advanced (BIN_INSTALL_DIR)
# SBIN_INSTALL_DIR - the directory where system executables will be installed
set (SBIN_INSTALL_DIR "sbin" CACHE STRING
"The install dir for system executables")
mark_as_advanced (SBIN_INSTALL_DIR)
# LIB_INSTALL_DIR - the directory where libraries will be installed
set (LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE STRING "The install dir for libraries")
mark_as_advanced (LIB_INSTALL_DIR)
# INCLUDE_INSTALL_DIR - the install dir for header files
set (INCLUDE_INSTALL_DIR "include" CACHE STRING "The install dir for headers")
mark_as_advanced (INCLUDE_INSTALL_DIR)
# DATA_INSTALL_DIR - the base install directory for data files
set (DATA_INSTALL_DIR "share" CACHE STRING
"The base install dir for data files")
mark_as_advanced (DATA_INSTALL_DIR)
# DOC_INSTALL_DIR - the install dir for documentation
set (DOC_INSTALL_DIR "share/doc" CACHE STRING
"The install dir for documentation")
mark_as_advanced (DOC_INSTALL_DIR)
# INFO_INSTALL_DIR - the info install dir
set (INFO_INSTALL_DIR "share/info" CACHE STRING "The info install dir")
mark_as_advanced (INFO_INSTALL_DIR)
# MAN_INSTALL_DIR - the man pages install dir
if ( CMAKE_SYSTEM_NAME MATCHES "FreeBSD|DragonFly")
set (MAN_INSTALL_DIR "man/man1" CACHE STRING "The man pages install dir")
else()
set (MAN_INSTALL_DIR "share/man/man1" CACHE STRING "The man pages install dir")
endif()
mark_as_advanced (MAN_INSTALL_DIR)
# SYSCONF_INSTALL_DIR - the config file install dir
set (SYSCONF_INSTALL_DIR "/etc" CACHE PATH
"The sysconfig install dir")
mark_as_advanced (SYSCONF_INSTALL_DIR)
# XDG_APPS_INSTALL_DIR - the XDG apps dir, where .desktop files are installed
set (XDG_APPS_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/applications" CACHE STRING "The XDG apps dir")
set (XDG_APPS_INSTALL_DIR "share/applications" CACHE STRING "The XDG apps dir")
mark_as_advanced (XDG_APPS_INSTALL_DIR)
# XDG_MIME_INSTALL_DIR - the XDG mimetypes install dir
set (XDG_MIME_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/mime/packages" CACHE STRING
set (XDG_MIME_INSTALL_DIR "share/mime/packages" CACHE STRING
"The install dir for the xdg mimetypes")
mark_as_advanced (XDG_MIME_INSTALL_DIR)
# DBUS_INTERFACES_INSTALL_DIR - the directory where dbus interfaces are
# installed
set (DBUS_INTERFACES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/dbus-1/interfaces" CACHE STRING
set (DBUS_INTERFACES_INSTALL_DIR "share/dbus-1/interfaces" CACHE STRING
"The dbus interfaces install dir")
mark_as_advanced (DBUS_INTERFACES_INSTALL_DIR)
# DBUS_SERVICES_INSTALL_DIR - the directory where dbus services are installed
set (DBUS_SERVICES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/dbus-1/services" CACHE STRING
set (DBUS_SERVICES_INSTALL_DIR "share/dbus-1/services" CACHE STRING
"The dbus services install dir")
mark_as_advanced (DBUS_SERVICES_INSTALL_DIR)
# DBUS_SYSTEM_SERVICES_INSTALL_DIR - the directory where dbus system services
# are installed
set (DBUS_SYSTEM_SERVICES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/dbus-1/system-services"
set (DBUS_SYSTEM_SERVICES_INSTALL_DIR "share/dbus-1/system-services"
CACHE STRING "The dbus system services install dir")
mark_as_advanced (DBUS_SYSTEM_SERVICES_INSTALL_DIR)

View file

@ -1,5 +1,5 @@
macro ( ADD_FLUID_TEST _test )
add_executable( ${_test} ${_test}.c )
ADD_EXECUTABLE(${_test} ${_test}.c $<TARGET_OBJECTS:libfluidsynth-OBJ> )
# only build this unit test when explicitly requested by "make check"
set_target_properties(${_test} PROPERTIES EXCLUDE_FROM_ALL TRUE)
@ -8,7 +8,7 @@ macro ( ADD_FLUID_TEST _test )
if ( FLUID_CPPFLAGS )
set_target_properties ( ${_test} PROPERTIES COMPILE_FLAGS ${FLUID_CPPFLAGS} )
endif ( FLUID_CPPFLAGS )
target_link_libraries( ${_test} libfluidsynth-OBJ )
TARGET_LINK_LIBRARIES(${_test} $<TARGET_PROPERTY:libfluidsynth,INTERFACE_LINK_LIBRARIES>)
# use the local include path to look for fluidsynth.h, as we cannot be sure fluidsynth is already installed
target_include_directories(${_test}
@ -16,7 +16,7 @@ macro ( ADD_FLUID_TEST _test )
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include> # include auto generated headers
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> # include "normal" public (sub-)headers
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src> # include private headers
$<TARGET_PROPERTY:libfluidsynth-OBJ,INCLUDE_DIRECTORIES> # include all other header search paths needed by libfluidsynth (esp. glib)
$<TARGET_PROPERTY:libfluidsynth,INCLUDE_DIRECTORIES> # include all other header search paths needed by libfluidsynth (esp. glib)
)
# add the test to ctest
@ -28,7 +28,7 @@ macro ( ADD_FLUID_TEST _test )
endmacro ( ADD_FLUID_TEST )
macro ( ADD_FLUID_TEST_UTIL _util )
add_executable( ${_util} ${_util}.c )
ADD_EXECUTABLE(${_util} ${_util}.c $<TARGET_OBJECTS:libfluidsynth-OBJ> )
# only build this unit test when explicitly requested by "make check"
set_target_properties(${_util} PROPERTIES EXCLUDE_FROM_ALL TRUE)
@ -40,7 +40,7 @@ macro ( ADD_FLUID_TEST_UTIL _util )
if ( FLUID_CPPFLAGS )
set_target_properties ( ${_util} PROPERTIES COMPILE_FLAGS ${FLUID_CPPFLAGS} )
endif ( FLUID_CPPFLAGS )
target_link_libraries( ${_util} libfluidsynth-OBJ )
TARGET_LINK_LIBRARIES(${_util} $<TARGET_PROPERTY:libfluidsynth,INTERFACE_LINK_LIBRARIES>)
# use the local include path to look for fluidsynth.h, as we cannot be sure fluidsynth is already installed
target_include_directories(${_util}
@ -48,7 +48,7 @@ macro ( ADD_FLUID_TEST_UTIL _util )
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include> # include auto generated headers
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> # include "normal" public (sub-)headers
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src> # include private headers
$<TARGET_PROPERTY:libfluidsynth-OBJ,INCLUDE_DIRECTORIES> # include all other header search paths needed by libfluidsynth (esp. glib)
$<TARGET_PROPERTY:libfluidsynth,INCLUDE_DIRECTORIES> # include all other header search paths needed by libfluidsynth (esp. glib)
)
# append the current unit test to check-target as dependency

View file

@ -1,75 +0,0 @@
macro ( sanitize_property_dirs target property )
set(_cleandirs)
get_target_property(_dirs ${target} ${property})
if(_dirs)
foreach(_d IN LISTS _dirs)
if(EXISTS ${_d})
list(APPEND _cleandirs ${_d})
else()
message(DEBUG "removing spurious directory ${_d} from property ${property} of target ${target}")
endif()
endforeach()
set_property(TARGET ${target} PROPERTY ${property} ${_cleandirs})
endif()
endmacro ( sanitize_property_dirs )
macro ( sanitize_target_dirs target )
if (TARGET ${target})
message(DEBUG "performing sanitize_target_dirs(${target})")
sanitize_property_dirs( ${target} INTERFACE_INCLUDE_DIRECTORIES )
sanitize_property_dirs( ${target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES )
sanitize_property_dirs( ${target} INTERFACE_LINK_DIRECTORIES )
endif()
endmacro ( sanitize_target_dirs )
macro ( generate_pkgconfig_spec template outfile target )
#message(DEBUG "generate_pkgconfig_spec: ${outfile} from template: ${template}")
if (TARGET ${target})
# retrieve all the private libs we depend on
get_target_property (_libs ${target} INTERFACE_LINK_LIBRARIES)
set(_cleanlibs)
foreach(_lib IN LISTS _libs)
if (TARGET ${_lib})
# All the imported PkgConfig target are explicitly added to PC_REQUIRES_PRIV.
# Do not duplicate them into the Libs.private section, as they will be already part of Requires.private
else()
list(APPEND _cleanlibs ${_lib})
endif()
endforeach()
list(REMOVE_DUPLICATES _cleanlibs)
set (LIBS_PRIVATE ${_cleanlibs})
# make a copy
set ( LIBS_PRIVATE_WITH_PATH ${LIBS_PRIVATE} )
# this matches any path and any flag entries (starting with '-')
set ( LIB_LIST_REGEX "(^(.+)\/([^\/]+)$)|(^\-.*$)" )
# remove all entries from the list which are specified by path and which already have -l
list ( FILTER LIBS_PRIVATE EXCLUDE REGEX ${LIB_LIST_REGEX} )
# include only entries specifed by path
list ( FILTER LIBS_PRIVATE_WITH_PATH INCLUDE REGEX ${LIB_LIST_REGEX} )
# prepend the linker flag to all entries except the ones that already have it
list ( TRANSFORM LIBS_PRIVATE PREPEND "-l")
list ( JOIN LIBS_PRIVATE " " LIBS_PRIVATE_JOINED )
list ( JOIN LIBS_PRIVATE_WITH_PATH " " LIBS_PRIVATE_WITH_PATH_JOINED )
list ( JOIN PC_REQUIRES_PRIV " " PC_REQUIRES_PRIV_JOINED )
configure_file ( ${template} ${outfile} IMMEDIATE @ONLY)
endif()
endmacro ( generate_pkgconfig_spec )
macro ( unset_pkg_config _prefix )
unset ( ${_prefix}_VERSION CACHE )
unset ( ${_prefix}_PREFIX CACHE )
unset ( ${_prefix}_CFLAGS CACHE )
unset ( ${_prefix}_CFLAGS_OTHER CACHE )
unset ( ${_prefix}_LDFLAGS CACHE )
unset ( ${_prefix}_LDFLAGS_OTHER CACHE )
unset ( ${_prefix}_LIBRARIES CACHE )
unset ( ${_prefix}_INCLUDEDIR CACHE )
unset ( ${_prefix}_INCLUDE_DIRS CACHE )
unset ( ${_prefix}_LIBDIR CACHE )
unset ( ${_prefix}_LIBRARY_DIRS CACHE )
unset ( __pkg_config_checked_${_prefix} CACHE )
endmacro ( unset_pkg_config )

View file

@ -22,7 +22,7 @@ if( test_not_successful )
endif( test_not_successful )
execute_process(
COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${expected_output} ${test_output}
COMMAND ${CMAKE_COMMAND} -E compare_files ${expected_output} ${test_output}
RESULT_VARIABLE compare_not_successful
)

View file

@ -0,0 +1,14 @@
macro ( unset_pkg_config _prefix )
unset ( ${_prefix}_VERSION CACHE )
unset ( ${_prefix}_PREFIX CACHE )
unset ( ${_prefix}_CFLAGS CACHE )
unset ( ${_prefix}_CFLAGS_OTHER CACHE )
unset ( ${_prefix}_LDFLAGS CACHE )
unset ( ${_prefix}_LDFLAGS_OTHER CACHE )
unset ( ${_prefix}_LIBRARIES CACHE )
unset ( ${_prefix}_INCLUDEDIR CACHE )
unset ( ${_prefix}_INCLUDE_DIRS CACHE )
unset ( ${_prefix}_LIBDIR CACHE )
unset ( ${_prefix}_LIBRARY_DIRS CACHE )
unset ( __pkg_config_checked_${_prefix} CACHE )
endmacro ( unset_pkg_config )

View file

@ -61,12 +61,6 @@ else ( OSS_SUPPORT )
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} OSS: no\n" )
endif ( OSS_SUPPORT )
if ( PIPEWIRE_SUPPORT )
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} PipeWire: yes\n" )
else ( PIPEWIRE_SUPPORT )
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} PipeWire: no\n" )
endif ( PIPEWIRE_SUPPORT )
if ( PORTAUDIO_SUPPORT )
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} PortAudio: yes\n" )
else ( PORTAUDIO_SUPPORT )
@ -246,14 +240,6 @@ else ( ENABLE_COVERAGE )
set ( DEVEL_REPORT "${DEVEL_REPORT} Coverage: no\n" )
endif ( ENABLE_COVERAGE )
if ( MSVC )
if ( enable-static-msvcrt )
set ( DEVEL_REPORT "${DEVEL_REPORT} Static MSVC Runtime: yes\n" )
else ( enable-static-msvcrt )
set ( DEVEL_REPORT "${DEVEL_REPORT} Static MSVC Runtime: no\n" )
endif ( enable-static-msvcrt )
endif ( MSVC )
message( STATUS
"\n**************************************************************\n"
"Build Summary:\n"

View file

@ -1 +0,0 @@
libfluidsynth2

View file

@ -1,23 +0,0 @@
fluidsynth (1.1.8-1) unstable; urgency=low
- Update to version 1.1.8:
* fix build against glib < 2.30 (#202)
* fix dsound audio driver on windows (#215)
* fix a bug around `synth.audio-groups` setting, which caused improper multi-channel rendering (#225)
* cmake 3.0.2 is now required
* compilation with clang is now possible
* build fixes on OS/2 (thanks to @komh)
-- Tom Moebert <tom.mbrt@googlemail.com> Fri, 13 Oct 2017 15:53:00 +0000
fluidsynth (1.1.7-1) unstable; urgency=low
* OBS snapshot.
-- Rui Nuno Capela <rncbc@rncbc.org> Tue, 5 Sep 2017 20:00:00 +0000
fluidsynth (1.1.6-1) unstable; urgency=low
* OBS snapshot.
-- Rui Nuno Capela <rncbc@rncbc.org> Sun, 19 Aug 2012 23:45:01 +0000

View file

@ -1 +0,0 @@
9

View file

@ -1,34 +0,0 @@
Source: fluidsynth
Priority: optional
Section: sound
Maintainer: Rui Nuno Capela <rncbc@rncbc.org>
Build-Depends: debhelper (>= 5.0.0), cmake, pkg-config, libdb-dev, libjack-dev, libasound2-dev,
libsndfile-dev, libglib2.0-dev
Standards-Version: 3.7.2
Package: libfluidsynth1
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: FluidSynth is a real-time software synthesizer
FluidSynth is a real-time software synthesizer based on
the SoundFont 2 specifications.
Package: libfluidsynth-dev
Section: libdevel
Architecture: any
Depends: libfluidsynth1 (= ${source:Version})
Description: FluidSynth is a real-time software synthesizer
FluidSynth is a real-time software synthesizer based on
the SoundFont 2 specifications.
This package contains the header file required for compiling
hosts and plugins.
Package: fluidsynth
Section: sound
Architecture: any
Depends: libfluidsynth1 (= ${source:Version})
Description: FluidSynth is a real-time software synthesizer
FluidSynth is a real-time software synthesizer based on
the SoundFont 2 specifications.
This package contains the command-line utilities.

View file

@ -1,30 +0,0 @@
This package was debianized by Rui Nuno Capela <rncbc@rncbc.org> on
Mon, 25 Jun 2007 10:42:40 +0100.
It was downloaded from http://www.fluidsynth.org
Upstream Author: Rui Nuno Capela <rncbc@rncbc.org>
Copyright:
Copyright (C) 2003-2015, rncbc aka Rui Nuno Capela. All rights reserved.
License:
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The Debian packaging is (C) 2007-2013, Rui Nuno Capela <rncbc@rncbc.org> and
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.

View file

@ -1,2 +0,0 @@
debian/tmp/usr/bin/*
debian/tmp/usr/share/*

View file

@ -1,4 +0,0 @@
debian/tmp/usr/include/*
debian/tmp/usr/lib/*/*.so
debian/tmp/usr/lib/*/pkgconfig/*.pc
debian/tmp/usr/lib/*/cmake/fluidsynth/*.cmake

View file

@ -1 +0,0 @@
debian/tmp/usr/lib/*/lib*.so.*

View file

@ -1,98 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# This is the debhelper compatibility version to use.
#export DH_COMPAT=7
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
config.status: CMakeLists.txt
dh_testdir
# Add here commands to configure the package.
cmake -DCMAKE_INSTALL_PREFIX=/usr .
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE)
# the build should fail if the tests are not successful
#$(MAKE) check
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
#-$(MAKE) distclean
dh_clean -a
install: build
dh_testdir
dh_testroot
dh_clean -k -a
dh_installdirs
# Add here commands to install the package into debian/tmp
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_install -a --list-missing
# dh_installchangelogs -a ChangeLog
# dh_installdocs -a
# dh_installexamples
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
# dh_installman
# dh_link
dh_strip -a
dh_compress -a
dh_fixperms -a
# dh_perl
# dh_python
dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View file

View file

@ -1,8 +0,0 @@
Format: 1.0
Source: fluidsynth
Version: 2.2.0-1
Binary: fluidsynth, libfluidsynth1, libfluidsynth-dev
Maintainer: Rui Nuno Capela <rncbc@rncbc.org>
Architecture: any
Standards-Version: 3.7.2
Build-Depends: debhelper (>= 5.0.0), cmake (>= 3.13.0), pkg-config, libdb-dev, libjack-dev, libasound2-dev, libsndfile-dev, libglib2.0-dev

View file

@ -1,144 +0,0 @@
#
# spec file for package fluidsynth
#
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
# fix build for older distros and architectures where _fillupdir is
# not yet defined by using the old path as recommended by
# https://en.opensuse.org/openSUSE:Packaging_Conventions_RPM_Macros#.25_fillupdir
%if ! %{defined _fillupdir}
%define _fillupdir /var/adm/fillup-templates
%endif
Name: fluidsynth
Version: 2.2.2
Release: 0
Summary: A Real-Time Software Synthesizer That Uses Soundfont(tm)
License: LGPL-2.1-or-later
Group: Productivity/Multimedia/Sound/Midi
Url: http://www.fluidsynth.org/
Source: https://github.com/FluidSynth/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
Source1000: baselibs.conf
BuildRequires: cmake >= 3.13.0
BuildRequires: gcc-c++
%if 0%{?is_opensuse}
BuildRequires: ladspa-devel
%endif
BuildRequires: pkgconfig
BuildRequires: readline-devel
BuildRequires: pkgconfig(alsa)
BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(jack)
BuildRequires: pkgconfig(libinstpatch-1.0) >= 1.1.0
BuildRequires: pkgconfig(libpulse)
BuildRequires: pkgconfig(sndfile)
%if 0%{?suse_version}
%{?systemd_requires}
PreReq: %fillup_prereq
%endif
%description
FluidSynth (formerly IIWU Synth) is a real-time software synthesizer
based on the SoundFont(tm) 2 specifications. It can read MIDI events
from the MIDI input device and render them to the audio device. It
can also play MIDI files.
%package devel
Summary: Development package for the fluidsynth library
Group: Development/Libraries/C and C++
Requires: glibc-devel
Requires: libfluidsynth3 = %{version}
Provides: libfluidsynth-devel = %{version}
%description devel
This package contains the files needed to compile programs that use the
fluidsynth library.
%package -n libfluidsynth3
Summary: Library for Fluidsynth
Group: System/Libraries
%description -n libfluidsynth3
This package contains the shared library for Fluidsynth.
%prep
%setup -q
%build
%cmake \
-DFLUID_DAEMON_ENV_FILE=%{_fillupdir}/sysconfig.%{name} \
-Denable-lash=0
%cmake_build
%check
%cmake
%if 0%{?fedora_version} || 0%{?mageia}
%cmake_build --target check
%else
%cmake_build check
%endif
%install
%cmake_install
%if 0%{?suse_version}
# manually install systemd service files
install -Dm 644 build/fluidsynth.conf %{buildroot}%{_fillupdir}/sysconfig.%{name}
install -Dm 644 build/fluidsynth.service %{buildroot}%{_unitdir}/%{name}.service
install -d %{buildroot}%{_sbindir}
ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name}
%pre
%service_add_pre %{name}.service
%post
%fillup_only
%service_add_post %{name}.service
%preun
%service_del_preun %{name}.service
%postun
%service_del_postun %{name}.service
%endif
%post -n libfluidsynth3 -p /sbin/ldconfig
%postun -n libfluidsynth3 -p /sbin/ldconfig
%files
%license LICENSE
%doc AUTHORS ChangeLog README.md THANKS TODO
%{_mandir}/man?/*
%{_bindir}/*
%if 0%{?suse_version}
%{_unitdir}/%{name}.service
%{_sbindir}/rc%{name}
%{_fillupdir}/sysconfig.%{name}
%endif
%files devel
%{_libdir}/lib*.so
%dir %{_libdir}/cmake/%{name}
%{_libdir}/cmake/%{name}/*.cmake
%{_libdir}/pkgconfig/*.pc
%{_includedir}/*
%files -n libfluidsynth3
%{_libdir}/lib*.so.*
%changelog

View file

@ -45,7 +45,7 @@ endif ( DOXYGEN_FOUND )
if ( UNIX )
install ( FILES fluidsynth.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 )
DESTINATION ${MAN_INSTALL_DIR} )
endif ( UNIX )
add_subdirectory ( examples )

View file

@ -11,7 +11,7 @@ target_compile_options ( fluidsynth-assetloader
PRIVATE -Wall
PRIVATE "$<$<CONFIG:DEBUG>:-Werror>") # Only include -Werror when building debug config
target_include_directories ( fluidsynth-assetloader PRIVATE ../../../include )
include_directories ( ../../../include )
set ( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L../../../dist/${ANDROID_ABI} -lfluidsynth" )

View file

@ -14,7 +14,7 @@ body
}
/* Reduce width of main content for more readability */
/* Reduce width of main content for more readibility */
div.contents,
div.header
{

View file

@ -19,8 +19,6 @@
#if defined(WIN32)
#include <windows.h>
#define sleep(_t) Sleep(_t * 1000)
#include <process.h>
#define getpid _getpid
#else
#include <stdlib.h>
#include <unistd.h>
@ -28,47 +26,31 @@
int main(int argc, char **argv)
{
fluid_settings_t *settings = NULL;
fluid_synth_t *synth = NULL;
fluid_audio_driver_t *adriver = NULL;
fluid_settings_t *settings;
fluid_synth_t *synth;
fluid_audio_driver_t *adriver;
int sfont_id;
int i, key;
/* Create the settings. */
settings = new_fluid_settings();
if(settings == NULL)
{
puts("Failed to create the settings!");
goto err;
}
/* Change the settings if necessary*/
/* Create the synthesizer. */
synth = new_fluid_synth(settings);
if(synth == NULL)
{
puts("Failed to create the synth!");
goto err;
}
/* Load a SoundFont and reset presets (so that new instruments
* get used from the SoundFont)
* Depending on the size of the SoundFont, this will take some time to complete...
*/
sfont_id = fluid_synth_sfload(synth, "example.sf2", 1);
if(sfont_id == FLUID_FAILED)
{
puts("Loading the SoundFont failed!");
goto err;
}
/* Create the audio driver. The synthesizer starts playing as soon
as the driver is created. */
adriver = new_fluid_audio_driver(settings, synth);
if(adriver == NULL)
/* Load a SoundFont and reset presets (so that new instruments
* get used from the SoundFont) */
sfont_id = fluid_synth_sfload(synth, "example.sf2", 1);
if(sfont_id == FLUID_FAILED)
{
puts("Failed to create the audio driver!");
puts("Loading the SoundFont failed!");
goto err;
}
@ -77,6 +59,7 @@ int main(int argc, char **argv)
for(i = 0; i < 12; i++)
{
/* Generate a random key */
key = 60 + (int)(12.0f * rand() / (float) RAND_MAX);

View file

@ -71,8 +71,7 @@ schedule_timer_event(void)
void
schedule_pattern(void)
{
unsigned int i;
int note_time, note_duration;
int i, note_time, note_duration;
note_time = time_marker;
note_duration = duration / pattern_size;
@ -136,7 +135,7 @@ main(int argc, char *argv[])
{
n = atoi(argv[2]);
if((n > 1) && (n <= (int)pattern_size))
if((n > 1) && (n <= pattern_size))
{
pattern_size = n;
}

View file

@ -141,7 +141,7 @@ int main(int argc, char **argv)
/* Fill in the data of the effects unit */
fx_data.synth = synth;
fx_data.gain = (float)atof(argv[2]);
fx_data.gain = atof(argv[2]);
/* Create the audio driver. As soon as the audio driver is
* created, the synthesizer can be played. */

View file

@ -61,8 +61,7 @@ schedule_timer_event(void)
void
schedule_pattern(void)
{
unsigned int i;
int note_time;
int i, note_time;
note_time = time_marker;
for(i = 0; i < pattern_size; ++i)

View file

@ -21,7 +21,7 @@ int main()
// array of buffers used to setup channel mapping
float *dry[1 * 2], *fx[1 * 2];
// first make sure to zero out the sample buffers every time before calling fluid_synth_process()
// first make sure to zero out the sample buffers everytime before calling fluid_synth_process()
memset(left, 0, sizeof(left));
memset(right, 0, sizeof(right));

View file

@ -14,6 +14,11 @@ https://stackoverflow.com/a/6251757
Developers:
- Settings can be deprecated by adding: <deprecated>SOME TEXT</deprecated>
- Real-time settings can be marked with <realtime>SOME OPTIONAL TEXT</realtime>.
ATTENTION: if you change anything in this file, make sure you also refresh
the doxygen/fluidsettings.txt file (used by fluidsynth.org API doc build)
and commit the results. Refresh with the following command:
xsltproc -o doxygen/fluidsettings.txt doxygen/fluidsettings.xsl fluidsettings.xml
-->
<?xml-stylesheet type="text/xsl" href="fluidsettings.xsl"?>
<fluidsettings>
@ -118,7 +123,8 @@ Developers:
<type>bool</type>
<def>0 (FALSE)</def>
<desc>
When set to 1 (TRUE), samples are loaded to and unloaded from memory whenever presets are being selected or unselected for a MIDI channel. PROGRAM_CHANGE and PROGRAM_SELECT events are typically responsible for this.
When set to 1 (TRUE), samples are loaded to and unloaded from memory
on demand.
</desc>
</setting>
<setting>
@ -413,7 +419,7 @@ Developers:
<min>64</min>
<max>8192</max>
<desc>
This is the number of audio samples most audio drivers will request from the synth at one time. In other words, it's the amount of samples the synth is allowed to render in one go when no state changes (events) are about to happen. Because of that, specifying too big numbers here may cause MIDI events to be poorly quantized (=untimed) when a MIDI driver or the synth's API directly is used, as fluidsynth cannot determine when those events are to arrive. This issue does not matter, when using the MIDI player or the MIDI sequencer, because in this case, fluidsynth does know when events will be received.
The size of the audio buffers (in frames).
</desc>
</setting>
<setting>
@ -452,32 +458,6 @@ Developers:
Selects the CoreAudio device to use.
</desc>
</setting>
<setting>
<name>coreaudio.channel-map</name>
<type>str</type>
<def>(empty string)</def>
<desc>
This setting is a comma-separated integer list that maps fluidsynth mono-channels
to CoreAudio device output channels. Each position in the list represents the output channel
of the CoreAudio device.
The value of each position indicates the zero-based index of the fluidsynth
output mono-channel to route there (i.e. the buffer index used for fluid_synth_process()).
Additionally, the special value of -1 will turn off an output.
<br /><br />
For example, the default map for a single stereo output is "0,1". A value of "0,0" will
copy the left channel to the right, a value of "1,0" will flip left and right, and a
value of "-1,1" will play only the right channel.
<br /><br />
With a six-channel output device, and the synth.audio-channels and synth.audio-groups
settings both set to "2", a channel map of "-1,-1,0,1,2,3" will result in notes from odd
MIDI channels (audible on the first stereo channel, i.e. mono-indices 0,1) being sent to
outputs 3 and 4, and even MIDI channels (audible on the second stereo channel, i.e. mono-indices 2,3)
being sent to outputs 5 and 6.
<br /><br />
If the list specifies less than the number of available outputs channels, outputs
beyond those specified will maintain the default channel mapping given by the CoreAudio driver.
</desc>
</setting>
<setting>
<name>dart.device</name>
<type>str</type>
@ -610,15 +590,6 @@ Developers:
Sets the performance mode as pointed out by Oboe's documentation.
</desc>
</setting>
<setting>
<name>oboe.error-recovery-mode</name>
<type>str</type>
<def>Reconnect</def>
<vals>Reconnect, Stop</vals>
<desc>
Sets the error recovery mode when audio device error such as earphone disconnection occurred. It reconnects by default (same as OpenSLES behavior), but can be stopped if Stop is specified.
</desc>
</setting>
<setting>
<name>oss.device</name>
<type>str</type>
@ -627,30 +598,6 @@ Developers:
Device to use for OSS audio output.
</desc>
</setting>
<setting>
<name>pipewire.media-category</name>
<type>str</type>
<def>Playback</def>
<desc>
The media category to use. This value will be passed to <code>PW_KEY_MEDIA_CATEGORY</code>, see Pipewire documentation for valid values.
</desc>
</setting>
<setting>
<name>pipewire.media-role</name>
<type>str</type>
<def>Music</def>
<desc>
The media role to use. This value will be passed to <code>PW_KEY_MEDIA_ROLE</code>, see Pipewire documentation for valid values.
</desc>
</setting>
<setting>
<name>pipewire.media-type</name>
<type>str</type>
<def>Audio</def>
<desc>
The media type to use. This value will be passed to <code>PW_KEY_MEDIA_TYPE</code>, see Pipewire documentation for valid values.
</desc>
</setting>
<setting>
<name>portaudio.device</name>
<type>str</type>

View file

@ -7,9 +7,9 @@
\author Josh Green
\author David Henningsson
\author Tom Moebert
\author Copyright &copy; 2003-2022 Peter Hanappe, Conrad Berhörster, Antoine Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert
\version Revision 2.2.8
\date 2022-07-10
\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.2.1
\date 2021-05-08
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 https://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 https://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.

View file

@ -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 "Jan 1, 2022"
.TH FluidSynth 1 "Jan 1, 2021"
.\" Please update the above date whenever this man page is modified.
.\"
.\" Some roff macros, for reference:

View file

@ -31,7 +31,7 @@ file.
## Introduction to LADSPA
You don't need to to have detailed knowledge of LADSPA to use effects with
FluidSynth, but knowing some of the LADSPA concepts will help if you want to make the
FluidSynth, but knowing some of it's concepts will help if you want to make the
best use of it.
If you have the LADSPA SDK installed you should be able to use the `listplugins`
@ -76,13 +76,13 @@ that only have a single output port and no input at all (think of noise
generators...)
Also note the line `Has run_adding() Function: No`. This specifies that this
plugin can not mix its audio output into an output buffer, but will always
plugin can not mix it's audio output into an output buffer, but will always
replace anything that is already there. This will become important again later
on.
## FluidSynth Host Ports
Just as LADSPA plugins have input and output ports, FluidSynth provides its
Just as LADSPA plugins have input and output ports, FluidSynth provides it's
own audio ports that can be connected to plugins. On a standard stereo setup,
the following four ports are automatically created:
@ -135,7 +135,7 @@ Please note that we only specified the path to the library
`/usr/lib/ladspa/delay.so` when creating the "e1" effect, but not which plugin
from the library to use. This is possible because the delay.so library contains
only a single plugin. If you want to use a library that contains more than one
plugin, you would need to specify the plugin name as well, as we've done when
plugin, you would need to give the plugin name as well, as we've done when
creating the "e2" effect. The string to use here is what is called "Plugin
Label" in the `analyseplugin` output.
@ -230,8 +230,8 @@ send amount specified in the SoundFont.
If you want to replace the internal reverb or chorus effects with a LADSPA
plugin and you want to honour the decisions made by the SoundFont designer, you
should use the `Reverb:Send` or `Chorus:Send` ports as inputs to the effects and
`Main:L` and `Main:R` ports as outputs. (See the "Example Setups" section
should use the `Reverb:Send` or `Chorus:Send` ports as effect input and
`Main:L` and `Main:R` ports as effect outputs. (See the "Example Setups" section
below for an example on how to replace the internal reverb with a LADSPA plugin.)
Please note that FluidSynth uses a mono signal for both effects, that is why
@ -260,16 +260,17 @@ ladspa_effect <effect-name> <library-path> [plugin-name] [--mix [gain]]
```
Load the LADSPA plugin library given by `<library-path>` and create a new effect
(i.e. an instance of a plugin). `<effect-name>` can be chosen by the user and must be
(i.e. an instance of a plugin). `<effect-name>` can be chosen by the user and must
unique. `<plugin-name>` is optional if the library contains only one plugin.
If the optional `--mix` parameter is given, then the LADSPA engine will call the
`run_adding` interface of the plugin. This will tell the effect to mix its output into the output buffers instead of replacing them. The `--mix` parameter takes an
`run_adding` interface of the plugin. This will make the effect add it's output
to the output buffers instead of replacing them. The `--mix` parameter takes an
optional float value `gain`, which will be multiplied with each sample before
adding to the output buffers.
Please note that there is no command to delete a single effect once created. To
remove effects, please use `ladspa_reset` to clear everything and start from
remove effects, please use `ladspa_reset` to clear everything start from
scratch.
Can only be called when the effect unit is not active.
@ -280,8 +281,8 @@ Can only be called when the effect unit is not active.
ladspa_buffer <buffer-name>
```
Create a new audio buffer called `<buffer-name>`. The buffer can be used as
mono output or mono input for an effect. Buffers can be used to connect plugins
Create a new audio buffer called `<buffer-name>`. The buffer is able to be used as
mono output or mono input to an effect. Buffers can be used to connect plugins
between each other without overwriting the host ports with temporary data.
Please note that there is no command to delete a buffer. To remove buffers,
@ -295,7 +296,7 @@ Can only be used when the effect unit is not active.
ladspa_link <effect-name> <audio-port-name> <buffer-or-host-port-name>
```
Connects an effect input or output port to a buffer or a host port. This
Connects an effect input or output port with a buffer or a host port. This
command can be called multiple times and will overwrite the previous connection
made on that effect port.
@ -347,7 +348,7 @@ it can be started again with `ladspa_start`.
ladspa_reset
```
Deactivates the effects unit if it is currently active and clears all configuration and loaded
Deactivates the effects unit if active and clears all configuration and loaded
plugins.
@ -439,7 +440,7 @@ Explaining multi-channel output in detail is out of scope for this guide. But
using multiple output channels has an effect on the host ports that are
available to LADSPA plugins.
As soon as you configure more than one audio-group, the main audio ports will
As soon as you configure more than one audio-channel, the main audio ports will
not be called "Main:L" and "Main:R" anymore, but will have indices added to
their name. So if you start FluidSynth with `-o synth.audio-groups=2`, then the
following ports will be created:
@ -461,7 +462,7 @@ LADSPA is a very simple plugin architecture and only requires the ladspa.h
header file as compile-time dependency. To build FluidSynth on non-Linux
platform with LADSPA support, download the ladspa.h file from
https://www.ladspa.org and place it somewhere in your compiler include path. Then
configure and build FluidSynth as you normally would.
configure and build LADSPA as you normally would.
All information in the above documentation is valid for all other platforms as
well. Just make sure you use the file path format specific to your platform in

View file

@ -1,12 +1,6 @@
/*!
\page RecentChanges Recent Changes
\section NewIn2_2_7 What's new in 2.2.7?
- Most getter functions of the MIDI event API are now const correct
- fluid_event_from_midi_event() has been added
\section NewIn2_2_0 What's new in 2.2.0?
- #fluid_file_callbacks_t <span style="color:red">now uses <code>long long</code> as file-offset type (see #fluid_long_long_t).</span><span style="color:red;font-weight:bold">This is a breaking change</span>, which allows to load SoundFonts bigger than 2GiB on Windows. This change required to bump fluidsynth's SOVERSION.

View file

@ -16,7 +16,7 @@ and a description.
- jack: JACK Audio Connection Kit (Linux, Mac OS X, Windows)
- alsa: Advanced Linux Sound Architecture (Linux)
- oss: Open Sound System (primarily needed on BSD, rarely also Linux and Unix in general)
- oss: Open Sound System (Linux, Unix)
- pulseaudio: PulseAudio (Linux, Mac OS X, Windows)
- coreaudio: Apple CoreAudio (Mac OS X)
- dsound: Microsoft DirectSound (Windows)
@ -31,7 +31,6 @@ and a description.
- file: Driver to output audio to a file
- sdl2*: Simple DirectMedia Layer (Linux, Windows, Mac OS X, iOS, Android,
FreeBSD, Haiku, etc.)
- pipewire**: PipeWire (Linux)
The default audio driver depends on the settings with which FluidSynth was
compiled. You can get the default driver with
@ -80,10 +79,4 @@ is responsible for initializing SDL (e.g. with SDL_Init()). This must be done
Also make sure to call SDL_Quit() after all fluidsynth instances have been
destroyed.
<strong>**Note:</strong> In order to use pipeiwre as audio driver, the application
is responsible for initializing PipeWire (e.g. with pw_init()). This must be done
<strong>before</strong> the first call to <code>new_fluid_settings()</code>!
Also make sure to call pw_deinit() after all fluidsynth instances have been
destroyed.
*/

View file

@ -32,7 +32,7 @@ The API contains the functions to query the type, the current value, the
default value, the range and the "hints" of a setting. The range is the minimum
and maximum value of the setting. The hints gives additional information about
a setting. For example, whether a string represents a filename. Or whether a
number should be interpreted on a logarithmic scale. Check the settings.h
number should be interpreted on on a logarithmic scale. Check the settings.h
API documentation for a description of all functions.
*/

View file

@ -6,7 +6,5 @@ includedir=@includedir@
Name: FluidSynth
Description: Software SoundFont synth
Version: @VERSION@
Requires.private: @PC_REQUIRES_PRIV_JOINED@
Libs: -L${libdir} -lfluidsynth
Libs.private: @LIBS_PRIVATE_JOINED@ @LIBS_PRIVATE_WITH_PATH_JOINED@
Cflags: -I${includedir}

View file

@ -8,7 +8,7 @@ Type=notify
NotifyAccess=main
EnvironmentFile=@FLUID_DAEMON_ENV_FILE@
EnvironmentFile=-%h/.config/fluidsynth
ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/fluidsynth -is $OTHER_OPTS $SOUND_FONT
ExecStart=@CMAKE_INSTALL_PREFIX@/@BIN_INSTALL_DIR@/fluidsynth -is $OTHER_OPTS $SOUND_FONT
[Install]
WantedBy=default.target

76
fluidsynth.spec.in Normal file
View file

@ -0,0 +1,76 @@
%define name @PACKAGE@
%define version @VERSION@
%define release 1
%define prefix /usr
Summary: A real-time software synthesizer based on SoundFont 2 specifications.
Name: %{name}
Version: %{version}
Release: %{release}
Prefix: %{prefix}
Copyright: LGPL
Group: Sound
Source: https://savannah.nongnu.org/download/fluid/stable.pkg/%{version}/fluidsynth-%{version}.tar.gz
URL: https://www.fluidsynth.org/
BuildRoot: /var/tmp/%{name}-%{version}
%description
FluidSynth is a real-time software synthesizer based on the SoundFont
2 specifications. FluidSynth can read MIDI events from MIDI input
devices and render them to audio devices using SoundFont files to
define the instrument sounds. It can also play MIDI files and supports
real time effect control via SoundFont modulators and MIDI
controls. FluidSynth can be interfaced to other programs in different
ways, including linking as a shared library.
%package devel
Summary: Libraries and includes to build FluidSynth into other applications
Group: Development/Libraries
%description devel
FluidSynth is a real-time software synthesizer based on the SoundFont
2 specifications. FluidSynth can read MIDI events from MIDI input
devices and render them to audio devices using SoundFont files to
define the instrument sounds. It can also play MIDI files and supports
real time effect control via SoundFont modulators and MIDI
controls. FluidSynth can be interfaced to other programs in different
ways, including linking as a shared library.
This package contains libraries and includes for building applications
with FluidSynth support.
%prep
%setup
%build
./configure --prefix=%{prefix}
make
%install
if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
mkdir -p $RPM_BUILD_ROOT
make prefix=$RPM_BUILD_ROOT%{prefix} install
%clean
if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
%files
%defattr(-,root,root)
%doc AUTHORS COPYING ChangeLog NEWS README TODO
%{prefix}/bin/fluidsynth
%{prefix}/lib/libfluidsynth.so*
%{prefix}/man/man1/*
%files devel
%defattr(-,root,root)
%doc doc/example.c doc/example.sf2 doc/api doc/html/*
%{prefix}/lib/libfluidsynth.a
%{prefix}/lib/libfluidsynth.la
%{prefix}/lib/pkgconfig/fluidsynth.pc
%{prefix}/include/fluidsynth.h
%{prefix}/include/fluidsynth
%changelog
* Mon Aug 25 2003 Josh Green <jgreen@users.sourceforge.net>
- Created initial fluidsynth.spec.in

View file

@ -74,9 +74,9 @@ extern "C" {
* For further details please refer to fluid_synth_process().
*
* @parblock
* @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarantee that @p out
* @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarentee that @p out
* and @p fx buffers provided by fluidsynth's audio drivers never alias. This prevents downstream
* applications from e.g. applying a custom effect accidentally to the same buffer multiple times.
* applications from e.g. applying a custom effect accidentially to the same buffer multiple times.
* @endparblock
*
* @parblock

View file

@ -117,7 +117,6 @@ FLUIDSYNTH_API void fluid_event_system_reset(fluid_event_t *evt);
FLUIDSYNTH_API void fluid_event_unregistering(fluid_event_t *evt);
FLUIDSYNTH_API void fluid_event_scale(fluid_event_t *evt, double new_scale);
FLUIDSYNTH_API int fluid_event_from_midi_event(fluid_event_t *, const fluid_midi_event_t *);
/* Accessing event data */
FLUIDSYNTH_API int fluid_event_get_type(fluid_event_t *evt);

View file

@ -114,20 +114,20 @@ FLUIDSYNTH_API void delete_fluid_midi_event(fluid_midi_event_t *event);
/** @endlifecycle */
FLUIDSYNTH_API int fluid_midi_event_set_type(fluid_midi_event_t *evt, int type);
FLUIDSYNTH_API int fluid_midi_event_get_type(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_type(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan);
FLUIDSYNTH_API int fluid_midi_event_get_channel(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_key(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_channel(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_key(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_set_key(fluid_midi_event_t *evt, int key);
FLUIDSYNTH_API int fluid_midi_event_get_velocity(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_velocity(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int vel);
FLUIDSYNTH_API int fluid_midi_event_get_control(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_control(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_set_control(fluid_midi_event_t *evt, int ctrl);
FLUIDSYNTH_API int fluid_midi_event_get_value(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_value(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_set_value(fluid_midi_event_t *evt, int val);
FLUIDSYNTH_API int fluid_midi_event_get_program(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_program(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_set_program(fluid_midi_event_t *evt, int val);
FLUIDSYNTH_API int fluid_midi_event_get_pitch(const fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_get_pitch(fluid_midi_event_t *evt);
FLUIDSYNTH_API int fluid_midi_event_set_pitch(fluid_midi_event_t *evt, int val);
FLUIDSYNTH_API int fluid_midi_event_set_sysex(fluid_midi_event_t *evt, void *data,
int size, int dynamic);
@ -145,7 +145,7 @@ FLUIDSYNTH_API int fluid_midi_event_get_lyrics(fluid_midi_event_t *evt,
* @defgroup midi_router MIDI Router
* @ingroup midi_input
*
* Rule based transformation and filtering of MIDI events.
* Rule based tranformation and filtering of MIDI events.
*
* @{
*/

View file

@ -47,7 +47,7 @@ extern "C" {
* @param data User defined data registered with the client
*
* @note @p time may not be of the same tick value as the scheduled event! In fact, depending on
* the sequencer's scale and the synth's sample-rate, @p time may be a few ticks too late. Although this
* the sequencer's scale and the synth's sample-rate, @p time may a few ticks too late. Although this
* itself is inaudible, it is important to consider,
* when you use this callback for enqueuing additional events over and over again with
* fluid_sequencer_send_at(): If you enqueue new events with a relative tick value you might introduce

View file

@ -34,8 +34,8 @@ extern "C" {
*/
FLUIDSYNTH_API
fluid_seq_id_t fluid_sequencer_register_fluidsynth(fluid_sequencer_t *seq, fluid_synth_t *synth);
FLUIDSYNTH_API
int fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event);
FLUIDSYNTH_API int
fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event);
/* @} */
#ifdef __cplusplus

View file

@ -26,7 +26,7 @@ extern "C" {
#endif
/**
* @defgroup soundfonts SoundFonts
* @defgroup soundfonts SountFonts
*
* SoundFont related functions
*

View file

@ -331,18 +331,6 @@ FLUIDSYNTH_API int fluid_synth_tuning_dump(fluid_synth_t *synth, int bank, int p
* render real-time audio, ensure that you call these functions from a high-priority
* thread with little to no other duties other than calling the rendering functions.
*
* @warning
* If a concurrently running thread calls any other sound affecting synth function
* (e.g. fluid_synth_noteon(), fluid_synth_cc(), etc.) it is unspecified whether the event triggered by such a call
* will be effective in the recently synthesized audio. While this is inaudible when only requesting small chunks from the
* synth with every call (cf. fluid_synth_get_internal_bufsize()), it will become evident when requesting larger sample chunks:
* With larger sample chunks it will get harder for the synth to react on those spontaneously occurring events in time
* (like events received from a MIDI driver, or directly made synth API calls).
* In those real-time scenarios, prefer requesting smaller
* sample chunks from the synth with each call, to avoid poor quantization of your events in the synthesized audio.
* This issue is not applicable when using the MIDI player or sequencer for event dispatching. Also
* refer to the documentation of \setting{audio_period-size}.
*
* @{
*/
FLUIDSYNTH_API int fluid_synth_write_s16(fluid_synth_t *synth, int len,

View file

@ -1 +0,0 @@
VintageDreamsWaves-v2.sf2

View file

@ -19,14 +19,42 @@
# CMake based build system. Pedro Lopez-Cabanillas <plcl@users.sf.net>
include_directories (
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/src/drivers
${CMAKE_SOURCE_DIR}/src/synth
${CMAKE_SOURCE_DIR}/src/rvoice
${CMAKE_SOURCE_DIR}/src/midi
${CMAKE_SOURCE_DIR}/src/utils
${CMAKE_SOURCE_DIR}/src/sfloader
${CMAKE_SOURCE_DIR}/src/bindings
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include
)
include_directories (
SYSTEM
${GLIB_INCLUDE_DIRS}
${PTHREADS_INCLUDE_DIR}
${SDL2_INCLUDE_DIR}
${LIBINSTPATCH_INCLUDE_DIRS}
)
# ************ library ************
if ( READLINE_SUPPORT )
include_directories ( ${READLINE_INCLUDE_DIR} )
endif ( READLINE_SUPPORT )
if ( PULSE_SUPPORT )
set ( fluid_pulse_SOURCES drivers/fluid_pulse.c )
include_directories ( ${PULSE_INCLUDE_DIRS} )
endif ( PULSE_SUPPORT )
if ( ALSA_SUPPORT )
set ( fluid_alsa_SOURCES drivers/fluid_alsa.c )
include_directories ( ${ALSA_INCLUDE_DIRS} )
endif ( ALSA_SUPPORT )
if ( COREAUDIO_SUPPORT )
@ -39,19 +67,17 @@ endif ( COREMIDI_SUPPORT )
if ( DBUS_SUPPORT )
set ( fluid_dbus_SOURCES bindings/fluid_rtkit.c bindings/fluid_rtkit.h )
include_directories ( ${DBUS_INCLUDE_DIRS} )
endif ( DBUS_SUPPORT )
if ( JACK_SUPPORT )
set ( fluid_jack_SOURCES drivers/fluid_jack.c )
include_directories ( ${JACK_INCLUDE_DIRS} )
endif ( JACK_SUPPORT )
if ( PIPEWIRE_SUPPORT )
set ( fluid_pipewire_SOURCES drivers/fluid_pipewire.c )
include_directories ( SYSTEM ${PIPEWIRE_INCLUDE_DIRS} )
endif ( PIPEWIRE_SUPPORT )
if ( PORTAUDIO_SUPPORT )
set ( fluid_portaudio_SOURCES drivers/fluid_portaudio.c )
include_directories ( ${PORTAUDIO_INCLUDE_DIRS} )
endif ( PORTAUDIO_SUPPORT )
if ( DSOUND_SUPPORT )
@ -72,6 +98,7 @@ endif ( WINMIDI_SUPPORT )
if ( SDL2_SUPPORT )
set ( fluid_sdl2_SOURCES drivers/fluid_sdl2.c )
include_directories ( ${SDL2_INCLUDE_DIRS} )
endif ( SDL2_SUPPORT )
if ( OSS_SUPPORT )
@ -80,14 +107,25 @@ endif ( OSS_SUPPORT )
if ( LASH_SUPPORT )
set ( fluid_lash_SOURCES bindings/fluid_lash.c bindings/fluid_lash.h )
include_directories ( ${LASH_INCLUDE_DIRS})
endif ( LASH_SUPPORT )
if ( SYSTEMD_SUPPORT )
include_directories ( ${SYSTEMD_INCLUDE_DIRS})
endif ( SYSTEMD_SUPPORT )
if ( DART_SUPPORT )
set ( fluid_dart_SOURCES drivers/fluid_dart.c )
include_directories ( ${DART_INCLUDE_DIRS} )
endif ( DART_SUPPORT )
if ( LIBSNDFILE_SUPPORT )
include_directories ( ${LIBSNDFILE_INCLUDE_DIRS} )
endif ( LIBSNDFILE_SUPPORT )
if ( MIDISHARE_SUPPORT )
set ( fluid_midishare_SOURCES drivers/fluid_midishare.c )
include_directories ( ${MidiShare_INCLUDE_DIRS} )
endif ( MIDISHARE_SUPPORT )
if ( AUFILE_SUPPORT )
@ -100,13 +138,15 @@ endif ( LIBINSTPATCH_SUPPORT )
if ( OPENSLES_SUPPORT )
set ( fluid_opensles_SOURCES drivers/fluid_opensles.c )
include_directories ( ${OpenSLES_INCLUDE_DIRS} )
endif ( OPENSLES_SUPPORT )
if ( OBOE_SUPPORT )
set ( fluid_oboe_SOURCES drivers/fluid_oboe.cpp )
include_directories ( ${OBOE_INCLUDE_DIRS} )
endif ( OBOE_SUPPORT )
set ( config_SOURCES ${FluidSynth_BINARY_DIR}/config.h )
set ( config_SOURCES ${CMAKE_BINARY_DIR}/config.h )
set ( libfluidsynth_SOURCES
utils/fluid_conv.c
@ -182,41 +222,33 @@ set ( libfluidsynth_SOURCES
bindings/fluid_ladspa.h
)
if ( WIN32_GLIBSTUBS )
set( libfluidsynth_SOURCES
${libfluidsynth_SOURCES}
utils/win32_glibstubs.c
utils/win32_glibstubs.h
)
endif ( WIN32_GLIBSTUBS )
set ( public_HEADERS
${FluidSynth_SOURCE_DIR}/include/fluidsynth/audio.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/event.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/gen.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/ladspa.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/log.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/midi.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/misc.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/mod.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/seq.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/seqbind.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/settings.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/sfont.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/shell.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/synth.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/types.h
${FluidSynth_SOURCE_DIR}/include/fluidsynth/voice.h
${FluidSynth_BINARY_DIR}/include/fluidsynth/version.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/audio.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/event.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/gen.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/ladspa.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/log.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/midi.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/misc.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/mod.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/seq.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/seqbind.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/settings.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/sfont.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/shell.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/synth.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/types.h
${CMAKE_SOURCE_DIR}/include/fluidsynth/voice.h
${CMAKE_BINARY_DIR}/include/fluidsynth/version.h
)
set ( public_main_HEADER
${FluidSynth_BINARY_DIR}/include/fluidsynth.h
${CMAKE_BINARY_DIR}/include/fluidsynth.h
)
configure_file ( ${FluidSynth_SOURCE_DIR}/include/fluidsynth/version.h.in
${FluidSynth_BINARY_DIR}/include/fluidsynth/version.h )
configure_file ( ${FluidSynth_SOURCE_DIR}/include/fluidsynth.cmake
configure_file ( ${CMAKE_SOURCE_DIR}/include/fluidsynth/version.h.in
${CMAKE_BINARY_DIR}/include/fluidsynth/version.h )
configure_file ( ${CMAKE_SOURCE_DIR}/include/fluidsynth.cmake
${public_main_HEADER} )
if ( WIN32 )
@ -245,7 +277,6 @@ add_library ( libfluidsynth-OBJ OBJECT
${fluid_dart_SOURCES}
${fluid_dbus_SOURCES}
${fluid_jack_SOURCES}
${fluid_pipewire_SOURCES}
${fluid_lash_SOURCES}
${fluid_midishare_SOURCES}
${fluid_opensles_SOURCES}
@ -265,38 +296,18 @@ add_library ( libfluidsynth-OBJ OBJECT
${VersionFilesOutputVariable}
)
target_include_directories ( libfluidsynth-OBJ PRIVATE
${FluidSynth_BINARY_DIR}
${FluidSynth_BINARY_DIR}/include
${FluidSynth_SOURCE_DIR}/src
${FluidSynth_SOURCE_DIR}/src/drivers
${FluidSynth_SOURCE_DIR}/src/synth
${FluidSynth_SOURCE_DIR}/src/rvoice
${FluidSynth_SOURCE_DIR}/src/midi
${FluidSynth_SOURCE_DIR}/src/utils
${FluidSynth_SOURCE_DIR}/src/sfloader
${FluidSynth_SOURCE_DIR}/src/bindings
${FluidSynth_SOURCE_DIR}/include
)
if ( LIBFLUID_CPPFLAGS )
set_target_properties ( libfluidsynth-OBJ
PROPERTIES COMPILE_FLAGS ${LIBFLUID_CPPFLAGS} )
endif ( LIBFLUID_CPPFLAGS )
# Note: by default this target creates a shared object (or dll). To build a
# note: by default this target creates a shared object (or dll). To build a
# static library instead, set the option BUILD_SHARED_LIBS to FALSE.
# Further note: The headers must be explicitly added here to have CMake install
# them correctly in case of MACOSX_FRAMEWORK
add_library ( libfluidsynth
$<TARGET_OBJECTS:libfluidsynth-OBJ>
${public_main_HEADER}
${public_HEADERS}
)
add_library ( libfluidsynth $<TARGET_OBJECTS:libfluidsynth-OBJ> )
if ( MACOSX_FRAMEWORK )
set_source_files_properties ( ${public_HEADERS}
PROPERTIES MACOSX_PACKAGE_LOCATION Headers/fluidsynth
set_property ( SOURCE ${public_HEADERS}
PROPERTY MACOSX_PACKAGE_LOCATION Headers/fluidsynth
)
set_target_properties ( libfluidsynth
PROPERTIES
@ -337,126 +348,33 @@ else ( MACOSX_FRAMEWORK )
)
endif ( MACOSX_FRAMEWORK )
# Since CMake 3.12, OBJECT libraries can be linked to with target_link_libraries().
# See https://cmake.org/cmake/help/latest/command/target_link_libraries.html#linking-object-libraries
# Object Libraries may "link" to other libraries to get usage requirements,
# but since they do not have a link step nothing is done with their object files.
target_link_libraries ( libfluidsynth-OBJ PUBLIC
target_link_libraries ( libfluidsynth
${GLIB_LIBRARIES}
${GMODULE_LIBRARIES}
${LASH_LIBRARIES}
${JACK_LIBRARIES}
${ALSA_LIBRARIES}
${PULSE_LIBRARIES}
${PORTAUDIO_LIBRARIES}
${LIBSNDFILE_LIBRARIES}
${SDL2_LIBRARIES}
${DBUS_LIBRARIES}
${READLINE_LIBS}
${DART_LIBS}
${COREAUDIO_LIBS}
${COREMIDI_LIBS}
${WINDOWS_LIBS}
${MidiShare_LIBS}
${OpenSLES_LIBS}
${OBOE_LIBS}
${LIBFLUID_LIBS}
${LIBINSTPATCH_LIBRARIES}
)
if ( TARGET OpenMP::OpenMP_C AND HAVE_OPENMP )
target_link_libraries ( libfluidsynth-OBJ PUBLIC OpenMP::OpenMP_C )
endif()
if ( TARGET PkgConfig::GLIB )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::GLIB )
else()
target_include_directories ( libfluidsynth-OBJ PUBLIC ${GLIB_INCLUDE_DIRS} )
target_link_libraries ( libfluidsynth-OBJ PUBLIC ${GLIB_LIBRARIES} )
endif()
if ( TARGET PkgConfig::LIBSNDFILE AND LIBSNDFILE_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::LIBSNDFILE )
endif()
if ( TARGET SndFile::sndfile AND LIBSNDFILE_SUPPORT )
target_include_directories ( libfluidsynth-OBJ PRIVATE ${SndFile_INCLUDE_DIR} )
target_link_libraries ( libfluidsynth-OBJ PUBLIC SndFile::sndfile )
endif()
if ( TARGET PkgConfig::PULSE AND PULSE_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::PULSE )
endif()
if ( ALSA_SUPPORT )
if ( TARGET PkgConfig::ALSA )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::ALSA )
else()
target_link_libraries ( libfluidsynth-OBJ PUBLIC ALSA::ALSA )
endif()
endif()
if ( TARGET PkgConfig::PORTAUDIO AND PORTAUDIO_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::PORTAUDIO )
endif()
if ( TARGET PkgConfig::JACK AND JACK_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::JACK )
endif()
if ( TARGET PkgConfig::PIPEWIRE AND PIPEWIRE_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::PIPEWIRE )
endif()
if ( TARGET PkgConfig::LASH AND LASH_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::LASH )
endif()
if ( TARGET PkgConfig::DBUS AND DBUS_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::DBUS )
endif()
if ( TARGET PkgConfig::GMODULE AND LADSPA_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::GMODULE )
endif()
if ( TARGET PkgConfig::LIBINSTPATCH AND LIBINSTPATCH_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::LIBINSTPATCH )
endif()
if ( TARGET PkgConfig::SDL2 AND SDL2_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::SDL2 )
endif()
if ( TARGET PkgConfig::OBOE AND OBOE_SUPPORT )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::OBOE )
endif()
if ( WITH_READLINE )
if ( TARGET PkgConfig::READLINE )
target_link_libraries ( libfluidsynth-OBJ PUBLIC PkgConfig::READLINE )
else()
target_link_libraries ( libfluidsynth-OBJ PUBLIC ${READLINE_LIBRARIES} )
target_include_directories ( libfluidsynth-OBJ PUBLIC ${READLINE_INCLUDE_DIR} )
endif()
endif()
if ( DART_SUPPORT )
target_include_directories ( libfluidsynth-OBJ PUBLIC ${DART_INCLUDE_DIRS} )
endif ( DART_SUPPORT )
if ( MIDISHARE_SUPPORT )
target_include_directories ( libfluidsynth-OBJ PUBLIC ${MidiShare_INCLUDE_DIRS} )
endif ( MIDISHARE_SUPPORT )
if ( OPENSLES_SUPPORT )
target_include_directories ( libfluidsynth-OBJ PUBLIC ${OpenSLES_INCLUDE_DIRS} )
endif ( OPENSLES_SUPPORT )
# This doesn't install any object file at all!
# it is only a trick for exporting targets
install( TARGETS libfluidsynth-OBJ
EXPORT FluidSynthTargets
OBJECTS )
# Here are applied/linked the OBJECT library dependencies
target_link_libraries ( libfluidsynth PRIVATE libfluidsynth-OBJ )
# ************ CLI program ************
set ( fluidsynth_SOURCES fluidsynth.c )
if ( WIN32_GLIBSTUBS )
set ( fluidsynth_SOURCES ${fluidsynth_SOURCES} utils/win32_glibstubs.c )
endif ( WIN32_GLIBSTUBS )
if ( WASAPI_SUPPORT )
set ( fluidsynth_SOURCES ${fluidsynth_SOURCES} fluid_wasapi_device_enumerate.c )
endif ( WASAPI_SUPPORT )
@ -465,94 +383,33 @@ add_executable ( fluidsynth
${fluidsynth_SOURCES}
)
set_target_properties ( fluidsynth
PROPERTIES IMPORT_PREFIX "" )
if ( FLUID_CPPFLAGS )
set_target_properties ( fluidsynth
PROPERTIES COMPILE_FLAGS ${FLUID_CPPFLAGS} )
endif ( FLUID_CPPFLAGS )
target_include_directories ( fluidsynth PRIVATE
${FluidSynth_BINARY_DIR}
${FluidSynth_BINARY_DIR}/include
${FluidSynth_SOURCE_DIR}/src/bindings
${FluidSynth_SOURCE_DIR}/src/midi
${FluidSynth_SOURCE_DIR}/src/rvoice
${FluidSynth_SOURCE_DIR}/src/sfloader
${FluidSynth_SOURCE_DIR}/src/synth
${FluidSynth_SOURCE_DIR}/src/utils
${FluidSynth_SOURCE_DIR}/src/
${FluidSynth_SOURCE_DIR}/include
)
target_link_libraries ( fluidsynth PRIVATE
target_link_libraries ( fluidsynth
libfluidsynth
${SYSTEMD_LIBRARIES}
${FLUID_LIBS}
)
if ( TARGET OpenMP::OpenMP_C AND HAVE_OPENMP )
target_link_libraries ( fluidsynth PRIVATE OpenMP::OpenMP_C )
endif()
if ( TARGET PkgConfig::SYSTEMD AND SYSTEMD_SUPPORT )
target_link_libraries ( fluidsynth PRIVATE PkgConfig::SYSTEMD )
endif()
if ( TARGET PkgConfig::GLIB ) # because g_file_test()
target_link_libraries ( fluidsynth PRIVATE PkgConfig::GLIB )
endif()
if ( TARGET PkgConfig::SDL2 AND SDL2_SUPPORT ) # because SDL_Init() etc.
target_link_libraries ( fluidsynth PRIVATE PkgConfig::SDL2 )
endif()
if ( TARGET PkgConfig::PIPEWIRE AND PIPEWIRE_SUPPORT ) # because pw_init() etc.
target_link_libraries ( fluidsynth PRIVATE PkgConfig::PIPEWIRE )
endif()
if ( TARGET PkgConfig::LIBINSTPATCH AND LIBINSTPATCH_SUPPORT )
target_link_libraries ( fluidsynth PRIVATE PkgConfig::LIBINSTPATCH )
endif()
if ( TARGET PkgConfig::LASH AND LASH_SUPPORT )
target_link_libraries ( fluidsynth PRIVATE PkgConfig::LASH )
endif()
if ( MACOSX_FRAMEWORK )
install ( TARGETS fluidsynth libfluidsynth
EXPORT FluidSynthTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION "${FRAMEWORK_INSTALL_PREFIX}/${FRAMEWORK_INSTALL_DIR}"
ARCHIVE DESTINATION "${FRAMEWORK_INSTALL_PREFIX}/${FRAMEWORK_INSTALL_DIR}"
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
ARCHIVE DESTINATION ${FRAMEWORK_INSTALL_DIR}
)
else ( MACOSX_FRAMEWORK )
install ( TARGETS fluidsynth libfluidsynth
EXPORT FluidSynthTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fluidsynth
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/fluidsynth
)
install ( FILES ${public_main_HEADER} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
install ( FILES ${public_main_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR} )
endif ( MACOSX_FRAMEWORK )
# Exported targets.
# build_interface: for the libfluidsynth target when imported from the build directory.
# install_interface: for the target when imported from the installed directory.
target_include_directories(libfluidsynth PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/;${PROJECT_BINARY_DIR}/include/>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
# installation of the exported targets
install(EXPORT FluidSynthTargets
FILE FluidSynthTargets.cmake
NAMESPACE FluidSynth::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/fluidsynth
)
# ******* Auto Generated Lookup Tables ******
include(ExternalProject)
@ -572,6 +429,6 @@ ExternalProject_Add(gentables
"${CMAKE_COMMAND}" -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} -G "${CMAKE_GENERATOR}" -B "${GENTAB_BDIR}" "${GENTAB_SDIR}"
BUILD_COMMAND
"${CMAKE_COMMAND}" --build "${GENTAB_BDIR}"
INSTALL_COMMAND ${GENTAB_BDIR}/make_tables.exe "${FluidSynth_BINARY_DIR}/"
INSTALL_COMMAND ${GENTAB_BDIR}/make_tables.exe "${CMAKE_BINARY_DIR}/"
)
add_dependencies(libfluidsynth-OBJ gentables)

View file

@ -441,14 +441,14 @@ fluid_command(fluid_cmd_handler_t *handler, const char *cmd, fluid_ostream_t out
return 1;
}
if(!fluid_shell_parse_argv(cmd, &num_tokens, &tokens))
if(!g_shell_parse_argv(cmd, &num_tokens, &tokens, NULL))
{
fluid_ostream_printf(out, "Error parsing command\n");
return FLUID_FAILED;
}
result = fluid_cmd_handler_handle(handler, num_tokens, &tokens[0], out);
fluid_strfreev(tokens);
g_strfreev(tokens);
return result;
}
@ -1137,7 +1137,7 @@ fluid_handle_reverbpreset(void *data, int ac, char **av, fluid_ostream_t out)
/*
The function is useful for reverb and chorus commands which have
1 or 2 parameters.
The function checks that there is 1 or 2 arguments.
The function checks that there is 1 or 2 aguments.
When there is 2 parameters it checks the first argument that must be
an fx group index in the range[0..synth->effects_groups-1].
@ -1159,7 +1159,7 @@ static int check_fx_group_idx(int ac, char **av, fluid_ostream_t out,
return -2;
}
/* check optional first argument which is a fx group index */
/* check optionnal first argument which is a fx group index */
fx_group = -1;
if(ac > 1)

View file

@ -199,7 +199,6 @@ new_fluid_file_renderer(fluid_synth_t *synth)
double samplerate;
int retval;
#endif
int audio_channels;
char *filename = NULL;
fluid_file_renderer_t *dev;
@ -234,7 +233,6 @@ new_fluid_file_renderer(fluid_synth_t *synth)
}
fluid_settings_dupstr(synth->settings, "audio.file.name", &filename);
fluid_settings_getint(synth->settings, "synth.audio-channels", &audio_channels);
if(filename == NULL)
{
@ -312,11 +310,6 @@ new_fluid_file_renderer(fluid_synth_t *synth)
#endif
if(audio_channels != 1)
{
FLUID_LOG(FLUID_WARN, "The file-renderer currently only supports a single stereo channel. You have provided %d stereo channels. Audio may sound strange or incomplete.", audio_channels);
}
FLUID_FREE(filename);
return dev;

View file

@ -509,8 +509,8 @@ int fluid_ladspa_reset(fluid_ladspa_fx_t *fx)
* @param block_count number of blocks to render
* @param block_size number of samples in a block
*
* FluidSynth calls this function during main output mixing,
* just before processing the internal reverb and chorus effects.
* FluidSynth calls this function during main output mixing, just after
* the internal reverb and chorus effects have been processed.
*
* It copies audio data from the supplied buffers, runs all effects and copies the
* resulting audio back into the same buffers.
@ -1325,16 +1325,13 @@ static void delete_fluid_ladspa_effect(fluid_ladspa_effect_t *effect)
* are private to this effect, so we can safely remove them here. Nodes connected
* to audio ports might be connected to other effects as well, so we simply remove
* any pointers to them from the effect. */
if(effect->desc != NULL)
for(i = 0; i < effect->desc->PortCount; i++)
{
for(i = 0; i < effect->desc->PortCount; i++)
{
node = (fluid_ladspa_node_t *) effect->port_nodes[i];
node = (fluid_ladspa_node_t *) effect->port_nodes[i];
if(node && node->type & FLUID_LADSPA_NODE_CONTROL)
{
delete_fluid_ladspa_node(node);
}
if(node && node->type & FLUID_LADSPA_NODE_CONTROL)
{
delete_fluid_ladspa_node(node);
}
}

View file

@ -130,9 +130,6 @@
/* Define to enable JACK driver */
#cmakedefine JACK_SUPPORT @JACK_SUPPORT@
/* Define to enable PipeWire driver */
#cmakedefine PIPEWIRE_SUPPORT @PIPEWIRE_SUPPORT@
/* Include the LADSPA Fx unit */
#cmakedefine LADSPA @LADSPA_SUPPORT@
@ -215,9 +212,7 @@
#cmakedefine TEST_SOUNDFONT "@TEST_SOUNDFONT@"
/* Soundfont to load for UTF-8 unit testing */
#cmakedefine TEST_SOUNDFONT_UTF8_1 "@TEST_SOUNDFONT_UTF8_1@"
#cmakedefine TEST_SOUNDFONT_UTF8_2 "@TEST_SOUNDFONT_UTF8_2@"
#cmakedefine TEST_MIDI_UTF8 "@TEST_MIDI_UTF8@"
#cmakedefine TEST_SOUNDFONT_UTF8 "@TEST_SOUNDFONT_UTF8@"
/* SF3 Soundfont to load for unit testing */
#cmakedefine TEST_SOUNDFONT_SF3 "@TEST_SOUNDFONT_SF3@"
@ -265,10 +260,4 @@
/* Define to 1 if you have the logf() function. */
#cmakedefine HAVE_LOGF @HAVE_LOGF@
/* Define to 1 if you have the socklen_t type. */
#cmakedefine HAVE_SOCKLEN_T @HAVE_SOCKLEN_T@
/* Define if using glib stubs instead of real glib. */
#cmakedefine WITH_GLIB_STUBS
#endif /* CONFIG_H */

View file

@ -70,16 +70,6 @@ static const fluid_audriver_definition_t fluid_audio_drivers[] =
},
#endif
#if PIPEWIRE_SUPPORT
{
"pipewire",
new_fluid_pipewire_audio_driver,
new_fluid_pipewire_audio_driver2,
delete_fluid_pipewire_audio_driver,
fluid_pipewire_audio_driver_settings
},
#endif
#if OSS_SUPPORT
{
"oss",
@ -320,9 +310,8 @@ find_fluid_audio_driver(fluid_settings_t *settings)
* Otherwise the behaviour is undefined.
*
* @note As soon as an audio driver is created, the \p synth starts rendering audio.
* This means that all necessary initialization and sound-setup should have been
* completed before calling this function.
* Thus, of all object types in use (synth, midi player, sequencer, etc.) the 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.
*/
@ -333,20 +322,7 @@ new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
if(def)
{
fluid_audio_driver_t *driver;
double srate, midi_event_latency;
int period_size;
fluid_settings_getint(settings, "audio.period-size", &period_size);
fluid_settings_getnum(settings, "synth.sample-rate", &srate);
midi_event_latency = period_size / srate;
if(midi_event_latency >= 0.05)
{
FLUID_LOG(FLUID_WARN, "You have chosen 'audio.period-size' to be %d samples. Given a sample rate of %.1f this results in a latency of %.1f ms, which will cause MIDI events to be poorly quantized (=untimed) in the synthesized audio (also known as the 'drunken-drummer' syndrome). To avoid that, you're strongly advised to increase 'audio.periods' instead, while keeping 'audio.period-size' small enough to make this warning disappear.", period_size, srate, midi_event_latency*1000.0);
}
driver = (*def->new)(settings, synth);
fluid_audio_driver_t *driver = (*def->new)(settings, synth);
if(driver)
{

View file

@ -23,10 +23,6 @@
#include "fluidsynth_priv.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* fluid_audio_driver_t
*/
@ -142,14 +138,6 @@ void fluid_jack_audio_driver_settings(fluid_settings_t *settings);
int fluid_jack_obtain_synth(fluid_settings_t *settings, fluid_synth_t **synth);
#endif
#if PIPEWIRE_SUPPORT
fluid_audio_driver_t *new_fluid_pipewire_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth);
fluid_audio_driver_t *new_fluid_pipewire_audio_driver2(fluid_settings_t *settings,
fluid_audio_func_t func, void *data);
void delete_fluid_pipewire_audio_driver(fluid_audio_driver_t *p);
void fluid_pipewire_audio_driver_settings(fluid_settings_t *settings);
#endif
#if SNDMAN_SUPPORT
fluid_audio_driver_t *new_fluid_sndmgr_audio_driver(fluid_settings_t *settings,
fluid_synth_t *synth);
@ -179,8 +167,6 @@ fluid_audio_driver_t *new_fluid_file_audio_driver(fluid_settings_t *settings,
void delete_fluid_file_audio_driver(fluid_audio_driver_t *p);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _FLUID_AUDRIVER_H */

View file

@ -553,7 +553,7 @@ static fluid_thread_return_t fluid_alsa_audio_run_s16(void *d)
{
FLUID_MEMSET(left, 0, buffer_size * sizeof(*left));
FLUID_MEMSET(right, 0, buffer_size * sizeof(*right));
(*dev->callback)(dev->data, buffer_size, 0, NULL, 2, handle);
/* convert floating point data to 16 bit (with dithering) */
@ -1347,26 +1347,6 @@ fluid_alsa_seq_run(void *d)
}
break;
case SND_SEQ_EVENT_START:
evt.type = MIDI_START;
break;
case SND_SEQ_EVENT_CONTINUE:
evt.type = MIDI_CONTINUE;
break;
case SND_SEQ_EVENT_STOP:
evt.type = MIDI_STOP;
break;
case SND_SEQ_EVENT_CLOCK:
evt.type = MIDI_SYNC;
break;
case SND_SEQ_EVENT_RESET:
evt.type = MIDI_SYSTEM_RESET;
break;
default:
continue; /* unhandled event, next loop iteration */
}

View file

@ -39,6 +39,7 @@
typedef struct
{
fluid_audio_driver_t driver;
fluid_audio_func_t callback;
void *data;
fluid_file_renderer_t *renderer;
int period_size;
@ -48,7 +49,7 @@ typedef struct
} fluid_file_audio_driver_t;
static int fluid_file_audio_run(void *d, unsigned int msec);
static int fluid_file_audio_run_s16(void *d, unsigned int msec);
/**************************************************************
*
@ -77,6 +78,7 @@ new_fluid_file_audio_driver(fluid_settings_t *settings,
fluid_settings_getnum(settings, "synth.sample-rate", &dev->sample_rate);
dev->data = synth;
dev->callback = (fluid_audio_func_t) fluid_synth_process;
dev->samples = 0;
dev->renderer = new_fluid_file_renderer(synth);
@ -87,7 +89,7 @@ new_fluid_file_audio_driver(fluid_settings_t *settings,
}
msec = (int)(0.5 + dev->period_size / dev->sample_rate * 1000.0);
dev->timer = new_fluid_timer(msec, fluid_file_audio_run, (void *) dev, TRUE, FALSE, TRUE);
dev->timer = new_fluid_timer(msec, fluid_file_audio_run_s16, (void *) dev, TRUE, FALSE, TRUE);
if(dev->timer == NULL)
{
@ -113,7 +115,7 @@ void delete_fluid_file_audio_driver(fluid_audio_driver_t *p)
FLUID_FREE(dev);
}
static int fluid_file_audio_run(void *d, unsigned int clock_time)
static int fluid_file_audio_run_s16(void *d, unsigned int clock_time)
{
fluid_file_audio_driver_t *dev = (fluid_file_audio_driver_t *) d;
unsigned int sample_time;

View file

@ -27,10 +27,10 @@
#include "fluid_adriver.h"
#include "fluid_settings.h"
/*
/*
* !!! Make sure that no include above includes <netinet/tcp.h> !!!
* It #defines some macros that collide with enum definitions of OpenTransportProviders.h, which is included from OSServices.h, included from CoreServices.h
*
*
* https://trac.macports.org/ticket/36962
*/
@ -52,8 +52,7 @@ typedef struct
fluid_audio_func_t callback;
void *data;
unsigned int buffer_size;
unsigned int buffer_count;
float **buffers;
float *buffers[2];
double phase;
} fluid_core_audio_driver_t;
@ -74,10 +73,6 @@ OSStatus fluid_core_audio_callback(void *data,
#define OK(x) (x == noErr)
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 120000
#define kAudioObjectPropertyElementMain (kAudioObjectPropertyElementMaster)
#endif
int
get_num_outputs(AudioDeviceID deviceID)
{
@ -86,7 +81,7 @@ get_num_outputs(AudioDeviceID deviceID)
AudioObjectPropertyAddress pa;
pa.mSelector = kAudioDevicePropertyStreamConfiguration;
pa.mScope = kAudioDevicePropertyScopeOutput;
pa.mElement = kAudioObjectPropertyElementMain;
pa.mElement = kAudioObjectPropertyElementMaster;
if(OK(AudioObjectGetPropertyDataSize(deviceID, &pa, 0, 0, &size)) && size > 0)
{
@ -115,76 +110,6 @@ get_num_outputs(AudioDeviceID deviceID)
return total;
}
void
set_channel_map(AudioUnit outputUnit, int audio_channels, const char *map_string)
{
OSStatus status;
long int number_of_channels;
int i, *channel_map;
UInt32 property_size;
Boolean writable = false;
status = AudioUnitGetPropertyInfo(outputUnit,
kAudioOutputUnitProperty_ChannelMap,
kAudioUnitScope_Output,
0,
&property_size, &writable);
if(status != noErr)
{
FLUID_LOG(FLUID_ERR, "Failed to get the channel map size. Status=%ld\n", (long int) status);
return;
}
number_of_channels = property_size / sizeof(int);
if(!number_of_channels)
{
return;
}
channel_map = FLUID_ARRAY(int, number_of_channels);
if(channel_map == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory.\n");
return;
}
FLUID_MEMSET(channel_map, 0xff, property_size);
status = AudioUnitGetProperty(outputUnit,
kAudioOutputUnitProperty_ChannelMap,
kAudioUnitScope_Output,
0,
channel_map, &property_size);
if(status != noErr)
{
FLUID_LOG(FLUID_ERR, "Failed to get the existing channel map. Status=%ld\n", (long int) status);
FLUID_FREE(channel_map);
return;
}
fluid_settings_split_csv(map_string, channel_map, (int) number_of_channels);
for(i = 0; i < number_of_channels; i++)
{
if(channel_map[i] < -1 || channel_map[i] >= audio_channels)
{
FLUID_LOG(FLUID_DBG, "Channel map of output channel %d is out-of-range. Silencing.", i);
channel_map[i] = -1;
}
}
status = AudioUnitSetProperty(outputUnit,
kAudioOutputUnitProperty_ChannelMap,
kAudioUnitScope_Output,
0,
channel_map, property_size);
if(status != noErr)
{
FLUID_LOG(FLUID_ERR, "Failed to set the channel map. Status=%ld\n", (long int) status);
}
FLUID_FREE(channel_map);
}
void
fluid_core_audio_driver_settings(fluid_settings_t *settings)
{
@ -193,10 +118,9 @@ fluid_core_audio_driver_settings(fluid_settings_t *settings)
AudioObjectPropertyAddress pa;
pa.mSelector = kAudioHardwarePropertyDevices;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMain;
pa.mElement = kAudioObjectPropertyElementMaster;
fluid_settings_register_str(settings, "audio.coreaudio.device", "default", 0);
fluid_settings_register_str(settings, "audio.coreaudio.channel-map", "", 0);
fluid_settings_add_option(settings, "audio.coreaudio.device", "default");
if(OK(AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &pa, 0, 0, &size)))
@ -241,21 +165,13 @@ new_fluid_core_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
fluid_audio_driver_t *
new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
{
char *devname = NULL, *channel_map = NULL;
char *devname = NULL;
fluid_core_audio_driver_t *dev = NULL;
int period_size, periods, audio_channels = 1;
int period_size, periods;
double sample_rate;
OSStatus status;
UInt32 size;
int i;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
ComponentDescription desc;
Component comp;
#else
AudioComponentDescription desc;
AudioComponent comp;
#endif
AURenderCallbackStruct render;
dev = FLUID_NEW(fluid_core_audio_driver_t);
@ -271,17 +187,14 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
dev->data = data;
// Open the default output unit
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_HALOutput; //kAudioUnitSubType_DefaultOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
comp = FindNextComponent(NULL, &desc);
#else
comp = AudioComponentFindNext(NULL, &desc);
#endif
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
if(comp == NULL)
{
@ -289,11 +202,7 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
goto error_recovery;
}
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
status = OpenAComponent(comp, &dev->outputUnit);
#else
status = AudioComponentInstanceNew(comp, &dev->outputUnit);
#endif
if(status != noErr)
{
@ -302,6 +211,7 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
}
// Set up a callback function to generate output
AURenderCallbackStruct render;
render.inputProc = fluid_core_audio_callback;
render.inputProcRefCon = (void *) dev;
status = AudioUnitSetProperty(dev->outputUnit,
@ -317,14 +227,10 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
goto error_recovery;
}
fluid_settings_getint(settings, "synth.audio-channels", &audio_channels);
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
fluid_settings_getint(settings, "audio.periods", &periods);
fluid_settings_getint(settings, "audio.period-size", &period_size);
/* audio channels are in stereo, with a minimum of one pair */
audio_channels = (audio_channels > 0) ? (2 * audio_channels) : 2;
/* get the selected device name. if none is specified, use NULL for the default device. */
if(fluid_settings_dupstr(settings, "audio.coreaudio.device", &devname) == FLUID_OK /* alloc device name */
&& devname && strlen(devname) > 0)
@ -332,7 +238,7 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
AudioObjectPropertyAddress pa;
pa.mSelector = kAudioHardwarePropertyDevices;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMain;
pa.mElement = kAudioObjectPropertyElementMaster;
if(OK(AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &pa, 0, 0, &size)))
{
@ -379,11 +285,11 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
// necessary from our format to the device's format.
dev->format.mSampleRate = sample_rate; // sample rate of the audio stream
dev->format.mFormatID = kAudioFormatLinearPCM; // encoding type of the audio stream
dev->format.mFormatFlags = kLinearPCMFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved;
dev->format.mBytesPerPacket = sizeof(float);
dev->format.mFormatFlags = kLinearPCMFormatFlagIsFloat;
dev->format.mBytesPerPacket = 2 * sizeof(float);
dev->format.mFramesPerPacket = 1;
dev->format.mBytesPerFrame = sizeof(float);
dev->format.mChannelsPerFrame = audio_channels;
dev->format.mBytesPerFrame = 2 * sizeof(float);
dev->format.mChannelsPerFrame = 2;
dev->format.mBitsPerChannel = 8 * sizeof(float);
FLUID_LOG(FLUID_DBG, "mSampleRate %g", dev->format.mSampleRate);
@ -407,13 +313,6 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
goto error_recovery;
}
if(fluid_settings_dupstr(settings, "audio.coreaudio.channel-map", &channel_map) == FLUID_OK /* alloc channel map */
&& channel_map && strlen(channel_map) > 0)
{
set_channel_map(dev->outputUnit, audio_channels, channel_map);
}
FLUID_FREE(channel_map); /* free channel map */
status = AudioUnitSetProperty(dev->outputUnit,
kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Input,
@ -429,16 +328,15 @@ new_fluid_core_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
FLUID_LOG(FLUID_DBG, "MaximumFramesPerSlice = %d", dev->buffer_size);
dev->buffers = FLUID_ARRAY(float *, audio_channels);
if(dev->buffers == NULL)
dev->buffers[0] = FLUID_ARRAY(float, dev->buffer_size);
dev->buffers[1] = FLUID_ARRAY(float, dev->buffer_size);
if(dev->buffers[0] == NULL || dev->buffers[1] == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory.");
goto error_recovery;
}
dev->buffer_count = (unsigned int) audio_channels;
// Initialize the audio unit
status = AudioUnitInitialize(dev->outputUnit);
@ -474,15 +372,16 @@ delete_fluid_core_audio_driver(fluid_audio_driver_t *p)
fluid_core_audio_driver_t *dev = (fluid_core_audio_driver_t *) p;
fluid_return_if_fail(dev != NULL);
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
CloseComponent(dev->outputUnit);
#else
AudioComponentInstanceDispose(dev->outputUnit);
#endif
if(dev->buffers != NULL)
if(dev->buffers[0])
{
FLUID_FREE(dev->buffers);
FLUID_FREE(dev->buffers[0]);
}
if(dev->buffers[1])
{
FLUID_FREE(dev->buffers[1]);
}
FLUID_FREE(dev);
@ -496,18 +395,30 @@ fluid_core_audio_callback(void *data,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
int i, k;
fluid_core_audio_driver_t *dev = (fluid_core_audio_driver_t *) data;
int len = inNumberFrames;
UInt32 i, nBuffers = ioData->mNumberBuffers;
fluid_audio_func_t callback = (dev->callback != NULL) ? dev->callback : (fluid_audio_func_t) fluid_synth_process;
float *buffer = ioData->mBuffers[0].mData;
for(i = 0; i < ioData->mNumberBuffers && i < dev->buffer_count; i++)
if(dev->callback)
{
dev->buffers[i] = ioData->mBuffers[i].mData;
FLUID_MEMSET(dev->buffers[i], 0, len * sizeof(float));
}
float *left = dev->buffers[0];
float *right = dev->buffers[1];
callback(dev->data, len, nBuffers, dev->buffers, nBuffers, dev->buffers);
FLUID_MEMSET(left, 0, len * sizeof(float));
FLUID_MEMSET(right, 0, len * sizeof(float));
(*dev->callback)(dev->data, len, 0, NULL, 2, dev->buffers);
for(i = 0, k = 0; i < len; i++)
{
buffer[k++] = left[i];
buffer[k++] = right[i];
}
}
else
fluid_synth_write_float((fluid_synth_t *) dev->data, len, buffer, 0, 2,
buffer, 1, 2);
return noErr;
}

View file

@ -49,7 +49,6 @@
/* End work around */
#include <unistd.h>
#include <os/log.h>
#include <CoreServices/CoreServices.h>
#include <CoreMIDI/MIDIServices.h>
@ -63,10 +62,6 @@ typedef struct
int autoconn_inputs;
} fluid_coremidi_driver_t;
static const MIDIClientRef invalid_client = (MIDIClientRef)-1;
static const MIDIEndpointRef invalid_endpoint = (MIDIEndpointRef)-1;
static const MIDIPortRef invalid_port = (MIDIPortRef)-1;
void fluid_coremidi_callback(const MIDIPacketList *list, void *p, void *src);
void fluid_coremidi_driver_settings(fluid_settings_t *settings)
@ -113,8 +108,6 @@ new_fluid_coremidi_driver(fluid_settings_t *settings, handle_midi_event_func_t h
char *id;
CFStringRef str_portname;
CFStringRef str_clientname;
OSStatus result;
CFStringRef str_input_portname;
/* not much use doing anything */
if(handler == NULL)
@ -131,10 +124,9 @@ new_fluid_coremidi_driver(fluid_settings_t *settings, handle_midi_event_func_t h
return NULL;
}
dev->client = invalid_client;
dev->endpoint = invalid_endpoint;
dev->input_port = invalid_port;
dev->parser = NULL;
dev->client = 0;
dev->endpoint = 0;
dev->parser = 0;
dev->driver.handler = handler;
dev->driver.data = data;
@ -181,7 +173,7 @@ new_fluid_coremidi_driver(fluid_settings_t *settings, handle_midi_event_func_t h
FLUID_FREE(portname); /* -- free port name */
}
result = MIDIClientCreate(str_clientname, NULL, NULL, &client);
OSStatus result = MIDIClientCreate(str_clientname, NULL, NULL, &client);
CFRelease(str_clientname);
if(result != noErr)
@ -202,7 +194,7 @@ new_fluid_coremidi_driver(fluid_settings_t *settings, handle_midi_event_func_t h
goto error_recovery;
}
str_input_portname = CFSTR("input");
CFStringRef str_input_portname = CFSTR("input");
result = MIDIInputPortCreate(client, str_input_portname,
fluid_coremidi_callback,
(void *)dev, &dev->input_port);
@ -239,17 +231,17 @@ delete_fluid_coremidi_driver(fluid_midi_driver_t *p)
fluid_coremidi_driver_t *dev = (fluid_coremidi_driver_t *) p;
fluid_return_if_fail(dev != NULL);
if(dev->input_port != invalid_port)
if(dev->input_port != NULL)
{
MIDIPortDispose(dev->input_port);
}
if(dev->client != invalid_client)
if(dev->client != NULL)
{
MIDIClientDispose(dev->client);
}
if(dev->endpoint != invalid_endpoint)
if(dev->endpoint != NULL)
{
MIDIEndpointDispose(dev->endpoint);
}

View file

@ -614,14 +614,14 @@ new_fluid_jack_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
{
jack_ports = jack_get_ports(client, NULL, NULL, JackPortIsInput | JackPortIsPhysical);
if(jack_ports && jack_ports[0])
if(jack_ports)
{
int err, o = 0;
int err;
int connected = 0;
for(i = 0; i < 2 * dev->num_output_ports; ++i)
for(i = 0; jack_ports[i] && i < 2 * dev->num_output_ports; ++i)
{
err = jack_connect(client, jack_port_name(dev->output_ports[i]), jack_ports[o++]);
err = jack_connect(client, jack_port_name(dev->output_ports[i]), jack_ports[i]);
if(err)
{
@ -631,17 +631,11 @@ new_fluid_jack_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
{
connected++;
}
if(!jack_ports[o])
{
o = 0;
}
}
o = 0;
for(i = 0; i < 2 * dev->num_fx_ports; ++i)
for(i = 0; jack_ports[i] && i < 2 * dev->num_fx_ports; ++i)
{
err = jack_connect(client, jack_port_name(dev->fx_ports[i]), jack_ports[o++]);
err = jack_connect(client, jack_port_name(dev->fx_ports[i]), jack_ports[i]);
if(err)
{
@ -651,11 +645,6 @@ new_fluid_jack_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
{
connected++;
}
if(!jack_ports[o])
{
o = 0;
}
}
jack_free(jack_ports); /* free jack ports array (not the port values!) */

View file

@ -87,17 +87,6 @@ new_fluid_midishare_midi_driver(fluid_settings_t *settings,
fluid_midishare_midi_driver_t *dev;
int i;
FLUID_LOG(FLUID_WARN,
"\n\n"
"================ MidiShare MIDI driver has been deprecated! =================\n"
"You're using the MidiShare driver. This driver is old, unmaintained and believed\n"
"to be unused. If you still need it, pls. let us know by posting to our\n"
"mailing list at fluid-dev@nongnu.org - otherwise this driver might be removed\n"
"in a future release of FluidSynth!\n"
"================ MidiShare MIDI driver has been deprecated! =================\n"
"\n"
);
/* not much use doing anything */
if(handler == NULL)
{

View file

@ -25,9 +25,13 @@
* This file may make use of C++14, because it's required by oboe anyway.
*/
extern "C" {
#include "fluid_adriver.h"
#include "fluid_settings.h"
} // extern "C"
#if OBOE_SUPPORT
#include <oboe/Oboe.h>
@ -39,7 +43,6 @@ using namespace oboe;
constexpr int NUM_CHANNELS = 2;
class OboeAudioStreamCallback;
class OboeAudioStreamErrorCallback;
/** fluid_oboe_audio_driver_t
*
@ -52,16 +55,7 @@ typedef struct
fluid_synth_t *synth = nullptr;
bool cont = false;
std::unique_ptr<OboeAudioStreamCallback> oboe_callback;
std::unique_ptr<OboeAudioStreamErrorCallback> oboe_error_callback;
std::shared_ptr<AudioStream> stream;
double sample_rate;
int is_sample_format_float;
int device_id;
int sharing_mode; // 0: Shared, 1: Exclusive
int performance_mode; // 0: None, 1: PowerSaving, 2: LowLatency
oboe::SampleRateConversionQuality srate_conversion_quality;
int error_recovery_mode; // 0: Reconnect, 1: Stop
} fluid_oboe_audio_driver_t;
@ -99,34 +93,20 @@ private:
void *user_data;
};
class OboeAudioStreamErrorCallback : public AudioStreamErrorCallback
{
fluid_oboe_audio_driver_t *dev;
public:
OboeAudioStreamErrorCallback(fluid_oboe_audio_driver_t *dev) : dev(dev) {}
void onErrorAfterClose(AudioStream *stream, Result result);
};
constexpr char OBOE_ID[] = "audio.oboe.id";
constexpr char SHARING_MODE[] = "audio.oboe.sharing-mode";
constexpr char PERF_MODE[] = "audio.oboe.performance-mode";
constexpr char SRCQ_SET[] = "audio.oboe.sample-rate-conversion-quality";
constexpr char RECOVERY_MODE[] = "audio.oboe.error-recovery-mode";
void fluid_oboe_audio_driver_settings(fluid_settings_t *settings)
{
fluid_settings_register_int(settings, OBOE_ID, 0, 0, 0x7FFFFFFF, 0);
fluid_settings_register_int(settings, "audio.oboe.id", 0, 0, 0x7FFFFFFF, 0);
fluid_settings_register_str(settings, SHARING_MODE, "Shared", 0);
fluid_settings_add_option(settings, SHARING_MODE, "Shared");
fluid_settings_add_option(settings, SHARING_MODE, "Exclusive");
fluid_settings_register_str(settings, "audio.oboe.sharing-mode", "Shared", 0);
fluid_settings_add_option(settings, "audio.oboe.sharing-mode", "Shared");
fluid_settings_add_option(settings, "audio.oboe.sharing-mode", "Exclusive");
fluid_settings_register_str(settings, PERF_MODE, "None", 0);
fluid_settings_add_option(settings, PERF_MODE, "None");
fluid_settings_add_option(settings, PERF_MODE, "PowerSaving");
fluid_settings_add_option(settings, PERF_MODE, "LowLatency");
fluid_settings_register_str(settings, "audio.oboe.performance-mode", "None", 0);
fluid_settings_add_option(settings, "audio.oboe.performance-mode", "None");
fluid_settings_add_option(settings, "audio.oboe.performance-mode", "PowerSaving");
fluid_settings_add_option(settings, "audio.oboe.performance-mode", "LowLatency");
fluid_settings_register_str(settings, SRCQ_SET, "Medium", 0);
fluid_settings_add_option(settings, SRCQ_SET, "None");
@ -135,10 +115,6 @@ void fluid_oboe_audio_driver_settings(fluid_settings_t *settings)
fluid_settings_add_option(settings, SRCQ_SET, "Medium");
fluid_settings_add_option(settings, SRCQ_SET, "High");
fluid_settings_add_option(settings, SRCQ_SET, "Best");
fluid_settings_register_str(settings, RECOVERY_MODE, "Reconnect", 0);
fluid_settings_add_option(settings, RECOVERY_MODE, "Reconnect");
fluid_settings_add_option(settings, RECOVERY_MODE, "Stop");
}
static oboe::SampleRateConversionQuality get_srate_conversion_quality(fluid_settings_t *settings)
@ -181,28 +157,6 @@ static oboe::SampleRateConversionQuality get_srate_conversion_quality(fluid_sett
return q;
}
Result
fluid_oboe_connect_or_reconnect(fluid_oboe_audio_driver_t *dev)
{
AudioStreamBuilder builder;
builder.setDeviceId(dev->device_id)
->setDirection(Direction::Output)
->setChannelCount(NUM_CHANNELS)
->setSampleRate(dev->sample_rate)
->setFormat(dev->is_sample_format_float ? AudioFormat::Float : AudioFormat::I16)
->setSharingMode(dev->sharing_mode == 1 ? SharingMode::Exclusive : SharingMode::Shared)
->setPerformanceMode(
dev->performance_mode == 1 ? PerformanceMode::PowerSaving :
dev->performance_mode == 2 ? PerformanceMode::LowLatency : PerformanceMode::None)
->setUsage(Usage::Media)
->setContentType(ContentType::Music)
->setCallback(dev->oboe_callback.get())
->setErrorCallback(dev->oboe_error_callback.get())
->setSampleRateConversionQuality(dev->srate_conversion_quality);
return builder.openStream(dev->stream);
}
/*
* new_fluid_oboe_audio_driver
*/
@ -214,24 +168,44 @@ new_fluid_oboe_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
try
{
Result result;
AudioStreamBuilder builder_obj;
AudioStreamBuilder *builder = &builder_obj;
double sample_rate;
int is_sample_format_float;
int device_id;
int sharing_mode; // 0: Shared, 1: Exclusive
int performance_mode; // 0: None, 1: PowerSaving, 2: LowLatency
dev = new fluid_oboe_audio_driver_t();
dev->synth = synth;
dev->oboe_callback = std::make_unique<OboeAudioStreamCallback>(dev);
dev->oboe_error_callback = std::make_unique<OboeAudioStreamErrorCallback>(dev);
fluid_settings_getnum(settings, "synth.sample-rate", &dev->sample_rate);
dev->is_sample_format_float = fluid_settings_str_equal(settings, "audio.sample-format", "float");
fluid_settings_getint(settings, OBOE_ID, &dev->device_id);
dev->sharing_mode =
fluid_settings_str_equal(settings, SHARING_MODE, "Exclusive") ? 1 : 0;
dev->performance_mode =
fluid_settings_str_equal(settings, PERF_MODE, "PowerSaving") ? 1 :
fluid_settings_str_equal(settings, PERF_MODE, "LowLatency") ? 2 : 0;
dev->srate_conversion_quality = get_srate_conversion_quality(settings);
dev->error_recovery_mode = fluid_settings_str_equal(settings, RECOVERY_MODE, "Stop") ? 1 : 0;
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
is_sample_format_float = fluid_settings_str_equal(settings, "audio.sample-format", "float");
fluid_settings_getint(settings, "audio.oboe.id", &device_id);
sharing_mode =
fluid_settings_str_equal(settings, "audio.oboe.sharing-mode", "Exclusive") ? 1 : 0;
performance_mode =
fluid_settings_str_equal(settings, "audio.oboe.performance-mode", "PowerSaving") ? 1 :
fluid_settings_str_equal(settings, "audio.oboe.performance-mode", "LowLatency") ? 2 : 0;
result = fluid_oboe_connect_or_reconnect(dev);
builder->setDeviceId(device_id)
->setDirection(Direction::Output)
->setChannelCount(NUM_CHANNELS)
->setSampleRate(sample_rate)
->setFormat(is_sample_format_float ? AudioFormat::Float : AudioFormat::I16)
->setSharingMode(sharing_mode == 1 ? SharingMode::Exclusive : SharingMode::Shared)
->setPerformanceMode(
performance_mode == 1 ? PerformanceMode::PowerSaving :
performance_mode == 2 ? PerformanceMode::LowLatency : PerformanceMode::None)
->setUsage(Usage::Media)
->setContentType(ContentType::Music)
->setCallback(dev->oboe_callback.get())
->setSampleRateConversionQuality(get_srate_conversion_quality(settings));
result = builder->openStream(dev->stream);
if(result != Result::OK)
{
@ -295,38 +269,5 @@ void delete_fluid_oboe_audio_driver(fluid_audio_driver_t *p)
delete dev;
}
void
OboeAudioStreamErrorCallback::onErrorAfterClose(AudioStream *stream, Result result)
{
if(dev->error_recovery_mode == 1) // Stop
{
FLUID_LOG(FLUID_ERR, "Oboe driver encountered an error (such as earphone unplugged). Stopped.");
dev->stream.reset();
return;
}
else
{
FLUID_LOG(FLUID_WARN, "Oboe driver encountered an error (such as earphone unplugged). Recovering...");
}
result = fluid_oboe_connect_or_reconnect(dev);
if(result != Result::OK)
{
FLUID_LOG(FLUID_ERR, "Unable to reconnect Oboe audio stream");
return; // cannot do anything further
}
// start the new stream.
result = dev->stream->start();
if(result != Result::OK)
{
FLUID_LOG(FLUID_ERR, "Unable to restart Oboe audio stream");
return; // cannot do anything further
}
}
#endif // OBOE_SUPPORT

View file

@ -187,18 +187,9 @@ new_fluid_oss_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
}
}
dev->dspfd = open(devname, O_WRONLY, 0);
if(dev->dspfd == -1)
if(stat(devname, &devstat) == -1)
{
FLUID_LOG(FLUID_ERR, "Device <%s> could not be opened for writing: %s",
devname, g_strerror(errno));
goto error_recovery;
}
if(fstat(dev->dspfd, &devstat) == -1)
{
FLUID_LOG(FLUID_ERR, "fstat failed on device <%s>: %s", devname, g_strerror(errno));
FLUID_LOG(FLUID_ERR, "Device <%s> does not exists", devname);
goto error_recovery;
}
@ -208,6 +199,15 @@ new_fluid_oss_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
goto error_recovery;
}
dev->dspfd = open(devname, O_WRONLY, 0);
if(dev->dspfd == -1)
{
FLUID_LOG(FLUID_ERR, "Device <%s> could not be opened for writing: %s",
devname, strerror(errno));
goto error_recovery;
}
if(fluid_oss_set_queue_size(dev, sample_size, 2, queuesize, period_size) < 0)
{
FLUID_LOG(FLUID_ERR, "Can't set device buffer size");
@ -333,18 +333,9 @@ new_fluid_oss_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func,
}
}
dev->dspfd = open(devname, O_WRONLY, 0);
if(dev->dspfd == -1)
if(stat(devname, &devstat) == -1)
{
FLUID_LOG(FLUID_ERR, "Device <%s> could not be opened for writing: %s",
devname, g_strerror(errno));
goto error_recovery;
}
if(fstat(dev->dspfd, &devstat) == -1)
{
FLUID_LOG(FLUID_ERR, "fstat failed on device <%s>: %s", devname, g_strerror(errno));
FLUID_LOG(FLUID_ERR, "Device <%s> does not exists", devname);
goto error_recovery;
}
@ -354,6 +345,16 @@ new_fluid_oss_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func,
goto error_recovery;
}
dev->dspfd = open(devname, O_WRONLY, 0);
if(dev->dspfd == -1)
{
FLUID_LOG(FLUID_ERR, "Device <%s> could not be opened for writing: %s",
devname, strerror(errno));
goto error_recovery;
}
if(fluid_oss_set_queue_size(dev, 16, 2, queuesize, period_size) < 0)
{
FLUID_LOG(FLUID_ERR, "Can't set device buffer size");
@ -403,7 +404,7 @@ new_fluid_oss_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func,
goto error_recovery;
}
/* allocate the buffers. */
/* allocate the buffers. FIXME!!! don't use interleaved samples */
dev->buffer = FLUID_MALLOC(dev->buffer_byte_size);
dev->buffers[0] = FLUID_ARRAY(float, dev->buffer_size);
dev->buffers[1] = FLUID_ARRAY(float, dev->buffer_size);
@ -463,8 +464,6 @@ delete_fluid_oss_audio_driver(fluid_audio_driver_t *p)
}
FLUID_FREE(dev->buffer);
FLUID_FREE(dev->buffers[0]);
FLUID_FREE(dev->buffers[1]);
FLUID_FREE(dev);
}
@ -667,7 +666,7 @@ new_fluid_oss_midi_driver(fluid_settings_t *settings,
if(fcntl(dev->fd, F_SETFL, O_NONBLOCK) == -1)
{
FLUID_LOG(FLUID_ERR, "Failed to set OSS MIDI device to non-blocking: %s",
g_strerror(errno));
strerror(errno));
goto error_recovery;
}
@ -756,7 +755,7 @@ fluid_oss_midi_run(void *d)
if(n < 0)
{
FLUID_LOG(FLUID_ERR, "Error waiting for MIDI input: %s", g_strerror(errno));
FLUID_LOG(FLUID_ERR, "Error waiting for MIDI input: %s", strerror(errno));
break;
}

View file

@ -1,324 +0,0 @@
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 Peter Hanappe and others.
* Copyright (C) 2021 E. "sykhro" Melucci
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
*/
/* fluid_pipewire.c
*
* Audio driver for PipeWire.
*
*/
#include "fluid_synth.h"
#include "fluid_adriver.h"
#include "fluid_settings.h"
#if PIPEWIRE_SUPPORT
#include <pipewire/pipewire.h>
#include <spa/param/audio/format-utils.h>
/* At the moment, only stereo is supported */
#define NUM_CHANNELS 2
static const int stride = sizeof(float) * NUM_CHANNELS;
typedef struct
{
fluid_audio_driver_t driver;
fluid_audio_func_t user_callback;
void *data;
/* Used only with the user-provided callback */
float *lbuf, *rbuf;
int buffer_period;
struct spa_pod_builder *builder;
struct pw_thread_loop *pw_loop;
struct pw_stream *pw_stream;
struct pw_stream_events *events;
} fluid_pipewire_audio_driver_t;
/* Fast-path rendering routine with no user processing callbacks */
static void fluid_pipewire_event_process(void *data)
{
fluid_pipewire_audio_driver_t *drv = data;
struct pw_buffer *pwb;
struct spa_buffer *buf;
float *dest;
pwb = pw_stream_dequeue_buffer(drv->pw_stream);
if(!pwb)
{
FLUID_LOG(FLUID_WARN, "No buffers!");
return;
}
buf = pwb->buffer;
dest = buf->datas[0].data;
if(!dest)
{
return;
}
fluid_synth_write_float(drv->data, drv->buffer_period, dest, 0, 2, dest, 1, 2);
buf->datas[0].chunk->offset = 0;
buf->datas[0].chunk->stride = stride;
buf->datas[0].chunk->size = drv->buffer_period * stride;
pw_stream_queue_buffer(drv->pw_stream, pwb);
}
/* Rendering routine with support for user-defined audio manipulation */
static void fluid_pipewire_event_process2(void *data)
{
fluid_pipewire_audio_driver_t *drv = data;
struct pw_buffer *pwb;
struct spa_buffer *buf;
float *dest;
float *channels[NUM_CHANNELS] = { drv->lbuf, drv->rbuf };
int i;
pwb = pw_stream_dequeue_buffer(drv->pw_stream);
if(!pwb)
{
FLUID_LOG(FLUID_WARN, "No buffers!");
return;
}
buf = pwb->buffer;
dest = buf->datas[0].data;
if(!dest)
{
return;
}
FLUID_MEMSET(drv->lbuf, 0, drv->buffer_period * sizeof(float));
FLUID_MEMSET(drv->rbuf, 0, drv->buffer_period * sizeof(float));
(*drv->user_callback)(drv->data, drv->buffer_period, 0, NULL, NUM_CHANNELS, channels);
/* Interleave the floating point data */
for(i = 0; i < drv->buffer_period; i++)
{
dest[i * 2] = drv->lbuf[i];
dest[i * 2 + 1] = drv->rbuf[i];
}
buf->datas[0].chunk->offset = 0;
buf->datas[0].chunk->stride = stride;
buf->datas[0].chunk->size = drv->buffer_period * stride;
pw_stream_queue_buffer(drv->pw_stream, pwb);
}
fluid_audio_driver_t *new_fluid_pipewire_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
{
return new_fluid_pipewire_audio_driver2(settings, NULL, synth);
}
fluid_audio_driver_t *
new_fluid_pipewire_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
{
fluid_pipewire_audio_driver_t *drv;
int period_size;
int buffer_length;
int res;
int pw_flags;
int realtime_prio = 0;
double sample_rate;
char *media_role = NULL;
char *media_type = NULL;
char *media_category = NULL;
float *buffer = NULL;
const struct spa_pod *params[1];
drv = FLUID_NEW(fluid_pipewire_audio_driver_t);
if(!drv)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
FLUID_MEMSET(drv, 0, sizeof(*drv));
fluid_settings_getint(settings, "audio.period-size", &period_size);
fluid_settings_getint(settings, "audio.realtime-prio", &realtime_prio);
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
fluid_settings_dupstr(settings, "audio.pipewire.media-role", &media_role);
fluid_settings_dupstr(settings, "audio.pipewire.media-type", &media_type);
fluid_settings_dupstr(settings, "audio.pipewire.media-category", &media_category);
drv->data = data;
drv->user_callback = func;
drv->buffer_period = period_size;
drv->events = FLUID_NEW(struct pw_stream_events);
if(!drv->events)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
goto driver_cleanup;
}
FLUID_MEMSET(drv->events, 0, sizeof(*drv->events));
drv->events->version = PW_VERSION_STREAM_EVENTS;
drv->events->process = func ? fluid_pipewire_event_process2 : fluid_pipewire_event_process;
drv->pw_loop = pw_thread_loop_new("fluid_pipewire", NULL);
if(!drv->pw_loop)
{
FLUID_LOG(FLUID_ERR, "Failed to allocate PipeWire loop. Have you called pw_init() ?");
goto driver_cleanup;
}
drv->pw_stream = pw_stream_new_simple(
pw_thread_loop_get_loop(drv->pw_loop),
"FluidSynth",
pw_properties_new(PW_KEY_MEDIA_TYPE, media_type, PW_KEY_MEDIA_CATEGORY, media_category, PW_KEY_MEDIA_ROLE, media_role, NULL),
drv->events,
drv);
if(!drv->pw_stream)
{
FLUID_LOG(FLUID_ERR, "Failed to allocate PipeWire stream");
goto driver_cleanup;
}
buffer = FLUID_ARRAY(float, NUM_CHANNELS * period_size);
if(!buffer)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
goto driver_cleanup;
}
buffer_length = period_size * sizeof(float) * NUM_CHANNELS;
drv->builder = FLUID_NEW(struct spa_pod_builder);
if(!drv->builder)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
goto driver_cleanup;
}
FLUID_MEMSET(drv->builder, 0, sizeof(*drv->builder));
drv->builder->data = buffer;
drv->builder->size = buffer_length;
if(func)
{
drv->lbuf = FLUID_ARRAY(float, period_size);
drv->rbuf = FLUID_ARRAY(float, period_size);
if(!drv->lbuf || !drv->rbuf)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
goto driver_cleanup;
}
}
params[0] = spa_format_audio_raw_build(drv->builder,
SPA_PARAM_EnumFormat,
&SPA_AUDIO_INFO_RAW_INIT(.format = SPA_AUDIO_FORMAT_F32,
.channels = 2,
.rate = sample_rate));
pw_flags = PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS;
pw_flags |= realtime_prio ? PW_STREAM_FLAG_RT_PROCESS : 0;
res = pw_stream_connect(drv->pw_stream, PW_DIRECTION_OUTPUT, PW_ID_ANY, pw_flags, params, 1);
if(res < 0)
{
FLUID_LOG(FLUID_ERR, "PipeWire stream connection failed");
goto driver_cleanup;
}
res = pw_thread_loop_start(drv->pw_loop);
if(res != 0)
{
FLUID_LOG(FLUID_ERR, "Failed starting PipeWire loop");
goto driver_cleanup;
}
FLUID_LOG(FLUID_INFO, "Using PipeWire audio driver");
FLUID_FREE(media_role);
FLUID_FREE(media_type);
FLUID_FREE(media_category);
return (fluid_audio_driver_t *)drv;
driver_cleanup:
FLUID_FREE(media_role);
FLUID_FREE(media_type);
FLUID_FREE(media_category);
delete_fluid_pipewire_audio_driver((fluid_audio_driver_t *)drv);
return NULL;
}
void delete_fluid_pipewire_audio_driver(fluid_audio_driver_t *p)
{
fluid_pipewire_audio_driver_t *drv = (fluid_pipewire_audio_driver_t *)p;
fluid_return_if_fail(drv);
if(drv->pw_stream)
{
pw_stream_destroy(drv->pw_stream);
}
if(drv->pw_loop)
{
pw_thread_loop_destroy(drv->pw_loop);
}
FLUID_FREE(drv->lbuf);
FLUID_FREE(drv->rbuf);
if(drv->builder)
{
FLUID_FREE(drv->builder->data);
}
FLUID_FREE(drv->builder);
FLUID_FREE(drv->events);
FLUID_FREE(drv);
}
void fluid_pipewire_audio_driver_settings(fluid_settings_t *settings)
{
fluid_settings_register_str(settings, "audio.pipewire.media-role", "Music", 0);
fluid_settings_register_str(settings, "audio.pipewire.media-type", "Audio", 0);
fluid_settings_register_str(settings, "audio.pipewire.media-category", "Playback", 0);
}
#endif

View file

@ -83,12 +83,12 @@ new_fluid_pulse_audio_driver2(fluid_settings_t *settings,
pa_sample_spec samplespec;
pa_buffer_attr bufattr;
double sample_rate;
int period_size, period_bytes, adjust_latency, periods;
int period_size, period_bytes, adjust_latency;
char *server = NULL;
char *device = NULL;
char *media_role = NULL;
int realtime_prio = 0;
int err = 0;
int err;
float *left = NULL,
*right = NULL,
*buf = NULL;
@ -103,7 +103,6 @@ new_fluid_pulse_audio_driver2(fluid_settings_t *settings,
FLUID_MEMSET(dev, 0, sizeof(fluid_pulse_audio_driver_t));
fluid_settings_getint(settings, "audio.periods", &periods);
fluid_settings_getint(settings, "audio.period-size", &period_size);
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
fluid_settings_dupstr(settings, "audio.pulseaudio.server", &server); /* ++ alloc server string */
@ -144,7 +143,7 @@ new_fluid_pulse_audio_driver2(fluid_settings_t *settings,
samplespec.rate = sample_rate;
period_bytes = period_size * sizeof(float) * 2;
bufattr.maxlength = adjust_latency ? -1 : period_bytes * periods;
bufattr.maxlength = adjust_latency ? -1 : period_bytes;
bufattr.tlength = period_bytes;
bufattr.minreq = -1;
bufattr.prebuf = -1; /* Just initialize to same value as tlength */
@ -156,9 +155,9 @@ new_fluid_pulse_audio_driver2(fluid_settings_t *settings,
&bufattr,
&err);
if(!dev->pa_handle || err != PA_OK)
if(!dev->pa_handle)
{
FLUID_LOG(FLUID_ERR, "Failed to create PulseAudio connection, because pa_simple_new() failed with error: %s", pa_strerror(err));
FLUID_LOG(FLUID_ERR, "Failed to create PulseAudio connection");
goto error_recovery;
}
@ -177,7 +176,6 @@ new_fluid_pulse_audio_driver2(fluid_settings_t *settings,
}
buf = FLUID_ARRAY(float, period_size * 2);
if(buf == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory.");
@ -244,8 +242,10 @@ fluid_pulse_audio_run(void *d)
{
fluid_pulse_audio_driver_t *dev = (fluid_pulse_audio_driver_t *) d;
float *buf = dev->buf;
int buffer_size = dev->buffer_size;
int err = 0;
int buffer_size;
int err;
buffer_size = dev->buffer_size;
while(dev->cont)
{
@ -254,20 +254,9 @@ fluid_pulse_audio_run(void *d)
if(pa_simple_write(dev->pa_handle, buf,
buffer_size * sizeof(float) * 2, &err) < 0)
{
FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection: %s", pa_strerror(err));
FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection.");
break;
}
#if 0
{
pa_usec_t pa_latency = pa_simple_get_latency(dev->pa_handle, &err);
if(err == PA_OK)
{
FLUID_LOG(FLUID_DBG, "PulseAudio latency: %d ms", (int) pa_latency / 1000);
}
}
#endif
} /* while (dev->cont) */
return FLUID_THREAD_RETURN_VALUE;
@ -282,10 +271,12 @@ fluid_pulse_audio_run2(void *d)
*right = dev->right,
*buf = dev->buf;
float *handle[2];
int buffer_size = dev->buffer_size;
int err = 0;
int buffer_size;
int err;
int i;
buffer_size = dev->buffer_size;
handle[0] = left;
handle[1] = right;
@ -306,20 +297,9 @@ fluid_pulse_audio_run2(void *d)
if(pa_simple_write(dev->pa_handle, buf,
buffer_size * sizeof(float) * 2, &err) < 0)
{
FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection: %s", pa_strerror(err));
FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection.");
break;
}
#if 0
{
pa_usec_t pa_latency = pa_simple_get_latency(dev->pa_handle, &err);
if(err == PA_OK)
{
FLUID_LOG(FLUID_DBG, "PulseAudio latency: %d ms", (int) pa_latency / 1000);
}
}
#endif
} /* while (dev->cont) */
return FLUID_THREAD_RETURN_VALUE;

View file

@ -73,7 +73,7 @@ static const IID _IID_IAudioRenderClient =
*
* Current limitations:
* - Only one stereo audio output.
* - If audio.sample-format is "16bits", a conversion from float
* - If audio.sample-format is "16bits", a convertion from float
* without dithering is used.
*
* Available settings:
@ -261,7 +261,7 @@ fluid_audio_driver_t *new_fluid_wasapi_audio_driver2(fluid_settings_t *settings,
/* start event must be first */
wait_handles[0] = dev->start_ev;
wait_handles[1] = dev->thread;
ret = WaitForMultipleObjects(FLUID_N_ELEMENTS(wait_handles), wait_handles, FALSE, 2000);
ret = WaitForMultipleObjects(FLUID_N_ELEMENTS(wait_handles), wait_handles, FALSE, 1000);
switch(ret)
{
@ -788,9 +788,9 @@ static void fluid_wasapi_register_callback(IMMDevice *dev, void *data)
int nsz;
char *name;
nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0);
nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz + 1);
WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0);
WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0);
fluid_settings_add_option(settings, "audio.wasapi.device", name);
FLUID_FREE(name);
}
@ -803,7 +803,6 @@ static void fluid_wasapi_finddev_callback(IMMDevice *dev, void *data)
{
fluid_wasapi_finddev_data_t *d = (fluid_wasapi_finddev_data_t *)data;
int nsz;
size_t id_len;
char *name = NULL;
wchar_t *id = NULL;
IPropertyStore *prop = NULL;
@ -828,9 +827,9 @@ static void fluid_wasapi_finddev_callback(IMMDevice *dev, void *data)
goto cleanup;
}
nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0);
nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz + 1);
WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0);
WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0);
if(!FLUID_STRCASECMP(name, d->name))
{
@ -842,15 +841,9 @@ static void fluid_wasapi_finddev_callback(IMMDevice *dev, void *data)
goto cleanup;
}
id_len = wcslen(id);
if(id_len >= UINT_MAX / sizeof(wchar_t))
{
FLUID_LOG(FLUID_ERR, "wasapi: the returned device identifier was way too long");
goto cleanup;
}
id_len++;
d->id = FLUID_ARRAY(wchar_t, id_len);
FLUID_MEMCPY(d->id, id, sizeof(wchar_t) * id_len);
nsz = wcslen(id);
d->id = FLUID_ARRAY(wchar_t, nsz + 1);
FLUID_MEMCPY(d->id, id, sizeof(wchar_t) * (nsz + 1));
}
cleanup:

View file

@ -344,7 +344,7 @@ new_fluid_waveout_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t f
}
/* allocate the internal waveout buffers:
The length of a single buffer in bytes is dependent of period_size.
The length of a single buffer in bytes is dependant of period_size.
*/
lenBuffer = wfx.Format.nBlockAlign * period_size;
/* create and clear the driver data */
@ -394,7 +394,7 @@ new_fluid_waveout_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t f
FLUID_MEMSET(dev->drybuf, 0, sizeof(float*) * audio_channels * 2);
for(i = 0; i < audio_channels * 2; ++i)
{
/* The length of a single buffer drybuf[i] is dependent of period_size */
/* The length of a single buffer drybuf[i] is dependant of period_size */
dev->drybuf[i] = FLUID_ARRAY(float, period_size);
if(dev->drybuf[i] == NULL)
{

View file

@ -29,11 +29,11 @@
* pointers to a queue and re-add them in a separate thread. Lame-o API! :(
*
* Multiple/single devices handling capabilities:
* This driver is able to handle multiple devices chosen by the user through
* This driver is able to handle multiple devices chosen by the user trough
* the settings midi.winmidi.device.
* For example, let the following device names:
* 0:Port MIDI SB Live! [CE00], 1:SB PCI External MIDI, default, x[;y;z;..]
* Then the driver is able receive MIDI messages coming from distinct devices
* Then the driver is able receive MIDI messages comming from distinct devices
* and forward these messages on distinct MIDI channels set.
* 1.1)For example, if the user chooses 2 devices at index 0 and 1, the user
* must specify this by putting the name "0;1" in midi.winmidi.device setting.
@ -95,8 +95,8 @@ struct fluid_winmidi_driver
HANDLE hThread;
DWORD dwThread;
/* devices information table */
int dev_count; /* device information count in dev_infos[] table */
/* devices informations table */
int dev_count; /* device informations count in dev_infos[] table */
device_infos_t dev_infos[1];
};
@ -145,28 +145,21 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
break;
case MIM_DATA:
if(msg_param < 0xF0) /* Voice category message */
event.type = msg_type(msg_param);
event.channel = msg_chan(msg_param) + dev_infos->channel_map;
FLUID_LOG(FLUID_DBG, "\ndevice at index %d sending MIDI message on channel %d, forwarded on channel: %d",
dev_infos->dev_idx, msg_chan(msg_param), event.channel);
if(event.type != PITCH_BEND)
{
event.type = msg_type(msg_param);
event.channel = msg_chan(msg_param) + dev_infos->channel_map;
FLUID_LOG(FLUID_DBG, "\ndevice at index %d sending MIDI message on channel %d, forwarded on channel: %d",
dev_infos->dev_idx, msg_chan(msg_param), event.channel);
if(event.type != PITCH_BEND)
{
event.param1 = msg_p1(msg_param);
event.param2 = msg_p2(msg_param);
}
else /* Pitch bend is a 14 bit value */
{
event.param1 = (msg_p2(msg_param) << 7) | msg_p1(msg_param);
event.param2 = 0;
}
event.param1 = msg_p1(msg_param);
event.param2 = msg_p2(msg_param);
}
else /* System message */
else /* Pitch bend is a 14 bit value */
{
event.type = msg_param;
event.param1 = (msg_p2(msg_param) << 7) | msg_p1(msg_param);
event.param2 = 0;
}
(*dev->driver.handler)(dev->driver.data, &event);
@ -212,7 +205,7 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
* build a device name prefixed by its index. The format of the returned
* name is: dev_idx:dev_name
* The name returned is convenient for midi.winmidi.device setting.
* It allows the user to identify a device index through its name or vice
* It allows the user to identify a device index through its name or vise
* versa. This allows the user to specify a multi device name using a list of
* devices index (see fluid_winmidi_midi_driver_settings()).
*
@ -357,7 +350,7 @@ fluid_winmidi_parse_device_name(fluid_winmidi_driver_t *dev, char *dev_name)
/* look for a multi device naming */
/* multi devices name "x;[y;..]". parse devices index: x;y;..
Each ascii index are separated by a semicolon character.
Each ascii index are separated by a semicolon caracter.
*/
FLUID_STRCPY(cpy_dev_name, dev_name); /* fluid_strtok() will overwrite */
next_idx = cpy_dev_name;
@ -503,7 +496,7 @@ new_fluid_winmidi_driver(fluid_settings_t *settings,
return NULL;
}
/* allocation of driver structure size dependent of max_devices */
/* allocation of driver structure size dependant of max_devices */
i = sizeof(fluid_winmidi_driver_t) + (max_devices - 1) * sizeof(device_infos_t);
dev = FLUID_MALLOC(i);

View file

@ -42,10 +42,6 @@
#include <SDL.h>
#endif
#if PIPEWIRE_SUPPORT
#include <pipewire/pipewire.h>
#endif
void print_usage(void);
void print_help(fluid_settings_t *settings);
void print_welcome(void);
@ -160,45 +156,6 @@ print_pretty_int(int i)
}
}
#ifdef WIN32
/* Function using win32 api to convert ANSI encoding string to UTF8 encoding string */
static char*
win32_ansi_to_utf8(const char* ansi_null_terminated_string)
{
LPWSTR u16_buf = NULL;
char *u8_buf = NULL;
fluid_return_val_if_fail(ansi_null_terminated_string != NULL, NULL);
do
{
int u16_count, u8_byte_count;
u16_count = MultiByteToWideChar(CP_ACP, 0, ansi_null_terminated_string, -1, NULL, 0);
if (u16_count == 0)
{
fprintf(stderr, "Failed to convert ANSI string to wide char string\n");
break;
}
u16_buf = malloc(u16_count * sizeof(WCHAR));
if (u16_buf == NULL)
{
fprintf(stderr, "Out of memory\n");
break;
}
u16_count = MultiByteToWideChar(CP_ACP, 0, ansi_null_terminated_string, -1, u16_buf, u16_count);
u8_byte_count = WideCharToMultiByte(CP_UTF8, 0, u16_buf, u16_count, NULL, 0, NULL, NULL);
u8_buf = malloc(u8_byte_count);
if (u8_buf == NULL)
{
fprintf(stderr, "Out of memory\n");
break;
}
WideCharToMultiByte(CP_UTF8, 0, u16_buf, u16_count, u8_buf, u8_byte_count, NULL, NULL);
} while (0);
free(u16_buf);
return u8_buf;
}
#endif
typedef struct
{
int count; /* Total count of options */
@ -394,7 +351,7 @@ int main(int argc, char **argv)
int audio_channels = 0;
int dump = 0;
int fast_render = 0;
static const char optchars[] = "a:C:c:dE:f:F:G:g:hijK:L:lm:nO:o:p:QqR:r:sT:Vvz:";
static const char optchars[] = "a:C:c:dE:f:F:G:g:hijK:L:lm:nO:o:p:qR:r:sT:Vvz:";
#ifdef HAVE_LASH
int connect_lash = 1;
int enabled_lash = 0; /* set to TRUE if lash gets enabled */
@ -404,8 +361,7 @@ int main(int argc, char **argv)
#endif
#if SDL2_SUPPORT
// Tell SDL that it shouldn't intercept signals, otherwise SIGINT and SIGTERM won't quit fluidsynth
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
if(SDL_Init(SDL_INIT_AUDIO) != 0)
{
fprintf(stderr, "Warning: Unable to initialize SDL2 Audio: %s", SDL_GetError());
@ -414,11 +370,7 @@ int main(int argc, char **argv)
{
atexit(SDL_Quit);
}
#endif
#if PIPEWIRE_SUPPORT
pw_init(&argc, &argv);
atexit(pw_deinit);
#endif
/* create the settings */
@ -899,13 +851,13 @@ int main(int argc, char **argv)
if(config_file == NULL)
{
config_file = fluid_get_userconf(buf, sizeof(buf));
if(config_file == NULL || !g_file_test(config_file, G_FILE_TEST_EXISTS))
if(config_file == NULL)
{
config_file = fluid_get_sysconf(buf, sizeof(buf));
}
/* if the automatically selected command file does not exist, do not even attempt to open it */
if(config_file != NULL && !fluid_file_test(config_file, FLUID_FILE_TEST_EXISTS))
if(!g_file_test(config_file, G_FILE_TEST_EXISTS))
{
config_file = NULL;
}
@ -944,25 +896,14 @@ int main(int argc, char **argv)
/* load the soundfonts (check that all non options are SoundFont or MIDI files) */
for(i = arg1; i < argc; i++)
{
const char *u8_path = argv[i];
#if defined(WIN32)
/* try to convert ANSI encoding path to UTF8 encoding path */
char *u8_buf = win32_ansi_to_utf8(argv[i]);
if (u8_buf == NULL)
{
// error msg. already printed
goto cleanup;
}
u8_path = u8_buf;
#endif
if(fluid_is_midifile(u8_path))
if(fluid_is_midifile(argv[i]))
{
continue;
}
if(fluid_is_soundfont(u8_path))
if(fluid_is_soundfont(argv[i]))
{
if(fluid_synth_sfload(synth, u8_path, 1) == -1)
if(fluid_synth_sfload(synth, argv[i], 1) == -1)
{
fprintf(stderr, "Failed to load the SoundFont %s\n", argv[i]);
}
@ -971,9 +912,6 @@ int main(int argc, char **argv)
{
fprintf(stderr, "Parameter '%s' not a SoundFont or MIDI file or error occurred identifying it.\n", argv[i]);
}
#if defined(WIN32)
free(u8_buf);
#endif
}
/* Try to load the default soundfont, if no soundfont specified */
@ -1222,7 +1160,7 @@ void
print_welcome()
{
printf("FluidSynth runtime version %s\n"
"Copyright (C) 2000-2022 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 Creative Technology Ltd.\n\n",
fluid_version_str());

View file

@ -21,14 +21,14 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../)
# Add the executable that generates the table
add_executable( make_tables
make_tables.c
gen_conv.c
gen_rvoice_dsp.c)
target_include_directories( make_tables PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ )
if ( WIN32 )
add_definitions ( -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS )
else ( WIN32 )

View file

@ -126,13 +126,8 @@ new_fluid_midi_file(const char *buffer, size_t length)
{
fluid_midi_file *mf;
if(length > INT_MAX)
{
FLUID_LOG(FLUID_ERR, "Refusing to open a MIDI file which is bigger than 2GiB");
return NULL;
}
mf = FLUID_NEW(fluid_midi_file);
if(mf == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
@ -145,7 +140,7 @@ new_fluid_midi_file(const char *buffer, size_t length)
mf->running_status = -1;
mf->buffer = buffer;
mf->buf_len = (int)length;
mf->buf_len = length;
mf->buf_pos = 0;
mf->eof = FALSE;
@ -493,7 +488,7 @@ fluid_midi_file_read_track(fluid_midi_file *mf, fluid_player_t *player, int num)
if(fluid_isasciistring((char *) id) == 0)
{
FLUID_LOG(FLUID_ERR,
"A non-ascii track header found, corrupt file");
"An non-ascii track header found, corrupt file");
return FLUID_FAILED;
}
@ -1111,7 +1106,7 @@ delete_fluid_midi_event(fluid_midi_event_t *evt)
* @return Event type field (MIDI status byte without channel)
*/
int
fluid_midi_event_get_type(const fluid_midi_event_t *evt)
fluid_midi_event_get_type(fluid_midi_event_t *evt)
{
return evt->type;
}
@ -1135,7 +1130,7 @@ fluid_midi_event_set_type(fluid_midi_event_t *evt, int type)
* @return Channel field
*/
int
fluid_midi_event_get_channel(const fluid_midi_event_t *evt)
fluid_midi_event_get_channel(fluid_midi_event_t *evt)
{
return evt->channel;
}
@ -1159,7 +1154,7 @@ fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan)
* @return MIDI note number (0-127)
*/
int
fluid_midi_event_get_key(const fluid_midi_event_t *evt)
fluid_midi_event_get_key(fluid_midi_event_t *evt)
{
return evt->param1;
}
@ -1183,7 +1178,7 @@ fluid_midi_event_set_key(fluid_midi_event_t *evt, int v)
* @return MIDI velocity number (0-127)
*/
int
fluid_midi_event_get_velocity(const fluid_midi_event_t *evt)
fluid_midi_event_get_velocity(fluid_midi_event_t *evt)
{
return evt->param2;
}
@ -1207,7 +1202,7 @@ fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int v)
* @return MIDI control number
*/
int
fluid_midi_event_get_control(const fluid_midi_event_t *evt)
fluid_midi_event_get_control(fluid_midi_event_t *evt)
{
return evt->param1;
}
@ -1231,7 +1226,7 @@ fluid_midi_event_set_control(fluid_midi_event_t *evt, int v)
* @return Value field
*/
int
fluid_midi_event_get_value(const fluid_midi_event_t *evt)
fluid_midi_event_get_value(fluid_midi_event_t *evt)
{
return evt->param2;
}
@ -1255,7 +1250,7 @@ fluid_midi_event_set_value(fluid_midi_event_t *evt, int v)
* @return MIDI program number (0-127)
*/
int
fluid_midi_event_get_program(const fluid_midi_event_t *evt)
fluid_midi_event_get_program(fluid_midi_event_t *evt)
{
return evt->param1;
}
@ -1279,7 +1274,7 @@ fluid_midi_event_set_program(fluid_midi_event_t *evt, int val)
* @return Pitch value (14 bit value, 0-16383, 8192 is center)
*/
int
fluid_midi_event_get_pitch(const fluid_midi_event_t *evt)
fluid_midi_event_get_pitch(fluid_midi_event_t *evt)
{
return evt->param1;
}
@ -1582,12 +1577,12 @@ fluid_track_send_events(fluid_track_t *track,
return;
}
/* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */
/* track->num, */
/* ticks, */
/* track->ticks, */
/* event->dtime, */
/* track->ticks + event->dtime); */
/* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */
/* track->num, */
/* ticks, */
/* track->ticks, */
/* event->dtime, */
/* track->ticks + event->dtime); */
if(track->ticks + event->dtime > ticks)
{
@ -1609,10 +1604,6 @@ fluid_track_send_events(fluid_track_t *track,
if(player->playback_callback)
{
player->playback_callback(player->playback_userdata, event);
if(event->type == NOTE_ON && event->param2 != 0 && !player->channel_isplaying[event->channel])
{
player->channel_isplaying[event->channel] = TRUE;
}
}
}
@ -1660,7 +1651,6 @@ new_fluid_player(fluid_synth_t *synth)
}
fluid_atomic_int_set(&player->status, FLUID_PLAYER_READY);
fluid_atomic_int_set(&player->stopping, 0);
player->loop = 1;
player->ntracks = 0;
@ -1796,14 +1786,9 @@ fluid_player_reset(fluid_player_t *player)
}
}
for(i = 0; i < MAX_NUMBER_OF_CHANNELS; i++)
{
player->channel_isplaying[i] = FALSE;
}
/* player->current_file = NULL; */
/* player->status = FLUID_PLAYER_READY; */
/* player->loop = 1; */
/* player->current_file = NULL; */
/* player->status = FLUID_PLAYER_READY; */
/* player->loop = 1; */
player->ntracks = 0;
player->division = 0;
player->miditempo = 500000;
@ -2094,32 +2079,16 @@ fluid_player_callback(void *data, unsigned int msec)
int i;
int loadnextfile;
int status = FLUID_PLAYER_DONE;
fluid_midi_event_t mute_event;
fluid_player_t *player;
fluid_synth_t *synth;
player = (fluid_player_t *) data;
synth = player->synth;
loadnextfile = player->currentfile == NULL ? 1 : 0;
fluid_midi_event_set_type(&mute_event, CONTROL_CHANGE);
mute_event.param1 = ALL_SOUND_OFF;
mute_event.param2 = 1;
if(fluid_player_get_status(player) != FLUID_PLAYER_PLAYING)
{
if(fluid_atomic_int_get(&player->stopping))
{
for(i = 0; i < synth->midi_channels; i++)
{
if(player->channel_isplaying[i])
{
fluid_midi_event_set_channel(&mute_event, i);
player->playback_callback(player->playback_userdata, &mute_event);
}
}
fluid_atomic_int_set(&player->stopping, 0);
}
fluid_synth_all_notes_off(synth, -1);
return 1;
}
do
@ -2147,14 +2116,7 @@ fluid_player_callback(void *data, unsigned int msec)
seek_ticks = fluid_atomic_int_get(&player->seek_ticks);
if(seek_ticks >= 0)
{
for(i = 0; i < synth->midi_channels; i++)
{
if(player->channel_isplaying[i])
{
fluid_midi_event_set_channel(&mute_event, i);
player->playback_callback(player->playback_userdata, &mute_event);
}
}
fluid_synth_all_sounds_off(synth, -1); /* avoid hanging notes */
}
for(i = 0; i < player->ntracks; i++)
@ -2205,9 +2167,6 @@ fluid_player_callback(void *data, unsigned int msec)
* Activates play mode for a MIDI player if not already playing.
* @param player MIDI player instance
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* If the list of files added to the player has completed its requested number of loops,
* the playlist will be restarted from the beginning with a loop count of 1.
*/
int
fluid_player_play(fluid_player_t *player)
@ -2223,17 +2182,10 @@ fluid_player_play(fluid_player_t *player)
fluid_sample_timer_reset(player->synth, player->sample_timer);
}
/* If we're at the end of the playlist and there are no loops left, loop once */
if(player->currentfile == NULL && player->loop == 0)
{
player->loop = 1;
}
fluid_atomic_int_set(&player->status, FLUID_PLAYER_PLAYING);
return FLUID_OK;
}
/**
* Pauses the MIDI playback.
*
@ -2246,7 +2198,6 @@ int
fluid_player_stop(fluid_player_t *player)
{
fluid_atomic_int_set(&player->status, FLUID_PLAYER_DONE);
fluid_atomic_int_set(&player->stopping, 1);
fluid_player_seek(player, fluid_player_get_current_tick(player));
return FLUID_OK;
}
@ -2328,7 +2279,7 @@ int fluid_player_set_loop(fluid_player_t *player, int loop)
}
/**
* update the MIDI player internal deltatime dependent of actual tempo.
* update the MIDI player internal deltatime dependant of actual tempo.
* @param player MIDI player instance
*/
static void fluid_player_update_tempo(fluid_player_t *player)
@ -2336,12 +2287,6 @@ static void fluid_player_update_tempo(fluid_player_t *player)
int tempo; /* tempo in micro seconds by quarter note */
float deltatime;
/* do nothing if the division is still unknown to avoid a div by zero */
if(player->division == 0)
{
return;
}
if(fluid_atomic_int_get(&player->sync_mode))
{
/* take internal tempo from MIDI file */
@ -2406,10 +2351,6 @@ static void fluid_player_update_tempo(fluid_player_t *player)
* #FLUID_PLAYER_TEMPO_INTERNAL will set the player to follow this internal
* tempo.
*
* @warning If the function is called when no MIDI file is loaded or currently playing, it
* would have caused a division by zero in fluidsynth 2.2.7 and earlier. Starting with 2.2.8, the
* new tempo change will be stashed and applied later.
*
* @return #FLUID_OK if success or #FLUID_FAILED otherwise (incorrect parameters).
* @since 2.2.0
*/
@ -2652,9 +2593,14 @@ fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigned char c)
* of another message. */
if(c >= 0xF8)
{
parser->event.type = c;
parser->status = 0; /* clear the status */
return &parser->event;
if(c == MIDI_SYSTEM_RESET)
{
parser->event.type = c;
parser->status = 0; /* clear the status */
return &parser->event;
}
return NULL;
}
/* Status byte? - If previous message not yet complete, it is discarded (re-sync). */

View file

@ -39,7 +39,6 @@ fluid_midi_event_t *fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigne
#define MAX_NUMBER_OF_TRACKS 128
#define MAX_NUMBER_OF_CHANNELS 16
enum fluid_midi_event_type
{
@ -201,7 +200,7 @@ enum midi_sysex_tuning_msg_id
MIDI_SYSEX_TUNING_BULK_DUMP = 0x01, /**< Bulk tuning dump response (non-realtime) */
MIDI_SYSEX_TUNING_NOTE_TUNE = 0x02, /**< Tuning note change message (realtime) */
MIDI_SYSEX_TUNING_BULK_DUMP_REQ_BANK = 0x03, /**< Bulk tuning dump request (with bank, non-realtime) */
MIDI_SYSEX_TUNING_BULK_DUMP_BANK = 0x04, /**< Bulk tuning dump response (with bank, non-realtime) */
MIDI_SYSEX_TUNING_BULK_DUMP_BANK = 0x04, /**< Bulk tuning dump resonse (with bank, non-realtime) */
MIDI_SYSEX_TUNING_OCTAVE_DUMP_1BYTE = 0x05, /**< Octave tuning dump using 1 byte values (non-realtime) */
MIDI_SYSEX_TUNING_OCTAVE_DUMP_2BYTE = 0x06, /**< Octave tuning dump using 2 byte values (non-realtime) */
MIDI_SYSEX_TUNING_NOTE_TUNE_BANK = 0x07, /**< Tuning note change message (with bank, realtime/non-realtime) */
@ -286,7 +285,6 @@ typedef struct
struct _fluid_player_t
{
fluid_atomic_int_t status;
fluid_atomic_int_t stopping; /* Flag for sending all_notes_off when player is stopped */
int ntracks;
fluid_track_t *track[MAX_NUMBER_OF_TRACKS];
fluid_synth_t *synth;
@ -311,7 +309,7 @@ struct _fluid_player_t
0, the player is driven by external tempo (exttempo)
*/
int sync_mode;
/* miditempo: internal tempo coming from MIDI file tempo change events
/* miditempo: internal tempo comming from MIDI file tempo change events
(in micro seconds per quarter note)
*/
int miditempo; /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */
@ -326,8 +324,6 @@ struct _fluid_player_t
void *playback_userdata; /* pointer to user-defined data passed to playback_callback function */
handle_midi_tick_func_t tick_callback; /* function fired on each tick change */
void *tick_userdata; /* pointer to user-defined data passed to tick_callback function */
int channel_isplaying[MAX_NUMBER_OF_CHANNELS]; /* flags indicating channels on which notes have played */
};
void fluid_player_settings(fluid_settings_t *settings);

View file

@ -536,10 +536,7 @@ fluid_midi_router_rule_set_param2(fluid_midi_router_rule_t *rule, int min, int m
* this function can be used as a callback for other subsystems
* (new_fluid_midi_driver() for example).
* @param event MIDI event to handle
* @return #FLUID_OK if all rules were applied successfully, #FLUID_FAILED if
* an error occurred while applying a rule or (since 2.2.2) the event was
* ignored because a parameter was out-of-range after the rule had been applied.
* See the note below.
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* Purpose: The midi router is called for each event, that is received
* via the 'physical' midi input. Each event can trigger an arbitrary number
@ -557,17 +554,6 @@ fluid_midi_router_rule_set_param2(fluid_midi_router_rule_t *rule, int min, int m
* - velocity switching ("v <=100: Angel Choir; V > 100: Hell's Bells")
* - get rid of aftertouch
* - ...
*
* @note Each input event has values (ch, par1, par2) that could be changed by a rule.
* After a rule has been applied on any value and the value is out of range, the event
* can be either ignored or the value can be clamped depending on the type of the event:
* - To get full benefice of the rule the value is clamped and the event passed to the output.
* - To avoid MIDI messages conflicts at the output, the event is ignored
* (i.e not passed to the output).
* - ch out of range: event is ignored regardless of the event type.
* - par1 out of range: event is ignored for PROG_CHANGE or CONTROL_CHANGE type,
* par1 is clamped otherwise.
* - par2 out of range: par2 is clamped regardless of the event type.
*/
int
fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event)
@ -575,9 +561,6 @@ fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event)
fluid_midi_router_t *router = (fluid_midi_router_t *)data;
fluid_midi_router_rule_t **rulep, *rule, *next_rule, *prev_rule = NULL;
int event_has_par2 = 0; /* Flag, indicates that current event needs two parameters */
int is_par1_ignored = 0; /* Flag, indicates that current event should be
ignored/clamped when par1 is getting out of range
value after the rule had been applied:1:ignored, 0:clamped */
int par1_max = 127; /* Range limit for par1 */
int par2_max = 127; /* Range limit for par2 */
int ret_val = FLUID_OK;
@ -602,50 +585,34 @@ fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event)
/* Depending on the event type, choose the correct list of rules. */
switch(event->type)
{
/* For NOTE_ON event, par1(pitch) and par2(velocity) will be clamped if
they are out of range after the rule had been applied */
case NOTE_ON:
rulep = &router->rules[FLUID_MIDI_ROUTER_RULE_NOTE];
event_has_par2 = 1;
break;
/* For NOTE_OFF event, par1(pitch) and par2(velocity) will be clamped if
they are out of range after the rule had been applied */
case NOTE_OFF:
rulep = &router->rules[FLUID_MIDI_ROUTER_RULE_NOTE];
event_has_par2 = 1;
break;
/* CONTROL_CHANGE event will be ignored if par1 (ctrl num) is out
of range after the rule had been applied */
case CONTROL_CHANGE:
rulep = &router->rules[FLUID_MIDI_ROUTER_RULE_CC];
event_has_par2 = 1;
is_par1_ignored = 1;
break;
/* PROGRAM_CHANGE event will be ignored if par1 (program num) is out
of range after the rule had been applied */
case PROGRAM_CHANGE:
rulep = &router->rules[FLUID_MIDI_ROUTER_RULE_PROG_CHANGE];
is_par1_ignored = 1;
break;
/* For PITCH_BEND event, par1(bend value) will be clamped if
it is out of range after the rule had been applied */
case PITCH_BEND:
rulep = &router->rules[FLUID_MIDI_ROUTER_RULE_PITCH_BEND];
par1_max = 16383;
break;
/* For CHANNEL_PRESSURE event, par1(pressure value) will be clamped if
it is out of range after the rule had been applied */
case CHANNEL_PRESSURE:
rulep = &router->rules[FLUID_MIDI_ROUTER_RULE_CHANNEL_PRESSURE];
break;
/* For KEY_PRESSURE event, par1(pitch) and par2(pressure value) will be
clamped if they are out of range after the rule had been applied */
case KEY_PRESSURE:
rulep = &router->rules[FLUID_MIDI_ROUTER_RULE_KEY_PRESSURE];
event_has_par2 = 1;
@ -733,46 +700,44 @@ fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event)
chan = rule->chan_add + (int)((fluid_real_t)event->channel * rule->chan_mul
+ (fluid_real_t)0.5);
/* We ignore the event if chan is out of range */
if((chan < 0) || (chan >= router->nr_midi_channels))
{
ret_val = FLUID_FAILED;
continue; /* go to next rule */
}
/* par 1 scaling / offset */
/* Par 1 scaling / offset */
par1 = rule->par1_add + (int)((fluid_real_t)event_par1 * rule->par1_mul
+ (fluid_real_t)0.5);
if(is_par1_ignored)
{
/* We ignore the event if par1 is out of range */
if((par1 < 0) || (par1 > par1_max))
{
ret_val = FLUID_FAILED;
continue; /* go to next rule */
}
}
else
{
/* par1 range clamping */
if(par1 < 0)
{
par1 = 0;
}
else if(par1 > par1_max)
{
par1 = par1_max;
}
}
/* par 2 scaling / offset, if applicable */
/* Par 2 scaling / offset, if applicable */
if(event_has_par2)
{
par2 = rule->par2_add + (int)((fluid_real_t)event_par2 * rule->par2_mul
+ (fluid_real_t)0.5);
}
else
{
par2 = 0;
}
/* par2 range clamping */
/* Channel range limiting */
if(chan < 0)
{
chan = 0;
}
else if(chan >= router->nr_midi_channels)
{
chan = router->nr_midi_channels - 1;
}
/* Par1 range limiting */
if(par1 < 0)
{
par1 = 0;
}
else if(par1 > par1_max)
{
par1 = par1_max;
}
/* Par2 range limiting */
if(event_has_par2)
{
if(par2 < 0)
{
par2 = 0;
@ -782,10 +747,6 @@ fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event)
par2 = par2_max;
}
}
else
{
par2 = 0;
}
/* At this point we have to create an event of event->type on 'chan' with par1 (maybe par2).
* We keep track on the state of noteon and sustain pedal events. If the application tries

View file

@ -560,7 +560,7 @@ fluid_sequencer_get_tick(fluid_sequencer_t *seq)
* the events are adjusted accordingly.
*
* @note May only be called from a sequencer callback or initially when no event dispatching happens.
* Otherwise it will mess up your event timing, because you have zero control over which events are
* Otherwise it will mess up your event timing, because you have zero contol over which events are
* affected by the scale change.
*/
void
@ -624,7 +624,7 @@ fluid_sequencer_process(fluid_sequencer_t *seq, unsigned int msec)
/**
* @internal
* only used privately by fluid_seqbind and only from sequencer callback, thus lock acquire is not needed.
* only used privately by fluid_seqbind and only from sequencer callback, thus lock aquire is not needed.
*/
void fluid_sequencer_invalidate_note(fluid_sequencer_t *seq, fluid_seq_id_t dest, fluid_note_id_t id)
{

View file

@ -84,7 +84,7 @@ static bool event_compare(const fluid_event_t& left, const fluid_event_t& right)
// | NOTEON | 0 | 0 | 0 | 0 | 1 | 0 |
// | X | 0 | 0 | 0 | 0 | 1 | 1 |
//
// The values in the diagonal (i.e. comparison with itself) must be true to make them become false after leaving this
// The values in the diagonal (i.e. comparision with itself) must be true to make them become false after leaving this
// function in order to satisfy the irreflexive requirement, i.e. assert(!(a < a))
leftIsBeforeRight =

View file

@ -367,20 +367,64 @@ static fluid_seq_id_t get_fluidsynth_dest(fluid_sequencer_t *seq)
*
* @since 1.1.0
*/
int fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event)
int
fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event)
{
fluid_event_t evt;
fluid_sequencer_t *seq;
int chan;
fluid_return_val_if_fail(data != NULL, FLUID_FAILED);
fluid_return_val_if_fail(event != NULL, FLUID_FAILED);
seq = (fluid_sequencer_t *)data;
seq = (fluid_sequencer_t *) data;
chan = fluid_midi_event_get_channel(event);
fluid_event_clear(&evt);
fluid_event_from_midi_event(&evt, event);
fluid_event_set_dest(&evt, get_fluidsynth_dest(seq));
switch(fluid_midi_event_get_type(event))
{
case NOTE_OFF:
fluid_event_noteoff(&evt, chan, (short)fluid_midi_event_get_key(event));
break;
case NOTE_ON:
fluid_event_noteon(&evt, fluid_midi_event_get_channel(event),
(short)fluid_midi_event_get_key(event), (short)fluid_midi_event_get_velocity(event));
break;
case CONTROL_CHANGE:
fluid_event_control_change(&evt, chan, (short)fluid_midi_event_get_control(event),
(short)fluid_midi_event_get_value(event));
break;
case PROGRAM_CHANGE:
fluid_event_program_change(&evt, chan, (short)fluid_midi_event_get_program(event));
break;
case PITCH_BEND:
fluid_event_pitch_bend(&evt, chan, fluid_midi_event_get_pitch(event));
break;
case CHANNEL_PRESSURE:
fluid_event_channel_pressure(&evt, chan, (short)fluid_midi_event_get_program(event));
break;
case KEY_PRESSURE:
fluid_event_key_pressure(&evt, chan,
(short)fluid_midi_event_get_key(event),
(short)fluid_midi_event_get_value(event));
break;
case MIDI_SYSTEM_RESET:
fluid_event_system_reset(&evt);
break;
default: /* Not yet implemented */
return FLUID_FAILED;
}
/* Schedule for sending at next call to fluid_sequencer_process */
return fluid_sequencer_send_at(seq, &evt, 0, 0);
}

View file

@ -37,7 +37,7 @@ struct _fluid_env_data_t
};
/* Indices for envelope tables */
enum fluid_voice_envelope_index
enum fluid_voice_envelope_index_t
{
FLUID_VOICE_ENVDELAY,
FLUID_VOICE_ENVATTACK,
@ -49,7 +49,7 @@ enum fluid_voice_envelope_index
FLUID_VOICE_ENVLAST
};
typedef enum fluid_voice_envelope_index fluid_adsr_env_section_t;
typedef enum fluid_voice_envelope_index_t fluid_adsr_env_section_t;
typedef struct _fluid_adsr_env_t fluid_adsr_env_t;
@ -57,14 +57,14 @@ struct _fluid_adsr_env_t
{
fluid_env_data_t data[FLUID_VOICE_ENVLAST];
unsigned int count;
int section;
fluid_real_t val; /* the current value of the envelope */
fluid_adsr_env_section_t section;
};
/* For performance, all functions are inlined */
static FLUID_INLINE void
fluid_adsr_env_calc(fluid_adsr_env_t *env)
fluid_adsr_env_calc(fluid_adsr_env_t *env, int is_volenv)
{
fluid_env_data_t *env_data;
fluid_real_t x;
@ -76,8 +76,7 @@ fluid_adsr_env_calc(fluid_adsr_env_t *env)
{
// If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage
// Hmm, should this only apply to volenv? It was so before refactoring, so keep it for now. [DH]
// No, must apply to both, otherwise some voices may sound detuned. [TM] (https://github.com/FluidSynth/fluidsynth/issues/1059)
if(env->section == FLUID_VOICE_ENVDECAY)
if(env->section == FLUID_VOICE_ENVDECAY && is_volenv)
{
env->val = env_data->min * env_data->coeff;
}
@ -107,6 +106,8 @@ fluid_adsr_env_calc(fluid_adsr_env_t *env)
}
env->val = x;
}
/* This one cannot be inlined since it is referenced in
@ -117,7 +118,7 @@ static FLUID_INLINE void
fluid_adsr_env_reset(fluid_adsr_env_t *env)
{
env->count = 0;
env->section = FLUID_VOICE_ENVDELAY;
env->section = 0;
env->val = 0.0f;
}

View file

@ -110,8 +110,8 @@
/* SCALE_WET_WIDTH is a compensation weight factor to get an output
amplitude (wet) rather independent of the width setting.
0: the output amplitude is fully dependent on the width setting.
>0: the output amplitude is less dependent on the width setting.
0: the output amplitude is fully dependant on the width setting.
>0: the output amplitude is less dependant on the width setting.
With a SCALE_WET_WIDTH of 0.2 the output amplitude is rather
independent of width setting (see fluid_chorus_set()).
*/
@ -134,7 +134,7 @@
/* and max lfo speed (5 Hz) */
#define RANGE_MOD_RATE (HIGH_MOD_RATE - LOW_MOD_RATE)
/* some chorus cpu_load measurement dependent of modulation rate: mod_rate
/* some chorus cpu_load measurement dependant of modulation rate: mod_rate
(number of chorus blocks: 2)
No stero unit:
@ -560,7 +560,7 @@ static void update_parameters_from_sample_rate(fluid_chorus_t *chorus)
Modulated delay line initialization.
Sets the length line ( alloc delay samples).
Remark: the function sets the internal size according to the length delay_length.
Remark: the function sets the internal size accordling to the length delay_length.
The size is augmented by INTERP_SAMPLES_NBR to take account of interpolation.
@param chorus, pointer on chorus unit.
@ -783,7 +783,7 @@ fluid_chorus_set(fluid_chorus_t *chorus, int set, int nr, fluid_real_t level,
chorus->level = 0.1;
}
/* update parameters dependent of sample rate */
/* update parameters dependant of sample rate */
update_parameters_from_sample_rate(chorus);
#ifdef DEBUG_PRINT
@ -915,7 +915,7 @@ fluid_chorus_samplerate_change(fluid_chorus_t *chorus, fluid_real_t sample_rate)
{
chorus->sample_rate = sample_rate;
/* update parameters dependent of sample rate */
/* update parameters dependant of sample rate */
update_parameters_from_sample_rate(chorus);
}

View file

@ -210,8 +210,8 @@
-----------------------------------------------------------------------------*/
/* SCALE_WET_WIDTH is a compensation weight factor to get an output
amplitude (wet) rather independent of the width setting.
0: the output amplitude is fully dependent on the width setting.
>0: the output amplitude is less dependent on the width setting.
0: the output amplitude is fully dependant on the width setting.
>0: the output amplitude is less dependant on the width setting.
With a SCALE_WET_WIDTH of 0.2 the output amplitude is rather
independent of width setting (see fluid_revmodel_update()).
*/
@ -363,7 +363,7 @@ static void set_fdn_delay_lpf(fdn_delay_lpf *lpf,
/*-----------------------------------------------------------------------------
Delay line :
The delay line is composed of the line plus an absorbent low pass filter
to get frequency dependent reverb time.
to get frequency dependant reverb time.
-----------------------------------------------------------------------------*/
typedef struct
{
@ -928,7 +928,7 @@ static void initialize_mod_delay_lines(fluid_late *late, fluid_real_t sample_rat
int i;
fluid_real_t mod_depth, length_factor;
/* update delay line parameter dependent of sample rate */
/* update delay line parameter dependant of sample rate */
late->samplerate = sample_rate;
/* compute mod_depth, length factor */

View file

@ -331,7 +331,7 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
/******************* vol env **********************/
fluid_adsr_env_calc(&voice->envlfo.volenv);
fluid_adsr_env_calc(&voice->envlfo.volenv, 1);
fluid_check_fpe("voice_write vol env");
if(fluid_adsr_env_get_section(&voice->envlfo.volenv) == FLUID_VOICE_ENVFINISHED)
@ -341,7 +341,7 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
/******************* mod env **********************/
fluid_adsr_env_calc(&voice->envlfo.modenv);
fluid_adsr_env_calc(&voice->envlfo.modenv, 0);
fluid_check_fpe("voice_write mod env");
/******************* lfo **********************/

View file

@ -150,17 +150,6 @@ fluid_rvoice_mixer_process_fx(fluid_rvoice_mixer_t *mixer, int current_blockcoun
fluid_profile_ref_var(prof_ref);
#ifdef LADSPA
/* Run the signal through the LADSPA Fx unit. The buffers have already been
* set up in fluid_rvoice_mixer_set_ladspa. */
if(mixer->ladspa_fx)
{
fluid_ladspa_run(mixer->ladspa_fx, current_blockcount, FLUID_BUFSIZE);
fluid_check_fpe("LADSPA");
}
#endif
if(mix_fx_to_out)
{
@ -249,6 +238,17 @@ fluid_rvoice_mixer_process_fx(fluid_rvoice_mixer_t *mixer, int current_blockcoun
current_blockcount * FLUID_BUFSIZE);
}
#ifdef LADSPA
/* Run the signal through the LADSPA Fx unit. The buffers have already been
* set up in fluid_rvoice_mixer_set_ladspa. */
if(mixer->ladspa_fx)
{
fluid_ladspa_run(mixer->ladspa_fx, current_blockcount, FLUID_BUFSIZE);
fluid_check_fpe("LADSPA");
}
#endif
}
/**

View file

@ -27,7 +27,6 @@
#include "fluid_sys.h"
#include "fluid_synth.h"
#include "fluid_samplecache.h"
#include "fluid_chan.h"
/* EMU8k/10k hardware applies this factor to initial attenuation generator values set at preset and
* instrument level in a soundfont. We apply this factor when loading the generator values to stay
@ -376,7 +375,6 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
fluid_sample_t *sample;
int sf3_file = (sfdata->version.major == 3);
int sample_parsing_result = FLUID_OK;
int invalid_loops_were_sanitized = FALSE;
/* For SF2 files, we load the sample data in one large block */
if(!sf3_file)
@ -405,7 +403,7 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
{
/* SF3 samples get loaded individually, as most (or all) of them are in Ogg Vorbis format
* anyway */
#pragma omp task firstprivate(sample,sfdata,defsfont) shared(sample_parsing_result, invalid_loops_were_sanitized) default(none)
#pragma omp task firstprivate(sample,sfdata,defsfont) shared(sample_parsing_result) default(none)
{
if(fluid_defsfont_load_sampledata(defsfont, sfdata, sample) == FLUID_FAILED)
{
@ -417,46 +415,24 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
}
else
{
int modified = fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
if(modified)
{
#pragma omp critical
{
invalid_loops_were_sanitized = TRUE;
}
}
fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
fluid_voice_optimize_sample(sample);
}
}
}
else
{
#pragma omp task firstprivate(sample, defsfont) shared(invalid_loops_were_sanitized) default(none)
#pragma omp task firstprivate(sample, defsfont) default(none)
{
int modified;
/* Data pointers of SF2 samples point to large sample data block loaded above */
sample->data = defsfont->sampledata;
sample->data24 = defsfont->sample24data;
modified = fluid_sample_sanitize_loop(sample, defsfont->samplesize);
if(modified)
{
#pragma omp critical
{
invalid_loops_were_sanitized = TRUE;
}
}
fluid_sample_sanitize_loop(sample, defsfont->samplesize);
fluid_voice_optimize_sample(sample);
}
}
}
if(invalid_loops_were_sanitized)
{
FLUID_LOG(FLUID_WARN,
"Some invalid sample loops were sanitized! If you experience audible glitches, "
"start fluidsynth in verbose mode for detailed information.");
}
return sample_parsing_result;
}
@ -891,26 +867,8 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
fluid_voice_zone_t *voice_zone;
fluid_list_t *list;
fluid_voice_t *voice;
int tuned_key;
int i;
/* For detuned channels it might be better to use another key for Soundfont sample selection
* giving better approximations for the pitch than the original key.
* Example: play key 60 on 6370 Hz => use tuned key 64 for sample selection
*
* This feature is only enabled for melodic channels.
* For drum channels we always select Soundfont samples by key numbers.
*/
if(synth->channel[chan]->channel_type == CHANNEL_TYPE_MELODIC)
{
tuned_key = (int)(fluid_channel_get_key_pitch(synth->channel[chan], key) / 100.0f + 0.5f);
}
else
{
tuned_key = key;
}
global_preset_zone = fluid_defpreset_get_global_zone(defpreset);
/* run thru all the zones of this preset */
@ -921,7 +879,7 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
/* check if the note falls into the key and velocity range of this
preset */
if(fluid_zone_inside_range(&preset_zone->range, tuned_key, vel))
if(fluid_zone_inside_range(&preset_zone->range, key, vel))
{
inst = fluid_preset_zone_get_inst(preset_zone);
@ -936,7 +894,7 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
the key and velocity range of this instrument zone.
An instrument zone must be ignored when its voice is already running
played by a legato passage (see fluid_synth_noteon_monopoly_legato()) */
if(fluid_zone_inside_range(&voice_zone->range, tuned_key, vel))
if(fluid_zone_inside_range(&voice_zone->range, key, vel))
{
inst_zone = voice_zone->inst_zone;

View file

@ -789,19 +789,12 @@ int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int buffer_size)
if(sample->loopstart == sample->loopend)
{
/* Some SoundFonts disable loops by setting loopstart = loopend. While
* technically invalid, we decided to accept those samples anyway.
* Before fluidsynth 2.2.5 we've set those indices to zero, as this
* change was believed to be inaudible. This turned out to be an
* incorrect assumption, as the loop points may still be modified by
* loop offset modulators afterwards.
*/
if(sample->loopstart != sample->start)
{
// Many soundfonts set loopstart == loopend == sample->start to disabled to loop.
// Only report cases where it's not equal to the sample->start, to avoid spam.
FLUID_LOG(FLUID_DBG, "Sample '%s': zero length loop detected: loopstart == loopend == '%d', sample start '%d', using it anyway",
sample->name, sample->loopstart, sample->start);
}
* technically invalid, we decided to accept those samples anyway. Just
* ensure that those two pointers are within the sampledata by setting
* them to 0. Don't report the modification, as this change has no audible
* effect. */
sample->loopstart = sample->loopend = 0;
return FALSE;
}
else if(sample->loopstart > sample->loopend)
{

View file

@ -162,10 +162,9 @@ fluid_channel_init_ctrl(fluid_channel_t *chan, int is_all_ctrl_off)
fluid_channel_set_cc(chan, i, 0);
}
fluid_channel_clear_portamento(chan); /* Clear PTC receive */
chan->previous_cc_breath = 0;/* Reset previous breath */
}
/* Unconditionally clear PTC receive (issue #1050) */
fluid_channel_clear_portamento(chan);
/* Reset polyphonic key pressure on all voices */
for(i = 0; i < 128; i++)
@ -375,27 +374,6 @@ fluid_channel_get_sfont_bank_prog(fluid_channel_t *chan, int *sfont,
}
}
/**
* Compute the pitch for a key after applying Fluidsynth's tuning functionality
* and channel coarse/fine tunings.
* @param chan fluid_channel_t
* @param key MIDI note number (0-127)
* @return the pitch of the key
*/
fluid_real_t fluid_channel_get_key_pitch(fluid_channel_t *chan, int key)
{
if(chan->tuning)
{
return fluid_tuning_get_pitch(chan->tuning, key)
+ 100.0f * fluid_channel_get_gen(chan, GEN_COARSETUNE)
+ fluid_channel_get_gen(chan, GEN_FINETUNE);
}
else
{
return key * 100.0f;
}
}
/**
* Updates legato/ staccato playing state
* The function is called:

View file

@ -142,7 +142,6 @@ void fluid_channel_set_bank_lsb(fluid_channel_t *chan, int banklsb);
void fluid_channel_set_bank_msb(fluid_channel_t *chan, int bankmsb);
void fluid_channel_get_sfont_bank_prog(fluid_channel_t *chan, int *sfont,
int *bank, int *prog);
fluid_real_t fluid_channel_get_key_pitch(fluid_channel_t *chan, int key);
#define fluid_channel_get_preset(chan) ((chan)->preset)
#define fluid_channel_set_cc(chan, num, val) \

View file

@ -30,7 +30,6 @@
#include "fluid_event.h"
#include "fluidsynth_priv.h"
#include "fluid_midi.h"
/***************************************************************
*
@ -143,18 +142,10 @@ fluid_event_timer(fluid_event_t *evt, void *data)
* @param channel MIDI channel number
* @param key MIDI note number (0-127)
* @param vel MIDI velocity value (0-127)
* @note Since fluidsynth 2.2.2, this function will give you a #FLUID_SEQ_NOTEOFF when
* called with @p vel being zero.
*/
void
fluid_event_noteon(fluid_event_t *evt, int channel, short key, short vel)
{
if(vel == 0)
{
fluid_event_noteoff(evt, channel, key);
return;
}
evt->type = FLUID_SEQ_NOTEON;
evt->channel = channel;
evt->key = key;
@ -185,11 +176,10 @@ fluid_event_noteoff(fluid_event_t *evt, int channel, short key)
* @param evt Sequencer event structure
* @param channel MIDI channel number
* @param key MIDI note number (0-127)
* @param vel MIDI velocity value (1-127)
* @param duration Duration of note in the time scale used by the sequencer
* @param vel MIDI velocity value (0-127)
* @param duration Duration of note in the time scale used by the sequencer (by default milliseconds)
*
* @note The application should decide whether to use only Notes with duration, or separate NoteOn and NoteOff events.
* @warning Calling this function with @p vel or @p duration being zero results in undefined behavior!
*/
void
fluid_event_note(fluid_event_t *evt, int channel, short key, short vel, unsigned int duration)
@ -578,88 +568,7 @@ fluid_event_system_reset(fluid_event_t *evt)
evt->type = FLUID_SEQ_SYSTEMRESET;
}
/**
* Transforms an incoming MIDI event (from a MIDI driver or MIDI router) to a
* sequencer event.
*
* @param evt Sequencer event structure
* @param event MIDI event
* @return #FLUID_OK or #FLUID_FAILED
*
* @note This function copies the fields of the MIDI event into the provided
* sequencer event. Calling applications must create the sequencer event and set
* additional fields such as the source and destination of the sequencer event.
*
* @code{.cpp}
* // ... get MIDI event, e.g. using player_callback()
*
* // Send MIDI event to sequencer to play
* fluid_event_t *evt = new_fluid_event();
* fluid_event_set_source(evt, -1);
* fluid_event_set_dest(evt, seqid);
* fluid_event_from_midi_event(evt, event);
* fluid_sequencer_send_at(sequencer, evt, 50, 0); // relative time
* delete_fluid_event(evt);
* @endcode
*
* @since 2.2.7
*/
int fluid_event_from_midi_event(fluid_event_t *evt, const fluid_midi_event_t *event)
{
int chan;
fluid_return_val_if_fail(event != NULL, FLUID_FAILED);
chan = fluid_midi_event_get_channel(event);
switch (fluid_midi_event_get_type(event))
{
case NOTE_OFF:
fluid_event_noteoff(evt, chan, (short)fluid_midi_event_get_key(event));
break;
case NOTE_ON:
fluid_event_noteon(evt,
fluid_midi_event_get_channel(event),
(short)fluid_midi_event_get_key(event),
(short)fluid_midi_event_get_velocity(event));
break;
case CONTROL_CHANGE:
fluid_event_control_change(evt,
chan,
(short)fluid_midi_event_get_control(event),
(short)fluid_midi_event_get_value(event));
break;
case PROGRAM_CHANGE:
fluid_event_program_change(evt, chan, (short)fluid_midi_event_get_program(event));
break;
case PITCH_BEND:
fluid_event_pitch_bend(evt, chan, fluid_midi_event_get_pitch(event));
break;
case CHANNEL_PRESSURE:
fluid_event_channel_pressure(evt, chan, (short)fluid_midi_event_get_program(event));
break;
case KEY_PRESSURE:
fluid_event_key_pressure(evt,
chan,
(short)fluid_midi_event_get_key(event),
(short)fluid_midi_event_get_value(event));
break;
case MIDI_SYSTEM_RESET:
fluid_event_system_reset(evt);
break;
default: /* Not yet implemented */
return FLUID_FAILED;
}
return FLUID_OK;
}
/*
* Accessing event data

View file

@ -184,8 +184,6 @@ fluid_mod_get_source_value(const unsigned char mod_src,
if(mod_flags & FLUID_MOD_CC)
{
val = fluid_channel_get_cc(chan, mod_src);
/* From MIDI Recommended Practice (RP-036) Default Pan Formula:
* "Since MIDI controller values range from 0 to 127, the exact center
* of the range, 63.5, cannot be represented. Therefore, the effective
@ -199,20 +197,16 @@ fluid_mod_get_source_value(const unsigned char mod_src,
if(mod_src == PAN_MSB || mod_src == BALANCE_MSB)
{
*range = 126;
val -= 1;
val = fluid_channel_get_cc(chan, mod_src) - 1;
if(val < 0)
{
val = 0;
}
}
else if(mod_src == PORTAMENTO_CTRL)
else
{
// an invalid portamento fromkey should be treated as 0 when it's actually used for moulating
if(!fluid_channel_is_valid_note(val))
{
val = 0;
}
val = fluid_channel_get_cc(chan, mod_src);
}
}
else

View file

@ -1557,10 +1557,6 @@ fluid_synth_remove_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod)
/**
* Send a MIDI controller event on a MIDI channel.
*
* Most CCs are 7-bits wide in FluidSynth. There are a few exceptions which may be 14-bits wide as are documented here:
* https://github.com/FluidSynth/fluidsynth/wiki/FluidFeatures#midi-control-change-implementation-chart
*
* @param synth FluidSynth instance
* @param chan MIDI channel number (0 to MIDI channel count - 1)
* @param num MIDI controller number (0-127)
@ -1575,8 +1571,6 @@ fluid_synth_remove_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod)
* could be used as CC global for all channels belonging to basic channel 7.
* - Let a basic channel 0 in mode 3. If MIDI channel 15 is disabled it could be used
* as CC global for all channels belonging to basic channel 0.
* @warning Contrary to the MIDI Standard, this function does not clear LSB controllers,
* when MSB controllers are received.
*/
int
fluid_synth_cc(fluid_synth_t *synth, int chan, int num, int val)
@ -1800,9 +1794,6 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
case ALL_CTRL_OFF: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
fluid_channel_init_ctrl(chan, 1);
// the hold pedals have been reset, we maybe need to release voices
fluid_synth_damp_voices_by_sustain_LOCAL(synth, channum);
fluid_synth_damp_voices_by_sostenuto_LOCAL(synth, channum);
fluid_synth_modulate_voices_all_LOCAL(synth, channum);
break;
@ -2380,7 +2371,6 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
if(len < 9) // at least one byte of data should be transmitted
{
FLUID_LOG(FLUID_INFO, "SysEx DT1: message too short, dropping it.");
return FLUID_FAILED;
}
len_data = len - 8;
@ -2390,10 +2380,8 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
{
checksum += data[i];
}
checksum = 0x80 - (checksum & 0x7F);
if (checksum != data[len - 1])
if (0x80 - (checksum & 0x7F) != data[len - 1])
{
FLUID_LOG(FLUID_INFO, "SysEx DT1: dropping message on addr 0x%x due to incorrect checksum 0x%x. Correct checksum: 0x%x", addr, (int)data[len - 1], checksum);
return FLUID_FAILED;
}
@ -2401,7 +2389,6 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
{
if (len_data > 1 || (data[7] != 0 && data[7] != 0x7f))
{
FLUID_LOG(FLUID_INFO, "SysEx DT1: dropping invalid mode set message");
return FLUID_FAILED;
}
if (handled)
@ -2432,7 +2419,6 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
{
if (len_data > 1 || data[7] > 0x02)
{
FLUID_LOG(FLUID_INFO, "SysEx DT1: dropping invalid rhythm part message");
return FLUID_FAILED;
}
if (handled)
@ -2447,7 +2433,6 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
synth->channel[chan]->channel_type =
data[7] == 0x00 ? CHANNEL_TYPE_MELODIC : CHANNEL_TYPE_DRUM;
FLUID_LOG(FLUID_DBG, "SysEx DT1: setting MIDI channel %d to type %d", chan, (int)synth->channel[chan]->channel_type);
//Roland synths seem to "remember" the last instrument a channel
//used in the selected mode. This behavior is not replicated here.
fluid_synth_program_change(synth, chan, 0);
@ -3717,8 +3702,7 @@ fluid_synth_get_active_voice_count(fluid_synth_t *synth)
* @param synth FluidSynth instance
* @return Internal buffer size in audio frames.
*
* Audio is synthesized at this number of frames at a time. Defaults to 64 frames. I.e. the synth can only react to notes,
* control changes, and other audio affecting events after having processed 64 audio frames.
* Audio is synthesized this number of frames at a time. Defaults to 64 frames.
*/
int
fluid_synth_get_internal_bufsize(fluid_synth_t *synth)
@ -6835,9 +6819,8 @@ fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t *synth, int chan,
synth->storeid = fluid_voice_get_id(voice);
}
/* Force the voice into release stage except if pedaling
(sostenuto or sustain) is active */
fluid_voice_noteoff(voice);
/* Force the voice into release stage (pedaling is ignored) */
fluid_voice_release(voice);
}
}
}

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