mirror of
https://github.com/ZDoom/ZMusic.git
synced 2025-04-24 01:51:35 +00:00
Compare commits
No commits in common. "master" and "1.1.5" have entirely different histories.
397 changed files with 26810 additions and 140477 deletions
96
.github/workflows/continuous_integration.yml
vendored
96
.github/workflows/continuous_integration.yml
vendored
|
@ -10,65 +10,62 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
config:
|
config:
|
||||||
- name: Visual Studio - Release
|
- {
|
||||||
os: windows-latest
|
name: "Visual Studio 64-bit",
|
||||||
build_type: Release
|
os: windows-latest,
|
||||||
|
build_type: "Release",
|
||||||
- name: Visual Studio - Debug
|
extra_options: "-A x64"
|
||||||
os: windows-latest
|
}
|
||||||
build_type: Debug
|
- {
|
||||||
|
name: "Visual Studio 32-bit",
|
||||||
- name: macOS Clang - Dynamic Deps
|
os: windows-latest,
|
||||||
os: macos-latest
|
build_type: "Release",
|
||||||
build_type: Release
|
extra_options: "-A Win32 -DFORCE_INTERNAL_ZLIB=ON"
|
||||||
|
}
|
||||||
- name: macOS Clang - Static Deps
|
- {
|
||||||
os: macos-latest
|
name: "macOS Clang",
|
||||||
build_type: Release
|
os: macos-latest,
|
||||||
cmake_options: -DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF
|
build_type: "Release"
|
||||||
deps_cmd: brew install libsndfile mpg123
|
}
|
||||||
|
- {
|
||||||
- name: Linux GCC - Dynamic Deps
|
name: "Linux GCC",
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest,
|
||||||
build_type: Release
|
build_type: "Release"
|
||||||
deps_cmd: sudo apt update && sudo apt install libglib2.0-dev
|
}
|
||||||
|
- {
|
||||||
- name: Linux GCC - Static Deps
|
name: "Linux Clang",
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest,
|
||||||
build_type: Release
|
build_type: "Release",
|
||||||
cmake_options: -DDYN_FLUIDSYNTH=OFF -DDYN_MPG123=OFF -DDYN_SNDFILE=OFF
|
extra_options: "-DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++"
|
||||||
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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v1
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
${{ matrix.config.deps_cmd }}
|
if [[ "${{ runner.os }}" == 'Linux' ]]; then
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install libasound2-dev
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Configure
|
- name: Configure
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} -DCMAKE_INSTALL_PREFIX=./build_install ${{ matrix.config.cmake_options }} .
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} -DCMAKE_INSTALL_PREFIX=../build_install ${{ matrix.config.extra_options }} ..
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
export MAKEFLAGS=--keep-going
|
cd build
|
||||||
cmake --build build --target install --config ${{ matrix.config.build_type }} --parallel 3
|
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
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -77,7 +74,7 @@ jobs:
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
declare -x PREFIX=`pwd`/../../../build_install
|
declare -x PREFIX=`pwd`/../../../build_install
|
||||||
cmake -DCMAKE_PREFIX_PATH=${PREFIX} ${{ matrix.config.cmake_options }} ..
|
cmake -DCMAKE_PREFIX_PATH=${PREFIX} ${{ matrix.config.extra_options }} ..
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ matrix.config.build_type }}
|
||||||
if [[ "${{ runner.os }}" == 'macOS' ]]; then
|
if [[ "${{ runner.os }}" == 'macOS' ]]; then
|
||||||
declare -x DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${PREFIX}
|
declare -x DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${PREFIX}
|
||||||
|
@ -88,10 +85,3 @@ jobs:
|
||||||
else
|
else
|
||||||
./list_midi_devices
|
./list_midi_devices
|
||||||
fi
|
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,24 +1,9 @@
|
||||||
cmake_minimum_required(VERSION 3.13...3.19)
|
cmake_minimum_required(VERSION 3.13...3.19)
|
||||||
|
|
||||||
if (VCPKG_LIBSNDFILE)
|
|
||||||
list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-libsndfile")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
project(ZMusic
|
project(ZMusic
|
||||||
VERSION 1.1.14
|
VERSION 1.1.4
|
||||||
LANGUAGES C CXX
|
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)
|
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
@ -27,28 +12,12 @@ include(ZUtility)
|
||||||
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
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)
|
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)
|
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||||
|
elseif(NOT DEFINED BUILD_SHARED_LIBS)
|
||||||
# Enable install rules
|
set(BUILD_SHARED_LIBS ON)
|
||||||
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()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
@ -128,11 +97,6 @@ endif()
|
||||||
# Initialize our list of find_package dependencies for configure_package_config_file
|
# Initialize our list of find_package dependencies for configure_package_config_file
|
||||||
set(ZMUSIC_PACKAGE_DEPENDENCIES "" CACHE INTERNAL "")
|
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(thirdparty)
|
||||||
add_subdirectory(source)
|
add_subdirectory(source)
|
||||||
|
|
||||||
|
@ -146,12 +110,10 @@ configure_package_config_file(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake
|
||||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
|
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
|
||||||
)
|
)
|
||||||
if(ZMUSIC_INSTALL)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfigVersion.cmake
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/ZMusicConfigVersion.cmake
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic
|
COMPONENT devel
|
||||||
COMPONENT devel
|
)
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||||
set(CPACK_PACKAGE_CONTACT "First Last <example@example.com>" CACHE STRING "Contact info for archive maintainer.")
|
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
|
git clone https://github.com/coelckers/ZMusic.git
|
||||||
mkdir ZMusic/build
|
mkdir ZMusic/build
|
||||||
cd ZMusic/build
|
cd ZMusic/build
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||||
cmake --build .
|
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.
|
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.
|
||||||
|
|
|
@ -27,7 +27,7 @@ include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(SndFile DEFAULT_MSG SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR)
|
find_package_handle_standard_args(SndFile DEFAULT_MSG SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR)
|
||||||
|
|
||||||
if(SNDFILE_FOUND)
|
if(SNDFILE_FOUND)
|
||||||
add_library(sndfile UNKNOWN IMPORTED GLOBAL)
|
add_library(sndfile UNKNOWN IMPORTED)
|
||||||
set_target_properties(sndfile
|
set_target_properties(sndfile
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
IMPORTED_LOCATION "${SNDFILE_LIBRARY}"
|
IMPORTED_LOCATION "${SNDFILE_LIBRARY}"
|
||||||
|
|
|
@ -120,18 +120,10 @@ function(require_strnicmp Tgt Visibility)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(use_fast_math)
|
function(use_fast_math Tgt)
|
||||||
foreach(Tgt IN LISTS ARGN)
|
if(MSVC)
|
||||||
if(TARGET Tgt)
|
set_property( TARGET "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "/fp:fast" )
|
||||||
set(TgtType TARGET)
|
elseif(ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE)
|
||||||
else()
|
set_property( TARGET "${Tgt}" APPEND PROPERTY COMPILE_OPTIONS "-ffast-math" "-ffp-contract=fast" )
|
||||||
set(TgtType SOURCE)
|
endif()
|
||||||
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()
|
endfunction()
|
||||||
|
|
|
@ -67,8 +67,7 @@ typedef struct SoundStreamInfo_
|
||||||
typedef enum SampleType_
|
typedef enum SampleType_
|
||||||
{
|
{
|
||||||
SampleType_UInt8,
|
SampleType_UInt8,
|
||||||
SampleType_Int16,
|
SampleType_Int16
|
||||||
SampleType_Float32
|
|
||||||
} SampleType;
|
} SampleType;
|
||||||
|
|
||||||
typedef enum ChannelConfig_
|
typedef enum ChannelConfig_
|
||||||
|
@ -77,15 +76,6 @@ typedef enum ChannelConfig_
|
||||||
ChannelConfig_Stereo
|
ChannelConfig_Stereo
|
||||||
} ChannelConfig;
|
} 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_
|
typedef enum EIntConfigKey_
|
||||||
{
|
{
|
||||||
zmusic_adl_chips_count,
|
zmusic_adl_chips_count,
|
||||||
|
@ -151,7 +141,6 @@ typedef enum EIntConfigKey_
|
||||||
|
|
||||||
zmusic_snd_mididevice,
|
zmusic_snd_mididevice,
|
||||||
zmusic_snd_outputrate,
|
zmusic_snd_outputrate,
|
||||||
zmusic_mod_preferredplayer,
|
|
||||||
|
|
||||||
NUM_ZMUSIC_INT_CONFIGS
|
NUM_ZMUSIC_INT_CONFIGS
|
||||||
} EIntConfigKey;
|
} EIntConfigKey;
|
||||||
|
@ -275,14 +264,14 @@ typedef struct ZMusicConfigurationSetting_
|
||||||
|
|
||||||
|
|
||||||
#ifndef ZMUSIC_INTERNAL
|
#ifndef ZMUSIC_INTERNAL
|
||||||
#if defined(_MSC_VER) && !defined(ZMUSIC_STATIC)
|
#ifdef _MSC_VER
|
||||||
#define DLL_IMPORT _declspec(dllimport)
|
#define DLL_IMPORT _declspec(dllimport)
|
||||||
#else
|
#else // !_MSC_VER
|
||||||
#define DLL_IMPORT
|
#define DLL_IMPORT
|
||||||
#endif
|
#endif // _MSC_VER
|
||||||
// Note that the internal 'class' definitions are not C compatible!
|
// Note that the internal 'class' definitions are not C compatible!
|
||||||
typedef struct _ZMusic_MidiSource_Struct { int zm1; } *ZMusic_MidiSource;
|
typedef struct { int zm1; } *ZMusic_MidiSource;
|
||||||
typedef struct _ZMusic_MusicStream_Struct { int zm2; } *ZMusic_MusicStream;
|
typedef struct { int zm2; } *ZMusic_MusicStream;
|
||||||
struct SoundDecoder;
|
struct SoundDecoder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -325,12 +314,10 @@ extern "C"
|
||||||
DLL_IMPORT void ZMusic_Close(ZMusic_MusicStream song);
|
DLL_IMPORT void ZMusic_Close(ZMusic_MusicStream song);
|
||||||
DLL_IMPORT zmusic_bool ZMusic_SetSubsong(ZMusic_MusicStream song, int subsong);
|
DLL_IMPORT zmusic_bool ZMusic_SetSubsong(ZMusic_MusicStream song, int subsong);
|
||||||
DLL_IMPORT zmusic_bool ZMusic_IsLooping(ZMusic_MusicStream song);
|
DLL_IMPORT zmusic_bool ZMusic_IsLooping(ZMusic_MusicStream song);
|
||||||
DLL_IMPORT int ZMusic_GetDeviceType(ZMusic_MusicStream song);
|
|
||||||
DLL_IMPORT zmusic_bool ZMusic_IsMIDI(ZMusic_MusicStream song);
|
DLL_IMPORT zmusic_bool ZMusic_IsMIDI(ZMusic_MusicStream song);
|
||||||
DLL_IMPORT void ZMusic_VolumeChanged(ZMusic_MusicStream song);
|
DLL_IMPORT void ZMusic_VolumeChanged(ZMusic_MusicStream song);
|
||||||
DLL_IMPORT zmusic_bool ZMusic_WriteSMF(ZMusic_MidiSource source, const char* fn, int looplimit);
|
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_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.
|
// 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.
|
// 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);
|
DLL_IMPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue);
|
||||||
|
@ -418,7 +405,6 @@ typedef zmusic_bool (*pfn_ZMusic_IsMIDI)(ZMusic_MusicStream song);
|
||||||
typedef void (*pfn_ZMusic_VolumeChanged)(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 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_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_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_ChangeMusicSettingFloat)(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue);
|
||||||
typedef zmusic_bool (*pfn_ChangeMusicSettingString)(EStringConfigKey key, ZMusic_MusicStream song, const char* value);
|
typedef zmusic_bool (*pfn_ChangeMusicSettingString)(EStringConfigKey key, ZMusic_MusicStream song, const char* value);
|
||||||
|
@ -432,4 +418,4 @@ typedef const ZMusicMidiOutDevice *(*pfn_ZMusic_GetMidiDevices)(int *pAmount);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -18,9 +18,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
Dynamic Universal Music Bibliotheque, Version 0.9.3
|
Dynamic Universal Music Bibliotheque
|
||||||
|
|
||||||
Copyright (C) 2001-2005 Ben Davis, Robert J Ohannessian and Julien Cugniere
|
Copyright (C) 2001-2003 Ben Davis, Robert J Ohannessian and Julien Cugniere
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied warranty.
|
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
|
In no event shall the authors be held liable for any damages arising from the
|
||||||
|
@ -39,49 +39,16 @@ freely, subject to the following restrictions:
|
||||||
[Note that the above point asks for a link to DUMB, not just a mention.
|
[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/".]
|
Googling for DUMB doesn't help much! The URL is "http://dumb.sf.net/".]
|
||||||
|
|
||||||
[The link was originally strictly required. This was changed for two
|
[The only reason why the link is not strictly required is that such a
|
||||||
reasons. Firstly, if many projects request an acknowledgement, the list of
|
requirement prevents DUMB from being used in projects with certain other
|
||||||
acknowledgements can become quite unmanageable. Secondly, DUMB was placing
|
licences, notably the GPL. See http://www.gnu.org/philosophy/bsd.html .]
|
||||||
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
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
misrepresented as being the original software.
|
misrepresented as being the original software.
|
||||||
|
|
||||||
3. This notice may not be removed from or altered in any source distribution.
|
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 on any Monday at
|
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
|
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 provided by Inphernic; every licence should contain at least one
|
||||||
clause, the reasoning behind which is far from obvious.]
|
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,7 +25,6 @@ INTERFACE
|
||||||
streamsources/music_dumb.cpp
|
streamsources/music_dumb.cpp
|
||||||
streamsources/music_gme.cpp
|
streamsources/music_gme.cpp
|
||||||
streamsources/music_libsndfile.cpp
|
streamsources/music_libsndfile.cpp
|
||||||
streamsources/music_libxmp.cpp
|
|
||||||
streamsources/music_opl.cpp
|
streamsources/music_opl.cpp
|
||||||
streamsources/music_xa.cpp
|
streamsources/music_xa.cpp
|
||||||
musicformats/music_stream.cpp
|
musicformats/music_stream.cpp
|
||||||
|
@ -66,12 +65,7 @@ if(NOT WIN32 AND NOT APPLE)
|
||||||
determine_package_config_dependency(ZMUSIC_PACKAGE_DEPENDENCIES TARGET Threads::Threads MODULE Threads)
|
determine_package_config_dependency(ZMUSIC_PACKAGE_DEPENDENCIES TARGET Threads::Threads MODULE Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("vcpkg-libsndfile" IN_LIST VCPKG_MANIFEST_FEATURES)
|
option(DYN_SNDFILE "Dynamically load libsndfile" ON)
|
||||||
set(DYN_SNDFILE 0)
|
|
||||||
else()
|
|
||||||
option(DYN_SNDFILE "Dynamically load libsndfile" ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DYN_SNDFILE)
|
if(DYN_SNDFILE)
|
||||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_SNDFILE DYN_SNDFILE)
|
target_compile_definitions(zmusic-obj INTERFACE HAVE_SNDFILE DYN_SNDFILE)
|
||||||
else()
|
else()
|
||||||
|
@ -84,14 +78,10 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("vcpkg-libsndfile" IN_LIST VCPKG_MANIFEST_FEATURES)
|
option(DYN_MPG123 "Dynamically load libmpg123" ON)
|
||||||
set(DYN_MPG123 0)
|
|
||||||
else()
|
|
||||||
option(DYN_MPG123 "Dynamically load libmpg123" ON)
|
|
||||||
endif()
|
|
||||||
if(DYN_MPG123)
|
if(DYN_MPG123)
|
||||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_MPG123 DYN_MPG123)
|
target_compile_definitions(zmusic-obj INTERFACE HAVE_MPG123 DYN_MPG123)
|
||||||
elseif(NOT ("vcpkg-libsndfile" IN_LIST VCPKG_MANIFEST_FEATURES))
|
else()
|
||||||
find_package(MPG123)
|
find_package(MPG123)
|
||||||
|
|
||||||
if(MPG123_FOUND)
|
if(MPG123_FOUND)
|
||||||
|
@ -101,6 +91,19 @@ elseif(NOT ("vcpkg-libsndfile" IN_LIST VCPKG_MANIFEST_FEATURES))
|
||||||
endif()
|
endif()
|
||||||
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
|
# System MIDI support
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_compile_definitions(zmusic-obj INTERFACE HAVE_SYSTEM_MIDI)
|
target_compile_definitions(zmusic-obj INTERFACE HAVE_SYSTEM_MIDI)
|
||||||
|
@ -128,7 +131,7 @@ if(WIN32)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(zmusic-obj INTERFACE dumb gme libxmp miniz ${CMAKE_DL_LIBS})
|
target_link_libraries(zmusic-obj INTERFACE dumb gme ZLIB::ZLIB ${CMAKE_DL_LIBS})
|
||||||
|
|
||||||
target_include_directories(zmusic-obj
|
target_include_directories(zmusic-obj
|
||||||
INTERFACE
|
INTERFACE
|
||||||
|
@ -149,14 +152,13 @@ use_fast_math(zmusiclite)
|
||||||
|
|
||||||
# Although zmusic-obj puts the public include directory in our private include
|
# 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.
|
# list, we need to add it to the interface include directories for consumers.
|
||||||
target_include_directories(zmusic INTERFACE $<INSTALL_INTERFACE:include> $<BUILD_INTERFACE:${ZMusic_SOURCE_DIR}/include>)
|
target_include_directories(zmusic INTERFACE $<INSTALL_INTERFACE:include>)
|
||||||
target_include_directories(zmusiclite INTERFACE $<INSTALL_INTERFACE:include> $<BUILD_INTERFACE:${ZMusic_SOURCE_DIR}/include>)
|
target_include_directories(zmusiclite INTERFACE $<INSTALL_INTERFACE:include>)
|
||||||
|
|
||||||
target_link_libraries_hidden(zmusic zmusic-obj adl oplsynth opn timidity timidityplus wildmidi fluidsynth)
|
target_link_libraries_hidden(zmusic zmusic-obj adl oplsynth opn timidity timidityplus wildmidi)
|
||||||
target_link_libraries_hidden(zmusiclite zmusic-obj fluidsynth)
|
target_link_libraries_hidden(zmusiclite zmusic-obj)
|
||||||
|
|
||||||
target_compile_definitions(zmusic PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:zmusic,TYPE>,STATIC_LIBRARY>:ZMUSIC_STATIC>)
|
target_compile_definitions(zmusiclite PRIVATE ZMUSIC_LITE=1)
|
||||||
target_compile_definitions(zmusiclite PRIVATE ZMUSIC_LITE=1 PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:zmusiclite,TYPE>,STATIC_LIBRARY>:ZMUSIC_STATIC>)
|
|
||||||
|
|
||||||
set_target_properties(zmusic zmusiclite
|
set_target_properties(zmusic zmusiclite
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
|
@ -166,43 +168,37 @@ PROPERTIES
|
||||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (VCPKG_TOOLCHAIN)
|
install(TARGETS zmusic EXPORT ZMusicFullTargets
|
||||||
x_vcpkg_install_local_dependencies(TARGETS zmusic zmusiclite DESTINATION ".")
|
PUBLIC_HEADER
|
||||||
endif()
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
COMPONENT devel
|
||||||
|
LIBRARY
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
|
COMPONENT full
|
||||||
|
NAMELINK_COMPONENT devel
|
||||||
|
)
|
||||||
|
|
||||||
if(ZMUSIC_INSTALL)
|
install(TARGETS zmusiclite EXPORT ZMusicLiteTargets
|
||||||
install(TARGETS zmusic EXPORT ZMusicFullTargets
|
PUBLIC_HEADER
|
||||||
PUBLIC_HEADER
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
COMPONENT devel
|
||||||
COMPONENT devel
|
LIBRARY
|
||||||
LIBRARY
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
COMPONENT lite
|
||||||
COMPONENT full
|
NAMELINK_COMPONENT devel
|
||||||
NAMELINK_COMPONENT devel
|
)
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS zmusiclite EXPORT ZMusicLiteTargets
|
install(EXPORT ZMusicFullTargets
|
||||||
PUBLIC_HEADER
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
NAMESPACE ZMusic::
|
||||||
COMPONENT devel
|
COMPONENT devel
|
||||||
LIBRARY
|
)
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
COMPONENT lite
|
|
||||||
NAMELINK_COMPONENT devel
|
|
||||||
)
|
|
||||||
|
|
||||||
install(EXPORT ZMusicFullTargets
|
install(EXPORT ZMusicLiteTargets
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
||||||
NAMESPACE ZMusic::
|
NAMESPACE ZMusic::
|
||||||
COMPONENT devel
|
COMPONENT devel
|
||||||
)
|
)
|
||||||
|
|
||||||
install(EXPORT ZMusicLiteTargets
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ZMusic"
|
|
||||||
NAMESPACE ZMusic::
|
|
||||||
COMPONENT devel
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if( MSVC )
|
if( MSVC )
|
||||||
option( ZMUSIC_GENERATE_MAPFILE "Generate .map file for debugging." OFF )
|
option( ZMUSIC_GENERATE_MAPFILE "Generate .map file for debugging." OFF )
|
||||||
|
|
16926
source/data/xg.h
16926
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
|
#ifdef _WIN32
|
||||||
static const char* libnames[] = { "sndfile.dll", "libsndfile-1.dll" };
|
#define SNDFILELIB "libsndfile-1.dll"
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
static const char* libnames[] = { "libsndfile.1.dylib" };
|
#define SNDFILELIB "libsndfile.1.dylib"
|
||||||
#else
|
#else
|
||||||
static const char* libnames[] = { "libsndfile.so.1" };
|
#define SNDFILELIB "libsndfile.so.1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" int IsSndFilePresent()
|
bool IsSndFilePresent()
|
||||||
{
|
{
|
||||||
#if !defined DYN_SNDFILE
|
#if !defined DYN_SNDFILE
|
||||||
return true;
|
return true;
|
||||||
|
@ -61,17 +61,14 @@ extern "C" int IsSndFilePresent()
|
||||||
if (!done)
|
if (!done)
|
||||||
{
|
{
|
||||||
done = true;
|
done = true;
|
||||||
for (auto libname : libnames)
|
auto abspath = FModule_GetProgDir() + "/" SNDFILELIB;
|
||||||
{
|
cached_result = SndFileModule.Load({abspath.c_str(), SNDFILELIB});
|
||||||
auto abspath = FModule_GetProgDir() + "/" + libname;
|
|
||||||
cached_result = SndFileModule.Load({ abspath.c_str(), libname });
|
|
||||||
if (cached_result) break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return cached_result;
|
return cached_result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sf_count_t SndFileDecoder::file_get_filelen(void *user_data)
|
sf_count_t SndFileDecoder::file_get_filelen(void *user_data)
|
||||||
{
|
{
|
||||||
auto &reader = reinterpret_cast<SndFileDecoder*>(user_data)->Reader;
|
auto &reader = reinterpret_cast<SndFileDecoder*>(user_data)->Reader;
|
||||||
|
@ -209,60 +206,4 @@ size_t SndFileDecoder::getSampleLength()
|
||||||
return (size_t)((SndInfo.frames > 0) ? SndInfo.frames : 0);
|
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
|
#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,8 +43,6 @@ private:
|
||||||
static sf_count_t file_tell(void *user_data);
|
static sf_count_t file_tell(void *user_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
|
||||||
#include "../thirdparty/sndfile.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* SNDFILE_DECODER_H */
|
#endif /* SNDFILE_DECODER_H */
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
#ifndef SNDDEF_H
|
#ifndef SNDDEF_H
|
||||||
#define SNDDEF_H
|
#define SNDDEF_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined HAVE_SNDFILE && defined DYN_SNDFILE
|
#if defined HAVE_SNDFILE && defined DYN_SNDFILE
|
||||||
|
|
||||||
#define DEFINE_ENTRY(type, name) static TReqProc<SndFileModule, type> p_##name{#name};
|
#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(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(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, 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)
|
DEFINE_ENTRY(sf_count_t (*)(SNDFILE *sndfile, sf_count_t frames, int whence), sf_seek)
|
||||||
#undef DEFINE_ENTRY
|
#undef DEFINE_ENTRY
|
||||||
|
|
||||||
|
|
|
@ -105,53 +105,13 @@ short* dumb_decode_vorbis(int outlen, const void* oggstream, int sizebytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->getInfo(&srate, &chans, &type);
|
decoder->getInfo(&srate, &chans, &type);
|
||||||
if (chans != ChannelConfig_Mono)
|
if (chans != ChannelConfig_Mono || type != SampleType_Int16)
|
||||||
{
|
{
|
||||||
delete decoder;
|
delete decoder;
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == SampleType_Int16)
|
decoder->read((char*)samples, outlen);
|
||||||
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;
|
delete decoder;
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
virtual std::string GetStats();
|
virtual std::string GetStats();
|
||||||
virtual int GetDeviceType() const { return MDEV_DEFAULT; }
|
virtual int GetDeviceType() const { return MDEV_DEFAULT; }
|
||||||
virtual bool CanHandleSysex() const { return true; }
|
virtual bool CanHandleSysex() const { return true; }
|
||||||
virtual SoundStreamInfoEx GetStreamInfoEx() const;
|
virtual SoundStreamInfo GetStreamInfo() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MidiCallback Callback;
|
MidiCallback Callback;
|
||||||
|
@ -81,7 +81,7 @@ public:
|
||||||
virtual int Open() override;
|
virtual int Open() override;
|
||||||
virtual bool ServiceStream(void* buff, int numbytes);
|
virtual bool ServiceStream(void* buff, int numbytes);
|
||||||
int GetSampleRate() const { return SampleRate; }
|
int GetSampleRate() const { return SampleRate; }
|
||||||
SoundStreamInfoEx GetStreamInfoEx() const override;
|
SoundStreamInfo GetStreamInfo() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double Tempo;
|
double Tempo;
|
||||||
|
@ -117,7 +117,6 @@ public:
|
||||||
int Resume() override;
|
int Resume() override;
|
||||||
int Open() override
|
int Open() override
|
||||||
{
|
{
|
||||||
playDevice->SetCallback(Callback, CallbackData);
|
|
||||||
return playDevice->Open();
|
return playDevice->Open();
|
||||||
}
|
}
|
||||||
int OpenRenderer() override { return playDevice->OpenRenderer(); }
|
int OpenRenderer() override { return playDevice->OpenRenderer(); }
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace {
|
||||||
|
|
||||||
enum class EventType {
|
enum class EventType {
|
||||||
Null,
|
Null,
|
||||||
|
Delay,
|
||||||
Action
|
Action
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,7 +160,7 @@ int AlsaMIDIDevice::Open()
|
||||||
snd_seq_port_info_set_port(pinfo, IntendedPortId);
|
snd_seq_port_info_set_port(pinfo, IntendedPortId);
|
||||||
snd_seq_port_info_set_port_specified(pinfo, 1);
|
snd_seq_port_info_set_port_specified(pinfo, 1);
|
||||||
|
|
||||||
snd_seq_port_info_set_name(pinfo, "ZMusic Program Music");
|
snd_seq_port_info_set_name(pinfo, "GZDoom Music");
|
||||||
|
|
||||||
snd_seq_port_info_set_capability(pinfo, 0);
|
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);
|
snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
|
||||||
|
@ -171,7 +172,7 @@ int AlsaMIDIDevice::Open()
|
||||||
|
|
||||||
if (QueueId < 0)
|
if (QueueId < 0)
|
||||||
{
|
{
|
||||||
QueueId = snd_seq_alloc_named_queue(sequencer.handle, "ZMusic Program Queue");
|
QueueId = snd_seq_alloc_named_queue(sequencer.handle, "GZDoom Queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Connected) {
|
if (!Connected) {
|
||||||
|
@ -289,8 +290,8 @@ EventType AlsaMIDIDevice::PullEvent(EventState & state) {
|
||||||
return EventType::Action;
|
return EventType::Action;
|
||||||
|
|
||||||
case MIDI_POLYPRESS:
|
case MIDI_POLYPRESS:
|
||||||
snd_seq_ev_set_keypress(&state.data, channel, parm1, parm2);
|
// FIXME: Seems to be missing in the Alsa sequencer implementation
|
||||||
return EventType::Action;
|
break;
|
||||||
|
|
||||||
case MIDI_CTRLCHANGE:
|
case MIDI_CTRLCHANGE:
|
||||||
snd_seq_ev_set_controller(&state.data, channel, parm1, parm2);
|
snd_seq_ev_set_controller(&state.data, channel, parm1, parm2);
|
||||||
|
@ -314,10 +315,8 @@ EventType AlsaMIDIDevice::PullEvent(EventState & state) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We didn't really recognize the event, treat it as a NOP
|
// We didn't really recognize the event, treat it as a delay
|
||||||
state.data.type = SND_SEQ_EVENT_NONE;
|
return EventType::Delay;
|
||||||
snd_seq_ev_set_fixed(&state.data);
|
|
||||||
return EventType::Action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlsaMIDIDevice::SetExit(bool exit) {
|
void AlsaMIDIDevice::SetExit(bool exit) {
|
||||||
|
@ -375,6 +374,13 @@ void AlsaMIDIDevice::PumpEvents() {
|
||||||
continue;
|
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
|
// 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 next_event_tick = buffer_ticks + event.ticks;
|
||||||
int queue_tick = snd_seq_queue_status_get_tick_time(status);
|
int queue_tick = snd_seq_queue_status_get_tick_time(status);
|
||||||
|
@ -427,6 +433,7 @@ void AlsaMIDIDevice::PumpEvents() {
|
||||||
snd_seq_drain_output(sequencer.handle);
|
snd_seq_drain_output(sequencer.handle);
|
||||||
snd_seq_sync_output_queue(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_stop_queue(sequencer.handle, QueueId, NULL);
|
||||||
snd_seq_drain_output(sequencer.handle);
|
snd_seq_drain_output(sequencer.handle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ bool AlsaSequencer::Open() {
|
||||||
if(error) {
|
if(error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
error = snd_seq_set_client_name(handle, "ZMusic Program");
|
error = snd_seq_set_client_name(handle, "GZDoom");
|
||||||
if(error) {
|
if(error) {
|
||||||
snd_seq_close(handle);
|
snd_seq_close(handle);
|
||||||
handle = nullptr;
|
handle = nullptr;
|
||||||
|
@ -131,7 +131,11 @@ int AlsaSequencer::EnumerateDevices() {
|
||||||
while (snd_seq_query_next_client(handle, cinfo) >= 0) {
|
while (snd_seq_query_next_client(handle, cinfo) >= 0) {
|
||||||
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
|
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);
|
int clientID = snd_seq_client_info_get_client(cinfo);
|
||||||
|
if(clientID < 16) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
snd_seq_port_info_set_port(pinfo, -1);
|
snd_seq_port_info_set_port(pinfo, -1);
|
||||||
// enumerate ports
|
// enumerate ports
|
||||||
|
|
|
@ -172,11 +172,11 @@ std::string MIDIDevice::GetStats()
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// MIDIDevice :: GetStreamInfoEx
|
// MIDIDevice :: GetStreamInfo
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
SoundStreamInfoEx MIDIDevice::GetStreamInfoEx() const
|
SoundStreamInfo MIDIDevice::GetStreamInfo() const
|
||||||
{
|
{
|
||||||
return {}; // i.e. do not use streaming.
|
return { 0, 0, 0 }; // i.e. do not use streaming.
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,19 +35,27 @@
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <stdexcept>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
#include "mididevice.h"
|
#include "mididevice.h"
|
||||||
#include "zmusic/mus2midi.h"
|
#include "zmusic/mus2midi.h"
|
||||||
#include "loader/i_module.h"
|
|
||||||
|
|
||||||
// FluidSynth implementation of a MIDI device -------------------------------
|
// FluidSynth implementation of a MIDI device -------------------------------
|
||||||
|
|
||||||
FluidConfig fluidConfig;
|
FluidConfig fluidConfig;
|
||||||
|
|
||||||
#include "../thirdparty/fluidsynth/include/fluidsynth.h"
|
#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
|
||||||
|
|
||||||
class FluidSynthMIDIDevice : public SoftSynthMIDIDevice
|
class FluidSynthMIDIDevice : public SoftSynthMIDIDevice
|
||||||
{
|
{
|
||||||
|
@ -76,10 +84,70 @@ protected:
|
||||||
int FluidSettingsResultOk = FLUID_OK;
|
int FluidSettingsResultOk = FLUID_OK;
|
||||||
int FluidSettingsResultFailed = FLUID_FAILED;
|
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 ------------------------------------------------------------------
|
// 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 -------------------------------------------------------------------
|
// TYPES -------------------------------------------------------------------
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
@ -111,6 +179,21 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, std::vector<std::stri
|
||||||
|
|
||||||
FluidSynth = NULL;
|
FluidSynth = NULL;
|
||||||
FluidSettings = 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();
|
FluidSettings = new_fluid_settings();
|
||||||
if (FluidSettings == NULL)
|
if (FluidSettings == NULL)
|
||||||
|
@ -142,8 +225,8 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(int samplerate, std::vector<std::stri
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_fluid_synth(FluidSynth);
|
|
||||||
delete_fluid_settings(FluidSettings);
|
delete_fluid_settings(FluidSettings);
|
||||||
|
delete_fluid_synth(FluidSynth);
|
||||||
FluidSynth = nullptr;
|
FluidSynth = nullptr;
|
||||||
FluidSettings = nullptr;
|
FluidSettings = nullptr;
|
||||||
throw std::runtime_error("Failed to load any MIDI patches.\n");
|
throw std::runtime_error("Failed to load any MIDI patches.\n");
|
||||||
|
@ -168,6 +251,9 @@ FluidSynthMIDIDevice::~FluidSynthMIDIDevice()
|
||||||
{
|
{
|
||||||
delete_fluid_settings(FluidSettings);
|
delete_fluid_settings(FluidSettings);
|
||||||
}
|
}
|
||||||
|
#ifdef DYN_FLUIDSYNTH
|
||||||
|
UnloadFluidSynth();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -180,8 +266,7 @@ FluidSynthMIDIDevice::~FluidSynthMIDIDevice()
|
||||||
|
|
||||||
int FluidSynthMIDIDevice::OpenRenderer()
|
int FluidSynthMIDIDevice::OpenRenderer()
|
||||||
{
|
{
|
||||||
// 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);
|
||||||
//fluid_synth_system_reset(FluidSynth);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,10 +324,9 @@ void FluidSynthMIDIDevice::HandleEvent(int status, int parm1, int parm2)
|
||||||
|
|
||||||
void FluidSynthMIDIDevice::HandleLongEvent(const uint8_t *data, int len)
|
void FluidSynthMIDIDevice::HandleLongEvent(const uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
constexpr int excludedByteCount = 2; // 0xF0 (first byte) and 0xF7 (last byte) are not given to FluidSynth.
|
if (len > 1 && (data[0] == 0xF0 || data[0] == 0xF7))
|
||||||
if (len > excludedByteCount && data[0] == 0xF0 && data[len - 1] == 0xF7)
|
|
||||||
{
|
{
|
||||||
fluid_synth_sysex(FluidSynth, (const char *)data + 1, len - excludedByteCount, NULL, NULL, NULL, 0);
|
fluid_synth_sysex(FluidSynth, (const char *)data + 1, len - 1, NULL, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,6 +492,85 @@ std::string FluidSynthMIDIDevice::GetStats()
|
||||||
return out;
|
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
|
// sndfile
|
||||||
//
|
//
|
||||||
|
@ -522,3 +685,12 @@ MIDIDevice *CreateFluidSynthMIDIDevice(int samplerate, const char *Args)
|
||||||
Fluid_SetupConfig(Args, fluid_patchset, true);
|
Fluid_SetupConfig(Args, fluid_patchset, true);
|
||||||
return new FluidSynthMIDIDevice(samplerate, fluid_patchset);
|
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,7 +35,6 @@
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
#include "mididevice.h"
|
#include "mididevice.h"
|
||||||
#include "zmusic/mus2midi.h"
|
#include "zmusic/mus2midi.h"
|
||||||
|
@ -334,4 +333,4 @@ MIDIDevice* CreateOplMIDIDevice(const char* Args)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("OPL device not supported in this configuration");
|
throw std::runtime_error("OPL device not supported in this configuration");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "mididevice.h"
|
#include "mididevice.h"
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
|
|
||||||
|
|
|
@ -88,19 +88,18 @@ SoftSynthMIDIDevice::~SoftSynthMIDIDevice()
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// SoftSynthMIDIDevice :: GetStreamInfoEx
|
// SoftSynthMIDIDevice :: GwrStreamInfo
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
SoundStreamInfoEx SoftSynthMIDIDevice::GetStreamInfoEx() const
|
SoundStreamInfo SoftSynthMIDIDevice::GetStreamInfo() const
|
||||||
{
|
{
|
||||||
int chunksize = (SampleRate / StreamBlockSize) * 4;
|
int chunksize = (SampleRate / StreamBlockSize) * 4;
|
||||||
if (!isMono)
|
if (!isMono)
|
||||||
{
|
{
|
||||||
chunksize *= 2;
|
chunksize *= 2;
|
||||||
}
|
}
|
||||||
return { chunksize, SampleRate, SampleType_Float32,
|
return { chunksize, SampleRate, isMono? 1:2 };
|
||||||
isMono ? ChannelConfig_Mono : ChannelConfig_Stereo };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "mididevice.h"
|
#include "mididevice.h"
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
|
@ -95,44 +94,42 @@ protected:
|
||||||
|
|
||||||
void TimidityMIDIDevice::LoadInstruments()
|
void TimidityMIDIDevice::LoadInstruments()
|
||||||
{
|
{
|
||||||
if (gusConfig.reader)
|
if (gusConfig.dmxgus.size())
|
||||||
{
|
{
|
||||||
// Check if we got some GUS data before using it.
|
// Check if we got some GUS data before using it.
|
||||||
std::string ultradir;
|
std::string ultradir = getenv("ULTRADIR");
|
||||||
const char *ret = getenv("ULTRADIR");
|
if (ultradir.length() || gusConfig.gus_patchdir.length() != 0)
|
||||||
if (ret) ultradir = std::string(ret);
|
|
||||||
// The GUS put its patches in %ULTRADIR%/MIDI so we can try that
|
|
||||||
if (ultradir.length())
|
|
||||||
{
|
{
|
||||||
ultradir += "/midi";
|
auto psreader = new MusicIO::FileSystemSoundFontReader("");
|
||||||
gusConfig.reader->add_search_path(ultradir.c_str());
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Load DMXGUS lump and patches from gus_patchdir
|
gusConfig.loadedConfig = "";
|
||||||
if (gusConfig.gus_patchdir.length() != 0) gusConfig.reader->add_search_path(gusConfig.gus_patchdir.c_str());
|
gusConfig.instruments.reset();
|
||||||
|
throw std::runtime_error("Unable to initialize DMXGUS for GUS MIDI device");
|
||||||
gusConfig.instruments.reset(new Timidity::Instruments(gusConfig.reader));
|
}
|
||||||
|
else if (gusConfig.reader)
|
||||||
|
{
|
||||||
gusConfig.loadedConfig = gusConfig.readerName;
|
gusConfig.loadedConfig = gusConfig.readerName;
|
||||||
}
|
gusConfig.instruments.reset(new Timidity::Instruments(gusConfig.reader));
|
||||||
|
|
||||||
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;
|
bool err = gusConfig.instruments->LoadConfig() < 0;
|
||||||
gusConfig.reader = nullptr;
|
gusConfig.reader = nullptr;
|
||||||
|
|
||||||
|
@ -143,6 +140,10 @@ void TimidityMIDIDevice::LoadInstruments()
|
||||||
throw std::runtime_error("Unable to initialize instruments for GUS MIDI device");
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -256,11 +257,20 @@ void TimidityMIDIDevice::ComputeOutput(float *buffer, int len)
|
||||||
|
|
||||||
bool GUS_SetupConfig(const char* args)
|
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 (*args == 0) args = gusConfig.gus_config.c_str();
|
||||||
if (gusConfig.gus_dmxgus && *args == 0) args = "DMXGUS";
|
if (stricmp(gusConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
||||||
//if (stricmp(gusConfig.loadedConfig.c_str(), args) == 0) return false; // aleady loaded
|
|
||||||
|
|
||||||
MusicIO::SoundFontReaderInterface* reader = MusicIO::ClientOpenSoundFont(args, SF_GUS);
|
MusicIO::SoundFontReaderInterface* reader = MusicIO::ClientOpenSoundFont(args, SF_GUS | SF_SF2);
|
||||||
if (!reader && MusicIO::fileExists(args))
|
if (!reader && MusicIO::fileExists(args))
|
||||||
{
|
{
|
||||||
auto f = MusicIO::utf8_fopen(args, "rb");
|
auto f = MusicIO::utf8_fopen(args, "rb");
|
||||||
|
@ -276,11 +286,6 @@ bool GUS_SetupConfig(const char* args)
|
||||||
if (!reader) reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
if (!reader) reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reader && gusConfig.gus_dmxgus)
|
|
||||||
{
|
|
||||||
reader = new MusicIO::FileSystemSoundFontReader(args, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader == nullptr)
|
if (reader == nullptr)
|
||||||
{
|
{
|
||||||
char error[80];
|
char error[80];
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "mididevice.h"
|
#include "mididevice.h"
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
|
|
||||||
|
@ -240,4 +239,4 @@ MIDIDevice* CreateTimidityPPMIDIDevice(const char* Args, int samplerate)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Timidity++ device not supported in this configuration");
|
throw std::runtime_error("Timidity++ device not supported in this configuration");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -38,7 +38,6 @@
|
||||||
#include "mididevice.h"
|
#include "mididevice.h"
|
||||||
#include "zmusic/m_swap.h"
|
#include "zmusic/m_swap.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include <stdexcept>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
@ -87,7 +86,7 @@ struct FmtChunk
|
||||||
MIDIWaveWriter::MIDIWaveWriter(const char *filename, SoftSynthMIDIDevice *playdevice)
|
MIDIWaveWriter::MIDIWaveWriter(const char *filename, SoftSynthMIDIDevice *playdevice)
|
||||||
: SoftSynthMIDIDevice(playdevice->GetSampleRate())
|
: SoftSynthMIDIDevice(playdevice->GetSampleRate())
|
||||||
{
|
{
|
||||||
File = MusicIO::utf8_fopen(filename, "wb");
|
File = MusicIO::utf8_fopen(filename, "wt");
|
||||||
playDevice = playdevice;
|
playDevice = playdevice;
|
||||||
if (File != nullptr)
|
if (File != nullptr)
|
||||||
{ // Write wave header
|
{ // Write wave header
|
||||||
|
@ -151,9 +150,9 @@ bool MIDIWaveWriter::CloseFile()
|
||||||
if (4 == fwrite(&size, 1, 4, File))
|
if (4 == fwrite(&size, 1, 4, File))
|
||||||
{
|
{
|
||||||
size = LittleLong(uint32_t(pos - 12 - sizeof(FmtChunk) - 8));
|
size = LittleLong(uint32_t(pos - 12 - sizeof(FmtChunk) - 8));
|
||||||
if (0 == fseek(File, 4 + sizeof(FmtChunk) + 8, SEEK_CUR))
|
if (0 == fseek(File, 4 + sizeof(FmtChunk) + 4, SEEK_CUR))
|
||||||
{
|
{
|
||||||
if (4 == fwrite(&size, 1, 4, File))
|
if (4 == fwrite(&size, 1, 5, File))
|
||||||
{
|
{
|
||||||
fclose(File);
|
fclose(File);
|
||||||
File = nullptr;
|
File = nullptr;
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "mididevice.h"
|
#include "mididevice.h"
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
|
|
||||||
|
@ -88,7 +87,15 @@ void WildMIDIDevice::LoadInstruments()
|
||||||
{
|
{
|
||||||
wildMidiConfig.loadedConfig = wildMidiConfig.readerName;
|
wildMidiConfig.loadedConfig = wildMidiConfig.readerName;
|
||||||
wildMidiConfig.instruments.reset(new WildMidi::Instruments(wildMidiConfig.reader, SampleRate));
|
wildMidiConfig.instruments.reset(new WildMidi::Instruments(wildMidiConfig.reader, SampleRate));
|
||||||
|
bool success = wildMidiConfig.instruments->LoadConfig(wildMidiConfig.readerName.c_str());
|
||||||
wildMidiConfig.reader = nullptr;
|
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)
|
else if (wildMidiConfig.instruments == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -97,9 +104,7 @@ void WildMIDIDevice::LoadInstruments()
|
||||||
instruments = wildMidiConfig.instruments;
|
instruments = wildMidiConfig.instruments;
|
||||||
if (instruments->LoadConfig(nullptr) < 0)
|
if (instruments->LoadConfig(nullptr) < 0)
|
||||||
{
|
{
|
||||||
wildMidiConfig.instruments.reset();
|
throw std::runtime_error("Unable to load instruments set for WildMidi device");
|
||||||
wildMidiConfig.loadedConfig = "";
|
|
||||||
throw std::runtime_error("Unable to initialize instruments for WildMidi device");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,4 +284,4 @@ MIDIDevice* CreateWildMIDIDevice(const char* Args, int samplerate)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("WildMidi device not supported in this configuration");
|
throw std::runtime_error("WildMidi device not supported in this configuration");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -39,7 +39,6 @@
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <stdexcept>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
|
@ -134,8 +134,8 @@ void MUSSong2::DoInitialSetup()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
{
|
{
|
||||||
LastVelocity[i] = 127;
|
LastVelocity[i] = 100;
|
||||||
ChannelVolumes[i] = 100;
|
ChannelVolumes[i] = 127;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,29 +178,16 @@ 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)
|
void MIDISong2::CheckCaps(int tech)
|
||||||
{
|
{
|
||||||
|
DesignationMask = 0xFF0F;
|
||||||
if (tech == MIDIDEV_FMSYNTH)
|
if (tech == MIDIDEV_FMSYNTH)
|
||||||
{
|
{
|
||||||
DesignationMask = 1 << EMIDI_Adlib;
|
DesignationMask = 0x00F0;
|
||||||
}
|
}
|
||||||
else
|
else if (tech == MIDIDEV_MIDIPORT)
|
||||||
{
|
{
|
||||||
DesignationMask = 1 << EMIDI_GeneralMIDI;
|
DesignationMask = 0x0001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,12 +443,7 @@ uint32_t *MIDISong2::SendCommand (uint32_t *events, TrackInfo *track, uint32_t d
|
||||||
case 111: // EMIDI Track Exclusion - InitBeat only
|
case 111: // EMIDI Track Exclusion - InitBeat only
|
||||||
if (track->PlayedTime < (uint32_t)Division)
|
if (track->PlayedTime < (uint32_t)Division)
|
||||||
{
|
{
|
||||||
if (!track->Designated)
|
if (track->Designated && data2 <= 9)
|
||||||
{
|
|
||||||
track->Designation = ~0;
|
|
||||||
track->Designated = true;
|
|
||||||
}
|
|
||||||
if (data2 <= 9)
|
|
||||||
{
|
{
|
||||||
track->Designation &= ~(1 << data2);
|
track->Designation &= ~(1 << data2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ public:
|
||||||
void Resume();
|
void Resume();
|
||||||
void Stop();
|
void Stop();
|
||||||
bool IsPlaying();
|
bool IsPlaying();
|
||||||
SoundStreamInfoEx GetStreamInfoEx() const override { return {}; }
|
|
||||||
bool IsValid() const { return m_Inited; }
|
bool IsValid() const { return m_Inited; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -34,9 +34,8 @@
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "zmusic/zmusic_internal.h"
|
#include "zmusic/zmusic_internal.h"
|
||||||
#include "zmusic/musinfo.h"
|
#include "zmusic/musinfo.h"
|
||||||
|
@ -88,7 +87,7 @@ public:
|
||||||
int ServiceEvent();
|
int ServiceEvent();
|
||||||
void SetMIDISource(MIDISource* _source);
|
void SetMIDISource(MIDISource* _source);
|
||||||
bool ServiceStream(void* buff, int len) override;
|
bool ServiceStream(void* buff, int len) override;
|
||||||
SoundStreamInfoEx GetStreamInfoEx() const override;
|
SoundStreamInfo GetStreamInfo() const override;
|
||||||
|
|
||||||
int GetDeviceType() const override;
|
int GetDeviceType() const override;
|
||||||
|
|
||||||
|
@ -447,10 +446,10 @@ bool MIDIStreamer::InitPlayback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundStreamInfoEx MIDIStreamer::GetStreamInfoEx() const
|
SoundStreamInfo MIDIStreamer::GetStreamInfo() const
|
||||||
{
|
{
|
||||||
if (MIDI) return MIDI->GetStreamInfoEx();
|
if (MIDI) return MIDI->GetStreamInfo();
|
||||||
else return {};
|
else return { 0, 0, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -815,7 +814,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
||||||
if (InitialPlayback)
|
if (InitialPlayback)
|
||||||
{
|
{
|
||||||
InitialPlayback = false;
|
InitialPlayback = false;
|
||||||
// Send the GM System Enable SysEx message.
|
// Send the GS System Reset SysEx message.
|
||||||
events[0] = 0; // dwDeltaTime
|
events[0] = 0; // dwDeltaTime
|
||||||
events[1] = 0; // dwStreamID
|
events[1] = 0; // dwStreamID
|
||||||
events[2] = (MEVENT_LONGMSG << 24) | 6; // dwEvent
|
events[2] = (MEVENT_LONGMSG << 24) | 6; // dwEvent
|
||||||
|
@ -823,15 +822,6 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
||||||
events[4] = MAKE_ID(0x01, 0xf7, 0x00, 0x00); // dwParms[1]
|
events[4] = MAKE_ID(0x01, 0xf7, 0x00, 0x00); // dwParms[1]
|
||||||
events += 5;
|
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.
|
// Send the full master volume SysEx message.
|
||||||
events[0] = 0; // dwDeltaTime
|
events[0] = 0; // dwDeltaTime
|
||||||
events[1] = 0; // dwStreamID
|
events[1] = 0; // dwStreamID
|
||||||
|
@ -1031,7 +1021,7 @@ DLL_EXPORT zmusic_bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MIDIStreamer me(devtype, devarg ? devarg : "");
|
MIDIStreamer me(devtype, devarg);
|
||||||
me.SetMIDISource(source);
|
me.SetMIDISource(source);
|
||||||
me.DumpWave(outname, subsong, samplerate);
|
me.DumpWave(outname, subsong, samplerate);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
void ChangeSettingNum(const char *name, double value) override { if (m_Source) m_Source->ChangeSettingNum(name, value); }
|
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); }
|
void ChangeSettingString(const char *name, const char *value) override { if(m_Source) m_Source->ChangeSettingString(name, value); }
|
||||||
bool ServiceStream(void* buff, int len) override;
|
bool ServiceStream(void* buff, int len) override;
|
||||||
SoundStreamInfoEx GetStreamInfoEx() const override { return m_Source->GetFormatEx(); }
|
SoundStreamInfo GetStreamInfo() const override { return m_Source->GetFormat(); }
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
//bool SetPosition(int ms);
|
//bool SetPosition(int ms);
|
||||||
bool SetSubsong(int subsong) override;
|
bool SetSubsong(int subsong) override;
|
||||||
bool Start() override;
|
bool Start() override;
|
||||||
SoundStreamInfoEx GetFormatEx() override;
|
SoundStreamInfo GetFormat() override;
|
||||||
void ChangeSettingNum(const char* setting, double val) override;
|
void ChangeSettingNum(const char* setting, double val) override;
|
||||||
std::string GetStats() override;
|
std::string GetStats() override;
|
||||||
|
|
||||||
|
@ -885,18 +885,6 @@ StreamSource* MOD_OpenSong(MusicIO::FileInterface *reader, int samplerate)
|
||||||
duh = dumb_read_okt_quick(f);
|
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 )
|
if ( ! duh )
|
||||||
{
|
{
|
||||||
|
@ -1016,7 +1004,7 @@ DumbSong::DumbSong(DUH* myduh, int samplerate)
|
||||||
written = 0;
|
written = 0;
|
||||||
length = 0;
|
length = 0;
|
||||||
start_order = 0;
|
start_order = 0;
|
||||||
MasterVolume = (float)dumbConfig.mod_dumb_mastervolume * 4;
|
MasterVolume = (float)dumbConfig.mod_dumb_mastervolume;
|
||||||
if (dumbConfig.mod_samplerate != 0)
|
if (dumbConfig.mod_samplerate != 0)
|
||||||
{
|
{
|
||||||
srate = dumbConfig.mod_samplerate;
|
srate = dumbConfig.mod_samplerate;
|
||||||
|
@ -1042,13 +1030,13 @@ DumbSong::~DumbSong()
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DumbSong GetFormatEx
|
// DumbSong GetFormat
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
SoundStreamInfoEx DumbSong::GetFormatEx()
|
SoundStreamInfo DumbSong::GetFormat()
|
||||||
{
|
{
|
||||||
return { 32*1024, srate, SampleType_Float32, ChannelConfig_Stereo };
|
return { 32*1024, srate, 2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -38,11 +38,9 @@
|
||||||
//#define GME_DLL
|
//#define GME_DLL
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <mutex>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include "streamsource.h"
|
#include "streamsource.h"
|
||||||
#include <gme/gme.h>
|
#include <gme/gme.h>
|
||||||
|
#include <mutex>
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
@ -59,7 +57,7 @@ public:
|
||||||
void ChangeSettingNum(const char *name, double val) override;
|
void ChangeSettingNum(const char *name, double val) override;
|
||||||
std::string GetStats() override;
|
std::string GetStats() override;
|
||||||
bool GetData(void *buffer, size_t len) override;
|
bool GetData(void *buffer, size_t len) override;
|
||||||
SoundStreamInfoEx GetFormatEx() override;
|
SoundStreamInfo GetFormat() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Music_Emu *Emu;
|
Music_Emu *Emu;
|
||||||
|
@ -169,9 +167,9 @@ GMESong::GMESong(Music_Emu *emu, int sample_rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SoundStreamInfoEx GMESong::GetFormatEx()
|
SoundStreamInfo GMESong::GetFormat()
|
||||||
{
|
{
|
||||||
return { 32*1024, SampleRate, SampleType_Int16, ChannelConfig_Stereo };
|
return { 32*1024, SampleRate, -2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -50,13 +50,14 @@ public:
|
||||||
SndFileSong(SoundDecoder *decoder, uint32_t loop_start, uint32_t loop_end, bool startass, bool endass);
|
SndFileSong(SoundDecoder *decoder, uint32_t loop_start, uint32_t loop_end, bool startass, bool endass);
|
||||||
~SndFileSong();
|
~SndFileSong();
|
||||||
std::string GetStats() override;
|
std::string GetStats() override;
|
||||||
SoundStreamInfoEx GetFormatEx() override;
|
SoundStreamInfo GetFormat() override;
|
||||||
bool GetData(void *buffer, size_t len) override;
|
bool GetData(void *buffer, size_t len) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SoundDecoder *Decoder;
|
SoundDecoder *Decoder;
|
||||||
unsigned int FrameSize;
|
int Channels;
|
||||||
|
int SampleRate;
|
||||||
|
|
||||||
uint32_t Loop_Start;
|
uint32_t Loop_Start;
|
||||||
uint32_t Loop_End;
|
uint32_t Loop_End;
|
||||||
|
|
||||||
|
@ -433,30 +434,25 @@ 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)
|
SndFileSong::SndFileSong(SoundDecoder *decoder, uint32_t loop_start, uint32_t loop_end, bool startass, bool endass)
|
||||||
{
|
{
|
||||||
ChannelConfig chanconf;
|
ChannelConfig iChannels;
|
||||||
SampleType stype;
|
SampleType Type;
|
||||||
int srate;
|
|
||||||
|
decoder->getInfo(&SampleRate, &iChannels, &Type);
|
||||||
|
|
||||||
decoder->getInfo(&srate, &chanconf, &stype);
|
if (!startass) loop_start = Scale(loop_start, SampleRate, 1000);
|
||||||
|
if (!endass) loop_end = Scale(loop_end, SampleRate, 1000);
|
||||||
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();
|
const uint32_t sampleLength = (uint32_t)decoder->getSampleLength();
|
||||||
Loop_Start = loop_start;
|
Loop_Start = loop_start;
|
||||||
Loop_End = sampleLength == 0 ? loop_end : std::min<uint32_t>(loop_end, sampleLength);
|
Loop_End = sampleLength == 0 ? loop_end : std::min<uint32_t>(loop_end, sampleLength);
|
||||||
Decoder = decoder;
|
Decoder = decoder;
|
||||||
FrameSize = ZMusic_ChannelCount(chanconf) * ZMusic_SampleTypeSize(stype);
|
Channels = iChannels == ChannelConfig_Stereo? 2:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundStreamInfoEx SndFileSong::GetFormatEx()
|
SoundStreamInfo SndFileSong::GetFormat()
|
||||||
{
|
{
|
||||||
ChannelConfig chanconf;
|
// deal with this once the configuration is handled better.
|
||||||
SampleType stype;
|
return { 64/*snd_streambuffersize*/ * 1024, SampleRate, -Channels };
|
||||||
int srate;
|
|
||||||
|
|
||||||
Decoder->getInfo(&srate, &chanconf, &stype);
|
|
||||||
return { 64/*snd_streambuffersize*/ * 1024, srate, stype, chanconf };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -483,17 +479,14 @@ std::string SndFileSong::GetStats()
|
||||||
{
|
{
|
||||||
char out[80];
|
char out[80];
|
||||||
|
|
||||||
ChannelConfig chanconf;
|
size_t SamplePos;
|
||||||
SampleType stype;
|
|
||||||
int srate;
|
|
||||||
Decoder->getInfo(&srate, &chanconf, &stype);
|
|
||||||
|
|
||||||
size_t SamplePos = Decoder->getSampleOffset();
|
SamplePos = Decoder->getSampleOffset();
|
||||||
int time = int (SamplePos / srate);
|
int time = int (SamplePos / SampleRate);
|
||||||
|
|
||||||
snprintf(out, 80,
|
snprintf(out, 80,
|
||||||
"Track: %s, %dHz Time: %02d:%02d",
|
"Track: %s, %dHz Time: %02d:%02d",
|
||||||
ZMusic_ChannelConfigName(chanconf), srate,
|
Channels == 2? "Stereo" : "Mono", SampleRate,
|
||||||
time/60,
|
time/60,
|
||||||
time % 60);
|
time % 60);
|
||||||
return out;
|
return out;
|
||||||
|
@ -510,7 +503,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
||||||
char *buff = (char*)vbuff;
|
char *buff = (char*)vbuff;
|
||||||
|
|
||||||
size_t currentpos = Decoder->getSampleOffset();
|
size_t currentpos = Decoder->getSampleOffset();
|
||||||
size_t framestoread = len / FrameSize;
|
size_t framestoread = len / (Channels*2);
|
||||||
bool err = false;
|
bool err = false;
|
||||||
if (!m_Looping)
|
if (!m_Looping)
|
||||||
{
|
{
|
||||||
|
@ -522,7 +515,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
||||||
}
|
}
|
||||||
if (currentpos + framestoread > maxpos)
|
if (currentpos + framestoread > maxpos)
|
||||||
{
|
{
|
||||||
size_t got = Decoder->read(buff, (maxpos - currentpos) * FrameSize);
|
size_t got = Decoder->read(buff, (maxpos - currentpos) * Channels * 2);
|
||||||
memset(buff + got, 0, len - got);
|
memset(buff + got, 0, len - got);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -539,7 +532,7 @@ bool SndFileSong::GetData(void *vbuff, size_t len)
|
||||||
// Loop can be very short, make sure the current position doesn't exceed it
|
// Loop can be very short, make sure the current position doesn't exceed it
|
||||||
if (currentpos < Loop_End)
|
if (currentpos < Loop_End)
|
||||||
{
|
{
|
||||||
size_t endblock = (Loop_End - currentpos) * FrameSize;
|
size_t endblock = (Loop_End - currentpos) * Channels * 2;
|
||||||
size_t endlen = Decoder->read(buff, endblock);
|
size_t endlen = Decoder->read(buff, endblock);
|
||||||
|
|
||||||
// Even if zero bytes was read give it a chance to start from the beginning
|
// Even if zero bytes was read give it a chance to start from the beginning
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
/*
|
|
||||||
** 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,8 +35,6 @@
|
||||||
|
|
||||||
#ifdef HAVE_OPL
|
#ifdef HAVE_OPL
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include "streamsource.h"
|
#include "streamsource.h"
|
||||||
#include "oplsynth/opl.h"
|
#include "oplsynth/opl.h"
|
||||||
#include "oplsynth/opl_mus_player.h"
|
#include "oplsynth/opl_mus_player.h"
|
||||||
|
@ -56,7 +54,7 @@ public:
|
||||||
~OPLMUSSong ();
|
~OPLMUSSong ();
|
||||||
bool Start() override;
|
bool Start() override;
|
||||||
void ChangeSettingInt(const char *name, int value) override;
|
void ChangeSettingInt(const char *name, int value) override;
|
||||||
SoundStreamInfoEx GetFormatEx() override;
|
SoundStreamInfo GetFormat() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool GetData(void *buffer, size_t len) override;
|
bool GetData(void *buffer, size_t len) override;
|
||||||
|
@ -95,11 +93,10 @@ OPLMUSSong::OPLMUSSong(MusicIO::FileInterface* reader, OPLConfig* config)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
SoundStreamInfoEx OPLMUSSong::GetFormatEx()
|
SoundStreamInfo OPLMUSSong::GetFormat()
|
||||||
{
|
{
|
||||||
int samples = int(OPL_SAMPLE_RATE / 14);
|
int samples = int(OPL_SAMPLE_RATE / 14);
|
||||||
return { samples * 4, int(OPL_SAMPLE_RATE), SampleType_Float32,
|
return { samples * 4, int(OPL_SAMPLE_RATE), current_opl_core == 0? 1:2 };
|
||||||
current_opl_core == 0? ChannelConfig_Mono:ChannelConfig_Stereo };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -235,7 +235,7 @@ class XASong : public StreamSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XASong(MusicIO::FileInterface *readr);
|
XASong(MusicIO::FileInterface *readr);
|
||||||
SoundStreamInfoEx GetFormatEx() override;
|
SoundStreamInfo GetFormat() override;
|
||||||
bool Start() override;
|
bool Start() override;
|
||||||
bool GetData(void *buffer, size_t len) override;
|
bool GetData(void *buffer, size_t len) override;
|
||||||
|
|
||||||
|
@ -260,10 +260,10 @@ XASong::XASong(MusicIO::FileInterface * reader)
|
||||||
getNextXABlock(&xad, false);
|
getNextXABlock(&xad, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundStreamInfoEx XASong::GetFormatEx()
|
SoundStreamInfo XASong::GetFormat()
|
||||||
{
|
{
|
||||||
auto SampleRate = xad.blockIs18K? 18900 : 37800;
|
auto SampleRate = xad.blockIs18K? 18900 : 37800;
|
||||||
return { 64*1024, SampleRate, SampleType_Float32, ChannelConfig_Stereo };
|
return { 64*1024, SampleRate, 2};
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
virtual bool SetPosition(unsigned position) { return false; }
|
virtual bool SetPosition(unsigned position) { return false; }
|
||||||
virtual bool SetSubsong(int subsong) { return false; }
|
virtual bool SetSubsong(int subsong) { return false; }
|
||||||
virtual bool GetData(void *buffer, size_t len) = 0;
|
virtual bool GetData(void *buffer, size_t len) = 0;
|
||||||
virtual SoundStreamInfoEx GetFormatEx() = 0;
|
virtual SoundStreamInfo GetFormat() { return {65536, m_OutputRate, 2 }; } // Default format is: System's output sample rate, 32 bit float, stereo
|
||||||
virtual std::string GetStats() { return ""; }
|
virtual std::string GetStats() { return ""; }
|
||||||
virtual void ChangeSettingInt(const char *name, int value) { }
|
virtual void ChangeSettingInt(const char *name, int value) { }
|
||||||
virtual void ChangeSettingNum(const char *name, double value) { }
|
virtual void ChangeSettingNum(const char *name, double value) { }
|
||||||
|
@ -33,7 +33,6 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
StreamSource *MOD_OpenSong(MusicIO::FileInterface* reader, int samplerate);
|
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* GME_OpenSong(MusicIO::FileInterface* reader, const char* fmt, int sample_rate);
|
||||||
StreamSource *SndFile_OpenSong(MusicIO::FileInterface* fr);
|
StreamSource *SndFile_OpenSong(MusicIO::FileInterface* fr);
|
||||||
StreamSource* XA_OpenSong(MusicIO::FileInterface* reader);
|
StreamSource* XA_OpenSong(MusicIO::FileInterface* reader);
|
||||||
|
|
|
@ -197,9 +197,9 @@ struct MidiDeviceList
|
||||||
#ifdef HAVE_WILDMIDI
|
#ifdef HAVE_WILDMIDI
|
||||||
devices.push_back({ strdup("WildMidi"), -6, MIDIDEV_SWSYNTH });
|
devices.push_back({ strdup("WildMidi"), -6, MIDIDEV_SWSYNTH });
|
||||||
#endif
|
#endif
|
||||||
// this will always exist.
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
devices.push_back({ strdup("FluidSynth"), -5, MIDIDEV_SWSYNTH });
|
devices.push_back({ strdup("FluidSynth"), -5, MIDIDEV_SWSYNTH });
|
||||||
|
#endif
|
||||||
#ifdef HAVE_GUS
|
#ifdef HAVE_GUS
|
||||||
devices.push_back({ strdup("GUS Emulation"), -4, MIDIDEV_SWSYNTH });
|
devices.push_back({ strdup("GUS Emulation"), -4, MIDIDEV_SWSYNTH });
|
||||||
#endif
|
#endif
|
||||||
|
@ -503,7 +503,7 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSon
|
||||||
|
|
||||||
case zmusic_gus_memsize:
|
case zmusic_gus_memsize:
|
||||||
ChangeAndReturn(gusConfig.gus_memsize, value, pRealValue);
|
ChangeAndReturn(gusConfig.gus_memsize, value, pRealValue);
|
||||||
return devType() == MDEV_GUS;
|
return devType() == MDEV_GUS && gusConfig.gus_dmxgus;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_TIMIDITY
|
#ifdef HAVE_TIMIDITY
|
||||||
case zmusic_timidity_modulation_wheel:
|
case zmusic_timidity_modulation_wheel:
|
||||||
|
@ -518,15 +518,15 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSon
|
||||||
|
|
||||||
case zmusic_timidity_reverb:
|
case zmusic_timidity_reverb:
|
||||||
if (value < 0 || value > 4) value = 0;
|
if (value < 0 || value > 4) value = 0;
|
||||||
|
else TimidityPlus_SetReverb();
|
||||||
local_timidity_reverb = value;
|
local_timidity_reverb = value;
|
||||||
TimidityPlus_SetReverb();
|
|
||||||
if (pRealValue) *pRealValue = value;
|
if (pRealValue) *pRealValue = value;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case zmusic_timidity_reverb_level:
|
case zmusic_timidity_reverb_level:
|
||||||
if (value < 0 || value > 127) value = 0;
|
if (value < 0 || value > 127) value = 0;
|
||||||
|
else TimidityPlus_SetReverb();
|
||||||
local_timidity_reverb_level = value;
|
local_timidity_reverb_level = value;
|
||||||
TimidityPlus_SetReverb();
|
|
||||||
if (pRealValue) *pRealValue = value;
|
if (pRealValue) *pRealValue = value;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -652,10 +652,6 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, MusInfo *currSon
|
||||||
miscConfig.snd_outputrate = value;
|
miscConfig.snd_outputrate = value;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case zmusic_mod_preferredplayer:
|
|
||||||
dumbConfig.mod_preferred_player = value;
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -682,8 +678,8 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* cur
|
||||||
case zmusic_fluid_reverb_roomsize:
|
case zmusic_fluid_reverb_roomsize:
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
value = 0;
|
value = 0;
|
||||||
else if (value > 1.0f)
|
else if (value > 1.2f)
|
||||||
value = 1.0f;
|
value = 1.2f;
|
||||||
|
|
||||||
if (currSong != NULL)
|
if (currSong != NULL)
|
||||||
currSong->ChangeSettingNum("fluidsynth.z.reverb", value);
|
currSong->ChangeSettingNum("fluidsynth.z.reverb", value);
|
||||||
|
@ -740,8 +736,8 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* cur
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case zmusic_fluid_chorus_speed:
|
case zmusic_fluid_chorus_speed:
|
||||||
if (value < 0.1f)
|
if (value < 0.29f)
|
||||||
value = 0.1f;
|
value = 0.29f;
|
||||||
else if (value > 5)
|
else if (value > 5)
|
||||||
value = 5;
|
value = 5;
|
||||||
|
|
||||||
|
@ -755,8 +751,8 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, MusInfo* cur
|
||||||
case zmusic_fluid_chorus_depth:
|
case zmusic_fluid_chorus_depth:
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
value = 0;
|
value = 0;
|
||||||
else if (value > 256)
|
else if (value > 21)
|
||||||
value = 256;
|
value = 21;
|
||||||
|
|
||||||
if (currSong != NULL)
|
if (currSong != NULL)
|
||||||
currSong->ChangeSettingNum("fluidsynth.z.chorus", value);
|
currSong->ChangeSettingNum("fluidsynth.z.chorus", value);
|
||||||
|
@ -860,7 +856,7 @@ DLL_EXPORT zmusic_bool ChangeMusicSettingString(EStringConfigKey key, MusInfo* c
|
||||||
#ifdef HAVE_WILDMIDI
|
#ifdef HAVE_WILDMIDI
|
||||||
case zmusic_wildmidi_config:
|
case zmusic_wildmidi_config:
|
||||||
wildMidiConfig.config = value;
|
wildMidiConfig.config = value;
|
||||||
return devType() == MDEV_WILDMIDI;
|
return devType() == MDEV_TIMIDITY;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -946,7 +942,6 @@ static ZMusicConfigurationSetting config[] = {
|
||||||
{"zmusic_mod_autochip_size_force", zmusic_mod_autochip_size_force, ZMUSIC_VAR_INT, 100},
|
{"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_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_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_mod_dumb_mastervolume", zmusic_mod_dumb_mastervolume, ZMUSIC_VAR_FLOAT, 1},
|
||||||
|
|
||||||
{"zmusic_gme_stereodepth", zmusic_gme_stereodepth, ZMUSIC_VAR_FLOAT, 0},
|
{"zmusic_gme_stereodepth", zmusic_gme_stereodepth, ZMUSIC_VAR_FLOAT, 0},
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <cstdint>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -221,9 +220,6 @@ struct VectorReader : public MemoryReader
|
||||||
{
|
{
|
||||||
mVector.resize(size);
|
mVector.resize(size);
|
||||||
memcpy(mVector.data(), data, size);
|
memcpy(mVector.data(), data, size);
|
||||||
mData = mVector.data();
|
|
||||||
mLength = (long)size;
|
|
||||||
mPos = 0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -324,7 +320,7 @@ public:
|
||||||
std::string fullname;
|
std::string fullname;
|
||||||
if (!fn)
|
if (!fn)
|
||||||
{
|
{
|
||||||
f = utf8_fopen(mBaseFile.c_str(), "rb");
|
f = utf8_fopen(mBaseFile.c_str(), "rt");
|
||||||
fullname = mBaseFile;
|
fullname = mBaseFile;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -334,11 +330,11 @@ public:
|
||||||
for(int i = (int)mPaths.size()-1; i>=0; i--)
|
for(int i = (int)mPaths.size()-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
fullname = mPaths[i] + fn;
|
fullname = mPaths[i] + fn;
|
||||||
f = utf8_fopen(fullname.c_str(), "rb");
|
f = utf8_fopen(fullname.c_str(), "rt");
|
||||||
if (f) break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!f) f = fopen(fn, "rb");
|
if (!f) f = fopen(fn, "rt");
|
||||||
}
|
}
|
||||||
if (!f) return nullptr;
|
if (!f) return nullptr;
|
||||||
auto tf = new StdioFileReader;
|
auto tf = new StdioFileReader;
|
||||||
|
|
|
@ -129,7 +129,6 @@ struct DumbConfig
|
||||||
int mod_autochip_size_force = 100;
|
int mod_autochip_size_force = 100;
|
||||||
int mod_autochip_size_scan = 500;
|
int mod_autochip_size_scan = 500;
|
||||||
int mod_autochip_scan_threshold = 12;
|
int mod_autochip_scan_threshold = 12;
|
||||||
int mod_preferred_player = 0;
|
|
||||||
float mod_dumb_mastervolume = 1;
|
float mod_dumb_mastervolume = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
virtual void ChangeSettingNum(const char* setting, double value) {} // "
|
virtual void ChangeSettingNum(const char* setting, double value) {} // "
|
||||||
virtual void ChangeSettingString(const char* setting, const char* value) {} // "
|
virtual void ChangeSettingString(const char* setting, const char* value) {} // "
|
||||||
virtual bool ServiceStream(void *buff, int len) { return false; }
|
virtual bool ServiceStream(void *buff, int len) { return false; }
|
||||||
virtual SoundStreamInfoEx GetStreamInfoEx() const = 0;
|
virtual SoundStreamInfo GetStreamInfo() const { return { 0,0,0 }; }
|
||||||
|
|
||||||
enum EState
|
enum EState
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <miniz.h>
|
#include <zlib.h>
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
#include "zmusic_internal.h"
|
#include "zmusic_internal.h"
|
||||||
#include "midiconfig.h"
|
#include "midiconfig.h"
|
||||||
|
@ -257,27 +257,9 @@ static MusInfo *ZMusic_OpenSongInternal (MusicIO::FileInterface *reader, EMidiD
|
||||||
streamsource = GME_OpenSong(reader, fmt, miscConfig.snd_outputrate);
|
streamsource = GME_OpenSong(reader, fmt, miscConfig.snd_outputrate);
|
||||||
}
|
}
|
||||||
// Check for module formats
|
// Check for module formats
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
// give the calling app an option to select between XMP and DUMB.
|
streamsource = MOD_OpenSong(reader, miscConfig.snd_outputrate);
|
||||||
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)
|
if (streamsource == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -458,12 +440,6 @@ DLL_EXPORT zmusic_bool ZMusic_IsLooping(MusInfo *song)
|
||||||
return song->m_Looping;
|
return song->m_Looping;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT int ZMusic_GetDeviceType(MusInfo* song)
|
|
||||||
{
|
|
||||||
if (!song) return false;
|
|
||||||
return song->GetDeviceType();
|
|
||||||
}
|
|
||||||
|
|
||||||
DLL_EXPORT zmusic_bool ZMusic_IsMIDI(MusInfo *song)
|
DLL_EXPORT zmusic_bool ZMusic_IsMIDI(MusInfo *song)
|
||||||
{
|
{
|
||||||
if (!song) return false;
|
if (!song) return false;
|
||||||
|
@ -471,34 +447,11 @@ DLL_EXPORT zmusic_bool ZMusic_IsMIDI(MusInfo *song)
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT void ZMusic_GetStreamInfo(MusInfo *song, SoundStreamInfo *fmt)
|
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 (!fmt) return;
|
||||||
if (!song) *fmt = {};
|
if (!song) *fmt = {};
|
||||||
std::lock_guard<FCriticalSection> lock(song->CritSec);
|
std::lock_guard<FCriticalSection> lock(song->CritSec);
|
||||||
*fmt = song->GetStreamInfoEx();
|
*fmt = song->GetStreamInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT void ZMusic_Close(MusInfo *song)
|
DLL_EXPORT void ZMusic_Close(MusInfo *song)
|
||||||
|
@ -544,6 +497,6 @@ DLL_EXPORT zmusic_bool ZMusic_WriteSMF(MIDISource* source, const char *fn, int l
|
||||||
auto f = MusicIO::utf8_fopen(fn, "wt");
|
auto f = MusicIO::utf8_fopen(fn, "wt");
|
||||||
if (f == nullptr) return false;
|
if (f == nullptr) return false;
|
||||||
success = (fwrite(&midi[0], 1, midi.size(), f) == midi.size());
|
success = (fwrite(&midi[0], 1, midi.size(), f) == midi.size());
|
||||||
fclose(f);
|
delete f;
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define ZMUSIC_INTERNAL
|
#define ZMUSIC_INTERNAL
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(ZMUSIC_STATIC)
|
#ifdef _MSC_VER
|
||||||
#define DLL_EXPORT __declspec(dllexport)
|
#define DLL_EXPORT __declspec(dllexport)
|
||||||
#define DLL_IMPORT __declspec(dllexport) // without this the compiler complains.
|
#define DLL_IMPORT __declspec(dllexport) // without this the compiler complains.
|
||||||
#else
|
#else // !_MSC_VER
|
||||||
#define DLL_EXPORT
|
#define DLL_EXPORT
|
||||||
#define DLL_IMPORT
|
#define DLL_IMPORT
|
||||||
#endif
|
#endif // _MSC_VER
|
||||||
|
|
||||||
typedef class MIDISource *ZMusic_MidiSource;
|
typedef class MIDISource *ZMusic_MidiSource;
|
||||||
typedef class MusInfo *ZMusic_MusicStream;
|
typedef class MusInfo *ZMusic_MusicStream;
|
||||||
|
@ -49,34 +49,3 @@ struct CustomFileReader : public MusicIO::FileInterface
|
||||||
|
|
||||||
|
|
||||||
void ZMusic_Printf(int type, const char* msg, ...);
|
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,4 +1,20 @@
|
||||||
add_subdirectory(miniz)
|
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()
|
||||||
|
|
||||||
# GME is not currently released in a way that's conducive to using as a system
|
# 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
|
# 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
|
# system copy exists soley to placate people following distro guidelines to the
|
||||||
|
@ -15,7 +31,7 @@ add_subdirectory(miniz)
|
||||||
# message(STATUS "Using internal gme library")
|
# message(STATUS "Using internal gme library")
|
||||||
# Use MAME as it's a balanced emulator: well-accurate, but doesn't eats lot of CPU
|
# 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
|
# Nuked OPN2 is very accurate emulator, but it eats too much CPU for the workflow
|
||||||
set(GME_YM2612_EMU "Nuked" CACHE STRING "Which YM2612 emulator to use: \"Nuked\" (LGPLv2.1+), \"MAME\" (GPLv2+), or \"GENS\" (LGPLv2.1+)")
|
set(GME_YM2612_EMU "MAME" CACHE STRING "Which YM2612 emulator to use: \"Nuked\" (LGPLv2.1+), \"MAME\" (GPLv2+), or \"GENS\" (LGPLv2.1+)")
|
||||||
mark_as_advanced(GME_YM2612_EMU)
|
mark_as_advanced(GME_YM2612_EMU)
|
||||||
add_subdirectory(game-music-emu)
|
add_subdirectory(game-music-emu)
|
||||||
#endif()
|
#endif()
|
||||||
|
@ -27,5 +43,3 @@ add_subdirectory(timidity)
|
||||||
add_subdirectory(timidityplus)
|
add_subdirectory(timidityplus)
|
||||||
add_subdirectory(wildmidi)
|
add_subdirectory(wildmidi)
|
||||||
add_subdirectory(oplsynth)
|
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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -551,24 +551,6 @@ ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, in
|
||||||
play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0);
|
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)
|
ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
|
||||||
{
|
{
|
||||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
||||||
|
@ -583,34 +565,6 @@ ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
|
||||||
#endif
|
#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)
|
ADLMIDI_EXPORT void adl_setSoftPanEnabled(ADL_MIDIPlayer *device, int softPanEn)
|
||||||
{
|
{
|
||||||
if(!device)
|
if(!device)
|
||||||
|
@ -664,29 +618,6 @@ ADLMIDI_EXPORT int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device)
|
||||||
return play->m_synth->getVolumeScaleModel();
|
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)
|
ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath)
|
||||||
{
|
{
|
||||||
if(device)
|
if(device)
|
||||||
|
@ -785,35 +716,6 @@ ADLMIDI_EXPORT int adl_openData(ADL_MIDIPlayer *device, const void *mem, unsigne
|
||||||
return -1;
|
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()
|
ADLMIDI_EXPORT const char *adl_emulatorName()
|
||||||
{
|
{
|
||||||
|
@ -1181,36 +1083,6 @@ ADLMIDI_EXPORT void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_D
|
||||||
#endif
|
#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 ADLMIDI_HW_OPL
|
||||||
|
|
||||||
# ifndef __WATCOMC__
|
# ifndef __WATCOMC__
|
||||||
|
@ -1438,69 +1310,74 @@ ADLMIDI_EXPORT int adl_playFormat(ADL_MIDIPlayer *device, int sampleCount,
|
||||||
|
|
||||||
while(left > 0)
|
while(left > 0)
|
||||||
{
|
{
|
||||||
const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
|
{//...
|
||||||
if(hasSkipped)
|
if(setup.delay <= 0.0)
|
||||||
{
|
setup.delay = double(left / 2) / double(setup.PCM_RATE);
|
||||||
size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay;
|
const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
|
||||||
n_periodCountStereo = samples / 2;
|
if(hasSkipped)
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
setup.tick_skip_samples_delay = (n_periodCountStereo - leftSamples) * 2;
|
size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay;
|
||||||
n_periodCountStereo = leftSamples;
|
n_periodCountStereo = samples / 2;
|
||||||
}
|
}
|
||||||
//! Count of stereo samples
|
else
|
||||||
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);
|
setup.delay -= eat_delay;
|
||||||
}
|
setup.carry += double(setup.PCM_RATE) * eat_delay;
|
||||||
else if(n_periodCountStereo > 0)
|
n_periodCountStereo = static_cast<ssize_t>(setup.carry);
|
||||||
{
|
setup.carry -= double(n_periodCountStereo);
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process it */
|
//if(setup.SkipForward > 0)
|
||||||
if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
|
// setup.SkipForward -= 1;
|
||||||
return 0;
|
//else
|
||||||
|
{
|
||||||
|
if((player->m_sequencer->positionAtEnd()) && (setup.delay <= 0.0))
|
||||||
|
break;//Stop to fetch samples at reaching the song end with disabled loop
|
||||||
|
|
||||||
left -= (int)in_generatedPhys;
|
ssize_t leftSamples = left / 2;
|
||||||
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
if(hasSkipped)
|
/* Process it */
|
||||||
{
|
if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
|
||||||
setup.tick_skip_samples_delay -= n_periodCountStereo * 2;
|
return 0;
|
||||||
hasSkipped = setup.tick_skip_samples_delay > 0;
|
|
||||||
}
|
left -= (int)in_generatedPhys;
|
||||||
else
|
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
|
||||||
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);
|
return static_cast<int>(gotten_len);
|
||||||
|
@ -1543,45 +1420,47 @@ ADLMIDI_EXPORT int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleC
|
||||||
|
|
||||||
while(left > 0)
|
while(left > 0)
|
||||||
{
|
{
|
||||||
if(delay <= 0.0)
|
{//...
|
||||||
delay = double(left / 2) / double(setup.PCM_RATE);
|
if(delay <= 0.0)
|
||||||
const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
|
delay = double(left / 2) / double(setup.PCM_RATE);
|
||||||
delay -= eat_delay;
|
const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
|
||||||
setup.carry += double(setup.PCM_RATE) * eat_delay;
|
delay -= eat_delay;
|
||||||
n_periodCountStereo = static_cast<ssize_t>(setup.carry);
|
setup.carry += double(setup.PCM_RATE) * eat_delay;
|
||||||
setup.carry -= double(n_periodCountStereo);
|
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)
|
|
||||||
{
|
{
|
||||||
/* Generate data from every chip and mix result */
|
ssize_t leftSamples = left / 2;
|
||||||
for(unsigned card = 0; card < chips; ++card)
|
if(n_periodCountStereo > leftSamples)
|
||||||
synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
|
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*/;
|
||||||
}
|
}
|
||||||
/* Process it */
|
|
||||||
if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
left -= (int)in_generatedPhys;
|
player->TickIterators(eat_delay);
|
||||||
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
|
}//...
|
||||||
}
|
|
||||||
|
|
||||||
player->TickIterators(eat_delay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<int>(gotten_len);
|
return static_cast<int>(gotten_len);
|
||||||
|
@ -1673,27 +1552,6 @@ ADLMIDI_EXPORT int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t tra
|
||||||
#endif
|
#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)
|
ADLMIDI_EXPORT int adl_setTriggerHandler(struct ADL_MIDIPlayer *device, ADL_TriggerHandler handler, void *userData)
|
||||||
{
|
{
|
||||||
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
|
#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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -30,7 +30,7 @@ extern "C" {
|
||||||
|
|
||||||
#define ADLMIDI_VERSION_MAJOR 1
|
#define ADLMIDI_VERSION_MAJOR 1
|
||||||
#define ADLMIDI_VERSION_MINOR 5
|
#define ADLMIDI_VERSION_MINOR 5
|
||||||
#define ADLMIDI_VERSION_PATCHLEVEL 1
|
#define ADLMIDI_VERSION_PATCHLEVEL 0
|
||||||
|
|
||||||
#define ADLMIDI_TOSTR_I(s) #s
|
#define ADLMIDI_TOSTR_I(s) #s
|
||||||
#define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s)
|
#define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s)
|
||||||
|
@ -125,26 +125,7 @@ enum ADLMIDI_VolumeModels
|
||||||
/*! HMI Sound Operating System volume scaling model */
|
/*! HMI Sound Operating System volume scaling model */
|
||||||
ADLMIDI_VolumeModel_HMI = 10,
|
ADLMIDI_VolumeModel_HMI = 10,
|
||||||
/*! HMI Sound Operating System volume scaling model, older variant with bugs */
|
/*! 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -567,21 +548,6 @@ extern ADLMIDI_DECLSPEC void adl_setScaleModulators(struct ADL_MIDIPlayer *devic
|
||||||
*/
|
*/
|
||||||
extern ADLMIDI_DECLSPEC void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness);
|
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)
|
* @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
|
* @param device Instance of the library
|
||||||
|
@ -589,23 +555,6 @@ extern ADLMIDI_DECLSPEC int adl_getAutoArpeggio(struct ADL_MIDIPlayer *device);
|
||||||
*/
|
*/
|
||||||
extern ADLMIDI_DECLSPEC void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn);
|
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
|
* @brief Enable or disable soft panning with chip emulators
|
||||||
* @param device Instance of the library
|
* @param device Instance of the library
|
||||||
|
@ -635,20 +584,6 @@ extern ADLMIDI_DECLSPEC void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *devi
|
||||||
*/
|
*/
|
||||||
extern ADLMIDI_DECLSPEC int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device);
|
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
|
* @brief Load WOPL bank file from File System
|
||||||
*
|
*
|
||||||
|
@ -831,27 +766,6 @@ 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);
|
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
|
* @brief Resets MIDI player (per-channel setup) into initial state
|
||||||
* @param device Instance of the library
|
* @param device Instance of the library
|
||||||
|
@ -962,15 +876,6 @@ enum ADLMIDI_TrackOptions
|
||||||
*/
|
*/
|
||||||
extern ADLMIDI_DECLSPEC int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned 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
|
* @brief Handler of callback trigger events
|
||||||
* @param userData Pointer to user data (usually, context of something)
|
* @param userData Pointer to user data (usually, context of something)
|
||||||
|
@ -1305,19 +1210,8 @@ typedef void (*ADL_NoteHook)(void *userdata, int adlchn, int note, int ins, int
|
||||||
*/
|
*/
|
||||||
typedef void (*ADL_DebugMessageHook)(void *userdata, const char *fmt, ...);
|
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
|
* @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 device Instance of the library
|
||||||
* @param rawEventHook Pointer to the callback function which will be called on every MIDI event
|
* @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.
|
* @param userData Pointer to user data which will be passed through the callback.
|
||||||
|
@ -1326,11 +1220,6 @@ extern ADLMIDI_DECLSPEC void adl_setRawEventHook(struct ADL_MIDIPlayer *device,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set note hook
|
* @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 device Instance of the library
|
||||||
* @param noteHook Pointer to the callback function which will be called on every noteOn MIDI event
|
* @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.
|
* @param userData Pointer to user data which will be passed through the callback.
|
||||||
|
@ -1339,46 +1228,12 @@ extern ADLMIDI_DECLSPEC void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set debug message hook
|
* @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 device Instance of the library
|
||||||
* @param debugMessageHook Pointer to the callback function which will be called on every debug message
|
* @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.
|
* @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);
|
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.
|
* @brief Get a textual description of the channel state. For display only.
|
||||||
* @param device Instance of the library
|
* @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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* 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
|
* libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* 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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* 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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if !defined(_MSC_VER) && !defined(__aarch64__) && !defined(__3DS__)
|
#ifndef _MSC_VER
|
||||||
#define ATTRIB_PACKED __attribute__((__packed__))
|
#define ATTRIB_PACKED __attribute__((__packed__))
|
||||||
#else
|
#else
|
||||||
#define ATTRIB_PACKED
|
#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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -117,7 +117,6 @@ bool MIDIplay::LoadBank(FileAndMemReader &fr)
|
||||||
synth.m_insBankSetup.scaleModulators = false;
|
synth.m_insBankSetup.scaleModulators = false;
|
||||||
synth.m_insBankSetup.deepTremolo = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0;
|
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.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;
|
synth.m_insBankSetup.volumeModel = wopl->volume_model;
|
||||||
m_setup.deepTremoloMode = -1;
|
m_setup.deepTremoloMode = -1;
|
||||||
m_setup.deepVibratoMode = -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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -36,8 +36,7 @@ enum { MasterVolumeDefault = 127 };
|
||||||
|
|
||||||
inline bool isXgPercChannel(uint8_t msb, uint8_t lsb)
|
inline bool isXgPercChannel(uint8_t msb, uint8_t lsb)
|
||||||
{
|
{
|
||||||
ADL_UNUSED(lsb);
|
return (msb == 0x7E || msb == 0x7F) && (lsb == 0);
|
||||||
return (msb == 0x7E || msb == 0x7F);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIDIplay::AdlChannel::addAge(int64_t us)
|
void MIDIplay::AdlChannel::addAge(int64_t us)
|
||||||
|
@ -91,7 +90,6 @@ MIDIplay::MIDIplay(unsigned long sampleRate):
|
||||||
//m_setup.SkipForward = 0;
|
//m_setup.SkipForward = 0;
|
||||||
m_setup.scaleModulators = -1;
|
m_setup.scaleModulators = -1;
|
||||||
m_setup.fullRangeBrightnessCC74 = false;
|
m_setup.fullRangeBrightnessCC74 = false;
|
||||||
m_setup.enableAutoArpeggio = false;
|
|
||||||
m_setup.delay = 0.0;
|
m_setup.delay = 0.0;
|
||||||
m_setup.carry = 0.0;
|
m_setup.carry = 0.0;
|
||||||
m_setup.tick_skip_samples_delay = 0;
|
m_setup.tick_skip_samples_delay = 0;
|
||||||
|
@ -128,7 +126,6 @@ void MIDIplay::applySetup()
|
||||||
synth.m_insBankSetup.volumeModel = (b.bankSetup & 0x00FF);
|
synth.m_insBankSetup.volumeModel = (b.bankSetup & 0x00FF);
|
||||||
synth.m_insBankSetup.deepTremolo = (b.bankSetup >> 8 & 0x0001) != 0;
|
synth.m_insBankSetup.deepTremolo = (b.bankSetup >> 8 & 0x0001) != 0;
|
||||||
synth.m_insBankSetup.deepVibrato = (b.bankSetup >> 8 & 0x0002) != 0;
|
synth.m_insBankSetup.deepVibrato = (b.bankSetup >> 8 & 0x0002) != 0;
|
||||||
synth.m_insBankSetup.mt32defaults = (b.bankSetup >> 8 & 0x0004) != 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -203,15 +200,15 @@ void MIDIplay::resetMIDIDefaults(int offset)
|
||||||
for(size_t c = offset, n = m_midiChannels.size(); c < n; ++c)
|
for(size_t c = offset, n = m_midiChannels.size(); c < n; ++c)
|
||||||
{
|
{
|
||||||
MIDIchannel &ch = m_midiChannels[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_volume = 127;
|
||||||
ch.def_bendsense_lsb = 0;
|
ch.def_bendsense_lsb = 0;
|
||||||
ch.def_bendsense_msb = 12;
|
ch.def_bendsense_msb = 12;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if(synth.m_musicMode == Synth::MODE_RSXX)
|
||||||
|
ch.def_volume = 127;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,11 +290,10 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
||||||
if(!i.is_end())
|
if(!i.is_end())
|
||||||
{
|
{
|
||||||
MIDIchannel::NoteInfo &ni = i->value;
|
MIDIchannel::NoteInfo &ni = i->value;
|
||||||
const int veloffset = ni.ains ? ni.ains->midiVelocityOffset : 0;
|
const int veloffset = ni.ains->midiVelocityOffset;
|
||||||
velocity = (uint8_t)std::min(127, std::max(1, (int)velocity + veloffset));
|
velocity = (uint8_t)std::min(127, std::max(1, (int)velocity + veloffset));
|
||||||
ni.vol = velocity;
|
ni.vol = velocity;
|
||||||
if(ni.ains)
|
noteUpdate(channel, i, Upd_Volume);
|
||||||
noteUpdate(channel, i, Upd_Volume);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,7 +329,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)
|
// Let XG Percussion bank will use (0...127 LSB range in WOPN file)
|
||||||
|
|
||||||
// Choose: SFX or Drum Kits
|
// Choose: SFX or Drum Kits
|
||||||
bank = midiins + ((midiChan.bank_msb == 0x7E) ? 128 : 0);
|
bank = midiins + ((bank == 0x7E00) ? 128 : 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -361,8 +357,8 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
||||||
caughtMissingBank = true;
|
caughtMissingBank = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Or fall back to bank ignoring LSB (GS/XG)
|
//Or fall back to bank ignoring LSB (GS)
|
||||||
if(ains->flags & OplInstMeta::Flag_NoSound)
|
if((ains->flags & OplInstMeta::Flag_NoSound) && ((m_synthMode & Mode_GS) != 0))
|
||||||
{
|
{
|
||||||
size_t fallback = bank & ~(size_t)0x7F;
|
size_t fallback = bank & ~(size_t)0x7F;
|
||||||
if(fallback != bank)
|
if(fallback != bank)
|
||||||
|
@ -1349,17 +1345,6 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
|
||||||
const AdlChannel &chan = m_chipChannels[c];
|
const AdlChannel &chan = m_chipChannels[c];
|
||||||
int64_t koff_ms = chan.koff_time_until_neglible_us / 1000;
|
int64_t koff_ms = chan.koff_time_until_neglible_us / 1000;
|
||||||
int64_t s = -koff_ms;
|
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
|
// Rate channel with a releasing note
|
||||||
if(s < 0 && chan.users.empty())
|
if(s < 0 && chan.users.empty())
|
||||||
|
@ -1368,22 +1353,19 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
|
||||||
s -= 40000;
|
s -= 40000;
|
||||||
|
|
||||||
// If it's same instrument, better chance to get it when no free channels
|
// If it's same instrument, better chance to get it when no free channels
|
||||||
switch(allocType)
|
if(synth.m_musicMode == Synth::MODE_CMF)
|
||||||
{
|
{
|
||||||
case ADLMIDI_ChanAlloc_SameInst:
|
|
||||||
if(isSame)
|
if(isSame)
|
||||||
s = 0; // Re-use releasing channel with the same instrument
|
s = 0; // Re-use releasing channel with the same instrument
|
||||||
break;
|
}
|
||||||
|
else if(synth.m_volumeScale == Synth::VOLUME_HMI)
|
||||||
case ADLMIDI_ChanAlloc_AnyReleased:
|
{
|
||||||
s = 0; // Re-use any releasing channel
|
s = 0; // HMI doesn't care about the same instrument
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
default:
|
{
|
||||||
case ADLMIDI_ChanAlloc_OffDelay:
|
|
||||||
if(isSame)
|
if(isSame)
|
||||||
s = -koff_ms; // Wait until releasing sound will complete
|
s = -koff_ms; // Wait until releasing sound will complete
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
@ -1520,9 +1502,6 @@ void MIDIplay::killOrEvacuate(size_t from_channel,
|
||||||
{
|
{
|
||||||
uint16_t cs = static_cast<uint16_t>(c);
|
uint16_t cs = static_cast<uint16_t>(c);
|
||||||
|
|
||||||
if(!m_setup.enableAutoArpeggio)
|
|
||||||
break; // Arpeggio disabled completely
|
|
||||||
|
|
||||||
if(c >= maxChannels)
|
if(c >= maxChannels)
|
||||||
break;
|
break;
|
||||||
if(c == from_channel)
|
if(c == from_channel)
|
||||||
|
@ -1746,13 +1725,6 @@ void MIDIplay::updateArpeggio(double) // amount = amount of time passed
|
||||||
|
|
||||||
Synth &synth = *m_synth;
|
Synth &synth = *m_synth;
|
||||||
|
|
||||||
if(!m_setup.enableAutoArpeggio) // Arpeggio was disabled
|
|
||||||
{
|
|
||||||
if(m_arpeggioCounter != 0)
|
|
||||||
m_arpeggioCounter = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
const unsigned desired_arpeggio_rate = 40; // Hz (upper limit)
|
const unsigned desired_arpeggio_rate = 40; // Hz (upper limit)
|
||||||
# if 1
|
# 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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -37,10 +37,6 @@ struct MIDIEventHooks
|
||||||
MIDIEventHooks() :
|
MIDIEventHooks() :
|
||||||
onNote(NULL),
|
onNote(NULL),
|
||||||
onNote_userData(NULL),
|
onNote_userData(NULL),
|
||||||
onLoopStart(NULL),
|
|
||||||
onLoopStart_userData(NULL),
|
|
||||||
onLoopEnd(NULL),
|
|
||||||
onLoopEnd_userData(NULL),
|
|
||||||
onDebugMessage(NULL),
|
onDebugMessage(NULL),
|
||||||
onDebugMessage_userData(NULL)
|
onDebugMessage_userData(NULL)
|
||||||
{}
|
{}
|
||||||
|
@ -50,13 +46,6 @@ struct MIDIEventHooks
|
||||||
NoteHook onNote;
|
NoteHook onNote;
|
||||||
void *onNote_userData;
|
void *onNote_userData;
|
||||||
|
|
||||||
// Loop start/end hooks
|
|
||||||
ADL_LoopPointHook onLoopStart;
|
|
||||||
void *onLoopStart_userData;
|
|
||||||
ADL_LoopPointHook onLoopEnd;
|
|
||||||
void *onLoopEnd_userData;
|
|
||||||
|
|
||||||
|
|
||||||
//! Library internal debug messages
|
//! Library internal debug messages
|
||||||
typedef void (*DebugMessageHook)(void *userdata, const char *fmt, ...);
|
typedef void (*DebugMessageHook)(void *userdata, const char *fmt, ...);
|
||||||
DebugMessageHook onDebugMessage;
|
DebugMessageHook onDebugMessage;
|
||||||
|
@ -537,7 +526,6 @@ public:
|
||||||
//unsigned int SkipForward;
|
//unsigned int SkipForward;
|
||||||
int scaleModulators;
|
int scaleModulators;
|
||||||
bool fullRangeBrightnessCC74;
|
bool fullRangeBrightnessCC74;
|
||||||
bool enableAutoArpeggio;
|
|
||||||
|
|
||||||
double delay;
|
double delay;
|
||||||
double carry;
|
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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -868,14 +868,12 @@ OPL3::OPL3() :
|
||||||
m_softPanning(false),
|
m_softPanning(false),
|
||||||
m_masterVolume(MasterVolumeDefault),
|
m_masterVolume(MasterVolumeDefault),
|
||||||
m_musicMode(MODE_MIDI),
|
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.volumeModel = OPL3::VOLUME_Generic;
|
||||||
m_insBankSetup.deepTremolo = false;
|
m_insBankSetup.deepTremolo = false;
|
||||||
m_insBankSetup.deepVibrato = false;
|
m_insBankSetup.deepVibrato = false;
|
||||||
m_insBankSetup.scaleModulators = false;
|
m_insBankSetup.scaleModulators = false;
|
||||||
m_insBankSetup.mt32defaults = false;
|
|
||||||
|
|
||||||
#ifdef DISABLE_EMBEDDED_BANKS
|
#ifdef DISABLE_EMBEDDED_BANKS
|
||||||
m_embeddedBank = CustomBankTag;
|
m_embeddedBank = CustomBankTag;
|
||||||
|
@ -915,7 +913,6 @@ void OPL3::setEmbeddedBank(uint32_t bank)
|
||||||
const BanksDump::BankEntry &bankEntry = g_embeddedBanks[m_embeddedBank];
|
const BanksDump::BankEntry &bankEntry = g_embeddedBanks[m_embeddedBank];
|
||||||
m_insBankSetup.deepTremolo = ((bankEntry.bankSetup >> 8) & 0x01) != 0;
|
m_insBankSetup.deepTremolo = ((bankEntry.bankSetup >> 8) & 0x01) != 0;
|
||||||
m_insBankSetup.deepVibrato = ((bankEntry.bankSetup >> 8) & 0x02) != 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.volumeModel = (bankEntry.bankSetup & 0xFF);
|
||||||
m_insBankSetup.scaleModulators = false;
|
m_insBankSetup.scaleModulators = false;
|
||||||
|
|
||||||
|
@ -1631,7 +1628,6 @@ void OPL3::setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel)
|
||||||
{
|
{
|
||||||
switch(volumeModel)
|
switch(volumeModel)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
case ADLMIDI_VolumeModel_AUTO://Do nothing until restart playing
|
case ADLMIDI_VolumeModel_AUTO://Do nothing until restart playing
|
||||||
break;
|
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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -162,9 +162,6 @@ public:
|
||||||
VOLUME_HMI_OLD
|
VOLUME_HMI_OLD
|
||||||
} m_volumeScale;
|
} m_volumeScale;
|
||||||
|
|
||||||
//! Channel allocation algorithm
|
|
||||||
ADLMIDI_ChannelAlloc m_channelAlloc;
|
|
||||||
|
|
||||||
//! Reserved
|
//! Reserved
|
||||||
char _padding3[8];
|
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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* 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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* 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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* 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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -21,26 +21,14 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_NO_MUTEX
|
#if !defined(_WIN32)
|
||||||
# if defined(USE_LIBOGC_MUTEX)
|
#include <pthread.h>
|
||||||
# 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;
|
typedef pthread_mutex_t MutexNativeObject;
|
||||||
# else
|
#else
|
||||||
# include <windows.h>
|
#include <windows.h>
|
||||||
typedef CRITICAL_SECTION MutexNativeObject;
|
typedef CRITICAL_SECTION MutexNativeObject;
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class Mutex
|
class Mutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -49,9 +37,7 @@ public:
|
||||||
void lock();
|
void lock();
|
||||||
void unlock();
|
void unlock();
|
||||||
private:
|
private:
|
||||||
#if !defined(DOSBOX_NO_MUTEX)
|
|
||||||
MutexNativeObject m;
|
MutexNativeObject m;
|
||||||
#endif
|
|
||||||
Mutex(const Mutex &);
|
Mutex(const Mutex &);
|
||||||
Mutex &operator=(const Mutex &);
|
Mutex &operator=(const Mutex &);
|
||||||
};
|
};
|
||||||
|
@ -67,65 +53,7 @@ private:
|
||||||
MutexHolder &operator=(const MutexHolder &);
|
MutexHolder &operator=(const MutexHolder &);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DOSBOX_NO_MUTEX) // No mutex, just a dummy
|
#if !defined(_WIN32)
|
||||||
|
|
||||||
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()
|
inline Mutex::Mutex()
|
||||||
{
|
{
|
||||||
pthread_mutex_init(&m, NULL);
|
pthread_mutex_init(&m, NULL);
|
||||||
|
@ -145,9 +73,7 @@ inline void Mutex::unlock()
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&m);
|
pthread_mutex_unlock(&m);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
#else // Win32
|
|
||||||
|
|
||||||
inline Mutex::Mutex()
|
inline Mutex::Mutex()
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(&m);
|
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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Interfaces over Yamaha OPL3 (YMF262) chip emulators
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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-2022 Vitaly Novichkov (Wohlstand)
|
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* FileAndMemoryReader - a tiny helper to utify file reading from a disk and memory block
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the "Software"),
|
* 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
|
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
|
||||||
*
|
*
|
||||||
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
|
||||||
* ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
|
||||||
* http://iki.fi/bisqwit/source/adlmidi.html
|
* http://iki.fi/bisqwit/source/adlmidi.html
|
||||||
|
@ -106,7 +106,6 @@ struct OplBankSetup
|
||||||
bool deepTremolo;
|
bool deepTremolo;
|
||||||
bool deepVibrato;
|
bool deepVibrato;
|
||||||
bool scaleModulators;
|
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
|
* Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the "Software"),
|
* 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
|
* Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
|
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the "Software"),
|
* a copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -32,22 +32,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Solaris defines the integer types regardless of what C/C++ standard is actually available,
|
#if !defined(__STDC_VERSION__) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)) \
|
||||||
* so avoid defining them at all by ourselves. */
|
|| defined(__STRICT_ANSI__) || !defined(__cplusplus)
|
||||||
#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 signed char int8_t;
|
||||||
typedef unsigned char uint8_t;
|
typedef unsigned char uint8_t;
|
||||||
typedef signed short int int16_t;
|
typedef signed short int int16_t;
|
||||||
|
@ -60,9 +46,7 @@ typedef enum WOPLFileFlags
|
||||||
/* Enable Deep-Tremolo flag */
|
/* Enable Deep-Tremolo flag */
|
||||||
WOPL_FLAG_DEEP_TREMOLO = 0x01,
|
WOPL_FLAG_DEEP_TREMOLO = 0x01,
|
||||||
/* Enable Deep-Vibrato flag */
|
/* 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;
|
} WOPLFileFlags;
|
||||||
|
|
||||||
/* Volume scaling model implemented in the libADLMIDI */
|
/* Volume scaling model implemented in the libADLMIDI */
|
||||||
|
|
119
thirdparty/fluidsynth/include/fluidsynth.h
vendored
119
thirdparty/fluidsynth/include/fluidsynth.h
vendored
|
@ -1,119 +0,0 @@
|
||||||
/* 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
155
thirdparty/fluidsynth/include/fluidsynth/audio.h
vendored
|
@ -1,155 +0,0 @@
|
||||||
/* 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
143
thirdparty/fluidsynth/include/fluidsynth/event.h
vendored
|
@ -1,143 +0,0 @@
|
||||||
/* 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
134
thirdparty/fluidsynth/include/fluidsynth/gen.h
vendored
|
@ -1,134 +0,0 @@
|
||||||
/* 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 */
|
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
/* 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
97
thirdparty/fluidsynth/include/fluidsynth/log.h
vendored
|
@ -1,97 +0,0 @@
|
||||||
/* 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
294
thirdparty/fluidsynth/include/fluidsynth/midi.h
vendored
|
@ -1,294 +0,0 @@
|
||||||
/* 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
77
thirdparty/fluidsynth/include/fluidsynth/misc.h
vendored
|
@ -1,77 +0,0 @@
|
||||||
/* 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
105
thirdparty/fluidsynth/include/fluidsynth/mod.h
vendored
|
@ -1,105 +0,0 @@
|
||||||
/* 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
92
thirdparty/fluidsynth/include/fluidsynth/seq.h
vendored
|
@ -1,92 +0,0 @@
|
||||||
/* 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 */
|
|
|
@ -1,45 +0,0 @@
|
||||||
/* 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
194
thirdparty/fluidsynth/include/fluidsynth/settings.h
vendored
|
@ -1,194 +0,0 @@
|
||||||
/* 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
362
thirdparty/fluidsynth/include/fluidsynth/sfont.h
vendored
|
@ -1,362 +0,0 @@
|
||||||
/* 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
150
thirdparty/fluidsynth/include/fluidsynth/shell.h
vendored
|
@ -1,150 +0,0 @@
|
||||||
/* 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
552
thirdparty/fluidsynth/include/fluidsynth/synth.h
vendored
|
@ -1,552 +0,0 @@
|
||||||
/* 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
85
thirdparty/fluidsynth/include/fluidsynth/types.h
vendored
|
@ -1,85 +0,0 @@
|
||||||
/* 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 */
|
|
|
@ -1,47 +0,0 @@
|
||||||
/* 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
77
thirdparty/fluidsynth/include/fluidsynth/voice.h
vendored
|
@ -1,77 +0,0 @@
|
||||||
/* 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
162
thirdparty/fluidsynth/src/CMakeLists.txt
vendored
|
@ -1,162 +0,0 @@
|
||||||
# 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()
|
|
|
@ -1,590 +0,0 @@
|
||||||
/* 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
1882
thirdparty/fluidsynth/src/bindings/fluid_ladspa.c
vendored
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue