mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-04-09 17:22:32 +00:00
Compare commits
226 commits
v2.2.1
...
native_win
Author | SHA1 | Date | |
---|---|---|---|
|
2867c8d8db | ||
|
b58d142dd9 | ||
|
32f4347d26 | ||
|
85fcbde9e0 | ||
|
7e3fdc9056 | ||
|
57554ee35a | ||
|
24898c126d | ||
|
1f8c6a4633 | ||
|
9910b0dc9b | ||
|
a50680aafa | ||
|
3a3ed4f783 | ||
|
b274aaefba | ||
|
58ec0d8eb7 | ||
|
41f00ec8cb | ||
|
3591299ea0 | ||
|
ff362b52cd | ||
|
fe7fa3e309 | ||
|
1b4b7ddbfe | ||
|
b675a392ea | ||
|
f06619e079 | ||
|
a293761e44 | ||
|
7ede2382d3 | ||
|
0e0a287be4 | ||
|
0d0b4d4b84 | ||
|
d554067fc5 | ||
|
f013e82d58 | ||
|
eff5da51c4 | ||
|
308cf73796 | ||
|
2779d5b2b8 | ||
|
1daf078708 | ||
|
50003761c1 | ||
|
4ee4b0403e | ||
|
a0ca05e16d | ||
|
0771899e3f | ||
|
0995727374 | ||
|
cd0b3ce0c5 | ||
|
486e3f34d7 | ||
|
b80ad6ecf5 | ||
|
034f316d2c | ||
|
2bf041cf76 | ||
|
552bfce3ed | ||
|
ab0b79c114 | ||
|
15529d50a8 | ||
|
2acb068075 | ||
|
a9d555ff50 | ||
|
7e081d700b | ||
|
326d90e952 | ||
|
49a3b410f0 | ||
|
757b151601 | ||
|
719b525e2b | ||
|
b1a28624ba | ||
|
88e039efeb | ||
|
8b00644751 | ||
|
5dcae73657 | ||
|
8784dbbc74 | ||
|
c037dde536 | ||
|
2715e4bc98 | ||
|
c88ed31585 | ||
|
344796a6a8 | ||
|
122066ca6d | ||
|
80611111e9 | ||
|
22144a4fa3 | ||
|
bf23f7a2a5 | ||
|
fa619aaae8 | ||
|
764ceae1ef | ||
|
62ed1c813d | ||
|
ea9758a2ed | ||
|
8d00f6cdac | ||
|
43282855dd | ||
|
3ac9b6fbf0 | ||
|
adc2794ef6 | ||
|
a5bdbd57e2 | ||
|
d8113d497b | ||
|
ac0aab2fa0 | ||
|
0b4fa214b6 | ||
|
b89898ef7f | ||
|
4a36f0b085 | ||
|
3e0321f49c | ||
|
0c4342b461 | ||
|
d6903d0ff7 | ||
|
91515b09c4 | ||
|
59fdc3795b | ||
|
290ab8402b | ||
|
634a8b0c04 | ||
|
166f767767 | ||
|
8a96ec9c3a | ||
|
bee42dd5cc | ||
|
f4f897d3bf | ||
|
b580a112c1 | ||
|
dbd7e728b6 | ||
|
e3d8b3f2c3 | ||
|
b7a0264459 | ||
|
3229899a34 | ||
|
dc24dcd435 | ||
|
015c6af52d | ||
|
46998a9d21 | ||
|
47d57bfe78 | ||
|
4eb3afe8a4 | ||
|
6b96c19b01 | ||
|
870ae6be88 | ||
|
ab3ab92c15 | ||
|
13b376819c | ||
|
881236dc03 | ||
|
a173da91da | ||
|
76639ecf33 | ||
|
bf83911631 | ||
|
ce6e270a41 | ||
|
d9f95b77d4 | ||
|
cfc5d722ec | ||
|
d47f53518e | ||
|
8eaa91bf3b | ||
|
0d92eba476 | ||
|
776b4510c1 | ||
|
72b74820a9 | ||
|
30e80abe77 | ||
|
69113aad89 | ||
|
3bc4e88903 | ||
|
94c459970e | ||
|
e63ea6698e | ||
|
6292e2c04d | ||
|
c831deb81c | ||
|
5b36a556fe | ||
|
56034e7f2b | ||
|
056e29ea59 | ||
|
56fd559860 | ||
|
6c807bdd37 | ||
|
a3dd7fddcb | ||
|
a01917baa2 | ||
|
bb3bc6da26 | ||
|
90da8af70f | ||
|
de05ef2a1c | ||
|
fa75468595 | ||
|
7ef8652326 | ||
|
db5db4b845 | ||
|
6c593180ce | ||
|
1ddf4c54cf | ||
|
563592aa3d | ||
|
926581851e | ||
|
27d357ed31 | ||
|
1d9957f14b | ||
|
6a0d838f33 | ||
|
054685fa67 | ||
|
6e123d6ef0 | ||
|
b23dc4e961 | ||
|
55678a078a | ||
|
19b9a12e4f | ||
|
5a71336bd9 | ||
|
21aca082a9 | ||
|
66b77bfb6f | ||
|
1e6c5b75e3 | ||
|
ebed81099d | ||
|
7ca3407d30 | ||
|
ad4f1b9191 | ||
|
f6fa0290b7 | ||
|
a244420666 | ||
|
e6ce0f4845 | ||
|
fab1ca1ca9 | ||
|
ec0d6e011e | ||
|
5e1fbf1866 | ||
|
fefd22a9d6 | ||
|
c1e286629f | ||
|
2fafca42a1 | ||
|
f023d7e014 | ||
|
64a7787e90 | ||
|
cf5fbac9af | ||
|
ff6b4db503 | ||
|
8e56188316 | ||
|
ec6d563c39 | ||
|
c68a10ca13 | ||
|
62b60ae161 | ||
|
1511b5a575 | ||
|
0e3411cba4 | ||
|
475f902584 | ||
|
4240d31e51 | ||
|
fc21d284dc | ||
|
a0ec2c5932 | ||
|
e4c8ef080c | ||
|
aa2561d091 | ||
|
346331020b | ||
|
be79856caa | ||
|
e096919477 | ||
|
7ff164d8ab | ||
|
bfca737a7c | ||
|
92089e0a0f | ||
|
95e3693779 | ||
|
15bd824af0 | ||
|
9eb855a96d | ||
|
0ef0c703b6 | ||
|
6b7fc061eb | ||
|
e36d1438df | ||
|
7dd8f0118c | ||
|
f176cd8e7b | ||
|
c232274d6a | ||
|
ecdae699da | ||
|
12cc9ed74b | ||
|
962a544d15 | ||
|
ed555f076b | ||
|
0635766f85 | ||
|
ea2a824383 | ||
|
e4ef966630 | ||
|
6e23e82a29 | ||
|
fc4dcd709e | ||
|
e6b3ce8a6b | ||
|
f81caf37f1 | ||
|
d709339ab5 | ||
|
2321868124 | ||
|
de478947bf | ||
|
bf574c6f03 | ||
|
17b6e44a3f | ||
|
9380e27009 | ||
|
768fa225db | ||
|
20e09bb76d | ||
|
9e9aa997f1 | ||
|
17fb48def5 | ||
|
148cec6c03 | ||
|
aba9485a9c | ||
|
eda2fb21b0 | ||
|
bf884758cb | ||
|
a28a5e6d20 | ||
|
cd393d863a | ||
|
8446023255 | ||
|
fbd9d139ec | ||
|
ba99ed36dc | ||
|
e8963251be | ||
|
8ddf8fadb5 | ||
|
6d78ebe154 |
165 changed files with 5279 additions and 1355 deletions
|
@ -1,81 +0,0 @@
|
|||
|
||||
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)
|
|
@ -1,27 +0,0 @@
|
|||
# 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'
|
|
@ -1,3 +1,18 @@
|
|||
|
||||
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
|
||||
|
@ -18,18 +33,19 @@ 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: 'dd5bd03075149d7cf8441875c1a344e8beb57dde'
|
||||
FFI_VERSION: '3.4.2'
|
||||
GETTEXT_VERSION: '0.21'
|
||||
#need to switch to meson build system to use a more recent version
|
||||
GLIB_VERSION: '2.58'
|
||||
GLIB_EXTRAVERSION: '3'
|
||||
GLIB_VERSION: '2.71'
|
||||
GLIB_EXTRAVERSION: '2'
|
||||
OBOE_VERSION: '1.5.0'
|
||||
SNDFILE_VERSION: '1.0.31'
|
||||
INSTPATCH_VERSION: '1.1.6'
|
||||
VORBIS_VERSION: '1.3.7'
|
||||
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'
|
||||
OGG_VERSION: '1.3.5'
|
||||
OPUS_VERSION: '1.3.1'
|
||||
FLAC_VERSION: '1.3.4'
|
||||
PCRE_VERSION: '8.45'
|
||||
|
||||
# Android NDK sources and standalone toolchain is put here
|
||||
DEV: '$(System.DefaultWorkingDirectory)/android-build-root'
|
||||
|
@ -37,17 +53,22 @@ 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: '$(PREFIX)/lib/pkgconfig'
|
||||
PKG_CONFIG_PATH: '$(LIBPATH0)/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)'
|
||||
|
||||
|
@ -61,9 +82,10 @@ 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 -fno-integrated-as"
|
||||
CFLAGS: "-fPIE -fPIC -I$(PREFIX)/include --sysroot=$(NDK_TOOLCHAIN)/sysroot -I$(NDK_TOOLCHAIN)/sysroot/usr/include -Werror=implicit-function-declaration"
|
||||
CXXFLAGS: $(CFLAGS)
|
||||
CPPFLAGS: $(CXXFLAGS)
|
||||
DEBIAN_FRONTEND: 'noninteractive'
|
||||
|
||||
ARTIFACT_NAME: 'fluidsynth-android$(ANDROID_API)'
|
||||
|
||||
|
@ -76,30 +98,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)-none-linux-$(ANDROID_TARGET_ABI)"
|
||||
AUTOTOOLS_TARGET: "$(ARCH)-linux-android$(ANDROID_TARGET_ABI)"
|
||||
AARCH64:
|
||||
ARCH: 'aarch64'
|
||||
ANDROID_ARCH: 'aarch64'
|
||||
ANDROID_ABI_CMAKE: 'arm64-v8a'
|
||||
ANDROID_TARGET_ABI:
|
||||
#AUTOTOOLS_TARGET: "$(ARCH)-none-linux-android"
|
||||
AUTOTOOLS_TARGET: "$(ARCH)-none-linux"
|
||||
ANDROID_ABI_MESON: 'aarch64'
|
||||
AUTOTOOLS_TARGET: "$(ARCH)-none-linux-android"
|
||||
i686:
|
||||
ARCH: 'i686'
|
||||
ANDROID_ARCH: 'i686'
|
||||
ANDROID_ABI_CMAKE: 'x86'
|
||||
ANDROID_TARGET_ABI:
|
||||
#AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
|
||||
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux"
|
||||
ANDROID_ABI_MESON: 'x86'
|
||||
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
|
||||
x86_64:
|
||||
ARCH: 'x86_64'
|
||||
ANDROID_ARCH: 'x86_64'
|
||||
ANDROID_ABI_CMAKE: 'x86_64'
|
||||
ANDROID_TARGET_ABI:
|
||||
#AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
|
||||
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux"
|
||||
ANDROID_ABI_MESON: 'x86_64'
|
||||
AUTOTOOLS_TARGET: "$(ARCH)-pc-linux-android"
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
@ -110,13 +132,22 @@ 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/archive/${FFI_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
|
||||
tar zxf libffi-${FFI_VERSION}.tar.gz
|
||||
|
||||
wget http://ftp.gnu.org/pub/gnu/gettext/gettext-${GETTEXT_VERSION}.tar.gz
|
||||
|
@ -140,15 +171,25 @@ 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/${FLAC_VERSION}.tar.gz
|
||||
wget -O flac-${FLAC_VERSION}.tar.gz https://github.com/xiph/flac/archive/refs/tags/${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.gz | cacheVersion1'
|
||||
key: '$(ARCH) | $(DEV)/*.tar.*'
|
||||
path: '$(PREFIX)'
|
||||
cacheHitVar: 'CACHE_RESTORED'
|
||||
displayName: 'Cache fluidsynth dependency libraries'
|
||||
|
@ -161,19 +202,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: ne(variables.CACHE_RESTORED, 'true')
|
||||
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
|
||||
enabled: 'false'
|
||||
|
||||
- script: |
|
||||
sudo apt-get update -y
|
||||
displayName: 'Update apt'
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
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'))
|
||||
|
||||
- script: |
|
||||
set -ex
|
||||
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')
|
||||
ln -sfn $ANDROID_SDK_ROOT/ndk/21.4.7075529 $ANDROID_NDK_ROOT
|
||||
displayName: 'Use NDK r22'
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
|
@ -189,7 +230,6 @@ 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)
|
||||
|
@ -222,9 +262,10 @@ jobs:
|
|||
./configure \
|
||||
--host=${AUTOTOOLS_TARGET} \
|
||||
--prefix=${PREFIX} \
|
||||
--libdir=${LIBPATH0} \
|
||||
--disable-rpath \
|
||||
--disable-static \
|
||||
--enable-shared \
|
||||
--enable-static \
|
||||
--disable-shared \
|
||||
--with-pic \
|
||||
--disable-maintainer-mode \
|
||||
--disable-silent-rules \
|
||||
|
@ -237,7 +278,15 @@ jobs:
|
|||
|
||||
displayName: 'Compile libiconv'
|
||||
workingDirectory: $(DEV)
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
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'))
|
||||
|
||||
- script: |
|
||||
set -ex
|
||||
|
@ -247,109 +296,13 @@ 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} --enable-shared --disable-static
|
||||
./configure --host=${AUTOTOOLS_TARGET} --prefix=${PREFIX} --libdir=${LIBPATH0} --enable-static --disable-shared
|
||||
make -j$((`nproc`+1))
|
||||
make install
|
||||
popd
|
||||
displayName: 'Compile libffi'
|
||||
workingDirectory: $(DEV)
|
||||
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'
|
||||
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
|
||||
|
||||
- script: |
|
||||
set -ex
|
||||
|
@ -358,14 +311,15 @@ jobs:
|
|||
./configure \
|
||||
--host=${AUTOTOOLS_TARGET} \
|
||||
--prefix=${PREFIX} \
|
||||
--libdir=${LIBPATH0} \
|
||||
--disable-rpath \
|
||||
--disable-libasprintf \
|
||||
--disable-java \
|
||||
--disable-native-java \
|
||||
--disable-openmp \
|
||||
--disable-curses \
|
||||
--disable-static \
|
||||
--enable-shared \
|
||||
--enable-static \
|
||||
--disable-shared \
|
||||
--with-pic \
|
||||
--disable-maintainer-mode \
|
||||
--disable-silent-rules \
|
||||
|
@ -376,95 +330,85 @@ jobs:
|
|||
popd
|
||||
displayName: 'Compile gettext'
|
||||
workingDirectory: $(DEV)
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
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'
|
||||
|
||||
- script: |
|
||||
set -ex
|
||||
|
||||
export PKGCFG=`which pkg-config`
|
||||
pushd glib-${GLIB_VERSION}.${GLIB_EXTRAVERSION}
|
||||
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
|
||||
|
||||
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'
|
||||
EOF
|
||||
|
||||
# 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
|
||||
cat cross_file.ini
|
||||
|
||||
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
|
||||
# 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
|
||||
popd
|
||||
displayName: 'Compile glib'
|
||||
displayName: 'Compile glib (meson)'
|
||||
workingDirectory: $(DEV)
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
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'))
|
||||
|
||||
- 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
|
||||
|
@ -472,27 +416,17 @@ 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'
|
||||
|
||||
- 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)
|
||||
# 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'
|
||||
|
||||
- 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)'
|
||||
|
@ -519,7 +453,7 @@ jobs:
|
|||
|
||||
displayName: 'Create fake oboe.pc'
|
||||
workingDirectory: $(DEV)
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
|
||||
|
||||
- template: cmake-android.yml
|
||||
parameters:
|
||||
|
@ -558,27 +492,29 @@ jobs:
|
|||
sourceDir: '.'
|
||||
condition: succeeded()
|
||||
installCommand: 'cp *.so ${PREFIX}/lib/'
|
||||
|
||||
|
||||
- script: |
|
||||
ls -Rg $(PREFIX)
|
||||
displayName: 'Show cross-compiled files in $(PREFIX)'
|
||||
condition: always()
|
||||
condition: or(succeeded(), failed())
|
||||
|
||||
- script: |
|
||||
set -ex
|
||||
mkdir -p $(Build.ArtifactStagingDirectory)/$(ARCH)
|
||||
cd $(Build.ArtifactStagingDirectory)/$(ARCH)
|
||||
cp -a $(PREFIX)/lib/* .
|
||||
# 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/* .
|
||||
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
|
||||
|
@ -586,20 +522,21 @@ 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) $(ARCH)'
|
||||
displayName: 'Publishing Artefacts for Android API$(ANDROID_API) $(ANDROID_ABI_CMAKE)'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
ArtifactName: '$(ARTIFACT_NAME)'
|
||||
|
@ -611,4 +548,4 @@ jobs:
|
|||
pushd build
|
||||
make uninstall
|
||||
popd
|
||||
displayName: 'Uninstall fluidsynth'
|
||||
displayName: 'Uninstall fluidsynth'
|
||||
|
|
199
.azure/azure-pipelines-mac.yml
Normal file
199
.azure/azure-pipelines-mac.yml
Normal file
|
@ -0,0 +1,199 @@
|
|||
|
||||
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'
|
154
.azure/azure-pipelines-vcpkg.yml
Normal file
154
.azure/azure-pipelines-vcpkg.yml
Normal file
|
@ -0,0 +1,154 @@
|
|||
|
||||
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)
|
|
@ -1,7 +1,17 @@
|
|||
# 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
|
||||
|
||||
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'
|
||||
|
||||
jobs:
|
||||
- job: WindowsXP
|
||||
|
@ -14,11 +24,15 @@ 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:
|
||||
|
@ -28,7 +42,7 @@ jobs:
|
|||
# https://dev.azure.com/tommbrt/_apis/projects?api-version=5.0
|
||||
project: 'd3638885-de4a-4ce7-afe7-f237ae461c07'
|
||||
pipeline: 1
|
||||
artifactName: libinstpatch-$(platform)
|
||||
artifactName: libinstpatch-XP-$(platform)
|
||||
downloadPath: '$(Build.ArtifactStagingDirectory)'
|
||||
displayName: 'Get libinstpatch'
|
||||
- script: |
|
||||
|
@ -42,11 +56,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-$(platform)
|
||||
cd $(Build.ArtifactStagingDirectory)\libinstpatch-XP-$(platform)
|
||||
cp -rf * d:\deps\
|
||||
mv -f * ..
|
||||
cd ..
|
||||
rmdir $(Build.ArtifactStagingDirectory)\libinstpatch-$(platform)\
|
||||
rmdir $(Build.ArtifactStagingDirectory)\libinstpatch-XP-$(platform)\
|
||||
DEL /F C:\Strawberry\perl\bin\pkg-config.bat
|
||||
displayName: 'Prerequisites'
|
||||
- script: |
|
||||
|
@ -54,8 +68,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 -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
|
||||
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
|
||||
displayName: 'Compile fluidsynth'
|
||||
- script: |
|
||||
@ECHO ON
|
||||
|
@ -63,6 +77,12 @@ 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
|
||||
|
@ -99,7 +119,7 @@ jobs:
|
|||
CMAKE_FLAGS: -DBUILD_SHARED_LIBS=0
|
||||
CMAKE_CONFIG: Release
|
||||
minimal:
|
||||
CMAKE_FLAGS: -Denable-ipv6=0 -Denable-network=0 -Denable-aufile=0 -Denable-dbus=0 -Denable-threads=0 -Denable-winmidi=0 -Denable-waveout=0 -Denable-dsound=0 -Denable-libsndfile=0 -Denable-floats=1
|
||||
CMAKE_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_CONFIG: Release
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
|
@ -121,8 +141,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 .. || exit -1
|
||||
cmake --build . --config $(CMAKE_CONFIG) || 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
|
||||
displayName: 'Compile fluidsynth'
|
||||
- script: |
|
||||
@ECHO ON
|
||||
|
@ -130,24 +150,30 @@ 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:
|
||||
|
@ -186,8 +212,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 -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1
|
||||
mingw32-make.exe -j4 all || 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
|
||||
displayName: 'Compile fluidsynth'
|
||||
- script: |
|
||||
@ECHO ON
|
||||
|
@ -198,7 +224,15 @@ jobs:
|
|||
cd build || exit -1
|
||||
mingw32-make.exe -j4 check || exit -1
|
||||
displayName: 'Execute Unittests'
|
||||
continueOnError: 'true'
|
||||
- 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'
|
||||
- script: |
|
||||
@ECHO ON
|
||||
cd build
|
|
@ -11,7 +11,7 @@ parameters:
|
|||
default: $(DEV)
|
||||
- name: condition
|
||||
type: string
|
||||
default: ne(variables.CACHE_RESTORED, 'true')
|
||||
default: and(succeeded(), ne(variables.CACHE_RESTORED, 'true'))
|
||||
- name: installCommand
|
||||
type: string
|
||||
default: 'make install'
|
||||
|
@ -33,6 +33,7 @@ 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} \
|
||||
|
@ -55,3 +56,12 @@ 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 }}
|
||||
|
|
71
.github/workflows/codeql-analysis.yml
vendored
Normal file
71
.github/workflows/codeql-analysis.yml
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
# 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
|
32
.github/workflows/linux.yml
vendored
32
.github/workflows/linux.yml
vendored
|
@ -1,6 +1,14 @@
|
|||
name: FluidSynth Linux
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
paths-ignore:
|
||||
- '.azure/**'
|
||||
- '.circleci/**'
|
||||
- '.github/workflows/sonarcloud.yml'
|
||||
- '.cirrus.yml'
|
||||
- 'README.md'
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
|
@ -17,26 +25,22 @@ 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"]
|
||||
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"]
|
||||
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
|
||||
|
@ -58,7 +62,6 @@ 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
|
||||
|
@ -89,6 +92,11 @@ 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
|
||||
|
|
10
.github/workflows/sonarcloud.yml
vendored
10
.github/workflows/sonarcloud.yml
vendored
|
@ -4,9 +4,15 @@ 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
|
||||
|
@ -79,7 +85,7 @@ jobs:
|
|||
ls -la ${{ github.workspace }}/build
|
||||
ls -la ${{ github.workspace }}/build/coverage
|
||||
|
||||
# The offical sonarsource/sonarcloud-github-action@v1.5 action does not work properly.
|
||||
# The official 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
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
build/
|
||||
.vs/
|
||||
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
|
|
6
.obs/workflows.yml
Normal file
6
.obs/workflows.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
workflow:
|
||||
steps:
|
||||
- branch_package:
|
||||
source_project: home:derselbst:anmp
|
||||
source_package: fluidsynth
|
||||
target_project: home:derselbst:anmp:github-ci
|
2
AUTHORS
2
AUTHORS
|
@ -151,3 +151,5 @@ Sven Meier
|
|||
Marcus Weseloh
|
||||
Jean-jacques Ceresa
|
||||
Vladimir Davidovich
|
||||
Tamás Korodi
|
||||
Evan Miller
|
||||
|
|
578
CMakeLists.txt
578
CMakeLists.txt
|
@ -1,6 +1,6 @@
|
|||
# FluidSynth - A Software Synthesizer
|
||||
#
|
||||
# Copyright (C) 2003-2021 Peter Hanappe and others.
|
||||
# Copyright (C) 2003-2022 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,18 +19,21 @@
|
|||
|
||||
# CMake based build system. Pedro Lopez-Cabanillas <plcl@users.sf.net>
|
||||
|
||||
cmake_minimum_required ( VERSION 3.1.0 ) # because of CMAKE_C_STANDARD
|
||||
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
|
||||
|
||||
if(POLICY CMP0075)
|
||||
if(POLICY CMP0075) # CMake version 3.13.5 warns when the policy is not set or value is OLD
|
||||
cmake_policy(SET CMP0075 NEW)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0091)
|
||||
if(POLICY CMP0091) # new in CMake 3.15, defaults to OLD
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
endif()
|
||||
|
||||
project ( FluidSynth C CXX )
|
||||
set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_admin )
|
||||
list( APPEND CMAKE_MODULE_PATH ${FluidSynth_SOURCE_DIR}/cmake_admin )
|
||||
|
||||
# FluidSynth package name
|
||||
set ( PACKAGE "fluidsynth" )
|
||||
|
@ -38,7 +41,7 @@ set ( PACKAGE "fluidsynth" )
|
|||
# FluidSynth package version
|
||||
set ( FLUIDSYNTH_VERSION_MAJOR 2 )
|
||||
set ( FLUIDSYNTH_VERSION_MINOR 2 )
|
||||
set ( FLUIDSYNTH_VERSION_MICRO 1 )
|
||||
set ( FLUIDSYNTH_VERSION_MICRO 8 )
|
||||
set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" )
|
||||
set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
|
||||
|
||||
|
@ -52,20 +55,22 @@ 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 0 )
|
||||
set ( LIB_VERSION_AGE 1 )
|
||||
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 )
|
||||
|
@ -86,10 +91,11 @@ 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" )
|
||||
|
@ -112,20 +118,6 @@ 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)
|
||||
|
||||
|
@ -133,6 +125,7 @@ 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.
|
||||
|
@ -149,11 +142,11 @@ if ( NOT OS2 )
|
|||
endif ( NOT OS2 )
|
||||
|
||||
# enforce visibility control for all types of cmake targets
|
||||
if ( POLICY CMP0063 )
|
||||
if ( POLICY CMP0063 ) # since version 3.3, CMake version 3.21.2 warns when the policy is not set and uses OLD behavior.
|
||||
cmake_policy ( SET CMP0063 NEW )
|
||||
endif ( POLICY CMP0063 )
|
||||
|
||||
# Default install directory names
|
||||
# Default install directory names, some provided by GNUInstallDirs
|
||||
include ( DefaultDirs )
|
||||
|
||||
# Basic C library checks
|
||||
|
@ -188,6 +181,7 @@ 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 )
|
||||
|
@ -200,12 +194,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 )
|
||||
if ( NOT APPLE AND NOT OS2 AND NOT EMSCRIPTEN )
|
||||
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 )
|
||||
endif ( NOT APPLE AND NOT OS2 AND NOT EMSCRIPTEN )
|
||||
|
||||
# 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" )
|
||||
|
@ -267,23 +261,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 "Targetting Windows Version ${windows-version}" )
|
||||
message ( STATUS "Targeting 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}" )
|
||||
|
@ -328,10 +322,18 @@ 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
|
||||
|
@ -369,7 +371,7 @@ unset ( MACOSX_FRAMEWORK CACHE )
|
|||
if ( CMAKE_SYSTEM MATCHES "Darwin" )
|
||||
set ( DARWIN 1 )
|
||||
set ( CMAKE_INSTALL_NAME_DIR
|
||||
${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR} )
|
||||
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} )
|
||||
if ( enable-coreaudio )
|
||||
check_include_file ( CoreAudio/AudioHardware.h COREAUDIO_FOUND )
|
||||
if ( COREAUDIO_FOUND )
|
||||
|
@ -412,17 +414,15 @@ if ( enable-profiling )
|
|||
|
||||
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPT_FLAGS}" )
|
||||
|
||||
if ( CMAKE_VERSION VERSION_GREATER "3.6.0" )
|
||||
find_program( CLANG_TIDY
|
||||
NAMES "clang-tidy"
|
||||
DOC "Path to clang-tidy executable" )
|
||||
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 )
|
||||
endif ( CMAKE_VERSION VERSION_GREATER "3.6.0" )
|
||||
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 ( enable-profiling )
|
||||
|
||||
|
@ -440,11 +440,6 @@ 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 )
|
||||
|
@ -461,13 +456,13 @@ endif ( CMAKE_BUILD_TYPE MATCHES "Debug" )
|
|||
file(GLOB_RECURSE
|
||||
ALL_SOURCE_FILES
|
||||
LIST_DIRECTORIES false
|
||||
${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]
|
||||
${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]
|
||||
)
|
||||
|
||||
find_program ( ASTYLE "astyle" )
|
||||
|
@ -487,164 +482,236 @@ if ( ASTYLE )
|
|||
)
|
||||
endif(ASTYLE)
|
||||
|
||||
if(NOT enable-pkgconfig)
|
||||
if ( NOT WIN32 )
|
||||
find_package ( PkgConfig REQUIRED )
|
||||
|
||||
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 )
|
||||
# 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")
|
||||
|
||||
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()
|
||||
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 )
|
||||
|
||||
SET( GLIB_INCLUDE_DIRS ${GLIBH_DIR} ${GLIBCONF_DIR} )
|
||||
SET( GLIB_LIBRARIES ${GLIB_LIB} ${GTHREAD_LIB} )
|
||||
include ( PkgConfigHelpers ) # has unset_pkg_config()
|
||||
|
||||
message( STATUS "GLIB_INCLUDE_DIRS: " ${GLIB_INCLUDE_DIRS} )
|
||||
message( STATUS "GLIB_LIBRARIES: " ${GLIB_LIBRARIES} )
|
||||
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 )
|
||||
|
||||
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 )
|
||||
# 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 )
|
||||
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 )
|
||||
unset ( PULSE_SUPPORT CACHE )
|
||||
if ( enable-pulseaudio )
|
||||
pkg_check_modules ( PULSE libpulse-simple>=0.9.8 IMPORTED_TARGET )
|
||||
set ( PULSE_SUPPORT ${PULSE_FOUND} )
|
||||
else ( enable-pulseaudio )
|
||||
if ( PULSE_SUPPORT )
|
||||
list( APPEND PC_REQUIRES_PRIV "libpulse-simple")
|
||||
endif ( PULSE_SUPPORT )
|
||||
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 )
|
||||
unset ( ALSA_SUPPORT CACHE )
|
||||
if ( enable-alsa )
|
||||
pkg_check_modules ( ALSA alsa>=0.9.1 IMPORTED_TARGET )
|
||||
set ( ALSA_SUPPORT ${ALSA_FOUND} )
|
||||
else ( enable-alsa )
|
||||
if ( ALSA_SUPPORT )
|
||||
list( APPEND PC_REQUIRES_PRIV "alsa")
|
||||
endif ( ALSA_SUPPORT )
|
||||
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 )
|
||||
unset ( PORTAUDIO_SUPPORT CACHE )
|
||||
if ( enable-portaudio )
|
||||
pkg_check_modules ( PORTAUDIO portaudio-2.0>=19 IMPORTED_TARGET )
|
||||
set ( PORTAUDIO_SUPPORT ${PORTAUDIO_FOUND} )
|
||||
else ( enable-portaudio )
|
||||
if ( PORTAUDIO_SUPPORT )
|
||||
list( APPEND PC_REQUIRES_PRIV "portaudio-2.0")
|
||||
endif ()
|
||||
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 )
|
||||
unset ( JACK_SUPPORT CACHE )
|
||||
if ( enable-jack )
|
||||
pkg_check_modules ( JACK jack IMPORTED_TARGET )
|
||||
set ( JACK_SUPPORT ${JACK_FOUND} )
|
||||
else ( enable-jack )
|
||||
if (JACK_SUPPORT)
|
||||
sanitize_target_dirs(PkgConfig::JACK)
|
||||
list( APPEND PC_REQUIRES_PRIV "jack")
|
||||
endif()
|
||||
else ( enable-jack )
|
||||
unset_pkg_config ( JACK )
|
||||
endif ( enable-jack )
|
||||
endif ( enable-jack )
|
||||
|
||||
unset ( LASH_SUPPORT CACHE )
|
||||
if ( enable-lash )
|
||||
pkg_check_modules ( LASH lash-1.0>=0.3 )
|
||||
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 )
|
||||
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 )
|
||||
set ( SYSTEMD_SUPPORT ${SYSTEMD_FOUND} )
|
||||
else ( enable-systemd )
|
||||
unset_pkg_config ( SYSTEMD )
|
||||
endif ( enable-systemd )
|
||||
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 ( DBUS_SUPPORT CACHE )
|
||||
if ( enable-dbus )
|
||||
pkg_check_modules ( DBUS dbus-1>=1.0.0 )
|
||||
set ( DBUS_SUPPORT ${DBUS_FOUND} )
|
||||
else ( enable-dbus )
|
||||
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_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 )
|
||||
set ( LADSPA 1 )
|
||||
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 IMPORTED_TARGET )
|
||||
set ( LADSPA 1 )
|
||||
list( APPEND PC_REQUIRES_PRIV "gmodule-2.0")
|
||||
endif ( LADSPA_SUPPORT )
|
||||
endif ( enable-ladspa )
|
||||
|
||||
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 ( 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 ( 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 ( 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 ( 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 ( 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 ( 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 ( 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 ( AUFILE_SUPPORT CACHE )
|
||||
if ( enable-aufile )
|
||||
|
@ -689,24 +756,27 @@ endif ( enable-threads )
|
|||
|
||||
unset ( HAVE_OPENMP CACHE )
|
||||
find_package ( OpenMP QUIET )
|
||||
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 )
|
||||
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.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# manipulate some variables to setup a proper test env
|
||||
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")
|
||||
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")
|
||||
|
||||
# Make sure to link against libm before checking for math functions below
|
||||
set ( CMAKE_REQUIRED_LIBRARIES "${LIBFLUID_LIBS};${WINDOWS_LIBS}" )
|
||||
|
@ -762,25 +832,22 @@ 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 ( ${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}
|
||||
)
|
||||
configure_file ( ${FluidSynth_SOURCE_DIR}/src/config.cmake
|
||||
${FluidSynth_BINARY_DIR}/config.h )
|
||||
|
||||
# required to allow ctest to be called from top-level build directory
|
||||
ENABLE_TESTING()
|
||||
|
@ -793,61 +860,66 @@ add_subdirectory ( doc )
|
|||
# pkg-config support
|
||||
set ( prefix "${CMAKE_INSTALL_PREFIX}" )
|
||||
set ( exec_prefix "\${prefix}" )
|
||||
if ( IS_ABSOLUTE "${LIB_INSTALL_DIR}" )
|
||||
set ( libdir "${LIB_INSTALL_DIR}" )
|
||||
if ( IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}" )
|
||||
set ( libdir "${CMAKE_INSTALL_LIBDIR}" )
|
||||
else ()
|
||||
set ( libdir "\${exec_prefix}/${LIB_INSTALL_DIR}" )
|
||||
set ( libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}" )
|
||||
endif ()
|
||||
if ( IS_ABSOLUTE "${INCLUDE_INSTALL_DIR}" )
|
||||
set ( includedir "${INCLUDE_INSTALL_DIR}" )
|
||||
if ( IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}" )
|
||||
set ( includedir "${CMAKE_INSTALL_INCLUDEDIR}" )
|
||||
else ()
|
||||
set ( includedir "\${prefix}/${INCLUDE_INSTALL_DIR}" )
|
||||
set ( includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}" )
|
||||
endif ()
|
||||
configure_file ( fluidsynth.pc.in
|
||||
${CMAKE_BINARY_DIR}/fluidsynth.pc IMMEDIATE @ONLY )
|
||||
install ( FILES ${CMAKE_BINARY_DIR}/fluidsynth.pc
|
||||
DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
# 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
|
||||
${CMAKE_BINARY_DIR}/fluidsynth.service @ONLY )
|
||||
${FluidSynth_BINARY_DIR}/fluidsynth.service @ONLY )
|
||||
|
||||
configure_file ( fluidsynth.conf.in
|
||||
${CMAKE_BINARY_DIR}/fluidsynth.conf @ONLY )
|
||||
${FluidSynth_BINARY_DIR}/fluidsynth.conf @ONLY )
|
||||
|
||||
endif ( DEFINED FLUID_DAEMON_ENV_FILE )
|
||||
|
||||
# uninstall custom target
|
||||
configure_file ( "${CMAKE_SOURCE_DIR}/cmake_admin/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||
configure_file ( "${FluidSynth_SOURCE_DIR}/cmake_admin/cmake_uninstall.cmake.in"
|
||||
"${FluidSynth_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||
add_custom_target ( uninstall
|
||||
"${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}
|
||||
)
|
||||
|
||||
"${CMAKE_COMMAND}" -P "${FluidSynth_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
endif ( UNIX )
|
||||
|
||||
include ( report )
|
||||
|
@ -855,8 +927,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 "${CMAKE_SOURCE_DIR}/README.md" )
|
||||
set ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE" )
|
||||
set ( CPACK_PACKAGE_DESCRIPTION_FILE "${FluidSynth_SOURCE_DIR}/README.md" )
|
||||
set ( CPACK_RESOURCE_FILE_LICENSE "${FluidSynth_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} )
|
||||
|
|
10
FluidSynthConfig.cmake.in
Normal file
10
FluidSynthConfig.cmake.in
Normal file
|
@ -0,0 +1,10 @@
|
|||
# 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")
|
|
@ -8,8 +8,6 @@
|
|||
| <img src="https://www.microsoft.com/windows/favicon.ico" height="25" alt=""> **Windows (vcpkg)** | [](https://dev.azure.com/tommbrt/tommbrt/_build/latest?definitionId=6&branchName=master) |
|
||||
| <img src="https://www.apple.com/favicon.ico" height="30" alt=""> **MacOSX** | [](https://dev.azure.com/tommbrt/tommbrt/_build/latest?definitionId=5&branchName=master) |
|
||||
| <img src="https://www.android.com/favicon.ico" height="30" alt=""> **Android** | [](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) | [](https://circleci.com/gh/FluidSynth/fluidsynth) |
|
||||
|
||||
|
||||
|
||||
#### FluidSynth is a cross-platform, real-time software synthesizer based on the Soundfont 2 specification.
|
||||
|
|
|
@ -1,92 +1,56 @@
|
|||
# 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:\\\\soundfonts\\\\default.sf2" CACHE STRING
|
||||
set (DEFAULT_SOUNDFONT "C:\\\\ProgramData\\\\soundfonts\\\\default.sf2" CACHE STRING
|
||||
"Default soundfont file")
|
||||
else ( WIN32 )
|
||||
set (DEFAULT_SOUNDFONT "${CMAKE_INSTALL_PREFIX}/share/soundfonts/default.sf2" CACHE STRING
|
||||
set (DEFAULT_SOUNDFONT "${CMAKE_INSTALL_FULL_DATADIR}/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)
|
||||
|
||||
# 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)
|
||||
mark_as_advanced (FRAMEWORK_INSTALL_DIR)
|
||||
|
||||
# XDG_APPS_INSTALL_DIR - the XDG apps dir, where .desktop files are installed
|
||||
set (XDG_APPS_INSTALL_DIR "share/applications" CACHE STRING "The XDG apps dir")
|
||||
set (XDG_APPS_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/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 "share/mime/packages" CACHE STRING
|
||||
set (XDG_MIME_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/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 "share/dbus-1/interfaces" CACHE STRING
|
||||
set (DBUS_INTERFACES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/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 "share/dbus-1/services" CACHE STRING
|
||||
set (DBUS_SERVICES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/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 "share/dbus-1/system-services"
|
||||
set (DBUS_SYSTEM_SERVICES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/dbus-1/system-services"
|
||||
CACHE STRING "The dbus system services install dir")
|
||||
mark_as_advanced (DBUS_SYSTEM_SERVICES_INSTALL_DIR)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
macro ( ADD_FLUID_TEST _test )
|
||||
ADD_EXECUTABLE(${_test} ${_test}.c $<TARGET_OBJECTS:libfluidsynth-OBJ> )
|
||||
add_executable( ${_test} ${_test}.c )
|
||||
|
||||
# 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} $<TARGET_PROPERTY:libfluidsynth,INTERFACE_LINK_LIBRARIES>)
|
||||
target_link_libraries( ${_test} libfluidsynth-OBJ )
|
||||
|
||||
# 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,INCLUDE_DIRECTORIES> # include all other header search paths needed by libfluidsynth (esp. glib)
|
||||
$<TARGET_PROPERTY:libfluidsynth-OBJ,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 $<TARGET_OBJECTS:libfluidsynth-OBJ> )
|
||||
add_executable( ${_util} ${_util}.c )
|
||||
|
||||
# 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} $<TARGET_PROPERTY:libfluidsynth,INTERFACE_LINK_LIBRARIES>)
|
||||
target_link_libraries( ${_util} libfluidsynth-OBJ )
|
||||
|
||||
# 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,INCLUDE_DIRECTORIES> # include all other header search paths needed by libfluidsynth (esp. glib)
|
||||
$<TARGET_PROPERTY:libfluidsynth-OBJ,INCLUDE_DIRECTORIES> # include all other header search paths needed by libfluidsynth (esp. glib)
|
||||
)
|
||||
|
||||
# append the current unit test to check-target as dependency
|
||||
|
|
75
cmake_admin/PkgConfigHelpers.cmake
Normal file
75
cmake_admin/PkgConfigHelpers.cmake
Normal file
|
@ -0,0 +1,75 @@
|
|||
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 )
|
|
@ -22,7 +22,7 @@ if( test_not_successful )
|
|||
endif( test_not_successful )
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files ${expected_output} ${test_output}
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${expected_output} ${test_output}
|
||||
RESULT_VARIABLE compare_not_successful
|
||||
)
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
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 )
|
|
@ -61,6 +61,12 @@ 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 )
|
||||
|
@ -240,6 +246,14 @@ 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"
|
||||
|
|
1
contrib/baselibs.conf
Normal file
1
contrib/baselibs.conf
Normal file
|
@ -0,0 +1 @@
|
|||
libfluidsynth2
|
23
contrib/debian.changelog
Normal file
23
contrib/debian.changelog
Normal file
|
@ -0,0 +1,23 @@
|
|||
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
|
1
contrib/debian.compat
Normal file
1
contrib/debian.compat
Normal file
|
@ -0,0 +1 @@
|
|||
9
|
34
contrib/debian.control
Normal file
34
contrib/debian.control
Normal file
|
@ -0,0 +1,34 @@
|
|||
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.
|
30
contrib/debian.copyright
Normal file
30
contrib/debian.copyright
Normal file
|
@ -0,0 +1,30 @@
|
|||
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'.
|
||||
|
2
contrib/debian.fluidsynth.install
Normal file
2
contrib/debian.fluidsynth.install
Normal file
|
@ -0,0 +1,2 @@
|
|||
debian/tmp/usr/bin/*
|
||||
debian/tmp/usr/share/*
|
4
contrib/debian.libfluidsynth-dev.install
Normal file
4
contrib/debian.libfluidsynth-dev.install
Normal file
|
@ -0,0 +1,4 @@
|
|||
debian/tmp/usr/include/*
|
||||
debian/tmp/usr/lib/*/*.so
|
||||
debian/tmp/usr/lib/*/pkgconfig/*.pc
|
||||
debian/tmp/usr/lib/*/cmake/fluidsynth/*.cmake
|
1
contrib/debian.libfluidsynth1.install
Normal file
1
contrib/debian.libfluidsynth1.install
Normal file
|
@ -0,0 +1 @@
|
|||
debian/tmp/usr/lib/*/lib*.so.*
|
98
contrib/debian.rules
Normal file
98
contrib/debian.rules
Normal file
|
@ -0,0 +1,98 @@
|
|||
#!/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
|
0
contrib/debian.series
Normal file
0
contrib/debian.series
Normal file
8
contrib/fluidsynth.dsc
Normal file
8
contrib/fluidsynth.dsc
Normal file
|
@ -0,0 +1,8 @@
|
|||
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
|
144
contrib/fluidsynth.spec
Normal file
144
contrib/fluidsynth.spec
Normal file
|
@ -0,0 +1,144 @@
|
|||
#
|
||||
# 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
|
|
@ -45,7 +45,7 @@ endif ( DOXYGEN_FOUND )
|
|||
|
||||
if ( UNIX )
|
||||
install ( FILES fluidsynth.1
|
||||
DESTINATION ${MAN_INSTALL_DIR} )
|
||||
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 )
|
||||
endif ( UNIX )
|
||||
|
||||
add_subdirectory ( examples )
|
||||
|
|
|
@ -11,7 +11,7 @@ target_compile_options ( fluidsynth-assetloader
|
|||
PRIVATE -Wall
|
||||
PRIVATE "$<$<CONFIG:DEBUG>:-Werror>") # Only include -Werror when building debug config
|
||||
|
||||
include_directories ( ../../../include )
|
||||
target_include_directories ( fluidsynth-assetloader PRIVATE ../../../include )
|
||||
|
||||
set ( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L../../../dist/${ANDROID_ABI} -lfluidsynth" )
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ body
|
|||
}
|
||||
|
||||
|
||||
/* Reduce width of main content for more readibility */
|
||||
/* Reduce width of main content for more readability */
|
||||
div.contents,
|
||||
div.header
|
||||
{
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#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>
|
||||
|
@ -26,31 +28,47 @@
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
fluid_settings_t *settings;
|
||||
fluid_synth_t *synth;
|
||||
fluid_audio_driver_t *adriver;
|
||||
fluid_settings_t *settings = NULL;
|
||||
fluid_synth_t *synth = NULL;
|
||||
fluid_audio_driver_t *adriver = NULL;
|
||||
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);
|
||||
|
||||
/* 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)
|
||||
if(adriver == NULL)
|
||||
{
|
||||
puts("Loading the SoundFont failed!");
|
||||
puts("Failed to create the audio driver!");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -59,7 +77,6 @@ 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);
|
||||
|
||||
|
|
|
@ -71,7 +71,8 @@ schedule_timer_event(void)
|
|||
void
|
||||
schedule_pattern(void)
|
||||
{
|
||||
int i, note_time, note_duration;
|
||||
unsigned int i;
|
||||
int note_time, note_duration;
|
||||
note_time = time_marker;
|
||||
note_duration = duration / pattern_size;
|
||||
|
||||
|
@ -135,7 +136,7 @@ main(int argc, char *argv[])
|
|||
{
|
||||
n = atoi(argv[2]);
|
||||
|
||||
if((n > 1) && (n <= pattern_size))
|
||||
if((n > 1) && (n <= (int)pattern_size))
|
||||
{
|
||||
pattern_size = n;
|
||||
}
|
||||
|
|
|
@ -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 = atof(argv[2]);
|
||||
fx_data.gain = (float)atof(argv[2]);
|
||||
|
||||
/* Create the audio driver. As soon as the audio driver is
|
||||
* created, the synthesizer can be played. */
|
||||
|
|
|
@ -61,7 +61,8 @@ schedule_timer_event(void)
|
|||
void
|
||||
schedule_pattern(void)
|
||||
{
|
||||
int i, note_time;
|
||||
unsigned int i;
|
||||
int note_time;
|
||||
note_time = time_marker;
|
||||
|
||||
for(i = 0; i < pattern_size; ++i)
|
||||
|
|
|
@ -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 everytime before calling fluid_synth_process()
|
||||
// first make sure to zero out the sample buffers every time before calling fluid_synth_process()
|
||||
memset(left, 0, sizeof(left));
|
||||
memset(right, 0, sizeof(right));
|
||||
|
||||
|
|
|
@ -14,11 +14,6 @@ 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>
|
||||
|
@ -123,8 +118,7 @@ and commit the results. Refresh with the following command:
|
|||
<type>bool</type>
|
||||
<def>0 (FALSE)</def>
|
||||
<desc>
|
||||
When set to 1 (TRUE), samples are loaded to and unloaded from memory
|
||||
on demand.
|
||||
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.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
|
@ -419,7 +413,7 @@ and commit the results. Refresh with the following command:
|
|||
<min>64</min>
|
||||
<max>8192</max>
|
||||
<desc>
|
||||
The size of the audio buffers (in frames).
|
||||
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.
|
||||
</desc>
|
||||
</setting>
|
||||
<setting>
|
||||
|
@ -458,6 +452,32 @@ and commit the results. Refresh with the following command:
|
|||
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>
|
||||
|
@ -590,6 +610,15 @@ and commit the results. Refresh with the following command:
|
|||
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>
|
||||
|
@ -598,6 +627,30 @@ and commit the results. Refresh with the following command:
|
|||
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>
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
\author Josh Green
|
||||
\author David Henningsson
|
||||
\author Tom Moebert
|
||||
\author Copyright © 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
|
||||
\author Copyright © 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
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -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, 2021"
|
||||
.TH FluidSynth 1 "Jan 1, 2022"
|
||||
.\" Please update the above date whenever this man page is modified.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
|
|
|
@ -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 it's concepts will help if you want to make the
|
||||
FluidSynth, but knowing some of the LADSPA 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 it's audio output into an output buffer, but will always
|
||||
plugin can not mix its 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 it's
|
||||
Just as LADSPA plugins have input and output ports, FluidSynth provides its
|
||||
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 give the plugin name as well, as we've done when
|
||||
plugin, you would need to specify 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 effect input and
|
||||
`Main:L` and `Main:R` ports as effect outputs. (See the "Example Setups" section
|
||||
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
|
||||
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,17 +260,16 @@ 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
|
||||
(i.e. an instance of a plugin). `<effect-name>` can be chosen by the user and must be
|
||||
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 make the effect add it's output
|
||||
to the output buffers instead of replacing them. The `--mix` parameter takes an
|
||||
`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
|
||||
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 start from
|
||||
remove effects, please use `ladspa_reset` to clear everything and start from
|
||||
scratch.
|
||||
|
||||
Can only be called when the effect unit is not active.
|
||||
|
@ -281,8 +280,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 is able to be used as
|
||||
mono output or mono input to an effect. Buffers can be used to connect plugins
|
||||
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
|
||||
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,
|
||||
|
@ -296,7 +295,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 with a buffer or a host port. This
|
||||
Connects an effect input or output port to a buffer or a host port. This
|
||||
command can be called multiple times and will overwrite the previous connection
|
||||
made on that effect port.
|
||||
|
||||
|
@ -348,7 +347,7 @@ it can be started again with `ladspa_start`.
|
|||
ladspa_reset
|
||||
```
|
||||
|
||||
Deactivates the effects unit if active and clears all configuration and loaded
|
||||
Deactivates the effects unit if it is currently active and clears all configuration and loaded
|
||||
plugins.
|
||||
|
||||
|
||||
|
@ -440,7 +439,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-channel, the main audio ports will
|
||||
As soon as you configure more than one audio-group, 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:
|
||||
|
@ -462,7 +461,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 LADSPA as you normally would.
|
||||
configure and build FluidSynth 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
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
/*!
|
||||
|
||||
\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.
|
||||
|
|
|
@ -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 (Linux, Unix)
|
||||
- oss: Open Sound System (primarily needed on BSD, rarely also Linux and Unix in general)
|
||||
- pulseaudio: PulseAudio (Linux, Mac OS X, Windows)
|
||||
- coreaudio: Apple CoreAudio (Mac OS X)
|
||||
- dsound: Microsoft DirectSound (Windows)
|
||||
|
@ -31,6 +31,7 @@ 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
|
||||
|
@ -79,4 +80,10 @@ 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.
|
||||
|
||||
*/
|
||||
|
|
|
@ -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 on a logarithmic scale. Check the settings.h
|
||||
number should be interpreted on a logarithmic scale. Check the settings.h
|
||||
API documentation for a description of all functions.
|
||||
|
||||
*/
|
||||
|
|
|
@ -6,5 +6,7 @@ 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}
|
||||
|
|
|
@ -8,7 +8,7 @@ Type=notify
|
|||
NotifyAccess=main
|
||||
EnvironmentFile=@FLUID_DAEMON_ENV_FILE@
|
||||
EnvironmentFile=-%h/.config/fluidsynth
|
||||
ExecStart=@CMAKE_INSTALL_PREFIX@/@BIN_INSTALL_DIR@/fluidsynth -is $OTHER_OPTS $SOUND_FONT
|
||||
ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/fluidsynth -is $OTHER_OPTS $SOUND_FONT
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
|
||||
%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
|
|
@ -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 guarentee that @p out
|
||||
* @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarantee 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 accidentially to the same buffer multiple times.
|
||||
* applications from e.g. applying a custom effect accidentally to the same buffer multiple times.
|
||||
* @endparblock
|
||||
*
|
||||
* @parblock
|
||||
|
|
|
@ -117,6 +117,7 @@ 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);
|
||||
|
|
|
@ -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(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_type(const 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(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_key(fluid_midi_event_t *evt);
|
||||
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_set_key(fluid_midi_event_t *evt, int key);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_velocity(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_velocity(const 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(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_control(const 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(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_value(const 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(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_program(const 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(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_pitch(const 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 tranformation and filtering of MIDI events.
|
||||
* Rule based transformation and filtering of MIDI events.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
|
|
@ -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 a few ticks too late. Although this
|
||||
* the sequencer's scale and the synth's sample-rate, @p time may be 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,7 +26,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup soundfonts SountFonts
|
||||
* @defgroup soundfonts SoundFonts
|
||||
*
|
||||
* SoundFont related functions
|
||||
*
|
||||
|
|
|
@ -331,6 +331,18 @@ 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,
|
||||
|
|
1
sf2/VìntàgèDrèàmsWàvès-v2.sf2
Symbolic link
1
sf2/VìntàgèDrèàmsWàvès-v2.sf2
Symbolic link
|
@ -0,0 +1 @@
|
|||
VintageDreamsWaves-v2.sf2
|
|
@ -19,42 +19,14 @@
|
|||
|
||||
# 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 )
|
||||
|
@ -67,17 +39,19 @@ 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 )
|
||||
|
@ -98,7 +72,6 @@ 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 )
|
||||
|
@ -107,25 +80,14 @@ 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 )
|
||||
|
@ -138,15 +100,13 @@ 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 ${CMAKE_BINARY_DIR}/config.h )
|
||||
set ( config_SOURCES ${FluidSynth_BINARY_DIR}/config.h )
|
||||
|
||||
set ( libfluidsynth_SOURCES
|
||||
utils/fluid_conv.c
|
||||
|
@ -222,33 +182,41 @@ 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
|
||||
${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
|
||||
${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
|
||||
)
|
||||
|
||||
set ( public_main_HEADER
|
||||
${CMAKE_BINARY_DIR}/include/fluidsynth.h
|
||||
${FluidSynth_BINARY_DIR}/include/fluidsynth.h
|
||||
)
|
||||
|
||||
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
|
||||
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
|
||||
${public_main_HEADER} )
|
||||
|
||||
if ( WIN32 )
|
||||
|
@ -277,6 +245,7 @@ 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}
|
||||
|
@ -296,18 +265,38 @@ 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.
|
||||
add_library ( libfluidsynth $<TARGET_OBJECTS:libfluidsynth-OBJ> )
|
||||
# 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}
|
||||
)
|
||||
|
||||
if ( MACOSX_FRAMEWORK )
|
||||
set_property ( SOURCE ${public_HEADERS}
|
||||
PROPERTY MACOSX_PACKAGE_LOCATION Headers/fluidsynth
|
||||
set_source_files_properties ( ${public_HEADERS}
|
||||
PROPERTIES MACOSX_PACKAGE_LOCATION Headers/fluidsynth
|
||||
)
|
||||
set_target_properties ( libfluidsynth
|
||||
PROPERTIES
|
||||
|
@ -348,33 +337,126 @@ else ( MACOSX_FRAMEWORK )
|
|||
)
|
||||
endif ( MACOSX_FRAMEWORK )
|
||||
|
||||
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}
|
||||
# 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
|
||||
${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 )
|
||||
|
@ -383,33 +465,94 @@ 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_link_libraries ( fluidsynth
|
||||
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
|
||||
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
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${FRAMEWORK_INSTALL_DIR}
|
||||
EXPORT FluidSynthTargets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
FRAMEWORK DESTINATION "${FRAMEWORK_INSTALL_PREFIX}/${FRAMEWORK_INSTALL_DIR}"
|
||||
ARCHIVE DESTINATION "${FRAMEWORK_INSTALL_PREFIX}/${FRAMEWORK_INSTALL_DIR}"
|
||||
)
|
||||
else ( MACOSX_FRAMEWORK )
|
||||
install ( TARGETS fluidsynth libfluidsynth
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/fluidsynth
|
||||
EXPORT FluidSynthTargets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fluidsynth
|
||||
)
|
||||
install ( FILES ${public_main_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR} )
|
||||
install ( FILES ${public_main_HEADER} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
|
||||
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)
|
||||
|
@ -429,6 +572,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 "${CMAKE_BINARY_DIR}/"
|
||||
INSTALL_COMMAND ${GENTAB_BDIR}/make_tables.exe "${FluidSynth_BINARY_DIR}/"
|
||||
)
|
||||
add_dependencies(libfluidsynth-OBJ gentables)
|
||||
|
|
|
@ -441,14 +441,14 @@ fluid_command(fluid_cmd_handler_t *handler, const char *cmd, fluid_ostream_t out
|
|||
return 1;
|
||||
}
|
||||
|
||||
if(!g_shell_parse_argv(cmd, &num_tokens, &tokens, NULL))
|
||||
if(!fluid_shell_parse_argv(cmd, &num_tokens, &tokens))
|
||||
{
|
||||
fluid_ostream_printf(out, "Error parsing command\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
result = fluid_cmd_handler_handle(handler, num_tokens, &tokens[0], out);
|
||||
g_strfreev(tokens);
|
||||
fluid_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 aguments.
|
||||
The function checks that there is 1 or 2 arguments.
|
||||
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 optionnal first argument which is a fx group index */
|
||||
/* check optional first argument which is a fx group index */
|
||||
fx_group = -1;
|
||||
|
||||
if(ac > 1)
|
||||
|
|
|
@ -199,6 +199,7 @@ new_fluid_file_renderer(fluid_synth_t *synth)
|
|||
double samplerate;
|
||||
int retval;
|
||||
#endif
|
||||
int audio_channels;
|
||||
char *filename = NULL;
|
||||
fluid_file_renderer_t *dev;
|
||||
|
||||
|
@ -233,6 +234,7 @@ 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)
|
||||
{
|
||||
|
@ -310,6 +312,11 @@ 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;
|
||||
|
||||
|
|
|
@ -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 after
|
||||
* the internal reverb and chorus effects have been processed.
|
||||
* FluidSynth calls this function during main output mixing,
|
||||
* just before processing the internal reverb and chorus effects.
|
||||
*
|
||||
* It copies audio data from the supplied buffers, runs all effects and copies the
|
||||
* resulting audio back into the same buffers.
|
||||
|
@ -1325,13 +1325,16 @@ 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. */
|
||||
for(i = 0; i < effect->desc->PortCount; i++)
|
||||
if(effect->desc != NULL)
|
||||
{
|
||||
node = (fluid_ladspa_node_t *) effect->port_nodes[i];
|
||||
|
||||
if(node && node->type & FLUID_LADSPA_NODE_CONTROL)
|
||||
for(i = 0; i < effect->desc->PortCount; i++)
|
||||
{
|
||||
delete_fluid_ladspa_node(node);
|
||||
node = (fluid_ladspa_node_t *) effect->port_nodes[i];
|
||||
|
||||
if(node && node->type & FLUID_LADSPA_NODE_CONTROL)
|
||||
{
|
||||
delete_fluid_ladspa_node(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,9 @@
|
|||
/* 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@
|
||||
|
||||
|
@ -212,7 +215,9 @@
|
|||
#cmakedefine TEST_SOUNDFONT "@TEST_SOUNDFONT@"
|
||||
|
||||
/* Soundfont to load for UTF-8 unit testing */
|
||||
#cmakedefine TEST_SOUNDFONT_UTF8 "@TEST_SOUNDFONT_UTF8@"
|
||||
#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@"
|
||||
|
||||
/* SF3 Soundfont to load for unit testing */
|
||||
#cmakedefine TEST_SOUNDFONT_SF3 "@TEST_SOUNDFONT_SF3@"
|
||||
|
@ -260,4 +265,10 @@
|
|||
/* 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 */
|
||||
|
|
|
@ -70,6 +70,16 @@ 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",
|
||||
|
@ -310,8 +320,9 @@ 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 sound-setup should be completed after this point,
|
||||
* thus of all object types in use (synth, midi player, sequencer, etc.) the 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
|
||||
* 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.
|
||||
*/
|
||||
|
@ -322,7 +333,20 @@ new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
|
||||
if(def)
|
||||
{
|
||||
fluid_audio_driver_t *driver = (*def->new)(settings, synth);
|
||||
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);
|
||||
|
||||
if(driver)
|
||||
{
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
|
||||
#include "fluidsynth_priv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fluid_audio_driver_t
|
||||
*/
|
||||
|
@ -138,6 +142,14 @@ 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);
|
||||
|
@ -167,6 +179,8 @@ 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 */
|
||||
|
|
|
@ -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,6 +1347,26 @@ 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 */
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
typedef struct
|
||||
{
|
||||
fluid_audio_driver_t driver;
|
||||
fluid_audio_func_t callback;
|
||||
void *data;
|
||||
fluid_file_renderer_t *renderer;
|
||||
int period_size;
|
||||
|
@ -49,7 +48,7 @@ typedef struct
|
|||
} fluid_file_audio_driver_t;
|
||||
|
||||
|
||||
static int fluid_file_audio_run_s16(void *d, unsigned int msec);
|
||||
static int fluid_file_audio_run(void *d, unsigned int msec);
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
|
@ -78,7 +77,6 @@ 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);
|
||||
|
@ -89,7 +87,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_s16, (void *) dev, TRUE, FALSE, TRUE);
|
||||
dev->timer = new_fluid_timer(msec, fluid_file_audio_run, (void *) dev, TRUE, FALSE, TRUE);
|
||||
|
||||
if(dev->timer == NULL)
|
||||
{
|
||||
|
@ -115,7 +113,7 @@ void delete_fluid_file_audio_driver(fluid_audio_driver_t *p)
|
|||
FLUID_FREE(dev);
|
||||
}
|
||||
|
||||
static int fluid_file_audio_run_s16(void *d, unsigned int clock_time)
|
||||
static int fluid_file_audio_run(void *d, unsigned int clock_time)
|
||||
{
|
||||
fluid_file_audio_driver_t *dev = (fluid_file_audio_driver_t *) d;
|
||||
unsigned int sample_time;
|
||||
|
|
|
@ -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,7 +52,8 @@ typedef struct
|
|||
fluid_audio_func_t callback;
|
||||
void *data;
|
||||
unsigned int buffer_size;
|
||||
float *buffers[2];
|
||||
unsigned int buffer_count;
|
||||
float **buffers;
|
||||
double phase;
|
||||
} fluid_core_audio_driver_t;
|
||||
|
||||
|
@ -73,6 +74,10 @@ 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)
|
||||
{
|
||||
|
@ -81,7 +86,7 @@ get_num_outputs(AudioDeviceID deviceID)
|
|||
AudioObjectPropertyAddress pa;
|
||||
pa.mSelector = kAudioDevicePropertyStreamConfiguration;
|
||||
pa.mScope = kAudioDevicePropertyScopeOutput;
|
||||
pa.mElement = kAudioObjectPropertyElementMaster;
|
||||
pa.mElement = kAudioObjectPropertyElementMain;
|
||||
|
||||
if(OK(AudioObjectGetPropertyDataSize(deviceID, &pa, 0, 0, &size)) && size > 0)
|
||||
{
|
||||
|
@ -110,6 +115,76 @@ 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)
|
||||
{
|
||||
|
@ -118,9 +193,10 @@ fluid_core_audio_driver_settings(fluid_settings_t *settings)
|
|||
AudioObjectPropertyAddress pa;
|
||||
pa.mSelector = kAudioHardwarePropertyDevices;
|
||||
pa.mScope = kAudioObjectPropertyScopeWildcard;
|
||||
pa.mElement = kAudioObjectPropertyElementMaster;
|
||||
pa.mElement = kAudioObjectPropertyElementMain;
|
||||
|
||||
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)))
|
||||
|
@ -165,13 +241,21 @@ 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;
|
||||
char *devname = NULL, *channel_map = NULL;
|
||||
fluid_core_audio_driver_t *dev = NULL;
|
||||
int period_size, periods;
|
||||
int period_size, periods, audio_channels = 1;
|
||||
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);
|
||||
|
||||
|
@ -187,14 +271,17 @@ 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;
|
||||
|
||||
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
comp = FindNextComponent(NULL, &desc);
|
||||
#else
|
||||
comp = AudioComponentFindNext(NULL, &desc);
|
||||
#endif
|
||||
|
||||
if(comp == NULL)
|
||||
{
|
||||
|
@ -202,7 +289,11 @@ 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)
|
||||
{
|
||||
|
@ -211,7 +302,6 @@ 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,
|
||||
|
@ -227,10 +317,14 @@ 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)
|
||||
|
@ -238,7 +332,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 = kAudioObjectPropertyElementMaster;
|
||||
pa.mElement = kAudioObjectPropertyElementMain;
|
||||
|
||||
if(OK(AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &pa, 0, 0, &size)))
|
||||
{
|
||||
|
@ -285,11 +379,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;
|
||||
dev->format.mBytesPerPacket = 2 * sizeof(float);
|
||||
dev->format.mFormatFlags = kLinearPCMFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved;
|
||||
dev->format.mBytesPerPacket = sizeof(float);
|
||||
dev->format.mFramesPerPacket = 1;
|
||||
dev->format.mBytesPerFrame = 2 * sizeof(float);
|
||||
dev->format.mChannelsPerFrame = 2;
|
||||
dev->format.mBytesPerFrame = sizeof(float);
|
||||
dev->format.mChannelsPerFrame = audio_channels;
|
||||
dev->format.mBitsPerChannel = 8 * sizeof(float);
|
||||
|
||||
FLUID_LOG(FLUID_DBG, "mSampleRate %g", dev->format.mSampleRate);
|
||||
|
@ -313,6 +407,13 @@ 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,
|
||||
|
@ -328,15 +429,16 @@ 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[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)
|
||||
dev->buffers = FLUID_ARRAY(float *, audio_channels);
|
||||
|
||||
if(dev->buffers == 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);
|
||||
|
||||
|
@ -372,16 +474,15 @@ 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[0])
|
||||
if(dev->buffers != NULL)
|
||||
{
|
||||
FLUID_FREE(dev->buffers[0]);
|
||||
}
|
||||
|
||||
if(dev->buffers[1])
|
||||
{
|
||||
FLUID_FREE(dev->buffers[1]);
|
||||
FLUID_FREE(dev->buffers);
|
||||
}
|
||||
|
||||
FLUID_FREE(dev);
|
||||
|
@ -395,30 +496,18 @@ 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;
|
||||
float *buffer = ioData->mBuffers[0].mData;
|
||||
UInt32 i, nBuffers = ioData->mNumberBuffers;
|
||||
fluid_audio_func_t callback = (dev->callback != NULL) ? dev->callback : (fluid_audio_func_t) fluid_synth_process;
|
||||
|
||||
if(dev->callback)
|
||||
for(i = 0; i < ioData->mNumberBuffers && i < dev->buffer_count; i++)
|
||||
{
|
||||
float *left = dev->buffers[0];
|
||||
float *right = dev->buffers[1];
|
||||
|
||||
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];
|
||||
}
|
||||
dev->buffers[i] = ioData->mBuffers[i].mData;
|
||||
FLUID_MEMSET(dev->buffers[i], 0, len * sizeof(float));
|
||||
}
|
||||
else
|
||||
fluid_synth_write_float((fluid_synth_t *) dev->data, len, buffer, 0, 2,
|
||||
buffer, 1, 2);
|
||||
|
||||
callback(dev->data, len, nBuffers, dev->buffers, nBuffers, dev->buffers);
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
/* End work around */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <os/log.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <CoreMIDI/MIDIServices.h>
|
||||
|
||||
|
@ -62,6 +63,10 @@ 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)
|
||||
|
@ -108,6 +113,8 @@ 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)
|
||||
|
@ -124,9 +131,10 @@ new_fluid_coremidi_driver(fluid_settings_t *settings, handle_midi_event_func_t h
|
|||
return NULL;
|
||||
}
|
||||
|
||||
dev->client = 0;
|
||||
dev->endpoint = 0;
|
||||
dev->parser = 0;
|
||||
dev->client = invalid_client;
|
||||
dev->endpoint = invalid_endpoint;
|
||||
dev->input_port = invalid_port;
|
||||
dev->parser = NULL;
|
||||
dev->driver.handler = handler;
|
||||
dev->driver.data = data;
|
||||
|
||||
|
@ -173,7 +181,7 @@ new_fluid_coremidi_driver(fluid_settings_t *settings, handle_midi_event_func_t h
|
|||
FLUID_FREE(portname); /* -- free port name */
|
||||
}
|
||||
|
||||
OSStatus result = MIDIClientCreate(str_clientname, NULL, NULL, &client);
|
||||
result = MIDIClientCreate(str_clientname, NULL, NULL, &client);
|
||||
CFRelease(str_clientname);
|
||||
|
||||
if(result != noErr)
|
||||
|
@ -194,7 +202,7 @@ new_fluid_coremidi_driver(fluid_settings_t *settings, handle_midi_event_func_t h
|
|||
goto error_recovery;
|
||||
}
|
||||
|
||||
CFStringRef str_input_portname = CFSTR("input");
|
||||
str_input_portname = CFSTR("input");
|
||||
result = MIDIInputPortCreate(client, str_input_portname,
|
||||
fluid_coremidi_callback,
|
||||
(void *)dev, &dev->input_port);
|
||||
|
@ -231,17 +239,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 != NULL)
|
||||
if(dev->input_port != invalid_port)
|
||||
{
|
||||
MIDIPortDispose(dev->input_port);
|
||||
}
|
||||
|
||||
if(dev->client != NULL)
|
||||
if(dev->client != invalid_client)
|
||||
{
|
||||
MIDIClientDispose(dev->client);
|
||||
}
|
||||
|
||||
if(dev->endpoint != NULL)
|
||||
if(dev->endpoint != invalid_endpoint)
|
||||
{
|
||||
MIDIEndpointDispose(dev->endpoint);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
if(jack_ports && jack_ports[0])
|
||||
{
|
||||
int err;
|
||||
int err, o = 0;
|
||||
int connected = 0;
|
||||
|
||||
for(i = 0; jack_ports[i] && i < 2 * dev->num_output_ports; ++i)
|
||||
for(i = 0; i < 2 * dev->num_output_ports; ++i)
|
||||
{
|
||||
err = jack_connect(client, jack_port_name(dev->output_ports[i]), jack_ports[i]);
|
||||
err = jack_connect(client, jack_port_name(dev->output_ports[i]), jack_ports[o++]);
|
||||
|
||||
if(err)
|
||||
{
|
||||
|
@ -631,11 +631,17 @@ new_fluid_jack_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func
|
|||
{
|
||||
connected++;
|
||||
}
|
||||
|
||||
if(!jack_ports[o])
|
||||
{
|
||||
o = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; jack_ports[i] && i < 2 * dev->num_fx_ports; ++i)
|
||||
o = 0;
|
||||
for(i = 0; i < 2 * dev->num_fx_ports; ++i)
|
||||
{
|
||||
err = jack_connect(client, jack_port_name(dev->fx_ports[i]), jack_ports[i]);
|
||||
err = jack_connect(client, jack_port_name(dev->fx_ports[i]), jack_ports[o++]);
|
||||
|
||||
if(err)
|
||||
{
|
||||
|
@ -645,6 +651,11 @@ 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!) */
|
||||
|
|
|
@ -87,6 +87,17 @@ 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)
|
||||
{
|
||||
|
|
|
@ -25,13 +25,9 @@
|
|||
* 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>
|
||||
|
@ -43,6 +39,7 @@ using namespace oboe;
|
|||
constexpr int NUM_CHANNELS = 2;
|
||||
|
||||
class OboeAudioStreamCallback;
|
||||
class OboeAudioStreamErrorCallback;
|
||||
|
||||
/** fluid_oboe_audio_driver_t
|
||||
*
|
||||
|
@ -55,7 +52,16 @@ 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;
|
||||
|
||||
|
||||
|
@ -93,20 +99,34 @@ 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, "audio.oboe.id", 0, 0, 0x7FFFFFFF, 0);
|
||||
fluid_settings_register_int(settings, OBOE_ID, 0, 0, 0x7FFFFFFF, 0);
|
||||
|
||||
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, 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.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, 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, SRCQ_SET, "Medium", 0);
|
||||
fluid_settings_add_option(settings, SRCQ_SET, "None");
|
||||
|
@ -115,6 +135,10 @@ 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)
|
||||
|
@ -157,6 +181,28 @@ 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
|
||||
*/
|
||||
|
@ -168,44 +214,24 @@ 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", &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;
|
||||
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;
|
||||
|
||||
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);
|
||||
result = fluid_oboe_connect_or_reconnect(dev);
|
||||
|
||||
if(result != Result::OK)
|
||||
{
|
||||
|
@ -269,5 +295,38 @@ 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
|
||||
|
||||
|
|
|
@ -187,9 +187,18 @@ new_fluid_oss_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
}
|
||||
}
|
||||
|
||||
if(stat(devname, &devstat) == -1)
|
||||
dev->dspfd = open(devname, O_WRONLY, 0);
|
||||
|
||||
if(dev->dspfd == -1)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Device <%s> does not exists", devname);
|
||||
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));
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
|
@ -199,15 +208,6 @@ 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,9 +333,18 @@ new_fluid_oss_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func,
|
|||
}
|
||||
}
|
||||
|
||||
if(stat(devname, &devstat) == -1)
|
||||
dev->dspfd = open(devname, O_WRONLY, 0);
|
||||
|
||||
if(dev->dspfd == -1)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Device <%s> does not exists", devname);
|
||||
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));
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
|
@ -345,16 +354,6 @@ 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");
|
||||
|
@ -404,7 +403,7 @@ new_fluid_oss_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func,
|
|||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* allocate the buffers. FIXME!!! don't use interleaved samples */
|
||||
/* allocate the buffers. */
|
||||
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);
|
||||
|
@ -464,6 +463,8 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -666,7 +667,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",
|
||||
strerror(errno));
|
||||
g_strerror(errno));
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
|
@ -755,7 +756,7 @@ fluid_oss_midi_run(void *d)
|
|||
|
||||
if(n < 0)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Error waiting for MIDI input: %s", strerror(errno));
|
||||
FLUID_LOG(FLUID_ERR, "Error waiting for MIDI input: %s", g_strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
324
src/drivers/fluid_pipewire.c
Normal file
324
src/drivers/fluid_pipewire.c
Normal file
|
@ -0,0 +1,324 @@
|
|||
/* 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
|
|
@ -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;
|
||||
int period_size, period_bytes, adjust_latency, periods;
|
||||
char *server = NULL;
|
||||
char *device = NULL;
|
||||
char *media_role = NULL;
|
||||
int realtime_prio = 0;
|
||||
int err;
|
||||
int err = 0;
|
||||
float *left = NULL,
|
||||
*right = NULL,
|
||||
*buf = NULL;
|
||||
|
@ -103,6 +103,7 @@ 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 */
|
||||
|
@ -143,7 +144,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;
|
||||
bufattr.maxlength = adjust_latency ? -1 : period_bytes * periods;
|
||||
bufattr.tlength = period_bytes;
|
||||
bufattr.minreq = -1;
|
||||
bufattr.prebuf = -1; /* Just initialize to same value as tlength */
|
||||
|
@ -155,9 +156,9 @@ new_fluid_pulse_audio_driver2(fluid_settings_t *settings,
|
|||
&bufattr,
|
||||
&err);
|
||||
|
||||
if(!dev->pa_handle)
|
||||
if(!dev->pa_handle || err != PA_OK)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to create PulseAudio connection");
|
||||
FLUID_LOG(FLUID_ERR, "Failed to create PulseAudio connection, because pa_simple_new() failed with error: %s", pa_strerror(err));
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
|
@ -176,6 +177,7 @@ 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.");
|
||||
|
@ -242,10 +244,8 @@ 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;
|
||||
int err;
|
||||
|
||||
buffer_size = dev->buffer_size;
|
||||
int buffer_size = dev->buffer_size;
|
||||
int err = 0;
|
||||
|
||||
while(dev->cont)
|
||||
{
|
||||
|
@ -254,9 +254,20 @@ 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.");
|
||||
FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection: %s", pa_strerror(err));
|
||||
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;
|
||||
|
@ -271,12 +282,10 @@ fluid_pulse_audio_run2(void *d)
|
|||
*right = dev->right,
|
||||
*buf = dev->buf;
|
||||
float *handle[2];
|
||||
int buffer_size;
|
||||
int err;
|
||||
int buffer_size = dev->buffer_size;
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
buffer_size = dev->buffer_size;
|
||||
|
||||
handle[0] = left;
|
||||
handle[1] = right;
|
||||
|
||||
|
@ -297,9 +306,20 @@ 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.");
|
||||
FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection: %s", pa_strerror(err));
|
||||
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;
|
||||
|
|
|
@ -73,7 +73,7 @@ static const IID _IID_IAudioRenderClient =
|
|||
*
|
||||
* Current limitations:
|
||||
* - Only one stereo audio output.
|
||||
* - If audio.sample-format is "16bits", a convertion from float
|
||||
* - If audio.sample-format is "16bits", a conversion 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, 1000);
|
||||
ret = WaitForMultipleObjects(FLUID_N_ELEMENTS(wait_handles), wait_handles, FALSE, 2000);
|
||||
|
||||
switch(ret)
|
||||
{
|
||||
|
@ -788,9 +788,9 @@ static void fluid_wasapi_register_callback(IMMDevice *dev, void *data)
|
|||
int nsz;
|
||||
char *name;
|
||||
|
||||
nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0);
|
||||
nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0);
|
||||
name = FLUID_ARRAY(char, nsz + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0);
|
||||
WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0);
|
||||
fluid_settings_add_option(settings, "audio.wasapi.device", name);
|
||||
FLUID_FREE(name);
|
||||
}
|
||||
|
@ -803,6 +803,7 @@ 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;
|
||||
|
@ -827,9 +828,9 @@ static void fluid_wasapi_finddev_callback(IMMDevice *dev, void *data)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0);
|
||||
nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0);
|
||||
name = FLUID_ARRAY(char, nsz + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0);
|
||||
WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0);
|
||||
|
||||
if(!FLUID_STRCASECMP(name, d->name))
|
||||
{
|
||||
|
@ -841,9 +842,15 @@ static void fluid_wasapi_finddev_callback(IMMDevice *dev, void *data)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
nsz = wcslen(id);
|
||||
d->id = FLUID_ARRAY(wchar_t, nsz + 1);
|
||||
FLUID_MEMCPY(d->id, id, sizeof(wchar_t) * (nsz + 1));
|
||||
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);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
|
|
@ -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 dependant of period_size.
|
||||
The length of a single buffer in bytes is dependent 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 dependant of period_size */
|
||||
/* The length of a single buffer drybuf[i] is dependent of period_size */
|
||||
dev->drybuf[i] = FLUID_ARRAY(float, period_size);
|
||||
if(dev->drybuf[i] == NULL)
|
||||
{
|
||||
|
|
|
@ -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 trough
|
||||
* This driver is able to handle multiple devices chosen by the user through
|
||||
* 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 comming from distinct devices
|
||||
* Then the driver is able receive MIDI messages coming 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 informations table */
|
||||
int dev_count; /* device informations count in dev_infos[] table */
|
||||
/* devices information table */
|
||||
int dev_count; /* device information count in dev_infos[] table */
|
||||
device_infos_t dev_infos[1];
|
||||
};
|
||||
|
||||
|
@ -145,21 +145,28 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
|
|||
break;
|
||||
|
||||
case MIM_DATA:
|
||||
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)
|
||||
if(msg_param < 0xF0) /* Voice category message */
|
||||
{
|
||||
event.param1 = msg_p1(msg_param);
|
||||
event.param2 = msg_p2(msg_param);
|
||||
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;
|
||||
}
|
||||
}
|
||||
else /* Pitch bend is a 14 bit value */
|
||||
else /* System message */
|
||||
{
|
||||
event.param1 = (msg_p2(msg_param) << 7) | msg_p1(msg_param);
|
||||
event.param2 = 0;
|
||||
event.type = msg_param;
|
||||
}
|
||||
|
||||
(*dev->driver.handler)(dev->driver.data, &event);
|
||||
|
@ -205,7 +212,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 vise
|
||||
* It allows the user to identify a device index through its name or vice
|
||||
* versa. This allows the user to specify a multi device name using a list of
|
||||
* devices index (see fluid_winmidi_midi_driver_settings()).
|
||||
*
|
||||
|
@ -350,7 +357,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 caracter.
|
||||
Each ascii index are separated by a semicolon character.
|
||||
*/
|
||||
FLUID_STRCPY(cpy_dev_name, dev_name); /* fluid_strtok() will overwrite */
|
||||
next_idx = cpy_dev_name;
|
||||
|
@ -496,7 +503,7 @@ new_fluid_winmidi_driver(fluid_settings_t *settings,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* allocation of driver structure size dependant of max_devices */
|
||||
/* allocation of driver structure size dependent of max_devices */
|
||||
i = sizeof(fluid_winmidi_driver_t) + (max_devices - 1) * sizeof(device_infos_t);
|
||||
dev = FLUID_MALLOC(i);
|
||||
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
#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);
|
||||
|
@ -156,6 +160,45 @@ 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 */
|
||||
|
@ -351,7 +394,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:qR:r:sT:Vvz:";
|
||||
static const char optchars[] = "a:C:c:dE:f:F:G:g:hijK:L:lm:nO:o:p:QqR:r:sT:Vvz:";
|
||||
#ifdef HAVE_LASH
|
||||
int connect_lash = 1;
|
||||
int enabled_lash = 0; /* set to TRUE if lash gets enabled */
|
||||
|
@ -361,7 +404,8 @@ 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());
|
||||
|
@ -370,7 +414,11 @@ int main(int argc, char **argv)
|
|||
{
|
||||
atexit(SDL_Quit);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PIPEWIRE_SUPPORT
|
||||
pw_init(&argc, &argv);
|
||||
atexit(pw_deinit);
|
||||
#endif
|
||||
|
||||
/* create the settings */
|
||||
|
@ -851,13 +899,13 @@ int main(int argc, char **argv)
|
|||
if(config_file == NULL)
|
||||
{
|
||||
config_file = fluid_get_userconf(buf, sizeof(buf));
|
||||
if(config_file == NULL)
|
||||
if(config_file == NULL || !g_file_test(config_file, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
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(!g_file_test(config_file, G_FILE_TEST_EXISTS))
|
||||
if(config_file != NULL && !fluid_file_test(config_file, FLUID_FILE_TEST_EXISTS))
|
||||
{
|
||||
config_file = NULL;
|
||||
}
|
||||
|
@ -896,14 +944,25 @@ 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++)
|
||||
{
|
||||
if(fluid_is_midifile(argv[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))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(fluid_is_soundfont(argv[i]))
|
||||
if(fluid_is_soundfont(u8_path))
|
||||
{
|
||||
if(fluid_synth_sfload(synth, argv[i], 1) == -1)
|
||||
if(fluid_synth_sfload(synth, u8_path, 1) == -1)
|
||||
{
|
||||
fprintf(stderr, "Failed to load the SoundFont %s\n", argv[i]);
|
||||
}
|
||||
|
@ -912,6 +971,9 @@ 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 */
|
||||
|
@ -1160,7 +1222,7 @@ void
|
|||
print_welcome()
|
||||
{
|
||||
printf("FluidSynth runtime version %s\n"
|
||||
"Copyright (C) 2000-2021 Peter Hanappe and others.\n"
|
||||
"Copyright (C) 2000-2022 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());
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -126,8 +126,13 @@ new_fluid_midi_file(const char *buffer, size_t length)
|
|||
{
|
||||
fluid_midi_file *mf;
|
||||
|
||||
mf = FLUID_NEW(fluid_midi_file);
|
||||
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");
|
||||
|
@ -140,7 +145,7 @@ new_fluid_midi_file(const char *buffer, size_t length)
|
|||
mf->running_status = -1;
|
||||
|
||||
mf->buffer = buffer;
|
||||
mf->buf_len = length;
|
||||
mf->buf_len = (int)length;
|
||||
mf->buf_pos = 0;
|
||||
mf->eof = FALSE;
|
||||
|
||||
|
@ -488,7 +493,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,
|
||||
"An non-ascii track header found, corrupt file");
|
||||
"A non-ascii track header found, corrupt file");
|
||||
return FLUID_FAILED;
|
||||
|
||||
}
|
||||
|
@ -1106,7 +1111,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(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_type(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->type;
|
||||
}
|
||||
|
@ -1130,7 +1135,7 @@ fluid_midi_event_set_type(fluid_midi_event_t *evt, int type)
|
|||
* @return Channel field
|
||||
*/
|
||||
int
|
||||
fluid_midi_event_get_channel(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_channel(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->channel;
|
||||
}
|
||||
|
@ -1154,7 +1159,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(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_key(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->param1;
|
||||
}
|
||||
|
@ -1178,7 +1183,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(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_velocity(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->param2;
|
||||
}
|
||||
|
@ -1202,7 +1207,7 @@ fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int v)
|
|||
* @return MIDI control number
|
||||
*/
|
||||
int
|
||||
fluid_midi_event_get_control(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_control(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->param1;
|
||||
}
|
||||
|
@ -1226,7 +1231,7 @@ fluid_midi_event_set_control(fluid_midi_event_t *evt, int v)
|
|||
* @return Value field
|
||||
*/
|
||||
int
|
||||
fluid_midi_event_get_value(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_value(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->param2;
|
||||
}
|
||||
|
@ -1250,7 +1255,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(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_program(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->param1;
|
||||
}
|
||||
|
@ -1274,7 +1279,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(fluid_midi_event_t *evt)
|
||||
fluid_midi_event_get_pitch(const fluid_midi_event_t *evt)
|
||||
{
|
||||
return evt->param1;
|
||||
}
|
||||
|
@ -1577,12 +1582,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)
|
||||
{
|
||||
|
@ -1604,6 +1609,10 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1651,6 +1660,7 @@ 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;
|
||||
|
||||
|
@ -1786,9 +1796,14 @@ fluid_player_reset(fluid_player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
/* player->current_file = NULL; */
|
||||
/* player->status = FLUID_PLAYER_READY; */
|
||||
/* player->loop = 1; */
|
||||
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->ntracks = 0;
|
||||
player->division = 0;
|
||||
player->miditempo = 500000;
|
||||
|
@ -2079,16 +2094,32 @@ 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)
|
||||
{
|
||||
fluid_synth_all_notes_off(synth, -1);
|
||||
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);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
do
|
||||
|
@ -2116,7 +2147,14 @@ fluid_player_callback(void *data, unsigned int msec)
|
|||
seek_ticks = fluid_atomic_int_get(&player->seek_ticks);
|
||||
if(seek_ticks >= 0)
|
||||
{
|
||||
fluid_synth_all_sounds_off(synth, -1); /* avoid hanging notes */
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < player->ntracks; i++)
|
||||
|
@ -2167,6 +2205,9 @@ 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)
|
||||
|
@ -2182,10 +2223,17 @@ 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.
|
||||
*
|
||||
|
@ -2198,6 +2246,7 @@ 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;
|
||||
}
|
||||
|
@ -2279,7 +2328,7 @@ int fluid_player_set_loop(fluid_player_t *player, int loop)
|
|||
}
|
||||
|
||||
/**
|
||||
* update the MIDI player internal deltatime dependant of actual tempo.
|
||||
* update the MIDI player internal deltatime dependent of actual tempo.
|
||||
* @param player MIDI player instance
|
||||
*/
|
||||
static void fluid_player_update_tempo(fluid_player_t *player)
|
||||
|
@ -2287,6 +2336,12 @@ 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 */
|
||||
|
@ -2351,6 +2406,10 @@ 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
|
||||
*/
|
||||
|
@ -2593,14 +2652,9 @@ fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigned char c)
|
|||
* of another message. */
|
||||
if(c >= 0xF8)
|
||||
{
|
||||
if(c == MIDI_SYSTEM_RESET)
|
||||
{
|
||||
parser->event.type = c;
|
||||
parser->status = 0; /* clear the status */
|
||||
return &parser->event;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
parser->event.type = c;
|
||||
parser->status = 0; /* clear the status */
|
||||
return &parser->event;
|
||||
}
|
||||
|
||||
/* Status byte? - If previous message not yet complete, it is discarded (re-sync). */
|
||||
|
|
|
@ -39,6 +39,7 @@ 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
|
||||
{
|
||||
|
@ -200,7 +201,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 resonse (with bank, non-realtime) */
|
||||
MIDI_SYSEX_TUNING_BULK_DUMP_BANK = 0x04, /**< Bulk tuning dump response (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) */
|
||||
|
@ -285,6 +286,7 @@ 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;
|
||||
|
@ -309,7 +311,7 @@ struct _fluid_player_t
|
|||
0, the player is driven by external tempo (exttempo)
|
||||
*/
|
||||
int sync_mode;
|
||||
/* miditempo: internal tempo comming from MIDI file tempo change events
|
||||
/* miditempo: internal tempo coming 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! */
|
||||
|
@ -324,6 +326,8 @@ 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);
|
||||
|
|
|
@ -536,7 +536,10 @@ 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 on success, #FLUID_FAILED otherwise
|
||||
* @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.
|
||||
*
|
||||
* Purpose: The midi router is called for each event, that is received
|
||||
* via the 'physical' midi input. Each event can trigger an arbitrary number
|
||||
|
@ -554,6 +557,17 @@ 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)
|
||||
|
@ -561,6 +575,9 @@ 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;
|
||||
|
@ -585,34 +602,50 @@ 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;
|
||||
|
@ -700,44 +733,46 @@ 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);
|
||||
|
||||
/* Par 1 scaling / offset */
|
||||
/* 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 */
|
||||
par1 = rule->par1_add + (int)((fluid_real_t)event_par1 * rule->par1_mul
|
||||
+ (fluid_real_t)0.5);
|
||||
|
||||
/* Par 2 scaling / offset, if applicable */
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* par2 range clamping */
|
||||
if(par2 < 0)
|
||||
{
|
||||
par2 = 0;
|
||||
|
@ -747,6 +782,10 @@ 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
|
||||
|
|
|
@ -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 contol over which events are
|
||||
* Otherwise it will mess up your event timing, because you have zero control 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 aquire is not needed.
|
||||
* only used privately by fluid_seqbind and only from sequencer callback, thus lock acquire is not needed.
|
||||
*/
|
||||
void fluid_sequencer_invalidate_note(fluid_sequencer_t *seq, fluid_seq_id_t dest, fluid_note_id_t id)
|
||||
{
|
||||
|
|
|
@ -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. comparision with itself) must be true to make them become false after leaving this
|
||||
// The values in the diagonal (i.e. comparison 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 =
|
||||
|
|
|
@ -367,64 +367,20 @@ 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;
|
||||
chan = fluid_midi_event_get_channel(event);
|
||||
seq = (fluid_sequencer_t *)data;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ struct _fluid_env_data_t
|
|||
};
|
||||
|
||||
/* Indices for envelope tables */
|
||||
enum fluid_voice_envelope_index_t
|
||||
enum fluid_voice_envelope_index
|
||||
{
|
||||
FLUID_VOICE_ENVDELAY,
|
||||
FLUID_VOICE_ENVATTACK,
|
||||
|
@ -49,7 +49,7 @@ enum fluid_voice_envelope_index_t
|
|||
FLUID_VOICE_ENVLAST
|
||||
};
|
||||
|
||||
typedef enum fluid_voice_envelope_index_t fluid_adsr_env_section_t;
|
||||
typedef enum fluid_voice_envelope_index 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, int is_volenv)
|
||||
fluid_adsr_env_calc(fluid_adsr_env_t *env)
|
||||
{
|
||||
fluid_env_data_t *env_data;
|
||||
fluid_real_t x;
|
||||
|
@ -76,7 +76,8 @@ fluid_adsr_env_calc(fluid_adsr_env_t *env, int is_volenv)
|
|||
{
|
||||
// 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]
|
||||
if(env->section == FLUID_VOICE_ENVDECAY && is_volenv)
|
||||
// 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)
|
||||
{
|
||||
env->val = env_data->min * env_data->coeff;
|
||||
}
|
||||
|
@ -106,8 +107,6 @@ fluid_adsr_env_calc(fluid_adsr_env_t *env, int is_volenv)
|
|||
}
|
||||
|
||||
env->val = x;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* This one cannot be inlined since it is referenced in
|
||||
|
@ -118,7 +117,7 @@ static FLUID_INLINE void
|
|||
fluid_adsr_env_reset(fluid_adsr_env_t *env)
|
||||
{
|
||||
env->count = 0;
|
||||
env->section = 0;
|
||||
env->section = FLUID_VOICE_ENVDELAY;
|
||||
env->val = 0.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 dependant on the width setting.
|
||||
>0: the output amplitude is less dependant on 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.
|
||||
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 dependant of modulation rate: mod_rate
|
||||
/* some chorus cpu_load measurement dependent 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 accordling to the length delay_length.
|
||||
Remark: the function sets the internal size according 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 dependant of sample rate */
|
||||
/* update parameters dependent 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 dependant of sample rate */
|
||||
/* update parameters dependent of sample rate */
|
||||
update_parameters_from_sample_rate(chorus);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 dependant on the width setting.
|
||||
>0: the output amplitude is less dependant on 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.
|
||||
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 dependant reverb time.
|
||||
to get frequency dependent 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 dependant of sample rate */
|
||||
/* update delay line parameter dependent of sample rate */
|
||||
late->samplerate = sample_rate;
|
||||
|
||||
/* compute mod_depth, length factor */
|
||||
|
|
|
@ -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, 1);
|
||||
fluid_adsr_env_calc(&voice->envlfo.volenv);
|
||||
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, 0);
|
||||
fluid_adsr_env_calc(&voice->envlfo.modenv);
|
||||
fluid_check_fpe("voice_write mod env");
|
||||
|
||||
/******************* lfo **********************/
|
||||
|
|
|
@ -150,6 +150,17 @@ 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)
|
||||
{
|
||||
|
@ -238,17 +249,6 @@ 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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#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
|
||||
|
@ -375,6 +376,7 @@ 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)
|
||||
|
@ -403,7 +405,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) default(none)
|
||||
#pragma omp task firstprivate(sample,sfdata,defsfont) shared(sample_parsing_result, invalid_loops_were_sanitized) default(none)
|
||||
{
|
||||
if(fluid_defsfont_load_sampledata(defsfont, sfdata, sample) == FLUID_FAILED)
|
||||
{
|
||||
|
@ -415,24 +417,46 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
|
|||
}
|
||||
else
|
||||
{
|
||||
fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
|
||||
int modified = fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
|
||||
if(modified)
|
||||
{
|
||||
#pragma omp critical
|
||||
{
|
||||
invalid_loops_were_sanitized = TRUE;
|
||||
}
|
||||
}
|
||||
fluid_voice_optimize_sample(sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#pragma omp task firstprivate(sample, defsfont) default(none)
|
||||
#pragma omp task firstprivate(sample, defsfont) shared(invalid_loops_were_sanitized) 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;
|
||||
fluid_sample_sanitize_loop(sample, defsfont->samplesize);
|
||||
modified = fluid_sample_sanitize_loop(sample, defsfont->samplesize);
|
||||
if(modified)
|
||||
{
|
||||
#pragma omp critical
|
||||
{
|
||||
invalid_loops_were_sanitized = TRUE;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -867,8 +891,26 @@ 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 */
|
||||
|
@ -879,7 +921,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, key, vel))
|
||||
if(fluid_zone_inside_range(&preset_zone->range, tuned_key, vel))
|
||||
{
|
||||
|
||||
inst = fluid_preset_zone_get_inst(preset_zone);
|
||||
|
@ -894,7 +936,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, key, vel))
|
||||
if(fluid_zone_inside_range(&voice_zone->range, tuned_key, vel))
|
||||
{
|
||||
|
||||
inst_zone = voice_zone->inst_zone;
|
||||
|
|
|
@ -789,12 +789,19 @@ 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. 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;
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
else if(sample->loopstart > sample->loopend)
|
||||
{
|
||||
|
|
|
@ -162,9 +162,10 @@ 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++)
|
||||
|
@ -374,6 +375,27 @@ 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:
|
||||
|
|
|
@ -142,6 +142,7 @@ 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) \
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "fluid_event.h"
|
||||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_midi.h"
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
@ -142,10 +143,18 @@ 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;
|
||||
|
@ -176,10 +185,11 @@ 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 (0-127)
|
||||
* @param duration Duration of note in the time scale used by the sequencer (by default milliseconds)
|
||||
* @param vel MIDI velocity value (1-127)
|
||||
* @param duration Duration of note in the time scale used by the sequencer
|
||||
*
|
||||
* @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)
|
||||
|
@ -568,7 +578,88 @@ 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
|
||||
|
|
|
@ -184,6 +184,8 @@ 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
|
||||
|
@ -197,16 +199,20 @@ fluid_mod_get_source_value(const unsigned char mod_src,
|
|||
if(mod_src == PAN_MSB || mod_src == BALANCE_MSB)
|
||||
{
|
||||
*range = 126;
|
||||
val = fluid_channel_get_cc(chan, mod_src) - 1;
|
||||
val -= 1;
|
||||
|
||||
if(val < 0)
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(mod_src == PORTAMENTO_CTRL)
|
||||
{
|
||||
val = fluid_channel_get_cc(chan, mod_src);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1557,6 +1557,10 @@ 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)
|
||||
|
@ -1571,6 +1575,8 @@ 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)
|
||||
|
@ -1794,6 +1800,9 @@ 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;
|
||||
|
||||
|
@ -2371,6 +2380,7 @@ 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;
|
||||
|
@ -2380,8 +2390,10 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
|
|||
{
|
||||
checksum += data[i];
|
||||
}
|
||||
if (0x80 - (checksum & 0x7F) != data[len - 1])
|
||||
checksum = 0x80 - (checksum & 0x7F);
|
||||
if (checksum != 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;
|
||||
}
|
||||
|
||||
|
@ -2389,6 +2401,7 @@ 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)
|
||||
|
@ -2419,6 +2432,7 @@ 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)
|
||||
|
@ -2433,6 +2447,7 @@ 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);
|
||||
|
@ -3702,7 +3717,8 @@ fluid_synth_get_active_voice_count(fluid_synth_t *synth)
|
|||
* @param synth FluidSynth instance
|
||||
* @return Internal buffer size in audio frames.
|
||||
*
|
||||
* Audio is synthesized this number of frames at a time. Defaults to 64 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.
|
||||
*/
|
||||
int
|
||||
fluid_synth_get_internal_bufsize(fluid_synth_t *synth)
|
||||
|
@ -6819,8 +6835,9 @@ 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 (pedaling is ignored) */
|
||||
fluid_voice_release(voice);
|
||||
/* Force the voice into release stage except if pedaling
|
||||
(sostenuto or sustain) is active */
|
||||
fluid_voice_noteoff(voice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue