mirror of
https://github.com/ZDoom/ZMusic.git
synced 2025-04-07 01:42:11 +00:00
Compare commits
68 commits
Author | SHA1 | Date | |
---|---|---|---|
|
6928b8609d | ||
|
f6facdaa68 | ||
|
7e369774d5 | ||
|
4cc05f7584 | ||
|
628cd49221 | ||
|
7062053c04 | ||
|
3944bbc756 | ||
|
519b76b6e7 | ||
|
89f3d65734 | ||
|
6c5cf572aa | ||
|
b71e1a2639 | ||
|
fd03bca3ff | ||
|
05601a9ee1 | ||
|
1a1499d20e | ||
|
0b9d08d243 | ||
|
7307ecfc93 | ||
|
50ad730c38 | ||
|
b31b43efd0 | ||
|
7476a18975 | ||
|
3eabbd3598 | ||
|
5ce525efc7 | ||
|
26c889088d | ||
|
33de9d93fc | ||
|
3e1deba3a2 | ||
|
b5bd930369 | ||
|
576b7da64d | ||
|
e970fb15f0 | ||
|
1d5e34466d | ||
|
0a7dc86a55 | ||
|
a036a16450 | ||
|
fc30a8f1e4 | ||
|
22ab5b210c | ||
|
7695852856 | ||
|
75d2994b4b | ||
|
faa997b986 | ||
|
5bd573478b | ||
|
36a5308de1 | ||
|
1dda85bbe1 | ||
|
7a7ee92ff8 | ||
|
4725517832 | ||
|
8ebcd430b2 | ||
|
dad5c5a765 | ||
|
da12efde2b | ||
|
43203cb207 | ||
|
47475495f4 | ||
|
6da5525ba8 | ||
|
304de9b0aa | ||
|
c5b6c0d317 | ||
|
9fbc2ec095 | ||
|
ad00418fec | ||
|
a3b79ca8f6 | ||
|
f4cfb36f4a | ||
|
6b5aebf6a3 | ||
|
8375c06737 | ||
|
5ac16461ad | ||
|
592bb9126b | ||
|
ae70ea40f2 | ||
|
db05f4a8ef | ||
|
3696d8fa27 | ||
|
dd76ab1fce | ||
|
d8e6e28879 | ||
|
95e6bfcd8c | ||
|
514ef6b528 | ||
|
fee3bc352e | ||
|
2b291705f2 | ||
|
0ee7aa9a5b | ||
|
69692696ec | ||
|
2cae98b442 |
396 changed files with 141957 additions and 28316 deletions
.github/workflows
CMakeLists.txtREADME.mdcmake
include
licenses
source
CMakeLists.txt
data
decoder
mididevices
mididevice.hmusic_adlmidi_mididevice.cppmusic_alsa_mididevice.cppmusic_alsa_state.cppmusic_base_mididevice.cppmusic_fluidsynth_mididevice.cppmusic_opl_mididevice.cppmusic_opnmidi_mididevice.cppmusic_softsynth_mididevice.cppmusic_timidity_mididevice.cppmusic_timiditypp_mididevice.cppmusic_wavewriter_mididevice.cppmusic_wildmidi_mididevice.cppmusic_win_mididevice.cpp
midisources
musicformats
streamsources
music_dumb.cppmusic_gme.cppmusic_libsndfile.cppmusic_libxmp.cppmusic_opl.cppmusic_xa.cppstreamsource.h
zmusic
thirdparty
CMakeLists.txt
adlmidi
adlmidi.cppadlmidi.hadlmidi_bankmap.hadlmidi_bankmap.tccadlmidi_cvt.hppadlmidi_db.hadlmidi_load.cppadlmidi_midiplay.cppadlmidi_midiplay.hppadlmidi_opl3.cppadlmidi_opl3.hppadlmidi_private.cppadlmidi_private.hppadlmidi_ptr.hppfile_reader.hppinst_db.cppoplinst.h
chips
common
dosbox_opl3.cppdosbox_opl3.hjava_opl3.cppjava_opl3.hnuked_opl3.cppnuked_opl3.hnuked_opl3_v174.cppnuked_opl3_v174.hopal_opl3.cppopal_opl3.hopl_chip_base.hwopl
fluidsynth
114
.github/workflows/continuous_integration.yml
vendored
114
.github/workflows/continuous_integration.yml
vendored
|
@ -10,80 +10,65 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
name: "Visual Studio - Release",
|
||||
os: windows-2019,
|
||||
build_type: "Release"
|
||||
}
|
||||
- {
|
||||
name: "Visual Studio - Debug",
|
||||
os: windows-2019,
|
||||
build_type: "Debug"
|
||||
}
|
||||
- {
|
||||
name: "macOS Clang - Dynamic Deps",
|
||||
os: macos-10.15,
|
||||
build_type: "Release"
|
||||
}
|
||||
- {
|
||||
name: "macOS Clang - Static Deps",
|
||||
os: macos-10.15,
|
||||
build_type: "Release",
|
||||
extra_options: "-DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF"
|
||||
}
|
||||
- {
|
||||
name: "Linux GCC - Dynamic Deps",
|
||||
os: ubuntu-20.04,
|
||||
build_type: "Release"
|
||||
}
|
||||
- {
|
||||
name: "Linux GCC - Static Deps",
|
||||
os: ubuntu-20.04,
|
||||
build_type: "Release",
|
||||
extra_options: "-DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF"
|
||||
}
|
||||
- {
|
||||
name: "Linux Clang - Dynamic Deps",
|
||||
os: ubuntu-20.04,
|
||||
build_type: "Release",
|
||||
extra_options: "-DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++"
|
||||
}
|
||||
- {
|
||||
name: "Linux Clang - Static Deps",
|
||||
os: ubuntu-20.04,
|
||||
build_type: "Release",
|
||||
extra_options: "-DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF"
|
||||
}
|
||||
- name: Visual Studio - Release
|
||||
os: windows-latest
|
||||
build_type: Release
|
||||
|
||||
- name: Visual Studio - Debug
|
||||
os: windows-latest
|
||||
build_type: Debug
|
||||
|
||||
- name: macOS Clang - Dynamic Deps
|
||||
os: macos-latest
|
||||
build_type: Release
|
||||
|
||||
- name: macOS Clang - Static Deps
|
||||
os: macos-latest
|
||||
build_type: Release
|
||||
cmake_options: -DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF
|
||||
deps_cmd: brew install libsndfile mpg123
|
||||
|
||||
- name: Linux GCC - Dynamic Deps
|
||||
os: ubuntu-latest
|
||||
build_type: Release
|
||||
deps_cmd: sudo apt update && sudo apt install libglib2.0-dev
|
||||
|
||||
- name: Linux GCC - Static Deps
|
||||
os: ubuntu-latest
|
||||
build_type: Release
|
||||
cmake_options: -DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF
|
||||
deps_cmd: sudo apt update && sudo apt install libasound2-dev libglib2.0-dev libmpg123-dev libsndfile1-dev
|
||||
|
||||
- name: Linux Clang - Dynamic Deps
|
||||
os: ubuntu-latest
|
||||
build_type: Release
|
||||
cmake_options: -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
|
||||
deps_cmd: sudo apt update && sudo apt install libglib2.0-dev
|
||||
|
||||
- name: Linux Clang - Static Deps
|
||||
os: ubuntu-latest
|
||||
build_type: Release
|
||||
cmake_options: -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF
|
||||
deps_cmd: sudo apt update && sudo apt install libasound2-dev libglib2.0-dev libmpg123-dev libsndfile1-dev
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ runner.os }}" == 'Linux' ]]; then
|
||||
sudo apt update
|
||||
sudo apt install libasound2-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev
|
||||
elif [[ "${{ runner.os }}" == 'macOS' ]]; then
|
||||
brew install fluidsynth mpg123 libsndfile
|
||||
fi
|
||||
${{ matrix.config.deps_cmd }}
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} -DCMAKE_INSTALL_PREFIX=../build_install ${{ matrix.config.extra_options }} ..
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} -DCMAKE_INSTALL_PREFIX=./build_install ${{ matrix.config.cmake_options }} .
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
if [[ "${{ runner.os }}" == 'Windows' ]]; then
|
||||
cmake --build . --target install --config ${{ matrix.config.build_type }} -- -maxcpucount -verbosity:minimal
|
||||
else
|
||||
cmake --build . --target install -- --jobs=2 --keep-going
|
||||
fi
|
||||
export MAKEFLAGS=--keep-going
|
||||
cmake --build build --target install --config ${{ matrix.config.build_type }} --parallel 3
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
|
@ -92,7 +77,7 @@ jobs:
|
|||
mkdir build
|
||||
cd build
|
||||
declare -x PREFIX=`pwd`/../../../build_install
|
||||
cmake -DCMAKE_PREFIX_PATH=${PREFIX} ${{ matrix.config.extra_options }} ..
|
||||
cmake -DCMAKE_PREFIX_PATH=${PREFIX} ${{ matrix.config.cmake_options }} ..
|
||||
cmake --build . --config ${{ matrix.config.build_type }}
|
||||
if [[ "${{ runner.os }}" == 'macOS' ]]; then
|
||||
declare -x DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${PREFIX}
|
||||
|
@ -103,3 +88,10 @@ jobs:
|
|||
else
|
||||
./list_midi_devices
|
||||
fi
|
||||
|
||||
- name: Upload Install Directory
|
||||
if: false # Remove this line to upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.config.name }}
|
||||
path: build_install
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
cmake_minimum_required(VERSION 3.13...3.19)
|
||||
|
||||
if (VCPKG_LIBSNDFILE)
|
||||
list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-libsndfile")
|
||||
endif()
|
||||
|
||||
project(ZMusic
|
||||
VERSION 1.1.4
|
||||
VERSION 1.1.14
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
if (VCPKG_TOOLCHAIN)
|
||||
if(VCPKG_TARGET_TRIPLET MATCHES "-static$")
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
|
||||
option(VCPKG_LIBSNDFILE "Import libsndfile from vcpkg" OFF)
|
||||
else()
|
||||
set(VCPKG_MANIFEST_FEATURES)
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
@ -12,12 +27,28 @@ include(ZUtility)
|
|||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# If building standalone give the user the option to build shared or static.
|
||||
# Otherwise the vendoring project should set the variable.
|
||||
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
# This project is being built standalone
|
||||
|
||||
# Give user option to build shared or static
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
elseif(NOT DEFINED BUILD_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
|
||||
# Enable install rules
|
||||
set(ZMUSIC_INSTALL ON)
|
||||
else()
|
||||
# This project is being vendored by another project, set option default if
|
||||
# the parent project doesn't provide them.
|
||||
|
||||
if(NOT DEFINED BUILD_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif()
|
||||
|
||||
# Although install rules can be avoided with EXCLUDE_FROM_ALL on
|
||||
# add_subdirectory, the EXPORT rules may place certain usage requirements on
|
||||
# targets shared between the two projects.
|
||||
if(NOT DEFINED ZMUSIC_INSTALL)
|
||||
set(ZMUSIC_INSTALL OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
|
@ -97,6 +128,11 @@ endif()
|
|||
# Initialize our list of find_package dependencies for configure_package_config_file
|
||||
set(ZMUSIC_PACKAGE_DEPENDENCIES "" CACHE INTERNAL "")
|
||||
|
||||
if (WIN32 AND MINGW)
|
||||
add_compile_definitions(-D_UNICODE -DUNICODE)
|
||||
add_compile_definitions(-D__USE_MINGW_ANSI_STDIO=1)
|
||||
endif()
|
||||
|
||||
add_subdirectory(thirdparty)
|
||||
add_subdirectory(source)
|
||||
|
||||
|
@ -110,10 +146,12 @@ configure_package_config_file(
|
|||
${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
|
||||
)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic
|
||||
COMPONENT devel
|
||||
)
|
||||
if(ZMUSIC_INSTALL)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic
|
||||
COMPONENT devel
|
||||
)
|
||||
endif()
|
||||
|
||||
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(CPACK_PACKAGE_CONTACT "First Last <example@example.com>" CACHE STRING "Contact info for archive maintainer.")
|
||||
|
|
|
@ -9,8 +9,8 @@ Compile instructions are pretty simple for most systems.
|
|||
git clone https://github.com/coelckers/ZMusic.git
|
||||
mkdir ZMusic/build
|
||||
cd ZMusic/build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
cmake . --build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
On Unix/Linux you may also supply `sudo make install` in the build folder to push the compiled library directly into the file system so that it can be found by the previously mentioned projects.
|
||||
|
|
|
@ -120,10 +120,18 @@ function(require_strnicmp Tgt Visibility)
|
|||
endif()
|
||||
endfunction()
|
||||
|
||||
function(use_fast_math Tgt)
|
||||
if(MSVC)
|
||||
set_property( TARGET "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "/fp:fast" )
|
||||
elseif(ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE)
|
||||
set_property( TARGET "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "-ffast-math" "-ffp-contract=fast" )
|
||||
endif()
|
||||
function(use_fast_math)
|
||||
foreach(Tgt IN LISTS ARGN)
|
||||
if(TARGET Tgt)
|
||||
set(TgtType TARGET)
|
||||
else()
|
||||
set(TgtType SOURCE)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set_property("${TgtType}" "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "/fp:fast")
|
||||
elseif(COMPILER_IS_GNUCXX_COMPATIBLE)
|
||||
set_property("${TgtType}" "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "-ffast-math" "-ffp-contract=fast")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
|
|
@ -67,7 +67,8 @@ typedef struct SoundStreamInfo_
|
|||
typedef enum SampleType_
|
||||
{
|
||||
SampleType_UInt8,
|
||||
SampleType_Int16
|
||||
SampleType_Int16,
|
||||
SampleType_Float32
|
||||
} SampleType;
|
||||
|
||||
typedef enum ChannelConfig_
|
||||
|
@ -76,6 +77,15 @@ typedef enum ChannelConfig_
|
|||
ChannelConfig_Stereo
|
||||
} ChannelConfig;
|
||||
|
||||
typedef struct SoundStreamInfoEx_
|
||||
{
|
||||
int mBufferSize; // If mBufferSize is 0, the song doesn't use streaming but plays through a different interface.
|
||||
int mSampleRate;
|
||||
SampleType mSampleType;
|
||||
ChannelConfig mChannelConfig;
|
||||
} SoundStreamInfoEx;
|
||||
|
||||
|
||||
typedef enum EIntConfigKey_
|
||||
{
|
||||
zmusic_adl_chips_count,
|
||||
|
@ -141,6 +151,7 @@ typedef enum EIntConfigKey_
|
|||
|
||||
zmusic_snd_mididevice,
|
||||
zmusic_snd_outputrate,
|
||||
zmusic_mod_preferredplayer,
|
||||
|
||||
NUM_ZMUSIC_INT_CONFIGS
|
||||
} EIntConfigKey;
|
||||
|
@ -264,14 +275,14 @@ typedef struct ZMusicConfigurationSetting_
|
|||
|
||||
|
||||
#ifndef ZMUSIC_INTERNAL
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(ZMUSIC_STATIC)
|
||||
#define DLL_IMPORT _declspec(dllimport)
|
||||
#else // !_MSC_VER
|
||||
#else
|
||||
#define DLL_IMPORT
|
||||
#endif // _MSC_VER
|
||||
#endif
|
||||
// Note that the internal 'class' definitions are not C compatible!
|
||||
typedef struct { int zm1; } *ZMusic_MidiSource;
|
||||
typedef struct { int zm2; } *ZMusic_MusicStream;
|
||||
typedef struct _ZMusic_MidiSource_Struct { int zm1; } *ZMusic_MidiSource;
|
||||
typedef struct _ZMusic_MusicStream_Struct { int zm2; } *ZMusic_MusicStream;
|
||||
struct SoundDecoder;
|
||||
#endif
|
||||
|
||||
|
@ -319,6 +330,7 @@ extern "C"
|
|||
DLL_IMPORT void ZMusic_VolumeChanged(ZMusic_MusicStream song);
|
||||
DLL_IMPORT zmusic_bool ZMusic_WriteSMF(ZMusic_MidiSource source, const char* fn, int looplimit);
|
||||
DLL_IMPORT void ZMusic_GetStreamInfo(ZMusic_MusicStream song, SoundStreamInfo *info);
|
||||
DLL_IMPORT void ZMusic_GetStreamInfoEx(ZMusic_MusicStream song, SoundStreamInfoEx *info);
|
||||
// Configuration interface. The return value specifies if a music restart is needed.
|
||||
// RealValue should be written back to the CVAR or whatever other method the client uses to store configuration state.
|
||||
DLL_IMPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue);
|
||||
|
@ -406,6 +418,7 @@ typedef zmusic_bool (*pfn_ZMusic_IsMIDI)(ZMusic_MusicStream song);
|
|||
typedef void (*pfn_ZMusic_VolumeChanged)(ZMusic_MusicStream song);
|
||||
typedef zmusic_bool (*pfn_ZMusic_WriteSMF)(ZMusic_MidiSource source, const char* fn, int looplimit);
|
||||
typedef void (*pfn_ZMusic_GetStreamInfo)(ZMusic_MusicStream song, SoundStreamInfo *info);
|
||||
typedef void (*pfn_ZMusic_GetStreamInfoEx)(ZMusic_MusicStream song, SoundStreamInfoEx *info);
|
||||
typedef zmusic_bool (*pfn_ChangeMusicSettingInt)(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue);
|
||||
typedef zmusic_bool (*pfn_ChangeMusicSettingFloat)(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue);
|
||||
typedef zmusic_bool (*pfn_ChangeMusicSettingString)(EStringConfigKey key, ZMusic_MusicStream song, const char* value);
|
||||
|
@ -419,4 +432,4 @@ typedef const ZMusicMidiOutDevice *(*pfn_ZMusic_GetMidiDevices)(int *pAmount);
|
|||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
*/
|
||||
|
||||
|
||||
Dynamic Universal Music Bibliotheque
|
||||
Dynamic Universal Music Bibliotheque, Version 0.9.3
|
||||
|
||||
Copyright (C) 2001-2003 Ben Davis, Robert J Ohannessian and Julien Cugniere
|
||||
Copyright (C) 2001-2005 Ben Davis, Robert J Ohannessian and Julien Cugniere
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event shall the authors be held liable for any damages arising from the
|
||||
|
@ -39,16 +39,49 @@ freely, subject to the following restrictions:
|
|||
[Note that the above point asks for a link to DUMB, not just a mention.
|
||||
Googling for DUMB doesn't help much! The URL is "http://dumb.sf.net/".]
|
||||
|
||||
[The only reason why the link is not strictly required is that such a
|
||||
requirement prevents DUMB from being used in projects with certain other
|
||||
licences, notably the GPL. See http://www.gnu.org/philosophy/bsd.html .]
|
||||
[The link was originally strictly required. This was changed for two
|
||||
reasons. Firstly, if many projects request an acknowledgement, the list of
|
||||
acknowledgements can become quite unmanageable. Secondly, DUMB was placing
|
||||
a restriction on the code using it, preventing people from using the GNU
|
||||
General Public Licence which disallows any such restrictions. See
|
||||
http://www.gnu.org/philosophy/bsd.html for more information on this
|
||||
subject. However, if DUMB plays a significant part in your project, we do
|
||||
urge you to acknowledge its use.]
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed from or altered in any source distribution.
|
||||
|
||||
4. If you are using the Program in someone else's bedroom at any Monday
|
||||
3:05 PM, you are not allowed to modify the Program for ten minutes. [This
|
||||
4. If you are using the Program in someone else's bedroom on any Monday at
|
||||
3:05 pm, you are not allowed to modify the Program for ten minutes. [This
|
||||
clause provided by Inphernic; every licence should contain at least one
|
||||
clause, the reasoning behind which is far from obvious.]
|
||||
|
||||
5. Users who wish to use DUMB for the specific purpose of playing music are
|
||||
required to feed their dog on every full moon (if deemed appropriate).
|
||||
[This clause provided by Allefant, who couldn't remember what Inphernic's
|
||||
clause was.]
|
||||
|
||||
6. No clause in this licence shall prevent this software from being depended
|
||||
upon by a product licensed under the GNU General Public Licence. If such a
|
||||
clause is deemed to exist, Debian, then it shall be respected in spirit as
|
||||
far as possible and all other clauses shall continue to apply in full
|
||||
force.
|
||||
|
||||
8. Take the number stated as introducing this clause. Multiply it by two,
|
||||
then subtract four. Now insert a '+' between the two digits and evaluate
|
||||
the resulting sum. Call the result 'x'. If you have not yet concluded that
|
||||
every numbered clause in this licence whose ordinal number is strictly
|
||||
greater than 'x' (with the exception of the present clause) is null and
|
||||
void, Debian, then you are hereby informed that laughter is good for one's
|
||||
health and you are warmly suggested to do it. By the way, Clauses 4, 5 and
|
||||
6 are null and void. Incidentally, I like Kubuntu. The work you guys do is
|
||||
awesome. (Lawyers, on the other hand ...)
|
||||
|
||||
We regret that we cannot provide any warranty, not even the implied warranty
|
||||
of merchantability or fitness for a particular purpose.
|
||||
|
||||
Some files generated or copied by automake, autoconf and friends are
|
||||
available in an extra download. These fall under separate licences but are
|
||||
all free to distribute. Please check their licences as necessary.
|
||||
|
|
|
@ -25,6 +25,7 @@ INTERFACE
|
|||
streamsources/music_dumb.cpp
|
||||
streamsources/music_gme.cpp
|
||||
streamsources/music_libsndfile.cpp
|
||||
streamsources/music_libxmp.cpp
|
||||
streamsources/music_opl.cpp
|
||||
streamsources/music_xa.cpp
|
||||
musicformats/music_stream.cpp
|
||||
|
@ -65,7 +66,12 @@ if(NOT WIN32 AND NOT APPLE)
|
|||
determine_package_config_dependency(ZMUSIC_PACKAGE_DEPENDENCIES TARGET Threads::Threads MODULE Threads)
|
||||
endif()
|
||||
|
||||
option(DYN_SNDFILE "Dynamically load libsndfile" ON)
|
||||
if ("vcpkg-libsndfile" IN_LIST VCPKG_MANIFEST_FEATURES)
|
||||
set(DYN_SNDFILE 0)
|
||||
else()
|
||||
option(DYN_SNDFILE "Dynamically load libsndfile" ON)
|
||||
endif()
|
||||
|
||||
if(DYN_SNDFILE)
|
||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_SNDFILE DYN_SNDFILE)
|
||||
else()
|
||||
|
@ -78,10 +84,14 @@ else()
|
|||
endif()
|
||||
endif()
|
||||
|
||||
option(DYN_MPG123 "Dynamically load libmpg123" ON)
|
||||
if ("vcpkg-libsndfile" IN_LIST VCPKG_MANIFEST_FEATURES)
|
||||
set(DYN_MPG123 0)
|
||||
else()
|
||||
option(DYN_MPG123 "Dynamically load libmpg123" ON)
|
||||
endif()
|
||||
if(DYN_MPG123)
|
||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_MPG123 DYN_MPG123)
|
||||
else()
|
||||
elseif(NOT ("vcpkg-libsndfile" IN_LIST VCPKG_MANIFEST_FEATURES))
|
||||
find_package(MPG123)
|
||||
|
||||
if(MPG123_FOUND)
|
||||
|
@ -91,19 +101,6 @@ else()
|
|||
endif()
|
||||
endif()
|
||||
|
||||
option(DYN_FLUIDSYNTH "Dynamically load fluidsynth" ON)
|
||||
if(DYN_FLUIDSYNTH)
|
||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_FLUIDSYNTH DYN_FLUIDSYNTH)
|
||||
else()
|
||||
find_package(FluidSynth)
|
||||
|
||||
if(FLUIDSYNTH_FOUND)
|
||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_FLUIDSYNTH)
|
||||
target_link_libraries(zmusic-obj INTERFACE libfluidsynth)
|
||||
determine_package_config_dependency(ZMUSIC_PACKAGE_DEPENDENCIES TARGET libfluidsynth MODULE FluidSynth)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# System MIDI support
|
||||
if(WIN32)
|
||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_SYSTEM_MIDI)
|
||||
|
@ -131,7 +128,7 @@ if(WIN32)
|
|||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(zmusic-obj INTERFACE dumb gme ZLIB::ZLIB ${CMAKE_DL_LIBS})
|
||||
target_link_libraries(zmusic-obj INTERFACE dumb gme libxmp miniz ${CMAKE_DL_LIBS})
|
||||
|
||||
target_include_directories(zmusic-obj
|
||||
INTERFACE
|
||||
|
@ -152,13 +149,14 @@ use_fast_math(zmusiclite)
|
|||
|
||||
# Although zmusic-obj puts the public include directory in our private include
|
||||
# list, we need to add it to the interface include directories for consumers.
|
||||
target_include_directories(zmusic INTERFACE $<INSTALL_INTERFACE:include>)
|
||||
target_include_directories(zmusiclite INTERFACE $<INSTALL_INTERFACE:include>)
|
||||
target_include_directories(zmusic INTERFACE $<INSTALL_INTERFACE:include> $<BUILD_INTERFACE:${ZMusic_SOURCE_DIR}/include>)
|
||||
target_include_directories(zmusiclite INTERFACE $<INSTALL_INTERFACE:include> $<BUILD_INTERFACE:${ZMusic_SOURCE_DIR}/include>)
|
||||
|
||||
target_link_libraries_hidden(zmusic zmusic-obj adl oplsynth opn timidity timidityplus wildmidi)
|
||||
target_link_libraries_hidden(zmusiclite zmusic-obj)
|
||||
target_link_libraries_hidden(zmusic zmusic-obj adl oplsynth opn timidity timidityplus wildmidi fluidsynth)
|
||||
target_link_libraries_hidden(zmusiclite zmusic-obj fluidsynth)
|
||||
|
||||
target_compile_definitions(zmusiclite PRIVATE ZMUSIC_LITE=1)
|
||||
target_compile_definitions(zmusic PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:zmusic,TYPE>,STATIC_LIBRARY>:ZMUSIC_STATIC>)
|
||||
target_compile_definitions(zmusiclite PRIVATE ZMUSIC_LITE=1 PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:zmusiclite,TYPE>,STATIC_LIBRARY>:ZMUSIC_STATIC>)
|
||||
|
||||
set_target_properties(zmusic zmusiclite
|
||||
PROPERTIES
|
||||
|
@ -168,37 +166,43 @@ PROPERTIES
|
|||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
)
|
||||
|
||||
install(TARGETS zmusic EXPORT ZMusicFullTargets
|
||||
PUBLIC_HEADER
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT devel
|
||||
LIBRARY
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
COMPONENT full
|
||||
NAMELINK_COMPONENT devel
|
||||
)
|
||||
if (VCPKG_TOOLCHAIN)
|
||||
x_vcpkg_install_local_dependencies(TARGETS zmusic zmusiclite DESTINATION ".")
|
||||
endif()
|
||||
|
||||
install(TARGETS zmusiclite EXPORT ZMusicLiteTargets
|
||||
PUBLIC_HEADER
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT devel
|
||||
LIBRARY
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
COMPONENT lite
|
||||
NAMELINK_COMPONENT devel
|
||||
)
|
||||
if(ZMUSIC_INSTALL)
|
||||
install(TARGETS zmusic EXPORT ZMusicFullTargets
|
||||
PUBLIC_HEADER
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT devel
|
||||
LIBRARY
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
COMPONENT full
|
||||
NAMELINK_COMPONENT devel
|
||||
)
|
||||
|
||||
install(EXPORT ZMusicFullTargets
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
||||
NAMESPACE ZMusic::
|
||||
COMPONENT devel
|
||||
)
|
||||
install(TARGETS zmusiclite EXPORT ZMusicLiteTargets
|
||||
PUBLIC_HEADER
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT devel
|
||||
LIBRARY
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
COMPONENT lite
|
||||
NAMELINK_COMPONENT devel
|
||||
)
|
||||
|
||||
install(EXPORT ZMusicLiteTargets
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
||||
NAMESPACE ZMusic::
|
||||
COMPONENT devel
|
||||
)
|
||||
install(EXPORT ZMusicFullTargets
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
||||
NAMESPACE ZMusic::
|
||||
COMPONENT devel
|
||||
)
|
||||
|
||||
install(EXPORT ZMusicLiteTargets
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
||||
NAMESPACE ZMusic::
|
||||
COMPONENT devel
|
||||
)
|
||||
endif()
|
||||
|
||||
if( MSVC )
|
||||
option( ZMUSIC_GENERATE_MAPFILE "Generate .map file for debugging." OFF )
|
||||
|
|
19916
source/data/xg.h
19916
source/data/xg.h
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -43,14 +43,14 @@ FModule SndFileModule{"SndFile"};
|
|||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SNDFILELIB "libsndfile-1.dll"
|
||||
static const char* libnames[] = { "sndfile.dll", "libsndfile-1.dll" };
|
||||
#elif defined(__APPLE__)
|
||||
#define SNDFILELIB "libsndfile.1.dylib"
|
||||
static const char* libnames[] = { "libsndfile.1.dylib" };
|
||||
#else
|
||||
#define SNDFILELIB "libsndfile.so.1"
|
||||
static const char* libnames[] = { "libsndfile.so.1" };
|
||||
#endif
|
||||
|
||||
bool IsSndFilePresent()
|
||||
extern "C" int IsSndFilePresent()
|
||||
{
|
||||
#if !defined DYN_SNDFILE
|
||||
return true;
|
||||
|
@ -61,14 +61,17 @@ bool IsSndFilePresent()
|
|||
if (!done)
|
||||
{
|
||||
done = true;
|
||||
auto abspath = FModule_GetProgDir() + "/" SNDFILELIB;
|
||||
cached_result = SndFileModule.Load({abspath.c_str(), SNDFILELIB});
|
||||
for (auto libname : libnames)
|
||||
{
|
||||
auto abspath = FModule_GetProgDir() + "/" + libname;
|
||||
cached_result = SndFileModule.Load({ abspath.c_str(), libname });
|
||||
if (cached_result) break;
|
||||
}
|
||||
}
|
||||
return cached_result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
sf_count_t SndFileDecoder::file_get_filelen(void *user_data)
|
||||
{
|
||||
auto &reader = reinterpret_cast<SndFileDecoder*>(user_data)->Reader;
|
||||
|
@ -206,4 +209,60 @@ size_t SndFileDecoder::getSampleLength()
|
|||
return (size_t)((SndInfo.frames > 0) ? SndInfo.frames : 0);
|
||||
}
|
||||
|
||||
// band-aid for FluidSynth, which is C, not C++ and cannot use the module interface.
|
||||
#ifdef DYN_SNDFILE
|
||||
|
||||
#undef sf_open_virtual
|
||||
extern "C" SNDFILE * sf_open_virtual(SF_VIRTUAL_IO * sfvirtual, int mode, SF_INFO * sfinfo, void* user_data)
|
||||
{
|
||||
return p_sf_open_virtual(sfvirtual, mode, sfinfo, user_data);
|
||||
}
|
||||
|
||||
extern "C" const char* sf_strerror(SNDFILE * sndfile)
|
||||
{
|
||||
return p_sf_strerror(sndfile);
|
||||
}
|
||||
|
||||
extern "C" sf_count_t sf_readf_short(SNDFILE * sndfile, short* ptr, sf_count_t frames)
|
||||
{
|
||||
return p_sf_readf_short(sndfile, ptr, frames);
|
||||
}
|
||||
|
||||
#undef sf_close
|
||||
extern "C" int sf_close(SNDFILE * sndfile)
|
||||
{
|
||||
return p_sf_close(sndfile);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else // in case someone decided to build without sndfile support
|
||||
|
||||
extern "C" int IsSndFilePresent()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" SNDFILE * sf_open_virtual(SF_VIRTUAL_IO * sfvirtual, int mode, SF_INFO * sfinfo, void* user_data)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" const char* sf_strerror(SNDFILE * sndfile)
|
||||
{
|
||||
return "no sndfile support";
|
||||
}
|
||||
|
||||
extern "C" sf_count_t sf_readf_short(SNDFILE * sndfile, short* ptr, sf_count_t frames)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int sf_close(SNDFILE * sndfile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ private:
|
|||
static sf_count_t file_tell(void *user_data);
|
||||
};
|
||||
|
||||
#else
|
||||
#include "../thirdparty/sndfile.h"
|
||||
#endif
|
||||
|
||||
#endif /* SNDFILE_DECODER_H */
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#ifndef SNDDEF_H
|
||||
#define SNDDEF_H
|
||||
|
||||
|
||||
|
||||
#if defined HAVE_SNDFILE && defined DYN_SNDFILE
|
||||
|
||||
#define DEFINE_ENTRY(type, name) static TReqProc<SndFileModule, type> p_##name{#name};
|
||||
DEFINE_ENTRY(const char* (*)(SNDFILE* sndfile), sf_strerror)
|
||||
DEFINE_ENTRY(int (*)(SNDFILE *sndfile), sf_close)
|
||||
DEFINE_ENTRY(SNDFILE* (*)(SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data), sf_open_virtual)
|
||||
DEFINE_ENTRY(sf_count_t (*)(SNDFILE *sndfile, float *ptr, sf_count_t frames), sf_readf_float)
|
||||
DEFINE_ENTRY(sf_count_t(*)(SNDFILE* sndfile, short* ptr, sf_count_t frames), sf_readf_short)
|
||||
DEFINE_ENTRY(sf_count_t (*)(SNDFILE *sndfile, sf_count_t frames, int whence), sf_seek)
|
||||
#undef DEFINE_ENTRY
|
||||
|
||||
|
|
|
@ -105,13 +105,53 @@ short* dumb_decode_vorbis(int outlen, const void* oggstream, int sizebytes)
|
|||
}
|
||||
|
||||
decoder->getInfo(&srate, &chans, &type);
|
||||
if (chans != ChannelConfig_Mono || type != SampleType_Int16)
|
||||
if (chans != ChannelConfig_Mono)
|
||||
{
|
||||
delete decoder;
|
||||
return samples;
|
||||
}
|
||||
|
||||
decoder->read((char*)samples, outlen);
|
||||
if(type == SampleType_Int16)
|
||||
decoder->read((char*)samples, outlen);
|
||||
else if(type == SampleType_Float32)
|
||||
{
|
||||
constexpr size_t tempsize = 1024;
|
||||
float temp[tempsize];
|
||||
size_t spos = 0;
|
||||
|
||||
outlen /= sizeof(short);
|
||||
int done = 0;
|
||||
while(done < outlen)
|
||||
{
|
||||
size_t got = decoder->read((char*)temp, tempsize * sizeof(float)) / sizeof(float);
|
||||
for(size_t i = 0;i < got;++i)
|
||||
{
|
||||
float s = temp[i] * 32768.0f;
|
||||
samples[spos++] = (s > 32767.0f) ? 32767 : (s < -32768.0f) ? -32768 : (short)s;
|
||||
}
|
||||
if(got < tempsize)
|
||||
break;
|
||||
done += got;
|
||||
}
|
||||
}
|
||||
else if(type == SampleType_UInt8)
|
||||
{
|
||||
constexpr size_t tempsize = 1024;
|
||||
uint8_t temp[tempsize];
|
||||
size_t spos = 0;
|
||||
|
||||
outlen /= sizeof(short);
|
||||
int done = 0;
|
||||
while(done < outlen)
|
||||
{
|
||||
size_t got = decoder->read((char*)temp, tempsize);
|
||||
for(size_t i = 0;i < got;++i)
|
||||
samples[spos++] = (short)((temp[i]-128) * 256);
|
||||
if(got < tempsize)
|
||||
break;
|
||||
done += got;
|
||||
}
|
||||
}
|
||||
delete decoder;
|
||||
return samples;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
virtual std::string GetStats();
|
||||
virtual int GetDeviceType() const { return MDEV_DEFAULT; }
|
||||
virtual bool CanHandleSysex() const { return true; }
|
||||
virtual SoundStreamInfo GetStreamInfo() const;
|
||||
virtual SoundStreamInfoEx GetStreamInfoEx() const;
|
||||
|
||||
protected:
|
||||
MidiCallback Callback;
|
||||
|
@ -81,7 +81,7 @@ public:
|
|||
virtual int Open() override;
|
||||
virtual bool ServiceStream(void* buff, int numbytes);
|
||||
int GetSampleRate() const { return SampleRate; }
|
||||
SoundStreamInfo GetStreamInfo() const override;
|
||||
SoundStreamInfoEx GetStreamInfoEx() const override;
|
||||
|
||||
protected:
|
||||
double Tempo;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
|
|
|
@ -50,7 +50,6 @@ namespace {
|
|||
|
||||
enum class EventType {
|
||||
Null,
|
||||
Delay,
|
||||
Action
|
||||
};
|
||||
|
||||
|
@ -160,7 +159,7 @@ int AlsaMIDIDevice::Open()
|
|||
snd_seq_port_info_set_port(pinfo, IntendedPortId);
|
||||
snd_seq_port_info_set_port_specified(pinfo, 1);
|
||||
|
||||
snd_seq_port_info_set_name(pinfo, "GZDoom Music");
|
||||
snd_seq_port_info_set_name(pinfo, "ZMusic Program Music");
|
||||
|
||||
snd_seq_port_info_set_capability(pinfo, 0);
|
||||
snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
|
||||
|
@ -172,7 +171,7 @@ int AlsaMIDIDevice::Open()
|
|||
|
||||
if (QueueId < 0)
|
||||
{
|
||||
QueueId = snd_seq_alloc_named_queue(sequencer.handle, "GZDoom Queue");
|
||||
QueueId = snd_seq_alloc_named_queue(sequencer.handle, "ZMusic Program Queue");
|
||||
}
|
||||
|
||||
if (!Connected) {
|
||||
|
@ -290,8 +289,8 @@ EventType AlsaMIDIDevice::PullEvent(EventState & state) {
|
|||
return EventType::Action;
|
||||
|
||||
case MIDI_POLYPRESS:
|
||||
// FIXME: Seems to be missing in the Alsa sequencer implementation
|
||||
break;
|
||||
snd_seq_ev_set_keypress(&state.data, channel, parm1, parm2);
|
||||
return EventType::Action;
|
||||
|
||||
case MIDI_CTRLCHANGE:
|
||||
snd_seq_ev_set_controller(&state.data, channel, parm1, parm2);
|
||||
|
@ -315,8 +314,10 @@ EventType AlsaMIDIDevice::PullEvent(EventState & state) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
// We didn't really recognize the event, treat it as a delay
|
||||
return EventType::Delay;
|
||||
// We didn't really recognize the event, treat it as a NOP
|
||||
state.data.type = SND_SEQ_EVENT_NONE;
|
||||
snd_seq_ev_set_fixed(&state.data);
|
||||
return EventType::Action;
|
||||
}
|
||||
|
||||
void AlsaMIDIDevice::SetExit(bool exit) {
|
||||
|
@ -374,13 +375,6 @@ void AlsaMIDIDevice::PumpEvents() {
|
|||
continue;
|
||||
}
|
||||
|
||||
// chomp delays as they come...
|
||||
if(type == EventType::Delay) {
|
||||
buffer_ticks += event.ticks;
|
||||
Position += event.size_of;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Figure out if we should sleep (the event is too far in the future for us to care), and for how long
|
||||
int next_event_tick = buffer_ticks + event.ticks;
|
||||
int queue_tick = snd_seq_queue_status_get_tick_time(status);
|
||||
|
@ -433,7 +427,6 @@ void AlsaMIDIDevice::PumpEvents() {
|
|||
snd_seq_drain_output(sequencer.handle);
|
||||
snd_seq_sync_output_queue(sequencer.handle);
|
||||
}
|
||||
snd_seq_sync_output_queue(sequencer.handle);
|
||||
snd_seq_stop_queue(sequencer.handle, QueueId, NULL);
|
||||
snd_seq_drain_output(sequencer.handle);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ bool AlsaSequencer::Open() {
|
|||
if(error) {
|
||||
return false;
|
||||
}
|
||||
error = snd_seq_set_client_name(handle, "GZDoom");
|
||||
error = snd_seq_set_client_name(handle, "ZMusic Program");
|
||||
if(error) {
|
||||
snd_seq_close(handle);
|
||||
handle = nullptr;
|
||||
|
@ -131,11 +131,7 @@ int AlsaSequencer::EnumerateDevices() {
|
|||
while (snd_seq_query_next_client(handle, cinfo) >= 0) {
|
||||
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
|
||||
|
||||
// Ignore 'ALSA oddities' that we don't want to use
|
||||
int clientID = snd_seq_client_info_get_client(cinfo);
|
||||
if(clientID < 16) {
|
||||
continue;
|
||||
}
|
||||
|
||||
snd_seq_port_info_set_port(pinfo, -1);
|
||||
// enumerate ports
|
||||
|
|
|
@ -172,11 +172,11 @@ std::string MIDIDevice::GetStats()
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// MIDIDevice :: GetStreamInfo
|
||||
// MIDIDevice :: GetStreamInfoEx
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
SoundStreamInfo MIDIDevice::GetStreamInfo() const
|
||||
SoundStreamInfoEx MIDIDevice::GetStreamInfoEx() const
|
||||
{
|
||||
return { 0, 0, 0 }; // i.e. do not use streaming.
|
||||
return {}; // i.e. do not use streaming.
|
||||
}
|
||||
|
|
|
@ -35,27 +35,19 @@
|
|||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
#include "mididevice.h"
|
||||
#include "zmusic/mus2midi.h"
|
||||
#include "loader/i_module.h"
|
||||
|
||||
// FluidSynth implementation of a MIDI device -------------------------------
|
||||
|
||||
FluidConfig fluidConfig;
|
||||
|
||||
#ifdef HAVE_FLUIDSYNTH
|
||||
|
||||
#if !defined DYN_FLUIDSYNTH
|
||||
#include <fluidsynth.h>
|
||||
#else
|
||||
#include "loader/i_module.h"
|
||||
extern FModule FluidSynthModule;
|
||||
|
||||
struct fluid_settings_t;
|
||||
struct fluid_synth_t;
|
||||
#endif
|
||||
#include "../thirdparty/fluidsynth/include/fluidsynth.h"
|
||||
|
||||
class FluidSynthMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
|
@ -84,70 +76,10 @@ protected:
|
|||
int FluidSettingsResultOk = FLUID_OK;
|
||||
int FluidSettingsResultFailed = FLUID_FAILED;
|
||||
|
||||
#ifdef DYN_FLUIDSYNTH
|
||||
enum { FLUID_FAILED = -1, FLUID_OK = 0 };
|
||||
static TReqProc<FluidSynthModule, void (*)(int *, int*, int*)> fluid_version;
|
||||
static TReqProc<FluidSynthModule, fluid_settings_t *(*)()> new_fluid_settings;
|
||||
static TReqProc<FluidSynthModule, fluid_synth_t *(*)(fluid_settings_t *)> new_fluid_synth;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *)> delete_fluid_synth;
|
||||
static TReqProc<FluidSynthModule, void (*)(fluid_settings_t *)> delete_fluid_settings;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_settings_t *, const char *, double)> fluid_settings_setnum;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_settings_t *, const char *, const char *)> fluid_settings_setstr;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_settings_t *, const char *, int)> fluid_settings_setint;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_settings_t *, const char *, int *)> fluid_settings_getint;
|
||||
static TReqProc<FluidSynthModule, void (*)(fluid_synth_t *, int)> fluid_synth_set_reverb_on;
|
||||
static TReqProc<FluidSynthModule, void (*)(fluid_synth_t *, int)> fluid_synth_set_chorus_on;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, int)> fluid_synth_set_interp_method;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int)> fluid_synth_set_polyphony;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *)> fluid_synth_get_polyphony;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *)> fluid_synth_get_active_voice_count;
|
||||
static TReqProc<FluidSynthModule, double (*)(fluid_synth_t *)> fluid_synth_get_cpu_load;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *)> fluid_synth_system_reset;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, int, int)> fluid_synth_noteon;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, int)> fluid_synth_noteoff;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, int, int)> fluid_synth_cc;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, int)> fluid_synth_program_change;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, int)> fluid_synth_channel_pressure;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, int)> fluid_synth_pitch_bend;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, int, void *, int, int, void *, int, int)> fluid_synth_write_float;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, const char *, int)> fluid_synth_sfload;
|
||||
static TReqProc<FluidSynthModule, void (*)(fluid_synth_t *, double, double, double, double)> fluid_synth_set_reverb;
|
||||
static TReqProc<FluidSynthModule, void (*)(fluid_synth_t *, int, double, double, double, int)> fluid_synth_set_chorus;
|
||||
static TReqProc<FluidSynthModule, int (*)(fluid_synth_t *, const char *, int, char *, int *, int *, int)> fluid_synth_sysex;
|
||||
|
||||
bool LoadFluidSynth(const char *fluid_lib);
|
||||
void UnloadFluidSynth();
|
||||
#endif
|
||||
};
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#ifdef DYN_FLUIDSYNTH
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef _M_X64
|
||||
#define FLUIDSYNTHLIB1 "fluidsynth.dll"
|
||||
#define FLUIDSYNTHLIB2 "libfluidsynth.dll"
|
||||
#else
|
||||
#define FLUIDSYNTHLIB1 "fluidsynth64.dll"
|
||||
#define FLUIDSYNTHLIB2 "libfluidsynth64.dll"
|
||||
#endif
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define FLUIDSYNTHLIB1 "libfluidsynth.1.dylib"
|
||||
#define FLUIDSYNTHLIB2 "libfluidsynth.2.dylib"
|
||||
#else // !__APPLE__
|
||||
#define FLUIDSYNTHLIB1 "libfluidsynth.so.1"
|
||||
#define FLUIDSYNTHLIB2 "libfluidsynth.so.2"
|
||||
#endif // __APPLE__
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
@ -179,21 +111,6 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, std::vector<std::stri
|
|||
|
||||
FluidSynth = NULL;
|
||||
FluidSettings = NULL;
|
||||
#ifdef DYN_FLUIDSYNTH
|
||||
if (!LoadFluidSynth(fluidConfig.fluid_lib.c_str()))
|
||||
{
|
||||
throw std::runtime_error("Failed to load FluidSynth.\n");
|
||||
}
|
||||
#endif
|
||||
int major = 0, minor = 0, micro = 0;
|
||||
fluid_version(&major, &minor, µ);
|
||||
|
||||
if (major < 2)
|
||||
{
|
||||
// FluidSynth 1.x: fluid_settings_...() functions return 1 on success and 0 otherwise
|
||||
FluidSettingsResultOk = 1;
|
||||
FluidSettingsResultFailed = 0;
|
||||
}
|
||||
|
||||
FluidSettings = new_fluid_settings();
|
||||
if (FluidSettings == NULL)
|
||||
|
@ -225,8 +142,8 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, std::vector<std::stri
|
|||
return;
|
||||
}
|
||||
|
||||
delete_fluid_settings(FluidSettings);
|
||||
delete_fluid_synth(FluidSynth);
|
||||
delete_fluid_settings(FluidSettings);
|
||||
FluidSynth = nullptr;
|
||||
FluidSettings = nullptr;
|
||||
throw std::runtime_error("Failed to load any MIDI patches.\n");
|
||||
|
@ -251,9 +168,6 @@ FluidSynthMIDIDevice::~FluidSynthMIDIDevice()
|
|||
{
|
||||
delete_fluid_settings(FluidSettings);
|
||||
}
|
||||
#ifdef DYN_FLUIDSYNTH
|
||||
UnloadFluidSynth();
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -266,7 +180,8 @@ FluidSynthMIDIDevice::~FluidSynthMIDIDevice()
|
|||
|
||||
int FluidSynthMIDIDevice::OpenRenderer()
|
||||
{
|
||||
fluid_synth_system_reset(FluidSynth);
|
||||
// Send MIDI system reset command (big red 'panic' button), turns off notes, resets controllers and restores initial basic channel configuration.
|
||||
//fluid_synth_system_reset(FluidSynth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -324,9 +239,10 @@ void FluidSynthMIDIDevice::HandleEvent(int status, int parm1, int parm2)
|
|||
|
||||
void FluidSynthMIDIDevice::HandleLongEvent(const uint8_t *data, int len)
|
||||
{
|
||||
if (len > 1 && (data[0] == 0xF0 || data[0] == 0xF7))
|
||||
constexpr int excludedByteCount = 2; // 0xF0 (first byte) and 0xF7 (last byte) are not given to FluidSynth.
|
||||
if (len > excludedByteCount && data[0] == 0xF0 && data[len - 1] == 0xF7)
|
||||
{
|
||||
fluid_synth_sysex(FluidSynth, (const char *)data + 1, len - 1, NULL, NULL, NULL, 0);
|
||||
fluid_synth_sysex(FluidSynth, (const char *)data + 1, len - excludedByteCount, NULL, NULL, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,85 +408,6 @@ std::string FluidSynthMIDIDevice::GetStats()
|
|||
return out;
|
||||
}
|
||||
|
||||
#ifdef DYN_FLUIDSYNTH
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FluidSynthMIDIDevice :: LoadFluidSynth
|
||||
//
|
||||
// Returns true if the FluidSynth library was successfully loaded.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FModuleMaybe<DYN_FLUIDSYNTH> FluidSynthModule{"FluidSynth"};
|
||||
|
||||
#define DYN_FLUID_SYM(x) decltype(FluidSynthMIDIDevice::x) FluidSynthMIDIDevice::x{#x}
|
||||
DYN_FLUID_SYM(fluid_version);
|
||||
DYN_FLUID_SYM(new_fluid_settings);
|
||||
DYN_FLUID_SYM(new_fluid_synth);
|
||||
DYN_FLUID_SYM(delete_fluid_synth);
|
||||
DYN_FLUID_SYM(delete_fluid_settings);
|
||||
DYN_FLUID_SYM(fluid_settings_setnum);
|
||||
DYN_FLUID_SYM(fluid_settings_setstr);
|
||||
DYN_FLUID_SYM(fluid_settings_setint);
|
||||
DYN_FLUID_SYM(fluid_settings_getint);
|
||||
DYN_FLUID_SYM(fluid_synth_set_reverb_on);
|
||||
DYN_FLUID_SYM(fluid_synth_set_chorus_on);
|
||||
DYN_FLUID_SYM(fluid_synth_set_interp_method);
|
||||
DYN_FLUID_SYM(fluid_synth_set_polyphony);
|
||||
DYN_FLUID_SYM(fluid_synth_get_polyphony);
|
||||
DYN_FLUID_SYM(fluid_synth_get_active_voice_count);
|
||||
DYN_FLUID_SYM(fluid_synth_get_cpu_load);
|
||||
DYN_FLUID_SYM(fluid_synth_system_reset);
|
||||
DYN_FLUID_SYM(fluid_synth_noteon);
|
||||
DYN_FLUID_SYM(fluid_synth_noteoff);
|
||||
DYN_FLUID_SYM(fluid_synth_cc);
|
||||
DYN_FLUID_SYM(fluid_synth_program_change);
|
||||
DYN_FLUID_SYM(fluid_synth_channel_pressure);
|
||||
DYN_FLUID_SYM(fluid_synth_pitch_bend);
|
||||
DYN_FLUID_SYM(fluid_synth_write_float);
|
||||
DYN_FLUID_SYM(fluid_synth_sfload);
|
||||
DYN_FLUID_SYM(fluid_synth_set_reverb);
|
||||
DYN_FLUID_SYM(fluid_synth_set_chorus);
|
||||
DYN_FLUID_SYM(fluid_synth_sysex);
|
||||
|
||||
bool FluidSynthMIDIDevice::LoadFluidSynth(const char *fluid_lib)
|
||||
{
|
||||
if (fluid_lib && strlen(fluid_lib) > 0)
|
||||
{
|
||||
if(!FluidSynthModule.Load({fluid_lib}))
|
||||
{
|
||||
const char* libname = fluid_lib;
|
||||
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Could not load %s\n", libname);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!FluidSynthModule.Load({FLUIDSYNTHLIB1, FLUIDSYNTHLIB2}))
|
||||
{
|
||||
ZMusic_Printf(ZMUSIC_MSG_ERROR, "Could not load " FLUIDSYNTHLIB1 " or " FLUIDSYNTHLIB2 "\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FluidSynthMIDIDevice :: UnloadFluidSynth
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FluidSynthMIDIDevice::UnloadFluidSynth()
|
||||
{
|
||||
FluidSynthModule.Unload();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// sndfile
|
||||
//
|
||||
|
@ -685,12 +522,3 @@ MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, const char *Args)
|
|||
Fluid_SetupConfig(Args, fluid_patchset, true);
|
||||
return new FluidSynthMIDIDevice(samplerate, fluid_patchset);
|
||||
}
|
||||
#else
|
||||
|
||||
MIDIDevice* CreateFluidSynthMIDIDevice(int samplerate, const char* Args)
|
||||
{
|
||||
throw std::runtime_error("FlidSynth device not supported in this configuration");
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_FLUIDSYNTH
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <stdexcept>
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
#include "mididevice.h"
|
||||
#include "zmusic/mus2midi.h"
|
||||
|
@ -333,4 +334,4 @@ MIDIDevice* CreateOplMIDIDevice(const char* Args)
|
|||
{
|
||||
throw std::runtime_error("OPL device not supported in this configuration");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <stdexcept>
|
||||
#include "mididevice.h"
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
|
||||
|
|
|
@ -88,18 +88,19 @@ SoftSynthMIDIDevice::~SoftSynthMIDIDevice()
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// SoftSynthMIDIDevice :: GwrStreamInfo
|
||||
// SoftSynthMIDIDevice :: GetStreamInfoEx
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
SoundStreamInfo SoftSynthMIDIDevice::GetStreamInfo() const
|
||||
SoundStreamInfoEx SoftSynthMIDIDevice::GetStreamInfoEx() const
|
||||
{
|
||||
int chunksize = (SampleRate / StreamBlockSize) * 4;
|
||||
if (!isMono)
|
||||
{
|
||||
chunksize *= 2;
|
||||
}
|
||||
return { chunksize, SampleRate, isMono? 1:2 };
|
||||
return { chunksize, SampleRate, SampleType_Float32,
|
||||
isMono ? ChannelConfig_Mono : ChannelConfig_Stereo };
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
#include "mididevice.h"
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
|
@ -94,42 +95,44 @@ protected:
|
|||
|
||||
void TimidityMIDIDevice::LoadInstruments()
|
||||
{
|
||||
if (gusConfig.dmxgus.size())
|
||||
if (gusConfig.reader)
|
||||
{
|
||||
// Check if we got some GUS data before using it.
|
||||
std::string ultradir = getenv("ULTRADIR");
|
||||
if (ultradir.length() || gusConfig.gus_patchdir.length() != 0)
|
||||
std::string ultradir;
|
||||
const char *ret = getenv("ULTRADIR");
|
||||
if (ret) ultradir = std::string(ret);
|
||||
// The GUS put its patches in %ULTRADIR%/MIDI so we can try that
|
||||
if (ultradir.length())
|
||||
{
|
||||
auto psreader = new MusicIO::FileSystemSoundFontReader("");
|
||||
|
||||
// The GUS put its patches in %ULTRADIR%/MIDI so we can try that
|
||||
if (ultradir.length())
|
||||
{
|
||||
ultradir += "/midi";
|
||||
psreader->add_search_path(ultradir.c_str());
|
||||
}
|
||||
// Load DMXGUS lump and patches from gus_patchdir
|
||||
if (gusConfig.gus_patchdir.length() != 0) psreader->add_search_path(gusConfig.gus_patchdir.c_str());
|
||||
|
||||
gusConfig.instruments.reset(new Timidity::Instruments(psreader));
|
||||
bool success = gusConfig.instruments->LoadDMXGUS(gusConfig.gus_memsize, (const char*)gusConfig.dmxgus.data(), gusConfig.dmxgus.size()) >= 0;
|
||||
|
||||
gusConfig.dmxgus.clear();
|
||||
|
||||
if (success)
|
||||
{
|
||||
gusConfig.loadedConfig = "DMXGUS";
|
||||
return;
|
||||
}
|
||||
ultradir += "/midi";
|
||||
gusConfig.reader->add_search_path(ultradir.c_str());
|
||||
}
|
||||
gusConfig.loadedConfig = "";
|
||||
gusConfig.instruments.reset();
|
||||
throw std::runtime_error("Unable to initialize DMXGUS for GUS MIDI device");
|
||||
}
|
||||
else if (gusConfig.reader)
|
||||
{
|
||||
gusConfig.loadedConfig = gusConfig.readerName;
|
||||
// Load DMXGUS lump and patches from gus_patchdir
|
||||
if (gusConfig.gus_patchdir.length() != 0) gusConfig.reader->add_search_path(gusConfig.gus_patchdir.c_str());
|
||||
|
||||
gusConfig.instruments.reset(new Timidity::Instruments(gusConfig.reader));
|
||||
gusConfig.loadedConfig = gusConfig.readerName;
|
||||
}
|
||||
|
||||
if (gusConfig.instruments == nullptr)
|
||||
{
|
||||
throw std::runtime_error("No instruments set for GUS device");
|
||||
}
|
||||
|
||||
if (gusConfig.gus_dmxgus && gusConfig.dmxgus.size())
|
||||
{
|
||||
bool success = gusConfig.instruments->LoadDMXGUS(gusConfig.gus_memsize, (const char*)gusConfig.dmxgus.data(), gusConfig.dmxgus.size()) >= 0;
|
||||
gusConfig.reader = nullptr;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
gusConfig.instruments.reset();
|
||||
gusConfig.loadedConfig = "";
|
||||
throw std::runtime_error("Unable to initialize DMXGUS for GUS MIDI device");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool err = gusConfig.instruments->LoadConfig() < 0;
|
||||
gusConfig.reader = nullptr;
|
||||
|
||||
|
@ -140,10 +143,6 @@ void TimidityMIDIDevice::LoadInstruments()
|
|||
throw std::runtime_error("Unable to initialize instruments for GUS MIDI device");
|
||||
}
|
||||
}
|
||||
else if (gusConfig.instruments == nullptr)
|
||||
{
|
||||
throw std::runtime_error("No instruments set for GUS device");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -257,20 +256,11 @@ void TimidityMIDIDevice::ComputeOutput(float *buffer, int len)
|
|||
|
||||
bool GUS_SetupConfig(const char* args)
|
||||
{
|
||||
gusConfig.reader = nullptr;
|
||||
if ((gusConfig.gus_dmxgus && *args == 0) || !stricmp(args, "DMXGUS"))
|
||||
{
|
||||
if (stricmp(gusConfig.loadedConfig.c_str(), "DMXGUS") == 0) return false; // aleady loaded
|
||||
if (gusConfig.dmxgus.size() > 0)
|
||||
{
|
||||
gusConfig.readerName = "DMXGUS";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (*args == 0) args = gusConfig.gus_config.c_str();
|
||||
if (stricmp(gusConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
if (gusConfig.gus_dmxgus && *args == 0) args = "DMXGUS";
|
||||
//if (stricmp(gusConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||
|
||||
MusicIO::SoundFontReaderInterface* reader = MusicIO::ClientOpenSoundFont(args, SF_GUS | SF_SF2);
|
||||
MusicIO::SoundFontReaderInterface* reader = MusicIO::ClientOpenSoundFont(args, SF_GUS);
|
||||
if (!reader && MusicIO::fileExists(args))
|
||||
{
|
||||
auto f = MusicIO::utf8_fopen(args, "rb");
|
||||
|
@ -286,6 +276,11 @@ bool GUS_SetupConfig(const char* args)
|
|||
if (!reader) reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
||||
}
|
||||
|
||||
if (!reader && gusConfig.gus_dmxgus)
|
||||
{
|
||||
reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
||||
}
|
||||
|
||||
if (reader == nullptr)
|
||||
{
|
||||
char error[80];
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include "mididevice.h"
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
|
||||
|
@ -239,4 +240,4 @@ MIDIDevice* CreateTimidityPPMIDIDevice(const char* Args, int samplerate)
|
|||
{
|
||||
throw std::runtime_error("Timidity++ device not supported in this configuration");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "mididevice.h"
|
||||
#include "zmusic/m_swap.h"
|
||||
#include "fileio.h"
|
||||
#include <stdexcept>
|
||||
#include <errno.h>
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <stdexcept>
|
||||
#include "mididevice.h"
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
|
||||
|
@ -87,15 +88,7 @@ void WildMIDIDevice::LoadInstruments()
|
|||
{
|
||||
wildMidiConfig.loadedConfig = wildMidiConfig.readerName;
|
||||
wildMidiConfig.instruments.reset(new WildMidi::Instruments(wildMidiConfig.reader, SampleRate));
|
||||
bool success = wildMidiConfig.instruments->LoadConfig(wildMidiConfig.readerName.c_str());
|
||||
wildMidiConfig.reader = nullptr;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
wildMidiConfig.instruments.reset();
|
||||
wildMidiConfig.loadedConfig = "";
|
||||
throw std::runtime_error("Unable to initialize instruments for WildMidi device");
|
||||
}
|
||||
}
|
||||
else if (wildMidiConfig.instruments == nullptr)
|
||||
{
|
||||
|
@ -104,7 +97,9 @@ void WildMIDIDevice::LoadInstruments()
|
|||
instruments = wildMidiConfig.instruments;
|
||||
if (instruments->LoadConfig(nullptr) < 0)
|
||||
{
|
||||
throw std::runtime_error("Unable to load instruments set for WildMidi device");
|
||||
wildMidiConfig.instruments.reset();
|
||||
wildMidiConfig.loadedConfig = "";
|
||||
throw std::runtime_error("Unable to initialize instruments for WildMidi device");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,4 +279,4 @@ MIDIDevice* CreateWildMIDIDevice(const char* Args, int samplerate)
|
|||
{
|
||||
throw std::runtime_error("WildMidi device not supported in this configuration");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <mmsystem.h>
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <assert.h>
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
|
|
@ -134,8 +134,8 @@ void MUSSong2::DoInitialSetup()
|
|||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
LastVelocity[i] = 100;
|
||||
ChannelVolumes[i] = 127;
|
||||
LastVelocity[i] = 127;
|
||||
ChannelVolumes[i] = 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -178,16 +178,29 @@ MIDISong2::MIDISong2 (const uint8_t* data, size_t len)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
enum
|
||||
{
|
||||
EMIDI_GeneralMIDI = 0,
|
||||
EMIDI_SoundCanvas = 1,
|
||||
EMIDI_AWE32 = 2,
|
||||
EMIDI_WaveBlaster = 3,
|
||||
EMIDI_SoundBlaster = 4,
|
||||
EMIDI_ProAudio = 5,
|
||||
EMIDI_SoundMan16 = 6,
|
||||
EMIDI_Adlib = 7,
|
||||
EMIDI_Soundscape = 8,
|
||||
EMIDI_Ultrasound = 9,
|
||||
};
|
||||
|
||||
void MIDISong2::CheckCaps(int tech)
|
||||
{
|
||||
DesignationMask = 0xFF0F;
|
||||
if (tech == MIDIDEV_FMSYNTH)
|
||||
{
|
||||
DesignationMask = 0x00F0;
|
||||
DesignationMask = 1 << EMIDI_Adlib;
|
||||
}
|
||||
else if (tech == MIDIDEV_MIDIPORT)
|
||||
else
|
||||
{
|
||||
DesignationMask = 0x0001;
|
||||
DesignationMask = 1 << EMIDI_GeneralMIDI;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -443,7 +456,12 @@ uint32_t *MIDISong2::SendCommand (uint32_t *events, TrackInfo *track, uint32_t d
|
|||
case 111: // EMIDI Track Exclusion - InitBeat only
|
||||
if (track->PlayedTime < (uint32_t)Division)
|
||||
{
|
||||
if (track->Designated && data2 <= 9)
|
||||
if (!track->Designated)
|
||||
{
|
||||
track->Designation = ~0;
|
||||
track->Designated = true;
|
||||
}
|
||||
if (data2 <= 9)
|
||||
{
|
||||
track->Designation &= ~(1 << data2);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
void Resume();
|
||||
void Stop();
|
||||
bool IsPlaying();
|
||||
SoundStreamInfoEx GetStreamInfoEx() const override { return {}; }
|
||||
bool IsValid() const { return m_Inited; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -34,8 +34,9 @@
|
|||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include "zmusic/zmusic_internal.h"
|
||||
#include "zmusic/musinfo.h"
|
||||
|
@ -87,7 +88,7 @@ public:
|
|||
int ServiceEvent();
|
||||
void SetMIDISource(MIDISource* _source);
|
||||
bool ServiceStream(void* buff, int len) override;
|
||||
SoundStreamInfo GetStreamInfo() const override;
|
||||
SoundStreamInfoEx GetStreamInfoEx() const override;
|
||||
|
||||
int GetDeviceType() const override;
|
||||
|
||||
|
@ -446,10 +447,10 @@ bool MIDIStreamer::InitPlayback()
|
|||
}
|
||||
}
|
||||
|
||||
SoundStreamInfo MIDIStreamer::GetStreamInfo() const
|
||||
SoundStreamInfoEx MIDIStreamer::GetStreamInfoEx() const
|
||||
{
|
||||
if (MIDI) return MIDI->GetStreamInfo();
|
||||
else return { 0, 0, 0 };
|
||||
if (MIDI) return MIDI->GetStreamInfoEx();
|
||||
else return {};
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -814,7 +815,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
|||
if (InitialPlayback)
|
||||
{
|
||||
InitialPlayback = false;
|
||||
// Send the GS System Reset SysEx message.
|
||||
// Send the GM System Enable SysEx message.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
events[2] = (MEVENT_LONGMSG << 24) | 6; // dwEvent
|
||||
|
@ -822,6 +823,15 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
|||
events[4] = MAKE_ID(0x01, 0xf7, 0x00, 0x00); // dwParms[1]
|
||||
events += 5;
|
||||
|
||||
// Send the GS DT1 MODE SET GS Reset SysEx message.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
events[2] = (MEVENT_LONGMSG << 24) | 11; // dwEvent
|
||||
events[3] = MAKE_ID(0xf0, 0x41, 0x7f, 0x42); // dwParms[0]
|
||||
events[4] = MAKE_ID(0x12, 0x40, 0x00, 0x7f); // dwParms[1]
|
||||
events[5] = MAKE_ID(0x00, 0x41, 0xf7, 0x00); // dwParms[2]
|
||||
events += 6;
|
||||
|
||||
// Send the full master volume SysEx message.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
void ChangeSettingNum(const char *name, double value) override { if (m_Source) m_Source->ChangeSettingNum(name, value); }
|
||||
void ChangeSettingString(const char *name, const char *value) override { if(m_Source) m_Source->ChangeSettingString(name, value); }
|
||||
bool ServiceStream(void* buff, int len) override;
|
||||
SoundStreamInfo GetStreamInfo() const override { return m_Source->GetFormat(); }
|
||||
SoundStreamInfoEx GetStreamInfoEx() const override { return m_Source->GetFormatEx(); }
|
||||
|
||||
|
||||
protected:
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
//bool SetPosition(int ms);
|
||||
bool SetSubsong(int subsong) override;
|
||||
bool Start() override;
|
||||
SoundStreamInfo GetFormat() override;
|
||||
SoundStreamInfoEx GetFormatEx() override;
|
||||
void ChangeSettingNum(const char* setting, double val) override;
|
||||
std::string GetStats() override;
|
||||
|
||||
|
@ -885,6 +885,18 @@ StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, int samplerate)
|
|||
duh = dumb_read_okt_quick(f);
|
||||
}
|
||||
}
|
||||
else if (size >= 4 &&
|
||||
(dstart[0] == MAKE_ID('A','M','F','\xa') ||
|
||||
dstart[0] == MAKE_ID('A','M','F','\xb') ||
|
||||
dstart[0] == MAKE_ID('A','M','F','\xc') ||
|
||||
dstart[0] == MAKE_ID('A','M','F','\xd') ||
|
||||
dstart[0] == MAKE_ID('A','M','F','\xe')))
|
||||
{
|
||||
if ((f = dumb_read_allfile(&filestate, start, reader, headsize, size)))
|
||||
{
|
||||
duh = dumb_read_amf_quick(f);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! duh )
|
||||
{
|
||||
|
@ -1030,13 +1042,13 @@ DumbSong::~DumbSong()
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// DumbSong GetFormat
|
||||
// DumbSong GetFormatEx
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
SoundStreamInfo DumbSong::GetFormat()
|
||||
SoundStreamInfoEx DumbSong::GetFormatEx()
|
||||
{
|
||||
return { 32*1024, srate, 2 };
|
||||
return { 32*1024, srate, SampleType_Float32, ChannelConfig_Stereo };
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -38,9 +38,11 @@
|
|||
//#define GME_DLL
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "streamsource.h"
|
||||
#include <gme/gme.h>
|
||||
#include <mutex>
|
||||
#include "fileio.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
@ -57,7 +59,7 @@ public:
|
|||
void ChangeSettingNum(const char *name, double val) override;
|
||||
std::string GetStats() override;
|
||||
bool GetData(void *buffer, size_t len) override;
|
||||
SoundStreamInfo GetFormat() override;
|
||||
SoundStreamInfoEx GetFormatEx() override;
|
||||
|
||||
protected:
|
||||
Music_Emu *Emu;
|
||||
|
@ -167,9 +169,9 @@ GMESong::GMESong(Music_Emu *emu, int sample_rate)
|
|||
}
|
||||
|
||||
|
||||
SoundStreamInfo GMESong::GetFormat()
|
||||
SoundStreamInfoEx GMESong::GetFormatEx()
|
||||
{
|
||||
return { 32*1024, SampleRate, -2 };
|
||||
return { 32*1024, SampleRate, SampleType_Int16, ChannelConfig_Stereo };
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -50,14 +50,13 @@ public:
|
|||
SndFileSong(SoundDecoder *decoder, uint32_t loop_start, uint32_t loop_end, bool startass, bool endass);
|
||||
~SndFileSong();
|
||||
std::string GetStats() override;
|
||||
SoundStreamInfo GetFormat() override;
|
||||
SoundStreamInfoEx GetFormatEx() override;
|
||||
bool GetData(void *buffer, size_t len) override;
|
||||
|
||||
protected:
|
||||
SoundDecoder *Decoder;
|
||||
int Channels;
|
||||
int SampleRate;
|
||||
|
||||
unsigned int FrameSize;
|
||||
|
||||
uint32_t Loop_Start;
|
||||
uint32_t Loop_End;
|
||||
|
||||
|
@ -434,25 +433,30 @@ static int32_t Scale(int32_t a, int32_t b, int32_t c)
|
|||
|
||||
SndFileSong::SndFileSong(SoundDecoder *decoder, uint32_t loop_start, uint32_t loop_end, bool startass, bool endass)
|
||||
{
|
||||
ChannelConfig iChannels;
|
||||
SampleType Type;
|
||||
|
||||
decoder->getInfo(&SampleRate, &iChannels, &Type);
|
||||
ChannelConfig chanconf;
|
||||
SampleType stype;
|
||||
int srate;
|
||||
|
||||
if (!startass) loop_start = Scale(loop_start, SampleRate, 1000);
|
||||
if (!endass) loop_end = Scale(loop_end, SampleRate, 1000);
|
||||
decoder->getInfo(&srate, &chanconf, &stype);
|
||||
|
||||
if (!startass) loop_start = Scale(loop_start, srate, 1000);
|
||||
if (!endass) loop_end = Scale(loop_end, srate, 1000);
|
||||
|
||||
const uint32_t sampleLength = (uint32_t)decoder->getSampleLength();
|
||||
Loop_Start = loop_start;
|
||||
Loop_End = sampleLength == 0 ? loop_end : std::min<uint32_t>(loop_end, sampleLength);
|
||||
Decoder = decoder;
|
||||
Channels = iChannels == ChannelConfig_Stereo? 2:1;
|
||||
FrameSize = ZMusic_ChannelCount(chanconf) * ZMusic_SampleTypeSize(stype);
|
||||
}
|
||||
|
||||
SoundStreamInfo SndFileSong::GetFormat()
|
||||
SoundStreamInfoEx SndFileSong::GetFormatEx()
|
||||
{
|
||||
// deal with this once the configuration is handled better.
|
||||
return { 64/*snd_streambuffersize*/ * 1024, SampleRate, -Channels };
|
||||
ChannelConfig chanconf;
|
||||
SampleType stype;
|
||||
int srate;
|
||||
|
||||
Decoder->getInfo(&srate, &chanconf, &stype);
|
||||
return { 64/*snd_streambuffersize*/ * 1024, srate, stype, chanconf };
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -479,14 +483,17 @@ std::string SndFileSong::GetStats()
|
|||
{
|
||||
char out[80];
|
||||
|
||||
size_t SamplePos;
|
||||
ChannelConfig chanconf;
|
||||
SampleType stype;
|
||||
int srate;
|
||||
Decoder->getInfo(&srate, &chanconf, &stype);
|
||||
|
||||
SamplePos = Decoder->getSampleOffset();
|
||||
int time = int (SamplePos / SampleRate);
|
||||
size_t SamplePos = Decoder->getSampleOffset();
|
||||
int time = int (SamplePos / srate);
|
||||
|
||||
snprintf(out, 80,
|
||||
"Track: %s, %dHz Time: %02d:%02d",
|
||||
Channels == 2? "Stereo" : "Mono", SampleRate,
|
||||
ZMusic_ChannelConfigName(chanconf), srate,
|
||||
time/60,
|
||||
time % 60);
|
||||
return out;
|
||||
|
@ -503,7 +510,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
|||
char *buff = (char*)vbuff;
|
||||
|
||||
size_t currentpos = Decoder->getSampleOffset();
|
||||
size_t framestoread = len / (Channels*2);
|
||||
size_t framestoread = len / FrameSize;
|
||||
bool err = false;
|
||||
if (!m_Looping)
|
||||
{
|
||||
|
@ -515,7 +522,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
|||
}
|
||||
if (currentpos + framestoread > maxpos)
|
||||
{
|
||||
size_t got = Decoder->read(buff, (maxpos - currentpos) * Channels * 2);
|
||||
size_t got = Decoder->read(buff, (maxpos - currentpos) * FrameSize);
|
||||
memset(buff + got, 0, len - got);
|
||||
}
|
||||
else
|
||||
|
@ -532,7 +539,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
|||
// Loop can be very short, make sure the current position doesn't exceed it
|
||||
if (currentpos < Loop_End)
|
||||
{
|
||||
size_t endblock = (Loop_End - currentpos) * Channels * 2;
|
||||
size_t endblock = (Loop_End - currentpos) * FrameSize;
|
||||
size_t endlen = Decoder->read(buff, endblock);
|
||||
|
||||
// Even if zero bytes was read give it a chance to start from the beginning
|
||||
|
|
180
source/streamsources/music_libxmp.cpp
Normal file
180
source/streamsources/music_libxmp.cpp
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
** music_libxmp.cpp
|
||||
** libxmp module player.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2024 Cacodemon345
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include "streamsource.h"
|
||||
|
||||
#define LIBXMP_STATIC 1
|
||||
#include "../libxmp/include/xmp.h"
|
||||
#include "zmusic/m_swap.h"
|
||||
#include "zmusic/mididefs.h"
|
||||
#include "zmusic/midiconfig.h"
|
||||
#include "fileio.h"
|
||||
|
||||
extern DumbConfig dumbConfig;
|
||||
|
||||
static unsigned long xmp_read(void *dest, unsigned long len, unsigned long nmemb, void *priv)
|
||||
{
|
||||
if (len == 0 || nmemb == 0)
|
||||
return (unsigned long)0;
|
||||
|
||||
MusicIO::FileInterface* interface = (MusicIO::FileInterface*)priv;
|
||||
|
||||
auto origpos = interface->tell();
|
||||
auto length = interface->read(dest, (int32_t)(len * nmemb));
|
||||
|
||||
if (length != len * nmemb)
|
||||
{
|
||||
// Let's hope the compiler doesn't misoptimize this.
|
||||
interface->seek(origpos + (length / len) * len, SEEK_SET);
|
||||
}
|
||||
return length / len;
|
||||
}
|
||||
|
||||
static struct xmp_callbacks callbacks =
|
||||
{
|
||||
xmp_read,
|
||||
[](void *priv, long offset, int whence) -> int { return ((MusicIO::FileInterface*)priv)->seek(offset, whence); },
|
||||
[](void *priv) -> long { return ((MusicIO::FileInterface*)priv)->tell(); },
|
||||
[](void *priv) -> int { return 0; }
|
||||
};
|
||||
|
||||
class XMPSong : public StreamSource
|
||||
{
|
||||
private:
|
||||
xmp_context context = nullptr;
|
||||
int samplerate = 44100;
|
||||
int subsong = 0;
|
||||
|
||||
// libxmp can't output in float.
|
||||
std::vector<int16_t> int16_buffer;
|
||||
|
||||
public:
|
||||
XMPSong(xmp_context ctx, int samplerate);
|
||||
~XMPSong();
|
||||
bool SetSubsong(int subsong) override;
|
||||
bool Start() override;
|
||||
SoundStreamInfoEx GetFormatEx() override;
|
||||
|
||||
protected:
|
||||
bool GetData(void *buffer, size_t len) override;
|
||||
};
|
||||
|
||||
XMPSong::XMPSong(xmp_context ctx, int rate)
|
||||
{
|
||||
context = ctx;
|
||||
samplerate = (dumbConfig.mod_samplerate != 0) ? dumbConfig.mod_samplerate : rate;
|
||||
xmp_set_player(context, XMP_PLAYER_VOLUME, 100);
|
||||
xmp_set_player(context, XMP_PLAYER_INTERP, dumbConfig.mod_interp);
|
||||
|
||||
int16_buffer.reserve(16 * 1024);
|
||||
}
|
||||
|
||||
XMPSong::~XMPSong()
|
||||
{
|
||||
xmp_end_player(context);
|
||||
xmp_free_context(context);
|
||||
}
|
||||
|
||||
SoundStreamInfoEx XMPSong::GetFormatEx()
|
||||
{
|
||||
return { 32 * 1024, samplerate, SampleType_Float32, ChannelConfig_Stereo };
|
||||
}
|
||||
|
||||
bool XMPSong::SetSubsong(int subsong)
|
||||
{
|
||||
this->subsong = subsong;
|
||||
if (xmp_get_player(context, XMP_PLAYER_STATE) >= XMP_STATE_PLAYING)
|
||||
return xmp_set_position(context, subsong) >= 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XMPSong::GetData(void *buffer, size_t len)
|
||||
{
|
||||
if ((len / 4) > int16_buffer.size())
|
||||
int16_buffer.resize(len / 4);
|
||||
|
||||
int ret = xmp_play_buffer(context, (void*)int16_buffer.data(), len / 2, m_Looping? INT_MAX : 0);
|
||||
xmp_set_player(context, XMP_PLAYER_INTERP, dumbConfig.mod_interp);
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
float* soundbuffer = (float*)buffer;
|
||||
for (unsigned int i = 0; i < len / 4; i++)
|
||||
{
|
||||
soundbuffer[i] = ((int16_buffer[i] < 0.) ? (int16_buffer[i] / 32768.) : (int16_buffer[i] / 32767.)) * dumbConfig.mod_dumb_mastervolume;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0 && m_Looping)
|
||||
{
|
||||
xmp_restart_module(context);
|
||||
xmp_set_position(context, subsong);
|
||||
return true;
|
||||
}
|
||||
|
||||
return ret >= 0;
|
||||
}
|
||||
|
||||
bool XMPSong::Start()
|
||||
{
|
||||
int ret = xmp_start_player(context, samplerate, 0);
|
||||
if (ret >= 0)
|
||||
xmp_set_position(context, subsong);
|
||||
return ret >= 0;
|
||||
}
|
||||
|
||||
StreamSource* XMP_OpenSong(MusicIO::FileInterface* reader, int samplerate)
|
||||
{
|
||||
if (xmp_test_module_from_callbacks((void*)reader, callbacks, nullptr) < 0)
|
||||
return nullptr;
|
||||
|
||||
xmp_context ctx = xmp_create_context();
|
||||
if (!ctx)
|
||||
return nullptr;
|
||||
|
||||
reader->seek(0, SEEK_SET);
|
||||
|
||||
if (xmp_load_module_from_callbacks(ctx, (void*)reader, callbacks) < 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new XMPSong(ctx, samplerate);
|
||||
}
|
||||
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#ifdef HAVE_OPL
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "streamsource.h"
|
||||
#include "oplsynth/opl.h"
|
||||
#include "oplsynth/opl_mus_player.h"
|
||||
|
@ -54,7 +56,7 @@ public:
|
|||
~OPLMUSSong ();
|
||||
bool Start() override;
|
||||
void ChangeSettingInt(const char *name, int value) override;
|
||||
SoundStreamInfo GetFormat() override;
|
||||
SoundStreamInfoEx GetFormatEx() override;
|
||||
|
||||
protected:
|
||||
bool GetData(void *buffer, size_t len) override;
|
||||
|
@ -93,10 +95,11 @@ OPLMUSSong::OPLMUSSong(MusicIO::FileInterface* reader, OPLConfig* config)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
SoundStreamInfo OPLMUSSong::GetFormat()
|
||||
SoundStreamInfoEx OPLMUSSong::GetFormatEx()
|
||||
{
|
||||
int samples = int(OPL_SAMPLE_RATE / 14);
|
||||
return { samples * 4, int(OPL_SAMPLE_RATE), current_opl_core == 0? 1:2 };
|
||||
return { samples * 4, int(OPL_SAMPLE_RATE), SampleType_Float32,
|
||||
current_opl_core == 0? ChannelConfig_Mono:ChannelConfig_Stereo };
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -235,7 +235,7 @@ class XASong : public StreamSource
|
|||
{
|
||||
public:
|
||||
XASong(MusicIO::FileInterface *readr);
|
||||
SoundStreamInfo GetFormat() override;
|
||||
SoundStreamInfoEx GetFormatEx() override;
|
||||
bool Start() override;
|
||||
bool GetData(void *buffer, size_t len) override;
|
||||
|
||||
|
@ -260,10 +260,10 @@ XASong::XASong(MusicIO::FileInterface * reader)
|
|||
getNextXABlock(&xad, false);
|
||||
}
|
||||
|
||||
SoundStreamInfo XASong::GetFormat()
|
||||
SoundStreamInfoEx XASong::GetFormatEx()
|
||||
{
|
||||
auto SampleRate = xad.blockIs18K? 18900 : 37800;
|
||||
return { 64*1024, SampleRate, 2};
|
||||
return { 64*1024, SampleRate, SampleType_Float32, ChannelConfig_Stereo };
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
virtual bool SetPosition(unsigned position) { return false; }
|
||||
virtual bool SetSubsong(int subsong) { return false; }
|
||||
virtual bool GetData(void *buffer, size_t len) = 0;
|
||||
virtual SoundStreamInfo GetFormat() { return {65536, m_OutputRate, 2 }; } // Default format is: System's output sample rate, 32 bit float, stereo
|
||||
virtual SoundStreamInfoEx GetFormatEx() = 0;
|
||||
virtual std::string GetStats() { return ""; }
|
||||
virtual void ChangeSettingInt(const char *name, int value) { }
|
||||
virtual void ChangeSettingNum(const char *name, double value) { }
|
||||
|
@ -33,6 +33,7 @@ protected:
|
|||
|
||||
|
||||
StreamSource *MOD_OpenSong(MusicIO::FileInterface* reader, int samplerate);
|
||||
StreamSource *XMP_OpenSong(MusicIO::FileInterface* reader, int samplerate);
|
||||
StreamSource* GME_OpenSong(MusicIO::FileInterface* reader, const char* fmt, int sample_rate);
|
||||
StreamSource *SndFile_OpenSong(MusicIO::FileInterface* fr);
|
||||
StreamSource* XA_OpenSong(MusicIO::FileInterface* reader);
|
||||
|
|
|
@ -197,9 +197,9 @@ struct MidiDeviceList
|
|||
#ifdef HAVE_WILDMIDI
|
||||
devices.push_back({ strdup("WildMidi"), -6, MIDIDEV_SWSYNTH });
|
||||
#endif
|
||||
#ifdef HAVE_FLUIDSYNTH
|
||||
// this will always exist.
|
||||
devices.push_back({ strdup("FluidSynth"), -5, MIDIDEV_SWSYNTH });
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GUS
|
||||
devices.push_back({ strdup("GUS Emulation"), -4, MIDIDEV_SWSYNTH });
|
||||
#endif
|
||||
|
@ -503,7 +503,7 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSon
|
|||
|
||||
case zmusic_gus_memsize:
|
||||
ChangeAndReturn(gusConfig.gus_memsize, value, pRealValue);
|
||||
return devType() == MDEV_GUS && gusConfig.gus_dmxgus;
|
||||
return devType() == MDEV_GUS;
|
||||
#endif
|
||||
#ifdef HAVE_TIMIDITY
|
||||
case zmusic_timidity_modulation_wheel:
|
||||
|
@ -518,15 +518,15 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSon
|
|||
|
||||
case zmusic_timidity_reverb:
|
||||
if (value < 0 || value > 4) value = 0;
|
||||
else TimidityPlus_SetReverb();
|
||||
local_timidity_reverb = value;
|
||||
TimidityPlus_SetReverb();
|
||||
if (pRealValue) *pRealValue = value;
|
||||
return false;
|
||||
|
||||
case zmusic_timidity_reverb_level:
|
||||
if (value < 0 || value > 127) value = 0;
|
||||
else TimidityPlus_SetReverb();
|
||||
local_timidity_reverb_level = value;
|
||||
TimidityPlus_SetReverb();
|
||||
if (pRealValue) *pRealValue = value;
|
||||
return false;
|
||||
|
||||
|
@ -652,6 +652,10 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSon
|
|||
miscConfig.snd_outputrate = value;
|
||||
return false;
|
||||
|
||||
case zmusic_mod_preferredplayer:
|
||||
dumbConfig.mod_preferred_player = value;
|
||||
return false;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -678,8 +682,8 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* cur
|
|||
case zmusic_fluid_reverb_roomsize:
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
else if (value > 1.2f)
|
||||
value = 1.2f;
|
||||
else if (value > 1.0f)
|
||||
value = 1.0f;
|
||||
|
||||
if (currSong != NULL)
|
||||
currSong->ChangeSettingNum("fluidsynth.z.reverb", value);
|
||||
|
@ -736,8 +740,8 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* cur
|
|||
return false;
|
||||
|
||||
case zmusic_fluid_chorus_speed:
|
||||
if (value < 0.29f)
|
||||
value = 0.29f;
|
||||
if (value < 0.1f)
|
||||
value = 0.1f;
|
||||
else if (value > 5)
|
||||
value = 5;
|
||||
|
||||
|
@ -751,8 +755,8 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* cur
|
|||
case zmusic_fluid_chorus_depth:
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
else if (value > 21)
|
||||
value = 21;
|
||||
else if (value > 256)
|
||||
value = 256;
|
||||
|
||||
if (currSong != NULL)
|
||||
currSong->ChangeSettingNum("fluidsynth.z.chorus", value);
|
||||
|
@ -942,6 +946,7 @@ static ZMusicConfigurationSetting config[] = {
|
|||
{"zmusic_mod_autochip_size_force", zmusic_mod_autochip_size_force, ZMUSIC_VAR_INT, 100},
|
||||
{"zmusic_mod_autochip_size_scan", zmusic_mod_autochip_size_scan, ZMUSIC_VAR_INT, 500},
|
||||
{"zmusic_mod_autochip_scan_threshold", zmusic_mod_autochip_scan_threshold, ZMUSIC_VAR_INT, 12},
|
||||
{"zmusic_mod_preferred_player", zmusic_mod_preferredplayer, ZMUSIC_VAR_INT, 0},
|
||||
{"zmusic_mod_dumb_mastervolume", zmusic_mod_dumb_mastervolume, ZMUSIC_VAR_FLOAT, 1},
|
||||
|
||||
{"zmusic_gme_stereodepth", zmusic_gme_stereodepth, ZMUSIC_VAR_FLOAT, 0},
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
@ -220,6 +221,9 @@ struct VectorReader : public MemoryReader
|
|||
{
|
||||
mVector.resize(size);
|
||||
memcpy(mVector.data(), data, size);
|
||||
mData = mVector.data();
|
||||
mLength = (long)size;
|
||||
mPos = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -320,7 +324,7 @@ public:
|
|||
std::string fullname;
|
||||
if (!fn)
|
||||
{
|
||||
f = utf8_fopen(mBaseFile.c_str(), "rt");
|
||||
f = utf8_fopen(mBaseFile.c_str(), "rb");
|
||||
fullname = mBaseFile;
|
||||
}
|
||||
else
|
||||
|
@ -330,11 +334,11 @@ public:
|
|||
for(int i = (int)mPaths.size()-1; i>=0; i--)
|
||||
{
|
||||
fullname = mPaths[i] + fn;
|
||||
f = utf8_fopen(fullname.c_str(), "rt");
|
||||
break;
|
||||
f = utf8_fopen(fullname.c_str(), "rb");
|
||||
if (f) break;
|
||||
}
|
||||
}
|
||||
if (!f) f = fopen(fn, "rt");
|
||||
if (!f) f = fopen(fn, "rb");
|
||||
}
|
||||
if (!f) return nullptr;
|
||||
auto tf = new StdioFileReader;
|
||||
|
|
|
@ -129,6 +129,7 @@ struct DumbConfig
|
|||
int mod_autochip_size_force = 100;
|
||||
int mod_autochip_size_scan = 500;
|
||||
int mod_autochip_scan_threshold = 12;
|
||||
int mod_preferred_player = 0;
|
||||
float mod_dumb_mastervolume = 1;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
virtual void ChangeSettingNum(const char* setting, double value) {} // "
|
||||
virtual void ChangeSettingString(const char* setting, const char* value) {} // "
|
||||
virtual bool ServiceStream(void *buff, int len) { return false; }
|
||||
virtual SoundStreamInfo GetStreamInfo() const { return { 0,0,0 }; }
|
||||
virtual SoundStreamInfoEx GetStreamInfoEx() const = 0;
|
||||
|
||||
enum EState
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <zlib.h>
|
||||
#include <miniz.h>
|
||||
#include "m_swap.h"
|
||||
#include "zmusic_internal.h"
|
||||
#include "midiconfig.h"
|
||||
|
@ -257,10 +257,28 @@ static MusInfo *ZMusic_OpenSongInternal (MusicIO::FileInterface *reader, EMidiD
|
|||
streamsource = GME_OpenSong(reader, fmt, miscConfig.snd_outputrate);
|
||||
}
|
||||
// Check for module formats
|
||||
else
|
||||
else if ((id[0] == MAKE_ID('R', 'I', 'F', 'F') && id[2] == MAKE_ID('D', 'S', 'M', 'F')))
|
||||
{
|
||||
streamsource = MOD_OpenSong(reader, miscConfig.snd_outputrate);
|
||||
}
|
||||
else
|
||||
{
|
||||
// give the calling app an option to select between XMP and DUMB.
|
||||
if (dumbConfig.mod_preferred_player != 0)
|
||||
{
|
||||
streamsource = MOD_OpenSong(reader, miscConfig.snd_outputrate);
|
||||
}
|
||||
if (!streamsource)
|
||||
{
|
||||
reader->seek(0, SEEK_SET);
|
||||
streamsource = XMP_OpenSong(reader, miscConfig.snd_outputrate);
|
||||
if (!streamsource && dumbConfig.mod_preferred_player == 0)
|
||||
{
|
||||
reader->seek(0, SEEK_SET);
|
||||
streamsource = MOD_OpenSong(reader, miscConfig.snd_outputrate);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (streamsource == nullptr)
|
||||
{
|
||||
streamsource = SndFile_OpenSong(reader); // this only takes over the reader if it succeeds. We need to look out for this.
|
||||
|
@ -453,11 +471,34 @@ DLL_EXPORT zmusic_bool ZMusic_IsMIDI(MusInfo *song)
|
|||
}
|
||||
|
||||
DLL_EXPORT void ZMusic_GetStreamInfo(MusInfo *song, SoundStreamInfo *fmt)
|
||||
{
|
||||
if (!fmt) return;
|
||||
*fmt = {};
|
||||
|
||||
if (!song)
|
||||
return;
|
||||
|
||||
SoundStreamInfoEx fmtex;
|
||||
{
|
||||
std::lock_guard<FCriticalSection> lock(song->CritSec);
|
||||
fmtex = song->GetStreamInfoEx();
|
||||
}
|
||||
if (fmtex.mSampleRate > 0)
|
||||
{
|
||||
fmt->mBufferSize = fmtex.mBufferSize;
|
||||
fmt->mSampleRate = fmtex.mSampleRate;
|
||||
fmt->mNumChannels = ZMusic_ChannelCount(fmtex.mChannelConfig);
|
||||
if (fmtex.mSampleType == SampleType_Int16)
|
||||
fmt->mNumChannels *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void ZMusic_GetStreamInfoEx(MusInfo *song, SoundStreamInfoEx *fmt)
|
||||
{
|
||||
if (!fmt) return;
|
||||
if (!song) *fmt = {};
|
||||
std::lock_guard<FCriticalSection> lock(song->CritSec);
|
||||
*fmt = song->GetStreamInfo();
|
||||
*fmt = song->GetStreamInfoEx();
|
||||
}
|
||||
|
||||
DLL_EXPORT void ZMusic_Close(MusInfo *song)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#pragma once
|
||||
#define ZMUSIC_INTERNAL
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(ZMUSIC_STATIC)
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
#define DLL_IMPORT __declspec(dllexport) // without this the compiler complains.
|
||||
#else // !_MSC_VER
|
||||
#else
|
||||
#define DLL_EXPORT
|
||||
#define DLL_IMPORT
|
||||
#endif // _MSC_VER
|
||||
#endif
|
||||
|
||||
typedef class MIDISource *ZMusic_MidiSource;
|
||||
typedef class MusInfo *ZMusic_MusicStream;
|
||||
|
@ -49,3 +49,34 @@ struct CustomFileReader : public MusicIO::FileInterface
|
|||
|
||||
|
||||
void ZMusic_Printf(int type, const char* msg, ...);
|
||||
|
||||
inline uint8_t ZMusic_SampleTypeSize(SampleType stype)
|
||||
{
|
||||
switch(stype)
|
||||
{
|
||||
case SampleType_UInt8: return sizeof(uint8_t);
|
||||
case SampleType_Int16: return sizeof(int16_t);
|
||||
case SampleType_Float32: return sizeof(float);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint8_t ZMusic_ChannelCount(ChannelConfig chans)
|
||||
{
|
||||
switch(chans)
|
||||
{
|
||||
case ChannelConfig_Mono: return 1;
|
||||
case ChannelConfig_Stereo: return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline const char *ZMusic_ChannelConfigName(ChannelConfig chans)
|
||||
{
|
||||
switch(chans)
|
||||
{
|
||||
case ChannelConfig_Mono: return "Mono";
|
||||
case ChannelConfig_Stereo: return "Stereo";
|
||||
}
|
||||
return "(unknown)";
|
||||
}
|
||||
|
|
22
thirdparty/CMakeLists.txt
vendored
22
thirdparty/CMakeLists.txt
vendored
|
@ -1,20 +1,4 @@
|
|||
option(FORCE_INTERNAL_ZLIB "Use internal zlib" OFF)
|
||||
find_package(ZLIB QUIET)
|
||||
if(ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB)
|
||||
message(STATUS "Using system zlib, includes found at ${ZLIB_INCLUDE_DIRS}")
|
||||
set_property(TARGET ZLIB::ZLIB PROPERTY IMPORTED_GLOBAL TRUE)
|
||||
determine_package_config_dependency(ZMUSIC_PACKAGE_DEPENDENCIES TARGET ZLIB::ZLIB MODULE ZLIB)
|
||||
else()
|
||||
message(STATUS "Using internal zlib")
|
||||
set(SKIP_INSTALL_ALL TRUE) # Avoid installing zlib alongside ZMusic
|
||||
add_subdirectory(zlib)
|
||||
add_library(ZLIB::ZLIB ALIAS z)
|
||||
|
||||
# Setup variables for GME's CMakeLists
|
||||
set(ZLIB_LIBRARY ZLIB::ZLIB)
|
||||
get_property(ZLIB_INCLUDE_DIR TARGET ZLIB::ZLIB PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
||||
endif()
|
||||
|
||||
add_subdirectory(miniz)
|
||||
# GME is not currently released in a way that's conducive to using as a system
|
||||
# library. Nevertheless at least one person tried, and so the ability to use a
|
||||
# system copy exists soley to placate people following distro guidelines to the
|
||||
|
@ -31,7 +15,7 @@ endif()
|
|||
# message(STATUS "Using internal gme library")
|
||||
# Use MAME as it's a balanced emulator: well-accurate, but doesn't eats lot of CPU
|
||||
# Nuked OPN2 is very accurate emulator, but it eats too much CPU for the workflow
|
||||
set(GME_YM2612_EMU "MAME" CACHE STRING "Which YM2612 emulator to use: \"Nuked\" (LGPLv2.1+), \"MAME\" (GPLv2+), or \"GENS\" (LGPLv2.1+)")
|
||||
set(GME_YM2612_EMU "Nuked" CACHE STRING "Which YM2612 emulator to use: \"Nuked\" (LGPLv2.1+), \"MAME\" (GPLv2+), or \"GENS\" (LGPLv2.1+)")
|
||||
mark_as_advanced(GME_YM2612_EMU)
|
||||
add_subdirectory(game-music-emu)
|
||||
#endif()
|
||||
|
@ -43,3 +27,5 @@ add_subdirectory(timidity)
|
|||
add_subdirectory(timidityplus)
|
||||
add_subdirectory(wildmidi)
|
||||
add_subdirectory(oplsynth)
|
||||
add_subdirectory(libxmp)
|
||||
add_subdirectory(fluidsynth/src)
|
||||
|
|
340
thirdparty/adlmidi/adlmidi.cpp
vendored
340
thirdparty/adlmidi/adlmidi.cpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -551,6 +551,24 @@ ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, in
|
|||
play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0);
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT void adl_setAutoArpeggio(ADL_MIDIPlayer *device, int aaEn)
|
||||
{
|
||||
if(!device)
|
||||
return;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
play->m_setup.enableAutoArpeggio = (aaEn != 0);
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT int adl_getAutoArpeggio(ADL_MIDIPlayer *device)
|
||||
{
|
||||
if(!device)
|
||||
return 0;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
return play->m_setup.enableAutoArpeggio ? 1 : 0;
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
|
||||
{
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
|
@ -565,6 +583,34 @@ ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
|
|||
#endif
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT void adl_setLoopCount(ADL_MIDIPlayer *device, int loopCount)
|
||||
{
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
if(!device)
|
||||
return;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
play->m_sequencer->setLoopsCount(loopCount);
|
||||
#else
|
||||
ADL_UNUSED(device);
|
||||
ADL_UNUSED(loopCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT void adl_setLoopHooksOnly(ADL_MIDIPlayer *device, int loopHooksOnly)
|
||||
{
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
if(!device)
|
||||
return;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
play->m_sequencer->setLoopHooksOnly(loopHooksOnly);
|
||||
#else
|
||||
ADL_UNUSED(device);
|
||||
ADL_UNUSED(loopHooksOnly);
|
||||
#endif
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT void adl_setSoftPanEnabled(ADL_MIDIPlayer *device, int softPanEn)
|
||||
{
|
||||
if(!device)
|
||||
|
@ -618,6 +664,29 @@ ADLMIDI_EXPORT int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device)
|
|||
return play->m_synth->getVolumeScaleModel();
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT void adl_setChannelAllocMode(struct ADL_MIDIPlayer *device, int chanalloc)
|
||||
{
|
||||
if(!device)
|
||||
return;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
Synth &synth = *play->m_synth;
|
||||
|
||||
if(chanalloc < -1 || chanalloc >= ADLMIDI_ChanAlloc_Count)
|
||||
chanalloc = ADLMIDI_ChanAlloc_AUTO;
|
||||
|
||||
synth.m_channelAlloc = static_cast<ADLMIDI_ChannelAlloc>(chanalloc);
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT int adl_getChannelAllocMode(struct ADL_MIDIPlayer *device)
|
||||
{
|
||||
if(!device)
|
||||
return -1;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
return static_cast<int>(play->m_synth->m_channelAlloc);
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath)
|
||||
{
|
||||
if(device)
|
||||
|
@ -716,6 +785,35 @@ ADLMIDI_EXPORT int adl_openData(ADL_MIDIPlayer *device, const void *mem, unsigne
|
|||
return -1;
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT void adl_selectSongNum(struct ADL_MIDIPlayer *device, int songNumber)
|
||||
{
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
if(!device)
|
||||
return;
|
||||
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
play->m_sequencer->setSongNum(songNumber);
|
||||
#else
|
||||
ADL_UNUSED(device);
|
||||
ADL_UNUSED(songNumber);
|
||||
#endif
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT int adl_getSongsCount(struct ADL_MIDIPlayer *device)
|
||||
{
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
if(!device)
|
||||
return 0;
|
||||
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
return play->m_sequencer->getSongsCount();
|
||||
#else
|
||||
ADL_UNUSED(device);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT const char *adl_emulatorName()
|
||||
{
|
||||
|
@ -1083,6 +1181,36 @@ ADLMIDI_EXPORT void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_D
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Set loop start hook */
|
||||
ADLMIDI_EXPORT void adl_setLoopStartHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopStartHook, void *userData)
|
||||
{
|
||||
if(!device)
|
||||
return;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
play->hooks.onLoopStart = loopStartHook;
|
||||
play->hooks.onLoopStart_userData = userData;
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
play->m_sequencerInterface->onloopStart = loopStartHook;
|
||||
play->m_sequencerInterface->onloopStart_userData = userData;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set loop end hook */
|
||||
ADLMIDI_EXPORT void adl_setLoopEndHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopEndHook, void *userData)
|
||||
{
|
||||
if(!device)
|
||||
return;
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
play->hooks.onLoopEnd = loopEndHook;
|
||||
play->hooks.onLoopEnd_userData = userData;
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
play->m_sequencerInterface->onloopEnd = loopEndHook;
|
||||
play->m_sequencerInterface->onloopEnd_userData = userData;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef ADLMIDI_HW_OPL
|
||||
|
||||
# ifndef __WATCOMC__
|
||||
|
@ -1310,74 +1438,69 @@ ADLMIDI_EXPORT int adl_playFormat(ADL_MIDIPlayer *device, int sampleCount,
|
|||
|
||||
while(left > 0)
|
||||
{
|
||||
{//...
|
||||
if(setup.delay <= 0.0)
|
||||
setup.delay = double(left / 2) / double(setup.PCM_RATE);
|
||||
const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
|
||||
if(hasSkipped)
|
||||
const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
|
||||
if(hasSkipped)
|
||||
{
|
||||
size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay;
|
||||
n_periodCountStereo = samples / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
setup.delay -= eat_delay;
|
||||
setup.carry += double(setup.PCM_RATE) * eat_delay;
|
||||
n_periodCountStereo = static_cast<ssize_t>(setup.carry);
|
||||
setup.carry -= double(n_periodCountStereo);
|
||||
}
|
||||
|
||||
//if(setup.SkipForward > 0)
|
||||
// setup.SkipForward -= 1;
|
||||
//else
|
||||
{
|
||||
if((player->m_sequencer->positionAtEnd()) && (setup.delay <= 0.0))
|
||||
break;//Stop to fetch samples at reaching the song end with disabled loop
|
||||
|
||||
ssize_t leftSamples = left / 2;
|
||||
if(n_periodCountStereo > leftSamples)
|
||||
{
|
||||
size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay;
|
||||
n_periodCountStereo = samples / 2;
|
||||
setup.tick_skip_samples_delay = (n_periodCountStereo - leftSamples) * 2;
|
||||
n_periodCountStereo = leftSamples;
|
||||
}
|
||||
else
|
||||
//! Count of stereo samples
|
||||
ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo;
|
||||
//! Total count of samples
|
||||
ssize_t in_generatedPhys = in_generatedStereo * 2;
|
||||
//! Unsigned total sample count
|
||||
//fill buffer with zeros
|
||||
int32_t *out_buf = player->m_outBuf;
|
||||
std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
|
||||
Synth &synth = *player->m_synth;
|
||||
unsigned int chips = synth.m_numChips;
|
||||
if(chips == 1)
|
||||
{
|
||||
setup.delay -= eat_delay;
|
||||
setup.carry += double(setup.PCM_RATE) * eat_delay;
|
||||
n_periodCountStereo = static_cast<ssize_t>(setup.carry);
|
||||
setup.carry -= double(n_periodCountStereo);
|
||||
synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
|
||||
}
|
||||
else if(n_periodCountStereo > 0)
|
||||
{
|
||||
/* Generate data from every chip and mix result */
|
||||
for(size_t card = 0; card < chips; ++card)
|
||||
synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
|
||||
}
|
||||
|
||||
//if(setup.SkipForward > 0)
|
||||
// setup.SkipForward -= 1;
|
||||
//else
|
||||
{
|
||||
if((player->m_sequencer->positionAtEnd()) && (setup.delay <= 0.0))
|
||||
break;//Stop to fetch samples at reaching the song end with disabled loop
|
||||
/* Process it */
|
||||
if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
|
||||
return 0;
|
||||
|
||||
ssize_t leftSamples = left / 2;
|
||||
if(n_periodCountStereo > leftSamples)
|
||||
{
|
||||
setup.tick_skip_samples_delay = (n_periodCountStereo - leftSamples) * 2;
|
||||
n_periodCountStereo = leftSamples;
|
||||
}
|
||||
//! Count of stereo samples
|
||||
ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo;
|
||||
//! Total count of samples
|
||||
ssize_t in_generatedPhys = in_generatedStereo * 2;
|
||||
//! Unsigned total sample count
|
||||
//fill buffer with zeros
|
||||
int32_t *out_buf = player->m_outBuf;
|
||||
std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
|
||||
Synth &synth = *player->m_synth;
|
||||
unsigned int chips = synth.m_numChips;
|
||||
if(chips == 1)
|
||||
{
|
||||
synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
|
||||
}
|
||||
else if(n_periodCountStereo > 0)
|
||||
{
|
||||
/* Generate data from every chip and mix result */
|
||||
for(size_t card = 0; card < chips; ++card)
|
||||
synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
|
||||
}
|
||||
left -= (int)in_generatedPhys;
|
||||
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
|
||||
}
|
||||
|
||||
/* Process it */
|
||||
if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
|
||||
return 0;
|
||||
|
||||
left -= (int)in_generatedPhys;
|
||||
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
|
||||
}
|
||||
|
||||
if(hasSkipped)
|
||||
{
|
||||
setup.tick_skip_samples_delay -= n_periodCountStereo * 2;
|
||||
hasSkipped = setup.tick_skip_samples_delay > 0;
|
||||
}
|
||||
else
|
||||
setup.delay = player->Tick(eat_delay, setup.mindelay);
|
||||
|
||||
}//...
|
||||
if(hasSkipped)
|
||||
{
|
||||
setup.tick_skip_samples_delay -= n_periodCountStereo * 2;
|
||||
hasSkipped = setup.tick_skip_samples_delay > 0;
|
||||
}
|
||||
else
|
||||
setup.delay = player->Tick(eat_delay, setup.mindelay);
|
||||
}
|
||||
|
||||
return static_cast<int>(gotten_len);
|
||||
|
@ -1420,47 +1543,45 @@ ADLMIDI_EXPORT int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleC
|
|||
|
||||
while(left > 0)
|
||||
{
|
||||
{//...
|
||||
if(delay <= 0.0)
|
||||
delay = double(left / 2) / double(setup.PCM_RATE);
|
||||
const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
|
||||
delay -= eat_delay;
|
||||
setup.carry += double(setup.PCM_RATE) * eat_delay;
|
||||
n_periodCountStereo = static_cast<ssize_t>(setup.carry);
|
||||
setup.carry -= double(n_periodCountStereo);
|
||||
if(delay <= 0.0)
|
||||
delay = double(left / 2) / double(setup.PCM_RATE);
|
||||
const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
|
||||
delay -= eat_delay;
|
||||
setup.carry += double(setup.PCM_RATE) * eat_delay;
|
||||
n_periodCountStereo = static_cast<ssize_t>(setup.carry);
|
||||
setup.carry -= double(n_periodCountStereo);
|
||||
|
||||
{
|
||||
ssize_t leftSamples = left / 2;
|
||||
if(n_periodCountStereo > leftSamples)
|
||||
n_periodCountStereo = leftSamples;
|
||||
//! Count of stereo samples
|
||||
ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo;
|
||||
//! Total count of samples
|
||||
ssize_t in_generatedPhys = in_generatedStereo * 2;
|
||||
//! Unsigned total sample count
|
||||
//fill buffer with zeros
|
||||
int32_t *out_buf = player->m_outBuf;
|
||||
std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
|
||||
Synth &synth = *player->m_synth;
|
||||
unsigned int chips = synth.m_numChips;
|
||||
if(chips == 1)
|
||||
synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
|
||||
else if(n_periodCountStereo > 0)
|
||||
{
|
||||
ssize_t leftSamples = left / 2;
|
||||
if(n_periodCountStereo > leftSamples)
|
||||
n_periodCountStereo = leftSamples;
|
||||
//! Count of stereo samples
|
||||
ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo;
|
||||
//! Total count of samples
|
||||
ssize_t in_generatedPhys = in_generatedStereo * 2;
|
||||
//! Unsigned total sample count
|
||||
//fill buffer with zeros
|
||||
int32_t *out_buf = player->m_outBuf;
|
||||
std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
|
||||
Synth &synth = *player->m_synth;
|
||||
unsigned int chips = synth.m_numChips;
|
||||
if(chips == 1)
|
||||
synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
|
||||
else if(n_periodCountStereo > 0)
|
||||
{
|
||||
/* Generate data from every chip and mix result */
|
||||
for(unsigned card = 0; card < chips; ++card)
|
||||
synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
|
||||
}
|
||||
/* Process it */
|
||||
if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
|
||||
return 0;
|
||||
|
||||
left -= (int)in_generatedPhys;
|
||||
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
|
||||
/* Generate data from every chip and mix result */
|
||||
for(unsigned card = 0; card < chips; ++card)
|
||||
synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
|
||||
}
|
||||
/* Process it */
|
||||
if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
|
||||
return 0;
|
||||
|
||||
player->TickIterators(eat_delay);
|
||||
}//...
|
||||
left -= (int)in_generatedPhys;
|
||||
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
|
||||
}
|
||||
|
||||
player->TickIterators(eat_delay);
|
||||
}
|
||||
|
||||
return static_cast<int>(gotten_len);
|
||||
|
@ -1552,6 +1673,27 @@ ADLMIDI_EXPORT int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t tra
|
|||
#endif
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT int adl_setChannelEnabled(struct ADL_MIDIPlayer *device, size_t channelNumber, int enabled)
|
||||
{
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
if(!device)
|
||||
return -1;
|
||||
|
||||
MidiPlayer *play = GET_MIDI_PLAYER(device);
|
||||
assert(play);
|
||||
MidiSequencer &seq = *play->m_sequencer;
|
||||
|
||||
if(!seq.setChannelEnabled(channelNumber, (bool)enabled))
|
||||
return -1;
|
||||
return 0;
|
||||
#else
|
||||
ADL_UNUSED(device);
|
||||
ADL_UNUSED(channelNumber);
|
||||
ADL_UNUSED(enabled);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ADLMIDI_EXPORT int adl_setTriggerHandler(struct ADL_MIDIPlayer *device, ADL_TriggerHandler handler, void *userData)
|
||||
{
|
||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||
|
|
151
thirdparty/adlmidi/adlmidi.h
vendored
151
thirdparty/adlmidi/adlmidi.h
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -30,7 +30,7 @@ extern "C" {
|
|||
|
||||
#define ADLMIDI_VERSION_MAJOR 1
|
||||
#define ADLMIDI_VERSION_MINOR 5
|
||||
#define ADLMIDI_VERSION_PATCHLEVEL 0
|
||||
#define ADLMIDI_VERSION_PATCHLEVEL 1
|
||||
|
||||
#define ADLMIDI_TOSTR_I(s) #s
|
||||
#define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s)
|
||||
|
@ -125,7 +125,26 @@ enum ADLMIDI_VolumeModels
|
|||
/*! HMI Sound Operating System volume scaling model */
|
||||
ADLMIDI_VolumeModel_HMI = 10,
|
||||
/*! HMI Sound Operating System volume scaling model, older variant with bugs */
|
||||
ADLMIDI_VolumeModel_HMI_OLD = 11
|
||||
ADLMIDI_VolumeModel_HMI_OLD = 11,
|
||||
/*! Count of available volume model modes */
|
||||
ADLMIDI_VolumeModel_Count
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Algorithms of channel allocation for new notes
|
||||
*/
|
||||
enum ADLMIDI_ChannelAlloc
|
||||
{
|
||||
/*! Automatical choise of the method according to the volume model and internal preferrences */
|
||||
ADLMIDI_ChanAlloc_AUTO = -1,
|
||||
/*! Take only channels that has expired sounding delay */
|
||||
ADLMIDI_ChanAlloc_OffDelay,
|
||||
/*! Take any first released channel with the same instrument */
|
||||
ADLMIDI_ChanAlloc_SameInst,
|
||||
/*! Take any first released channel */
|
||||
ADLMIDI_ChanAlloc_AnyReleased,
|
||||
/*! Count of available channel allocation modes */
|
||||
ADLMIDI_ChanAlloc_Count
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -548,6 +567,21 @@ extern ADLMIDI_DECLSPEC void adl_setScaleModulators(struct ADL_MIDIPlayer *devic
|
|||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness);
|
||||
|
||||
/**
|
||||
* @brief Enable(1) or Disable(0) the automatical arpeggio system
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param aaEn 0 - disabled, 1 - enabled
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setAutoArpeggio(struct ADL_MIDIPlayer *device, int aaEn);
|
||||
|
||||
/**
|
||||
* @brief Get the state of the automatical arpeggio system enable state
|
||||
* @param device Instalce of the library
|
||||
* @return 0 - disabled, 1 - enabled
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC int adl_getAutoArpeggio(struct ADL_MIDIPlayer *device);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part)
|
||||
* @param device Instance of the library
|
||||
|
@ -555,6 +589,23 @@ extern ADLMIDI_DECLSPEC void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *d
|
|||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn);
|
||||
|
||||
/**
|
||||
* @brief Set how many times loop will be played
|
||||
*
|
||||
* Note: The song will be played once if loop has been disabled with no matter which value of loop count was set
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param loopCount Number of loops or -1 to loop infinitely
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setLoopCount(struct ADL_MIDIPlayer *device, int loopCount);
|
||||
|
||||
/**
|
||||
* @brief Make song immediately stop on reaching a loop end point
|
||||
* @param device Instance of the library
|
||||
* @param loopHooksOnly 0 - disabled, 1 - enabled
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setLoopHooksOnly(struct ADL_MIDIPlayer *device, int loopHooksOnly);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable soft panning with chip emulators
|
||||
* @param device Instance of the library
|
||||
|
@ -584,6 +635,20 @@ extern ADLMIDI_DECLSPEC void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *devi
|
|||
*/
|
||||
extern ADLMIDI_DECLSPEC int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device);
|
||||
|
||||
/**
|
||||
* @brief Set the channel allocation mode
|
||||
* @param device Instance of the library
|
||||
* @param chanalloc Channel allocation mode (#ADLMIDI_ChannelAlloc)
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setChannelAllocMode(struct ADL_MIDIPlayer *device, int chanalloc);
|
||||
|
||||
/**
|
||||
* @brief Get the current channel allocation mode
|
||||
* @param device Instance of the library
|
||||
* @return Channel allocation mode (#ADLMIDI_ChannelAlloc)
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC int adl_getChannelAllocMode(struct ADL_MIDIPlayer *device);
|
||||
|
||||
/**
|
||||
* @brief Load WOPL bank file from File System
|
||||
*
|
||||
|
@ -766,6 +831,27 @@ extern ADLMIDI_DECLSPEC int adl_openFile(struct ADL_MIDIPlayer *device, const ch
|
|||
*/
|
||||
extern ADLMIDI_DECLSPEC int adl_openData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size);
|
||||
|
||||
/**
|
||||
* @brief Switch another song if multi-song file is playing (for example, XMI)
|
||||
*
|
||||
* Note: to set the initial song to load, you should call this function
|
||||
* BBEFORE calling `adl_openFile` or `adl_openData`. When loaded file has more than
|
||||
* one built-in songs (Usually XMIformat), it will be started from the selected number.
|
||||
* You may call this function to switch another song.
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param songNumber Identifier of the track to load (or -1 to mix all tracks as one song)
|
||||
* @return
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_selectSongNum(struct ADL_MIDIPlayer *device, int songNumber);
|
||||
|
||||
/**
|
||||
* @brief Retrive the number of songs in a currently opened file
|
||||
* @param device Instance of the library
|
||||
* @return Number of songs in the file. If 1 or less, means, the file has only one song inside.
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC int adl_getSongsCount(struct ADL_MIDIPlayer *device);
|
||||
|
||||
/**
|
||||
* @brief Resets MIDI player (per-channel setup) into initial state
|
||||
* @param device Instance of the library
|
||||
|
@ -876,6 +962,15 @@ enum ADLMIDI_TrackOptions
|
|||
*/
|
||||
extern ADLMIDI_DECLSPEC int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions);
|
||||
|
||||
/**
|
||||
* @brief Sets the channel of the current sequence enable state
|
||||
* @param device Instance of the library
|
||||
* @param channelNumber Number of the channel (from 0 to 15)
|
||||
* @param enabled 1 to enable and 0 to disable
|
||||
* @return 0 on success, <0 when any error has occurred
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC int adl_setChannelEnabled(struct ADL_MIDIPlayer *device, size_t channelNumber, int enabled);
|
||||
|
||||
/**
|
||||
* @brief Handler of callback trigger events
|
||||
* @param userData Pointer to user data (usually, context of something)
|
||||
|
@ -1210,8 +1305,19 @@ typedef void (*ADL_NoteHook)(void *userdata, int adlchn, int note, int ins, int
|
|||
*/
|
||||
typedef void (*ADL_DebugMessageHook)(void *userdata, const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* @brief Loop start/end point reach hook
|
||||
* @param userdata Pointer to user data (usually, context of someting)
|
||||
*/
|
||||
typedef void (*ADL_LoopPointHook)(void *userdata);
|
||||
|
||||
/**
|
||||
* @brief Set raw MIDI event hook
|
||||
*
|
||||
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
|
||||
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
|
||||
* apply your action outside of this hook, for example, in the next after audio output call.
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param rawEventHook Pointer to the callback function which will be called on every MIDI event
|
||||
* @param userData Pointer to user data which will be passed through the callback.
|
||||
|
@ -1220,6 +1326,11 @@ extern ADLMIDI_DECLSPEC void adl_setRawEventHook(struct ADL_MIDIPlayer *device,
|
|||
|
||||
/**
|
||||
* @brief Set note hook
|
||||
*
|
||||
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
|
||||
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
|
||||
* apply your action outside of this hook, for example, in the next after audio output call.
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param noteHook Pointer to the callback function which will be called on every noteOn MIDI event
|
||||
* @param userData Pointer to user data which will be passed through the callback.
|
||||
|
@ -1228,12 +1339,46 @@ extern ADLMIDI_DECLSPEC void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_
|
|||
|
||||
/**
|
||||
* @brief Set debug message hook
|
||||
*
|
||||
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
|
||||
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
|
||||
* apply your action outside of this hook, for example, in the next after audio output call.
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param debugMessageHook Pointer to the callback function which will be called on every debug message
|
||||
* @param userData Pointer to user data which will be passed through the callback.
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData);
|
||||
|
||||
/**
|
||||
* @brief Set the look start point hook
|
||||
*
|
||||
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
|
||||
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
|
||||
* apply your action outside of this hook, for example, in the next after audio output call.
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param loopStartHook Pointer to the callback function which will be called on every loop start point passing
|
||||
* @param userData Pointer to user data which will be passed through the callback.
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setLoopStartHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopStartHook, void *userData);
|
||||
|
||||
/**
|
||||
* @brief Set the look start point hook
|
||||
*
|
||||
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
|
||||
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
|
||||
* apply your action outside of this hook, for example, in the next after audio output call.
|
||||
*
|
||||
* If you want to switch the song after calling this hook, suggested to call the function
|
||||
* adl_setLoopHooksOnly(device, 1) to immediately stop the song on reaching the loop point
|
||||
*
|
||||
* @param device Instance of the library
|
||||
* @param loopStartHook Pointer to the callback function which will be called on every loop start point passing
|
||||
* @param userData Pointer to user data which will be passed through the callback.
|
||||
*/
|
||||
extern ADLMIDI_DECLSPEC void adl_setLoopEndHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopEndHook, void *userData);
|
||||
|
||||
/**
|
||||
* @brief Get a textual description of the channel state. For display only.
|
||||
* @param device Instance of the library
|
||||
|
|
2
thirdparty/adlmidi/adlmidi_bankmap.h
vendored
2
thirdparty/adlmidi/adlmidi_bankmap.h
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
|
2
thirdparty/adlmidi/adlmidi_bankmap.tcc
vendored
2
thirdparty/adlmidi/adlmidi_bankmap.tcc
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
|
2
thirdparty/adlmidi/adlmidi_cvt.hpp
vendored
2
thirdparty/adlmidi/adlmidi_cvt.hpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
|
4
thirdparty/adlmidi/adlmidi_db.h
vendored
4
thirdparty/adlmidi/adlmidi_db.h
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -31,7 +31,7 @@
|
|||
#include <stddef.h>
|
||||
#include <vector>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && !defined(__aarch64__) && !defined(__3DS__)
|
||||
#define ATTRIB_PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define ATTRIB_PACKED
|
||||
|
|
3
thirdparty/adlmidi/adlmidi_load.cpp
vendored
3
thirdparty/adlmidi/adlmidi_load.cpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -117,6 +117,7 @@ bool MIDIplay::LoadBank(FileAndMemReader &fr)
|
|||
synth.m_insBankSetup.scaleModulators = false;
|
||||
synth.m_insBankSetup.deepTremolo = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0;
|
||||
synth.m_insBankSetup.deepVibrato = (wopl->opl_flags & WOPL_FLAG_DEEP_VIBRATO) != 0;
|
||||
synth.m_insBankSetup.mt32defaults = (wopl->opl_flags & WOPL_FLAG_MT32) != 0;
|
||||
synth.m_insBankSetup.volumeModel = wopl->volume_model;
|
||||
m_setup.deepTremoloMode = -1;
|
||||
m_setup.deepVibratoMode = -1;
|
||||
|
|
66
thirdparty/adlmidi/adlmidi_midiplay.cpp
vendored
66
thirdparty/adlmidi/adlmidi_midiplay.cpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -36,7 +36,8 @@ enum { MasterVolumeDefault = 127 };
|
|||
|
||||
inline bool isXgPercChannel(uint8_t msb, uint8_t lsb)
|
||||
{
|
||||
return (msb == 0x7E || msb == 0x7F) && (lsb == 0);
|
||||
ADL_UNUSED(lsb);
|
||||
return (msb == 0x7E || msb == 0x7F);
|
||||
}
|
||||
|
||||
void MIDIplay::AdlChannel::addAge(int64_t us)
|
||||
|
@ -90,6 +91,7 @@ MIDIplay::MIDIplay(unsigned long sampleRate):
|
|||
//m_setup.SkipForward = 0;
|
||||
m_setup.scaleModulators = -1;
|
||||
m_setup.fullRangeBrightnessCC74 = false;
|
||||
m_setup.enableAutoArpeggio = false;
|
||||
m_setup.delay = 0.0;
|
||||
m_setup.carry = 0.0;
|
||||
m_setup.tick_skip_samples_delay = 0;
|
||||
|
@ -126,6 +128,7 @@ void MIDIplay::applySetup()
|
|||
synth.m_insBankSetup.volumeModel = (b.bankSetup & 0x00FF);
|
||||
synth.m_insBankSetup.deepTremolo = (b.bankSetup >> 8 & 0x0001) != 0;
|
||||
synth.m_insBankSetup.deepVibrato = (b.bankSetup >> 8 & 0x0002) != 0;
|
||||
synth.m_insBankSetup.mt32defaults = (b.bankSetup >> 8 & 0x0004) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -200,15 +203,15 @@ void MIDIplay::resetMIDIDefaults(int offset)
|
|||
for(size_t c = offset, n = m_midiChannels.size(); c < n; ++c)
|
||||
{
|
||||
MIDIchannel &ch = m_midiChannels[c];
|
||||
if(synth.m_musicMode == Synth::MODE_XMIDI)
|
||||
|
||||
if(synth.m_musicMode == Synth::MODE_RSXX)
|
||||
ch.def_volume = 127;
|
||||
else if(synth.m_insBankSetup.mt32defaults)
|
||||
{
|
||||
ch.def_volume = 127;
|
||||
ch.def_bendsense_lsb = 0;
|
||||
ch.def_bendsense_msb = 12;
|
||||
}
|
||||
else
|
||||
if(synth.m_musicMode == Synth::MODE_RSXX)
|
||||
ch.def_volume = 127;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,10 +293,11 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
|||
if(!i.is_end())
|
||||
{
|
||||
MIDIchannel::NoteInfo &ni = i->value;
|
||||
const int veloffset = ni.ains->midiVelocityOffset;
|
||||
const int veloffset = ni.ains ? ni.ains->midiVelocityOffset : 0;
|
||||
velocity = (uint8_t)std::min(127, std::max(1, (int)velocity + veloffset));
|
||||
ni.vol = velocity;
|
||||
noteUpdate(channel, i, Upd_Volume);
|
||||
if(ni.ains)
|
||||
noteUpdate(channel, i, Upd_Volume);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +333,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
|||
// Let XG Percussion bank will use (0...127 LSB range in WOPN file)
|
||||
|
||||
// Choose: SFX or Drum Kits
|
||||
bank = midiins + ((bank == 0x7E00) ? 128 : 0);
|
||||
bank = midiins + ((midiChan.bank_msb == 0x7E) ? 128 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -357,8 +361,8 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
|||
caughtMissingBank = true;
|
||||
}
|
||||
|
||||
//Or fall back to bank ignoring LSB (GS)
|
||||
if((ains->flags & OplInstMeta::Flag_NoSound) && ((m_synthMode & Mode_GS) != 0))
|
||||
//Or fall back to bank ignoring LSB (GS/XG)
|
||||
if(ains->flags & OplInstMeta::Flag_NoSound)
|
||||
{
|
||||
size_t fallback = bank & ~(size_t)0x7F;
|
||||
if(fallback != bank)
|
||||
|
@ -1345,6 +1349,17 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
|
|||
const AdlChannel &chan = m_chipChannels[c];
|
||||
int64_t koff_ms = chan.koff_time_until_neglible_us / 1000;
|
||||
int64_t s = -koff_ms;
|
||||
ADLMIDI_ChannelAlloc allocType = synth.m_channelAlloc;
|
||||
|
||||
if(allocType == ADLMIDI_ChanAlloc_AUTO)
|
||||
{
|
||||
if(synth.m_musicMode == Synth::MODE_CMF)
|
||||
allocType = ADLMIDI_ChanAlloc_SameInst;
|
||||
else if(synth.m_volumeScale == Synth::VOLUME_HMI)
|
||||
allocType = ADLMIDI_ChanAlloc_AnyReleased; // HMI doesn't care about the same instrument
|
||||
else
|
||||
allocType = ADLMIDI_ChanAlloc_OffDelay;
|
||||
}
|
||||
|
||||
// Rate channel with a releasing note
|
||||
if(s < 0 && chan.users.empty())
|
||||
|
@ -1353,19 +1368,22 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
|
|||
s -= 40000;
|
||||
|
||||
// If it's same instrument, better chance to get it when no free channels
|
||||
if(synth.m_musicMode == Synth::MODE_CMF)
|
||||
switch(allocType)
|
||||
{
|
||||
case ADLMIDI_ChanAlloc_SameInst:
|
||||
if(isSame)
|
||||
s = 0; // Re-use releasing channel with the same instrument
|
||||
}
|
||||
else if(synth.m_volumeScale == Synth::VOLUME_HMI)
|
||||
{
|
||||
s = 0; // HMI doesn't care about the same instrument
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case ADLMIDI_ChanAlloc_AnyReleased:
|
||||
s = 0; // Re-use any releasing channel
|
||||
break;
|
||||
|
||||
default:
|
||||
case ADLMIDI_ChanAlloc_OffDelay:
|
||||
if(isSame)
|
||||
s = -koff_ms; // Wait until releasing sound will complete
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
@ -1502,6 +1520,9 @@ void MIDIplay::killOrEvacuate(size_t from_channel,
|
|||
{
|
||||
uint16_t cs = static_cast<uint16_t>(c);
|
||||
|
||||
if(!m_setup.enableAutoArpeggio)
|
||||
break; // Arpeggio disabled completely
|
||||
|
||||
if(c >= maxChannels)
|
||||
break;
|
||||
if(c == from_channel)
|
||||
|
@ -1725,6 +1746,13 @@ void MIDIplay::updateArpeggio(double) // amount = amount of time passed
|
|||
|
||||
Synth &synth = *m_synth;
|
||||
|
||||
if(!m_setup.enableAutoArpeggio) // Arpeggio was disabled
|
||||
{
|
||||
if(m_arpeggioCounter != 0)
|
||||
m_arpeggioCounter = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
const unsigned desired_arpeggio_rate = 40; // Hz (upper limit)
|
||||
# if 1
|
||||
|
|
14
thirdparty/adlmidi/adlmidi_midiplay.hpp
vendored
14
thirdparty/adlmidi/adlmidi_midiplay.hpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -37,6 +37,10 @@ struct MIDIEventHooks
|
|||
MIDIEventHooks() :
|
||||
onNote(NULL),
|
||||
onNote_userData(NULL),
|
||||
onLoopStart(NULL),
|
||||
onLoopStart_userData(NULL),
|
||||
onLoopEnd(NULL),
|
||||
onLoopEnd_userData(NULL),
|
||||
onDebugMessage(NULL),
|
||||
onDebugMessage_userData(NULL)
|
||||
{}
|
||||
|
@ -46,6 +50,13 @@ struct MIDIEventHooks
|
|||
NoteHook onNote;
|
||||
void *onNote_userData;
|
||||
|
||||
// Loop start/end hooks
|
||||
ADL_LoopPointHook onLoopStart;
|
||||
void *onLoopStart_userData;
|
||||
ADL_LoopPointHook onLoopEnd;
|
||||
void *onLoopEnd_userData;
|
||||
|
||||
|
||||
//! Library internal debug messages
|
||||
typedef void (*DebugMessageHook)(void *userdata, const char *fmt, ...);
|
||||
DebugMessageHook onDebugMessage;
|
||||
|
@ -526,6 +537,7 @@ public:
|
|||
//unsigned int SkipForward;
|
||||
int scaleModulators;
|
||||
bool fullRangeBrightnessCC74;
|
||||
bool enableAutoArpeggio;
|
||||
|
||||
double delay;
|
||||
double carry;
|
||||
|
|
8
thirdparty/adlmidi/adlmidi_opl3.cpp
vendored
8
thirdparty/adlmidi/adlmidi_opl3.cpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -868,12 +868,14 @@ OPL3::OPL3() :
|
|||
m_softPanning(false),
|
||||
m_masterVolume(MasterVolumeDefault),
|
||||
m_musicMode(MODE_MIDI),
|
||||
m_volumeScale(VOLUME_Generic)
|
||||
m_volumeScale(VOLUME_Generic),
|
||||
m_channelAlloc(ADLMIDI_ChanAlloc_AUTO)
|
||||
{
|
||||
m_insBankSetup.volumeModel = OPL3::VOLUME_Generic;
|
||||
m_insBankSetup.deepTremolo = false;
|
||||
m_insBankSetup.deepVibrato = false;
|
||||
m_insBankSetup.scaleModulators = false;
|
||||
m_insBankSetup.mt32defaults = false;
|
||||
|
||||
#ifdef DISABLE_EMBEDDED_BANKS
|
||||
m_embeddedBank = CustomBankTag;
|
||||
|
@ -913,6 +915,7 @@ void OPL3::setEmbeddedBank(uint32_t bank)
|
|||
const BanksDump::BankEntry &bankEntry = g_embeddedBanks[m_embeddedBank];
|
||||
m_insBankSetup.deepTremolo = ((bankEntry.bankSetup >> 8) & 0x01) != 0;
|
||||
m_insBankSetup.deepVibrato = ((bankEntry.bankSetup >> 8) & 0x02) != 0;
|
||||
m_insBankSetup.mt32defaults = ((bankEntry.bankSetup >> 8) & 0x04) != 0;
|
||||
m_insBankSetup.volumeModel = (bankEntry.bankSetup & 0xFF);
|
||||
m_insBankSetup.scaleModulators = false;
|
||||
|
||||
|
@ -1628,6 +1631,7 @@ void OPL3::setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel)
|
|||
{
|
||||
switch(volumeModel)
|
||||
{
|
||||
default:
|
||||
case ADLMIDI_VolumeModel_AUTO://Do nothing until restart playing
|
||||
break;
|
||||
|
||||
|
|
5
thirdparty/adlmidi/adlmidi_opl3.hpp
vendored
5
thirdparty/adlmidi/adlmidi_opl3.hpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -162,6 +162,9 @@ public:
|
|||
VOLUME_HMI_OLD
|
||||
} m_volumeScale;
|
||||
|
||||
//! Channel allocation algorithm
|
||||
ADLMIDI_ChannelAlloc m_channelAlloc;
|
||||
|
||||
//! Reserved
|
||||
char _padding3[8];
|
||||
|
||||
|
|
2
thirdparty/adlmidi/adlmidi_private.cpp
vendored
2
thirdparty/adlmidi/adlmidi_private.cpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
|
2
thirdparty/adlmidi/adlmidi_private.hpp
vendored
2
thirdparty/adlmidi/adlmidi_private.hpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
|
2
thirdparty/adlmidi/adlmidi_ptr.hpp
vendored
2
thirdparty/adlmidi/adlmidi_ptr.hpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
|
88
thirdparty/adlmidi/chips/common/mutex.hpp
vendored
88
thirdparty/adlmidi/chips/common/mutex.hpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -21,14 +21,26 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <pthread.h>
|
||||
#ifndef DOSBOX_NO_MUTEX
|
||||
# if defined(USE_LIBOGC_MUTEX)
|
||||
# include <ogc/mutex.h>
|
||||
typedef mutex_t MutexNativeObject;
|
||||
# elif defined(USE_WUT_MUTEX)
|
||||
# if __cplusplus < 201103L || (defined(_MSC_VER) && _MSC_VER < 1900)
|
||||
# define static_assert(x, y)
|
||||
# endif
|
||||
# include <coreinit/mutex.h>
|
||||
typedef OSMutex MutexNativeObject;
|
||||
# elif !defined(_WIN32)
|
||||
# include <pthread.h>
|
||||
typedef pthread_mutex_t MutexNativeObject;
|
||||
#else
|
||||
#include <windows.h>
|
||||
# else
|
||||
# include <windows.h>
|
||||
typedef CRITICAL_SECTION MutexNativeObject;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
|
@ -37,7 +49,9 @@ public:
|
|||
void lock();
|
||||
void unlock();
|
||||
private:
|
||||
#if !defined(DOSBOX_NO_MUTEX)
|
||||
MutexNativeObject m;
|
||||
#endif
|
||||
Mutex(const Mutex &);
|
||||
Mutex &operator=(const Mutex &);
|
||||
};
|
||||
|
@ -53,7 +67,65 @@ private:
|
|||
MutexHolder &operator=(const MutexHolder &);
|
||||
};
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#if defined(DOSBOX_NO_MUTEX) // No mutex, just a dummy
|
||||
|
||||
inline Mutex::Mutex()
|
||||
{}
|
||||
|
||||
inline Mutex::~Mutex()
|
||||
{}
|
||||
|
||||
inline void Mutex::lock()
|
||||
{}
|
||||
|
||||
inline void Mutex::unlock()
|
||||
{}
|
||||
|
||||
#elif defined(USE_WUT_MUTEX)
|
||||
|
||||
inline Mutex::Mutex()
|
||||
{
|
||||
OSInitMutex(&m);
|
||||
}
|
||||
|
||||
inline Mutex::~Mutex()
|
||||
{}
|
||||
|
||||
inline void Mutex::lock()
|
||||
{
|
||||
OSLockMutex(&m);
|
||||
}
|
||||
|
||||
inline void Mutex::unlock()
|
||||
{
|
||||
OSUnlockMutex(&m);
|
||||
}
|
||||
|
||||
#elif defined(USE_LIBOGC_MUTEX)
|
||||
|
||||
inline Mutex::Mutex()
|
||||
{
|
||||
m = LWP_MUTEX_NULL;
|
||||
LWP_MutexInit(&m, 0);
|
||||
}
|
||||
|
||||
inline Mutex::~Mutex()
|
||||
{
|
||||
LWP_MutexDestroy(m);
|
||||
}
|
||||
|
||||
inline void Mutex::lock()
|
||||
{
|
||||
LWP_MutexLock(m);
|
||||
}
|
||||
|
||||
inline void Mutex::unlock()
|
||||
{
|
||||
LWP_MutexUnlock(m);
|
||||
}
|
||||
|
||||
#elif !defined(_WIN32) // pthread
|
||||
|
||||
inline Mutex::Mutex()
|
||||
{
|
||||
pthread_mutex_init(&m, NULL);
|
||||
|
@ -73,7 +145,9 @@ inline void Mutex::unlock()
|
|||
{
|
||||
pthread_mutex_unlock(&m);
|
||||
}
|
||||
#else
|
||||
|
||||
#else // Win32
|
||||
|
||||
inline Mutex::Mutex()
|
||||
{
|
||||
InitializeCriticalSection(&m);
|
||||
|
|
2
thirdparty/adlmidi/chips/common/ptr.hpp
vendored
2
thirdparty/adlmidi/chips/common/ptr.hpp
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
|
2
thirdparty/adlmidi/chips/dosbox_opl3.cpp
vendored
2
thirdparty/adlmidi/chips/dosbox_opl3.cpp
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/dosbox_opl3.h
vendored
2
thirdparty/adlmidi/chips/dosbox_opl3.h
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/java_opl3.cpp
vendored
2
thirdparty/adlmidi/chips/java_opl3.cpp
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/java_opl3.h
vendored
2
thirdparty/adlmidi/chips/java_opl3.h
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/nuked_opl3.cpp
vendored
2
thirdparty/adlmidi/chips/nuked_opl3.cpp
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/nuked_opl3.h
vendored
2
thirdparty/adlmidi/chips/nuked_opl3.h
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/nuked_opl3_v174.cpp
vendored
2
thirdparty/adlmidi/chips/nuked_opl3_v174.cpp
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/nuked_opl3_v174.h
vendored
2
thirdparty/adlmidi/chips/nuked_opl3_v174.h
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/opal_opl3.cpp
vendored
2
thirdparty/adlmidi/chips/opal_opl3.cpp
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/opal_opl3.h
vendored
2
thirdparty/adlmidi/chips/opal_opl3.h
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||
*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/chips/opl_chip_base.h
vendored
2
thirdparty/adlmidi/chips/opl_chip_base.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
2
thirdparty/adlmidi/file_reader.hpp
vendored
2
thirdparty/adlmidi/file_reader.hpp
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* FileAndMemoryReader - a tiny helper to utify file reading from a disk and memory block
|
||||
*
|
||||
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
|
|
6451
thirdparty/adlmidi/inst_db.cpp
vendored
6451
thirdparty/adlmidi/inst_db.cpp
vendored
File diff suppressed because one or more lines are too long
3
thirdparty/adlmidi/oplinst.h
vendored
3
thirdparty/adlmidi/oplinst.h
vendored
|
@ -2,7 +2,7 @@
|
|||
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||
*
|
||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||
|
@ -106,6 +106,7 @@ struct OplBankSetup
|
|||
bool deepTremolo;
|
||||
bool deepVibrato;
|
||||
bool scaleModulators;
|
||||
bool mt32defaults;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
2
thirdparty/adlmidi/wopl/wopl_file.c
vendored
2
thirdparty/adlmidi/wopl/wopl_file.c
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup
|
||||
*
|
||||
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
|
|
24
thirdparty/adlmidi/wopl/wopl_file.h
vendored
24
thirdparty/adlmidi/wopl/wopl_file.h
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup
|
||||
*
|
||||
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
* Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -32,8 +32,22 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_VERSION__) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)) \
|
||||
|| defined(__STRICT_ANSI__) || !defined(__cplusplus)
|
||||
/* Solaris defines the integer types regardless of what C/C++ standard is actually available,
|
||||
* so avoid defining them at all by ourselves. */
|
||||
#if !defined(WOPL_STDINT_TYPEDEFS_NOT_NEEDED) && defined(__sun)
|
||||
# define WOPL_STDINT_TYPEDEFS_NOT_NEEDED
|
||||
#endif
|
||||
|
||||
#if !defined(WOPL_STDINT_TYPEDEFS_NEEDED) && !defined(WOPL_STDINT_TYPEDEFS_NOT_NEEDED)
|
||||
# if !defined(__STDC_VERSION__) || \
|
||||
(defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)) || \
|
||||
defined(__STRICT_ANSI__) || \
|
||||
!defined(__cplusplus)
|
||||
# define WOPL_STDINT_TYPEDEFS_NEEDED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WOPL_STDINT_TYPEDEFS_NEEDED
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed short int int16_t;
|
||||
|
@ -46,7 +60,9 @@ typedef enum WOPLFileFlags
|
|||
/* Enable Deep-Tremolo flag */
|
||||
WOPL_FLAG_DEEP_TREMOLO = 0x01,
|
||||
/* Enable Deep-Vibrato flag */
|
||||
WOPL_FLAG_DEEP_VIBRATO = 0x02
|
||||
WOPL_FLAG_DEEP_VIBRATO = 0x02,
|
||||
/* Enable MT32 defaults (127 initials and octave-wide pitch bend by default, etc.) */
|
||||
WOPL_FLAG_MT32 = 0x04
|
||||
} WOPLFileFlags;
|
||||
|
||||
/* Volume scaling model implemented in the libADLMIDI */
|
||||
|
|
119
thirdparty/fluidsynth/include/fluidsynth.h
vendored
Normal file
119
thirdparty/fluidsynth/include/fluidsynth.h
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* 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 _FLUIDSYNTH_H
|
||||
#define _FLUIDSYNTH_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if (BUILD_SHARED_LIBS == 0)
|
||||
#define FLUIDSYNTH_API // building static lib? no visibility control then
|
||||
#elif defined(WIN32)
|
||||
#if defined(FLUIDSYNTH_NOT_A_DLL)
|
||||
#define FLUIDSYNTH_API
|
||||
#elif defined(FLUIDSYNTH_DLL_EXPORTS)
|
||||
#define FLUIDSYNTH_API __declspec(dllexport)
|
||||
#else
|
||||
#define FLUIDSYNTH_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#elif defined(MACOS9)
|
||||
#define FLUIDSYNTH_API __declspec(export)
|
||||
|
||||
#elif defined(__OS2__)
|
||||
#define FLUIDSYNTH_API __declspec(dllexport)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define FLUIDSYNTH_API __attribute__ ((visibility ("default")))
|
||||
|
||||
#else
|
||||
#define FLUIDSYNTH_API
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define FLUID_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER) && _MSC_VER > 1200
|
||||
# define FLUID_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
# define FLUID_DEPRECATED
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file fluidsynth.h
|
||||
* @brief FluidSynth is a real-time synthesizer designed for SoundFont(R) files.
|
||||
*
|
||||
* This is the header of the fluidsynth library and contains the
|
||||
* synthesizer's public API.
|
||||
*
|
||||
* Depending on how you want to use or extend the synthesizer you
|
||||
* will need different API functions. You probably do not need all
|
||||
* of them. Here is what you might want to do:
|
||||
*
|
||||
* - Embedded synthesizer: create a new synthesizer and send MIDI
|
||||
* events to it. The sound goes directly to the audio output of
|
||||
* your system.
|
||||
*
|
||||
* - Plugin synthesizer: create a synthesizer and send MIDI events
|
||||
* but pull the audio back into your application.
|
||||
*
|
||||
* - SoundFont plugin: create a new type of "SoundFont" and allow
|
||||
* the synthesizer to load your type of SoundFonts.
|
||||
*
|
||||
* - MIDI input: Create a MIDI handler to read the MIDI input on your
|
||||
* machine and send the MIDI events directly to the synthesizer.
|
||||
*
|
||||
* - MIDI files: Open MIDI files and send the MIDI events to the
|
||||
* synthesizer.
|
||||
*
|
||||
* - Command lines: You can send textual commands to the synthesizer.
|
||||
*
|
||||
* SoundFont(R) is a registered trademark of E-mu Systems, Inc.
|
||||
*/
|
||||
|
||||
#include "fluidsynth/types.h"
|
||||
#include "fluidsynth/settings.h"
|
||||
#include "fluidsynth/synth.h"
|
||||
#include "fluidsynth/shell.h"
|
||||
#include "fluidsynth/sfont.h"
|
||||
#include "fluidsynth/audio.h"
|
||||
#include "fluidsynth/event.h"
|
||||
#include "fluidsynth/midi.h"
|
||||
#include "fluidsynth/seq.h"
|
||||
#include "fluidsynth/seqbind.h"
|
||||
#include "fluidsynth/log.h"
|
||||
#include "fluidsynth/misc.h"
|
||||
#include "fluidsynth/mod.h"
|
||||
#include "fluidsynth/gen.h"
|
||||
#include "fluidsynth/voice.h"
|
||||
#include "fluidsynth/version.h"
|
||||
#include "fluidsynth/ladspa.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_H */
|
155
thirdparty/fluidsynth/include/fluidsynth/audio.h
vendored
Normal file
155
thirdparty/fluidsynth/include/fluidsynth/audio.h
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* 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 _FLUIDSYNTH_AUDIO_H
|
||||
#define _FLUIDSYNTH_AUDIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup audio_output Audio Output
|
||||
*
|
||||
* Functions for managing audio drivers and file renderers.
|
||||
*
|
||||
* The file renderer is used for fast rendering of MIDI files to
|
||||
* audio files. The audio drivers are a high-level interface to
|
||||
* connect the synthesizer with external audio sinks or to render
|
||||
* real-time audio to files.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup audio_driver Audio Driver
|
||||
* @ingroup audio_output
|
||||
*
|
||||
* Functions for managing audio drivers.
|
||||
*
|
||||
* Defines functions for creating audio driver output. Use
|
||||
* new_fluid_audio_driver() to create a new audio driver for a given synth
|
||||
* and configuration settings.
|
||||
*
|
||||
* The function new_fluid_audio_driver2() can be
|
||||
* used if custom audio processing is desired before the audio is sent to the
|
||||
* audio driver (although it is not as efficient).
|
||||
*
|
||||
* @sa @ref CreatingAudioDriver
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback function type used with new_fluid_audio_driver2() to allow for
|
||||
* custom user audio processing before the audio is sent to the driver.
|
||||
*
|
||||
* @param data The user data parameter as passed to new_fluid_audio_driver2().
|
||||
* @param len Count of audio frames to synthesize.
|
||||
* @param nfx Count of arrays in \c fx.
|
||||
* @param fx Array of buffers to store effects audio to. Buffers may alias with buffers of \c out.
|
||||
* @param nout Count of arrays in \c out.
|
||||
* @param out Array of buffers to store (dry) audio to. Buffers may alias with buffers of \c fx.
|
||||
* @return Should return #FLUID_OK on success, #FLUID_FAILED if an error occurred.
|
||||
*
|
||||
* This function is responsible for rendering audio to the buffers.
|
||||
* The buffers passed to this function are allocated and owned by the respective
|
||||
* audio driver and are only valid during that specific call (do not cache them).
|
||||
* The buffers have already been zeroed-out.
|
||||
* For further details please refer to fluid_synth_process().
|
||||
*
|
||||
* @parblock
|
||||
* @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarantee that @p out
|
||||
* and @p fx buffers provided by fluidsynth's audio drivers never alias. This prevents downstream
|
||||
* applications from e.g. applying a custom effect accidentally to the same buffer multiple times.
|
||||
* @endparblock
|
||||
*
|
||||
* @parblock
|
||||
* @note Also note that the Jack driver is currently the only driver that has dedicated @p fx buffers
|
||||
* (but only if \setting{audio_jack_multi} is true). All other drivers do not provide @p fx buffers.
|
||||
* In this case, users are encouraged to mix the effects into the provided dry buffers when calling
|
||||
* fluid_synth_process().
|
||||
* @code{.cpp}
|
||||
int myCallback(void *, int len, int nfx, float *fx[], int nout, float *out[])
|
||||
{
|
||||
int ret;
|
||||
if(nfx == 0)
|
||||
{
|
||||
float *fxb[4] = {out[0], out[1], out[0], out[1]};
|
||||
ret = fluid_synth_process(synth, len, sizeof(fxb) / sizeof(fxb[0]), fxb, nout, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = fluid_synth_process(synth, len, nfx, fx, nout, out);
|
||||
}
|
||||
// ... client-code ...
|
||||
return ret;
|
||||
}
|
||||
* @endcode
|
||||
* For other possible use-cases refer to \ref fluidsynth_process.c .
|
||||
* @endparblock
|
||||
*/
|
||||
typedef int (*fluid_audio_func_t)(void *data, int len,
|
||||
int nfx, float *fx[],
|
||||
int nout, float *out[]);
|
||||
|
||||
/** @startlifecycle{Audio Driver} */
|
||||
FLUIDSYNTH_API fluid_audio_driver_t *new_fluid_audio_driver(fluid_settings_t *settings,
|
||||
fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API fluid_audio_driver_t *new_fluid_audio_driver2(fluid_settings_t *settings,
|
||||
fluid_audio_func_t func,
|
||||
void *data);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_audio_driver(fluid_audio_driver_t *driver);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_audio_driver_register(const char **adrivers);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup file_renderer File Renderer
|
||||
* @ingroup audio_output
|
||||
*
|
||||
* Functions for managing file renderers and triggering the rendering.
|
||||
*
|
||||
* The file renderer is only used to render a MIDI file to audio as fast
|
||||
* as possible. Please see \ref FileRenderer for a full example.
|
||||
*
|
||||
* If you are looking for a way to write audio generated
|
||||
* from real-time events (for example from an external sequencer or a MIDI controller) to a file,
|
||||
* please have a look at the \c file \ref audio_driver instead.
|
||||
*
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @startlifecycle{File Renderer} */
|
||||
FLUIDSYNTH_API fluid_file_renderer_t *new_fluid_file_renderer(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API void delete_fluid_file_renderer(fluid_file_renderer_t *dev);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_file_renderer_process_block(fluid_file_renderer_t *dev);
|
||||
FLUIDSYNTH_API int fluid_file_set_encoding_quality(fluid_file_renderer_t *dev, double q);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_AUDIO_H */
|
143
thirdparty/fluidsynth/include/fluidsynth/event.h
vendored
Normal file
143
thirdparty/fluidsynth/include/fluidsynth/event.h
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
/* 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 _FLUIDSYNTH_EVENT_H
|
||||
#define _FLUIDSYNTH_EVENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup sequencer_events Sequencer Events
|
||||
* @ingroup sequencer
|
||||
*
|
||||
* Create, modify, query and destroy sequencer events.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sequencer event type enumeration.
|
||||
*/
|
||||
enum fluid_seq_event_type
|
||||
{
|
||||
FLUID_SEQ_NOTE = 0, /**< Note event with duration */
|
||||
FLUID_SEQ_NOTEON, /**< Note on event */
|
||||
FLUID_SEQ_NOTEOFF, /**< Note off event */
|
||||
FLUID_SEQ_ALLSOUNDSOFF, /**< All sounds off event */
|
||||
FLUID_SEQ_ALLNOTESOFF, /**< All notes off event */
|
||||
FLUID_SEQ_BANKSELECT, /**< Bank select message */
|
||||
FLUID_SEQ_PROGRAMCHANGE, /**< Program change message */
|
||||
FLUID_SEQ_PROGRAMSELECT, /**< Program select message */
|
||||
FLUID_SEQ_PITCHBEND, /**< Pitch bend message */
|
||||
FLUID_SEQ_PITCHWHEELSENS, /**< Pitch wheel sensitivity set message @since 1.1.0 was misspelled previously */
|
||||
FLUID_SEQ_MODULATION, /**< Modulation controller event */
|
||||
FLUID_SEQ_SUSTAIN, /**< Sustain controller event */
|
||||
FLUID_SEQ_CONTROLCHANGE, /**< MIDI control change event */
|
||||
FLUID_SEQ_PAN, /**< Stereo pan set event */
|
||||
FLUID_SEQ_VOLUME, /**< Volume set event */
|
||||
FLUID_SEQ_REVERBSEND, /**< Reverb send set event */
|
||||
FLUID_SEQ_CHORUSSEND, /**< Chorus send set event */
|
||||
FLUID_SEQ_TIMER, /**< Timer event (useful for giving a callback at a certain time) */
|
||||
FLUID_SEQ_CHANNELPRESSURE, /**< Channel aftertouch event @since 1.1.0 */
|
||||
FLUID_SEQ_KEYPRESSURE, /**< Polyphonic aftertouch event @since 2.0.0 */
|
||||
FLUID_SEQ_SYSTEMRESET, /**< System reset event @since 1.1.0 */
|
||||
FLUID_SEQ_UNREGISTERING, /**< Called when a sequencer client is being unregistered. @since 1.1.0 */
|
||||
FLUID_SEQ_SCALE, /**< Sets a new time scale for the sequencer @since 2.2.0 */
|
||||
FLUID_SEQ_LASTEVENT /**< @internal Defines the count of events enums @warning This symbol
|
||||
is not part of the public API and ABI stability guarantee and
|
||||
may change at any time! */
|
||||
};
|
||||
|
||||
/* Event alloc/free */
|
||||
/** @startlifecycle{Sequencer Event} */
|
||||
FLUIDSYNTH_API fluid_event_t *new_fluid_event(void);
|
||||
FLUIDSYNTH_API void delete_fluid_event(fluid_event_t *evt);
|
||||
/** @endlifecycle */
|
||||
|
||||
/* Initializing events */
|
||||
FLUIDSYNTH_API void fluid_event_set_source(fluid_event_t *evt, fluid_seq_id_t src);
|
||||
FLUIDSYNTH_API void fluid_event_set_dest(fluid_event_t *evt, fluid_seq_id_t dest);
|
||||
|
||||
/* Timer events */
|
||||
FLUIDSYNTH_API void fluid_event_timer(fluid_event_t *evt, void *data);
|
||||
|
||||
/* Note events */
|
||||
FLUIDSYNTH_API void fluid_event_note(fluid_event_t *evt, int channel,
|
||||
short key, short vel,
|
||||
unsigned int duration);
|
||||
|
||||
FLUIDSYNTH_API void fluid_event_noteon(fluid_event_t *evt, int channel, short key, short vel);
|
||||
FLUIDSYNTH_API void fluid_event_noteoff(fluid_event_t *evt, int channel, short key);
|
||||
FLUIDSYNTH_API void fluid_event_all_sounds_off(fluid_event_t *evt, int channel);
|
||||
FLUIDSYNTH_API void fluid_event_all_notes_off(fluid_event_t *evt, int channel);
|
||||
|
||||
/* Instrument selection */
|
||||
FLUIDSYNTH_API void fluid_event_bank_select(fluid_event_t *evt, int channel, short bank_num);
|
||||
FLUIDSYNTH_API void fluid_event_program_change(fluid_event_t *evt, int channel, int preset_num);
|
||||
FLUIDSYNTH_API void fluid_event_program_select(fluid_event_t *evt, int channel, unsigned int sfont_id, short bank_num, short preset_num);
|
||||
|
||||
/* Real-time generic instrument controllers */
|
||||
FLUIDSYNTH_API
|
||||
void fluid_event_control_change(fluid_event_t *evt, int channel, short control, int val);
|
||||
|
||||
/* Real-time instrument controllers shortcuts */
|
||||
FLUIDSYNTH_API void fluid_event_pitch_bend(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_pitch_wheelsens(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_modulation(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_sustain(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_pan(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_volume(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_reverb_send(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_chorus_send(fluid_event_t *evt, int channel, int val);
|
||||
|
||||
FLUIDSYNTH_API void fluid_event_key_pressure(fluid_event_t *evt, int channel, short key, int val);
|
||||
FLUIDSYNTH_API void fluid_event_channel_pressure(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_system_reset(fluid_event_t *evt);
|
||||
|
||||
/* Only when unregistering clients */
|
||||
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);
|
||||
FLUIDSYNTH_API fluid_seq_id_t fluid_event_get_source(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API fluid_seq_id_t fluid_event_get_dest(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_event_get_channel(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_key(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_velocity(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_control(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_event_get_value(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_event_get_program(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API void *fluid_event_get_data(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API unsigned int fluid_event_get_duration(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_bank(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_event_get_pitch(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API double fluid_event_get_scale(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API unsigned int fluid_event_get_sfont_id(fluid_event_t *evt);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_EVENT_H */
|
134
thirdparty/fluidsynth/include/fluidsynth/gen.h
vendored
Normal file
134
thirdparty/fluidsynth/include/fluidsynth/gen.h
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
/* 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 _FLUIDSYNTH_GEN_H
|
||||
#define _FLUIDSYNTH_GEN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup generators SoundFont Generators
|
||||
* @ingroup soundfonts
|
||||
*
|
||||
* Functions and defines for SoundFont generator effects.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generator (effect) numbers (Soundfont 2.01 specifications section 8.1.3)
|
||||
*/
|
||||
enum fluid_gen_type
|
||||
{
|
||||
GEN_STARTADDROFS, /**< Sample start address offset (0-32767) */
|
||||
GEN_ENDADDROFS, /**< Sample end address offset (-32767-0) */
|
||||
GEN_STARTLOOPADDROFS, /**< Sample loop start address offset (-32767-32767) */
|
||||
GEN_ENDLOOPADDROFS, /**< Sample loop end address offset (-32767-32767) */
|
||||
GEN_STARTADDRCOARSEOFS, /**< Sample start address coarse offset (X 32768) */
|
||||
GEN_MODLFOTOPITCH, /**< Modulation LFO to pitch */
|
||||
GEN_VIBLFOTOPITCH, /**< Vibrato LFO to pitch */
|
||||
GEN_MODENVTOPITCH, /**< Modulation envelope to pitch */
|
||||
GEN_FILTERFC, /**< Filter cutoff */
|
||||
GEN_FILTERQ, /**< Filter Q */
|
||||
GEN_MODLFOTOFILTERFC, /**< Modulation LFO to filter cutoff */
|
||||
GEN_MODENVTOFILTERFC, /**< Modulation envelope to filter cutoff */
|
||||
GEN_ENDADDRCOARSEOFS, /**< Sample end address coarse offset (X 32768) */
|
||||
GEN_MODLFOTOVOL, /**< Modulation LFO to volume */
|
||||
GEN_UNUSED1, /**< Unused */
|
||||
GEN_CHORUSSEND, /**< Chorus send amount */
|
||||
GEN_REVERBSEND, /**< Reverb send amount */
|
||||
GEN_PAN, /**< Stereo panning */
|
||||
GEN_UNUSED2, /**< Unused */
|
||||
GEN_UNUSED3, /**< Unused */
|
||||
GEN_UNUSED4, /**< Unused */
|
||||
GEN_MODLFODELAY, /**< Modulation LFO delay */
|
||||
GEN_MODLFOFREQ, /**< Modulation LFO frequency */
|
||||
GEN_VIBLFODELAY, /**< Vibrato LFO delay */
|
||||
GEN_VIBLFOFREQ, /**< Vibrato LFO frequency */
|
||||
GEN_MODENVDELAY, /**< Modulation envelope delay */
|
||||
GEN_MODENVATTACK, /**< Modulation envelope attack */
|
||||
GEN_MODENVHOLD, /**< Modulation envelope hold */
|
||||
GEN_MODENVDECAY, /**< Modulation envelope decay */
|
||||
GEN_MODENVSUSTAIN, /**< Modulation envelope sustain */
|
||||
GEN_MODENVRELEASE, /**< Modulation envelope release */
|
||||
GEN_KEYTOMODENVHOLD, /**< Key to modulation envelope hold */
|
||||
GEN_KEYTOMODENVDECAY, /**< Key to modulation envelope decay */
|
||||
GEN_VOLENVDELAY, /**< Volume envelope delay */
|
||||
GEN_VOLENVATTACK, /**< Volume envelope attack */
|
||||
GEN_VOLENVHOLD, /**< Volume envelope hold */
|
||||
GEN_VOLENVDECAY, /**< Volume envelope decay */
|
||||
GEN_VOLENVSUSTAIN, /**< Volume envelope sustain */
|
||||
GEN_VOLENVRELEASE, /**< Volume envelope release */
|
||||
GEN_KEYTOVOLENVHOLD, /**< Key to volume envelope hold */
|
||||
GEN_KEYTOVOLENVDECAY, /**< Key to volume envelope decay */
|
||||
GEN_INSTRUMENT, /**< Instrument ID (shouldn't be set by user) */
|
||||
GEN_RESERVED1, /**< Reserved */
|
||||
GEN_KEYRANGE, /**< MIDI note range */
|
||||
GEN_VELRANGE, /**< MIDI velocity range */
|
||||
GEN_STARTLOOPADDRCOARSEOFS, /**< Sample start loop address coarse offset (X 32768) */
|
||||
GEN_KEYNUM, /**< Fixed MIDI note number */
|
||||
GEN_VELOCITY, /**< Fixed MIDI velocity value */
|
||||
GEN_ATTENUATION, /**< Initial volume attenuation */
|
||||
GEN_RESERVED2, /**< Reserved */
|
||||
GEN_ENDLOOPADDRCOARSEOFS, /**< Sample end loop address coarse offset (X 32768) */
|
||||
GEN_COARSETUNE, /**< Coarse tuning */
|
||||
GEN_FINETUNE, /**< Fine tuning */
|
||||
GEN_SAMPLEID, /**< Sample ID (shouldn't be set by user) */
|
||||
GEN_SAMPLEMODE, /**< Sample mode flags */
|
||||
GEN_RESERVED3, /**< Reserved */
|
||||
GEN_SCALETUNE, /**< Scale tuning */
|
||||
GEN_EXCLUSIVECLASS, /**< Exclusive class number */
|
||||
GEN_OVERRIDEROOTKEY, /**< Sample root note override */
|
||||
|
||||
/**
|
||||
* Initial Pitch
|
||||
*
|
||||
* @note This is not "standard" SoundFont generator, because it is not
|
||||
* mentioned in the list of generators in the SF2 specifications.
|
||||
* It is used by FluidSynth internally to compute the nominal pitch of
|
||||
* a note on note-on event. By nature it shouldn't be allowed to be modulated,
|
||||
* however the specification defines a default modulator having "Initial Pitch"
|
||||
* as destination (cf. SF2.01 page 57 section 8.4.10 MIDI Pitch Wheel to Initial Pitch).
|
||||
* Thus it is impossible to cancel this default modulator, which would be required
|
||||
* to let the MIDI Pitch Wheel controller modulate a different generator.
|
||||
* In order to provide this flexibility, FluidSynth >= 2.1.0 uses a default modulator
|
||||
* "Pitch Wheel to Fine Tune", rather than Initial Pitch. The same "compromise" can
|
||||
* be found on the Audigy 2 ZS for instance.
|
||||
*/
|
||||
GEN_PITCH,
|
||||
|
||||
GEN_CUSTOM_BALANCE, /**< Balance @note Not a real SoundFont generator */
|
||||
/* non-standard generator for an additional custom high- or low-pass filter */
|
||||
GEN_CUSTOM_FILTERFC, /**< Custom filter cutoff frequency */
|
||||
GEN_CUSTOM_FILTERQ, /**< Custom filter Q */
|
||||
|
||||
GEN_LAST /**< @internal Value defines the count of generators (#fluid_gen_type)
|
||||
@warning This symbol is not part of the public API and ABI
|
||||
stability guarantee and may change at any time! */
|
||||
};
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_GEN_H */
|
||||
|
69
thirdparty/fluidsynth/include/fluidsynth/ladspa.h
vendored
Normal file
69
thirdparty/fluidsynth/include/fluidsynth/ladspa.h
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* 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 _FLUIDSYNTH_LADSPA_H
|
||||
#define _FLUIDSYNTH_LADSPA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup ladspa Effect - LADSPA
|
||||
* @ingroup synth
|
||||
*
|
||||
* Functions for configuring the LADSPA effects unit
|
||||
*
|
||||
* This header defines useful functions for programmatically manipulating the ladspa
|
||||
* effects unit of the synth that can be retrieved via fluid_synth_get_ladspa_fx().
|
||||
*
|
||||
* Using any of those functions requires fluidsynth to be compiled with LADSPA support.
|
||||
* Else all of those functions are useless dummies.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API int fluid_ladspa_is_active(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_activate(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_deactivate(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_reset(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_check(fluid_ladspa_fx_t *fx, char *err, int err_size);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_host_port_exists(fluid_ladspa_fx_t *fx, const char *name);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_add_buffer(fluid_ladspa_fx_t *fx, const char *name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_buffer_exists(fluid_ladspa_fx_t *fx, const char *name);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_add_effect(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *lib_name, const char *plugin_name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_can_mix(fluid_ladspa_fx_t *fx, const char *name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_set_mix(fluid_ladspa_fx_t *fx, const char *name, int mix, float gain);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_port_exists(fluid_ladspa_fx_t *fx, const char *effect_name, const char *port_name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_set_control(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *port_name, float val);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_link(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *port_name, const char *name);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_LADSPA_H */
|
||||
|
97
thirdparty/fluidsynth/include/fluidsynth/log.h
vendored
Normal file
97
thirdparty/fluidsynth/include/fluidsynth/log.h
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* 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 _FLUIDSYNTH_LOG_H
|
||||
#define _FLUIDSYNTH_LOG_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup logging Logging
|
||||
*
|
||||
* Logging interface
|
||||
*
|
||||
* The default logging function of the fluidsynth prints its messages to the
|
||||
* stderr. The synthesizer uses five level of messages: #FLUID_PANIC,
|
||||
* #FLUID_ERR, #FLUID_WARN, #FLUID_INFO, and #FLUID_DBG.
|
||||
*
|
||||
* A client application can install a new log function to handle the messages
|
||||
* differently. In the following example, the application sets a callback
|
||||
* function to display #FLUID_PANIC messages in a dialog, and ignores all other
|
||||
* messages by setting the log function to NULL:
|
||||
*
|
||||
* @code
|
||||
* fluid_set_log_function(FLUID_PANIC, show_dialog, (void*) root_window);
|
||||
* fluid_set_log_function(FLUID_ERR, NULL, NULL);
|
||||
* fluid_set_log_function(FLUID_WARN, NULL, NULL);
|
||||
* fluid_set_log_function(FLUID_DBG, NULL, NULL);
|
||||
* @endcode
|
||||
*
|
||||
* @note The logging configuration is global and not tied to a specific
|
||||
* synthesizer instance. That means that all synthesizer instances created in
|
||||
* the same process share the same logging configuration.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* FluidSynth log levels.
|
||||
*/
|
||||
enum fluid_log_level
|
||||
{
|
||||
FLUID_PANIC, /**< The synth can't function correctly any more */
|
||||
FLUID_ERR, /**< Serious error occurred */
|
||||
FLUID_WARN, /**< Warning */
|
||||
FLUID_INFO, /**< Verbose informational messages */
|
||||
FLUID_DBG, /**< Debugging messages */
|
||||
LAST_LOG_LEVEL /**< @internal This symbol is not part of the public API and ABI
|
||||
stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
/**
|
||||
* Log function handler callback type used by fluid_set_log_function().
|
||||
*
|
||||
* @param level Log level (#fluid_log_level)
|
||||
* @param message Log message text
|
||||
* @param data User data pointer supplied to fluid_set_log_function().
|
||||
*/
|
||||
typedef void (*fluid_log_function_t)(int level, const char *message, void *data);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_log_function_t fluid_set_log_function(int level, fluid_log_function_t fun, void *data);
|
||||
|
||||
FLUIDSYNTH_API void fluid_default_log_function(int level, const char *message, void *data);
|
||||
|
||||
FLUIDSYNTH_API int fluid_log(int level, const char *fmt, ...)
|
||||
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
;
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_LOG_H */
|
294
thirdparty/fluidsynth/include/fluidsynth/midi.h
vendored
Normal file
294
thirdparty/fluidsynth/include/fluidsynth/midi.h
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
/* 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 _FLUIDSYNTH_MIDI_H
|
||||
#define _FLUIDSYNTH_MIDI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup midi_input MIDI Input
|
||||
*
|
||||
* MIDI Input Subsystem
|
||||
*
|
||||
* There are multiple ways to send MIDI events to the synthesizer. They can come
|
||||
* from MIDI files, from external MIDI sequencers or raw MIDI event sources,
|
||||
* can be modified via MIDI routers and also generated manually.
|
||||
*
|
||||
* The interface connecting all sources and sinks of MIDI events in libfluidsynth
|
||||
* is \ref handle_midi_event_func_t.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic callback function for MIDI event handler.
|
||||
*
|
||||
* @param data User defined data pointer
|
||||
* @param event The MIDI event
|
||||
* @return Should return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*
|
||||
* This callback is used to pass MIDI events
|
||||
* - from \ref midi_player, \ref midi_router or \ref midi_driver
|
||||
* - to \ref midi_router via fluid_midi_router_handle_midi_event()
|
||||
* - or to \ref synth via fluid_synth_handle_midi_event().
|
||||
*
|
||||
* Additionally, there is a translation layer to pass MIDI events to
|
||||
* a \ref sequencer via fluid_sequencer_add_midi_event_to_buffer().
|
||||
*/
|
||||
typedef int (*handle_midi_event_func_t)(void *data, fluid_midi_event_t *event);
|
||||
|
||||
/**
|
||||
* Generic callback function fired once by MIDI tick change.
|
||||
*
|
||||
* @param data User defined data pointer
|
||||
* @param tick The current (zero-based) tick, which triggered the callback
|
||||
* @return Should return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*
|
||||
* This callback is fired at a constant rate depending on the current BPM and PPQ.
|
||||
* e.g. for PPQ = 192 and BPM = 140 the callback is fired 192 * 140 times per minute (448/sec).
|
||||
*
|
||||
* It can be used to sync external elements with the beat,
|
||||
* or stop / loop the song on a given tick.
|
||||
* Ticks being BPM-dependent, you can manipulate values such as bars or beats,
|
||||
* without having to care about BPM.
|
||||
*
|
||||
* For example, this callback loops the song whenever it reaches the 5th bar :
|
||||
*
|
||||
* @code{.cpp}
|
||||
int handle_tick(void *data, int tick)
|
||||
{
|
||||
fluid_player_t *player = (fluid_player_t *)data;
|
||||
int ppq = 192; // From MIDI header
|
||||
int beatsPerBar = 4; // From the song's time signature
|
||||
int loopBar = 5;
|
||||
int loopTick = (loopBar - 1) * ppq * beatsPerBar;
|
||||
|
||||
if (tick == loopTick)
|
||||
{
|
||||
return fluid_player_seek(player, 0);
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
* @endcode
|
||||
*/
|
||||
typedef int (*handle_midi_tick_func_t)(void *data, int tick);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_events MIDI Events
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Functions to create, modify, query and delete MIDI events.
|
||||
*
|
||||
* These functions are intended to be used in MIDI routers and other filtering
|
||||
* and processing functions in the MIDI event path. If you want to simply
|
||||
* send MIDI messages to the synthesizer, you can use the more convenient
|
||||
* \ref midi_messages interface.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/** @startlifecycle{MIDI Event} */
|
||||
FLUIDSYNTH_API fluid_midi_event_t *new_fluid_midi_event(void);
|
||||
FLUIDSYNTH_API void delete_fluid_midi_event(fluid_midi_event_t *event);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_type(fluid_midi_event_t *evt, int type);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_type(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_channel(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_key(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_key(fluid_midi_event_t *evt, int key);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_velocity(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int vel);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_control(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_control(fluid_midi_event_t *evt, int ctrl);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_value(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_value(fluid_midi_event_t *evt, int val);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_program(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_program(fluid_midi_event_t *evt, int val);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_pitch(const fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_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);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_text(fluid_midi_event_t *evt,
|
||||
void *data, int size, int dynamic);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_text(fluid_midi_event_t *evt,
|
||||
void **data, int *size);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_lyrics(fluid_midi_event_t *evt,
|
||||
void *data, int size, int dynamic);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_lyrics(fluid_midi_event_t *evt,
|
||||
void **data, int *size);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_router MIDI Router
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Rule based transformation and filtering of MIDI events.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIDI router rule type.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FLUID_MIDI_ROUTER_RULE_NOTE, /**< MIDI note rule */
|
||||
FLUID_MIDI_ROUTER_RULE_CC, /**< MIDI controller rule */
|
||||
FLUID_MIDI_ROUTER_RULE_PROG_CHANGE, /**< MIDI program change rule */
|
||||
FLUID_MIDI_ROUTER_RULE_PITCH_BEND, /**< MIDI pitch bend rule */
|
||||
FLUID_MIDI_ROUTER_RULE_CHANNEL_PRESSURE, /**< MIDI channel pressure rule */
|
||||
FLUID_MIDI_ROUTER_RULE_KEY_PRESSURE, /**< MIDI key pressure rule */
|
||||
FLUID_MIDI_ROUTER_RULE_COUNT /**< @internal Total count of rule types. This symbol
|
||||
is not part of the public API and ABI stability
|
||||
guarantee and may change at any time!*/
|
||||
} fluid_midi_router_rule_type;
|
||||
|
||||
|
||||
/** @startlifecycle{MIDI Router} */
|
||||
FLUIDSYNTH_API fluid_midi_router_t *new_fluid_midi_router(fluid_settings_t *settings,
|
||||
handle_midi_event_func_t handler,
|
||||
void *event_handler_data);
|
||||
FLUIDSYNTH_API void delete_fluid_midi_router(fluid_midi_router_t *handler);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_midi_router_set_default_rules(fluid_midi_router_t *router);
|
||||
FLUIDSYNTH_API int fluid_midi_router_clear_rules(fluid_midi_router_t *router);
|
||||
FLUIDSYNTH_API int fluid_midi_router_add_rule(fluid_midi_router_t *router,
|
||||
fluid_midi_router_rule_t *rule, int type);
|
||||
|
||||
|
||||
/** @startlifecycle{MIDI Router Rule} */
|
||||
FLUIDSYNTH_API fluid_midi_router_rule_t *new_fluid_midi_router_rule(void);
|
||||
FLUIDSYNTH_API void delete_fluid_midi_router_rule(fluid_midi_router_rule_t *rule);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API void fluid_midi_router_rule_set_chan(fluid_midi_router_rule_t *rule,
|
||||
int min, int max, float mul, int add);
|
||||
FLUIDSYNTH_API void fluid_midi_router_rule_set_param1(fluid_midi_router_rule_t *rule,
|
||||
int min, int max, float mul, int add);
|
||||
FLUIDSYNTH_API void fluid_midi_router_rule_set_param2(fluid_midi_router_rule_t *rule,
|
||||
int min, int max, float mul, int add);
|
||||
FLUIDSYNTH_API int fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event);
|
||||
FLUIDSYNTH_API int fluid_midi_dump_prerouter(void *data, fluid_midi_event_t *event);
|
||||
FLUIDSYNTH_API int fluid_midi_dump_postrouter(void *data, fluid_midi_event_t *event);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_driver MIDI Driver
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Functions for managing MIDI drivers.
|
||||
*
|
||||
* The available MIDI drivers depend on your platform. See \ref settings_midi for all
|
||||
* available configuration options.
|
||||
*
|
||||
* To create a MIDI driver, you need to specify a source for the MIDI events to be
|
||||
* forwarded to via the \ref fluid_midi_event_t callback. Normally this will be
|
||||
* either a \ref midi_router via fluid_midi_router_handle_midi_event() or the synthesizer
|
||||
* via fluid_synth_handle_midi_event().
|
||||
*
|
||||
* But you can also write your own handler function that preprocesses the events and
|
||||
* forwards them on to the router or synthesizer instead.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @startlifecycle{MIDI Driver} */
|
||||
FLUIDSYNTH_API
|
||||
fluid_midi_driver_t *new_fluid_midi_driver(fluid_settings_t *settings,
|
||||
handle_midi_event_func_t handler,
|
||||
void *event_handler_data);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_midi_driver(fluid_midi_driver_t *driver);
|
||||
/** @endlifecycle */
|
||||
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_player MIDI File Player
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Parse standard MIDI files and emit MIDI events.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIDI File Player status enum.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
enum fluid_player_status
|
||||
{
|
||||
FLUID_PLAYER_READY, /**< Player is ready */
|
||||
FLUID_PLAYER_PLAYING, /**< Player is currently playing */
|
||||
FLUID_PLAYER_STOPPING, /**< Player is stopping, but hasn't finished yet (currently unused) */
|
||||
FLUID_PLAYER_DONE /**< Player is finished playing */
|
||||
};
|
||||
|
||||
/**
|
||||
* MIDI File Player tempo enum.
|
||||
* @since 2.2.0
|
||||
*/
|
||||
enum fluid_player_set_tempo_type
|
||||
{
|
||||
FLUID_PLAYER_TEMPO_INTERNAL, /**< Use midi file tempo set in midi file (120 bpm by default). Multiplied by a factor */
|
||||
FLUID_PLAYER_TEMPO_EXTERNAL_BPM, /**< Set player tempo in bpm, supersede midi file tempo */
|
||||
FLUID_PLAYER_TEMPO_EXTERNAL_MIDI, /**< Set player tempo in us per quarter note, supersede midi file tempo */
|
||||
FLUID_PLAYER_TEMPO_NBR /**< @internal Value defines the count of player tempo type (#fluid_player_set_tempo_type) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
/** @startlifecycle{MIDI File Player} */
|
||||
FLUIDSYNTH_API fluid_player_t *new_fluid_player(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API void delete_fluid_player(fluid_player_t *player);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_player_add(fluid_player_t *player, const char *midifile);
|
||||
FLUIDSYNTH_API int fluid_player_add_mem(fluid_player_t *player, const void *buffer, size_t len);
|
||||
FLUIDSYNTH_API int fluid_player_play(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_stop(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_join(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_set_loop(fluid_player_t *player, int loop);
|
||||
FLUIDSYNTH_API int fluid_player_set_tempo(fluid_player_t *player, int tempo_type, double tempo);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_player_set_midi_tempo(fluid_player_t *player, int tempo);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_player_set_bpm(fluid_player_t *player, int bpm);
|
||||
FLUIDSYNTH_API int fluid_player_set_playback_callback(fluid_player_t *player, handle_midi_event_func_t handler, void *handler_data);
|
||||
FLUIDSYNTH_API int fluid_player_set_tick_callback(fluid_player_t *player, handle_midi_tick_func_t handler, void *handler_data);
|
||||
|
||||
FLUIDSYNTH_API int fluid_player_get_status(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_current_tick(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_total_ticks(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_bpm(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_midi_tempo(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_seek(fluid_player_t *player, int ticks);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_MIDI_H */
|
77
thirdparty/fluidsynth/include/fluidsynth/misc.h
vendored
Normal file
77
thirdparty/fluidsynth/include/fluidsynth/misc.h
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* 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 _FLUIDSYNTH_MISC_H
|
||||
#define _FLUIDSYNTH_MISC_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup misc Miscellaneous
|
||||
*
|
||||
* Miscellaneous utility functions and defines
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Value that indicates success, used by most libfluidsynth functions.
|
||||
*
|
||||
* @note This was not publicly defined prior to libfluidsynth 1.1.0. When
|
||||
* writing code which should also be compatible with older versions, something
|
||||
* like the following can be used:
|
||||
*
|
||||
* @code
|
||||
* #include <fluidsynth.h>
|
||||
*
|
||||
* #ifndef FLUID_OK
|
||||
* #define FLUID_OK (0)
|
||||
* #define FLUID_FAILED (-1)
|
||||
* #endif
|
||||
* @endcode
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
#define FLUID_OK (0)
|
||||
|
||||
/**
|
||||
* Value that indicates failure, used by most libfluidsynth functions.
|
||||
*
|
||||
* @note See #FLUID_OK for more details.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
#define FLUID_FAILED (-1)
|
||||
|
||||
|
||||
FLUIDSYNTH_API int fluid_is_soundfont(const char *filename);
|
||||
FLUIDSYNTH_API int fluid_is_midifile(const char *filename);
|
||||
FLUIDSYNTH_API void fluid_free(void* ptr);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_MISC_H */
|
105
thirdparty/fluidsynth/include/fluidsynth/mod.h
vendored
Normal file
105
thirdparty/fluidsynth/include/fluidsynth/mod.h
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* 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 _FLUIDSYNTH_MOD_H
|
||||
#define _FLUIDSYNTH_MOD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup modulators SoundFont Modulators
|
||||
* @ingroup soundfonts
|
||||
*
|
||||
* SoundFont modulator functions and constants.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Flags defining the polarity, mapping function and type of a modulator source.
|
||||
* Compare with SoundFont 2.04 PDF section 8.2.
|
||||
*
|
||||
* Note: Bit values do not correspond to the SoundFont spec! Also note that
|
||||
* #FLUID_MOD_GC and #FLUID_MOD_CC are in the flags field instead of the source field.
|
||||
*/
|
||||
enum fluid_mod_flags
|
||||
{
|
||||
FLUID_MOD_POSITIVE = 0, /**< Mapping function is positive */
|
||||
FLUID_MOD_NEGATIVE = 1, /**< Mapping function is negative */
|
||||
FLUID_MOD_UNIPOLAR = 0, /**< Mapping function is unipolar */
|
||||
FLUID_MOD_BIPOLAR = 2, /**< Mapping function is bipolar */
|
||||
FLUID_MOD_LINEAR = 0, /**< Linear mapping function */
|
||||
FLUID_MOD_CONCAVE = 4, /**< Concave mapping function */
|
||||
FLUID_MOD_CONVEX = 8, /**< Convex mapping function */
|
||||
FLUID_MOD_SWITCH = 12, /**< Switch (on/off) mapping function */
|
||||
FLUID_MOD_GC = 0, /**< General controller source type (#fluid_mod_src) */
|
||||
FLUID_MOD_CC = 16, /**< MIDI CC controller (source will be a MIDI CC number) */
|
||||
|
||||
FLUID_MOD_SIN = 0x80, /**< Custom non-standard sinus mapping function */
|
||||
};
|
||||
|
||||
/**
|
||||
* General controller (if #FLUID_MOD_GC in flags). This
|
||||
* corresponds to SoundFont 2.04 PDF section 8.2.1
|
||||
*/
|
||||
enum fluid_mod_src
|
||||
{
|
||||
FLUID_MOD_NONE = 0, /**< No source controller */
|
||||
FLUID_MOD_VELOCITY = 2, /**< MIDI note-on velocity */
|
||||
FLUID_MOD_KEY = 3, /**< MIDI note-on note number */
|
||||
FLUID_MOD_KEYPRESSURE = 10, /**< MIDI key pressure */
|
||||
FLUID_MOD_CHANNELPRESSURE = 13, /**< MIDI channel pressure */
|
||||
FLUID_MOD_PITCHWHEEL = 14, /**< Pitch wheel */
|
||||
FLUID_MOD_PITCHWHEELSENS = 16 /**< Pitch wheel sensitivity */
|
||||
};
|
||||
|
||||
/** @startlifecycle{Modulator} */
|
||||
FLUIDSYNTH_API fluid_mod_t *new_fluid_mod(void);
|
||||
FLUIDSYNTH_API void delete_fluid_mod(fluid_mod_t *mod);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API size_t fluid_mod_sizeof(void);
|
||||
|
||||
FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t *mod, int src, int flags);
|
||||
FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t *mod, int src, int flags);
|
||||
FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t *mod, int dst);
|
||||
FLUIDSYNTH_API void fluid_mod_set_amount(fluid_mod_t *mod, double amount);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_get_source1(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_flags1(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_source2(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_flags2(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_dest(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API double fluid_mod_get_amount(const fluid_mod_t *mod);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_test_identity(const fluid_mod_t *mod1, const fluid_mod_t *mod2);
|
||||
FLUIDSYNTH_API int fluid_mod_has_source(const fluid_mod_t *mod, int cc, int ctrl);
|
||||
FLUIDSYNTH_API int fluid_mod_has_dest(const fluid_mod_t *mod, int gen);
|
||||
|
||||
FLUIDSYNTH_API void fluid_mod_clone(fluid_mod_t *mod, const fluid_mod_t *src);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_MOD_H */
|
||||
|
92
thirdparty/fluidsynth/include/fluidsynth/seq.h
vendored
Normal file
92
thirdparty/fluidsynth/include/fluidsynth/seq.h
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* 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 _FLUIDSYNTH_SEQ_H
|
||||
#define _FLUIDSYNTH_SEQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup sequencer MIDI Sequencer
|
||||
*
|
||||
* MIDI event sequencer.
|
||||
*
|
||||
* The MIDI sequencer can be used to play MIDI events in a more flexible way than
|
||||
* using the MIDI file player, which expects the events to be stored as
|
||||
* Standard MIDI Files. Using the sequencer, you can provide the events one by
|
||||
* one, with an optional timestamp for scheduling.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Event callback prototype for destination clients.
|
||||
*
|
||||
* @param time Current sequencer tick value (see fluid_sequencer_get_tick()).
|
||||
* @param event The event being received
|
||||
* @param seq The sequencer instance
|
||||
* @param data User defined data registered with the client
|
||||
*
|
||||
* @note @p time may not be of the same tick value as the scheduled event! In fact, depending on
|
||||
* the sequencer's scale and the synth's sample-rate, @p time may be a few ticks too late. Although this
|
||||
* 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
|
||||
* a timing error, which causes your sequence to sound e.g. slower than it's supposed to be. If this is
|
||||
* your use-case, make sure to enqueue events with an absolute tick value.
|
||||
*/
|
||||
typedef void (*fluid_event_callback_t)(unsigned int time, fluid_event_t *event,
|
||||
fluid_sequencer_t *seq, void *data);
|
||||
|
||||
|
||||
/** @startlifecycle{MIDI Sequencer} */
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API fluid_sequencer_t *new_fluid_sequencer(void);
|
||||
FLUIDSYNTH_API fluid_sequencer_t *new_fluid_sequencer2(int use_system_timer);
|
||||
FLUIDSYNTH_API void delete_fluid_sequencer(fluid_sequencer_t *seq);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_sequencer_get_use_system_timer(fluid_sequencer_t *seq);
|
||||
FLUIDSYNTH_API
|
||||
fluid_seq_id_t fluid_sequencer_register_client(fluid_sequencer_t *seq, const char *name,
|
||||
fluid_event_callback_t callback, void *data);
|
||||
FLUIDSYNTH_API void fluid_sequencer_unregister_client(fluid_sequencer_t *seq, fluid_seq_id_t id);
|
||||
FLUIDSYNTH_API int fluid_sequencer_count_clients(fluid_sequencer_t *seq);
|
||||
FLUIDSYNTH_API fluid_seq_id_t fluid_sequencer_get_client_id(fluid_sequencer_t *seq, int index);
|
||||
FLUIDSYNTH_API char *fluid_sequencer_get_client_name(fluid_sequencer_t *seq, fluid_seq_id_t id);
|
||||
FLUIDSYNTH_API int fluid_sequencer_client_is_dest(fluid_sequencer_t *seq, fluid_seq_id_t id);
|
||||
FLUIDSYNTH_API void fluid_sequencer_process(fluid_sequencer_t *seq, unsigned int msec);
|
||||
FLUIDSYNTH_API void fluid_sequencer_send_now(fluid_sequencer_t *seq, fluid_event_t *evt);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_sequencer_send_at(fluid_sequencer_t *seq, fluid_event_t *evt,
|
||||
unsigned int time, int absolute);
|
||||
FLUIDSYNTH_API
|
||||
void fluid_sequencer_remove_events(fluid_sequencer_t *seq, fluid_seq_id_t source, fluid_seq_id_t dest, int type);
|
||||
FLUIDSYNTH_API unsigned int fluid_sequencer_get_tick(fluid_sequencer_t *seq);
|
||||
FLUIDSYNTH_API void fluid_sequencer_set_time_scale(fluid_sequencer_t *seq, double scale);
|
||||
FLUIDSYNTH_API double fluid_sequencer_get_time_scale(fluid_sequencer_t *seq);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SEQ_H */
|
45
thirdparty/fluidsynth/include/fluidsynth/seqbind.h
vendored
Normal file
45
thirdparty/fluidsynth/include/fluidsynth/seqbind.h
vendored
Normal 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 _FLUIDSYNTH_SEQBIND_H
|
||||
#define _FLUIDSYNTH_SEQBIND_H
|
||||
|
||||
#include "seq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup sequencer
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
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);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_SEQBIND_H */
|
||||
|
194
thirdparty/fluidsynth/include/fluidsynth/settings.h
vendored
Normal file
194
thirdparty/fluidsynth/include/fluidsynth/settings.h
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
/* 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 _FLUIDSYNTH_SETTINGS_H
|
||||
#define _FLUIDSYNTH_SETTINGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup settings Settings
|
||||
*
|
||||
* Functions for settings management
|
||||
*
|
||||
* To create a synthesizer object you will have to specify its
|
||||
* settings. These settings are stored in a fluid_settings_t object.
|
||||
* @code
|
||||
* void
|
||||
* my_synthesizer ()
|
||||
* {
|
||||
* fluid_settings_t *settings;
|
||||
* fluid_synth_t *synth;
|
||||
* fluid_audio_driver_t *adriver;
|
||||
*
|
||||
* settings = new_fluid_settings ();
|
||||
* fluid_settings_setstr(settings, "audio.driver", "alsa");
|
||||
* // ... change settings ...
|
||||
* synth = new_fluid_synth (settings);
|
||||
* adriver = new_fluid_audio_driver (settings, synth);
|
||||
* // ...
|
||||
* }
|
||||
* @endcode
|
||||
* @sa @ref CreatingSettings
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hint FLUID_HINT_BOUNDED_BELOW indicates that the LowerBound field
|
||||
* of the FLUID_PortRangeHint should be considered meaningful. The
|
||||
* value in this field should be considered the (inclusive) lower
|
||||
* bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
|
||||
* specified then the value of LowerBound should be multiplied by the
|
||||
* sample rate.
|
||||
*/
|
||||
#define FLUID_HINT_BOUNDED_BELOW 0x1
|
||||
|
||||
/** Hint FLUID_HINT_BOUNDED_ABOVE indicates that the UpperBound field
|
||||
of the FLUID_PortRangeHint should be considered meaningful. The
|
||||
value in this field should be considered the (inclusive) upper
|
||||
bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
|
||||
specified then the value of UpperBound should be multiplied by the
|
||||
sample rate. */
|
||||
#define FLUID_HINT_BOUNDED_ABOVE 0x2
|
||||
|
||||
/**
|
||||
* Hint FLUID_HINT_TOGGLED indicates that the data item should be
|
||||
* considered a Boolean toggle. Data less than or equal to zero should
|
||||
* be considered `off' or `false,' and data above zero should be
|
||||
* considered `on' or `true.' FLUID_HINT_TOGGLED may not be used in
|
||||
* conjunction with any other hint.
|
||||
*/
|
||||
#define FLUID_HINT_TOGGLED 0x4
|
||||
|
||||
#define FLUID_HINT_OPTIONLIST 0x02 /**< Setting is a list of string options */
|
||||
|
||||
|
||||
/**
|
||||
* Settings type
|
||||
*
|
||||
* Each setting has a defined type: numeric (double), integer, string or a
|
||||
* set of values. The type of each setting can be retrieved using the
|
||||
* function fluid_settings_get_type()
|
||||
*/
|
||||
enum fluid_types_enum
|
||||
{
|
||||
FLUID_NO_TYPE = -1, /**< Undefined type */
|
||||
FLUID_NUM_TYPE, /**< Numeric (double) */
|
||||
FLUID_INT_TYPE, /**< Integer */
|
||||
FLUID_STR_TYPE, /**< String */
|
||||
FLUID_SET_TYPE /**< Set of values */
|
||||
};
|
||||
|
||||
/** @startlifecycle{Settings} */
|
||||
FLUIDSYNTH_API fluid_settings_t *new_fluid_settings(void);
|
||||
FLUIDSYNTH_API void delete_fluid_settings(fluid_settings_t *settings);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_get_type(fluid_settings_t *settings, const char *name);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_get_hints(fluid_settings_t *settings, const char *name, int *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_is_realtime(fluid_settings_t *settings, const char *name);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_setstr(fluid_settings_t *settings, const char *name, const char *str);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_copystr(fluid_settings_t *settings, const char *name, char *str, int len);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_dupstr(fluid_settings_t *settings, const char *name, char **str);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getstr_default(fluid_settings_t *settings, const char *name, char **def);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_str_equal(fluid_settings_t *settings, const char *name, const char *value);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_setnum(fluid_settings_t *settings, const char *name, double val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getnum(fluid_settings_t *settings, const char *name, double *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getnum_default(fluid_settings_t *settings, const char *name, double *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getnum_range(fluid_settings_t *settings, const char *name,
|
||||
double *min, double *max);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_setint(fluid_settings_t *settings, const char *name, int val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getint(fluid_settings_t *settings, const char *name, int *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getint_default(fluid_settings_t *settings, const char *name, int *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getint_range(fluid_settings_t *settings, const char *name,
|
||||
int *min, int *max);
|
||||
|
||||
/**
|
||||
* Callback function type used with fluid_settings_foreach_option()
|
||||
*
|
||||
* @param data User defined data pointer
|
||||
* @param name Setting name
|
||||
* @param option A string option for this setting (iterates through the list)
|
||||
*/
|
||||
typedef void (*fluid_settings_foreach_option_t)(void *data, const char *name, const char *option);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_settings_foreach_option(fluid_settings_t *settings,
|
||||
const char *name, void *data,
|
||||
fluid_settings_foreach_option_t func);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_option_count(fluid_settings_t *settings, const char *name);
|
||||
FLUIDSYNTH_API char *fluid_settings_option_concat(fluid_settings_t *settings,
|
||||
const char *name,
|
||||
const char *separator);
|
||||
|
||||
/**
|
||||
* Callback function type used with fluid_settings_foreach()
|
||||
*
|
||||
* @param data User defined data pointer
|
||||
* @param name Setting name
|
||||
* @param type Setting type (#fluid_types_enum)
|
||||
*/
|
||||
typedef void (*fluid_settings_foreach_t)(void *data, const char *name, int type);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_settings_foreach(fluid_settings_t *settings, void *data,
|
||||
fluid_settings_foreach_t func);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SETTINGS_H */
|
362
thirdparty/fluidsynth/include/fluidsynth/sfont.h
vendored
Normal file
362
thirdparty/fluidsynth/include/fluidsynth/sfont.h
vendored
Normal file
|
@ -0,0 +1,362 @@
|
|||
/* 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 _FLUIDSYNTH_SFONT_H
|
||||
#define _FLUIDSYNTH_SFONT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup soundfonts SoundFonts
|
||||
*
|
||||
* SoundFont related functions
|
||||
*
|
||||
* This part of the API contains functions, defines and types that are mostly
|
||||
* only used by internal or custom SoundFont loaders or client code that
|
||||
* modifies loaded presets, SoundFonts or voices directly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup soundfont_loader SoundFont Loader
|
||||
* @ingroup soundfonts
|
||||
*
|
||||
* Create custom SoundFont loaders
|
||||
*
|
||||
* It is possible to add new SoundFont loaders to the
|
||||
* synthesizer. This API allows for virtual SoundFont files to be loaded
|
||||
* and synthesized, which may not actually be SoundFont files, as long as they
|
||||
* can be represented by the SoundFont synthesis model.
|
||||
*
|
||||
* To add a new SoundFont loader to the synthesizer, call
|
||||
* fluid_synth_add_sfloader() and pass a pointer to an
|
||||
* #fluid_sfloader_t instance created by new_fluid_sfloader().
|
||||
* On creation, you must specify a callback function \p load
|
||||
* that will be called for every file attempting to load it and
|
||||
* if successful returns a #fluid_sfont_t instance, or NULL if it fails.
|
||||
*
|
||||
* The #fluid_sfont_t structure contains a callback to obtain the
|
||||
* name of the SoundFont. It contains two functions to iterate
|
||||
* though the contained presets, and one function to obtain a
|
||||
* preset corresponding to a bank and preset number. This
|
||||
* function should return a #fluid_preset_t instance.
|
||||
*
|
||||
* The #fluid_preset_t instance contains some functions to obtain
|
||||
* information from the preset (name, bank, number). The most
|
||||
* important callback is the noteon function. The noteon function
|
||||
* is called by fluidsynth internally and
|
||||
* should call fluid_synth_alloc_voice() for every sample that has
|
||||
* to be played. fluid_synth_alloc_voice() expects a pointer to a
|
||||
* #fluid_sample_t instance and returns a pointer to the opaque
|
||||
* #fluid_voice_t structure. To set or increment the values of a
|
||||
* generator, use fluid_voice_gen_set() or fluid_voice_gen_incr(). When you are
|
||||
* finished initializing the voice call fluid_voice_start() to
|
||||
* start playing the synthesis voice.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Some notification enums for presets and samples.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
FLUID_PRESET_SELECTED, /**< Preset selected notify */
|
||||
FLUID_PRESET_UNSELECTED, /**< Preset unselected notify */
|
||||
FLUID_SAMPLE_DONE, /**< Sample no longer needed notify */
|
||||
FLUID_PRESET_PIN, /**< Request to pin preset samples to cache */
|
||||
FLUID_PRESET_UNPIN /**< Request to unpin preset samples from cache */
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates the type of a sample used by the _fluid_sample_t::sampletype field.
|
||||
*
|
||||
* This enum corresponds to the \c SFSampleLink enum in the SoundFont spec.
|
||||
* One \c flag may be bit-wise OR-ed with one \c value.
|
||||
*/
|
||||
enum fluid_sample_type
|
||||
{
|
||||
FLUID_SAMPLETYPE_MONO = 0x1, /**< Value used for mono samples */
|
||||
FLUID_SAMPLETYPE_RIGHT = 0x2, /**< Value used for right samples of a stereo pair */
|
||||
FLUID_SAMPLETYPE_LEFT = 0x4, /**< Value used for left samples of a stereo pair */
|
||||
FLUID_SAMPLETYPE_LINKED = 0x8, /**< Value used for linked sample, which is currently not supported */
|
||||
FLUID_SAMPLETYPE_OGG_VORBIS = 0x10, /**< Flag used for Ogg Vorbis compressed samples (non-standard compliant extension) as found in the program "sftools" developed by Werner Schweer from MuseScore @since 1.1.7 */
|
||||
FLUID_SAMPLETYPE_ROM = 0x8000 /**< Flag that indicates ROM samples, causing the sample to be ignored */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Method to load an instrument file (does not actually need to be a real file name,
|
||||
* could be another type of string identifier that the \a loader understands).
|
||||
*
|
||||
* @param loader SoundFont loader
|
||||
* @param filename File name or other string identifier
|
||||
* @return The loaded instrument file (SoundFont) or NULL if an error occurred.
|
||||
*/
|
||||
typedef fluid_sfont_t *(*fluid_sfloader_load_t)(fluid_sfloader_t *loader, const char *filename);
|
||||
|
||||
/**
|
||||
* The free method should free the memory allocated for a fluid_sfloader_t instance in
|
||||
* addition to any private data.
|
||||
*
|
||||
* @param loader SoundFont loader
|
||||
*
|
||||
* Any custom user provided cleanup function must ultimately call
|
||||
* delete_fluid_sfloader() to ensure proper cleanup of the #fluid_sfloader_t struct. If no private data
|
||||
* needs to be freed, setting this to delete_fluid_sfloader() is sufficient.
|
||||
*
|
||||
*/
|
||||
typedef void (*fluid_sfloader_free_t)(fluid_sfloader_t *loader);
|
||||
|
||||
|
||||
/** @startlifecycle{SoundFont Loader} */
|
||||
FLUIDSYNTH_API fluid_sfloader_t *new_fluid_sfloader(fluid_sfloader_load_t load, fluid_sfloader_free_t free);
|
||||
FLUIDSYNTH_API void delete_fluid_sfloader(fluid_sfloader_t *loader);
|
||||
|
||||
FLUIDSYNTH_API fluid_sfloader_t *new_fluid_defsfloader(fluid_settings_t *settings);
|
||||
/** @endlifecycle */
|
||||
|
||||
/**
|
||||
* Opens the file or memory indicated by \c filename in binary read mode.
|
||||
*
|
||||
* @return returns a file handle on success, NULL otherwise
|
||||
*
|
||||
* \c filename matches the string provided during the fluid_synth_sfload() call.
|
||||
*/
|
||||
typedef void *(* fluid_sfloader_callback_open_t)(const char *filename);
|
||||
|
||||
/**
|
||||
* Reads \c count bytes to the specified buffer \c buf.
|
||||
*
|
||||
* @return returns #FLUID_OK if exactly \c count bytes were successfully read, else returns #FLUID_FAILED and leaves \a buf unmodified.
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_read_t)(void *buf, fluid_long_long_t count, void *handle);
|
||||
|
||||
/**
|
||||
* Same purpose and behaviour as fseek.
|
||||
*
|
||||
* @param origin either \c SEEK_SET, \c SEEK_CUR or \c SEEK_END
|
||||
* @return returns #FLUID_OK if the seek was successfully performed while not seeking beyond a buffer or file, #FLUID_FAILED otherwise
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_seek_t)(void *handle, fluid_long_long_t offset, int origin);
|
||||
|
||||
/**
|
||||
* Closes the handle returned by #fluid_sfloader_callback_open_t and frees used resources.
|
||||
*
|
||||
* @return returns #FLUID_OK on success, #FLUID_FAILED on error
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_close_t)(void *handle);
|
||||
|
||||
/** @return returns current file offset or #FLUID_FAILED on error */
|
||||
typedef fluid_long_long_t (* fluid_sfloader_callback_tell_t)(void *handle);
|
||||
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfloader_set_callbacks(fluid_sfloader_t *loader,
|
||||
fluid_sfloader_callback_open_t open,
|
||||
fluid_sfloader_callback_read_t read,
|
||||
fluid_sfloader_callback_seek_t seek,
|
||||
fluid_sfloader_callback_tell_t tell,
|
||||
fluid_sfloader_callback_close_t close);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfloader_set_data(fluid_sfloader_t *loader, void *data);
|
||||
FLUIDSYNTH_API void *fluid_sfloader_get_data(fluid_sfloader_t *loader);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Method to return the name of a virtual SoundFont.
|
||||
*
|
||||
* @param sfont Virtual SoundFont
|
||||
* @return The name of the virtual SoundFont.
|
||||
*/
|
||||
typedef const char *(*fluid_sfont_get_name_t)(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Get a virtual SoundFont preset by bank and program numbers.
|
||||
*
|
||||
* @param sfont Virtual SoundFont
|
||||
* @param bank MIDI bank number (0-16383)
|
||||
* @param prenum MIDI preset number (0-127)
|
||||
* @return Should return an allocated virtual preset or NULL if it could not
|
||||
* be found.
|
||||
*/
|
||||
typedef fluid_preset_t *(*fluid_sfont_get_preset_t)(fluid_sfont_t *sfont, int bank, int prenum);
|
||||
|
||||
/**
|
||||
* Start virtual SoundFont preset iteration method.
|
||||
*
|
||||
* @param sfont Virtual SoundFont
|
||||
*
|
||||
* Starts/re-starts virtual preset iteration in a SoundFont.
|
||||
*/
|
||||
typedef void (*fluid_sfont_iteration_start_t)(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Virtual SoundFont preset iteration function.
|
||||
*
|
||||
* @param sfont Virtual SoundFont
|
||||
* @return NULL when no more presets are available, otherwise the a pointer to the current preset
|
||||
*
|
||||
* Returns preset information to the caller. The returned buffer is only valid until a subsequent
|
||||
* call to this function.
|
||||
*/
|
||||
typedef fluid_preset_t *(*fluid_sfont_iteration_next_t)(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Method to free a virtual SoundFont bank.
|
||||
*
|
||||
* @param sfont Virtual SoundFont to free.
|
||||
* @return Should return 0 when it was able to free all resources or non-zero
|
||||
* if some of the samples could not be freed because they are still in use,
|
||||
* in which case the free will be tried again later, until success.
|
||||
*
|
||||
* Any custom user provided cleanup function must ultimately call
|
||||
* delete_fluid_sfont() to ensure proper cleanup of the #fluid_sfont_t struct. If no private data
|
||||
* needs to be freed, setting this to delete_fluid_sfont() is sufficient.
|
||||
*/
|
||||
typedef int (*fluid_sfont_free_t)(fluid_sfont_t *sfont);
|
||||
|
||||
|
||||
/** @startlifecycle{SoundFont} */
|
||||
FLUIDSYNTH_API fluid_sfont_t *new_fluid_sfont(fluid_sfont_get_name_t get_name,
|
||||
fluid_sfont_get_preset_t get_preset,
|
||||
fluid_sfont_iteration_start_t iter_start,
|
||||
fluid_sfont_iteration_next_t iter_next,
|
||||
fluid_sfont_free_t free);
|
||||
|
||||
FLUIDSYNTH_API int delete_fluid_sfont(fluid_sfont_t *sfont);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfont_set_data(fluid_sfont_t *sfont, void *data);
|
||||
FLUIDSYNTH_API void *fluid_sfont_get_data(fluid_sfont_t *sfont);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfont_get_id(fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API const char *fluid_sfont_get_name(fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API fluid_preset_t *fluid_sfont_get_preset(fluid_sfont_t *sfont, int bank, int prenum);
|
||||
FLUIDSYNTH_API void fluid_sfont_iteration_start(fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API fluid_preset_t *fluid_sfont_iteration_next(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Method to get a virtual SoundFont preset name.
|
||||
*
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @return Should return the name of the preset. The returned string must be
|
||||
* valid for the duration of the virtual preset (or the duration of the
|
||||
* SoundFont, in the case of preset iteration).
|
||||
*/
|
||||
typedef const char *(*fluid_preset_get_name_t)(fluid_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Method to get a virtual SoundFont preset MIDI bank number.
|
||||
*
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @param return The bank number of the preset
|
||||
*/
|
||||
typedef int (*fluid_preset_get_banknum_t)(fluid_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Method to get a virtual SoundFont preset MIDI program number.
|
||||
*
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @param return The program number of the preset
|
||||
*/
|
||||
typedef int (*fluid_preset_get_num_t)(fluid_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Method to handle a noteon event (synthesize the instrument).
|
||||
*
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @param synth Synthesizer instance
|
||||
* @param chan MIDI channel number of the note on event
|
||||
* @param key MIDI note number (0-127)
|
||||
* @param vel MIDI velocity (0-127)
|
||||
* @return #FLUID_OK on success (0) or #FLUID_FAILED (-1) otherwise
|
||||
*
|
||||
* This method may be called from within synthesis context and therefore
|
||||
* should be as efficient as possible and not perform any operations considered
|
||||
* bad for realtime audio output (memory allocations and other OS calls).
|
||||
*
|
||||
* Call fluid_synth_alloc_voice() for every sample that has
|
||||
* to be played. fluid_synth_alloc_voice() expects a pointer to a
|
||||
* #fluid_sample_t structure and returns a pointer to the opaque
|
||||
* #fluid_voice_t structure. To set or increment the values of a
|
||||
* generator, use fluid_voice_gen_set() or fluid_voice_gen_incr(). When you are
|
||||
* finished initializing the voice call fluid_voice_start() to
|
||||
* start playing the synthesis voice. Starting with FluidSynth 1.1.0 all voices
|
||||
* created will be started at the same time.
|
||||
*/
|
||||
typedef int (*fluid_preset_noteon_t)(fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel);
|
||||
|
||||
/**
|
||||
* Method to free a virtual SoundFont preset.
|
||||
*
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @return Should return 0
|
||||
*
|
||||
* Any custom user provided cleanup function must ultimately call
|
||||
* delete_fluid_preset() to ensure proper cleanup of the #fluid_preset_t struct. If no private data
|
||||
* needs to be freed, setting this to delete_fluid_preset() is sufficient.
|
||||
*/
|
||||
typedef void (*fluid_preset_free_t)(fluid_preset_t *preset);
|
||||
|
||||
/** @startlifecycle{Preset} */
|
||||
FLUIDSYNTH_API fluid_preset_t *new_fluid_preset(fluid_sfont_t *parent_sfont,
|
||||
fluid_preset_get_name_t get_name,
|
||||
fluid_preset_get_banknum_t get_bank,
|
||||
fluid_preset_get_num_t get_num,
|
||||
fluid_preset_noteon_t noteon,
|
||||
fluid_preset_free_t free);
|
||||
FLUIDSYNTH_API void delete_fluid_preset(fluid_preset_t *preset);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API int fluid_preset_set_data(fluid_preset_t *preset, void *data);
|
||||
FLUIDSYNTH_API void *fluid_preset_get_data(fluid_preset_t *preset);
|
||||
|
||||
FLUIDSYNTH_API const char *fluid_preset_get_name(fluid_preset_t *preset);
|
||||
FLUIDSYNTH_API int fluid_preset_get_banknum(fluid_preset_t *preset);
|
||||
FLUIDSYNTH_API int fluid_preset_get_num(fluid_preset_t *preset);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_preset_get_sfont(fluid_preset_t *preset);
|
||||
|
||||
/** @startlifecycle{Sample} */
|
||||
FLUIDSYNTH_API fluid_sample_t *new_fluid_sample(void);
|
||||
FLUIDSYNTH_API void delete_fluid_sample(fluid_sample_t *sample);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API size_t fluid_sample_sizeof(void);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sample_set_name(fluid_sample_t *sample, const char *name);
|
||||
FLUIDSYNTH_API int fluid_sample_set_sound_data(fluid_sample_t *sample,
|
||||
short *data,
|
||||
char *data24,
|
||||
unsigned int nbframes,
|
||||
unsigned int sample_rate,
|
||||
short copy_data);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sample_set_loop(fluid_sample_t *sample, unsigned int loop_start, unsigned int loop_end);
|
||||
FLUIDSYNTH_API int fluid_sample_set_pitch(fluid_sample_t *sample, int root_key, int fine_tune);
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SFONT_H */
|
150
thirdparty/fluidsynth/include/fluidsynth/shell.h
vendored
Normal file
150
thirdparty/fluidsynth/include/fluidsynth/shell.h
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* 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 _FLUIDSYNTH_SHELL_H
|
||||
#define _FLUIDSYNTH_SHELL_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup command_interface Command Interface
|
||||
*
|
||||
* Control and configuration interface
|
||||
*
|
||||
* The command interface allows you to send textual commands to
|
||||
* the synthesizer, to parse a command file, or to read commands
|
||||
* from the stdin or other input streams (like a TCP socket).
|
||||
*
|
||||
* For a full list of available commands, type \c help in the
|
||||
* \ref command_shell or send the same command via a command handler.
|
||||
* Further documentation can be found at
|
||||
* https://github.com/FluidSynth/fluidsynth/wiki/UserManual#shell-commands
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API fluid_istream_t fluid_get_stdin(void);
|
||||
FLUIDSYNTH_API fluid_ostream_t fluid_get_stdout(void);
|
||||
FLUIDSYNTH_API char *fluid_get_userconf(char *buf, int len);
|
||||
FLUIDSYNTH_API char *fluid_get_sysconf(char *buf, int len);
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup command_handler Command Handler
|
||||
* @ingroup command_interface
|
||||
* @brief Handles text commands and reading of configuration files
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @startlifecycle{Command Handler} */
|
||||
FLUIDSYNTH_API
|
||||
fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_router_t *router);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_cmd_handler_t *new_fluid_cmd_handler2(fluid_settings_t *settings, fluid_synth_t *synth,
|
||||
fluid_midi_router_t *router, fluid_player_t *player);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void delete_fluid_cmd_handler(fluid_cmd_handler_t *handler);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_cmd_handler_set_synth(fluid_cmd_handler_t *handler, fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_command(fluid_cmd_handler_t *handler, const char *cmd, fluid_ostream_t out);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_source(fluid_cmd_handler_t *handler, const char *filename);
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup command_shell Command Shell
|
||||
* @ingroup command_interface
|
||||
*
|
||||
* Interactive shell to control and configure a synthesizer instance.
|
||||
*
|
||||
* If you need a platform independent way to get the standard input
|
||||
* and output streams, use fluid_get_stdin() and fluid_get_stdout().
|
||||
*
|
||||
* For a full list of available commands, type \c help in the shell.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @startlifecycle{Command Shell} */
|
||||
FLUIDSYNTH_API
|
||||
fluid_shell_t *new_fluid_shell(fluid_settings_t *settings, fluid_cmd_handler_t *handler,
|
||||
fluid_istream_t in, fluid_ostream_t out, int thread);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_usershell(fluid_settings_t *settings, fluid_cmd_handler_t *handler);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_shell(fluid_shell_t *shell);
|
||||
/** @endlifecycle */
|
||||
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup command_server Command Server
|
||||
* @ingroup command_interface
|
||||
*
|
||||
* TCP socket server for a command handler.
|
||||
*
|
||||
* The socket server will open the TCP port set by \ref settings_shell_port
|
||||
* (default 9800) and starts a new thread and \ref command_handler for each
|
||||
* incoming connection.
|
||||
*
|
||||
* @note The server is only available if libfluidsynth has been compiled
|
||||
* with network support (enable-network). Without network support, all related
|
||||
* functions will return FLUID_FAILED or NULL.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @startlifecycle{Command Server} */
|
||||
FLUIDSYNTH_API
|
||||
fluid_server_t *new_fluid_server(fluid_settings_t *settings,
|
||||
fluid_synth_t *synth, fluid_midi_router_t *router);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_server_t *new_fluid_server2(fluid_settings_t *settings,
|
||||
fluid_synth_t *synth, fluid_midi_router_t *router,
|
||||
fluid_player_t *player);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_server(fluid_server_t *server);
|
||||
|
||||
FLUIDSYNTH_API int fluid_server_join(fluid_server_t *server);
|
||||
/** @endlifecycle */
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SHELL_H */
|
552
thirdparty/fluidsynth/include/fluidsynth/synth.h
vendored
Normal file
552
thirdparty/fluidsynth/include/fluidsynth/synth.h
vendored
Normal file
|
@ -0,0 +1,552 @@
|
|||
/* 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 _FLUIDSYNTH_SYNTH_H
|
||||
#define _FLUIDSYNTH_SYNTH_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup synth Synthesizer
|
||||
*
|
||||
* SoundFont synthesizer
|
||||
*
|
||||
* You create a new synthesizer with new_fluid_synth() and you destroy
|
||||
* it with delete_fluid_synth(). Use the fluid_settings_t structure to specify
|
||||
* the synthesizer characteristics.
|
||||
*
|
||||
* You have to load a SoundFont in order to hear any sound. For that
|
||||
* you use the fluid_synth_sfload() function.
|
||||
*
|
||||
* You can use the audio driver functions to open
|
||||
* the audio device and create a background audio thread.
|
||||
*
|
||||
* The API for sending MIDI events is probably what you expect:
|
||||
* fluid_synth_noteon(), fluid_synth_noteoff(), ...
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @startlifecycle{Synthesizer} */
|
||||
FLUIDSYNTH_API fluid_synth_t *new_fluid_synth(fluid_settings_t *settings);
|
||||
FLUIDSYNTH_API void delete_fluid_synth(fluid_synth_t *synth);
|
||||
/** @endlifecycle */
|
||||
|
||||
FLUIDSYNTH_API double fluid_synth_get_cpu_load(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API const char *fluid_synth_error(fluid_synth_t *synth);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_messages MIDI Channel Messages
|
||||
* @ingroup synth
|
||||
*
|
||||
* The MIDI channel message functions are mostly directly named after their
|
||||
* counterpart MIDI messages. They are a high-level interface to controlling
|
||||
* the synthesizer, playing notes and changing note and channel parameters.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API int fluid_synth_noteon(fluid_synth_t *synth, int chan, int key, int vel);
|
||||
FLUIDSYNTH_API int fluid_synth_noteoff(fluid_synth_t *synth, int chan, int key);
|
||||
FLUIDSYNTH_API int fluid_synth_cc(fluid_synth_t *synth, int chan, int ctrl, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_get_cc(fluid_synth_t *synth, int chan, int ctrl, int *pval);
|
||||
FLUIDSYNTH_API int fluid_synth_sysex(fluid_synth_t *synth, const char *data, int len,
|
||||
char *response, int *response_len, int *handled, int dryrun);
|
||||
FLUIDSYNTH_API int fluid_synth_pitch_bend(fluid_synth_t *synth, int chan, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_get_pitch_bend(fluid_synth_t *synth, int chan, int *ppitch_bend);
|
||||
FLUIDSYNTH_API int fluid_synth_pitch_wheel_sens(fluid_synth_t *synth, int chan, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_get_pitch_wheel_sens(fluid_synth_t *synth, int chan, int *pval);
|
||||
FLUIDSYNTH_API int fluid_synth_program_change(fluid_synth_t *synth, int chan, int program);
|
||||
FLUIDSYNTH_API int fluid_synth_channel_pressure(fluid_synth_t *synth, int chan, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_key_pressure(fluid_synth_t *synth, int chan, int key, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_bank_select(fluid_synth_t *synth, int chan, int bank);
|
||||
FLUIDSYNTH_API int fluid_synth_sfont_select(fluid_synth_t *synth, int chan, int sfont_id);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_program_select(fluid_synth_t *synth, int chan, int sfont_id,
|
||||
int bank_num, int preset_num);
|
||||
FLUIDSYNTH_API int
|
||||
fluid_synth_program_select_by_sfont_name(fluid_synth_t *synth, int chan,
|
||||
const char *sfont_name, int bank_num,
|
||||
int preset_num);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_get_program(fluid_synth_t *synth, int chan, int *sfont_id,
|
||||
int *bank_num, int *preset_num);
|
||||
FLUIDSYNTH_API int fluid_synth_unset_program(fluid_synth_t *synth, int chan);
|
||||
FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_all_notes_off(fluid_synth_t *synth, int chan);
|
||||
FLUIDSYNTH_API int fluid_synth_all_sounds_off(fluid_synth_t *synth, int chan);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_gen(fluid_synth_t *synth, int chan,
|
||||
int param, float value);
|
||||
FLUIDSYNTH_API float fluid_synth_get_gen(fluid_synth_t *synth, int chan, int param);
|
||||
/* @} MIDI Channel Messages */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup voice_control Synthesis Voice Control
|
||||
* @ingroup synth
|
||||
*
|
||||
* Low-level access to synthesis voices.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API int fluid_synth_start(fluid_synth_t *synth, unsigned int id,
|
||||
fluid_preset_t *preset, int audio_chan,
|
||||
int midi_chan, int key, int vel);
|
||||
FLUIDSYNTH_API int fluid_synth_stop(fluid_synth_t *synth, unsigned int id);
|
||||
|
||||
FLUIDSYNTH_API fluid_voice_t *fluid_synth_alloc_voice(fluid_synth_t *synth,
|
||||
fluid_sample_t *sample,
|
||||
int channum, int key, int vel);
|
||||
FLUIDSYNTH_API void fluid_synth_start_voice(fluid_synth_t *synth, fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API void fluid_synth_get_voicelist(fluid_synth_t *synth,
|
||||
fluid_voice_t *buf[], int bufsize, int ID);
|
||||
/* @} Voice Control */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup soundfont_management SoundFont Management
|
||||
* @ingroup synth
|
||||
*
|
||||
* Functions to load and unload SoundFonts.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_sfload(fluid_synth_t *synth, const char *filename, int reset_presets);
|
||||
FLUIDSYNTH_API int fluid_synth_sfreload(fluid_synth_t *synth, int id);
|
||||
FLUIDSYNTH_API int fluid_synth_sfunload(fluid_synth_t *synth, int id, int reset_presets);
|
||||
FLUIDSYNTH_API int fluid_synth_add_sfont(fluid_synth_t *synth, fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API int fluid_synth_remove_sfont(fluid_synth_t *synth, fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API int fluid_synth_sfcount(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_synth_get_sfont(fluid_synth_t *synth, unsigned int num);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_synth_get_sfont_by_id(fluid_synth_t *synth, int id);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_synth_get_sfont_by_name(fluid_synth_t *synth,
|
||||
const char *name);
|
||||
FLUIDSYNTH_API int fluid_synth_set_bank_offset(fluid_synth_t *synth, int sfont_id, int offset);
|
||||
FLUIDSYNTH_API int fluid_synth_get_bank_offset(fluid_synth_t *synth, int sfont_id);
|
||||
/* @} Soundfont Management */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup reverb_effect Effect - Reverb
|
||||
* @ingroup synth
|
||||
*
|
||||
* Functions for configuring the built-in reverb effect
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API void fluid_synth_set_reverb_on(fluid_synth_t *synth, int on);
|
||||
FLUIDSYNTH_API int fluid_synth_reverb_on(fluid_synth_t *synth, int fx_group, int on);
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_reverb(fluid_synth_t *synth, double roomsize,
|
||||
double damping, double width, double level);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_reverb_roomsize(fluid_synth_t *synth, double roomsize);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_reverb_damp(fluid_synth_t *synth, double damping);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_reverb_width(fluid_synth_t *synth, double width);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_reverb_level(fluid_synth_t *synth, double level);
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API double fluid_synth_get_reverb_roomsize(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API double fluid_synth_get_reverb_damp(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API double fluid_synth_get_reverb_level(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API double fluid_synth_get_reverb_width(fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_group_roomsize(fluid_synth_t *synth, int fx_group, double roomsize);
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_group_damp(fluid_synth_t *synth, int fx_group, double damping);
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_group_width(fluid_synth_t *synth, int fx_group, double width);
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_group_level(fluid_synth_t *synth, int fx_group, double level);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_get_reverb_group_roomsize(fluid_synth_t *synth, int fx_group, double *roomsize);
|
||||
FLUIDSYNTH_API int fluid_synth_get_reverb_group_damp(fluid_synth_t *synth, int fx_group, double *damping);
|
||||
FLUIDSYNTH_API int fluid_synth_get_reverb_group_width(fluid_synth_t *synth, int fx_group, double *width);
|
||||
FLUIDSYNTH_API int fluid_synth_get_reverb_group_level(fluid_synth_t *synth, int fx_group, double *level);
|
||||
/* @} Reverb */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup chorus_effect Effect - Chorus
|
||||
* @ingroup synth
|
||||
*
|
||||
* Functions for configuring the built-in chorus effect
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Chorus modulation waveform type.
|
||||
*/
|
||||
enum fluid_chorus_mod
|
||||
{
|
||||
FLUID_CHORUS_MOD_SINE = 0, /**< Sine wave chorus modulation */
|
||||
FLUID_CHORUS_MOD_TRIANGLE = 1 /**< Triangle wave chorus modulation */
|
||||
};
|
||||
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API void fluid_synth_set_chorus_on(fluid_synth_t *synth, int on);
|
||||
FLUIDSYNTH_API int fluid_synth_chorus_on(fluid_synth_t *synth, int fx_group, int on);
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_chorus(fluid_synth_t *synth, int nr, double level,
|
||||
double speed, double depth_ms, int type);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_chorus_nr(fluid_synth_t *synth, int nr);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_chorus_level(fluid_synth_t *synth, double level);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_chorus_speed(fluid_synth_t *synth, double speed);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_chorus_depth(fluid_synth_t *synth, double depth_ms);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_set_chorus_type(fluid_synth_t *synth, int type);
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_get_chorus_nr(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API double fluid_synth_get_chorus_level(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API double fluid_synth_get_chorus_speed(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API double fluid_synth_get_chorus_depth(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_get_chorus_type(fluid_synth_t *synth); /* see fluid_chorus_mod */
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_group_nr(fluid_synth_t *synth, int fx_group, int nr);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_group_level(fluid_synth_t *synth, int fx_group, double level);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_group_speed(fluid_synth_t *synth, int fx_group, double speed);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_group_depth(fluid_synth_t *synth, int fx_group, double depth_ms);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_group_type(fluid_synth_t *synth, int fx_group, int type);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_get_chorus_group_nr(fluid_synth_t *synth, int fx_group, int *nr);
|
||||
FLUIDSYNTH_API int fluid_synth_get_chorus_group_level(fluid_synth_t *synth, int fx_group, double *level);
|
||||
FLUIDSYNTH_API int fluid_synth_get_chorus_group_speed(fluid_synth_t *synth, int fx_group, double *speed);
|
||||
FLUIDSYNTH_API int fluid_synth_get_chorus_group_depth(fluid_synth_t *synth, int fx_group, double *depth_ms);
|
||||
FLUIDSYNTH_API int fluid_synth_get_chorus_group_type(fluid_synth_t *synth, int fx_group, int *type);
|
||||
/* @} Chorus */
|
||||
|
||||
/**
|
||||
* @defgroup synthesis_params Synthesis Parameters
|
||||
* @ingroup synth
|
||||
*
|
||||
* Functions to control and query synthesis parameters like gain and
|
||||
* polyphony count.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API int fluid_synth_count_midi_channels(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_audio_channels(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_audio_groups(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_effects_channels(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_effects_groups(fluid_synth_t *synth);
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API void fluid_synth_set_sample_rate(fluid_synth_t *synth, float sample_rate);
|
||||
FLUIDSYNTH_API void fluid_synth_set_gain(fluid_synth_t *synth, float gain);
|
||||
FLUIDSYNTH_API float fluid_synth_get_gain(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_set_polyphony(fluid_synth_t *synth, int polyphony);
|
||||
FLUIDSYNTH_API int fluid_synth_get_polyphony(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_get_active_voice_count(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_get_internal_bufsize(fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_set_interp_method(fluid_synth_t *synth, int chan, int interp_method);
|
||||
|
||||
/**
|
||||
* Synthesis interpolation method.
|
||||
*/
|
||||
enum fluid_interp
|
||||
{
|
||||
FLUID_INTERP_NONE = 0, /**< No interpolation: Fastest, but questionable audio quality */
|
||||
FLUID_INTERP_LINEAR = 1, /**< Straight-line interpolation: A bit slower, reasonable audio quality */
|
||||
FLUID_INTERP_4THORDER = 4, /**< Fourth-order interpolation, good quality, the default */
|
||||
FLUID_INTERP_7THORDER = 7, /**< Seventh-order interpolation */
|
||||
|
||||
FLUID_INTERP_DEFAULT = FLUID_INTERP_4THORDER, /**< Default interpolation method */
|
||||
FLUID_INTERP_HIGHEST = FLUID_INTERP_7THORDER, /**< Highest interpolation method */
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum used with fluid_synth_add_default_mod() to specify how to handle duplicate modulators.
|
||||
*/
|
||||
enum fluid_synth_add_mod
|
||||
{
|
||||
FLUID_SYNTH_OVERWRITE, /**< Overwrite any existing matching modulator */
|
||||
FLUID_SYNTH_ADD, /**< Sum up modulator amounts */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_add_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod, int mode);
|
||||
FLUIDSYNTH_API int fluid_synth_remove_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod);
|
||||
/* @} Synthesis Parameters */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup tuning MIDI Tuning
|
||||
* @ingroup synth
|
||||
*
|
||||
* The functions in this section implement the MIDI Tuning Standard interface.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_key_tuning(fluid_synth_t *synth, int bank, int prog,
|
||||
const char *name, const double *pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_octave_tuning(fluid_synth_t *synth, int bank, int prog,
|
||||
const char *name, const double *pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_tune_notes(fluid_synth_t *synth, int bank, int prog,
|
||||
int len, const int *keys, const double *pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_tuning(fluid_synth_t *synth, int chan, int bank, int prog,
|
||||
int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_deactivate_tuning(fluid_synth_t *synth, int chan, int apply);
|
||||
FLUIDSYNTH_API void fluid_synth_tuning_iteration_start(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_tuning_iteration_next(fluid_synth_t *synth, int *bank, int *prog);
|
||||
FLUIDSYNTH_API int fluid_synth_tuning_dump(fluid_synth_t *synth, int bank, int prog,
|
||||
char *name, int len, double *pitch);
|
||||
/* @} MIDI Tuning */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup audio_rendering Audio Rendering
|
||||
* @ingroup synth
|
||||
*
|
||||
* The functions in this section can be used to render audio directly to
|
||||
* memory buffers. They are used internally by the \ref audio_driver and \ref file_renderer,
|
||||
* but can also be used manually for custom processing of the rendered audio.
|
||||
*
|
||||
* @note Please note that all following functions block during rendering. If your goal is to
|
||||
* 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,
|
||||
void *lout, int loff, int lincr,
|
||||
void *rout, int roff, int rincr);
|
||||
FLUIDSYNTH_API int fluid_synth_write_float(fluid_synth_t *synth, int len,
|
||||
void *lout, int loff, int lincr,
|
||||
void *rout, int roff, int rincr);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_nwrite_float(fluid_synth_t *synth, int len,
|
||||
float **left, float **right,
|
||||
float **fx_left, float **fx_right);
|
||||
FLUIDSYNTH_API int fluid_synth_process(fluid_synth_t *synth, int len,
|
||||
int nfx, float *fx[],
|
||||
int nout, float *out[]);
|
||||
/* @} Audio Rendering */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup iir_filter Effect - IIR Filter
|
||||
* @ingroup synth
|
||||
*
|
||||
* Functions for configuring the built-in IIR filter effect
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Specifies the type of filter to use for the custom IIR filter
|
||||
*/
|
||||
enum fluid_iir_filter_type
|
||||
{
|
||||
FLUID_IIR_DISABLED = 0, /**< Custom IIR filter is not operating */
|
||||
FLUID_IIR_LOWPASS, /**< Custom IIR filter is operating as low-pass filter */
|
||||
FLUID_IIR_HIGHPASS, /**< Custom IIR filter is operating as high-pass filter */
|
||||
FLUID_IIR_LAST /**< @internal Value defines the count of filter types (#fluid_iir_filter_type) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies optional settings to use for the custom IIR filter. Can be bitwise ORed.
|
||||
*/
|
||||
enum fluid_iir_filter_flags
|
||||
{
|
||||
FLUID_IIR_Q_LINEAR = 1 << 0, /**< The Soundfont spec requires the filter Q to be interpreted in dB. If this flag is set the filter Q is instead assumed to be in a linear range */
|
||||
FLUID_IIR_Q_ZERO_OFF = 1 << 1, /**< If this flag the filter is switched off if Q == 0 (prior to any transformation) */
|
||||
FLUID_IIR_NO_GAIN_AMP = 1 << 2 /**< The Soundfont spec requires to correct the gain of the filter depending on the filter's Q. If this flag is set the filter gain will not be corrected. */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_custom_filter(fluid_synth_t *, int type, int flags);
|
||||
/* @} IIR Filter */
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup channel_setup MIDI Channel Setup
|
||||
* @ingroup synth
|
||||
*
|
||||
* The functions in this section provide interfaces to change the channel type
|
||||
* and to configure basic channels, legato and portamento setups.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @name Channel Type
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The midi channel type used by fluid_synth_set_channel_type()
|
||||
*/
|
||||
enum fluid_midi_channel_type
|
||||
{
|
||||
CHANNEL_TYPE_MELODIC = 0, /**< Melodic midi channel */
|
||||
CHANNEL_TYPE_DRUM = 1 /**< Drum midi channel */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_channel_type(fluid_synth_t *synth, int chan, int type);
|
||||
/** @} Channel Type */
|
||||
|
||||
|
||||
/** @name Basic Channel Mode
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Channel mode bits OR-ed together so that it matches with the midi spec: poly omnion (0), mono omnion (1), poly omnioff (2), mono omnioff (3)
|
||||
*/
|
||||
enum fluid_channel_mode_flags
|
||||
{
|
||||
FLUID_CHANNEL_POLY_OFF = 0x01, /**< if flag is set, the basic channel is in mono on state, if not set poly is on */
|
||||
FLUID_CHANNEL_OMNI_OFF = 0x02, /**< if flag is set, the basic channel is in omni off state, if not set omni is on */
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates the mode a basic channel is set to
|
||||
*/
|
||||
enum fluid_basic_channel_modes
|
||||
{
|
||||
FLUID_CHANNEL_MODE_MASK = (FLUID_CHANNEL_OMNI_OFF | FLUID_CHANNEL_POLY_OFF), /**< Mask Poly and Omni bits of #fluid_channel_mode_flags, usually only used internally */
|
||||
FLUID_CHANNEL_MODE_OMNION_POLY = FLUID_CHANNEL_MODE_MASK & (~FLUID_CHANNEL_OMNI_OFF & ~FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 0 */
|
||||
FLUID_CHANNEL_MODE_OMNION_MONO = FLUID_CHANNEL_MODE_MASK & (~FLUID_CHANNEL_OMNI_OFF & FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 1 */
|
||||
FLUID_CHANNEL_MODE_OMNIOFF_POLY = FLUID_CHANNEL_MODE_MASK & (FLUID_CHANNEL_OMNI_OFF & ~FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 2 */
|
||||
FLUID_CHANNEL_MODE_OMNIOFF_MONO = FLUID_CHANNEL_MODE_MASK & (FLUID_CHANNEL_OMNI_OFF | FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 3 */
|
||||
FLUID_CHANNEL_MODE_LAST /**< @internal Value defines the count of basic channel modes (#fluid_basic_channel_modes) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_reset_basic_channel(fluid_synth_t *synth, int chan);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_get_basic_channel(fluid_synth_t *synth, int chan,
|
||||
int *basic_chan_out,
|
||||
int *mode_chan_out,
|
||||
int *basic_val_out);
|
||||
FLUIDSYNTH_API int fluid_synth_set_basic_channel(fluid_synth_t *synth, int chan, int mode, int val);
|
||||
|
||||
/** @} Basic Channel Mode */
|
||||
|
||||
/** @name Legato Mode
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates the legato mode a channel is set to
|
||||
* n1,n2,n3,.. is a legato passage. n1 is the first note, and n2,n3,n4 are played legato with previous note. */
|
||||
enum fluid_channel_legato_mode
|
||||
{
|
||||
FLUID_CHANNEL_LEGATO_MODE_RETRIGGER, /**< Mode 0 - Release previous note, start a new note */
|
||||
FLUID_CHANNEL_LEGATO_MODE_MULTI_RETRIGGER, /**< Mode 1 - On contiguous notes retrigger in attack section using current value, shape attack using current dynamic and make use of previous voices if any */
|
||||
FLUID_CHANNEL_LEGATO_MODE_LAST /**< @internal Value defines the count of legato modes (#fluid_channel_legato_mode) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_legato_mode(fluid_synth_t *synth, int chan, int legatomode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_legato_mode(fluid_synth_t *synth, int chan, int *legatomode);
|
||||
/** @} Legato Mode */
|
||||
|
||||
/** @name Portamento Mode
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates the portamento mode a channel is set to
|
||||
*/
|
||||
enum fluid_channel_portamento_mode
|
||||
{
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_EACH_NOTE, /**< Mode 0 - Portamento on each note (staccato or legato) */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_LEGATO_ONLY, /**< Mode 1 - Portamento only on legato note */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_STACCATO_ONLY, /**< Mode 2 - Portamento only on staccato note */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_LAST /**< @internal Value defines the count of portamento modes
|
||||
@warning This symbol is not part of the public API and ABI
|
||||
stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_portamento_mode(fluid_synth_t *synth,
|
||||
int chan, int portamentomode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_portamento_mode(fluid_synth_t *synth,
|
||||
int chan, int *portamentomode);
|
||||
/** @} Portamento Mode */
|
||||
|
||||
/**@name Breath Mode
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates the breath mode a channel is set to
|
||||
*/
|
||||
enum fluid_channel_breath_flags
|
||||
{
|
||||
FLUID_CHANNEL_BREATH_POLY = 0x10, /**< when channel is poly, this flag indicates that the default velocity to initial attenuation modulator is replaced by a breath to initial attenuation modulator */
|
||||
FLUID_CHANNEL_BREATH_MONO = 0x20, /**< when channel is mono, this flag indicates that the default velocity to initial attenuation modulator is replaced by a breath modulator */
|
||||
FLUID_CHANNEL_BREATH_SYNC = 0x40, /**< when channel is mono, this flag indicates that the breath controller(MSB)triggers noteon/noteoff on the running note */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_breath_mode(fluid_synth_t *synth,
|
||||
int chan, int breathmode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_breath_mode(fluid_synth_t *synth,
|
||||
int chan, int *breathmode);
|
||||
/** @} Breath Mode */
|
||||
/* @} MIDI Channel Setup */
|
||||
|
||||
|
||||
/** @ingroup settings */
|
||||
FLUIDSYNTH_API fluid_settings_t *fluid_synth_get_settings(fluid_synth_t *synth);
|
||||
|
||||
/** @ingroup soundfont_loader */
|
||||
FLUIDSYNTH_API void fluid_synth_add_sfloader(fluid_synth_t *synth, fluid_sfloader_t *loader);
|
||||
|
||||
/** @ingroup soundfont_loader */
|
||||
FLUIDSYNTH_API fluid_preset_t *fluid_synth_get_channel_preset(fluid_synth_t *synth, int chan);
|
||||
|
||||
/** @ingroup midi_input */
|
||||
FLUIDSYNTH_API int fluid_synth_handle_midi_event(void *data, fluid_midi_event_t *event);
|
||||
|
||||
/** @ingroup soundfonts */
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_pin_preset(fluid_synth_t *synth, int sfont_id, int bank_num, int preset_num);
|
||||
|
||||
/** @ingroup soundfonts */
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_unpin_preset(fluid_synth_t *synth, int sfont_id, int bank_num, int preset_num);
|
||||
|
||||
/** @ingroup ladspa */
|
||||
FLUIDSYNTH_API fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SYNTH_H */
|
85
thirdparty/fluidsynth/include/fluidsynth/types.h
vendored
Normal file
85
thirdparty/fluidsynth/include/fluidsynth/types.h
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* 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 _FLUIDSYNTH_TYPES_H
|
||||
#define _FLUIDSYNTH_TYPES_H
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup Types Types
|
||||
* @brief Type declarations
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct _fluid_hashtable_t fluid_settings_t; /**< Configuration settings instance */
|
||||
typedef struct _fluid_synth_t fluid_synth_t; /**< Synthesizer instance */
|
||||
typedef struct _fluid_voice_t fluid_voice_t; /**< Synthesis voice instance */
|
||||
typedef struct _fluid_sfloader_t fluid_sfloader_t; /**< SoundFont loader plugin */
|
||||
typedef struct _fluid_sfont_t fluid_sfont_t; /**< SoundFont */
|
||||
typedef struct _fluid_preset_t fluid_preset_t; /**< SoundFont preset */
|
||||
typedef struct _fluid_sample_t fluid_sample_t; /**< SoundFont sample */
|
||||
typedef struct _fluid_mod_t fluid_mod_t; /**< SoundFont modulator */
|
||||
typedef struct _fluid_audio_driver_t fluid_audio_driver_t; /**< Audio driver instance */
|
||||
typedef struct _fluid_file_renderer_t fluid_file_renderer_t; /**< Audio file renderer instance */
|
||||
typedef struct _fluid_player_t fluid_player_t; /**< MIDI player instance */
|
||||
typedef struct _fluid_midi_event_t fluid_midi_event_t; /**< MIDI event */
|
||||
typedef struct _fluid_midi_driver_t fluid_midi_driver_t; /**< MIDI driver instance */
|
||||
typedef struct _fluid_midi_router_t fluid_midi_router_t; /**< MIDI router instance */
|
||||
typedef struct _fluid_midi_router_rule_t fluid_midi_router_rule_t; /**< MIDI router rule */
|
||||
typedef struct _fluid_hashtable_t fluid_cmd_hash_t; /**< Command handler hash table */
|
||||
typedef struct _fluid_shell_t fluid_shell_t; /**< Command shell */
|
||||
typedef struct _fluid_server_t fluid_server_t; /**< TCP/IP shell server instance */
|
||||
typedef struct _fluid_event_t fluid_event_t; /**< Sequencer event */
|
||||
typedef struct _fluid_sequencer_t fluid_sequencer_t; /**< Sequencer instance */
|
||||
typedef struct _fluid_ramsfont_t fluid_ramsfont_t; /**< RAM SoundFont */
|
||||
typedef struct _fluid_rampreset_t fluid_rampreset_t; /**< RAM SoundFont preset */
|
||||
typedef struct _fluid_cmd_handler_t fluid_cmd_handler_t; /**< Shell Command Handler */
|
||||
typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t; /**< LADSPA effects instance */
|
||||
typedef struct _fluid_file_callbacks_t fluid_file_callbacks_t; /**< Callback struct to perform custom file loading of soundfonts */
|
||||
|
||||
typedef int fluid_istream_t; /**< Input stream descriptor */
|
||||
typedef int fluid_ostream_t; /**< Output stream descriptor */
|
||||
|
||||
typedef short fluid_seq_id_t; /**< Unique client IDs used by the sequencer and #fluid_event_t, obtained by fluid_sequencer_register_client() and fluid_sequencer_register_fluidsynth() */
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||
typedef __int64 fluid_long_long_t; // even on 32bit windows
|
||||
#else
|
||||
/**
|
||||
* A typedef for C99's type long long, which is at least 64-bit wide, as guaranteed by the C99.
|
||||
* @p __int64 will be used as replacement for VisualStudio 2010 and older.
|
||||
*/
|
||||
typedef long long fluid_long_long_t;
|
||||
#endif
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_TYPES_H */
|
47
thirdparty/fluidsynth/include/fluidsynth/version.h
vendored
Normal file
47
thirdparty/fluidsynth/include/fluidsynth/version.h
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* 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 _FLUIDSYNTH_VERSION_H
|
||||
#define _FLUIDSYNTH_VERSION_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define FLUIDSYNTH_VERSION "2.2.8" /**< String constant of libfluidsynth version. */
|
||||
#define FLUIDSYNTH_VERSION_MAJOR 2 /**< libfluidsynth major version integer constant. */
|
||||
#define FLUIDSYNTH_VERSION_MINOR 2 /**< libfluidsynth minor version integer constant. */
|
||||
#define FLUIDSYNTH_VERSION_MICRO 8 /**< libfluidsynth micro version integer constant. */
|
||||
|
||||
FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro);
|
||||
FLUIDSYNTH_API char* fluid_version_str(void);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_VERSION_H */
|
77
thirdparty/fluidsynth/include/fluidsynth/voice.h
vendored
Normal file
77
thirdparty/fluidsynth/include/fluidsynth/voice.h
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* 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 _FLUIDSYNTH_VOICE_H
|
||||
#define _FLUIDSYNTH_VOICE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup voices Voice Manipulation
|
||||
* @ingroup soundfonts
|
||||
*
|
||||
* Synthesis voice manipulation functions.
|
||||
*
|
||||
* The interface to the synthesizer's voices.
|
||||
* Examples on using them can be found in the source code of the default SoundFont
|
||||
* loader (fluid_defsfont.c).
|
||||
*
|
||||
* Most of these functions should only be called from within synthesis context,
|
||||
* such as the SoundFont loader's noteon method.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enum used with fluid_voice_add_mod() to specify how to handle duplicate modulators.
|
||||
*/
|
||||
enum fluid_voice_add_mod
|
||||
{
|
||||
FLUID_VOICE_OVERWRITE, /**< Overwrite any existing matching modulator */
|
||||
FLUID_VOICE_ADD, /**< Add (sum) modulator amounts */
|
||||
FLUID_VOICE_DEFAULT /**< For default modulators only, no need to check for duplicates */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API void fluid_voice_add_mod(fluid_voice_t *voice, fluid_mod_t *mod, int mode);
|
||||
FLUIDSYNTH_API float fluid_voice_gen_get(fluid_voice_t *voice, int gen);
|
||||
FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t *voice, int gen, float val);
|
||||
FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t *voice, int gen, float val);
|
||||
|
||||
FLUIDSYNTH_API unsigned int fluid_voice_get_id(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_channel(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_key(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_key(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_velocity(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_velocity(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_playing(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_on(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_sustained(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_sostenuto(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t *s);
|
||||
FLUIDSYNTH_API void fluid_voice_update_param(fluid_voice_t *voice, int gen);
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_VOICE_H */
|
||||
|
162
thirdparty/fluidsynth/src/CMakeLists.txt
vendored
Normal file
162
thirdparty/fluidsynth/src/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
# FluidSynth - A Software Synthesizer
|
||||
#
|
||||
# Copyright (C) 2003-2010 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
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
# 02111-1307, USA
|
||||
|
||||
# CMake based build system. Pedro Lopez-Cabanillas <plcl@users.sf.net>
|
||||
|
||||
# ************ library ************
|
||||
|
||||
if ( LIBINSTPATCH_SUPPORT )
|
||||
set ( fluid_libinstpatch_SOURCES sfloader/fluid_instpatch.c sfloader/fluid_instpatch.h )
|
||||
endif ( LIBINSTPATCH_SUPPORT )
|
||||
|
||||
|
||||
set ( fluidsynth_SOURCES
|
||||
config.h
|
||||
utils/fluid_conv.c
|
||||
utils/fluid_conv.h
|
||||
utils/fluid_hash.c
|
||||
utils/fluid_hash.h
|
||||
utils/fluid_list.c
|
||||
utils/fluid_list.h
|
||||
utils/fluid_ringbuffer.c
|
||||
utils/fluid_ringbuffer.h
|
||||
utils/fluid_settings.c
|
||||
utils/fluid_settings.h
|
||||
utils/fluidsynth_priv.h
|
||||
utils/fluid_sys.c
|
||||
utils/fluid_sys.h
|
||||
sfloader/fluid_defsfont.c
|
||||
sfloader/fluid_defsfont.h
|
||||
sfloader/fluid_sfont.h
|
||||
sfloader/fluid_sfont.c
|
||||
sfloader/fluid_sffile.c
|
||||
sfloader/fluid_sffile.h
|
||||
sfloader/fluid_samplecache.c
|
||||
sfloader/fluid_samplecache.h
|
||||
rvoice/fluid_adsr_env.c
|
||||
rvoice/fluid_adsr_env.h
|
||||
rvoice/fluid_chorus.c
|
||||
rvoice/fluid_chorus.h
|
||||
rvoice/fluid_iir_filter.c
|
||||
rvoice/fluid_iir_filter.h
|
||||
rvoice/fluid_lfo.c
|
||||
rvoice/fluid_lfo.h
|
||||
rvoice/fluid_rvoice.h
|
||||
rvoice/fluid_rvoice.c
|
||||
rvoice/fluid_rvoice_dsp.c
|
||||
rvoice/fluid_rvoice_event.h
|
||||
rvoice/fluid_rvoice_event.c
|
||||
rvoice/fluid_rvoice_mixer.h
|
||||
rvoice/fluid_rvoice_mixer.c
|
||||
rvoice/fluid_phase.h
|
||||
rvoice/fluid_rev.c
|
||||
rvoice/fluid_rev.h
|
||||
synth/fluid_chan.c
|
||||
synth/fluid_chan.h
|
||||
synth/fluid_event.c
|
||||
synth/fluid_event.h
|
||||
synth/fluid_gen.c
|
||||
synth/fluid_gen.h
|
||||
synth/fluid_mod.c
|
||||
synth/fluid_mod.h
|
||||
synth/fluid_synth.c
|
||||
synth/fluid_synth.h
|
||||
synth/fluid_synth_monopoly.c
|
||||
synth/fluid_tuning.c
|
||||
synth/fluid_tuning.h
|
||||
synth/fluid_voice.c
|
||||
synth/fluid_voice.h
|
||||
midi/fluid_midi.c
|
||||
midi/fluid_midi.h
|
||||
midi/fluid_midi_router.c
|
||||
midi/fluid_midi_router.h
|
||||
midi/fluid_seqbind.c
|
||||
midi/fluid_seqbind_notes.cpp
|
||||
midi/fluid_seq.c
|
||||
midi/fluid_seq_queue.cpp
|
||||
drivers/fluid_adriver.c
|
||||
drivers/fluid_adriver.h
|
||||
drivers/fluid_mdriver.c
|
||||
drivers/fluid_mdriver.h
|
||||
bindings/fluid_filerenderer.c
|
||||
bindings/fluid_ladspa.c
|
||||
bindings/fluid_ladspa.h
|
||||
)
|
||||
|
||||
if ( WIN32 )
|
||||
set( fluidsynth_SOURCES
|
||||
${fluidsynth_SOURCES}
|
||||
utils/win32_glibstubs.c
|
||||
utils/win32_glibstubs.h
|
||||
)
|
||||
endif ( WIN32 )
|
||||
|
||||
set ( public_HEADERS
|
||||
../include/fluidsynth/audio.h
|
||||
../include/fluidsynth/event.h
|
||||
../include/fluidsynth/gen.h
|
||||
../include/fluidsynth/ladspa.h
|
||||
../include/fluidsynth/log.h
|
||||
../include/fluidsynth/midi.h
|
||||
../include/fluidsynth/misc.h
|
||||
../include/fluidsynth/mod.h
|
||||
../include/fluidsynth/seq.h
|
||||
../include/fluidsynth/seqbind.h
|
||||
../include/fluidsynth/settings.h
|
||||
../include/fluidsynth/sfont.h
|
||||
../include/fluidsynth/shell.h
|
||||
../include/fluidsynth/synth.h
|
||||
../include/fluidsynth/types.h
|
||||
../include/fluidsynth/voice.h
|
||||
../include/fluidsynth/version.h
|
||||
)
|
||||
|
||||
set ( public_main_HEADER
|
||||
../include/fluidsynth.h
|
||||
)
|
||||
|
||||
add_library ( fluidsynth OBJECT
|
||||
${config_SOURCES}
|
||||
${fluidsynth_SOURCES}
|
||||
${public_HEADERS}
|
||||
${public_main_HEADER}
|
||||
)
|
||||
|
||||
target_include_directories ( fluidsynth PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/synth
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rvoice
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/midi
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utils
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sfloader
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bindings
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../..
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../source/decoder
|
||||
)
|
||||
|
||||
|
||||
if (NOT WIN32)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(GLIB REQUIRED glib-2.0)
|
||||
target_include_directories ( fluidsynth PUBLIC ${GLIB_INCLUDE_DIRS} )
|
||||
target_link_libraries ( fluidsynth PUBLIC ${pkgcfg_lib_GLIB_glib-2.0} )
|
||||
|
||||
endif()
|
590
thirdparty/fluidsynth/src/bindings/fluid_filerenderer.c
vendored
Normal file
590
thirdparty/fluidsynth/src/bindings/fluid_filerenderer.c
vendored
Normal file
|
@ -0,0 +1,590 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Low-level routines for file output.
|
||||
*/
|
||||
|
||||
#include "fluid_sys.h"
|
||||
#include "fluid_synth.h"
|
||||
#include "fluid_settings.h"
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
#include <sndfile.h>
|
||||
#endif
|
||||
|
||||
struct _fluid_file_renderer_t
|
||||
{
|
||||
fluid_synth_t *synth;
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
SNDFILE *sndfile;
|
||||
float *buf;
|
||||
#else
|
||||
FILE *file;
|
||||
short *buf;
|
||||
#endif
|
||||
|
||||
int period_size;
|
||||
int buf_size;
|
||||
};
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
|
||||
/* Default file type used, if none specified and auto extension search fails */
|
||||
#define FLUID_FILE_RENDERER_DEFAULT_FILE_TYPE SF_FORMAT_WAV
|
||||
|
||||
/* File audio format names.
|
||||
* !! Keep in sync with format_ids[] */
|
||||
static const char *const format_names[] =
|
||||
{
|
||||
"s8",
|
||||
"s16",
|
||||
"s24",
|
||||
"s32",
|
||||
"u8",
|
||||
"float",
|
||||
"double"
|
||||
};
|
||||
|
||||
|
||||
/* File audio format IDs.
|
||||
* !! Keep in sync with format_names[] */
|
||||
static const int format_ids[] =
|
||||
{
|
||||
SF_FORMAT_PCM_S8,
|
||||
SF_FORMAT_PCM_16,
|
||||
SF_FORMAT_PCM_24,
|
||||
SF_FORMAT_PCM_32,
|
||||
SF_FORMAT_PCM_U8,
|
||||
SF_FORMAT_FLOAT,
|
||||
SF_FORMAT_DOUBLE
|
||||
};
|
||||
|
||||
/* File endian byte order names.
|
||||
* !! Keep in sync with endian_ids[] */
|
||||
static const char *const endian_names[] =
|
||||
{
|
||||
"auto",
|
||||
"little",
|
||||
"big",
|
||||
"cpu"
|
||||
};
|
||||
|
||||
/* File endian byte order ids.
|
||||
* !! Keep in sync with endian_names[] */
|
||||
static const int endian_ids[] =
|
||||
{
|
||||
SF_ENDIAN_FILE,
|
||||
SF_ENDIAN_LITTLE,
|
||||
SF_ENDIAN_BIG,
|
||||
SF_ENDIAN_CPU
|
||||
};
|
||||
|
||||
static int fluid_file_renderer_parse_options(char *filetype, char *format,
|
||||
char *endian, char *filename, SF_INFO *info);
|
||||
static int fluid_file_renderer_find_file_type(char *extension, int *type);
|
||||
static int fluid_file_renderer_find_valid_format(SF_INFO *info);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
fluid_file_renderer_settings(fluid_settings_t *settings)
|
||||
{
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
SF_FORMAT_INFO finfo, cmpinfo;
|
||||
int major_count;
|
||||
int i, i2;
|
||||
unsigned int n;
|
||||
|
||||
fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.wav", 0);
|
||||
fluid_settings_register_str(settings, "audio.file.type", "auto", 0);
|
||||
fluid_settings_register_str(settings, "audio.file.format", "s16", 0);
|
||||
fluid_settings_register_str(settings, "audio.file.endian", "auto", 0);
|
||||
|
||||
fluid_settings_add_option(settings, "audio.file.type", "auto");
|
||||
|
||||
sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof(int));
|
||||
|
||||
for(i = 0; i < major_count; i++)
|
||||
{
|
||||
finfo.format = i;
|
||||
sf_command(NULL, SFC_GET_FORMAT_MAJOR, &finfo, sizeof(finfo));
|
||||
|
||||
/* Check for duplicates */
|
||||
for(i2 = 0; i2 < i; i2++)
|
||||
{
|
||||
cmpinfo.format = i2;
|
||||
sf_command(NULL, SFC_GET_FORMAT_MAJOR, &cmpinfo, sizeof(cmpinfo));
|
||||
|
||||
if(FLUID_STRCMP(cmpinfo.extension, finfo.extension) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i2 == i)
|
||||
{
|
||||
fluid_settings_add_option(settings, "audio.file.type", finfo.extension);
|
||||
}
|
||||
}
|
||||
|
||||
for(n = 0; n < FLUID_N_ELEMENTS(format_names); n++)
|
||||
{
|
||||
fluid_settings_add_option(settings, "audio.file.format", format_names[n]);
|
||||
}
|
||||
|
||||
for(n = 0; n < FLUID_N_ELEMENTS(endian_names); n++)
|
||||
{
|
||||
fluid_settings_add_option(settings, "audio.file.endian", endian_names[n]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.raw", 0);
|
||||
fluid_settings_register_str(settings, "audio.file.type", "raw", 0);
|
||||
fluid_settings_add_option(settings, "audio.file.type", "raw");
|
||||
fluid_settings_register_str(settings, "audio.file.format", "s16", 0);
|
||||
fluid_settings_add_option(settings, "audio.file.format", "s16");
|
||||
fluid_settings_register_str(settings, "audio.file.endian", "cpu", 0);
|
||||
fluid_settings_add_option(settings, "audio.file.endian", "cpu");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new file renderer and open the file.
|
||||
*
|
||||
* @param synth The synth that creates audio data.
|
||||
* @return the new object, or NULL on failure
|
||||
*
|
||||
* @note Available file types and formats depends on if libfluidsynth was
|
||||
* built with libsndfile support or not. If not then only RAW 16 bit output is
|
||||
* supported.
|
||||
*
|
||||
* Uses the following settings from the synth object:
|
||||
* - \ref settings_audio_file_name : Output filename
|
||||
* - \ref settings_audio_file_type : File type, "auto" tries to determine type from filename
|
||||
* extension with fallback to "wav".
|
||||
* - \ref settings_audio_file_format : Audio format
|
||||
* - \ref settings_audio_file_endian : Endian byte order, "auto" for file type's default byte order
|
||||
* - \ref settings_audio_period-size : Size of audio blocks to process
|
||||
* - \ref settings_synth_sample-rate : Sample rate to use
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fluid_file_renderer_t *
|
||||
new_fluid_file_renderer(fluid_synth_t *synth)
|
||||
{
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
char *type, *format, *endian;
|
||||
SF_INFO info;
|
||||
double samplerate;
|
||||
int retval;
|
||||
#endif
|
||||
int audio_channels;
|
||||
char *filename = NULL;
|
||||
fluid_file_renderer_t *dev;
|
||||
|
||||
fluid_return_val_if_fail(synth != NULL, NULL);
|
||||
fluid_return_val_if_fail(synth->settings != NULL, NULL);
|
||||
|
||||
dev = FLUID_NEW(fluid_file_renderer_t);
|
||||
|
||||
if(dev == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FLUID_MEMSET(dev, 0, sizeof(fluid_file_renderer_t));
|
||||
|
||||
dev->synth = synth;
|
||||
fluid_settings_getint(synth->settings, "audio.period-size", &dev->period_size);
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
dev->buf_size = 2 * dev->period_size * sizeof(float);
|
||||
dev->buf = FLUID_ARRAY(float, 2 * dev->period_size);
|
||||
#else
|
||||
dev->buf_size = 2 * dev->period_size * sizeof(short);
|
||||
dev->buf = FLUID_ARRAY(short, 2 * dev->period_size);
|
||||
#endif
|
||||
|
||||
if(dev->buf == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
fluid_settings_dupstr(synth->settings, "audio.file.name", &filename);
|
||||
fluid_settings_getint(synth->settings, "synth.audio-channels", &audio_channels);
|
||||
|
||||
if(filename == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "No file name specified");
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
info.format = FLUID_FILE_RENDERER_DEFAULT_FILE_TYPE | SF_FORMAT_PCM_16;
|
||||
|
||||
fluid_settings_dupstr(synth->settings, "audio.file.type", &type);
|
||||
fluid_settings_dupstr(synth->settings, "audio.file.format", &format);
|
||||
fluid_settings_dupstr(synth->settings, "audio.file.endian", &endian);
|
||||
|
||||
retval = fluid_file_renderer_parse_options(type, format, endian, filename, &info);
|
||||
|
||||
if(type)
|
||||
{
|
||||
FLUID_FREE(type);
|
||||
}
|
||||
|
||||
if(format)
|
||||
{
|
||||
FLUID_FREE(format);
|
||||
}
|
||||
|
||||
if(endian)
|
||||
{
|
||||
FLUID_FREE(endian);
|
||||
}
|
||||
|
||||
if(!retval)
|
||||
{
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
fluid_settings_getnum(synth->settings, "synth.sample-rate", &samplerate);
|
||||
info.samplerate = samplerate + 0.5;
|
||||
info.channels = 2;
|
||||
|
||||
/* Search for valid format for given file type, if invalid and no format was specified.
|
||||
* To handle Ogg/Vorbis and possibly future file types with new formats.
|
||||
* Checking if format is SF_FORMAT_PCM_16 isn't a fool proof way to check if
|
||||
* format was specified or not (if user specifies "s16" itself), but should suffice. */
|
||||
if(!sf_format_check(&info)
|
||||
&& ((info.format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM_16
|
||||
|| !fluid_file_renderer_find_valid_format(&info)))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Invalid or unsupported audio file format settings");
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
dev->sndfile = sf_open(filename, SFM_WRITE, &info);
|
||||
|
||||
if(!dev->sndfile)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to open audio file '%s' for writing", filename);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* Turn on clipping and normalization of floats (-1.0 - 1.0) */
|
||||
sf_command(dev->sndfile, SFC_SET_CLIPPING, NULL, SF_TRUE);
|
||||
sf_command(dev->sndfile, SFC_SET_NORM_FLOAT, NULL, SF_TRUE);
|
||||
|
||||
#else
|
||||
dev->file = FLUID_FOPEN(filename, "wb");
|
||||
|
||||
if(dev->file == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to open the file '%s'", filename);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
error_recovery:
|
||||
|
||||
FLUID_FREE(filename);
|
||||
delete_fluid_file_renderer(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set vbr encoding quality (only available with libsndfile support)
|
||||
* @param dev File renderer object.
|
||||
* @param q The encoding quality, see libsndfile documentation of \c SFC_SET_VBR_ENCODING_QUALITY
|
||||
* @return #FLUID_OK if the quality has been successfully set, #FLUID_FAILED otherwise
|
||||
* @since 1.1.7
|
||||
*/
|
||||
int
|
||||
fluid_file_set_encoding_quality(fluid_file_renderer_t *dev, double q)
|
||||
{
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
|
||||
if(sf_command(dev->sndfile, SFC_SET_VBR_ENCODING_QUALITY, &q, sizeof(double)) == SF_TRUE)
|
||||
{
|
||||
return FLUID_OK;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close file and destroy a file renderer object.
|
||||
* @param dev File renderer object.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void delete_fluid_file_renderer(fluid_file_renderer_t *dev)
|
||||
{
|
||||
fluid_return_if_fail(dev != NULL);
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
|
||||
if(dev->sndfile != NULL)
|
||||
{
|
||||
int retval = sf_close(dev->sndfile);
|
||||
|
||||
if(retval != 0)
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN, "Error closing audio file: %s", sf_error_number(retval));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if(dev->file != NULL)
|
||||
{
|
||||
fclose(dev->file);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FLUID_FREE(dev->buf);
|
||||
FLUID_FREE(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write period_size samples to file.
|
||||
* @param dev File renderer instance
|
||||
* @return #FLUID_OK or #FLUID_FAILED if an error occurred
|
||||
* @since 1.1.0
|
||||
*/
|
||||
int
|
||||
fluid_file_renderer_process_block(fluid_file_renderer_t *dev)
|
||||
{
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
int n;
|
||||
|
||||
fluid_synth_write_float(dev->synth, dev->period_size, dev->buf, 0, 2, dev->buf, 1, 2);
|
||||
|
||||
n = sf_writef_float(dev->sndfile, dev->buf, dev->period_size);
|
||||
|
||||
if(n != dev->period_size)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Audio file write error: %s",
|
||||
sf_strerror(dev->sndfile));
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
|
||||
#else /* No libsndfile support */
|
||||
|
||||
size_t res, nmemb = dev->buf_size;
|
||||
|
||||
fluid_synth_write_s16(dev->synth, dev->period_size, dev->buf, 0, 2, dev->buf, 1, 2);
|
||||
|
||||
res = fwrite(dev->buf, 1, nmemb, dev->file);
|
||||
|
||||
if(res < nmemb)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Audio output file write error: %s",
|
||||
strerror(errno));
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
|
||||
/**
|
||||
* Parse a colon separated format string and configure an SF_INFO structure accordingly.
|
||||
* @param filetype File type string (NULL or "auto" to attempt to identify format
|
||||
* by filename extension, with fallback to "wav")
|
||||
* @param format File audio format string or NULL to use "s16"
|
||||
* @param endian File endian string or NULL to use "auto" which uses the file type's
|
||||
* default endian byte order.
|
||||
* @param filename File name (used by "auto" type to determine type, based on extension)
|
||||
* @param info Audio file info structure to configure
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
static int
|
||||
fluid_file_renderer_parse_options(char *filetype, char *format, char *endian,
|
||||
char *filename, SF_INFO *info)
|
||||
{
|
||||
int type = -1; /* -1 indicates "auto" type */
|
||||
char *s;
|
||||
unsigned int i;
|
||||
|
||||
/* If "auto" type, then use extension to search for a match */
|
||||
if(!filetype || FLUID_STRCMP(filetype, "auto") == 0)
|
||||
{
|
||||
type = FLUID_FILE_RENDERER_DEFAULT_FILE_TYPE;
|
||||
s = FLUID_STRRCHR(filename, '.');
|
||||
|
||||
if(s && s[1] != '\0')
|
||||
{
|
||||
if(!fluid_file_renderer_find_file_type(s + 1, &type))
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN, "Failed to determine audio file type from filename, defaulting to WAV");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!fluid_file_renderer_find_file_type(filetype, &type))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Invalid or unsupported audio file type '%s'", filetype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
info->format = (info->format & ~SF_FORMAT_TYPEMASK) | type;
|
||||
|
||||
/* Look for subtype */
|
||||
if(format)
|
||||
{
|
||||
for(i = 0; i < FLUID_N_ELEMENTS(format_names); i++)
|
||||
{
|
||||
if(FLUID_STRCMP(format, format_names[i]) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i >= FLUID_N_ELEMENTS(format_names))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Invalid or unsupported file audio format '%s'", format);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
info->format = (info->format & ~SF_FORMAT_SUBMASK) | format_ids[i];
|
||||
}
|
||||
|
||||
#if LIBSNDFILE_HASVORBIS
|
||||
|
||||
/* Force subformat to vorbis as nothing else would make sense currently */
|
||||
if((info->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_OGG)
|
||||
{
|
||||
info->format = (info->format & ~SF_FORMAT_SUBMASK) | SF_FORMAT_VORBIS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Look for endian */
|
||||
if(endian)
|
||||
{
|
||||
for(i = 0; i < FLUID_N_ELEMENTS(endian_names); i++)
|
||||
{
|
||||
if(FLUID_STRCMP(endian, endian_names[i]) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i >= FLUID_N_ELEMENTS(endian_names))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Invalid or unsupported endian byte order '%s'", endian);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
info->format = (info->format & ~SF_FORMAT_ENDMASK) | endian_ids[i];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a supported libsndfile file type by extension.
|
||||
* @param extension The extension string
|
||||
* @param type Location to store the type (unmodified if not found)
|
||||
* @return TRUE if found, FALSE otherwise
|
||||
*/
|
||||
static int
|
||||
fluid_file_renderer_find_file_type(char *extension, int *type)
|
||||
{
|
||||
SF_FORMAT_INFO finfo;
|
||||
int major_count;
|
||||
int i;
|
||||
|
||||
sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof(int));
|
||||
|
||||
for(i = 0; i < major_count; i++)
|
||||
{
|
||||
finfo.format = i;
|
||||
sf_command(NULL, SFC_GET_FORMAT_MAJOR, &finfo, sizeof(finfo));
|
||||
|
||||
if(FLUID_STRCMP(extension, finfo.extension) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i < major_count)
|
||||
{
|
||||
*type = finfo.format;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Search for a valid audio format for a given file type */
|
||||
static int
|
||||
fluid_file_renderer_find_valid_format(SF_INFO *info)
|
||||
{
|
||||
SF_FORMAT_INFO format_info;
|
||||
int count, i;
|
||||
|
||||
sf_command(NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof(int));
|
||||
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
format_info.format = i;
|
||||
|
||||
sf_command(NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof(format_info));
|
||||
|
||||
info->format = (info->format & ~SF_FORMAT_SUBMASK) | format_info.format;
|
||||
|
||||
if(sf_format_check(info))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
1882
thirdparty/fluidsynth/src/bindings/fluid_ladspa.c
vendored
Normal file
1882
thirdparty/fluidsynth/src/bindings/fluid_ladspa.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
36
thirdparty/fluidsynth/src/bindings/fluid_ladspa.h
vendored
Normal file
36
thirdparty/fluidsynth/src/bindings/fluid_ladspa.h
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* 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 _FLUID_LADSPA_H
|
||||
#define _FLUID_LADSPA_H
|
||||
|
||||
#include "fluid_sys.h"
|
||||
|
||||
fluid_ladspa_fx_t *new_fluid_ladspa_fx(fluid_real_t sample_rate, int buffer_size);
|
||||
void delete_fluid_ladspa_fx(fluid_ladspa_fx_t *fx);
|
||||
|
||||
int fluid_ladspa_set_sample_rate(fluid_ladspa_fx_t *fx, fluid_real_t sample_rate);
|
||||
|
||||
void fluid_ladspa_run(fluid_ladspa_fx_t *fx, int block_count, int block_size);
|
||||
|
||||
int fluid_ladspa_add_host_ports(fluid_ladspa_fx_t *fx, const char *prefix,
|
||||
int num_buffers, fluid_real_t buffers[], int buf_stride);
|
||||
|
||||
#endif /* _FLUID_LADSPA_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue