Merge branch 'master' into linked-modulators

This commit is contained in:
Tom M 2019-03-27 18:12:01 +01:00 committed by GitHub
commit 34cf685167
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
71 changed files with 1613 additions and 417 deletions

63
.appveyor-mingw.yml Normal file
View file

@ -0,0 +1,63 @@
image:
- Visual Studio 2013
build:
parallel: true
verbosity: detailed
environment:
matrix:
- platform: x86
glib-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib_2.28.8-1_win32.zip
glib-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib-dev_2.28.8-1_win32.zip
pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/pkg-config_0.26-1_win32.zip
gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime_0.18.1.1-2_win32.zip
proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/proxy-libintl-dev_20100902_win32.zip
- platform: x64
glib-url: http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib_2.26.1-1_win64.zip
glib-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib-dev_2.26.1-1_win64.zip
pkg-config-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/pkg-config_0.23-2_win64.zip
gettext-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip
proxy-libintl-dev-url: http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/proxy-libintl-dev_20100902_win64.zip
init:
- echo %APPVEYOR_BUILD_WORKER_IMAGE%
install:
# make sure the latest version of git is installed
- choco upgrade git -y
- mkdir c:\deps
- cd c:\deps
- curl -fsS -o glib.zip %glib-url%
- curl -fsS -o glib-dev.zip %glib-dev-url%
- curl -fsS -o pkg-config.zip %pkg-config-url%
- curl -fsS -o gettext.zip %gettext-url%
- curl -fsS -o libintl-dev.zip %proxy-libintl-dev-url%
- 7z x glib.zip > NUL
- 7z x glib-dev.zip > NUL
- 7z x pkg-config.zip > NUL
- 7z x gettext.zip > NUL
- 7z x libintl-dev.zip > NUL
- SET PATH=C:\deps\bin;%PATH%
- if "%platform%"=="x64" ( SET "PATH=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%" ) else ( SET "PATH=C:\MinGW\bin;%PATH%" )
build_script:
# - call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64
# - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
- cd C:\projects\fluidsynth-rjimi
- mkdir build
- cd build
# remove that path from PATH to make sure sh.exe is not found (cmake will complain otherwise)
- set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
- echo %PATH%
- echo %CFLAGS%
- cmake -G "MinGW Makefiles" -DCMAKE_VERBOSE_MAKEFILE=1 ..
- mingw32-make.exe check
after_build:
- 7z a fluidsynth-%platform%.zip %APPVEYOR_BUILD_FOLDER%\build\src\* c:\deps\bin\libglib*.dll c:\deps\bin\libgthread*.dll c:\deps\bin\*intl*.dll
artifacts:
- path: build/fluidsynth-%platform%.zip
name: FluidSynth

View file

@ -63,7 +63,7 @@ install:
- 7z x pkg-config.zip > NUL
- 7z x gettext.zip > NUL
- 7z x libintl-dev.zip > NUL
- SET PATH=C:\deps\bin;%PATH%
- SET "PATH=C:\deps\bin;%PATH%"
build_script:
# - call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64

10
.cirrus.yml Normal file
View file

@ -0,0 +1,10 @@
freebsd_instance:
image: freebsd-12-0-release-amd64
task:
install_script: pwd && ls -la && pkg install -y cmake glib alsa-lib ladspa portaudio pulseaudio pkgconf sdl2
compile_script: pwd && ls -la && mkdir $HOME/fluidsynth_install/ && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=$HOME/fluidsynth_install -Denable-portaudio=1 -Denable-ladspa=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=0 .. && make -j4 && make check && make install

View file

@ -16,7 +16,7 @@ We strongly recommend to use it! Feel free to edit or remove inapplicable/unneed
-->
### FluidSynth version <!-- enter FluidSynths version you're using -->
1.1.x
2.0.x
### Current behavior
<!-- Describe the current situation, e.g. how the bug manifests. -->

View file

@ -19,6 +19,7 @@ addons:
- libpulse-dev
- libdbus-glib-1-dev
- ladspa-sdk
- libsdl2-dev
env:
- CMAKE_FLAGS="-Denable-profiling=1"
- CMAKE_FLAGS="-Denable-floats=1 -Denable-profiling=1"
@ -58,7 +59,7 @@ matrix:
before_install:
- if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get update; else brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install glib gettext libsndfile jack dbus-glib pulseaudio portaudio; fi # && brew link gettext
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install glib gettext libsndfile jack dbus-glib pulseaudio portaudio sdl2; fi # && brew link gettext
- eval "${MATRIX_EVAL}"
before_script:

View file

@ -29,7 +29,7 @@ set ( PACKAGE "fluidsynth" )
# FluidSynth package version
set ( FLUIDSYNTH_VERSION_MAJOR 2 )
set ( FLUIDSYNTH_VERSION_MINOR 0 )
set ( FLUIDSYNTH_VERSION_MICRO 3 )
set ( FLUIDSYNTH_VERSION_MICRO 4 )
set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" )
set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
@ -44,7 +44,7 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
# This is not exactly the same algorithm as the libtool one, but the results are the same.
set ( LIB_VERSION_CURRENT 2 )
set ( LIB_VERSION_AGE 1 )
set ( LIB_VERSION_REVISION 0 )
set ( LIB_VERSION_REVISION 1 )
set ( LIB_VERSION_INFO
"${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
@ -55,6 +55,7 @@ option ( enable-fpe-check "enable Floating Point Exception checks and debug mess
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 )
# Options enabled by default
option ( enable-aufile "compile support for sound file output" on )
@ -65,6 +66,8 @@ option ( enable-jack "compile JACK support (if it is available)" on )
option ( enable-ladspa "enable LADSPA effect units" on )
option ( enable-libsndfile "compile libsndfile support (if it is available)" on )
option ( enable-midishare "compile MidiShare support (if it is available)" on )
option ( enable-opensles "compile OpenSLES support (if it is available)" off )
option ( enable-oboe "compile Oboe support (requires OpenSLES and/or AAudio)" off )
option ( enable-network "enable network support (requires BSD sockets)" on )
option ( enable-oss "compile OSS support (if it is available)" on )
option ( enable-dsound "compile DirectSound support (if it is available)" on )
@ -77,16 +80,19 @@ option ( enable-readline "compile readline lib line editing (if it is available)
option ( enable-threads "enable multi-threading support (such as parallel voice synthesis)" on )
# Platform specific options
if ( CMAKE_SYSTEM MATCHES "Linux" )
if ( CMAKE_SYSTEM MATCHES "Linux|FreeBSD|DragonFly" )
option ( enable-lash "compile LASH support (if it is available)" on )
option ( enable-alsa "compile ALSA support (if it is available)" on )
endif ( CMAKE_SYSTEM MATCHES "Linux|FreeBSD|DragonFly" )
if ( CMAKE_SYSTEM MATCHES "Linux" )
option ( enable-systemd "compile systemd support (if it is available)" on )
endif ( CMAKE_SYSTEM MATCHES "Linux" )
if ( CMAKE_SYSTEM MATCHES "Darwin" )
option ( enable-coreaudio "compile CoreAudio support (if it is available)" on )
option ( enable-coremidi "compile CoreMIDI support (if it is available)" on )
option ( enable-framework "create a Mac OSX style FluidSynth.framework" on )
set ( enable-network off )
endif ( CMAKE_SYSTEM MATCHES "Darwin" )
if ( CMAKE_SYSTEM MATCHES "OS2" )
@ -95,7 +101,7 @@ if ( CMAKE_SYSTEM MATCHES "OS2" )
endif ( CMAKE_SYSTEM MATCHES "OS2" )
# Initialize the library directory name suffix.
if (NOT MINGW AND NOT MSVC)
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 )
@ -166,6 +172,7 @@ unset ( LIBFLUID_CPPFLAGS CACHE )
unset ( LIBFLUID_LIBS CACHE )
unset ( FLUID_CPPFLAGS CACHE )
unset ( FLUID_LIBS CACHE )
unset ( ENABLE_UBSAN CACHE )
# Options for the GNU C compiler only
if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "Intel" )
@ -179,17 +186,23 @@ if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_
# 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" )
# prepend to build type specific flags, to allow users to override
set ( CMAKE_C_FLAGS_DEBUG "-g -DDEBUG ${CMAKE_C_FLAGS_DEBUG}" )
if ( CMAKE_C_COMPILER_ID STREQUAL "Intel" )
# icc needs the restrict flag to recognize C99 restrict pointers
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -restrict" )
else () # not intel
# gcc and clang support bad function cast and alignment warnings; add them as well.
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wbad-function-cast -Wcast-align" )
if ( enable-ubsan )
set ( CMAKE_C_FLAGS "-fsanitize=undefined ${CMAKE_C_FLAGS}" )
set ( CMAKE_EXE_LINKER_FLAGS "-fsanitize=undefined ${CMAKE_EXE_LINKER_FLAGS}" )
set ( CMAKE_SHARED_LINKER_FLAGS "-fsanitize=undefined ${CMAKE_SHARED_LINKER_FLAGS}" )
set ( ENABLE_UBSAN 1 )
endif ( enable-ubsan )
endif (CMAKE_C_COMPILER_ID STREQUAL "Intel" )
# prepend to build type specific flags, to allow users to override
set ( CMAKE_C_FLAGS_DEBUG "-g -DDEBUG -fsanitize=undefined ${CMAKE_C_FLAGS_DEBUG}" )
endif ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "Intel" )
# Windows
@ -465,6 +478,10 @@ else(NOT enable-pkgconfig)
# Mandatory libraries: glib and gthread
pkg_check_modules ( GLIB REQUIRED glib-2.0>=2.6.5 gthread-2.0>=2.6.5 )
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
@ -526,6 +543,14 @@ else(NOT enable-pkgconfig)
remove_definitions( -DHAVE_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 ( DBUS_SUPPORT CACHE )
if ( enable-dbus )
pkg_check_modules ( DBUS dbus-1>=1.0.0 )
@ -583,7 +608,32 @@ else ( enable-midishare )
unset ( MidiShare_LIBS CACHE )
endif ( enable-midishare )
unset ( OPENSLES_SUPPORT CACHE )
unset ( OpenSLES_LIBS CACHE )
if ( enable-opensles )
check_include_file ( SLES/OpenSLES.h OPENSLES_SUPPORT )
if ( OPENSLES_SUPPORT )
find_library ( OpenSLES_LIBS OpenSLES )
if ( NOT OpenSLES_LIBS )
unset ( OPENSLES_SUPPORT )
endif ( NOT OpenSLES_LIBS )
endif ( OPENSLES_SUPPORT )
endif ( enable-opensles )
unset ( OBOE_SUPPORT CACHE )
unset ( OBOE_LIBS CACHE )
if ( enable-oboe )
# enable C++ as it's needed for oboe
enable_language ( CXX )
pkg_check_modules ( OBOE oboe-1.0 )
if ( OBOE_FOUND )
set ( OBOE_SUPPORT 1 )
set ( OBOE_LIBS ${OBOE_LIBRARIES} )
endif ( OBOE_FOUND )
endif ( enable-oboe )
unset ( WITH_READLINE CACHE )
unset ( READLINE_LIBS CACHE )
if ( enable-readline )
find_package ( Readline )
set ( FOUND_READLINE ${HAVE_READLINE} )
@ -591,8 +641,6 @@ if ( enable-readline )
set ( WITH_READLINE 1 )
set ( READLINE_LIBS ${READLINE_LIBRARIES} )
endif ( HAVE_READLINE )
else ( enable-readline )
unset ( READLINE_LIBS CACHE )
endif ( enable-readline )
unset ( ENABLE_MIXER_THREADS CACHE )
@ -634,6 +682,7 @@ link_directories (
${PORTAUDIO_LIBRARY_DIRS}
${LIBSNDFILE_LIBRARY_DIRS}
${DBUS_LIBRARY_DIRS}
${OBOE_LIBRARY_DIRS}
)
# Process subdirectories

View file

@ -20,7 +20,7 @@ Some things that will increase the chance that your pull request or patch is acc
## Style Guide
Find FluidSynth's style guide below. Syntax related issues, like missing braces, will be automatically taken care of when compiling fluidsynth by calling `make` (provided that cmake has found `clang-tidy >= 5.0` on your system). An explicit reformatting can be achieved using `make format` (provided that cmake has found `clang-format` on your system).
Find FluidSynth's style guide below. Syntax related issues, like missing braces, can be taken care of by calling `make format` (provided that cmake has found `astyle` on your system).
#### General
* Every function should have a short comment explaining it's purpose

View file

@ -4,7 +4,9 @@
| Build Status | glib < 2.30 | glib >= 2.30 |
|---|---|---|
| Linux/MacOSX| n.a. | [![Build Status Travis](https://travis-ci.org/FluidSynth/fluidsynth.svg?branch=master)](https://travis-ci.org/FluidSynth/fluidsynth/branches) |
| Windows | [![Build status Appveyor](https://ci.appveyor.com/api/projects/status/n24ybk0dmttjwdk2/branch/master?svg=true)](https://ci.appveyor.com/project/derselbst/fluidsynth/branch/master) | [![Build status](https://ci.appveyor.com/api/projects/status/anbmtebt5uk4q1it/branch/master?svg=true)](https://ci.appveyor.com/project/derselbst/fluidsynth-g2ouw/branch/master) |
| FreeBSD | n.a. | [![Build Status](https://api.cirrus-ci.com/github/FluidSynth/fluidsynth.svg?branch=master)](https://cirrus-ci.com/github/FluidSynth/fluidsynth) |
| Windows (VisualStudio) | [![Build status Appveyor](https://ci.appveyor.com/api/projects/status/n24ybk0dmttjwdk2/branch/master?svg=true)](https://ci.appveyor.com/project/derselbst/fluidsynth/branch/master) | [![Build status](https://ci.appveyor.com/api/projects/status/anbmtebt5uk4q1it/branch/master?svg=true)](https://ci.appveyor.com/project/derselbst/fluidsynth-g2ouw/branch/master) |
| Windows (MinGW) | [![Build status](https://ci.appveyor.com/api/projects/status/vv7hn9s01nlhv81v/branch/master?svg=true)](https://ci.appveyor.com/project/derselbst/fluidsynth-rjimi/branch/master) | n.a. |
### FluidSynth is a software real-time synthesizer based on the Soundfont 2 specifications.

View file

@ -53,7 +53,11 @@ 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
set (MAN_INSTALL_DIR "share/man/man1" CACHE STRING "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

View file

@ -50,6 +50,18 @@ else ( OSS_SUPPORT )
message ( "OSS: no" )
endif ( OSS_SUPPORT )
if ( OPENSLES_SUPPORT )
message ( "OpenSLES: yes" )
else ( OPENSLES_SUPPORT )
message ( "OpenSLES: no" )
endif ( OPENSLES_SUPPORT )
if ( OBOE_SUPPORT )
message ( "Oboe: yes" )
else ( OBOE_SUPPORT )
message ( "Oboe: no" )
endif ( OBOE_SUPPORT )
if ( MIDISHARE_SUPPORT )
message ( "MidiShare: yes" )
else ( MIDISHARE_SUPPORT )
@ -110,6 +122,12 @@ else ( LASH_SUPPORT )
message ( "LASH support: no" )
endif ( LASH_SUPPORT )
if ( SYSTEMD_SUPPORT )
message ( "systemd support: yes" )
else ( SYSTEMD_SUPPORT )
message ( "systemd support: no" )
endif ( SYSTEMD_SUPPORT )
if ( DART_SUPPORT )
message ( "OS/2 DART support: yes" )
else ( DART_SUPPORT )
@ -182,4 +200,10 @@ else ( ENABLE_FPECHECK )
message ( "Check FPE (debug): no" )
endif ( ENABLE_FPECHECK )
if ( ENABLE_UBSAN )
message ( "UBSan (debug): yes" )
else ( ENABLE_UBSAN )
message ( "UBSan (debug): no" )
endif ( ENABLE_UBSAN )
message ( "**************************************************************\n\n" )

View file

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libfluidsynth
PROJECT_NUMBER = 2.0.3
PROJECT_NUMBER = 2.0.4
OUTPUT_DIRECTORY = api
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English

2
doc/android/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
external

View file

@ -0,0 +1,130 @@
#
# The public targets in this Makefile are: build, clean, wipe
#
# What `build` target does:
#
# - build cerbero to build glib
# - build glib-2.0.so and many other dependency shared libraries
# - build Oboe shared library
# - build libfluidsynth.so
#
# Android app developers are supposed to copy all those shared
# libraries into their apks (per ABI).
#
PWD=$(shell pwd)
CERBERO=$(PWD)/external/cerbero
OBOE=$(PWD)/external/oboe
CMAKE=cmake
ANDROID_NDK = $(PWD)/external/cerbero/build/android-ndk-18
ABIS_SIMPLE = x86 x86-64 armv7 arm64
DIST_PATH=$(CERBERO)/build/dist
OBOE_BUILD_PATH=$(OBOE)/build
all: build
.PHONY: prepare
prepare: checkout-oboe checkout-cerbero
for abi in $(ABIS_SIMPLE) ; do \
cd $(CERBERO) && ./cerbero-uninstalled -c config/cross-android-$$abi.cbc bootstrap && cd $(PWD) ; \
done
.PHONY: checkout-oboe
checkout-oboe: $(OBOE)
cd $(OBOE) && git checkout 9bf3943
$(OBOE):
git clone https://github.com/Google/oboe.git $(OBOE)
.PHONY: checkout-cerbero
checkout-cerbero: $(CERBERO)
cd $(CERBERO) && git checkout 7a6fd79
$(CERBERO):
git clone https://github.com/atsushieno/cerbero.git $(CERBERO)
.PHONY: build
build: build-oboe dist-oboe build-deps-cerbero dist-deps-cerbero build-fluidsynth dist-fluidsynth build-fluidsynth-assetloader dist-fluidsynth-assetloader
.PHONY: build-deps-cerbero
build-deps-cerbero:
for abi in $(ABIS_SIMPLE) ; do \
cd $(CERBERO) && ./cerbero-uninstalled -c config/cross-android-$$abi.cbc build glib && cd $(PWD) ; \
done
define run_make_abi_target
make -f Makefile.android BUILD_ABI=$(1) A_ABI=$(2) $(3)
endef
define run_make_abi_target-unsafe
if make -f Makefile.android BUILD_ABI=$(1) A_ABI=$(2) $(3) ; then \
echo "ignore failure for $(1)..." ; \
fi
endef
define run_make_for_all_abi
$(call run_make_abi_target,x86,x86,$(1) )
$(call run_make_abi_target,x86_64,x86_64,$(1) )
$(call run_make_abi_target,armv7,armeabi-v7a,$(1) )
$(call run_make_abi_target-unsafe,arm64,arm64-v8a,$(1) )
endef
.PHONY: dist-deps-cerbero
dist-deps-cerbero:
$(call run_make_for_all_abi, dist-deps-cerbero-one)
.PHONY: dist-fluidsynth
dist-fluidsynth:
$(call run_make_for_all_abi, dist-fluidsynth-one)
.PHONY: build-oboe
build-oboe:
$(call run_make_for_all_abi, build-oboe-one)
.PHONY: dist-oboe
dist-oboe:
$(call run_make_for_all_abi, dist-oboe-one)
.PHONY: build-fluidsynth
build-fluidsynth:
$(call run_make_for_all_abi, build-fluidsynth-one)
build-fluidsynth-one:
mkdir -p build/$(A_ABI) && cd build/$(A_ABI) && \
LD_RUN_PATH=$(DIST_PATH)/android-$(BUILD_ABI)/lib:$(OBOE_BUILD_PATH)/$(A_ABI) LD_LIBRARY_PATH=$(DIST_PATH)/android_$(BUILD_ABI)/lib PKG_CONFIG_PATH=$(DIST_PATH)/android_$(BUILD_ABI)/lib/pkgconfig/:$(OBOE_BUILD_PATH)/$(A_ABI) \
$(CMAKE) -DCMAKE_INSTALL_PREFIX=$(PWD)/dist/$(A_ABI) -DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK)/build/cmake/android.toolchain.cmake -Denable-opensles=on -Denable-oboe=on -Denable-jack=off -Denable-oss=off -Denable-pulseaudio=off -Denable-libsndfile=off -Denable-dbus=off -Denable-debug=on -DANDROID_NATIVE_API_LEVEL=android-27 -DANDROID_PLATFORM=android-27 -DANDROID_ABI=$(A_ABI) ../../../.. && make
build-oboe-one:
mkdir -p $(OBOE)/build/$(A_ABI) && cd $(OBOE)/build/$(A_ABI) && \
$(CMAKE) -DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK)/build/cmake/android.toolchain.cmake -DANDROID_ABI=$(A_ABI) -DANDROID_NATIVE_API_LEVEL=android-27 -DANDROID_PLATFORM=android-27 -DBUILD_SHARED_LIBS=on ../.. && make
cp oboe-1.0.pc $(OBOE)/build/$(A_ABI)
dist-oboe-one:
mkdir -p dist/$(A_ABI) && cp $(OBOE)/build/$(A_ABI)/*.so dist/$(A_ABI)/
dist-deps-cerbero-one:
mkdir -p dist/$(A_ABI) && cd dist/$(A_ABI) && cp ../../external/cerbero/build/dist/android_$(BUILD_ABI)/lib/*.so . && cd ../..
dist-fluidsynth-one:
mkdir -p dist/$(A_ABI) && cd dist/$(A_ABI) && cp ../../build/$(A_ABI)/src/libfluidsynth.so . && cd ../..
cp -r ../../include/fluidsynth build/$(A_ABI)/include/
build-fluidsynth-assetloader:
cd fluidsynth-assetloader && ./ext-build.sh
dist-fluidsynth-assetloader:
cp fluidsynth-assetloader/build/x86/*.so dist/x86/
cp fluidsynth-assetloader/build/x86_64/*.so dist/x86_64/
cp fluidsynth-assetloader/build/armeabi-v7a/*.so dist/armeabi-v7a/
cp fluidsynth-assetloader/build/arm64-v8a/*.so dist/arm64-v8a/
clean:
rm -rf dist/* build/* external/oboe/build/* obj/local/* fluidsynth-asset-loader/build/*
.PHONY: wipe
wipe: $(CERBERO)
for abi in $(ABIS_SIMPLE) ; do \
cd $(CERBERO) && ./cerbero-uninstalled -c config/cross-android-$$abi.cbc wipe && cd ../.. ; \
done

View file

@ -0,0 +1,38 @@
# Android support in Fluidsynth
Fluidsynth supports Android audio outputs by Oboe and OpenSLES audio drivers.
Android also has Android MIDI API which is exposed only in Android Java API, but it is not exposed as a native API, therefore there is no `mdriver` support for Android. There is an example MidiDeviceService implementation for Fluidsynth at: https://github.com/atsushieno/fluidsynth-midi-service-j
## Usage
`libfluidsynth.so` and `libfluidsynth-assetloader.so` are the library that should be packaged into apk. The latter is for asset-based "sfloader".
By default, "oboe" is the default driver for Android. You can also explicitly specify "opensles" instead, with "audio.driver" setting:
```
fluid_settings_setstr (settings_handle, "audio.driver", "opensles");
```
## Custom SoundFont loader
Since Android file access is quite limited and there is no common place
to store soundfonts unlike Linux desktop (e.g. `/usr/share/sounds/sf2`), you
will most likely have to provide custom soundfont loader.
Since version 2.0.0 Fluidsynth comes with `fluid_sfloader_set_callbacks()` which brings
[customizible file/stream reader](https://github.com/FluidSynth/fluidsynth/issues/241) (open/read/seek/tell/close). It is useful to implement simplified
custom SF loader e.g. with Android assets or OBB streams.
The Android implementation is in separate library called `libfluidsynth-assetloader.so`. It comes with native Asset sfloader. However, its usage is a bit tricky because AssetManager needs to be passed from Java code (even though we use AAssetManager API).
Use `Java_fluidsynth_androidextensions_NativeHandler_setAssetManagerContext()` to initialize the this loader, then call `new_fluid_android_asset_sfloader()` to create a new sfloader. If you already have AAssetManager instance, then the first JNI function is ignorable and you only have to specify the manager to the second function.
There is [an example source code](https://github.com/atsushieno/fluidsynth-midi-service-j/blob/a2a56b/fluidsynthjna/src/main/java/fluidsynth/androidextensions/AndroidNativeAssetSoundFontLoader.kt#L17) on how to do it.
## Building
By default, you are supposed to provide `PKG_CONFIG_PATH` to glib etc. as well as oboe. There is nothing special.
However, in reality, Oboe does not come up with an official package specification, so you will have to create it manually... unless you use `oboe-1.0.pc` in this directory as well as the build system set up here.
There are "non-normative" build scripts i.e. `Makefile.android` and a couple of helper files in this directory. In case you don't have any dependencies such as glib for Android, then it would be helpful.

View file

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.6.0)
project ( fluidsynth-assetloader C )
set ( fluidsynth-assetloader_sources fluid_androidasset.c )
add_library ( fluidsynth-assetloader SHARED ${fluidsynth-assetloader_sources} )
target_compile_options ( fluidsynth-assetloader
PRIVATE -v
PRIVATE -Wall
PRIVATE "$<$<CONFIG:DEBUG>:-Werror>") # Only include -Werror when building debug config
include_directories ( ../../../include )
set ( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L../../../dist/${ANDROID_ABI} -lfluidsynth" )
target_link_libraries ( fluidsynth-assetloader PRIVATE log android )

View file

@ -0,0 +1,16 @@
PWD=`pwd`
ABIS="x86 x86_64 armeabi-v7a arm64-v8a"
HOST_OS=`uname | tr [:upper:] [:lower:]`
ANDROID_NDK_PATH=~/android-sdk-$HOST_OS/ndk-bundle
CMAKEFILE=$ANDROID_NDK_PATH/build/cmake/android.toolchain.cmake
for A_ABI in $ABIS ; do
mkdir -p build/$A_ABI && \
cd build/$A_ABI && \
cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKEFILE -DANDROID_PLATFORM=android-27 -DANDROID_ABI=$A_ABI ../.. && \
make &&
cd ../.. ;
done

View file

@ -0,0 +1,110 @@
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 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
* 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
*/
#if defined(ANDROID) || defined(__DOXYGEN__)
#define FLUIDSYNTH_API
#include <stdlib.h>
#include <jni.h>
#include "fluid_androidasset.h"
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
AAssetManager *fluid_android_asset_manager;
fluid_sfloader_t* new_fluid_android_asset_sfloader(fluid_settings_t *settings, void *assetManager)
{
fluid_sfloader_t *loader;
if (settings == NULL)
return NULL;
if (!fluid_android_asset_manager)
fluid_android_asset_manager = (AAssetManager*) assetManager;
if (fluid_android_asset_manager == NULL)
return NULL;
loader = new_fluid_defsfloader(settings);
if (loader == NULL)
return NULL;
fluid_sfloader_set_callbacks(loader,
asset_open,
asset_read,
asset_seek,
asset_tell,
asset_close);
return loader;
}
/* This is a compromised solution for JNAerator for that 1) it cannot handle jobject with JNIEnv as parameters, and that 2) the returned pointer can be converted in the same manner that JNAerated methods. (Most likely my JNA usage issue but no one has answer for it.) */
void Java_fluidsynth_androidextensions_NativeHandler_setAssetManagerContext(JNIEnv *env, jobject _this, jobject assetManager)
{
if (assetManager == NULL)
return;
fluid_android_asset_manager = AAssetManager_fromJava (env, assetManager);
}
void *asset_open(const char *path)
{
if (fluid_android_asset_manager == NULL)
return NULL;
return AAssetManager_open (fluid_android_asset_manager, path, AASSET_MODE_RANDOM);
}
int asset_close(void *handle)
{
AAsset *asset;
asset = (AAsset*) handle;
AAsset_close (asset);
return 0;
}
long asset_tell(void *handle)
{
AAsset *asset;
asset = (AAsset*) handle;
return AAsset_getLength(asset) - AAsset_getRemainingLength(asset);
}
int asset_seek(void *handle, long offset, int origin)
{
AAsset *asset;
asset = (AAsset*) handle;
return AAsset_seek (asset, (off_t) offset, origin);
}
int asset_read(void *buf, int count, void *handle)
{
AAsset *asset;
asset = (AAsset*) handle;
return AAsset_read (asset, buf, (size_t) count);
}
#endif /* if defined(ANDROID) || defined(__DOXYGEN__) */

View file

@ -0,0 +1,45 @@
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 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
* 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
*/
#ifndef _PRIV_FLUID_ANDROIDASSET_H
#define _PRIV_FLUID_ANDROIDASSET_H
#ifdef __cplusplus
extern "C" {
#endif
#include <fluidsynth/types.h>
#include <fluidsynth/sfont.h>
fluid_sfloader_t* new_fluid_android_asset_sfloader(fluid_settings_t *settings, void *assetManager);
void Java_fluidsynth_androidextensions_NativeHandler_setAssetManagerContext(JNIEnv *env, jobject _this, jobject assetManager);
void *asset_open(const char *path);
int asset_close(void *handle);
long asset_tell(void *handle);
int asset_seek(void *handle, long offset, int origin);
int asset_read(void *buf, int count, void *handle);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _PRIV_FLUID_ANDROIDASSET_H */

View file

@ -0,0 +1,44 @@
LOCAL_PATH := $(call my-dir)
TARGET_PLATFORM := android-27
GLIB_LIB = ../dep/$(APP_ABI)/
include $(CLEAR_VARS)
LOCAL_MODULE := glib-2.0
LOCAL_SRC_FILES := $(GLIB_LIB)/libglib-2.0.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := iconv
LOCAL_SRC_FILES := $(GLIB_LIB)/libiconv.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := intl
LOCAL_SRC_FILES := $(GLIB_LIB)/libintl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := oboe
LOCAL_SRC_FILES := $(GLIB_LIB)/liboboe.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := fluidsynth_static
LOCAL_SRC_FILES := ../dep/$(APP_ABI)/libfluidsynth.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_MODULE := fluidsynth
ifeq ($(NDK_DEBUG),1)
cmd-strip :=
endif
LOCAL_STATIC_LIBRARIES := glib-2.0 iconv intl oboe
LOCAL_WHOLE_STATIC_LIBRARIES := fluidsynth_static
LOCAL_LDLIBS := -lc -lOpenSLES -ldl -llog -landroid -L$(LOCAL_PATH)/../dist/$(APP_ABI) -loboe-c
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,2 @@
APP_PLATFORM := android-21
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a

10
doc/android/oboe-1.0.pc Normal file
View file

@ -0,0 +1,10 @@
prefix=${pcfiledir}
exec_prefix=${prefix}
libdir=${prefix}
includedir=${prefix}/../../include/
Name: Oboe
Description: Oboe library
Version: 1.0.0
Libs: -L${libdir} -loboe -landroid -llog -lstdc++
Cflags: -I${includedir}

View file

@ -508,7 +508,7 @@ Developers: Settings can be deprecated by adding: <deprecated>SOME TEXT</depreca
<type>str</type>
<def>fluidsynth</def>
<desc>
ID used when creating Jack client connection.
Unique identifier used when creating Jack client connection.
</desc>
</setting>
<setting>
@ -527,6 +527,34 @@ Developers: Settings can be deprecated by adding: <deprecated>SOME TEXT</depreca
Jack server to connect to. Defaults to an empty string, which uses default Jack server.
</desc>
</setting>
<setting>
<name>oboe.id</name>
<type>int</type>
<def>0</def>
<min>0</min>
<max>2147483647</max>
<desc>
Request an audio device identified device using an ID as pointed out by Oboe's documentation.
</desc>
</setting>
<setting>
<name>oboe.sharing-mode</name>
<type>str</type>
<def>Shared</def>
<vals>Shared, Exclusive</vals>
<desc>
Sets the sharing mode as pointed out by Oboe's documentation.
</desc>
</setting>
<setting>
<name>oboe.performance-mode</name>
<type>str</type>
<def>None</def>
<vals>None, PowerSaving, LowLatency</vals>
<desc>
Sets the performance mode as pointed out by Oboe's documentation.
</desc>
</setting>
<setting>
<name>oss.device</name>
<type>str</type>

View file

@ -8,8 +8,8 @@
\author David Henningsson
\author Tom Moebert
\author Copyright &copy; 2003-2019 Peter Hanappe, Conrad Berhörster, Antoine Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert
\version Revision 2.0.3
\date 2019-01-01
\version Revision 2.0.4
\date 2019-02-09
All the source code examples in this document are in the public domain; you can use them as you please. This document is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ . The FluidSynth library is distributed under the GNU Lesser General Public License. A copy of the GNU Lesser General Public License is contained in the FluidSynth package; if not, visit http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -81,6 +81,7 @@ FluidSynths major version was bumped. The API was reworked, deprecated functions
<strong><span style="color:red">Important changes that may not result in a compilation error but may cause your app to misbehave:</span></strong>
- all public \c fluid_settings_* functions that return an integer which is not meant to be interpreted as bool consistently return either FLUID_OK or FLUID_FAILED
- fluid_settings_setstr() cannot be used to set integer (toggle) settings with "yes" or "no" values anymore. Use fluid_settings_setint() instead, for example: <br /><code>fluid_settings_setint(settings, "synth.reverb.active", 0)</code> instead of <code>fluid_settings_setstr(settings, "synth.reverb.active", "no")</code>
- explicit client unregistering is required for fluid_sequencer_register_client() and fluid_sequencer_register_fluidsynth()
- all public functions consistently receive signed integers for soundfont ids, bank and program numbers
- use unique device names for the "audio.portaudio.device" setting
@ -90,8 +91,9 @@ FluidSynths major version was bumped. The API was reworked, deprecated functions
- all public \c delete_* functions return void and are safe when called with NULL
- the shell command handler was decoupled internally, as a consequence the param list of new_fluid_server() and new_fluid_cmd_handler() was adapted
- \c fluid_settings_set* functions no longer silently register unknown settings but return an error instead
- reverb: roomsize is now limited to an upper threshold of 1.0 to avoid exponential volume increase
- rename fluid_mod_new() and fluid_mod_delete() to match naming conventions: new_fluid_mod() and delete_fluid_mod()
- rename \c fluid_mod_new() and \c fluid_mod_delete() to match naming conventions: new_fluid_mod() and delete_fluid_mod()
- rename chorus getters to match naming conventions: fluid_synth_get_chorus_speed() and fluid_synth_get_chorus_depth()
- fluid_synth_remove_sfont() returns FLUID_OK or FLUID_FAILED
- introduce a separate data type for sequencer client IDs: #fluid_seq_id_t
@ -218,6 +220,8 @@ Creating the audio driver is straightforward: set the <code>audio.driver</code>
- portaudio: PortAudio Library (Mac OS 9 & X, Windows, Linux)
- sndman: Apple SoundManager (Mac OS Classic)
- dart: DART sound driver (OS/2)
- opensles: OpenSL ES (Android)
- oboe: Oboe (Android)
- file: Driver to output audio to a file
- sdl2*: Simple DirectMedia Layer (Linux, Windows, Mac OS X, iOS, Android, FreeBSD, Haiku, etc.)
@ -594,8 +598,8 @@ void createsynth()
{
fluid_settings_t* settings;
settings = new_fluid_settings();
fluid_settings_setstr(settings, "synth.reverb.active", "yes");
fluid_settings_setstr(settings, "synth.chorus.active", "no");
fluid_settings_setint(settings, "synth.reverb.active", 0);
fluid_settings_setint(settings, "synth.chorus.active", 0);
synth = new_fluid_synth(settings);
adriver = new_fluid_audio_driver(settings, synth);
sequencer = new_fluid_sequencer2(0);

View file

@ -4,6 +4,8 @@ Documentation=man:fluidsynth(1)
After=sound.target
[Service]
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

View file

@ -104,6 +104,10 @@ if ( LASH_SUPPORT )
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} )
@ -122,6 +126,16 @@ if ( AUFILE_SUPPORT )
set ( fluid_aufile_SOURCES drivers/fluid_aufile.c )
endif ( AUFILE_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 ( libfluidsynth_SOURCES
@ -253,6 +267,8 @@ add_library ( libfluidsynth-OBJ OBJECT
${fluid_jack_SOURCES}
${fluid_lash_SOURCES}
${fluid_midishare_SOURCES}
${fluid_opensles_SOURCES}
${fluid_oboe_SOURCES}
${fluid_oss_SOURCES}
${fluid_portaudio_SOURCES}
${fluid_pulse_SOURCES}
@ -335,6 +351,8 @@ target_link_libraries ( libfluidsynth
${COREMIDI_LIBS}
${WINDOWS_LIBS}
${MidiShare_LIBS}
${OpenSLES_LIBS}
${OBOE_LIBS}
${LIBFLUID_LIBS}
)
@ -353,6 +371,7 @@ endif ( FLUID_CPPFLAGS )
target_link_libraries ( fluidsynth
libfluidsynth
${SYSTEMD_LIBRARIES}
${FLUID_LIBS}
)

View file

@ -18,12 +18,10 @@
* 02110-1301, USA
*/
#include "fluidsynth_priv.h"
#include "fluid_cmd.h"
#include "fluid_synth.h"
#include "fluid_settings.h"
#include "fluid_hash.h"
#include "fluid_sys.h"
#include "fluid_midi_router.h"
#include "fluid_sfont.h"
#include "fluid_chan.h"
@ -104,7 +102,7 @@ static const fluid_cmd_t fluid_commands[] =
},
{
"pitch_bend_range", "event", fluid_handle_pitch_bend_range,
"pitch_bend chan range Sets bend pitch range"
"pitch_bend_range chn range Sets pitch bend range for the given midi channel"
},
{
"cc", "event", fluid_handle_cc,

View file

@ -21,7 +21,7 @@
#ifndef _FLUID_CMD_H
#define _FLUID_CMD_H
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
void fluid_shell_settings(fluid_settings_t *settings);

View file

@ -298,7 +298,7 @@ new_fluid_file_renderer(fluid_synth_t *synth)
sf_command(dev->sndfile, SFC_SET_NORM_FLOAT, NULL, SF_TRUE);
#else
dev->file = fopen(filename, "wb");
dev->file = FLUID_FOPEN(filename, "wb");
if(dev->file == NULL)
{

View file

@ -25,14 +25,14 @@
SOFTWARE.
***/
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
#ifdef DBUS_SUPPORT
#include "fluid_rtkit.h"
#if defined(__linux__) || defined(__APPLE__)
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
@ -42,10 +42,17 @@
#include <sys/syscall.h>
#include <sys/resource.h>
#if defined(__FreeBSD__) || defined(__DragonFly__)
#include <pthread_np.h>
#endif
static pid_t _gettid(void)
{
#if defined(__FreeBSD__) || defined(__DragonFly__)
return pthread_getthreadid_np();
#else
return (pid_t) syscall(SYS_gettid);
#endif
}
static int translate_error(const char *name)

View file

@ -49,6 +49,9 @@
/* whether or not we are supporting lash */
#cmakedefine HAVE_LASH @HAVE_LASH@
/* Define if systemd support is enabled */
#cmakedefine SYSTEMD_SUPPORT @SYSTEMD_SUPPORT@
/* Define to 1 if you have the `MidiShare' library (-lMidiShare). */
#cmakedefine HAVE_LIBMIDISHARE @HAVE_LIBMIDISHARE@
@ -169,6 +172,12 @@
/* Define to enable OSS driver */
#cmakedefine OSS_SUPPORT @OSS_SUPPORT@
/* Define to enable OPENSLES driver */
#cmakedefine OPENSLES_SUPPORT @OPENSLES_SUPPORT@
/* Define to enable Oboe driver */
#cmakedefine OBOE_SUPPORT @OBOE_SUPPORT@
/* Name of package */
#cmakedefine PACKAGE "@PACKAGE@"

View file

@ -19,6 +19,7 @@
*/
#include "fluid_adriver.h"
#include "fluid_sys.h"
#include "fluid_settings.h"
/*
@ -79,6 +80,26 @@ static const fluid_audriver_definition_t fluid_audio_drivers[] =
},
#endif
#if OBOE_SUPPORT
{
"oboe",
new_fluid_oboe_audio_driver,
NULL,
delete_fluid_oboe_audio_driver,
fluid_oboe_audio_driver_settings
},
#endif
#if OPENSLES_SUPPORT
{
"opensles",
new_fluid_opensles_audio_driver,
NULL,
delete_fluid_opensles_audio_driver,
fluid_opensles_audio_driver_settings
},
#endif
#if COREAUDIO_SUPPORT
{
"coreaudio",

View file

@ -21,7 +21,7 @@
#ifndef _FLUID_AUDRIVER_H
#define _FLUID_AUDRIVER_H
#include "fluid_sys.h"
#include "fluidsynth_priv.h"
/*
* fluid_audio_driver_t
@ -66,6 +66,22 @@ void delete_fluid_oss_audio_driver(fluid_audio_driver_t *p);
void fluid_oss_audio_driver_settings(fluid_settings_t *settings);
#endif
#if OPENSLES_SUPPORT
fluid_audio_driver_t*
new_fluid_opensles_audio_driver(fluid_settings_t* settings,
fluid_synth_t* synth);
void delete_fluid_opensles_audio_driver(fluid_audio_driver_t* p);
void fluid_opensles_audio_driver_settings(fluid_settings_t* settings);
#endif
#if OBOE_SUPPORT
fluid_audio_driver_t*
new_fluid_oboe_audio_driver(fluid_settings_t* settings,
fluid_synth_t* synth);
void delete_fluid_oboe_audio_driver(fluid_audio_driver_t* p);
void fluid_oboe_audio_driver_settings(fluid_settings_t* settings);
#endif
#if COREAUDIO_SUPPORT
fluid_audio_driver_t *new_fluid_core_audio_driver(fluid_settings_t *settings,
fluid_synth_t *synth);

View file

@ -355,6 +355,7 @@ void delete_fluid_alsa_audio_driver(fluid_audio_driver_t *p)
if(dev->thread)
{
fluid_thread_join(dev->thread);
delete_fluid_thread(dev->thread);
}
if(dev->pcm)
@ -757,6 +758,7 @@ delete_fluid_alsa_rawmidi_driver(fluid_midi_driver_t *p)
if(dev->thread)
{
fluid_thread_join(dev->thread);
delete_fluid_thread(dev->thread);
}
if(dev->rawmidi_in)
@ -1210,6 +1212,7 @@ delete_fluid_alsa_seq_driver(fluid_midi_driver_t *p)
if(dev->thread)
{
fluid_thread_join(dev->thread);
delete_fluid_thread(dev->thread);
}
if(dev->seq_handle)

View file

@ -24,12 +24,16 @@
*
*/
#include "fluid_synth.h"
#include "fluid_midi.h"
#include "fluid_adriver.h"
#include "fluid_mdriver.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
*/
#if COREAUDIO_SUPPORT
#include <CoreServices/CoreServices.h>
#include <CoreAudio/CoreAudioTypes.h>

225
src/drivers/fluid_oboe.cpp Normal file
View file

@ -0,0 +1,225 @@
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 Peter Hanappe and others.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* as published by the Free Software Foundation; either version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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_oboe.c
*
* Audio driver for Android Oboe.
*
*/
extern "C" {
#include "fluid_adriver.h"
#include "fluid_settings.h"
} // extern "C"
#if OBOE_SUPPORT
#include <oboe/Oboe.h>
using namespace oboe;
static const int NUM_CHANNELS = 2;
class OboeAudioStreamCallback;
/** fluid_oboe_audio_driver_t
*
* This structure should not be accessed directly. Use audio port
* functions instead.
*/
typedef struct
{
fluid_audio_driver_t driver;
fluid_synth_t *synth;
int cont;
OboeAudioStreamCallback *oboe_callback;
AudioStream *stream;
} fluid_oboe_audio_driver_t;
class OboeAudioStreamCallback : public AudioStreamCallback
{
public:
OboeAudioStreamCallback(void *userData)
: user_data(userData)
{
}
DataCallbackResult onAudioReady(AudioStream *stream, void *audioData, int32_t numFrames)
{
fluid_oboe_audio_driver_t *dev = static_cast<fluid_oboe_audio_driver_t *>(this->user_data);
if(!dev->cont)
{
return DataCallbackResult::Stop;
}
if(stream->getFormat() == AudioFormat::Float)
{
fluid_synth_write_float(dev->synth, numFrames, static_cast<float *>(audioData), 0, 2, static_cast<float *>(audioData), 1, 2);
}
else
{
fluid_synth_write_s16(dev->synth, numFrames, static_cast<short *>(audioData), 0, 2, static_cast<short *>(audioData), 1, 2);
}
return DataCallbackResult::Continue;
}
private:
void *user_data;
};
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_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, "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");
}
/*
* new_fluid_oboe_audio_driver
*/
fluid_audio_driver_t *
new_fluid_oboe_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
{
Result result;
fluid_oboe_audio_driver_t *dev;
AudioStreamBuilder builder_obj;
AudioStreamBuilder *builder = &builder_obj;
AudioStream *stream;
int period_frames;
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
try
{
dev = FLUID_NEW(fluid_oboe_audio_driver_t);
if(dev == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
FLUID_MEMSET(dev, 0, sizeof(fluid_oboe_audio_driver_t));
dev->synth = synth;
dev->oboe_callback = new(std::nothrow) OboeAudioStreamCallback(dev);
if(!dev->oboe_callback)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
goto error_recovery;
}
fluid_settings_getint(settings, "audio.period-size", &period_frames);
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;
builder->setDeviceId(device_id)
->setDirection(Direction::Output)
->setChannelCount(NUM_CHANNELS)
->setSampleRate(sample_rate)
->setFramesPerCallback(period_frames)
->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);
result = builder->openStream(&stream);
dev->stream = stream;
if(result != Result::OK)
{
goto error_recovery;
}
dev->cont = 1;
FLUID_LOG(FLUID_INFO, "Using Oboe driver");
stream->start();
return reinterpret_cast<fluid_audio_driver_t *>(dev);
}
catch(...)
{
FLUID_LOG(FLUID_ERR, "Unexpected Oboe driver initialization error");
}
error_recovery:
delete_fluid_oboe_audio_driver(reinterpret_cast<fluid_audio_driver_t *>(dev));
return NULL;
}
void delete_fluid_oboe_audio_driver(fluid_audio_driver_t *p)
{
fluid_oboe_audio_driver_t *dev = reinterpret_cast<fluid_oboe_audio_driver_t *>(p);
fluid_return_if_fail(dev != NULL);
try
{
dev->cont = 0;
if(dev->stream != NULL)
{
dev->stream->stop();
dev->stream->close();
}
}
catch(...) {}
delete dev->oboe_callback;
FLUID_FREE(dev);
}
#endif // OBOE_SUPPORT

View file

@ -0,0 +1,333 @@
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 Peter Hanappe and others.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* as published by the Free Software Foundation; either version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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_opensles.c
*
* Audio driver for OpenSLES.
*
*/
#include "fluid_adriver.h"
#if OPENSLES_SUPPORT
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
static const int NUM_CHANNELS = 2;
/** fluid_opensles_audio_driver_t
*
* This structure should not be accessed directly. Use audio port
* functions instead.
*/
typedef struct
{
fluid_audio_driver_t driver;
SLObjectItf engine;
SLObjectItf output_mix_object;
SLObjectItf audio_player;
SLPlayItf audio_player_interface;
SLAndroidSimpleBufferQueueItf player_buffer_queue_interface;
void *synth;
int period_frames;
int is_sample_format_float;
/* used only by callback mode */
short *sles_buffer_short;
float *sles_buffer_float;
int cont;
double sample_rate;
} fluid_opensles_audio_driver_t;
static void opensles_callback(SLAndroidSimpleBufferQueueItf caller, void *pContext);
static void process_fluid_buffer(fluid_opensles_audio_driver_t *dev);
void fluid_opensles_audio_driver_settings(fluid_settings_t *settings)
{
}
/*
* new_fluid_opensles_audio_driver
*/
fluid_audio_driver_t *
new_fluid_opensles_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
{
SLresult result;
fluid_opensles_audio_driver_t *dev;
double sample_rate;
int period_size;
int realtime_prio = 0;
int is_sample_format_float;
SLEngineItf engine_interface;
dev = FLUID_NEW(fluid_opensles_audio_driver_t);
if(dev == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
FLUID_MEMSET(dev, 0, sizeof(*dev));
fluid_settings_getint(settings, "audio.period-size", &period_size);
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
fluid_settings_getint(settings, "audio.realtime-prio", &realtime_prio);
is_sample_format_float = fluid_settings_str_equal(settings, "audio.sample-format", "float");
dev->synth = synth;
dev->is_sample_format_float = is_sample_format_float;
dev->period_frames = period_size;
dev->sample_rate = sample_rate;
dev->cont = 1;
result = slCreateEngine(&(dev->engine), 0, NULL, 0, NULL, NULL);
if(!dev->engine)
{
FLUID_LOG(FLUID_ERR, "Failed to create OpenSLES connection");
goto error_recovery;
}
result = (*dev->engine)->Realize(dev->engine, SL_BOOLEAN_FALSE);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
result = (*dev->engine)->GetInterface(dev->engine, SL_IID_ENGINE, &engine_interface);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
result = (*engine_interface)->CreateOutputMix(engine_interface, &dev->output_mix_object, 0, 0, 0);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
result = (*dev->output_mix_object)->Realize(dev->output_mix_object, SL_BOOLEAN_FALSE);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
SLDataLocator_AndroidSimpleBufferQueue loc_buffer_queue =
{
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
2 /* number of buffers */
};
SLAndroidDataFormat_PCM_EX format_pcm =
{
SL_ANDROID_DATAFORMAT_PCM_EX,
NUM_CHANNELS,
((SLuint32) sample_rate) * 1000,
is_sample_format_float ? SL_PCMSAMPLEFORMAT_FIXED_32 : SL_PCMSAMPLEFORMAT_FIXED_16,
is_sample_format_float ? SL_PCMSAMPLEFORMAT_FIXED_32 : SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
SL_BYTEORDER_LITTLEENDIAN,
is_sample_format_float ? SL_ANDROID_PCM_REPRESENTATION_FLOAT : SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT
};
SLDataSource audio_src =
{
&loc_buffer_queue,
&format_pcm
};
SLDataLocator_OutputMix loc_outmix =
{
SL_DATALOCATOR_OUTPUTMIX,
dev->output_mix_object
};
SLDataSink audio_sink = {&loc_outmix, NULL};
const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req1[] = {SL_BOOLEAN_TRUE};
result = (*engine_interface)->CreateAudioPlayer(engine_interface,
&(dev->audio_player), &audio_src, &audio_sink, 1, ids1, req1);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
result = (*dev->audio_player)->Realize(dev->audio_player, SL_BOOLEAN_FALSE);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
result = (*dev->audio_player)->GetInterface(dev->audio_player,
SL_IID_PLAY, &(dev->audio_player_interface));
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
result = (*dev->audio_player)->GetInterface(dev->audio_player,
SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(dev->player_buffer_queue_interface));
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
if(dev->is_sample_format_float)
{
dev->sles_buffer_float = FLUID_ARRAY(float, dev->period_frames * NUM_CHANNELS);
}
else
{
dev->sles_buffer_short = FLUID_ARRAY(short, dev->period_frames * NUM_CHANNELS);
}
if(dev->sles_buffer_float == NULL && dev->sles_buffer_short == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory.");
goto error_recovery;
}
result = (*dev->player_buffer_queue_interface)->RegisterCallback(dev->player_buffer_queue_interface, opensles_callback, dev);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
if(dev->is_sample_format_float)
{
(*dev->player_buffer_queue_interface)->Enqueue(dev->player_buffer_queue_interface, dev->sles_buffer_float, dev->period_frames * NUM_CHANNELS * sizeof(float));
}
else
{
(*dev->player_buffer_queue_interface)->Enqueue(dev->player_buffer_queue_interface, dev->sles_buffer_short, dev->period_frames * NUM_CHANNELS * sizeof(short));
}
(*dev->audio_player_interface)->SetCallbackEventsMask(dev->audio_player_interface, SL_PLAYEVENT_HEADATEND);
result = (*dev->audio_player_interface)->SetPlayState(dev->audio_player_interface, SL_PLAYSTATE_PLAYING);
if(result != SL_RESULT_SUCCESS)
{
goto error_recovery;
}
FLUID_LOG(FLUID_INFO, "Using OpenSLES driver.");
return (fluid_audio_driver_t *) dev;
error_recovery:
delete_fluid_opensles_audio_driver((fluid_audio_driver_t *) dev);
return NULL;
}
void delete_fluid_opensles_audio_driver(fluid_audio_driver_t *p)
{
fluid_opensles_audio_driver_t *dev = (fluid_opensles_audio_driver_t *) p;
fluid_return_if_fail(dev != NULL);
dev->cont = 0;
if(dev->audio_player)
{
(*dev->audio_player)->Destroy(dev->audio_player);
}
if(dev->output_mix_object)
{
(*dev->output_mix_object)->Destroy(dev->output_mix_object);
}
if(dev->engine)
{
(*dev->engine)->Destroy(dev->engine);
}
if(dev->sles_buffer_float)
{
FLUID_FREE(dev->sles_buffer_float);
}
if(dev->sles_buffer_short)
{
FLUID_FREE(dev->sles_buffer_short);
}
FLUID_FREE(dev);
}
void opensles_callback(SLAndroidSimpleBufferQueueItf caller, void *pContext)
{
fluid_opensles_audio_driver_t *dev = (fluid_opensles_audio_driver_t *) pContext;
SLresult result;
process_fluid_buffer(dev);
if(dev->is_sample_format_float)
{
result = (*caller)->Enqueue(
dev->player_buffer_queue_interface, dev->sles_buffer_float, dev->period_frames * sizeof(float) * NUM_CHANNELS);
}
else
{
result = (*caller)->Enqueue(
dev->player_buffer_queue_interface, dev->sles_buffer_short, dev->period_frames * sizeof(short) * NUM_CHANNELS);
}
/*
if (result != SL_RESULT_SUCCESS)
{
// Do not simply break at just one single insufficient buffer. Go on.
}
*/
}
void process_fluid_buffer(fluid_opensles_audio_driver_t *dev)
{
short *out_short = dev->sles_buffer_short;
float *out_float = dev->sles_buffer_float;
int period_frames = dev->period_frames;
if(dev->is_sample_format_float)
{
fluid_synth_write_float(dev->synth, period_frames, out_float, 0, 2, out_float, 1, 2);
}
else
{
fluid_synth_write_s16(dev->synth, period_frames, out_short, 0, 2, out_short, 1, 2);
}
}
#endif

View file

@ -448,6 +448,7 @@ delete_fluid_oss_audio_driver(fluid_audio_driver_t *p)
if(dev->thread)
{
fluid_thread_join(dev->thread);
delete_fluid_thread(dev->thread);
}
if(dev->dspfd >= 0)
@ -705,6 +706,7 @@ delete_fluid_oss_midi_driver(fluid_midi_driver_t *p)
if(dev->thread)
{
fluid_thread_join(dev->thread);
delete_fluid_thread(dev->thread);
}
if(dev->fd >= 0)

View file

@ -221,6 +221,7 @@ void delete_fluid_pulse_audio_driver(fluid_audio_driver_t *p)
if(dev->thread)
{
fluid_thread_join(dev->thread);
delete_fluid_thread(dev->thread);
}
if(dev->pa_handle)

View file

@ -72,7 +72,7 @@ void fluid_sdl2_audio_driver_settings(fluid_settings_t *settings)
if(dev_name != NULL)
{
FLUID_LOG(FLUID_DBG, "Testing audio device: %s", dev_name);
FLUID_LOG(FLUID_DBG, "SDL2 driver testing audio device: %s", dev_name);
fluid_settings_add_option(settings, "audio.sdl2.device", dev_name);
}
}
@ -93,6 +93,13 @@ new_fluid_sdl2_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
char *device;
const char *dev_name;
/* Check if SDL library has been started */
if(!SDL_WasInit(SDL_INIT_AUDIO))
{
FLUID_LOG(FLUID_ERR, "Failed to create SDL2 audio driver, because the audio subsystem of SDL2 is not initialized.");
return NULL;
}
/* Retrieve the settings */
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
fluid_settings_getint(settings, "audio.period-size", &period_size);
@ -103,14 +110,14 @@ new_fluid_sdl2_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
period_size = 1024;
}
else
{
/* According to documentation, it MUST be a power of two */
if((period_size & (period_size - 1)) != 0)
{
FLUID_LOG(FLUID_DBG, "\"audio.period-size\" must be a power of 2");
FLUID_LOG(FLUID_ERR, "\"audio.period-size\" must be a power of 2 for SDL2");
return NULL;
}
}
/* Clear the format buffer */
FLUID_MEMSET(&aspec, 0, sizeof(aspec));
@ -147,13 +154,6 @@ new_fluid_sdl2_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
aspec.samples = aspec.channels * ((period_size + 7) & ~7);
aspec.callback = (SDL_AudioCallback)SDLAudioCallback;
/* Check if SDL library has been started */
if(!SDL_WasInit(SDL_INIT_AUDIO))
{
FLUID_LOG(FLUID_ERR, "SDL2 not initialized");
return NULL;
}
/* Set default device to use */
device = NULL;
dev_name = NULL;

View file

@ -18,13 +18,7 @@
* 02110-1301, USA
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
#if !defined(WIN32) && !defined(MACINTOSH)
#define _GNU_SOURCE
@ -35,10 +29,15 @@
#define GETOPT_SUPPORT 1
#endif
#include "fluidsynth.h"
#include "fluid_lash.h"
#ifdef SYSTEMD_SUPPORT
#include <systemd/sd-daemon.h>
#endif
#if SDL2_SUPPORT
#include <SDL.h>
#endif
void print_usage(void);
void print_help(fluid_settings_t *settings);
@ -350,6 +349,18 @@ int main(int argc, char **argv)
lash_args = fluid_lash_extract_args(&argc, &argv);
#endif
#if SDL2_SUPPORT
if (SDL_Init(SDL_INIT_AUDIO) != 0)
{
fprintf(stderr, "Warning: Unable to initialize SDL2 Audio: %s", SDL_GetError());
}
else
{
atexit(SDL_Quit);
}
#endif
print_welcome();
@ -629,6 +640,8 @@ int main(int argc, char **argv)
case 's':
#ifdef NETWORK_SUPPORT
with_server = 1;
#else
printf("\nNOTE: FluidSynth compiled without network support, unable to start server!\n");
#endif
break;
@ -898,6 +911,12 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to create the server.\n"
"Continuing without it.\n");
}
#ifdef SYSTEMD_SUPPORT
else
{
sd_notify(0, "READY=1");
}
#endif
}
#endif
@ -960,10 +979,13 @@ cleanup:
fluid_server_join(server);
}
#ifdef SYSTEMD_SUPPORT
sd_notify(0, "STOPPING=1");
#endif
delete_fluid_server(server);
}
#endif
#endif /* NETWORK_SUPPORT */
if(cmd_handler != NULL)
{

View file

@ -4,6 +4,12 @@ cmake_minimum_required(VERSION 3.1)
# which hopefully will be the host compiler
unset(ENV{CC})
# also unset $CFLAGS to avoid passing any cross compilation flags to the host compiler
unset(ENV{CFLAGS})
# linker flags as well
unset(ENV{LDFLAGS})
project (gentables C)
set ( CMAKE_BUILD_TYPE Debug )

View file

@ -22,7 +22,7 @@ static void fluid_conversion_config(void)
for(i = 0; i < FLUID_CENTS_HZ_SIZE; i++)
{
fluid_ct2hz_tab[i] = pow(2.0, (double) i / 1200.0);
fluid_ct2hz_tab[i] = powl(2.0, (double) i / 1200.0);
}
/* centibels to amplitude conversion
@ -32,7 +32,7 @@ static void fluid_conversion_config(void)
*/
for(i = 0; i < FLUID_CB_AMP_SIZE; i++)
{
fluid_cb2amp_tab[i] = pow(10.0, (double) i / -200.0);
fluid_cb2amp_tab[i] = powl(10.0, (double) i / -200.0);
}
/* initialize the conversion tables (see fluid_mod.c

View file

@ -34,6 +34,7 @@ static long fluid_getlength(unsigned char *s);
* Note: This rewinds the file to the start before reading.
* Returns NULL if there was an error reading or allocating memory.
*/
typedef FILE *fluid_file;
static char *fluid_file_read_full(fluid_file fp, size_t *length);
static void fluid_midi_event_set_sysex_LOCAL(fluid_midi_event_t *evt, int type, void *data, int size, int dynamic);
static void fluid_midi_event_get_sysex_LOCAL(fluid_midi_event_t *evt, void **data, int *size);
@ -92,17 +93,23 @@ static int fluid_midi_file_get_division(fluid_midi_file *midifile);
*/
int fluid_is_midifile(const char *filename)
{
FILE *fp = FLUID_FOPEN(filename, "rb");
FILE *fp;
uint32_t id;
int retcode = FALSE;
do
{
if(fp == NULL)
if(!fluid_file_test(filename, G_FILE_TEST_IS_REGULAR))
{
return retcode;
}
// file seems to exist and is a regular file or a symlink to such
if((fp = FLUID_FOPEN(filename, "rb")) == NULL)
{
return retcode;
}
if(FLUID_FREAD(&id, sizeof(id), 1, fp) != 1)
{
break;
@ -1669,7 +1676,7 @@ new_fluid_player(fluid_synth_t *synth)
player->currentfile = NULL;
player->division = 0;
player->send_program_change = 1;
player->miditempo = 480000;
player->miditempo = 500000;
player->deltatime = 4.0;
player->cur_msec = 0;
player->cur_ticks = 0;
@ -1753,7 +1760,7 @@ fluid_player_reset(fluid_player_t *player)
player->ntracks = 0;
player->division = 0;
player->send_program_change = 1;
player->miditempo = 480000;
player->miditempo = 500000;
player->deltatime = 4.0;
return 0;
}

View file

@ -18,10 +18,9 @@
* 02110-1301, USA
*/
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
#include "fluid_phase.h"
#include "fluid_rvoice.h"
#include "fluid_sys.h"
#include "fluid_rvoice_dsp_tables.c"
/* Purpose:

View file

@ -23,7 +23,6 @@
#include "fluid_sys.h"
#include "fluid_rev.h"
#include "fluid_chorus.h"
#include "fluidsynth_priv.h"
#include "fluid_ladspa.h"
#include "fluid_synth.h"

View file

@ -1312,7 +1312,7 @@ new_fluid_preset_zone(char *name)
/* Flag all generators as unused (default, they will be set when they are found
* in the sound font).
* This also sets the generator values to default, but that is of no concern here.*/
fluid_gen_set_default_values(&zone->gen[0]);
fluid_gen_init(&zone->gen[0], NULL);
zone->mod = NULL; /* list of modulators */
zone->linked_mod = NULL; /* List of linked modulators */
return zone;
@ -2411,7 +2411,7 @@ new_fluid_inst_zone(char *name)
zone->range.ignore = FALSE;
/* Flag the generators as unused.
* This also sets the generator values to default, but they will be overwritten anyway, if used.*/
fluid_gen_set_default_values(&zone->gen[0]);
fluid_gen_init(&zone->gen[0], NULL);
zone->mod = NULL; /* list of modulators */
zone->linked_mod = NULL; /* List of linked modulators */
return zone;

View file

@ -29,7 +29,6 @@
#include "fluid_samplecache.h"
#include "fluid_sys.h"
#include "fluidsynth.h"
#include "fluid_list.h"

View file

@ -334,17 +334,23 @@ static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int en
*/
int fluid_is_soundfont(const char *filename)
{
FILE *fp = FLUID_FOPEN(filename, "rb");
FILE *fp;
uint32_t fcc;
int retcode = FALSE;
do
{
if(fp == NULL)
if(!fluid_file_test(filename, G_FILE_TEST_IS_REGULAR))
{
return retcode;
}
// file seems to exist and is a regular file or a symlink to such
if((fp = FLUID_FOPEN(filename, "rb")) == NULL)
{
return retcode;
}
if(FLUID_FREAD(&fcc, sizeof(fcc), 1, fp) != 1)
{
break;

View file

@ -24,7 +24,27 @@
void *default_fopen(const char *path)
{
return FLUID_FOPEN(path, "rb");
FILE* handle;
if(!fluid_file_test(path, G_FILE_TEST_EXISTS))
{
FLUID_LOG(FLUID_ERR, "fluid_sfloader_load(): Unable to load non-existent file. ('%s')", path);
return NULL;
}
if(!fluid_file_test(path, G_FILE_TEST_IS_REGULAR))
{
FLUID_LOG(FLUID_ERR, "fluid_sfloader_load(): Refusing to load non-regular file! ('%s')", path);
return NULL;
}
if((handle = FLUID_FOPEN(path, "rb")) == NULL)
{
FLUID_LOG(FLUID_ERR, "fluid_sfloader_load(): Specified file does not exists or insufficient permissions to open it! ('%s')", path);
return NULL;
}
return handle;
}
int default_fclose(void *handle)

View file

@ -128,7 +128,6 @@ fluid_channel_init_ctrl(fluid_channel_t *chan, int is_all_ctrl_off)
for(i = 0; i < GEN_LAST; i++)
{
chan->gen[i] = 0.0f;
chan->gen_abs[i] = 0;
}
if(is_all_ctrl_off)

View file

@ -129,18 +129,6 @@ struct _fluid_channel_t
* applied to future notes. They are copied to a voice's generators
* in fluid_voice_init(), which calls fluid_gen_init(). */
fluid_real_t gen[GEN_LAST];
/* By default, the NRPN values are relative to the values of the
* generators set in the SoundFont. For example, if the NRPN
* specifies an attack of 100 msec then 100 msec will be added to the
* combined attack time of the sound font and the modulators.
*
* However, it is useful to be able to specify the generator value
* absolutely, completely ignoring the generators of the SoundFont
* and the values of modulators. The gen_abs field, is a boolean
* flag indicating whether the NRPN value is absolute or not.
*/
char gen_abs[GEN_LAST];
};
fluid_channel_t *new_fluid_channel(fluid_synth_t *synth, int num);
@ -200,9 +188,8 @@ void fluid_channel_get_sfont_bank_prog(fluid_channel_t *chan, int *sfont,
#define fluid_channel_legato(_c) ((_c)->cc[LEGATO_SWITCH] >= 64)
#define fluid_channel_sustained(_c) ((_c)->cc[SUSTAIN_SWITCH] >= 64)
#define fluid_channel_sostenuto(_c) ((_c)->cc[SOSTENUTO_SWITCH] >= 64)
#define fluid_channel_set_gen(_c, _n, _v, _a) { (_c)->gen[_n] = _v; (_c)->gen_abs[_n] = _a; }
#define fluid_channel_set_gen(_c, _n, _v) { (_c)->gen[_n] = _v; }
#define fluid_channel_get_gen(_c, _n) ((_c)->gen[_n])
#define fluid_channel_get_gen_abs(_c, _n) ((_c)->gen_abs[_n])
#define fluid_channel_get_min_note_length_ticks(chan) \
((chan)->synth->min_note_length_ticks)

View file

@ -92,14 +92,12 @@ static const fluid_gen_info_t fluid_gen_info[] =
{ GEN_CUSTOM_FILTERQ, 1, 1, 0.0f, 960.0f, 0.0f }
};
/**
* Set an array of generators to their default values.
* @param gen Array of generators (should be #GEN_LAST in size).
* @return Always returns #FLUID_OK
/* fluid_gen_init
*
* Set an array of generators to their initial value
*/
int
fluid_gen_set_default_values(fluid_gen_t *gen)
void
fluid_gen_init(fluid_gen_t *gen, fluid_channel_t *channel)
{
int i;
@ -107,39 +105,9 @@ fluid_gen_set_default_values(fluid_gen_t *gen)
{
gen[i].flags = GEN_UNUSED;
gen[i].mod = 0.0;
gen[i].nrpn = 0.0;
gen[i].nrpn = (channel == NULL) ? 0.0 : fluid_channel_get_gen(channel, i);
gen[i].val = fluid_gen_info[i].def;
}
return FLUID_OK;
}
/* fluid_gen_init
*
* Set an array of generators to their initial value
*/
int
fluid_gen_init(fluid_gen_t *gen, fluid_channel_t *channel)
{
int i;
fluid_gen_set_default_values(gen);
for(i = 0; i < GEN_LAST; i++)
{
gen[i].nrpn = fluid_channel_get_gen(channel, i);
/* This is an extension to the SoundFont standard. More
* documentation is available at the fluid_synth_set_gen2()
* function. */
if(fluid_channel_get_gen_abs(channel, i))
{
gen[i].flags = GEN_ABS_NRPN;
}
}
return FLUID_OK;
}
fluid_real_t fluid_gen_scale(int gen, float value)

View file

@ -31,7 +31,7 @@ typedef struct _fluid_gen_info_t
char nrpn_scale; /* The scale to convert from NRPN (cfr. fluid_gen_map_nrpn()) */
float min; /* The minimum value */
float max; /* The maximum value */
float def; /* The default value (cfr. fluid_gen_set_default_values()) */
float def; /* The default value (cfr. fluid_gen_init()) */
} fluid_gen_info_t;
/*
@ -52,7 +52,6 @@ enum fluid_gen_flags
{
GEN_UNUSED, /**< Generator value is not set */
GEN_SET, /**< Generator value is set */
GEN_ABS_NRPN /**< Generator is an absolute value */
};
#define fluid_gen_set_mod(_gen, _val) { (_gen)->mod = (double) (_val); }
@ -60,8 +59,7 @@ enum fluid_gen_flags
fluid_real_t fluid_gen_scale(int gen, float value);
fluid_real_t fluid_gen_scale_nrpn(int gen, int nrpn);
int fluid_gen_init(fluid_gen_t *gen, fluid_channel_t *channel);
int fluid_gen_set_default_values(fluid_gen_t *gen);
void fluid_gen_init(fluid_gen_t *gen, fluid_channel_t *channel);
#endif /* _FLUID_GEN_H */

View file

@ -109,7 +109,7 @@ static void fluid_synth_update_voice_tuning_LOCAL(fluid_synth_t *synth,
static int fluid_synth_set_tuning_LOCAL(fluid_synth_t *synth, int chan,
fluid_tuning_t *tuning, int apply);
static void fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan,
int param, float value, int absolute);
int param, float value);
static void fluid_synth_stop_LOCAL(fluid_synth_t *synth, unsigned int id);
@ -1107,12 +1107,10 @@ delete_fluid_synth(fluid_synth_t *synth)
* @deprecated This function is not thread-safe and does not work with multiple synths.
* It has been deprecated. It may return "" in a future release and will eventually be removed.
*/
/* FIXME - The error messages are not thread-safe, yet. They are still stored
* in a global message buffer (see fluid_sys.c). */
const char *
fluid_synth_error(fluid_synth_t *synth)
{
return fluid_error();
return "";
}
/**
@ -1696,7 +1694,7 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
if(nrpn_select < GEN_LAST)
{
float val = fluid_gen_scale_nrpn(nrpn_select, data);
fluid_synth_set_gen_LOCAL(synth, channum, nrpn_select, val, FALSE);
fluid_synth_set_gen_LOCAL(synth, channum, nrpn_select, val);
}
chan->nrpn_select = 0; /* Reset to 0 */
@ -1714,12 +1712,12 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */
fluid_synth_set_gen_LOCAL(synth, channum, GEN_FINETUNE,
(data - 8192) / 8192.0 * 100.0, FALSE);
(data - 8192) / 8192.0 * 100.0);
break;
case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */
fluid_synth_set_gen_LOCAL(synth, channum, GEN_COARSETUNE,
value - 64, FALSE);
value - 64);
break;
case RPN_TUNING_PROGRAM_CHANGE:
@ -6119,51 +6117,22 @@ fluid_synth_get_settings(fluid_synth_t *synth)
*/
int fluid_synth_set_gen(fluid_synth_t *synth, int chan, int param, float value)
{
return fluid_synth_set_gen2(synth, chan, param, value, FALSE, FALSE);
}
/**
* Set a SoundFont generator (effect) value on a MIDI channel in real-time.
* @param synth FluidSynth instance
* @param chan MIDI channel number (0 to MIDI channel count - 1)
* @param param SoundFont generator ID (#fluid_gen_type)
* @param value Offset or absolute generator value to assign to the MIDI channel
* @param absolute FALSE to assign a relative value, TRUE to assign an absolute value
* @param normalized FALSE if value is specified in the native units of the generator,
* TRUE to take the value as a 0.0-1.0 range and apply it to the valid
* generator effect range (scaled and shifted as necessary).
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* This function allows for setting all effect parameters in real time on a
* MIDI channel. Setting absolute to non-zero will cause the value to override
* any generator values set in the instruments played on the MIDI channel.
* See SoundFont 2.01 spec, paragraph 8.1.3, page 48 for details on SoundFont
* generator parameters and valid ranges.
*/
int
fluid_synth_set_gen2(fluid_synth_t *synth, int chan, int param,
float value, int absolute, int normalized)
{
float v;
fluid_return_val_if_fail(param >= 0 && param < GEN_LAST, FLUID_FAILED);
FLUID_API_ENTRY_CHAN(FLUID_FAILED);
v = normalized ? fluid_gen_scale(param, value) : value;
fluid_synth_set_gen_LOCAL(synth, chan, param, v, absolute);
fluid_synth_set_gen_LOCAL(synth, chan, param, value);
FLUID_API_RETURN(FLUID_OK);
}
/* Synthesis thread local set gen function */
static void
fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan, int param, float value,
int absolute)
fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan, int param, float value)
{
fluid_voice_t *voice;
int i;
fluid_channel_set_gen(synth->channel[chan], param, value, absolute);
fluid_channel_set_gen(synth->channel[chan], param, value);
for(i = 0; i < synth->polyphony; i++)
{
@ -6171,7 +6140,7 @@ fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan, int param, float value
if(fluid_voice_get_channel(voice) == chan)
{
fluid_voice_set_param(voice, param, value, absolute);
fluid_voice_set_param(voice, param, value);
}
}
}

View file

@ -209,9 +209,6 @@ void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer
void fluid_synth_process_event_queue(fluid_synth_t *synth);
int fluid_synth_set_gen2(fluid_synth_t *synth, int chan,
int param, float value,
int absolute, int normalized);
/*
* misc
*/

View file

@ -20,7 +20,6 @@
#include "fluid_tuning.h"
#include "fluidsynth_priv.h"
#include "fluid_sys.h"

View file

@ -18,7 +18,7 @@
* 02110-1301, USA
*/
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
#include "fluid_voice.h"
#include "fluid_mod.h"
#include "fluid_chan.h"
@ -428,17 +428,7 @@ fluid_voice_gen_get(fluid_voice_t *voice, int gen)
fluid_real_t fluid_voice_gen_value(const fluid_voice_t *voice, int num)
{
/* This is an extension to the SoundFont standard. More
* documentation is available at the fluid_synth_set_gen2()
* function. */
if(voice->gen[num].flags == GEN_ABS_NRPN)
{
return (fluid_real_t) voice->gen[num].nrpn;
}
else
{
return (fluid_real_t)(voice->gen[num].val + voice->gen[num].mod + voice->gen[num].nrpn);
}
return (fluid_real_t)(voice->gen[num].val + voice->gen[num].mod + voice->gen[num].nrpn);
}
/*
@ -605,7 +595,7 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t *voice)
* - Add the output value to the modulation value of the generator.
*
* Note: The generators have been initialized with
* fluid_gen_set_default_values.
* fluid_gen_init().
*/
/* The voice contains unlinked modulators + possible complex linked modulators.
@ -1951,10 +1941,10 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t *voice)
return lower_bound;
}
int fluid_voice_set_param(fluid_voice_t *voice, int gen, fluid_real_t nrpn_value, int abs)
int fluid_voice_set_param(fluid_voice_t *voice, int gen, fluid_real_t nrpn_value)
{
voice->gen[gen].nrpn = nrpn_value;
voice->gen[gen].flags = (abs) ? GEN_ABS_NRPN : GEN_SET;
voice->gen[gen].flags = GEN_SET;
fluid_voice_update_param(voice, gen);
return FLUID_OK;
}

View file

@ -30,7 +30,6 @@
#include "fluid_lfo.h"
#include "fluid_rvoice.h"
#include "fluid_rvoice_event.h"
#include "fluid_sys.h"
#define NO_CHANNEL 0xff
@ -131,7 +130,7 @@ int fluid_voice_modulate(fluid_voice_t *voice, int cc, int ctrl);
int fluid_voice_modulate_all(fluid_voice_t *voice);
/** Set the NRPN value of a generator. */
int fluid_voice_set_param(fluid_voice_t *voice, int gen, fluid_real_t value, int abs);
int fluid_voice_set_param(fluid_voice_t *voice, int gen, fluid_real_t value);
/** Set the gain. */

View file

@ -19,6 +19,7 @@
*/
#include "fluid_conv.h"
#include "fluid_sys.h"
#include "fluid_conv_tables.c"
/*

View file

@ -31,7 +31,7 @@
* MT safe
*/
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
#include "fluid_hash.h"
#include "fluid_list.h"

View file

@ -24,7 +24,7 @@
*/
#include "fluid_ringbuffer.h"
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
/**

View file

@ -457,7 +457,7 @@ fluid_settings_set(fluid_settings_t *settings, const char *name, fluid_setting_n
else
{
/* path ends prematurely */
FLUID_LOG(FLUID_WARN, "'%s' is not a node. Name of the setting was '%s'", tokens[n], name);
FLUID_LOG(FLUID_ERR, "'%s' is not a node. Name of the setting was '%s'", tokens[n], name);
return FLUID_FAILED;
}
@ -550,7 +550,7 @@ fluid_settings_register_str(fluid_settings_t *settings, const char *name, const
}
else
{
FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
FLUID_LOG(FLUID_ERR, "Failed to register string setting '%s' as it already exists with a different type", name);
}
}
@ -612,7 +612,7 @@ fluid_settings_register_num(fluid_settings_t *settings, const char *name, double
else
{
/* type mismatch */
FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
FLUID_LOG(FLUID_ERR, "Failed to register numeric setting '%s' as it already exists with a different type", name);
}
}
@ -674,7 +674,7 @@ fluid_settings_register_int(fluid_settings_t *settings, const char *name, int de
else
{
/* type mismatch */
FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
FLUID_LOG(FLUID_ERR, "Failed to register int setting '%s' as it already exists with a different type", name);
}
}
@ -936,6 +936,7 @@ fluid_settings_setstr(fluid_settings_t *settings, const char *name, const char *
if((fluid_settings_get(settings, name, &node) != FLUID_OK)
|| (node->type != FLUID_STR_TYPE))
{
FLUID_LOG(FLUID_ERR, "Unknown string setting '%s'", name);
goto error_recovery;
}
@ -1313,6 +1314,7 @@ fluid_settings_setnum(fluid_settings_t *settings, const char *name, double val)
if((fluid_settings_get(settings, name, &node) != FLUID_OK)
|| (node->type != FLUID_NUM_TYPE))
{
FLUID_LOG(FLUID_ERR, "Unknown numeric setting '%s'", name);
goto error_recovery;
}
@ -1320,7 +1322,7 @@ fluid_settings_setnum(fluid_settings_t *settings, const char *name, double val)
if(val < setting->min || val > setting->max)
{
FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name);
FLUID_LOG(FLUID_ERR, "requested set value for '%s' out of range", name);
goto error_recovery;
}
@ -1497,6 +1499,7 @@ fluid_settings_setint(fluid_settings_t *settings, const char *name, int val)
if((fluid_settings_get(settings, name, &node) != FLUID_OK)
|| (node->type != FLUID_INT_TYPE))
{
FLUID_LOG(FLUID_ERR, "Unknown integer parameter '%s'", name);
goto error_recovery;
}
@ -1504,7 +1507,7 @@ fluid_settings_setint(fluid_settings_t *settings, const char *name, int val)
if(val < setting->min || val > setting->max)
{
FLUID_LOG(FLUID_DBG, "requested set value for %s out of range", name);
FLUID_LOG(FLUID_ERR, "requested set value for setting '%s' out of range", name);
goto error_recovery;
}

View file

@ -30,6 +30,12 @@
#include "fluid_rtkit.h"
#endif
#if HAVE_PTHREAD_H && !defined(WIN32)
// Do not include pthread on windows. It includes winsock.h, which collides with ws2tcpip.h from fluid_sys.h
// It isn't need on Windows anyway.
#include <pthread.h>
#endif
/* WIN32 HACK - Flag used to differentiate between a file descriptor and a socket.
* Should work, so long as no SOCKET or file descriptor ends up with this bit set. - JG */
#ifdef _WIN32
@ -73,9 +79,6 @@ struct _fluid_server_socket_t
static int fluid_istream_gets(fluid_istream_t in, char *buf, int len);
static char fluid_errbuf[512]; /* buffer for error message */
static fluid_log_function_t fluid_log_function[LAST_LOG_LEVEL] =
{
fluid_default_log_function,
@ -169,20 +172,20 @@ fluid_default_log_function(int level, const char *message, void *data)
int
fluid_log(int level, const char *fmt, ...)
{
fluid_log_function_t fun = NULL;
va_list args;
va_start(args, fmt);
FLUID_VSNPRINTF(fluid_errbuf, sizeof(fluid_errbuf), fmt, args);
va_end(args);
if((level >= 0) && (level < LAST_LOG_LEVEL))
{
fun = fluid_log_function[level];
fluid_log_function_t fun = fluid_log_function[level];
if(fun != NULL)
{
(*fun)(level, fluid_errbuf, fluid_log_user_data[level]);
char errbuf[1024];
va_list args;
va_start(args, fmt);
FLUID_VSNPRINTF(errbuf, sizeof(errbuf), fmt, args);
va_end(args);
(*fun)(level, errbuf, fluid_log_user_data[level]);
}
}
@ -265,15 +268,6 @@ char *fluid_strtok(char **str, char *delim)
return token;
}
/*
* fluid_error
*/
char *
fluid_error()
{
return fluid_errbuf;
}
/**
* Suspend the execution of the current thread for the specified amount of time.
* @param milliseconds to wait.
@ -939,7 +933,7 @@ fluid_thread_t *
new_fluid_thread(const char *name, fluid_thread_func_t func, void *data, int prio_level, int detach)
{
GThread *thread;
fluid_thread_info_t *info;
fluid_thread_info_t *info = NULL;
GError *err = NULL;
g_return_val_if_fail(func != NULL, NULL);
@ -976,25 +970,21 @@ new_fluid_thread(const char *name, fluid_thread_func_t func, void *data, int pri
#endif
}
else
{
#if NEW_GLIB_THREAD_API
else
{
thread = g_thread_try_new(name, (GThreadFunc)func, data, &err);
}
#else
else
{
thread = g_thread_create((GThreadFunc)func, data, detach == FALSE, &err);
}
#endif
}
if(!thread)
{
FLUID_LOG(FLUID_ERR, "Failed to create the thread: %s",
fluid_gerror_message(err));
g_clear_error(&err);
FLUID_FREE(info);
return NULL;
}
@ -1343,12 +1333,12 @@ fluid_ostream_printf(fluid_ostream_t out, const char *format, ...)
/* Handle write differently depending on if its a socket or file descriptor */
if(!(out & FLUID_SOCKET_FLAG))
{
return write(out, buf, FLUID_STRLEN(buf));
return write(out, buf, (unsigned int)FLUID_STRLEN(buf));
}
#ifdef NETWORK_SUPPORT
/* Socket */
retval = send(out & ~FLUID_SOCKET_FLAG, buf, FLUID_STRLEN(buf), 0);
retval = send(out & ~FLUID_SOCKET_FLAG, buf, (int)FLUID_STRLEN(buf), 0);
return retval != SOCKET_ERROR ? retval : -1;
#else
return -1;

View file

@ -19,18 +19,21 @@
*/
/**
This header contains a bunch of (mostly) system and machine
dependent functions:
- timers
- current time in milliseconds and microseconds
- debug logging
- profiling
- memory locking
- checking for floating point exceptions
/*
* @file fluid_sys.h
*
* This header contains a bunch of (mostly) system and machine
* dependent functions:
*
* - timers
* - current time in milliseconds and microseconds
* - debug logging
* - profiling
* - memory locking
* - checking for floating point exceptions
*
* fluidsynth's wrapper OSAL so to say; include it in .c files, be careful to include
* it in fluidsynth's private header files (see comment in fluid_coreaudio.c)
*/
#ifndef _FLUID_SYS_H
@ -38,6 +41,116 @@
#include "fluidsynth_priv.h"
#if HAVE_MATH_H
#include <math.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_STDARG_H
#include <stdarg.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_OPENMP
#include <omp.h>
#endif
#if HAVE_IO_H
#include <io.h> // _open(), _close(), read(), write() on windows
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
/** Integer types */
#if HAVE_STDINT_H
#include <stdint.h>
#else
/* Assume GLIB types */
typedef gint8 int8_t;
typedef guint8 uint8_t;
typedef gint16 int16_t;
typedef guint16 uint16_t;
typedef gint32 int32_t;
typedef guint32 uint32_t;
typedef gint64 int64_t;
typedef guint64 uint64_t;
#endif
#if defined(WIN32) && HAVE_WINDOWS_H
#include <winsock2.h>
#include <ws2tcpip.h> /* Provides also socklen_t */
/* WIN32 special defines */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#ifdef _MSC_VER
#pragma warning(disable : 4244)
#pragma warning(disable : 4101)
#pragma warning(disable : 4305)
#pragma warning(disable : 4996)
#endif
#endif
/* Darwin special defines (taken from config_macosx.h) */
#ifdef DARWIN
# define MACINTOSH
# define __Types__
#endif
#ifdef LADSPA
#include <gmodule.h>
#endif
@ -52,26 +165,12 @@
*/
#define fluid_gerror_message(err) ((err) ? err->message : "No error details")
/* Misc */
#if defined(__INTEL_COMPILER)
#define FLUID_RESTRICT restrict
#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#define FLUID_RESTRICT __restrict__
#elif defined(_MSC_VER) && _MSC_VER >= 1400
#define FLUID_RESTRICT __restrict
#else
#warning "Dont know how this compiler handles restrict pointers, refuse to use them."
#define FLUID_RESTRICT
#endif
#define FLUID_INLINE inline
#define FLUID_POINTER_TO_UINT GPOINTER_TO_UINT
#define FLUID_UINT_TO_POINTER GUINT_TO_POINTER
#define FLUID_POINTER_TO_INT GPOINTER_TO_INT
#define FLUID_INT_TO_POINTER GINT_TO_POINTER
#define FLUID_N_ELEMENTS(struct) (sizeof (struct) / sizeof (struct[0]))
#define FLUID_MEMBER_SIZE(struct, member) ( sizeof (((struct *)0)->member) )
#define FLUID_IS_BIG_ENDIAN (G_BYTE_ORDER == G_BIG_ENDIAN)
#define FLUID_LE32TOH(x) GINT32_FROM_LE(x)
@ -85,17 +184,6 @@
(uint32_t)(((uint32_t)(_d) << 24) | ((uint32_t)(_c) << 16) | ((uint32_t)(_b) << 8) | (uint32_t)(_a))
#endif
#define fluid_return_if_fail(cond) \
if(cond) \
; \
else \
return
#define fluid_return_val_if_fail(cond, val) \
fluid_return_if_fail(cond) (val)
/*
* Utility functions
*/
@ -356,11 +444,15 @@ typedef GModule fluid_module_t;
/* Sockets and I/O */
fluid_istream_t fluid_get_stdin(void);
fluid_ostream_t fluid_get_stdout(void);
int fluid_istream_readline(fluid_istream_t in, fluid_ostream_t out, char *prompt, char *buf, int len);
int fluid_ostream_printf(fluid_ostream_t out, const char *format, ...);
#if defined(WIN32)
typedef SOCKET fluid_socket_t;
#else
typedef int fluid_socket_t;
#endif
/* The function should return 0 if no error occured, non-zero
otherwise. If the function return non-zero, the socket will be
closed by the server. */
@ -374,25 +466,26 @@ fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock);
fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock);
/* File access */
#define fluid_stat(_filename, _statbuf) g_stat((_filename), (_statbuf))
#if !GLIB_CHECK_VERSION(2, 26, 0)
/* GStatBuf has not been introduced yet, manually typedef to what they had at that time:
* https://github.com/GNOME/glib/blob/e7763678b56e3be073cc55d707a6e92fc2055ee0/glib/gstdio.h#L98-L115
*/
#if defined(WIN32) || HAVE_WINDOWS_H // somehow reliably mock G_OS_WIN32??
#if defined (_MSC_VER) && !defined(_WIN64)
typedef struct _stat32 fluid_stat_buf_t;
#else
typedef struct _stat fluid_stat_buf_t;
#endif
// Any effort from our side to reliably mock GStatBuf on Windows is in vain. E.g. glib-2.16 is broken as it uses struct stat rather than struct _stat32 on Win x86.
// Disable it (the user has been warned by cmake).
#undef fluid_stat
#define fluid_stat(_filename, _statbuf) (-1)
typedef struct _fluid_stat_buf_t{int st_mtime;} fluid_stat_buf_t;
#else
/* posix, OS/2, etc. */
typedef struct stat fluid_stat_buf_t;
/* posix, OS/2, etc. */
typedef struct stat fluid_stat_buf_t;
#endif
#else
typedef GStatBuf fluid_stat_buf_t;
#endif
#define fluid_stat(_filename, _statbuf) g_stat((_filename), (_statbuf))
#define fluid_file_test g_file_test
/* Profiling */
#if WITH_PROFILING

View file

@ -18,6 +18,13 @@
* 02110-1301, USA
*/
/*
* @file fluidsynth_priv.h
*
* lightweight part of fluid_sys.h, containing forward declarations of fluidsynth's private types and private macros
*
* include this one file in fluidsynth's private header files
*/
#ifndef _FLUIDSYNTH_PRIV_H
#define _FLUIDSYNTH_PRIV_H
@ -26,136 +33,18 @@
#include "config.h"
#if defined(__POWERPC__) && !(defined(__APPLE__) && defined(__MACH__))
#include "config_maxmsp43.h"
#if HAVE_STDLIB_H
#include <stdlib.h> // malloc, free
#endif
#if HAVE_STDIO_H
#include <stdio.h> // printf
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#if HAVE_MATH_H
#include <math.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_STDARG_H
#include <stdarg.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_PTHREAD_H
#include <pthread.h>
#endif
#if HAVE_OPENMP
#include <omp.h>
#endif
#if HAVE_IO_H
#include <io.h> // _open(), _close(), read(), write() on windows
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
/** Integer types */
#if HAVE_STDINT_H
#include <stdint.h>
#else
/* Assume GLIB types */
typedef gint8 int8_t;
typedef guint8 uint8_t;
typedef gint16 int16_t;
typedef guint16 uint16_t;
typedef gint32 int32_t;
typedef guint32 uint32_t;
typedef gint64 int64_t;
typedef guint64 uint64_t;
#endif
#if defined(WIN32) && HAVE_WINDOWS_H
#include <winsock2.h>
#include <ws2tcpip.h> /* Provides also socklen_t */
/* WIN32 special defines */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#ifdef _MSC_VER
#pragma warning(disable : 4244)
#pragma warning(disable : 4101)
#pragma warning(disable : 4305)
#pragma warning(disable : 4996)
#endif
#endif
/* Darwin special defines (taken from config_macosx.h) */
#ifdef DARWIN
# define MACINTOSH
# define __Types__
#endif
#include "fluidsynth.h"
@ -171,13 +60,6 @@ typedef float fluid_real_t;
typedef double fluid_real_t;
#endif
#if defined(WIN32)
typedef SOCKET fluid_socket_t;
#else
typedef int fluid_socket_t;
#endif
#if defined(SUPPORTS_VLA)
# define FLUID_DECLARE_VLA(_type, _name, _len) \
_type _name[_len]
@ -243,7 +125,6 @@ typedef void (*fluid_rvoice_function_t)(void *obj, const fluid_rvoice_param_t pa
*
* SYSTEM INTERFACE
*/
typedef FILE *fluid_file;
#define FLUID_MALLOC(_n) malloc(_n)
#define FLUID_REALLOC(_p,_n) realloc(_p,_n)
@ -352,6 +233,30 @@ do { strncpy(_dst,_src,_n); \
#define FLUID_LIKELY G_LIKELY
#define FLUID_UNLIKELY G_UNLIKELY
char *fluid_error(void);
/* Misc */
#if defined(__INTEL_COMPILER)
#define FLUID_RESTRICT restrict
#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#define FLUID_RESTRICT __restrict__
#elif defined(_MSC_VER) && _MSC_VER >= 1400
#define FLUID_RESTRICT __restrict
#else
#warning "Dont know how this compiler handles restrict pointers, refuse to use them."
#define FLUID_RESTRICT
#endif
#define FLUID_N_ELEMENTS(struct) (sizeof (struct) / sizeof (struct[0]))
#define FLUID_MEMBER_SIZE(struct, member) ( sizeof (((struct *)0)->member) )
#define fluid_return_if_fail(cond) \
if(cond) \
; \
else \
return
#define fluid_return_val_if_fail(cond, val) \
fluid_return_if_fail(cond) (val)
#endif /* _FLUIDSYNTH_PRIV_H */

View file

@ -2,7 +2,7 @@
#include "fluidsynth.h"
#include "sfloader/fluid_sfont.h"
#include "sfloader/fluid_defsfont.h"
#include "utils/fluidsynth_priv.h"
#include "utils/fluid_sys.h"
#include "utils/fluid_list.h"
// load our sf2 and sf3 test soundfonts, with and without dynamic sample loading

View file

@ -1,7 +1,7 @@
#include "test.h"
#include "fluidsynth.h" // use local fluidsynth header
#include "utils/fluidsynth_priv.h"
#include "utils/fluid_sys.h"
// this test aims to make sure that sample data used by multiple synths is not freed

View file

@ -4,7 +4,7 @@
#include "synth/fluid_synth.h"
#include "synth/fluid_voice.h"
#include "rvoice/fluid_rvoice.h"
#include "utils/fluidsynth_priv.h"
#include "utils/fluid_sys.h"
static void verify_sample_rate(fluid_synth_t *synth, int expected_srate)
{

View file

@ -1,7 +1,7 @@
#include "test.h"
#include "fluidsynth.h"
#include "sfloader/fluid_sfont.h"
#include "utils/fluidsynth_priv.h"
#include "utils/fluid_sys.h"
int main(void)

View file

@ -2,7 +2,7 @@
#include "test.h"
#include "fluidsynth.h"
#include "sfloader/fluid_sfont.h"
#include "utils/fluidsynth_priv.h"
#include "utils/fluid_sys.h"
// this tests the soundfont loading API of the synth.

View file

@ -1,6 +1,6 @@
#include "test.h"
#include "utils/fluidsynth_priv.h"
#include "utils/fluid_sys.h"
// this test makes sure FLUID_SNPRINTF uses a proper C99 compliant implementation