Add externals
This commit is contained in:
parent
0194ae1315
commit
bd301929e6
1
external/clownaudio/.gitattributes
vendored
Normal file
1
external/clownaudio/.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
PKGBUILD text eol=lf
|
9
external/clownaudio/.gitignore
vendored
Normal file
9
external/clownaudio/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
/build
|
||||
/example/build
|
||||
/example/obj
|
||||
/example/test
|
||||
/example/test.exe
|
||||
/test/build
|
||||
/test/obj
|
||||
/test/test
|
||||
/test/test.exe
|
509
external/clownaudio/CMakeLists.txt
vendored
Normal file
509
external/clownaudio/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,509 @@
|
|||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
option(CLOWNAUDIO_LIBVORBIS "Enable the libvorbis decoder backend" OFF)
|
||||
option(CLOWNAUDIO_STB_VORBIS "Enable the stb_vorbis decoder backend" ON)
|
||||
option(CLOWNAUDIO_DR_MP3 "Enable the dr_mp3 decoder backend" ON)
|
||||
option(CLOWNAUDIO_LIBOPUS "Enable the libopus decoder backend" OFF)
|
||||
option(CLOWNAUDIO_LIBFLAC "Enable the libFLAC decoder backend" OFF)
|
||||
option(CLOWNAUDIO_DR_FLAC "Enable the dr_flac decoder backend" ON)
|
||||
option(CLOWNAUDIO_DR_WAV "Enable the dr_wav decoder backend" ON)
|
||||
option(CLOWNAUDIO_LIBSNDFILE "Enable the libsndfile decoder backend" OFF)
|
||||
option(CLOWNAUDIO_LIBOPENMPT "Enable the libopenmpt decoder backend" OFF)
|
||||
option(CLOWNAUDIO_LIBXMPLITE "Enable the libxmp-lite decoder backend" OFF)
|
||||
option(CLOWNAUDIO_PXTONE "Enable the PxTone decoder backend" OFF)
|
||||
option(CLOWNAUDIO_SNES_SPC "Enable the snes_spc decoder backend" OFF)
|
||||
option(CLOWNAUDIO_MIXER_ONLY "Disables playback capabilities" OFF)
|
||||
if(NOT CLOWNAUDIO_MIXER_ONLY)
|
||||
set(CLOWNAUDIO_BACKEND "miniaudio" CACHE STRING "Which playback backend to use: supported options are 'miniaudio', 'SDL1', 'SDL2', 'Cubeb', and 'PortAudio'")
|
||||
endif()
|
||||
|
||||
project(clownaudio VERSION 0.2 DESCRIPTION "Stereo audio engine supporting various formats" LANGUAGES C CXX)
|
||||
|
||||
add_library(clownaudio
|
||||
"include/clownaudio/mixer.h"
|
||||
"src/miniaudio.cpp"
|
||||
"src/miniaudio.h"
|
||||
"src/mixer.cpp"
|
||||
"src/decoding/decoder_selector.cpp"
|
||||
"src/decoding/decoder_selector.h"
|
||||
"src/decoding/predecoder.cpp"
|
||||
"src/decoding/predecoder.h"
|
||||
"src/decoding/resampled_decoder.cpp"
|
||||
"src/decoding/resampled_decoder.h"
|
||||
"src/decoding/split_decoder.cpp"
|
||||
"src/decoding/split_decoder.h"
|
||||
"src/decoding/decoders/common.h"
|
||||
"src/decoding/decoders/memory_stream.cpp"
|
||||
"src/decoding/decoders/memory_stream.h"
|
||||
)
|
||||
|
||||
if(NOT CLOWNAUDIO_MIXER_ONLY)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"include/clownaudio/clownaudio.h"
|
||||
"include/clownaudio/playback.h"
|
||||
"src/clownaudio.cpp"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
####################
|
||||
# Decoding backends
|
||||
####################
|
||||
|
||||
if(CLOWNAUDIO_LIBVORBIS)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_LIBVORBIS)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/libvorbis.cpp"
|
||||
"src/decoding/decoders/libvorbis.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_STB_VORBIS)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_STB_VORBIS)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/stb_vorbis.cpp"
|
||||
"src/decoding/decoders/stb_vorbis.h"
|
||||
)
|
||||
|
||||
include(CheckLibraryExists)
|
||||
|
||||
check_library_exists(m exp "" LIBM)
|
||||
if(LIBM)
|
||||
target_link_libraries(clownaudio PRIVATE m)
|
||||
list(APPEND STATIC_LIBS m)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_DR_MP3)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_DR_MP3)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/dr_mp3.cpp"
|
||||
"src/decoding/decoders/dr_mp3.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBOPUS)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_LIBOPUS)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/libopus.cpp"
|
||||
"src/decoding/decoders/libopus.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBFLAC)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_LIBFLAC)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/libflac.cpp"
|
||||
"src/decoding/decoders/libflac.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_DR_FLAC)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_DR_FLAC)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/dr_flac.cpp"
|
||||
"src/decoding/decoders/dr_flac.h"
|
||||
"src/decoding/decoders/libs/dr_flac.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_DR_WAV)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_DR_WAV)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/dr_wav.cpp"
|
||||
"src/decoding/decoders/dr_wav.h"
|
||||
"src/decoding/decoders/libs/dr_wav.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBSNDFILE)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_LIBSNDFILE)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/libsndfile.cpp"
|
||||
"src/decoding/decoders/libsndfile.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBOPENMPT)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_LIBOPENMPT)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/libopenmpt.cpp"
|
||||
"src/decoding/decoders/libopenmpt.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBXMPLITE)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_LIBXMPLITE)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/libxmp-lite.cpp"
|
||||
"src/decoding/decoders/libxmp-lite.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_PXTONE)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_PXTONE)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/pxtone.cpp"
|
||||
"src/decoding/decoders/pxtone.h"
|
||||
"src/decoding/decoders/pxtone_noise.cpp"
|
||||
"src/decoding/decoders/pxtone_noise.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtn.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnDelay.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnDelay.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnDescriptor.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnDescriptor.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnError.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnError.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnEvelist.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnEvelist.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnMaster.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnMaster.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnMax.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnMem.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnMem.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnOverDrive.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnOverDrive.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Frequency.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Frequency.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Noise.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Noise.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_NoiseBuilder.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_NoiseBuilder.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Oggv.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Oggv.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Oscillator.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_Oscillator.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_PCM.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnPulse_PCM.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnService.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnService.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnService_moo.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnText.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnText.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnUnit.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnUnit.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnWoice.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnWoice.h"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnWoice_io.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtnWoicePTV.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtoneNoise.cpp"
|
||||
"src/decoding/decoders/libs/pxtone/pxtoneNoise.h"
|
||||
)
|
||||
list(APPEND STATIC_LIBS stdc++)
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_SNES_SPC)
|
||||
target_compile_definitions(clownaudio PRIVATE USE_SNES_SPC)
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/snes_spc.cpp"
|
||||
"src/decoding/decoders/snes_spc.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/blargg_common.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/blargg_config.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/blargg_endian.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/blargg_source.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/dsp.cpp"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/dsp.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SNES_SPC.cpp"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SNES_SPC.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SNES_SPC_misc.cpp"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SNES_SPC_state.cpp"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/spc.cpp"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/spc.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SPC_CPU.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SPC_DSP.cpp"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SPC_DSP.h"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SPC_Filter.cpp"
|
||||
"src/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/SPC_Filter.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
####################
|
||||
# Playback backends
|
||||
####################
|
||||
|
||||
if(NOT CLOWNAUDIO_MIXER_ONLY)
|
||||
if(CLOWNAUDIO_BACKEND STREQUAL "miniaudio")
|
||||
target_sources(clownaudio PRIVATE "src/playback/miniaudio.cpp")
|
||||
target_compile_definitions(clownaudio PRIVATE MINIAUDIO_ENABLE_DEVICE_IO)
|
||||
|
||||
include(CheckLibraryExists)
|
||||
|
||||
check_library_exists(m pow "" LIBM)
|
||||
if(LIBM)
|
||||
target_link_libraries(clownaudio PRIVATE m)
|
||||
list(APPEND STATIC_LIBS m)
|
||||
endif()
|
||||
|
||||
check_library_exists(pthread pthread_create "" LIBPTHREAD)
|
||||
if(LIBPTHREAD)
|
||||
target_link_libraries(clownaudio PRIVATE pthread)
|
||||
list(APPEND STATIC_LIBS pthread)
|
||||
endif()
|
||||
|
||||
target_link_libraries(clownaudio PRIVATE ${CMAKE_DL_LIBS})
|
||||
list(APPEND STATIC_LIBS ${CMAKE_DL_LIBS})
|
||||
elseif(CLOWNAUDIO_BACKEND STREQUAL "SDL1")
|
||||
target_sources(clownaudio PRIVATE "src/playback/sdl1.cpp")
|
||||
elseif(CLOWNAUDIO_BACKEND STREQUAL "SDL2")
|
||||
target_sources(clownaudio PRIVATE "src/playback/sdl2.cpp")
|
||||
elseif(CLOWNAUDIO_BACKEND STREQUAL "Cubeb")
|
||||
target_sources(clownaudio PRIVATE "src/playback/cubeb.cpp")
|
||||
elseif(CLOWNAUDIO_BACKEND STREQUAL "PortAudio")
|
||||
target_sources(clownaudio PRIVATE "src/playback/portaudio.cpp")
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid BACKEND selected")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
####################
|
||||
# Find dependencies
|
||||
####################
|
||||
|
||||
# CMake
|
||||
|
||||
if(NOT CLOWNAUDIO_MIXER_ONLY)
|
||||
if(CLOWNAUDIO_BACKEND STREQUAL "Cubeb")
|
||||
find_package(cubeb REQUIRED)
|
||||
|
||||
target_link_libraries(clownaudio PRIVATE cubeb::cubeb)
|
||||
list(APPEND STATIC_LIBS cubeb)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# pkg-config
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
|
||||
if(NOT CLOWNAUDIO_MIXER_ONLY)
|
||||
if(CLOWNAUDIO_BACKEND STREQUAL "SDL1")
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by SDL1, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(sdl REQUIRED IMPORTED_TARGET sdl)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::sdl)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} sdl")
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_BACKEND STREQUAL "SDL2")
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by SDL2, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(sdl2 REQUIRED IMPORTED_TARGET sdl2)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::sdl2)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} sdl2")
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_BACKEND STREQUAL "PortAudio")
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by PortAudio, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(portaudio REQUIRED IMPORTED_TARGET portaudio-2.0)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::portaudio)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} portaudio-2.0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBVORBIS)
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by libvorbis, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(vorbisfile REQUIRED IMPORTED_TARGET vorbisfile)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::vorbisfile)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} vorbisfile")
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBOPUS)
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by libopus, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(opusfile REQUIRED IMPORTED_TARGET opusfile)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::opusfile)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} opusfile")
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBFLAC)
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by libflac, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(flac REQUIRED IMPORTED_TARGET flac)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::flac)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} flac")
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBSNDFILE)
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by libsndfile, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(sndfile REQUIRED IMPORTED_TARGET sndfile)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::sndfile)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} sndfile")
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBOPENMPT)
|
||||
if (NOT PkgConfig_FOUND)
|
||||
message(FATAL_ERROR "pkg-config is needed by libopenmpt, but it couldn't be found")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(libopenmpt REQUIRED IMPORTED_TARGET libopenmpt)
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::libopenmpt)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} libopenmpt")
|
||||
endif()
|
||||
|
||||
if(CLOWNAUDIO_LIBXMPLITE)
|
||||
if (PkgConfig_FOUND)
|
||||
pkg_check_modules(libxmp-lite IMPORTED_TARGET libxmp-lite)
|
||||
endif()
|
||||
|
||||
if(libxmp-lite_FOUND)
|
||||
message(STATUS "Using system libxmp-lite")
|
||||
target_link_libraries(clownaudio PRIVATE PkgConfig::libxmp-lite)
|
||||
set(PKG_CONFIG_REQUIRES "${PKG_CONFIG_REQUIRES} libxmp-lite")
|
||||
else()
|
||||
# Compile it ourselves
|
||||
message(STATUS "Using local libxmp-lite")
|
||||
target_sources(clownaudio PRIVATE
|
||||
"src/decoding/decoders/libs/libxmp-lite/include/libxmp-lite/xmp.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/common.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/control.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/dataio.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/effects.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/effects.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/filter.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/format.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/format.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/hio.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/hio.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/lfo.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/lfo.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/list.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/load.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/load_helpers.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/mdataio.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/memio.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/memio.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/mix_all.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/mixer.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/mixer.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/period.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/period.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/player.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/player.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/precomp_lut.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/read_event.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/scan.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/smix.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/tempfile.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/virtual.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/virtual.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/common.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/it.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/it_load.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/itsex.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/loader.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/mod.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/mod_load.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/s3m.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/s3m_load.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/sample.c"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/xm.h"
|
||||
"src/decoding/decoders/libs/libxmp-lite/src/loaders/xm_load.c"
|
||||
)
|
||||
|
||||
target_include_directories(clownaudio PRIVATE "src/decoding/decoders/libs/libxmp-lite/include/libxmp-lite")
|
||||
target_compile_definitions(clownaudio PRIVATE LIBXMP_CORE_PLAYER=1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
####################
|
||||
# Misc. settings
|
||||
####################
|
||||
|
||||
# Include the public headers
|
||||
target_include_directories(clownaudio PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
|
||||
# Export symbols
|
||||
include(GenerateExportHeader)
|
||||
GENERATE_EXPORT_HEADER(clownaudio EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/export/clownaudio_export.h")
|
||||
target_include_directories(clownaudio PUBLIC "$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/export>")
|
||||
|
||||
set_target_properties(clownaudio PROPERTIES C_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON)
|
||||
|
||||
# Define public header
|
||||
if(CLOWNAUDIO_MIXER_ONLY)
|
||||
set_target_properties(clownaudio PROPERTIES PUBLIC_HEADER "include/clownaudio/mixer.h;${CMAKE_BINARY_DIR}/export/clownaudio_export.h")
|
||||
else()
|
||||
set_target_properties(clownaudio PROPERTIES PUBLIC_HEADER "include/clownaudio/clownaudio.h;include/clownaudio/playback.h;include/clownaudio/mixer.h;${CMAKE_BINARY_DIR}/export/clownaudio_export.h")
|
||||
endif()
|
||||
|
||||
# Set language standards
|
||||
# Extensions may be used by dependencies (miniaudio), so enable them
|
||||
set_target_properties(clownaudio PROPERTIES
|
||||
C_STANDARD 99
|
||||
C_EXTENSIONS ON
|
||||
CXX_STANDARD 11
|
||||
CXX_EXTENSIONS ON
|
||||
)
|
||||
|
||||
# Shut up those stupid MSVC warnings
|
||||
if(MSVC)
|
||||
target_compile_definitions(clownaudio PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Group files by directory when using an IDE
|
||||
get_target_property(CLOWNAUDIO_SOURCES clownaudio SOURCES)
|
||||
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES CLOWNAUDIO_SOURCES)
|
||||
|
||||
|
||||
####################
|
||||
# Install
|
||||
####################
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Install directories
|
||||
install(TARGETS clownaudio
|
||||
EXPORT clownaudioTargets
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/clownaudio"
|
||||
)
|
||||
|
||||
# Install `clownaudioConfig.cmake` and `clownaudioTargets.cmake`
|
||||
install(EXPORT clownaudioTargets DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/clownaudio")
|
||||
|
||||
export(TARGETS clownaudio FILE "clownaudioTargets.cmake")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(
|
||||
"clownaudioConfig.cmake.in"
|
||||
"clownaudioConfig.cmake"
|
||||
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/clownaudio"
|
||||
)
|
||||
|
||||
install(FILES "${CMAKE_BINARY_DIR}/clownaudioConfig.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/clownaudio")
|
||||
|
||||
# pkg-config
|
||||
if(DEFINED STATIC_LIBS)
|
||||
list(REMOVE_DUPLICATES STATIC_LIBS)
|
||||
foreach(ITEM ${STATIC_LIBS})
|
||||
set(PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} -l${ITEM}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
configure_file("clownaudio.pc.in" "clownaudio.pc" @ONLY)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/clownaudio.pc" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig")
|
19
external/clownaudio/LICENCE.txt
vendored
Normal file
19
external/clownaudio/LICENCE.txt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
zlib License
|
||||
|
||||
(C) 2018-2020 Clownacy
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
88
external/clownaudio/README.md
vendored
Normal file
88
external/clownaudio/README.md
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
## About
|
||||
|
||||
clownaudio is a stereo sound engine, capable of playing and mixing sounds in a
|
||||
variety of formats.
|
||||
|
||||
Supported formats include...
|
||||
* Ogg Vorbis
|
||||
* MP3
|
||||
* Opus
|
||||
* FLAC
|
||||
* WAV
|
||||
* Various tracker formats ('.it', '.xm', '.mod', etc.)
|
||||
* PxTone Music
|
||||
* PxTone Noise
|
||||
* SNES SPC
|
||||
|
||||
clownaudio is a 'full stack' sound engine, meaning that it handles everything
|
||||
from decoding to playback - the user merely has to provide it with sound data to
|
||||
process.
|
||||
|
||||
That said, clownaudio's internals are modular, meaning you can easily extract
|
||||
its mixer and use it as part of your own audio system if needed.
|
||||
|
||||
|
||||
## Decoding backends
|
||||
|
||||
In order to support a range of audio formats, clownaudio leverages numerous
|
||||
open-source libraries, dubbed 'decoding backends'. These libraries include...
|
||||
|
||||
| Library | Format | Licence | Included in-tree |
|
||||
|-------------|------------|---------------------|------------------|
|
||||
| libvorbis | Ogg Vorbis | BSD | No |
|
||||
| stb_vorbis | Ogg Vorbis | Public-domain/MIT-0 | Yes |
|
||||
| dr_mp3 | MP3 | Public-domain/MIT-0 | Yes |
|
||||
| libopus | Opus | BSD | No |
|
||||
| libFLAC | FLAC | BSD | No |
|
||||
| dr_flac | FLAC | Public-domain/MIT-0 | Yes |
|
||||
| dr_wav | WAV | Public-domain/MIT-0 | Yes |
|
||||
| libsndfile | Various (includes Ogg Vorbis, FLAC, WAV, AIFF, and others) | LGPL 2.1 | No |
|
||||
| libopenmpt | Various (includes .mod, .it, .xm, .s3m, .mptm, and **many** others) | BSD | No |
|
||||
| libxmp-lite | .mod, .it, .xm, .s3m | MIT | Yes |
|
||||
| PxTone | PxTone Music/PxTone Noise | Custom (appears to be permissive) | Yes |
|
||||
| snes_spc | SNES SPC | LGPL 2.1 | Yes |
|
||||
|
||||
clownaudio aims to be bloat-free and dependency-free: each decoding backend can
|
||||
be toggled at compile-time, and an effort is made to provide multiple backends
|
||||
for individual formats, to allow the user a choice between standard libraries
|
||||
(such as libvorbis), and lighter in-tree libraries (such as stb_vorbis).
|
||||
|
||||
|
||||
## Playback backends
|
||||
|
||||
In addition, clownaudio utilises one of the following libraries to provide
|
||||
audio-playback:
|
||||
|
||||
| Library | Licence | Included in-tree |
|
||||
|-----------|---------------------|------------------|
|
||||
| Cubeb | ISC | No |
|
||||
| miniaudio | Public-domain/MIT-0 | Yes |
|
||||
| PortAudio | MIT | No |
|
||||
| SDL1.2 | LGPL 2.1 | No |
|
||||
| SDL2 | zlib | No |
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
clownaudio is built with CMake - both shared and static libraries can be
|
||||
produced. Built libraries can be accessed via `pkg-config` and CMake's
|
||||
`find_package`.
|
||||
|
||||
As an alternative, CMake projects can embed clownaudio directly, using
|
||||
`add_subdirectory`.
|
||||
|
||||
Example `Makefile` and `CMakeLists.txt` files for a demo tool are provided: the
|
||||
`Makefile` demonstrates linking clownaudio with `pkg-config`, and the
|
||||
`CMakeLists.txt` file demonstrates linking with `find_package` and embedding
|
||||
with `add_subdirectory`.
|
||||
|
||||
`PKGBUILD` files for MSYS2 and Arch Linux are provided in the `packages`
|
||||
directory.
|
||||
|
||||
|
||||
## Licensing
|
||||
|
||||
clownaudio itself is under the zlib licence.
|
||||
|
||||
Be aware that libraries used by the various backends are subject to
|
||||
their own licences.
|
13
external/clownaudio/clownaudio.pc
vendored
Normal file
13
external/clownaudio/clownaudio.pc
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
prefix=C:/Program Files (x86)/CSE2
|
||||
exec_prefix=C:/Program Files (x86)/CSE2
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: clownaudio
|
||||
Description: Stereo audio engine supporting various formats
|
||||
Version: 0.2
|
||||
|
||||
Requires.private:
|
||||
Libs: -L${libdir} -lclownaudio
|
||||
Libs.private: OFF
|
||||
Cflags: -I${includedir}
|
13
external/clownaudio/clownaudio.pc.in
vendored
Normal file
13
external/clownaudio/clownaudio.pc.in
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @PROJECT_DESCRIPTION@
|
||||
Version: @PROJECT_VERSION@
|
||||
|
||||
Requires.private: @PKG_CONFIG_REQUIRES@
|
||||
Libs: -L${libdir} -lclownaudio
|
||||
Libs.private: @PKG_CONFIG_STATIC_LIBS@
|
||||
Cflags: -I${includedir}
|
60
external/clownaudio/clownaudioConfig.cmake
vendored
Normal file
60
external/clownaudio/clownaudioConfig.cmake
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
|
||||
####### Any changes to this file will be overwritten by the next CMake run ####
|
||||
####### The input file was clownaudioConfig.cmake.in ########
|
||||
|
||||
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
|
||||
|
||||
macro(set_and_check _var _file)
|
||||
set(${_var} "${_file}")
|
||||
if(NOT EXISTS "${_file}")
|
||||
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(check_required_components _NAME)
|
||||
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||
if(NOT ${_NAME}_${comp}_FOUND)
|
||||
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
####################################################################################
|
||||
|
||||
if(NOT OFF)
|
||||
if(OFF)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(vorbisfile REQUIRED IMPORTED_TARGET vorbisfile)
|
||||
endif()
|
||||
|
||||
if(OFF)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(flac REQUIRED IMPORTED_TARGET flac)
|
||||
endif()
|
||||
|
||||
if(OFF)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(opusfile REQUIRED IMPORTED_TARGET opusfile)
|
||||
endif()
|
||||
|
||||
if(OFF)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(sndfile REQUIRED IMPORTED_TARGET sndfile)
|
||||
endif()
|
||||
|
||||
if(OFF)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(libopenmpt REQUIRED IMPORTED_TARGET libopenmpt)
|
||||
endif()
|
||||
|
||||
if()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(libxmp-lite REQUIRED IMPORTED_TARGET libxmp-lite)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/clownaudioTargets.cmake")
|
||||
check_required_components(clownaudio)
|
36
external/clownaudio/clownaudioConfig.cmake.in
vendored
Normal file
36
external/clownaudio/clownaudioConfig.cmake.in
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
@PACKAGE_INIT@
|
||||
|
||||
if(NOT @BUILD_SHARED_LIBS@)
|
||||
if(@CLOWNAUDIO_LIBVORBIS@)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(vorbisfile REQUIRED IMPORTED_TARGET vorbisfile)
|
||||
endif()
|
||||
|
||||
if(@CLOWNAUDIO_LIBFLAC@)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(flac REQUIRED IMPORTED_TARGET flac)
|
||||
endif()
|
||||
|
||||
if(@CLOWNAUDIO_LIBOPUS@)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(opusfile REQUIRED IMPORTED_TARGET opusfile)
|
||||
endif()
|
||||
|
||||
if(@CLOWNAUDIO_LIBSNDFILE@)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(sndfile REQUIRED IMPORTED_TARGET sndfile)
|
||||
endif()
|
||||
|
||||
if(@CLOWNAUDIO_LIBOPENMPT@)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(libopenmpt REQUIRED IMPORTED_TARGET libopenmpt)
|
||||
endif()
|
||||
|
||||
if(@libxmp-lite_FOUND@)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(libxmp-lite REQUIRED IMPORTED_TARGET libxmp-lite)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/clownaudioTargets.cmake")
|
||||
check_required_components(clownaudio)
|
24
external/clownaudio/example/CMakeLists.txt
vendored
Normal file
24
external/clownaudio/example/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
option(SUBDIRECTORY "Use clownaudio as a subdirectory, instead of an external package" OFF)
|
||||
|
||||
project(clownaudio_test LANGUAGES CXX)
|
||||
|
||||
add_executable(test "test.cpp")
|
||||
|
||||
if(SUBDIRECTORY)
|
||||
add_subdirectory(".." "clownaudio" EXCLUDE_FROM_ALL)
|
||||
else()
|
||||
find_package(clownaudio REQUIRED)
|
||||
endif()
|
||||
|
||||
target_link_libraries(test PRIVATE clownaudio)
|
||||
|
||||
set_target_properties(test PROPERTIES
|
||||
CXX_STANDARD 98
|
||||
CXX_EXTENSIONS OFF
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_definitions(test PRIVATE _CRT_SECURE_NO_WARNINGS) # Shut up those stupid warnings
|
||||
endif()
|
13
external/clownaudio/example/Makefile
vendored
Normal file
13
external/clownaudio/example/Makefile
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
ALL_CXXFLAGS = $(CXXFLAGS)
|
||||
ALL_LIBS = $(LIBS)
|
||||
|
||||
ifeq ($(STATIC), 1)
|
||||
ALL_CXXFLAGS += $(shell pkg-config clownaudio --cflags --static) -static -DCLOWNAUDIO_STATIC_DEFINE
|
||||
ALL_LIBS += $(shell pkg-config clownaudio --libs --static)
|
||||
else
|
||||
ALL_CXXFLAGS += $(shell pkg-config clownaudio --cflags)
|
||||
ALL_LIBS += $(shell pkg-config clownaudio --libs)
|
||||
endif
|
||||
|
||||
test: test.cpp
|
||||
$(CXX) $(ALL_CXXFLAGS) -o $@ $^ $(LDFLAGS) $(ALL_LIBS)
|
273
external/clownaudio/example/Makefile.old
vendored
Normal file
273
external/clownaudio/example/Makefile.old
vendored
Normal file
|
@ -0,0 +1,273 @@
|
|||
USE_LIBVORBIS = false
|
||||
USE_STB_VORBIS = true
|
||||
USE_DR_MP3 = true
|
||||
USE_LIBOPUS = false
|
||||
USE_LIBFLAC = false
|
||||
USE_DR_FLAC = true
|
||||
USE_DR_WAV = true
|
||||
USE_LIBSNDFILE = false
|
||||
USE_LIBOPENMPT = false
|
||||
USE_LIBXMPLITE = true
|
||||
USE_PXTONE = true
|
||||
USE_SNES_SPC = true
|
||||
# Can be 'miniaudio', 'SDL1', 'SDL2', 'Cubeb', or 'PortAudio'
|
||||
BACKEND = miniaudio
|
||||
|
||||
CLOWNAUDIO_DIR = ../src
|
||||
|
||||
ifneq ($(RELEASE),)
|
||||
CFLAGS = -O2 -flto
|
||||
else
|
||||
CFLAGS = -Og -ggdb3
|
||||
endif
|
||||
ALL_CFLAGS = -std=c99 -MMD -MP -MF $@.d -DCLOWNAUDIO_EXPORT= -DCLOWNAUDIO_NO_EXPORT= -I $(CFLAGS)
|
||||
|
||||
ifneq ($(RELEASE),)
|
||||
CXXFLAGS = -O2 -flto
|
||||
else
|
||||
CXXFLAGS = -Og -ggdb3
|
||||
endif
|
||||
ALL_CXXFLAGS = -std=c++98 -MMD -MP -MF $@.d -DCLOWNAUDIO_EXPORT= -DCLOWNAUDIO_NO_EXPORT= $(CXXFLAGS)
|
||||
|
||||
ifneq ($(RELEASE),)
|
||||
LDFLAGS = -s
|
||||
else
|
||||
LDFLAGS =
|
||||
endif
|
||||
ALL_LDFLAGS = $(LDFLAGS)
|
||||
|
||||
LIBS =
|
||||
ALL_LIBS = $(LIBS)
|
||||
|
||||
SDL1_CFLAGS = $(shell pkg-config sdl --cflags)
|
||||
SDL1_LIBS = $(shell pkg-config sdl --libs --static)
|
||||
|
||||
SDL2_CFLAGS = $(shell pkg-config sdl2 --cflags)
|
||||
SDL2_LIBS = $(shell pkg-config sdl2 --libs --static)
|
||||
|
||||
CLOWNAUDIO_SOURCES = \
|
||||
miniaudio.cpp \
|
||||
mixer.cpp \
|
||||
decoding/decoder_selector.cpp \
|
||||
decoding/predecoder.cpp \
|
||||
decoding/resampled_decoder.cpp \
|
||||
decoding/split_decoder.cpp \
|
||||
decoding/decoders/memory_stream.cpp
|
||||
|
||||
ifeq ($(USE_LIBVORBIS), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/libvorbis.cpp
|
||||
ALL_CXXFLAGS += -DUSE_LIBVORBIS $(shell pkg-config vorbisfile --cflags)
|
||||
ALL_LIBS += $(shell pkg-config vorbisfile --libs --static)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_STB_VORBIS), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/stb_vorbis.cpp
|
||||
ALL_CXXFLAGS += -DUSE_STB_VORBIS
|
||||
ALL_LIBS += -lm
|
||||
endif
|
||||
|
||||
ifeq ($(USE_DR_MP3), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/dr_mp3.cpp
|
||||
ALL_CXXFLAGS += -DUSE_DR_MP3
|
||||
endif
|
||||
|
||||
ifeq ($(USE_LIBOPUS), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/libopus.cpp
|
||||
ALL_CXXFLAGS += -DUSE_LIBOPUS $(shell pkg-config opusfile --cflags)
|
||||
ALL_LIBS += $(shell pkg-config opusfile --libs --static)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_LIBFLAC), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/libflac.cpp
|
||||
ALL_CXXFLAGS += -DUSE_LIBFLAC $(shell pkg-config flac --cflags)
|
||||
ALL_LIBS += $(shell pkg-config flac --libs --static)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_DR_FLAC), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/dr_flac.cpp
|
||||
ALL_CXXFLAGS += -DUSE_DR_FLAC
|
||||
endif
|
||||
|
||||
ifeq ($(USE_DR_WAV), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/dr_wav.cpp
|
||||
ALL_CXXFLAGS += -DUSE_DR_WAV
|
||||
endif
|
||||
|
||||
ifeq ($(USE_LIBSNDFILE), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/libsndfile.cpp
|
||||
ALL_CXXFLAGS += -DUSE_LIBSNDFILE $(shell pkg-config sndfile --cflags)
|
||||
ALL_LIBS += $(shell pkg-config sndfile --libs --static)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_LIBOPENMPT), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/libopenmpt.cpp
|
||||
ALL_CXXFLAGS += -DUSE_LIBOPENMPT $(shell pkg-config libopenmpt --cflags)
|
||||
ALL_LIBS += $(shell pkg-config libopenmpt --libs --static)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_LIBXMPLITE), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/libxmp-lite.cpp
|
||||
ALL_CXXFLAGS += -DUSE_LIBXMPLITE
|
||||
|
||||
ifeq ($(shell pkg-config libxmp-lite --exists && echo 1), 1)
|
||||
ALL_CXXFLAGS += $(shell pkg-config libxmp-lite --cflags)
|
||||
ALL_LIBS += $(shell pkg-config libxmp-lite --libs --static)
|
||||
else
|
||||
ALL_CFLAGS += -I$(CLOWNAUDIO_DIR)/decoding/decoders/libs/libxmp-lite/include/libxmp-lite
|
||||
ALL_CXXFLAGS += -I$(CLOWNAUDIO_DIR)/decoding/decoders/libs/libxmp-lite/include/libxmp-lite
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_PXTONE), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/pxtone.cpp decoding/decoders/pxtone_noise.cpp
|
||||
ALL_CXXFLAGS += -DUSE_PXTONE
|
||||
ALL_LIBS += -lstdc++
|
||||
# Apparently PxTone supports Vorbis-encoded samples
|
||||
ifeq ($(USE_LIBVORBIS), true)
|
||||
ALL_CXXFLAGS += -DpxINCLUDE_OGGVORBIS
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SNES_SPC), true)
|
||||
CLOWNAUDIO_SOURCES += decoding/decoders/snes_spc.cpp
|
||||
ALL_CXXFLAGS += -DUSE_SNES_SPC
|
||||
ALL_LIBS += -lstdc++
|
||||
endif
|
||||
|
||||
ifeq ($(BACKEND), miniaudio)
|
||||
CLOWNAUDIO_SOURCES += playback/miniaudio.cpp
|
||||
ALL_CXXFLAGS += -DMINIAUDIO_ENABLE_DEVICE_IO
|
||||
ALL_LIBS += -lpthread -lm
|
||||
|
||||
ifneq ($(WINDOWS), 1)
|
||||
ALL_LIBS += -ldl
|
||||
endif
|
||||
else ifeq ($(BACKEND), SDL1)
|
||||
CLOWNAUDIO_SOURCES += playback/sdl1.cpp
|
||||
ALL_CXXFLAGS += $(SDL1_CFLAGS)
|
||||
ALL_LIBS += $(SDL1_LIBS)
|
||||
else ifeq ($(BACKEND), SDL2)
|
||||
CLOWNAUDIO_SOURCES += playback/sdl2.cpp
|
||||
ALL_CXXFLAGS += $(SDL2_CFLAGS)
|
||||
ALL_LIBS += $(SDL2_LIBS)
|
||||
else ifeq ($(BACKEND), Cubeb)
|
||||
CLOWNAUDIO_SOURCES += playback/cubeb.cpp
|
||||
ALL_LIBS += -lcubeb
|
||||
else ifeq ($(BACKEND), PortAudio)
|
||||
CLOWNAUDIO_SOURCES += playback/portaudio.cpp
|
||||
ALL_CXXFLAGS += $(shell pkg-config portaudio-2.0 --cflags)
|
||||
ALL_LIBS += $(shell pkg-config portaudio-2.0 --libs --static)
|
||||
endif
|
||||
|
||||
LIBXMPLITE_SOURCES = \
|
||||
src/virtual.c \
|
||||
src/format.c \
|
||||
src/period.c \
|
||||
src/player.c \
|
||||
src/read_event.c \
|
||||
src/dataio.c \
|
||||
src/lfo.c \
|
||||
src/scan.c \
|
||||
src/control.c \
|
||||
src/filter.c \
|
||||
src/effects.c \
|
||||
src/mixer.c \
|
||||
src/mix_all.c \
|
||||
src/load_helpers.c \
|
||||
src/load.c \
|
||||
src/hio.c \
|
||||
src/smix.c \
|
||||
src/memio.c \
|
||||
src/loaders/common.c \
|
||||
src/loaders/itsex.c \
|
||||
src/loaders/sample.c \
|
||||
src/loaders/xm_load.c \
|
||||
src/loaders/mod_load.c \
|
||||
src/loaders/s3m_load.c \
|
||||
src/loaders/it_load.c
|
||||
|
||||
PXTONE_SOURCES = \
|
||||
pxtnDelay.cpp \
|
||||
pxtnDescriptor.cpp \
|
||||
pxtnError.cpp \
|
||||
pxtnEvelist.cpp \
|
||||
pxtnMaster.cpp \
|
||||
pxtnMem.cpp \
|
||||
pxtnOverDrive.cpp \
|
||||
pxtnPulse_Frequency.cpp \
|
||||
pxtnPulse_Noise.cpp \
|
||||
pxtnPulse_NoiseBuilder.cpp \
|
||||
pxtnPulse_Oggv.cpp \
|
||||
pxtnPulse_Oscillator.cpp \
|
||||
pxtnPulse_PCM.cpp \
|
||||
pxtnService.cpp \
|
||||
pxtnService_moo.cpp \
|
||||
pxtnText.cpp \
|
||||
pxtnUnit.cpp \
|
||||
pxtnWoice.cpp \
|
||||
pxtnWoice_io.cpp \
|
||||
pxtnWoicePTV.cpp \
|
||||
pxtoneNoise.cpp
|
||||
|
||||
SPC_SOURCES = \
|
||||
dsp.cpp \
|
||||
SNES_SPC.cpp \
|
||||
SNES_SPC_misc.cpp \
|
||||
SNES_SPC_state.cpp \
|
||||
spc.cpp \
|
||||
SPC_DSP.cpp \
|
||||
SPC_Filter.cpp
|
||||
|
||||
OBJECTS += obj/test.o
|
||||
OBJECTS += $(addprefix obj/clownaudio/, $(addsuffix .o, $(CLOWNAUDIO_SOURCES)))
|
||||
ifeq ($(USE_LIBXMPLITE), true)
|
||||
ifneq ($(shell pkg-config libxmp-lite --exists && echo 1), 1)
|
||||
OBJECTS += $(addprefix obj/libxmp-lite/, $(addsuffix .o, $(LIBXMPLITE_SOURCES)))
|
||||
endif
|
||||
endif
|
||||
ifeq ($(USE_PXTONE), true)
|
||||
OBJECTS += $(addprefix obj/pxtone/, $(addsuffix .o, $(PXTONE_SOURCES)))
|
||||
endif
|
||||
ifeq ($(USE_SNES_SPC), true)
|
||||
OBJECTS += $(addprefix obj/spc/, $(addsuffix .o, $(SPC_SOURCES)))
|
||||
endif
|
||||
|
||||
DEPENDENCIES = $(addsuffix .d, $(OBJECTS))
|
||||
|
||||
all: test
|
||||
|
||||
obj/test.o: test.cpp
|
||||
$(info Compiling $<)
|
||||
@mkdir -p $(@D)
|
||||
@$(CXX) $(ALL_CXXFLAGS) -Wall -Wextra -pedantic -I. -I../include $< -o $@ -c
|
||||
|
||||
obj/clownaudio/%.c.o: $(CLOWNAUDIO_DIR)/%.c
|
||||
$(info Compiling $<)
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) $(ALL_CFLAGS) -Wall -Wextra -pedantic -I. -I../include $< -o $@ -c
|
||||
|
||||
obj/clownaudio/%.cpp.o: $(CLOWNAUDIO_DIR)/%.cpp
|
||||
$(info Compiling $<)
|
||||
@mkdir -p $(@D)
|
||||
@$(CXX) $(ALL_CXXFLAGS) -Wall -Wextra -pedantic -I. -I../include $< -o $@ -c
|
||||
|
||||
obj/libxmp-lite/%.o: $(CLOWNAUDIO_DIR)/decoding/decoders/libs/libxmp-lite/%
|
||||
$(info Compiling $<)
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) $(ALL_CFLAGS) -Wall -Wextra -pedantic -Wno-unused-parameter -Wno-sign-compare -Wno-maybe-uninitialized -I$(CLOWNAUDIO_DIR)/decoding/decoders/libs/libxmp-lite/src -DLIBXMP_CORE_PLAYER=1 $< -o $@ -c
|
||||
|
||||
obj/pxtone/%.o: $(CLOWNAUDIO_DIR)/decoding/decoders/libs/pxtone/%
|
||||
$(info Compiling $<)
|
||||
@mkdir -p $(@D)
|
||||
@$(CXX) $(ALL_CXXFLAGS) -std=c++11 -Wall -Wextra -pedantic $< -o $@ -c
|
||||
|
||||
obj/spc/%.o: $(CLOWNAUDIO_DIR)/decoding/decoders/libs/snes_spc-0.9.0/snes_spc/%
|
||||
$(info Compiling $<)
|
||||
@mkdir -p $(@D)
|
||||
@$(CXX) $(ALL_CXXFLAGS) $< -o $@ -c
|
||||
|
||||
test: $(OBJECTS)
|
||||
$(info Linking $@)
|
||||
@$(CC) $(ALL_CFLAGS) -Wall -Wextra -pedantic $^ -o $@ $(ALL_LDFLAGS) $(ALL_LIBS)
|
||||
|
||||
include $(wildcard $(DEPENDENCIES))
|
228
external/clownaudio/example/test.cpp
vendored
Normal file
228
external/clownaudio/example/test.cpp
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//#define STB_LEAKCHECK_IMPLEMENTATION
|
||||
//#include "stb_leakcheck.h"
|
||||
|
||||
#include "clownaudio/clownaudio.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2 && argc != 3)
|
||||
{
|
||||
printf("clownaudio test program\n\nUsage: %s [intro file] [loop file (optional)]\n\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Initialising clownaudio\n");
|
||||
fflush(stdout);
|
||||
|
||||
if (ClownAudio_Init())
|
||||
{
|
||||
const char *file_paths[2];
|
||||
if (argc == 3)
|
||||
{
|
||||
file_paths[0] = argv[1];
|
||||
file_paths[1] = argv[2];
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
file_paths[0] = argv[1];
|
||||
file_paths[1] = NULL;
|
||||
}
|
||||
|
||||
ClownAudio_SoundDataConfig config;
|
||||
ClownAudio_InitSoundDataConfig(&config);
|
||||
ClownAudio_SoundData *sound_data = ClownAudio_LoadSoundDataFromFiles(file_paths[0], file_paths[1], &config);
|
||||
|
||||
if (sound_data != NULL)
|
||||
{
|
||||
printf("Creating sound\n");
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_SoundConfig config2;
|
||||
ClownAudio_InitSoundConfig(&config2);
|
||||
config2.loop = true;
|
||||
ClownAudio_SoundID instance = ClownAudio_CreateSound(sound_data, &config2);
|
||||
ClownAudio_UnpauseSound(instance);
|
||||
|
||||
if (instance != 0)
|
||||
{
|
||||
printf("\n"
|
||||
"Controls:\n"
|
||||
" q - Quit\n"
|
||||
" r - Rewind sound\n"
|
||||
" o [duration] - Fade-out sound (milliseconds)\n"
|
||||
" i [duration] - Fade-in sound (milliseconds)\n"
|
||||
" c - Cancel fade\n"
|
||||
" u [rate] - Set sample-rate (Hz)\n"
|
||||
" p - Pause/unpause sound\n"
|
||||
" v [left] [right] - Set sound volume (0.0-1.0)\n"
|
||||
);
|
||||
fflush(stdout);
|
||||
|
||||
bool pause = false;
|
||||
|
||||
bool exit = false;
|
||||
while (!exit)
|
||||
{
|
||||
char buffer[128];
|
||||
fgets(buffer, sizeof(buffer), stdin);
|
||||
|
||||
char mode;
|
||||
while (sscanf(buffer, "%c", &mode) != 1);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 'q':
|
||||
printf("Quitting\n");
|
||||
fflush(stdout);
|
||||
|
||||
exit = true;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
printf("Rewinding sound\n");
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_RewindSound(instance);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
{
|
||||
unsigned int param;
|
||||
if (sscanf(buffer, "%c %u", &mode, ¶m) != 2)
|
||||
param = 1000 * 2;
|
||||
|
||||
printf("Fading-out sound over %u milliseconds\n", param);
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_FadeOutSound(instance, param);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i':
|
||||
{
|
||||
unsigned int param;
|
||||
if (sscanf(buffer, "%c %u", &mode, ¶m) != 2)
|
||||
param = 1000 * 2;
|
||||
|
||||
printf("Fading-in sound over %u milliseconds\n", param);
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_FadeInSound(instance, param);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c':
|
||||
printf("Cancelling fade\n");
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_CancelFade(instance);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
{
|
||||
unsigned int param;
|
||||
if (sscanf(buffer, "%c %u", &mode, ¶m) != 2)
|
||||
param = 8000;
|
||||
|
||||
printf("Setting sample-rate to %uHz\n", param);
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_SetSoundSampleRate(instance, param, param);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
if (pause)
|
||||
{
|
||||
printf("Unpausing sound\n");
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_UnpauseSound(instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Pausing sound\n");
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_PauseSound(instance);
|
||||
}
|
||||
|
||||
pause = !pause;
|
||||
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
{
|
||||
float volume_left, volume_right;
|
||||
int values_read = sscanf(buffer, "%c %f %f", &mode, &volume_left, &volume_right);
|
||||
|
||||
if (values_read == 1)
|
||||
volume_left = volume_right = 1.0f;
|
||||
else if (values_read == 2)
|
||||
volume_right = volume_left;
|
||||
|
||||
printf("Setting volume to %f left, %f right\n", volume_left, volume_right);
|
||||
fflush(stdout);
|
||||
|
||||
ClownAudio_SetSoundVolume(instance, volume_left * 0x100, volume_right * 0x100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Destroying sound\n");
|
||||
fflush(stdout);
|
||||
ClownAudio_DestroySound(instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Couldn't create sound\n");
|
||||
}
|
||||
|
||||
printf("Unloading sound data\n");
|
||||
fflush(stdout);
|
||||
ClownAudio_UnloadSoundData(sound_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Couldn't load sound data\n");
|
||||
}
|
||||
|
||||
printf("Deinitialising clownaudio\n");
|
||||
fflush(stdout);
|
||||
ClownAudio_Deinit();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Couldn't initialise clownaudio\n");
|
||||
}
|
||||
|
||||
|
||||
// stb_leakcheck_dumpmem();
|
||||
|
||||
return 0;
|
||||
}
|
152
external/clownaudio/include/clownaudio/clownaudio.h
vendored
Normal file
152
external/clownaudio/include/clownaudio/clownaudio.h
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
|
||||
#include "mixer.h"
|
||||
|
||||
#if !defined(CLOWNAUDIO_EXPORT) && !defined(CLOWNAUDIO_NO_EXPORT)
|
||||
#include "clownaudio_export.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Defined elsewhere, but included here for documentation
|
||||
typedef struct ClownAudio_SoundDataConfig
|
||||
{
|
||||
bool predecode; // If true, the sound *may* be predecoded if possible. If not, the sound will still be loaded, albeit not predecoded.
|
||||
bool must_predecode; // If true, the sound *must* be predecoded if possible. If not, the function will fail.
|
||||
bool dynamic_sample_rate; // If sound is predecoded, then this needs to be true for `ClownAudio_SetSoundSampleRate` to work
|
||||
} ClownAudio_SoundDataConfig;
|
||||
|
||||
typedef struct ClownAudio_SoundConfig
|
||||
{
|
||||
bool loop; // If true, the sound will loop indefinitely
|
||||
bool do_not_free_when_done; // If true, the sound will not be automatically destroyed once it finishes playing
|
||||
bool dynamic_sample_rate; // If sound is not predecoded, then this needs to be true for `ClownAudio_SetSoundSampleRate` to work
|
||||
} ClownAudio_SoundConfig;
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Configuration initialisation //
|
||||
//////////////////////////////////
|
||||
|
||||
// Initialises a `ClownAudio_SoundDataConfig` struct with sane default values
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_InitSoundDataConfig(ClownAudio_SoundDataConfig *config);
|
||||
|
||||
// Initialises a `ClownAudio_SoundConfig` struct with sane default values
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_InitSoundConfig(ClownAudio_SoundConfig *config);
|
||||
*/
|
||||
|
||||
////////////////////
|
||||
// Initialisation //
|
||||
////////////////////
|
||||
|
||||
// Initialises clownaudio
|
||||
CLOWNAUDIO_EXPORT bool ClownAudio_Init(void);
|
||||
|
||||
// Deinitialises clownaudio
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Deinit(void);
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Sound-data loading/unloading //
|
||||
//////////////////////////////////
|
||||
|
||||
// Loads data from up to two memory buffers - either buffer pointer can be NULL.
|
||||
// If two buffers are specified and looping is enabled, the sound will loop at the point where the first buffer ends, and the second one begins.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundData* ClownAudio_LoadSoundDataFromMemory(const unsigned char *file_buffer1, size_t file_size1, const unsigned char *file_buffer2, size_t file_size2, ClownAudio_SoundDataConfig *config);
|
||||
|
||||
// Loads data from up to two files - either file path can be NULL.
|
||||
// If two files are specified and looping is enabled, the sound will loop at the point where the first file ends, and the second one begins.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundData* ClownAudio_LoadSoundDataFromFiles(const char *intro_path, const char *loop_path, ClownAudio_SoundDataConfig *config);
|
||||
|
||||
// Unloads data. All sounds using the specified data must be destroyed manually before this function is called.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_UnloadSoundData(ClownAudio_SoundData *sound_data);
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Sound creation/destruction //
|
||||
////////////////////////////////
|
||||
|
||||
// Creates a sound from sound-data. The sound will be paused by default.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundID ClownAudio_CreateSound(ClownAudio_SoundData *sound_data, ClownAudio_SoundConfig *config);
|
||||
|
||||
// Destroys sound.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_DestroySound(ClownAudio_SoundID sound_id);
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// Assorted sound controls //
|
||||
/////////////////////////////
|
||||
|
||||
// Playback
|
||||
|
||||
// Rewinds sound to the very beginning.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_RewindSound(ClownAudio_SoundID sound_id);
|
||||
|
||||
// Pauses sound.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_PauseSound(ClownAudio_SoundID sound_id);
|
||||
|
||||
// Unpauses sound.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_UnpauseSound(ClownAudio_SoundID sound_id);
|
||||
|
||||
|
||||
// Fading
|
||||
|
||||
// Make sound fade-out over the specified duration, measured in milliseconds.
|
||||
// If the sound is currently fading-in, this function will override it, and cause the sound to fade-out from the volume is was currently at.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_FadeOutSound(ClownAudio_SoundID sound_id, unsigned int duration);
|
||||
|
||||
// Make sound fade-in over the specified duration, measured in milliseconds.
|
||||
// If the sound is currently fading-out, this function will override it, and cause the sound to fade-in from the volume is was currently at.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_FadeInSound(ClownAudio_SoundID sound_id, unsigned int duration);
|
||||
|
||||
// Aborts fading, and instantly restores the sound to full volume.
|
||||
// If you want to smoothly-undo an in-progress fade, use one of the above functions instead.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_CancelFade(ClownAudio_SoundID sound_id);
|
||||
|
||||
|
||||
// Miscellaneous
|
||||
|
||||
// Returns -1 if the sound doesn't exist, 0 if it's unpaused, or 1 if it is paused.
|
||||
CLOWNAUDIO_EXPORT int ClownAudio_GetSoundStatus(ClownAudio_SoundID sound_id);
|
||||
|
||||
// Sets stereo volume - volume is linear, ranging from 0 (silence) to 0x100 (full volume). Exceeding 0x100 will amplify the volume.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_SetSoundVolume(ClownAudio_SoundID sound_id, unsigned short volume_left, unsigned short volume_right);
|
||||
|
||||
// Change whether the sound should loop or not. Only certain file formats support this (for example - Ogg Vorbis does, and PxTone doesn't).
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_SetSoundLoop(ClownAudio_SoundID sound_id, bool loop);
|
||||
|
||||
// Override the sound's sample-rate. Note - the sound must have been created with `dynamic_sample_rate` enabled in the configuration struct,
|
||||
// otherwise this function will silently fail.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_SetSoundSampleRate(ClownAudio_SoundID sound_id, unsigned long sample_rate1, unsigned long sample_rate2);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
183
external/clownaudio/include/clownaudio/mixer.h
vendored
Normal file
183
external/clownaudio/include/clownaudio/mixer.h
vendored
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
|
||||
#if !defined(CLOWNAUDIO_EXPORT) && !defined(CLOWNAUDIO_NO_EXPORT)
|
||||
#include "clownaudio_export.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct ClownAudio_Mixer ClownAudio_Mixer;
|
||||
typedef struct ClownAudio_Sound ClownAudio_Sound;
|
||||
typedef struct ClownAudio_SoundData ClownAudio_SoundData;
|
||||
typedef unsigned int ClownAudio_SoundID;
|
||||
|
||||
typedef struct ClownAudio_SoundDataConfig
|
||||
{
|
||||
bool predecode; // If true, the sound *may* be predecoded if possible. If not, the sound will still be loaded, albeit not predecoded.
|
||||
bool must_predecode; // If true, the sound *must* be predecoded if possible. If not, the function will fail.
|
||||
bool dynamic_sample_rate; // If sound is predecoded, then this needs to be true for `ClownAudio_SetSoundSampleRate` to work
|
||||
} ClownAudio_SoundDataConfig;
|
||||
|
||||
typedef struct ClownAudio_SoundConfig
|
||||
{
|
||||
bool loop; // If true, the sound will loop indefinitely
|
||||
bool do_not_free_when_done; // If true, the sound will not be automatically destroyed once it finishes playing
|
||||
bool dynamic_sample_rate; // If sound is not predecoded, then this needs to be true for `ClownAudio_SetSoundSampleRate` to work
|
||||
} ClownAudio_SoundConfig;
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Configuration initialisation //
|
||||
//////////////////////////////////
|
||||
|
||||
// Initialises a `ClownAudio_SoundDataConfig` struct with sane default values
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_InitSoundDataConfig(ClownAudio_SoundDataConfig *config);
|
||||
|
||||
// Initialises a `ClownAudio_SoundConfig` struct with sane default values
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_InitSoundConfig(ClownAudio_SoundConfig *config);
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Mixer creation/destruction //
|
||||
////////////////////////////////
|
||||
|
||||
// Creates a mixer. Will return NULL if it fails.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_Mixer* ClownAudio_CreateMixer(unsigned long sample_rate);
|
||||
|
||||
// Destroys a mixer. All sounds playing through the specified mixer must be destroyed manually before this function is called.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_DestroyMixer(ClownAudio_Mixer *mixer);
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Sound-data loading/unloading //
|
||||
//////////////////////////////////
|
||||
|
||||
// Loads data from up to two memory buffers - either buffer pointer can be NULL.
|
||||
// If two buffers are specified and looping is enabled, the sound will loop at the point where the first buffer ends, and the second one begins.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundData* ClownAudio_Mixer_LoadSoundDataFromMemory(ClownAudio_Mixer *mixer, const unsigned char *file_buffer1, size_t file_size1, const unsigned char *file_buffer2, size_t file_size2, ClownAudio_SoundDataConfig *config);
|
||||
|
||||
// Loads data from up to two files - either file path can be NULL.
|
||||
// If two files are specified and looping is enabled, the sound will loop at the point where the first file ends, and the second one begins.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundData* ClownAudio_Mixer_LoadSoundDataFromFiles(ClownAudio_Mixer *mixer, const char *intro_path, const char *loop_path, ClownAudio_SoundDataConfig *config);
|
||||
|
||||
// Unloads data. All sounds using the specified data must be destroyed manually before this function is called.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_UnloadSoundData(ClownAudio_SoundData *sound_data);
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Sound creation/destruction //
|
||||
////////////////////////////////
|
||||
|
||||
// Creates a sound from sound-data. The sound will be paused by default.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_Sound* ClownAudio_Mixer_CreateSound(ClownAudio_Mixer *mixer, ClownAudio_SoundData *sound_data, ClownAudio_SoundConfig *config);
|
||||
|
||||
// Used to create a sound ID from a sound. Must be done only once.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundID ClownAudio_Mixer_RegisterSound(ClownAudio_Mixer *mixer, ClownAudio_Sound *sound);
|
||||
|
||||
// Destroys sound.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_DestroySound(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id);
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// Assorted sound controls //
|
||||
/////////////////////////////
|
||||
|
||||
// Playback
|
||||
|
||||
// Rewinds sound to the very beginning.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_RewindSound(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id);
|
||||
|
||||
// Pauses sound.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_PauseSound(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id);
|
||||
|
||||
// Unpauses sound.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_UnpauseSound(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id);
|
||||
|
||||
|
||||
// Fading
|
||||
|
||||
// Make sound fade-out over the specified duration, measured in milliseconds.
|
||||
// If the sound is currently fading-in, this function will override it, and cause the sound to fade-out from the volume is was currently at.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_FadeOutSound(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id, unsigned int duration);
|
||||
|
||||
// Make sound fade-in over the specified duration, measured in milliseconds.
|
||||
// If the sound is currently fading-out, this function will override it, and cause the sound to fade-in from the volume is was currently at.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_FadeInSound(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id, unsigned int duration);
|
||||
|
||||
// Aborts fading, and instantly restores the sound to full volume.
|
||||
// If you want to smoothly-undo an in-progress fade, use one of the above functions instead.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_CancelFade(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id);
|
||||
|
||||
|
||||
// Miscellaneous
|
||||
|
||||
// Returns -1 if the sound doesn't exist, 0 if it's unpaused, or 1 if it is paused.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT int ClownAudio_Mixer_GetSoundStatus(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id);
|
||||
|
||||
// Sets stereo volume - volume is linear, ranging from 0 (silence) to 0x100 (full volume). Exceeding 0x100 will amplify the volume.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_SetSoundVolume(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id, unsigned short volume_left, unsigned short volume_right);
|
||||
|
||||
// Change whether the sound should loop or not. Only certain file formats support this (for example - Ogg Vorbis does, and PxTone doesn't).
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_SetSoundLoop(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id, bool loop);
|
||||
|
||||
// Override the sound's sample-rate. Note - the sound must have been created with `dynamic_sample_rate` enabled in the configuration struct,
|
||||
// otherwise this function will silently fail.
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_SetSoundSampleRate(ClownAudio_Mixer *mixer, ClownAudio_SoundID sound_id, unsigned long sample_rate1, unsigned long sample_rate2);
|
||||
|
||||
|
||||
////////////
|
||||
// Output //
|
||||
////////////
|
||||
|
||||
// Mix interlaced (L,R ordering) S16 PCM samples into specified S32 buffer (not clamped).
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_MixSamples(ClownAudio_Mixer *mixer, long *output_buffer, size_t frames_to_do);
|
||||
|
||||
// Output interlaced (L,R ordering) S16 PCM samples into specified S16 buffer (clamped).
|
||||
// Must be guarded with mutex.
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Mixer_OutputSamples(ClownAudio_Mixer *mixer, short *output_buffer, size_t frames_to_do);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
52
external/clownaudio/include/clownaudio/playback.h
vendored
Normal file
52
external/clownaudio/include/clownaudio/playback.h
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* (C) 2018-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
|
||||
#if !defined(CLOWNAUDIO_EXPORT) && !defined(CLOWNAUDIO_NO_EXPORT)
|
||||
#include "clownaudio_export.h"
|
||||
#endif
|
||||
|
||||
#define CLOWNAUDIO_STREAM_CHANNEL_COUNT 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ClownAudio_Stream ClownAudio_Stream;
|
||||
|
||||
CLOWNAUDIO_EXPORT bool ClownAudio_InitPlayback(void);
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_DeinitPlayback(void);
|
||||
CLOWNAUDIO_EXPORT ClownAudio_Stream* ClownAudio_CreateStream(unsigned long *sample_rate, void (*user_callback)(void*, short*, size_t));
|
||||
CLOWNAUDIO_EXPORT bool ClownAudio_DestroyStream(ClownAudio_Stream *stream);
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_SetStreamCallbackData(ClownAudio_Stream *stream, void *user_data);
|
||||
CLOWNAUDIO_EXPORT bool ClownAudio_PauseStream(ClownAudio_Stream *stream);
|
||||
CLOWNAUDIO_EXPORT bool ClownAudio_ResumeStream(ClownAudio_Stream *stream);
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_LockStream(ClownAudio_Stream *stream);
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_UnlockStream(ClownAudio_Stream *stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
52
external/clownaudio/package/arch/PKGBUILD
vendored
Normal file
52
external/clownaudio/package/arch/PKGBUILD
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
pkgname=clownaudio-git
|
||||
pkgver=r430.4a508d0
|
||||
pkgrel=1
|
||||
pkgdesc='Stereo audio engine supporting various formats'
|
||||
arch=('any')
|
||||
url='https://github.com/Clownacy/clownaudio'
|
||||
license=('zlib', 'MIT', 'LGPL2', 'custom')
|
||||
depends=(
|
||||
'libvorbis'
|
||||
'flac'
|
||||
'opus'
|
||||
)
|
||||
makedepends=('cmake')
|
||||
source=("git+https://github.com/Clownacy/clownaudio.git")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/clownaudio"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
mkdir -p "${srcdir}/clownaudio/build"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/clownaudio/build"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCLOWNAUDIO_LIBVORBIS=ON \
|
||||
-DCLOWNAUDIO_STB_VORBIS=OFF \
|
||||
-DCLOWNAUDIO_DR_MP3=ON \
|
||||
-DCLOWNAUDIO_LIBOPUS=ON \
|
||||
-DCLOWNAUDIO_LIBFLAC=ON \
|
||||
-DCLOWNAUDIO_DR_FLAC=OFF \
|
||||
-DCLOWNAUDIO_DR_WAV=ON \
|
||||
-DCLOWNAUDIO_LIBSNDFILE=OFF \
|
||||
-DCLOWNAUDIO_LIBOPENMPT=OFF \
|
||||
-DCLOWNAUDIO_LIBXMPLITE=ON \
|
||||
-DCLOWNAUDIO_PXTONE=ON \
|
||||
-DCLOWNAUDIO_SNES_SPC=ON \
|
||||
-DCLOWNAUDIO_BACKEND=miniaudio
|
||||
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
make -C "${srcdir}/clownaudio/build" DESTDIR="$pkgdir" install
|
||||
}
|
82
external/clownaudio/package/msys2/PKGBUILD
vendored
Normal file
82
external/clownaudio/package/msys2/PKGBUILD
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
pkgbase=mingw-w64-clownaudio-git
|
||||
pkgname=${MINGW_PACKAGE_PREFIX}-clownaudio-git
|
||||
pkgver=r231.79004cd
|
||||
pkgrel=1
|
||||
pkgdesc='Stereo audio engine supporting various formats'
|
||||
arch=('any')
|
||||
url='https://github.com/Clownacy/clownaudio'
|
||||
license=('zlib', 'MIT', 'LGPL2', 'custom')
|
||||
depends=(
|
||||
"${MINGW_PACKAGE_PREFIX}-libvorbis"
|
||||
"${MINGW_PACKAGE_PREFIX}-flac"
|
||||
"${MINGW_PACKAGE_PREFIX}-opusfile"
|
||||
)
|
||||
makedepends=("${MINGW_PACKAGE_PREFIX}-cmake")
|
||||
options=('strip' 'staticlibs')
|
||||
source=("git+https://github.com/Clownacy/clownaudio.git")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/clownaudio"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
mkdir -p "${srcdir}/clownaudio/build-static-${MINGW_CHOST}"
|
||||
mkdir -p "${srcdir}/clownaudio/build-shared-${MINGW_CHOST}"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/clownaudio/build-static-${MINGW_CHOST}"
|
||||
|
||||
MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
|
||||
${MINGW_PREFIX}/bin/cmake .. \
|
||||
-G"MSYS Makefiles" \
|
||||
-DCMAKE_INSTALL_PREFIX=${MINGW_PREFIX} \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCLOWNAUDIO_LIBVORBIS=ON \
|
||||
-DCLOWNAUDIO_STB_VORBIS=OFF \
|
||||
-DCLOWNAUDIO_DR_MP3=ON \
|
||||
-DCLOWNAUDIO_LIBOPUS=ON \
|
||||
-DCLOWNAUDIO_LIBFLAC=ON \
|
||||
-DCLOWNAUDIO_DR_FLAC=OFF \
|
||||
-DCLOWNAUDIO_DR_WAV=ON \
|
||||
-DCLOWNAUDIO_LIBSNDFILE=OFF \
|
||||
-DCLOWNAUDIO_LIBOPENMPT=OFF \
|
||||
-DCLOWNAUDIO_LIBXMPLITE=ON \
|
||||
-DCLOWNAUDIO_PXTONE=ON \
|
||||
-DCLOWNAUDIO_SNES_SPC=ON \
|
||||
-DCLOWNAUDIO_BACKEND=miniaudio
|
||||
|
||||
make
|
||||
|
||||
cd "${srcdir}/clownaudio/build-shared-${MINGW_CHOST}"
|
||||
|
||||
MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
|
||||
${MINGW_PREFIX}/bin/cmake .. \
|
||||
-G"MSYS Makefiles" \
|
||||
-DCMAKE_INSTALL_PREFIX=${MINGW_PREFIX} \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCLOWNAUDIO_LIBVORBIS=ON \
|
||||
-DCLOWNAUDIO_STB_VORBIS=OFF \
|
||||
-DCLOWNAUDIO_DR_MP3=ON \
|
||||
-DCLOWNAUDIO_LIBOPUS=ON \
|
||||
-DCLOWNAUDIO_LIBFLAC=ON \
|
||||
-DCLOWNAUDIO_DR_FLAC=OFF \
|
||||
-DCLOWNAUDIO_DR_WAV=ON \
|
||||
-DCLOWNAUDIO_LIBSNDFILE=OFF \
|
||||
-DCLOWNAUDIO_LIBOPENMPT=OFF \
|
||||
-DCLOWNAUDIO_LIBXMPLITE=ON \
|
||||
-DCLOWNAUDIO_PXTONE=ON \
|
||||
-DCLOWNAUDIO_SNES_SPC=ON \
|
||||
-DCLOWNAUDIO_BACKEND=miniaudio
|
||||
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
make -C "${srcdir}/clownaudio/build-static-${MINGW_CHOST}" DESTDIR="$pkgdir" install
|
||||
make -C "${srcdir}/clownaudio/build-shared-${MINGW_CHOST}" DESTDIR="$pkgdir" install
|
||||
}
|
179
external/clownaudio/src/clownaudio.cpp
vendored
Normal file
179
external/clownaudio/src/clownaudio.cpp
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "clownaudio/clownaudio.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "clownaudio/mixer.h"
|
||||
#include "clownaudio/playback.h"
|
||||
|
||||
static ClownAudio_Stream *stream;
|
||||
static ClownAudio_Mixer *mixer;
|
||||
|
||||
static void StreamCallback(void *user_data, short *output_buffer, size_t frames_to_do)
|
||||
{
|
||||
(void)user_data;
|
||||
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_OutputSamples(mixer, output_buffer, frames_to_do);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT bool ClownAudio_Init(void)
|
||||
{
|
||||
if (ClownAudio_InitPlayback())
|
||||
{
|
||||
unsigned long sample_rate = 48000; // This default value is a fallback - it will be overwritten if the backend has a preferred rate
|
||||
stream = ClownAudio_CreateStream(&sample_rate, StreamCallback);
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
mixer = ClownAudio_CreateMixer(sample_rate);
|
||||
|
||||
if (mixer != NULL)
|
||||
{
|
||||
ClownAudio_ResumeStream(stream);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ClownAudio_DestroyStream(stream);
|
||||
}
|
||||
|
||||
ClownAudio_DeinitPlayback();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_Deinit(void)
|
||||
{
|
||||
ClownAudio_PauseStream(stream);
|
||||
ClownAudio_DestroyMixer(mixer);
|
||||
ClownAudio_DestroyStream(stream);
|
||||
ClownAudio_DeinitPlayback();
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundData* ClownAudio_LoadSoundDataFromMemory(const unsigned char *file_buffer1, size_t file_size1, const unsigned char *file_buffer2, size_t file_size2, ClownAudio_SoundDataConfig *config)
|
||||
{
|
||||
return ClownAudio_Mixer_LoadSoundDataFromMemory(mixer, file_buffer1, file_size1, file_buffer2, file_size2, config);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundData* ClownAudio_LoadSoundDataFromFiles(const char *intro_path, const char *loop_path, ClownAudio_SoundDataConfig *config)
|
||||
{
|
||||
return ClownAudio_Mixer_LoadSoundDataFromFiles(mixer, intro_path, loop_path, config);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_UnloadSoundData(ClownAudio_SoundData *sound_data)
|
||||
{
|
||||
ClownAudio_Mixer_UnloadSoundData(sound_data);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT ClownAudio_SoundID ClownAudio_CreateSound(ClownAudio_SoundData *sound_data, ClownAudio_SoundConfig *config)
|
||||
{
|
||||
ClownAudio_Sound *sound = ClownAudio_Mixer_CreateSound(mixer, sound_data, config);
|
||||
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_SoundID sound_id = ClownAudio_Mixer_RegisterSound(mixer, sound);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
|
||||
return sound_id;
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_DestroySound(ClownAudio_SoundID sound_id)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_DestroySound(mixer, sound_id);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_RewindSound(ClownAudio_SoundID sound_id)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_RewindSound(mixer, sound_id);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_PauseSound(ClownAudio_SoundID sound_id)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_PauseSound(mixer, sound_id);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_UnpauseSound(ClownAudio_SoundID sound_id)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_UnpauseSound(mixer, sound_id);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_FadeOutSound(ClownAudio_SoundID sound_id, unsigned int duration)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_FadeOutSound(mixer, sound_id, duration);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_FadeInSound(ClownAudio_SoundID sound_id, unsigned int duration)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_FadeInSound(mixer, sound_id, duration);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_CancelFade(ClownAudio_SoundID sound_id)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_CancelFade(mixer, sound_id);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT int ClownAudio_GetSoundStatus(ClownAudio_SoundID sound_id)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
int status = ClownAudio_Mixer_GetSoundStatus(mixer, sound_id);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_SetSoundVolume(ClownAudio_SoundID sound_id, unsigned short volume_left, unsigned short volume_right)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_SetSoundVolume(mixer, sound_id, volume_left, volume_right);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_SetSoundLoop(ClownAudio_SoundID sound_id, bool loop)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_SetSoundLoop(mixer, sound_id, loop);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
||||
|
||||
CLOWNAUDIO_EXPORT void ClownAudio_SetSoundSampleRate(ClownAudio_SoundID sound_id, unsigned long sample_rate1, unsigned long sample_rate2)
|
||||
{
|
||||
ClownAudio_LockStream(stream);
|
||||
ClownAudio_Mixer_SetSoundSampleRate(mixer, sound_id, sample_rate1, sample_rate2);
|
||||
ClownAudio_UnlockStream(stream);
|
||||
}
|
325
external/clownaudio/src/decoding/decoder_selector.cpp
vendored
Normal file
325
external/clownaudio/src/decoding/decoder_selector.cpp
vendored
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "decoder_selector.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "decoders/common.h"
|
||||
#include "predecoder.h"
|
||||
|
||||
#ifdef USE_LIBVORBIS
|
||||
#include "decoders/libvorbis.h"
|
||||
#endif
|
||||
#ifdef USE_STB_VORBIS
|
||||
#include "decoders/stb_vorbis.h"
|
||||
#endif
|
||||
#ifdef USE_DR_MP3
|
||||
#include "decoders/dr_mp3.h"
|
||||
#endif
|
||||
#ifdef USE_LIBOPUS
|
||||
#include "decoders/libopus.h"
|
||||
#endif
|
||||
#ifdef USE_LIBFLAC
|
||||
#include "decoders/libflac.h"
|
||||
#endif
|
||||
#ifdef USE_DR_FLAC
|
||||
#include "decoders/dr_flac.h"
|
||||
#endif
|
||||
#ifdef USE_DR_WAV
|
||||
#include "decoders/dr_wav.h"
|
||||
#endif
|
||||
#ifdef USE_LIBSNDFILE
|
||||
#include "decoders/libsndfile.h"
|
||||
#endif
|
||||
#ifdef USE_LIBOPENMPT
|
||||
#include "decoders/libopenmpt.h"
|
||||
#endif
|
||||
#ifdef USE_LIBXMPLITE
|
||||
#include "decoders/libxmp-lite.h"
|
||||
#endif
|
||||
#ifdef USE_PXTONE
|
||||
#include "decoders/pxtone.h"
|
||||
#include "decoders/pxtone_noise.h"
|
||||
#endif
|
||||
#ifdef USE_SNES_SPC
|
||||
#include "decoders/snes_spc.h"
|
||||
#endif
|
||||
|
||||
#define DECODER_FUNCTIONS(name) \
|
||||
{ \
|
||||
Decoder_##name##_Create, \
|
||||
Decoder_##name##_Destroy, \
|
||||
Decoder_##name##_Rewind, \
|
||||
Decoder_##name##_GetSamples \
|
||||
}
|
||||
|
||||
typedef enum DecoderType
|
||||
{
|
||||
DECODER_TYPE_PREDECODER,
|
||||
DECODER_TYPE_COMPLEX,
|
||||
DECODER_TYPE_SIMPLE
|
||||
} DecoderType;
|
||||
|
||||
typedef struct DecoderFunctions
|
||||
{
|
||||
void* (*Create)(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void (*Destroy)(void *decoder);
|
||||
void (*Rewind)(void *decoder);
|
||||
size_t (*GetSamples)(void *decoder, short *buffer, size_t frames_to_do);
|
||||
} DecoderFunctions;
|
||||
|
||||
typedef struct DecoderSelector
|
||||
{
|
||||
void *decoder;
|
||||
DecoderSelectorData *data;
|
||||
bool loop;
|
||||
} DecoderSelector;
|
||||
|
||||
struct DecoderSelectorData
|
||||
{
|
||||
const unsigned char *file_buffer;
|
||||
size_t file_size;
|
||||
DecoderType decoder_type;
|
||||
const DecoderFunctions *decoder_functions;
|
||||
PredecoderData *predecoder_data;
|
||||
unsigned int channel_count;
|
||||
};
|
||||
|
||||
static const DecoderFunctions decoder_function_list[] = {
|
||||
#ifdef USE_LIBVORBIS
|
||||
DECODER_FUNCTIONS(libVorbis),
|
||||
#endif
|
||||
#ifdef USE_STB_VORBIS
|
||||
DECODER_FUNCTIONS(STB_Vorbis),
|
||||
#endif
|
||||
#ifdef USE_DR_MP3
|
||||
DECODER_FUNCTIONS(DR_MP3),
|
||||
#endif
|
||||
#ifdef USE_LIBOPUS
|
||||
DECODER_FUNCTIONS(libOpus),
|
||||
#endif
|
||||
#ifdef USE_LIBFLAC
|
||||
DECODER_FUNCTIONS(libFLAC),
|
||||
#endif
|
||||
#ifdef USE_DR_FLAC
|
||||
DECODER_FUNCTIONS(DR_FLAC),
|
||||
#endif
|
||||
#ifdef USE_DR_WAV
|
||||
DECODER_FUNCTIONS(DR_WAV),
|
||||
#endif
|
||||
#ifdef USE_LIBSNDFILE
|
||||
DECODER_FUNCTIONS(libSndfile),
|
||||
#endif
|
||||
#ifdef USE_LIBOPENMPT
|
||||
DECODER_FUNCTIONS(libOpenMPT),
|
||||
#endif
|
||||
#ifdef USE_LIBXMPLITE
|
||||
DECODER_FUNCTIONS(libXMPLite),
|
||||
#endif
|
||||
#ifdef USE_PXTONE
|
||||
DECODER_FUNCTIONS(PxTone),
|
||||
#endif
|
||||
#ifdef USE_PXTONE
|
||||
DECODER_FUNCTIONS(PxToneNoise),
|
||||
#endif
|
||||
#ifdef USE_SNES_SPC
|
||||
DECODER_FUNCTIONS(SNES_SPC),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const DecoderFunctions predecoder_functions = {
|
||||
NULL,
|
||||
Predecoder_Destroy,
|
||||
Predecoder_Rewind,
|
||||
Predecoder_GetSamples
|
||||
};
|
||||
|
||||
DecoderSelectorData* DecoderSelector_LoadData(const unsigned char *file_buffer, size_t file_size, bool predecode, bool must_predecode, const DecoderSpec *wanted_spec)
|
||||
{
|
||||
DecoderType decoder_type;
|
||||
const DecoderFunctions *decoder_functions = NULL;
|
||||
PredecoderData *predecoder_data = NULL;
|
||||
|
||||
DecoderSpec spec;
|
||||
|
||||
// Figure out what format this sound is
|
||||
for (size_t i = 0; i < sizeof(decoder_function_list) / sizeof(decoder_function_list[0]); ++i)
|
||||
{
|
||||
void *decoder = decoder_function_list[i].Create(file_buffer, file_size, false, wanted_spec, &spec);
|
||||
|
||||
if (decoder != NULL)
|
||||
{
|
||||
decoder_type = spec.is_complex ? DECODER_TYPE_COMPLEX : DECODER_TYPE_SIMPLE;
|
||||
decoder_functions = &decoder_function_list[i];
|
||||
|
||||
DecoderStage stage;
|
||||
stage.decoder = decoder;
|
||||
stage.Destroy = decoder_functions->Destroy;
|
||||
stage.Rewind = decoder_functions->Rewind;
|
||||
stage.GetSamples = decoder_functions->GetSamples;
|
||||
stage.SetLoop = NULL;
|
||||
|
||||
if (decoder_type == DECODER_TYPE_SIMPLE && (predecode || must_predecode))
|
||||
{
|
||||
predecoder_data = Predecoder_DecodeData(&spec, wanted_spec, &stage);
|
||||
|
||||
if (predecoder_data != NULL)
|
||||
{
|
||||
decoder_type = DECODER_TYPE_PREDECODER;
|
||||
decoder_functions = &predecoder_functions;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
decoder_function_list[i].Destroy(decoder);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder_functions != NULL && (!must_predecode || decoder_type == DECODER_TYPE_PREDECODER))
|
||||
{
|
||||
DecoderSelectorData *data = (DecoderSelectorData*)malloc(sizeof(DecoderSelectorData));
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
data->file_buffer = file_buffer;
|
||||
data->file_size = file_size;
|
||||
data->decoder_type = decoder_type;
|
||||
data->decoder_functions = decoder_functions;
|
||||
data->predecoder_data = predecoder_data;
|
||||
data->channel_count = spec.channel_count;
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
if (predecoder_data != NULL)
|
||||
Predecoder_UnloadData(predecoder_data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DecoderSelector_UnloadData(DecoderSelectorData *data)
|
||||
{
|
||||
if (data->predecoder_data != NULL)
|
||||
Predecoder_UnloadData(data->predecoder_data);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
void* DecoderSelector_Create(DecoderSelectorData *data, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec)
|
||||
{
|
||||
DecoderSelector *selector = (DecoderSelector*)malloc(sizeof(DecoderSelector));
|
||||
|
||||
if (selector != NULL)
|
||||
{
|
||||
if (data->decoder_type == DECODER_TYPE_PREDECODER)
|
||||
selector->decoder = Predecoder_Create(data->predecoder_data, loop, wanted_spec, spec);
|
||||
else
|
||||
selector->decoder = data->decoder_functions->Create(data->file_buffer, data->file_size, loop, wanted_spec, spec);
|
||||
|
||||
if (selector->decoder != NULL)
|
||||
{
|
||||
selector->data = data;
|
||||
selector->loop = loop;
|
||||
return selector;
|
||||
}
|
||||
|
||||
free(selector);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DecoderSelector_Destroy(void *selector_void)
|
||||
{
|
||||
DecoderSelector *selector = (DecoderSelector*)selector_void;
|
||||
|
||||
selector->data->decoder_functions->Destroy(selector->decoder);
|
||||
free(selector);
|
||||
}
|
||||
|
||||
void DecoderSelector_Rewind(void *selector_void)
|
||||
{
|
||||
DecoderSelector *selector = (DecoderSelector*)selector_void;
|
||||
|
||||
selector->data->decoder_functions->Rewind(selector->decoder);
|
||||
}
|
||||
|
||||
size_t DecoderSelector_GetSamples(void *selector_void, short *buffer, size_t frames_to_do)
|
||||
{
|
||||
DecoderSelector *selector = (DecoderSelector*)selector_void;
|
||||
|
||||
size_t frames_done = 0;
|
||||
|
||||
switch (selector->data->decoder_type)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case DECODER_TYPE_PREDECODER:
|
||||
return Predecoder_GetSamples(selector->decoder, buffer, frames_to_do);
|
||||
|
||||
case DECODER_TYPE_COMPLEX:
|
||||
return selector->data->decoder_functions->GetSamples(selector->decoder, buffer, frames_to_do);
|
||||
|
||||
case DECODER_TYPE_SIMPLE:
|
||||
// Handle looping here, since the simple decoders don't do it by themselves
|
||||
while (frames_done != frames_to_do)
|
||||
{
|
||||
const size_t frames = selector->data->decoder_functions->GetSamples(selector->decoder, &buffer[frames_done * selector->data->channel_count], frames_to_do - frames_done);
|
||||
|
||||
if (frames == 0)
|
||||
{
|
||||
if (selector->loop)
|
||||
selector->data->decoder_functions->Rewind(selector->decoder);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
frames_done += frames;
|
||||
}
|
||||
|
||||
return frames_done;
|
||||
}
|
||||
}
|
||||
|
||||
void DecoderSelector_SetLoop(void *selector_void, bool loop)
|
||||
{
|
||||
DecoderSelector *selector = (DecoderSelector*)selector_void;
|
||||
|
||||
switch (selector->data->decoder_type)
|
||||
{
|
||||
case DECODER_TYPE_PREDECODER:
|
||||
Predecoder_SetLoop(selector->decoder, loop);
|
||||
break;
|
||||
|
||||
case DECODER_TYPE_SIMPLE:
|
||||
selector->loop = loop;
|
||||
break;
|
||||
|
||||
case DECODER_TYPE_COMPLEX:
|
||||
// TODO - This is impossible to implement
|
||||
break;
|
||||
}
|
||||
}
|
35
external/clownaudio/src/decoding/decoder_selector.h
vendored
Normal file
35
external/clownaudio/src/decoding/decoder_selector.h
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* (C) 2019 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "decoders/common.h"
|
||||
|
||||
typedef struct DecoderSelectorData DecoderSelectorData;
|
||||
|
||||
DecoderSelectorData* DecoderSelector_LoadData(const unsigned char *data, size_t data_size, bool predecode, bool must_predecode, const DecoderSpec *wanted_spec);
|
||||
void DecoderSelector_UnloadData(DecoderSelectorData *data);
|
||||
void* DecoderSelector_Create(DecoderSelectorData *data, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void DecoderSelector_Destroy(void *selector);
|
||||
void DecoderSelector_Rewind(void *selector);
|
||||
size_t DecoderSelector_GetSamples(void *selector, short *buffer, size_t frames_to_do);
|
||||
void DecoderSelector_SetLoop(void *selector, bool loop);
|
40
external/clownaudio/src/decoding/decoders/common.h
vendored
Normal file
40
external/clownaudio/src/decoding/decoders/common.h
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct DecoderSpec
|
||||
{
|
||||
unsigned long sample_rate;
|
||||
unsigned int channel_count;
|
||||
bool is_complex;
|
||||
} DecoderSpec;
|
||||
|
||||
typedef struct DecoderStage
|
||||
{
|
||||
void *decoder;
|
||||
|
||||
void (*Destroy)(void *decoder);
|
||||
void (*Rewind)(void *decoder);
|
||||
size_t (*GetSamples)(void *decoder, short *buffer, size_t frames_to_do);
|
||||
void (*SetLoop)(void *decoder, bool loop);
|
||||
} DecoderStage;
|
61
external/clownaudio/src/decoding/decoders/dr_flac.cpp
vendored
Normal file
61
external/clownaudio/src/decoding/decoders/dr_flac.cpp
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "dr_flac.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define DR_FLAC_IMPLEMENTATION
|
||||
#define DR_FLAC_NO_STDIO
|
||||
#include "libs/dr_flac.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_DR_FLAC_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec)
|
||||
{
|
||||
(void)loop; // This is ignored in simple decoders
|
||||
(void)wanted_spec;
|
||||
|
||||
drflac *backend = drflac_open_memory(data, data_size, NULL);
|
||||
|
||||
if (backend != NULL)
|
||||
{
|
||||
spec->sample_rate = backend->sampleRate;
|
||||
spec->channel_count = backend->channels;
|
||||
spec->is_complex = false;
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
void Decoder_DR_FLAC_Destroy(void *decoder)
|
||||
{
|
||||
drflac_close((drflac*)decoder);
|
||||
}
|
||||
|
||||
void Decoder_DR_FLAC_Rewind(void *decoder)
|
||||
{
|
||||
drflac_seek_to_pcm_frame((drflac*)decoder, 0);
|
||||
}
|
||||
|
||||
size_t Decoder_DR_FLAC_GetSamples(void *decoder, short *buffer, size_t frames_to_do)
|
||||
{
|
||||
return drflac_read_pcm_frames_s16((drflac*)decoder, frames_to_do, buffer);
|
||||
}
|
30
external/clownaudio/src/decoding/decoders/dr_flac.h
vendored
Normal file
30
external/clownaudio/src/decoding/decoders/dr_flac.h
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_DR_FLAC_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void Decoder_DR_FLAC_Destroy(void *decoder);
|
||||
void Decoder_DR_FLAC_Rewind(void *decoder);
|
||||
size_t Decoder_DR_FLAC_GetSamples(void *decoder, short *buffer, size_t frames_to_do);
|
75
external/clownaudio/src/decoding/decoders/dr_mp3.cpp
vendored
Normal file
75
external/clownaudio/src/decoding/decoders/dr_mp3.cpp
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* (C) 2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "dr_mp3.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
#define DR_MP3_NO_STDIO
|
||||
#include "libs/dr_mp3.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_DR_MP3_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec)
|
||||
{
|
||||
(void)loop; // This is ignored in simple decoders
|
||||
(void)wanted_spec;
|
||||
|
||||
if ((data[0] == 0xFF && data[1] == 0xFB) || (data[0] == 0x49 && data[1] == 0x44 && data[2] == 0x33))
|
||||
{
|
||||
drmp3 *instance = (drmp3*)malloc(sizeof(drmp3));
|
||||
|
||||
if (instance != NULL)
|
||||
{
|
||||
if (drmp3_init_memory(instance, data, data_size, NULL))
|
||||
{
|
||||
spec->sample_rate = instance->sampleRate;
|
||||
spec->channel_count = instance->channels;
|
||||
spec->is_complex = false;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
free(instance);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Decoder_DR_MP3_Destroy(void *decoder)
|
||||
{
|
||||
drmp3 *instance = (drmp3*)decoder;
|
||||
|
||||
drmp3_uninit(instance);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void Decoder_DR_MP3_Rewind(void *decoder)
|
||||
{
|
||||
drmp3_seek_to_pcm_frame((drmp3*)decoder, 0);
|
||||
}
|
||||
|
||||
size_t Decoder_DR_MP3_GetSamples(void *decoder, short *buffer, size_t frames_to_do)
|
||||
{
|
||||
return drmp3_read_pcm_frames_s16((drmp3*)decoder, frames_to_do, buffer);
|
||||
}
|
30
external/clownaudio/src/decoding/decoders/dr_mp3.h
vendored
Normal file
30
external/clownaudio/src/decoding/decoders/dr_mp3.h
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* (C) 2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_DR_MP3_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void Decoder_DR_MP3_Destroy(void *decoder);
|
||||
void Decoder_DR_MP3_Rewind(void *decoder);
|
||||
size_t Decoder_DR_MP3_GetSamples(void *decoder, short *buffer, size_t frames_to_do);
|
72
external/clownaudio/src/decoding/decoders/dr_wav.cpp
vendored
Normal file
72
external/clownaudio/src/decoding/decoders/dr_wav.cpp
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "dr_wav.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DR_WAV_IMPLEMENTATION
|
||||
#define DR_WAV_NO_STDIO
|
||||
#include "libs/dr_wav.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_DR_WAV_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec)
|
||||
{
|
||||
(void)loop; // This is ignored in simple decoders
|
||||
(void)wanted_spec;
|
||||
|
||||
drwav *instance = (drwav*)malloc(sizeof(drwav));
|
||||
|
||||
if (instance != NULL)
|
||||
{
|
||||
if (drwav_init_memory(instance, data, data_size, NULL))
|
||||
{
|
||||
spec->sample_rate = instance->sampleRate;
|
||||
spec->channel_count = instance->channels;
|
||||
spec->is_complex = false;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
free(instance);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Decoder_DR_WAV_Destroy(void *decoder)
|
||||
{
|
||||
drwav *instance = (drwav*)decoder;
|
||||
|
||||
drwav_uninit(instance);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void Decoder_DR_WAV_Rewind(void *decoder)
|
||||
{
|
||||
drwav_seek_to_pcm_frame((drwav*)decoder, 0);
|
||||
}
|
||||
|
||||
size_t Decoder_DR_WAV_GetSamples(void *decoder, short *buffer, size_t frames_to_do)
|
||||
{
|
||||
return drwav_read_pcm_frames_s16((drwav*)decoder, frames_to_do, buffer);
|
||||
}
|
30
external/clownaudio/src/decoding/decoders/dr_wav.h
vendored
Normal file
30
external/clownaudio/src/decoding/decoders/dr_wav.h
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_DR_WAV_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void Decoder_DR_WAV_Destroy(void *decoder);
|
||||
void Decoder_DR_WAV_Rewind(void *decoder);
|
||||
size_t Decoder_DR_WAV_GetSamples(void *decoder, short *buffer, size_t frames_to_do);
|
257
external/clownaudio/src/decoding/decoders/libflac.cpp
vendored
Normal file
257
external/clownaudio/src/decoding/decoders/libflac.cpp
vendored
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "libflac.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <FLAC/stream_decoder.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "memory_stream.h"
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
typedef struct Decoder_libFLAC
|
||||
{
|
||||
ROMemoryStream *memory_stream;
|
||||
FLAC__StreamDecoder *flac_stream_decoder;
|
||||
DecoderSpec *spec;
|
||||
|
||||
unsigned int channel_count;
|
||||
|
||||
bool error;
|
||||
|
||||
unsigned int bits_per_sample;
|
||||
|
||||
unsigned char *block_buffer;
|
||||
unsigned long block_buffer_index;
|
||||
unsigned long block_buffer_size;
|
||||
} Decoder_libFLAC;
|
||||
|
||||
static FLAC__StreamDecoderReadStatus fread_wrapper(const FLAC__StreamDecoder *flac_stream_decoder, FLAC__byte *output, size_t *count, void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
FLAC__StreamDecoderReadStatus status = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
|
||||
*count = ROMemoryStream_Read(decoder->memory_stream, output, sizeof(FLAC__byte), *count);
|
||||
|
||||
if (*count == 0)
|
||||
status = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderSeekStatus fseek_wrapper(const FLAC__StreamDecoder *flac_stream_decoder, FLAC__uint64 offset, void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
return ROMemoryStream_SetPosition(decoder->memory_stream, offset, MEMORYSTREAM_START) ? FLAC__STREAM_DECODER_SEEK_STATUS_OK : FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderTellStatus ftell_wrapper(const FLAC__StreamDecoder *flac_stream_decoder, FLAC__uint64 *offset, void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
*offset = ROMemoryStream_GetPosition(decoder->memory_stream);
|
||||
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderLengthStatus GetSize(const FLAC__StreamDecoder *flac_stream_decoder, FLAC__uint64 *length, void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
const size_t old_offset = ROMemoryStream_GetPosition(decoder->memory_stream);
|
||||
|
||||
ROMemoryStream_SetPosition(decoder->memory_stream, 0, MEMORYSTREAM_END);
|
||||
*length = ROMemoryStream_GetPosition(decoder->memory_stream);
|
||||
|
||||
ROMemoryStream_SetPosition(decoder->memory_stream, old_offset, MEMORYSTREAM_START);
|
||||
|
||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__bool CheckEOF(const FLAC__StreamDecoder *flac_stream_decoder, void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
const size_t offset = ROMemoryStream_GetPosition(decoder->memory_stream);
|
||||
|
||||
ROMemoryStream_SetPosition(decoder->memory_stream, 0, MEMORYSTREAM_END);
|
||||
const size_t size = ROMemoryStream_GetPosition(decoder->memory_stream);
|
||||
|
||||
ROMemoryStream_SetPosition(decoder->memory_stream, offset, MEMORYSTREAM_START);
|
||||
|
||||
return (offset == size);
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderWriteStatus WriteCallback(const FLAC__StreamDecoder *flac_stream_decoder, const FLAC__Frame *frame, const FLAC__int32* const buffer[], void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
FLAC__int16 *block_buffer_pointer = (FLAC__int16*)decoder->block_buffer;
|
||||
for (unsigned int i = 0; i < frame->header.blocksize; ++i)
|
||||
{
|
||||
for (unsigned int j = 0; j < frame->header.channels; ++j)
|
||||
{
|
||||
const FLAC__int32 sample = buffer[j][i];
|
||||
|
||||
// Downscale/upscale to 16-bit
|
||||
if (decoder->bits_per_sample < 16)
|
||||
*block_buffer_pointer++ = (FLAC__int16)(sample << (16 - decoder->bits_per_sample));
|
||||
else if (decoder->bits_per_sample > 16)
|
||||
*block_buffer_pointer++ = (FLAC__int16)(sample >> (decoder->bits_per_sample - 16));
|
||||
else
|
||||
*block_buffer_pointer++ = (FLAC__int16)sample;
|
||||
}
|
||||
}
|
||||
|
||||
decoder->block_buffer_index = 0;
|
||||
decoder->block_buffer_size = (block_buffer_pointer - (FLAC__int16*)decoder->block_buffer) / decoder->channel_count;
|
||||
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static void MetadataCallback(const FLAC__StreamDecoder *flac_stream_decoder, const FLAC__StreamMetadata *metadata, void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
decoder->spec->sample_rate = metadata->data.stream_info.sample_rate;
|
||||
decoder->spec->channel_count = decoder->channel_count = metadata->data.stream_info.channels;
|
||||
decoder->spec->is_complex = false;
|
||||
|
||||
decoder->bits_per_sample = metadata->data.stream_info.bits_per_sample;
|
||||
|
||||
// Init block buffer
|
||||
decoder->block_buffer = (unsigned char*)malloc(metadata->data.stream_info.max_blocksize * sizeof(FLAC__int16) * metadata->data.stream_info.channels);
|
||||
decoder->block_buffer_index = 0;
|
||||
decoder->block_buffer_size = 0;
|
||||
}
|
||||
|
||||
static void ErrorCallback(const FLAC__StreamDecoder *flac_stream_decoder, FLAC__StreamDecoderErrorStatus status, void *user)
|
||||
{
|
||||
(void)flac_stream_decoder;
|
||||
(void)status;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)user;
|
||||
|
||||
decoder->error = true;
|
||||
}
|
||||
|
||||
void* Decoder_libFLAC_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec)
|
||||
{
|
||||
(void)loop; // This is ignored in simple decoders
|
||||
(void)wanted_spec;
|
||||
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)malloc(sizeof(Decoder_libFLAC));
|
||||
|
||||
if (decoder != NULL)
|
||||
{
|
||||
decoder->flac_stream_decoder = FLAC__stream_decoder_new();
|
||||
|
||||
if (decoder->flac_stream_decoder != NULL)
|
||||
{
|
||||
decoder->memory_stream = ROMemoryStream_Create(data, data_size);
|
||||
|
||||
if (decoder->memory_stream != NULL)
|
||||
{
|
||||
if (FLAC__stream_decoder_init_stream(decoder->flac_stream_decoder, fread_wrapper, fseek_wrapper, ftell_wrapper, GetSize, CheckEOF, WriteCallback, MetadataCallback, ErrorCallback, decoder) == FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
||||
{
|
||||
decoder->error = false;
|
||||
decoder->spec = spec;
|
||||
FLAC__stream_decoder_process_until_end_of_metadata(decoder->flac_stream_decoder);
|
||||
|
||||
if (!decoder->error)
|
||||
return decoder;
|
||||
|
||||
FLAC__stream_decoder_finish(decoder->flac_stream_decoder);
|
||||
}
|
||||
|
||||
ROMemoryStream_Destroy(decoder->memory_stream);
|
||||
}
|
||||
|
||||
FLAC__stream_decoder_delete(decoder->flac_stream_decoder);
|
||||
}
|
||||
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Decoder_libFLAC_Destroy(void *decoder_void)
|
||||
{
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)decoder_void;
|
||||
|
||||
FLAC__stream_decoder_finish(decoder->flac_stream_decoder);
|
||||
FLAC__stream_decoder_delete(decoder->flac_stream_decoder);
|
||||
ROMemoryStream_Destroy(decoder->memory_stream);
|
||||
free(decoder->block_buffer);
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
void Decoder_libFLAC_Rewind(void *decoder_void)
|
||||
{
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)decoder_void;
|
||||
|
||||
FLAC__stream_decoder_seek_absolute(decoder->flac_stream_decoder, 0);
|
||||
}
|
||||
|
||||
size_t Decoder_libFLAC_GetSamples(void *decoder_void, short *buffer, size_t frames_to_do)
|
||||
{
|
||||
Decoder_libFLAC *decoder = (Decoder_libFLAC*)decoder_void;
|
||||
|
||||
if (decoder->block_buffer_index == decoder->block_buffer_size)
|
||||
{
|
||||
FLAC__stream_decoder_process_single(decoder->flac_stream_decoder);
|
||||
|
||||
if (FLAC__stream_decoder_get_state(decoder->flac_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const unsigned int SIZE_OF_FRAME = sizeof(FLAC__int16) * decoder->channel_count;
|
||||
|
||||
const unsigned long block_frames_to_do = MIN(frames_to_do, decoder->block_buffer_size - decoder->block_buffer_index);
|
||||
|
||||
memcpy(buffer, &decoder->block_buffer[decoder->block_buffer_index * SIZE_OF_FRAME], block_frames_to_do * SIZE_OF_FRAME);
|
||||
|
||||
decoder->block_buffer_index += block_frames_to_do;
|
||||
|
||||
return block_frames_to_do;
|
||||
}
|
30
external/clownaudio/src/decoding/decoders/libflac.h
vendored
Normal file
30
external/clownaudio/src/decoding/decoders/libflac.h
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_libFLAC_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void Decoder_libFLAC_Destroy(void *decoder);
|
||||
void Decoder_libFLAC_Rewind(void *decoder);
|
||||
size_t Decoder_libFLAC_GetSamples(void *decoder, short *buffer, size_t frames_to_do);
|
102
external/clownaudio/src/decoding/decoders/libopenmpt.cpp
vendored
Normal file
102
external/clownaudio/src/decoding/decoders/libopenmpt.cpp
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "libopenmpt.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libopenmpt/libopenmpt.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define SAMPLE_RATE 48000
|
||||
#define CHANNEL_COUNT 2
|
||||
|
||||
typedef struct Decoder_libOpenMPT
|
||||
{
|
||||
openmpt_module *module;
|
||||
unsigned long sample_rate;
|
||||
} Decoder_libOpenMPT;
|
||||
|
||||
void* Decoder_libOpenMPT_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec)
|
||||
{
|
||||
(void)wanted_spec;
|
||||
|
||||
Decoder_libOpenMPT *decoder = (Decoder_libOpenMPT*)malloc(sizeof(Decoder_libOpenMPT));
|
||||
|
||||
if (decoder != NULL)
|
||||
{
|
||||
unsigned long sample_rate = wanted_spec->sample_rate == 0 ? SAMPLE_RATE : wanted_spec->sample_rate;
|
||||
|
||||
decoder->module = openmpt_module_create_from_memory2(data, data_size, openmpt_log_func_silent, NULL, openmpt_error_func_ignore, NULL, NULL, NULL, NULL);
|
||||
decoder->sample_rate = sample_rate;
|
||||
|
||||
if (decoder->module != NULL)
|
||||
{
|
||||
spec->sample_rate = sample_rate;
|
||||
spec->channel_count = CHANNEL_COUNT;
|
||||
spec->is_complex = true;
|
||||
|
||||
if (loop)
|
||||
openmpt_module_set_repeat_count(decoder->module, -1);
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Decoder_libOpenMPT_Destroy(void *decoder_void)
|
||||
{
|
||||
Decoder_libOpenMPT *decoder = (Decoder_libOpenMPT*)decoder_void;
|
||||
|
||||
openmpt_module_destroy(decoder->module);
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
void Decoder_libOpenMPT_Rewind(void *decoder_void)
|
||||
{
|
||||
Decoder_libOpenMPT *decoder = (Decoder_libOpenMPT*)decoder_void;
|
||||
|
||||
openmpt_module_set_position_seconds(decoder->module, 0);
|
||||
}
|
||||
|
||||
size_t Decoder_libOpenMPT_GetSamples(void *decoder_void, short *buffer, size_t frames_to_do)
|
||||
{
|
||||
Decoder_libOpenMPT *decoder = (Decoder_libOpenMPT*)decoder_void;
|
||||
|
||||
size_t frames_done = 0;
|
||||
|
||||
while (frames_done != frames_to_do)
|
||||
{
|
||||
size_t frames = openmpt_module_read_interleaved_stereo(decoder->module, decoder->sample_rate, frames_to_do - frames_done, &buffer[frames_done * CHANNEL_COUNT]);
|
||||
|
||||
if (frames == 0)
|
||||
break;
|
||||
|
||||
frames_done += frames;
|
||||
}
|
||||
|
||||
return frames_done;
|
||||
}
|
30
external/clownaudio/src/decoding/decoders/libopenmpt.h
vendored
Normal file
30
external/clownaudio/src/decoding/decoders/libopenmpt.h
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_libOpenMPT_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void Decoder_libOpenMPT_Destroy(void *decoder);
|
||||
void Decoder_libOpenMPT_Rewind(void *decoder);
|
||||
size_t Decoder_libOpenMPT_GetSamples(void *decoder, short *buffer, size_t frames_to_do);
|
59
external/clownaudio/src/decoding/decoders/libopus.cpp
vendored
Normal file
59
external/clownaudio/src/decoding/decoders/libopus.cpp
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "libopus.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <opus/opusfile.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_libOpus_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec)
|
||||
{
|
||||
(void)loop; // This is ignored in simple decoders
|
||||
(void)wanted_spec;
|
||||
|
||||
OggOpusFile *backend = op_open_memory(data, data_size, NULL);
|
||||
|
||||
if (backend != NULL)
|
||||
{
|
||||
spec->sample_rate = 48000; // libopusfile always outputs at 48kHz (https://opus-codec.org/docs/opusfile_api-0.7/structOpusHead.html#a73b80a913eca33d829f1667caee80d9e)
|
||||
spec->channel_count = 2; // We use op_read_float_stereo, so libopusfile will handle conversion if it needs to
|
||||
spec->is_complex = false;
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
void Decoder_libOpus_Destroy(void *decoder)
|
||||
{
|
||||
op_free((OggOpusFile*)decoder);
|
||||
}
|
||||
|
||||
void Decoder_libOpus_Rewind(void *decoder)
|
||||
{
|
||||
op_pcm_seek((OggOpusFile*)decoder, 0);
|
||||
}
|
||||
|
||||
size_t Decoder_libOpus_GetSamples(void *decoder, short *buffer, size_t frames_to_do)
|
||||
{
|
||||
return op_read_stereo((OggOpusFile*)decoder, buffer, frames_to_do * 2); // You tell *me* why that last parameter is in samples and not frames
|
||||
}
|
30
external/clownaudio/src/decoding/decoders/libopus.h
vendored
Normal file
30
external/clownaudio/src/decoding/decoders/libopus.h
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* (C) 2019-2020 Clownacy
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void* Decoder_libOpus_Create(const unsigned char *data, size_t data_size, bool loop, const DecoderSpec *wanted_spec, DecoderSpec *spec);
|
||||
void Decoder_libOpus_Destroy(void *decoder);
|
||||
void Decoder_libOpus_Rewind(void *decoder);
|
||||
size_t Decoder_libOpus_GetSamples(void *decoder, short *buffer, size_t frames_to_do);
|
12179
external/clownaudio/src/decoding/decoders/libs/dr_flac.h
vendored
Normal file
12179
external/clownaudio/src/decoding/decoders/libs/dr_flac.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4705
external/clownaudio/src/decoding/decoders/libs/dr_mp3.h
vendored
Normal file
4705
external/clownaudio/src/decoding/decoders/libs/dr_mp3.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
6405
external/clownaudio/src/decoding/decoders/libs/dr_wav.h
vendored
Normal file
6405
external/clownaudio/src/decoding/decoders/libs/dr_wav.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
282
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/Changelog
vendored
Normal file
282
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/Changelog
vendored
Normal file
|
@ -0,0 +1,282 @@
|
|||
Stable versions
|
||||
---------------
|
||||
|
||||
4.4.1 (20161012):
|
||||
- fix MacOS Tiger build issues (reported by Misty De Meo)
|
||||
- fix sample loop corner case (reported by knight-ryu12)
|
||||
- fix set pan effect in multichannel MODs (reported by Leilei)
|
||||
- fix global volume on module loop (reported by Travis Evans)
|
||||
- fix IT pan right value (by NoSuck)
|
||||
- fix memory leak in XMs with 256 patterns
|
||||
- fix anticlick when rendering only one sample
|
||||
|
||||
4.4.0 (20160719):
|
||||
Fix bugs caught in the OpenMPT test cases:
|
||||
- fix XM arpeggio in FastTracker 2 compatible mode
|
||||
- fix IT bidirectional loop sample length
|
||||
- fix MOD vibrato and tremolo in Protracker compatible mode
|
||||
Fix multichannel MOD issues reported by Leilei:
|
||||
- fix XM replayer note delay and retrig quirk
|
||||
- fix XM replayer channel pan
|
||||
- fix MOD loader period to note conversion
|
||||
Fix issues reported by Lionel Debroux:
|
||||
- fix virtual channel deallocation error handling
|
||||
- fix S3M global volume effect
|
||||
- fix IT envelope reset on tone portamento
|
||||
- fix IT voice leak caused by disabled envelope
|
||||
- fix IT volume column tone portamento
|
||||
- fix XM envelope position setting
|
||||
- fix FT2 arpeggio+portamento quirk with finetunes
|
||||
- fix mixer anticlick routines
|
||||
- accept S3M modules with invalid effects
|
||||
Other changes:
|
||||
- fix S3M channel reset on sample end (reported by Alexander Null)
|
||||
- fix Noisetracker MOD speed setting (reported by Tero Auvinen)
|
||||
- fix IT loader DCA sanity check (reported by Paul Gomez Givera)
|
||||
- fix IT envelope reset after offset with portamento
|
||||
- fix bidirectional sample interpolation
|
||||
- fix mixer resampling and tuning issues
|
||||
- add flags to configure player mode
|
||||
- add option to set the maximum number of virtual channels
|
||||
- add support to IT sample sustain loop
|
||||
- code refactoring and cleanup
|
||||
|
||||
4.3.13 (20160417):
|
||||
Fix bugs caught in the OpenMPT test cases:
|
||||
- fix IT volume column fine volume slide with row delay
|
||||
Other changes:
|
||||
- fix MOD vs XM set finetune effect
|
||||
- fix IT old instrument volume
|
||||
- fix IT panbrello speed
|
||||
- fix IT random pan variation left bias
|
||||
- fix IT default pan in sample mode (reported by Hai Shalom)
|
||||
- fix S3M set pan effect (reported by Hai Shalom and Johannes Schultz)
|
||||
- code refactoring and cleanup
|
||||
|
||||
4.3.12 (20150305):
|
||||
Fix bugs caught in the OpenMPT test cases:
|
||||
- fix IT note off with instrument
|
||||
- fix IT note recover after cut
|
||||
- fix IT instrument without note after note cut event
|
||||
- fix IT pan reset on new note instead of new instrument
|
||||
- fix IT volume swing problems
|
||||
- fix XM glissando effect
|
||||
- fix Scream Tracker 3 period limits
|
||||
- fix Scream Tracker 3 tremolo memory
|
||||
Other changes:
|
||||
- fix IT pattern break in hexadecimal (reported by StarFox008)
|
||||
- fix S3M subsong detection (reported by knight-ryu12)
|
||||
- fix S3M/IT special marker handling (reported by knight-ryu12)
|
||||
- fix tone portamento memory without note (reported by NoSuck)
|
||||
- fix IT pan swing limits
|
||||
|
||||
4.3.11 (20160212):
|
||||
Fix bugs caught in the OpenMPT test cases:
|
||||
- fix FT2 XM arpeggio clamp
|
||||
- fix FT2 XM arpeggio + pitch slide
|
||||
- fix XM tremor effect handling
|
||||
- fix XM tremor recover after volume setting
|
||||
- fix IT instrument after keyoff
|
||||
- fix S3M first frame test in pattern delay
|
||||
- fix Protracker tone portamento target setting
|
||||
- fix Protracker arpeggio wraparound
|
||||
- fix Protracker finetune setting
|
||||
Other changes:
|
||||
- fix Visual C++ build (reported by Jochen Goernitz)
|
||||
- fix invalid sample offset handling in Skale Tracker XM (reported by
|
||||
Vladislav Suschikh)
|
||||
- fix Protracker sample loop to use full repeat only if start is 0
|
||||
- fix lite build with IT support disabled
|
||||
|
||||
4.3.10 (20151231):
|
||||
Fix bugs reported by Coverity Scan:
|
||||
- fix out of bounds access in IT/XM envelopes
|
||||
- fix negative array index read when setting position
|
||||
- fix resource leak in module load error handling
|
||||
- add sanity check to smix sample loading
|
||||
- add error handling to many I/O operations
|
||||
- remove dead code in virtual channel manager reset
|
||||
- remove unnecessary seeks in format loaders
|
||||
- prevent division by zero in memory I/O
|
||||
Other changes:
|
||||
- fix IT envelope release + fadeout (reported by NoSuck)
|
||||
- fix IT autovibrato depth (reported by Travis Evans)
|
||||
- fix tone portamento target setting (reported by Georgy Lomsadze)
|
||||
- disable ST3 sample size limit (reported by Jochen Goernitz)
|
||||
|
||||
4.3.9 (20150623):
|
||||
Fix bugs caught in the OpenMPT test cases:
|
||||
- fix IT tone portamento on sample change and NNA
|
||||
- fix IT tone portamento with offset
|
||||
Fix problems caused by fuzz files (reported by Jonathan Neuschäfer):
|
||||
- add sanity check to IT instrument name loader
|
||||
- add sanity check to IT loader instrument mapping
|
||||
- initialize IT loader last event data
|
||||
Other changes:
|
||||
- detect Amiga frequency limits in MOD (reported by Mirko Buffoni)
|
||||
- fix global volume on restart to invalid row (reported by Adam Purkrt)
|
||||
- fix external sample mixer for IT files (reported by honguito98)
|
||||
- allow short sample reads (reported by Adam Purkrt)
|
||||
- address problems reported by clang sanitizer
|
||||
|
||||
4.3.8 (20150404):
|
||||
- fix pre-increment of envelope indexes
|
||||
- fix IT note release at end of envelope sustain loop
|
||||
- reset channel flags in case of delay effect
|
||||
- refactor XM envelopes
|
||||
- refactor IT envelopes
|
||||
|
||||
4.3.7 (20150329):
|
||||
- fix IT sample mode note cut on invalid sample
|
||||
- fix IT sample mode note end detection
|
||||
- fix IT envelope handling with carry and fadeout
|
||||
- fix IT tone portamento with sample changes
|
||||
- fix IT initial global volume setting
|
||||
- fix IT keyoff with instrument in old effects mode
|
||||
- fix IT filter maximum values with resonance
|
||||
- fix IT random volume variation
|
||||
- fix pattern initialization sanity check
|
||||
- fix ++ pattern handling in IT loader (reported by honguito98)
|
||||
- add IT high offset command (SAx)
|
||||
- add IT surround command (S9x)
|
||||
- add IT surround channel support
|
||||
- add IT sample pan setting support
|
||||
|
||||
4.3.6 (20150322):
|
||||
- fix IT volume column volume slide effect memory
|
||||
- fix IT default filter cutoff on new note
|
||||
- fix IT filter envelope memory
|
||||
- add sanity check for IT old instrument loading
|
||||
- fix instrument number in channel initialization
|
||||
- fix sample size limit (reported by Jochen Goernitz)
|
||||
- fix loading of OpenMPT 1.17 IT modules (reported by Dane Bush)
|
||||
- fix XM loading for MED2XM modules (reported by Lorence Lombardo)
|
||||
- add IT random volume variation
|
||||
- add IT random pan variation
|
||||
|
||||
4.3.5 (20150207):
|
||||
- add sanity check for ST3 S3M maximum sample size
|
||||
- add sanity check for sample loop start
|
||||
- add sanity check for speed 0
|
||||
- add sanity check for invalid XM effects
|
||||
- add sanity check for maximum number of channels
|
||||
- add sanity check for number of points in IT envelope
|
||||
- add sanity check for S3M file format information
|
||||
- add sanity check for maximum sample size
|
||||
- add sanity check for invalid envelope points
|
||||
- add sanity check for basic module parameters
|
||||
- add sanity check for instrument release after load error
|
||||
- add sanity check for XM header size
|
||||
- add sanity check for XM/IT/S3M parameters and sample size
|
||||
- fix mixer index overflow with large samples
|
||||
- fix crash on attempt to play invalid sample
|
||||
- fix infinite loop in break+delay quirk
|
||||
- reset module data before loading module
|
||||
- fix loop processing error in scan (reported by Lionel Debroux)
|
||||
- fix sample loop adjustment (by Emmanuel Julien)
|
||||
|
||||
4.3.4 (20150111):
|
||||
- fix XM keyoff+delay combinations
|
||||
- fix XM fine pitch slide with pattern delay
|
||||
- fix XM vibrato rampdown waveform
|
||||
- fix XM volume column pan with keyoff and delay
|
||||
- fix XM pan envelope position setting
|
||||
- fix channel volume and instrument initialization
|
||||
- fix end of module detection inside a loop
|
||||
- fix overflow in linear interpolator (reported by Jochen Goernitz)
|
||||
- fix big-endian detection in configuration (by Andreas Schwab)
|
||||
|
||||
4.3.3 (20141231):
|
||||
- fix XM note delay volume with no note or instrument set
|
||||
- fix XM out-of-range note delays with pattern delays
|
||||
- fix XM envelope loop length (reported by Per Törner)
|
||||
|
||||
4.3.2 (20141130):
|
||||
- fix IT invalid instrument number recovery
|
||||
- fix IT note retrig on portamento with same sample
|
||||
- fix XM portamento target reset on new instrument
|
||||
- fix XM portamento with offset
|
||||
- fix XM pan slide memory
|
||||
- fix XM tremolo and vibrato waveforms
|
||||
- fix MOD pattern break with pattern delay
|
||||
- fix MOD Protracker offset bug emulation
|
||||
- fix tremolo rate
|
||||
- fix IT portamento after keyoff and note end
|
||||
- fix IT fadeout reset on new note
|
||||
- fix IT pattern row delay scan
|
||||
- fix MOD/XM volume up+down priority (reported by Jason Gibson)
|
||||
- fix MOD fine volume slide memory (reported by Dennis Lindroos)
|
||||
- fix set sample offset effect (by Dennis Lindroos)
|
||||
- add emulation of the FT2 pattern loop bug (by Eugene Toder)
|
||||
- code cleanup
|
||||
|
||||
4.3.1 (20141111):
|
||||
- fix IT filter envelope range
|
||||
- fix IT envelope carry after envelope end
|
||||
- fix IT tone portamento in first note (reported by Jan Engelhardt)
|
||||
- fix XM note off with volume command
|
||||
- fix XM K00 effect handling
|
||||
- fix XM portamento with volume column portamento
|
||||
- fix XM keyoff with instrument
|
||||
- fix XM note limits
|
||||
- fix XM invalid memory access in event reader
|
||||
- fix MOD period range enforcing (reported by Jason Gibson)
|
||||
- fix corner case memory leak in S3M loader
|
||||
- fix retrig of single-shot samples after the end of the sample
|
||||
- fix crash in envelope reset with invalid instrument
|
||||
- fix module titles and instrument names in Mac OS X
|
||||
- fix row delay initialization on new module
|
||||
|
||||
4.3.0 (20140927):
|
||||
- rebranded as libxmp-lite
|
||||
- build from the same source tree as the full libxmp
|
||||
- fix fine volume slide memory
|
||||
- fix IT portamento after note end in sample mode
|
||||
- fix S3M portamento after note end
|
||||
- add XM and IT envelope loop and sustain point quirk
|
||||
- fix Amiga limits for notes with finetune
|
||||
- fix XM invalid offset handling
|
||||
- fix XM note release reset on new volume
|
||||
- fix XM pattern loader to honor header size
|
||||
- fix XM fine volume slide effect memory
|
||||
- fix XM fine pitch slide effect memory
|
||||
- fix XM finetune effect
|
||||
- fix IT portamento if offset effect is used
|
||||
- fix IT NNA on invalid sample mapping
|
||||
- fix IT filter envelope index reset
|
||||
- fix IT envelope carry on note cut events
|
||||
- fix IT envelope reset on new instrument
|
||||
- fix IT instrument change on portamento in compatible GXX mode
|
||||
- fix IT unmapped sample parsing
|
||||
- fix IT filter cutoff reset
|
||||
- add API call to load a module from a file handle
|
||||
- add API call to set default pan separation value
|
||||
- refactor memory I/O calls
|
||||
- fix segfault in mixer caused by sample position overflow
|
||||
- fix XM, S3M, IT and MED offset effect handling
|
||||
- fix IT fadeout and envelope reset on new virtual channel
|
||||
- fix S3M shared effect parameter memory
|
||||
- fix S3M default pan positions
|
||||
- fix S3M set BPM effect with values < 32 (reported by Kyu S.)
|
||||
- fix loop counter reset on play buffer reset
|
||||
- fix finetune effect
|
||||
- fix sequence number reset on player start
|
||||
- fix stray notes in XM (reported by Andreas Argirakis)
|
||||
- limit note number to avoid crash (reported by Bastian Pflieger)
|
||||
|
||||
4.2.7 (20140412):
|
||||
- fix library name in pkg-config file (by Chris Spiegel)
|
||||
- fix XM set pan effect
|
||||
- fix IT disabled instrument pan
|
||||
|
||||
4.2.6 (20140407):
|
||||
- add configure option to disable IT support
|
||||
- minor Visual C++ port fixes
|
||||
- add Visual C++ nmake Makefile
|
||||
- fix double free in module loaded from memory (by Arnaud Troël)
|
||||
- fix Win64 portability issues (reported by Ozkan Sezer)
|
||||
- fix IT tempo slide effect
|
||||
- generate Android NDK static libraries
|
||||
|
||||
4.2.0 (20140302):
|
||||
- forked from libxmp 4.2.5 and removed unnecessary features
|
36
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/INSTALL
vendored
Normal file
36
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/INSTALL
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
Requirements
|
||||
------------
|
||||
|
||||
- This package needs to be built using GNU make
|
||||
(https://www.gnu.org/software/make/). On BSD or SysV systems, you may
|
||||
need to use "gmake" instead of "make".
|
||||
|
||||
|
||||
Building the library
|
||||
--------------------
|
||||
|
||||
In most systems just execute:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
|
||||
We'll build the shared library by default. Use ./configure --enable-static
|
||||
to build the static library. To check if the library was correctly built,
|
||||
run:
|
||||
|
||||
$ make check
|
||||
|
||||
Use ./configure --help to see more options.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
To install the library and development components, just run:
|
||||
|
||||
# make install
|
||||
|
||||
as the superuser. This will install the shared and static libraries,
|
||||
header file and pkg-config file into directories under /usr/local or a
|
||||
different location selected with the --prefix option in configure.
|
||||
|
207
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/Makefile.in
vendored
Normal file
207
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/Makefile.in
vendored
Normal file
|
@ -0,0 +1,207 @@
|
|||
VERSION_MAJOR = 4
|
||||
VERSION_MINOR = 4
|
||||
VERSION_RELEASE = 1
|
||||
|
||||
VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
|
||||
|
||||
# The dylib will support anything linked against COMPAT_VERSION through VERSION
|
||||
COMPAT_VERSION = $(VERSION_MAJOR)
|
||||
|
||||
CC = @CC@
|
||||
CFLAGS = -c @CFLAGS@ @DEFS@ -D_REENTRANT -DLIBXMP_CORE_PLAYER
|
||||
LD = @CC@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
RANLIB = @RANLIB@
|
||||
INSTALL = @INSTALL@
|
||||
DESTDIR =
|
||||
prefix = @prefix@
|
||||
exec_prefix = @prefix@
|
||||
datarootdir = @datarootdir@
|
||||
BINDIR = @bindir@
|
||||
LIBDIR = @libdir@
|
||||
MANDIR = @mandir@/man3
|
||||
INCLUDEDIR = @includedir@/libxmp-lite
|
||||
LD_VERSCRIPT = @LD_VERSCRIPT@
|
||||
SHELL = /bin/sh
|
||||
|
||||
DIST = libxmp-lite-$(VERSION)
|
||||
DFILES = README INSTALL Changelog install-sh configure configure.ac \
|
||||
config.sub config.guess Makefile.in libxmp-lite.pc.in \
|
||||
Makefile.vc libxmp.map
|
||||
DDIRS = include src loaders test
|
||||
V = 0
|
||||
LIB = libxmp-lite.a
|
||||
SOLIB = libxmp-lite.so
|
||||
SHLIB = $(SOLIB).$(VERSION)
|
||||
SONAME = $(SOLIB).$(VERSION_MAJOR)
|
||||
DLL = libxmp-lite.dll
|
||||
DYLIB = libxmp-lite.$(VERSION_MAJOR).dylib
|
||||
GCLIB = libxmp-lite-gc.a
|
||||
|
||||
all: @STATIC@ @SHARED@
|
||||
|
||||
include include/libxmp-lite/Makefile
|
||||
include src/Makefile
|
||||
include src/loaders/Makefile
|
||||
include test/Makefile
|
||||
|
||||
LOBJS = $(OBJS:.o=.lo)
|
||||
|
||||
GCOBJS = $(OBJS:.o=.gco)
|
||||
|
||||
CFLAGS += -Iinclude/libxmp-lite -Isrc
|
||||
|
||||
.SUFFIXES: .c .o .lo .a .so .dll .in .gco .gcda .gcno
|
||||
|
||||
.c.o:
|
||||
@CMD='$(CC) $(CPPFLAGS) $(CFLAGS) -o $*.o $<'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo CC $*.o ; fi; \
|
||||
eval $$CMD
|
||||
|
||||
.c.lo:
|
||||
@CMD='$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -o $*.lo $<'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo CC $*.lo ; fi; \
|
||||
eval $$CMD
|
||||
|
||||
.c.gco:
|
||||
@CMD='$(CC) $(CPPFLAGS) $(CFLAGS) -O0 -fno-inline -fprofile-arcs -ftest-coverage -o $*.gco $<'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo CC $*.gco ; fi; \
|
||||
eval $$CMD
|
||||
|
||||
static: lib/$(LIB)
|
||||
|
||||
shared: lib/$(SHLIB)
|
||||
|
||||
coverage: lib/$(GCLIB)
|
||||
|
||||
dll: lib/$(DLL)
|
||||
|
||||
dylib: lib/$(DYLIB)
|
||||
|
||||
lib/$(LIB): $(OBJS)
|
||||
@mkdir -p lib
|
||||
@CMD='$(AR) r $@ $(OBJS)'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo AR $@ ; fi; \
|
||||
eval $$CMD
|
||||
$(RANLIB) $@
|
||||
|
||||
lib/$(SHLIB): $(LOBJS)
|
||||
@mkdir -p lib
|
||||
@CMD='$(LD) $(LDFLAGS) -shared -Wl,-soname,$(SONAME) $(LD_VERSCRIPT) -o $@ $(LOBJS) $(LIBS)'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo LD $@ ; fi; \
|
||||
eval $$CMD
|
||||
ln -sf $(SHLIB) lib/$(SONAME)
|
||||
ln -sf $(SONAME) lib/$(SOLIB)
|
||||
|
||||
lib/$(DLL): $(OBJS)
|
||||
@mkdir -p lib
|
||||
@CMD='$(LD) $(LDFLAGS) -shared -Wl,--output-def,lib/libxmp-lite.def,--out-implib,lib/libxmp-lite_dll.a -o $@ $(OBJS) $(LIBS)'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo LD $@ ; fi; \
|
||||
eval $$CMD
|
||||
|
||||
# From http://stackoverflow.com/questions/15905310:
|
||||
# The version number checks that dyld performs are limited to ensuring that
|
||||
# the compatibility version of the library being loaded is higher than the
|
||||
# compatibility version of the library that was used at build time.
|
||||
|
||||
lib/$(DYLIB): $(LOBJS)
|
||||
@mkdir -p lib
|
||||
@CMD='$(LD) $(LDFLAGS) -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,$(COMPAT_VERSION),-current_version,$(VERSION),-install_name,$(prefix)/lib/$(DYLIB) -o $@ $(LOBJS) $(LIBS)'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo LD $@ ; fi; \
|
||||
eval $$CMD
|
||||
ln -sf $(DYLIB) lib/libxmp-lite.dylib
|
||||
|
||||
lib/$(GCLIB): $(GCOBJS)
|
||||
@mkdir -p lib
|
||||
@CMD='$(AR) r $@ $(GCOBJS)'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo AR $@ ; fi; \
|
||||
eval $$CMD
|
||||
$(RANLIB) $@
|
||||
|
||||
clean:
|
||||
@rm -f $(OBJS) $(LOBJS) lib/lib*
|
||||
@rm -f $(GCOBJS) $(OBJS:.o=.gcno) $(OBJS:.o=.gcda)
|
||||
|
||||
install: all
|
||||
@mkdir -p $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCLUDEDIR)
|
||||
@if [ -f lib/$(LIB) ]; then \
|
||||
echo "Installing $(LIB)..."; \
|
||||
$(INSTALL) -m644 lib/$(LIB) $(DESTDIR)$(LIBDIR); \
|
||||
fi
|
||||
@if [ -f lib/$(DYLIB) ]; then \
|
||||
echo "Installing $(DYLIB)..."; \
|
||||
$(INSTALL) -m755 lib/$(DYLIB) $(DESTDIR)$(LIBDIR); \
|
||||
ln -sf $(DYLIB) $(DESTDIR)$(LIBDIR)/libxmp-lite.dylib; \
|
||||
fi
|
||||
@if [ -f lib/$(SHLIB) ]; then \
|
||||
echo "Installing $(SHLIB)..."; \
|
||||
$(INSTALL) -m644 lib/$(SHLIB) $(DESTDIR)$(LIBDIR); \
|
||||
ln -sf $(SHLIB) $(DESTDIR)$(LIBDIR)/$(SONAME); \
|
||||
ln -sf $(SONAME) $(DESTDIR)$(LIBDIR)/$(SOLIB); \
|
||||
fi
|
||||
@echo "Installing xmp.h..."
|
||||
@$(INSTALL) -m644 include/libxmp-lite/xmp.h $(DESTDIR)$(INCLUDEDIR)
|
||||
@echo "Installing libxmp-lite.pc..."
|
||||
@mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig
|
||||
@$(INSTALL) -m644 libxmp-lite.pc $(DESTDIR)$(LIBDIR)/pkgconfig/
|
||||
|
||||
depend:
|
||||
@echo Building dependencies...
|
||||
@echo > $@
|
||||
@for i in $(OBJS) $(T_OBJS); do \
|
||||
c="$${i%.o}.c"; l="$${i%.o}.lo"; \
|
||||
$(CC) $(CFLAGS) -MM $$c | \
|
||||
sed "s!^.*\.o:!$$i $$l:!" >> $@ ; \
|
||||
done
|
||||
|
||||
dist: version-prepare dist-prepare vc-prepare dist-jni dist-subdirs
|
||||
|
||||
dist-jni:
|
||||
mkdir $(DIST)/jni
|
||||
cp jni/Android.mk jni/Application.mk $(DIST)/jni
|
||||
|
||||
dist-prepare:
|
||||
./config.status
|
||||
rm -Rf $(DIST) $(DIST).tar.gz
|
||||
mkdir -p $(DIST)
|
||||
cp -RPp $(DFILES) $(DIST)/
|
||||
|
||||
vc-prepare:
|
||||
@echo Generate Makefile.vc
|
||||
@sed -e 's!@OBJS@!$(subst /,\\,$(OBJS:.o=.obj))!' Makefile.vc.in > Makefile.vc
|
||||
|
||||
dist-subdirs: $(addprefix dist-,$(DDIRS))
|
||||
chmod -R u+w $(DIST)/*
|
||||
tar cvf - $(DIST) | gzip -9c > $(DIST).tar.gz
|
||||
rm -Rf $(DIST)
|
||||
ls -l $(DIST).tar.gz
|
||||
|
||||
distcheck:
|
||||
rm -Rf $(DIST)
|
||||
tar xf $(DIST).tar.gz
|
||||
(cd $(DIST); ./configure --enable-static --prefix=`pwd`/test-install; make; make check; make install; find test-install)
|
||||
|
||||
|
||||
devcheck:
|
||||
$(MAKE) -C test-dev
|
||||
|
||||
covercheck: coverage
|
||||
$(MAKE) -C test-dev covercheck
|
||||
|
||||
coverclean:
|
||||
rm -f $(OBJS:.o=.gco) $(OBJS:.o=.gcno) $(OBJS:.o=.gcda)
|
||||
$(MAKE) -C test-dev coverclean
|
||||
|
||||
$(OBJS): Makefile
|
||||
|
||||
$(LOBJS): Makefile
|
||||
|
||||
version-prepare:
|
||||
sed -i -e '/^Version: /s/:.*/: $(VERSION)/g' libxmp-lite.pc.in
|
||||
vercode=`printf "0x%02x%02x%02x" $(VERSION_MAJOR) $(VERSION_MINOR) $(VERSION_RELEASE)`; \
|
||||
sed -i -e "s/\(^#define XMP_VERSION\).*/\1 \"$(VERSION)\"/;s/\(^#define XMP_VERCODE\).*/\1 $$vercode/;s/\(^#define XMP_VER_MAJOR\).*/\1 $(VERSION_MAJOR)/;s/\(^#define XMP_VER_MINOR\).*/\1 $(VERSION_MINOR)/;s/\(^#define XMP_VER_RELEASE\).*/\1 $(VERSION_RELEASE)/" include/libxmp-lite/xmp.h
|
||||
./config.status
|
||||
|
||||
sinclude depend
|
||||
|
26
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/Makefile.vc
vendored
Normal file
26
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/Makefile.vc
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
CC = cl
|
||||
CFLAGS = /O2 /Iinclude\libxmp-lite /Isrc /DBUILDING_DLL /DWIN32 \
|
||||
/Dinline=__inline /D_USE_MATH_DEFINES /DLIBXMP_CORE_PLAYER
|
||||
LD = link
|
||||
LDFLAGS = /DLL /RELEASE /OUT:$(DLL)
|
||||
DLL = libxmp-lite.dll
|
||||
|
||||
OBJS = src\virtual.obj src\format.obj src\period.obj src\player.obj src\read_event.obj src\dataio.obj src\lfo.obj src\scan.obj src\control.obj src\filter.obj src\effects.obj src\mixer.obj src\mix_all.obj src\load_helpers.obj src\load.obj src\hio.obj src\smix.obj src\memio.obj src\loaders\common.obj src\loaders\itsex.obj src\loaders\sample.obj src\loaders\xm_load.obj src\loaders\mod_load.obj src\loaders\s3m_load.obj src\loaders\it_load.obj
|
||||
|
||||
TEST = test\md5.obj test\test.obj
|
||||
|
||||
.c.obj:
|
||||
$(CC) /c $(CFLAGS) /Fo$*.obj $<
|
||||
|
||||
all: $(DLL)
|
||||
|
||||
$(DLL): $(OBJS)
|
||||
$(LD) $(LDFLAGS) $(OBJS)
|
||||
|
||||
clean:
|
||||
del $(OBJS) $(DLL) *.lib *.exp
|
||||
|
||||
check: $(TEST)
|
||||
$(LD) /RELEASE /OUT:test\libxmp-lite-test.exe $(TEST) libxmp-lite.lib
|
||||
copy libxmp-lite.dll test
|
||||
cd test & libxmp-lite-test
|
42
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/README
vendored
Normal file
42
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/README
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
__ _ __ ___ __
|
||||
/ / (_) / __ __ __ _ ___ ____/ (_) /____
|
||||
/ /__/ / _ \\ \ // ' \/ _ \/___/ / / __/ -_)
|
||||
/____/_/_.__/_\_\/_/_/_/ .__/ /_/_/\__/\__/
|
||||
/_/
|
||||
|
||||
Libxmp-lite is a lean and lightweight subset of Libxmp that plays MOD, S3M,
|
||||
XM, and IT modules and retains full compatibility with the original API.
|
||||
It's intended for games and small or embedded applications where module
|
||||
format diversity and file depacking are not required.
|
||||
|
||||
Library size can be further reduced by disabling Impulse Tracker format
|
||||
support (configure with --disable-it). This option will also disable IT
|
||||
effects and lowpass filtering.
|
||||
|
||||
Please refer to http://xmp.sf.net/libxmp.html for details on the current
|
||||
Libxmp API.
|
||||
|
||||
|
||||
LICENSE
|
||||
|
||||
Extended Module Player Lite
|
||||
Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
1501
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/config.guess
vendored
Normal file
1501
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/config.guess
vendored
Normal file
File diff suppressed because it is too large
Load diff
1823
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/config.sub
vendored
Normal file
1823
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/config.sub
vendored
Normal file
File diff suppressed because it is too large
Load diff
5267
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/configure
vendored
Normal file
5267
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/configure
vendored
Normal file
File diff suppressed because it is too large
Load diff
118
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/configure.ac
vendored
Normal file
118
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/configure.ac
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
dnl AC_CONFIG_AUX_DIR(./scripts)
|
||||
AC_INIT
|
||||
AC_ARG_ENABLE(it, [ --disable-it Don't build IT format support])
|
||||
AC_ARG_ENABLE(static, [ --enable-static Build static library])
|
||||
AC_ARG_ENABLE(shared, [ --disable-shared Don't build shared library])
|
||||
AC_SUBST(LD_VERSCRIPT)
|
||||
AC_CANONICAL_HOST
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
dnl XMP_TRY_COMPILE(<message>,<cache-var>,<flags>,<program>,<ifyes>,<ifno>)
|
||||
AC_DEFUN([XMP_TRY_COMPILE],[
|
||||
AC_CACHE_CHECK([$1],[$2],[
|
||||
oldcflags="${CFLAGS}"
|
||||
CFLAGS="${CFLAGS} $3"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[$4]])],[$2=yes],[$2=no],[true])
|
||||
CFLAGS="${oldcflags}"])
|
||||
AS_IF([test "x$$2" = xyes], [$5], [$6])])
|
||||
|
||||
AC_DEFUN([AC_CHECK_DEFINED],[
|
||||
AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl
|
||||
AC_CACHE_CHECK([for $1 defined], ac_var,
|
||||
AC_TRY_COMPILE(,[
|
||||
#ifdef $1
|
||||
int ok;
|
||||
#else
|
||||
choke me
|
||||
#endif
|
||||
],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no)))
|
||||
AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl
|
||||
AS_VAR_POPDEF([ac_var])dnl
|
||||
])
|
||||
|
||||
case "$host_cpu" in
|
||||
powerpc64)
|
||||
CFLAGS="${CFLAGS} -m64"
|
||||
LDFLAGS="${LDFLAGS} -m64"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${host_os}" in
|
||||
cygwin*)
|
||||
enable_static=yes
|
||||
enable_shared=no
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "${enable_static}" = yes; then
|
||||
AC_SUBST(STATIC,static)
|
||||
fi
|
||||
if test "${enable_shared}" != no; then
|
||||
AC_CHECK_DEFINED(_WIN32,[
|
||||
AC_SUBST(SHARED,dll)
|
||||
CFLAGS="${CFLAGS} -DBUILDING_DLL"
|
||||
],[
|
||||
AC_CHECK_DEFINED(__APPLE__,[
|
||||
AC_SUBST(SHARED,dylib)
|
||||
],[
|
||||
AC_SUBST(SHARED,shared)
|
||||
])
|
||||
])
|
||||
fi
|
||||
|
||||
if test "${enable_it}" = no; then
|
||||
CFLAGS="${CFLAGS} -DLIBXMP_CORE_DISABLE_IT"
|
||||
fi
|
||||
|
||||
XMP_TRY_COMPILE(whether compiler understands -Wall,
|
||||
ac_cv_c_flag_w_all,
|
||||
-Wall,[
|
||||
int main(){}],
|
||||
CFLAGS="${CFLAGS} -Wall")
|
||||
|
||||
XMP_TRY_COMPILE(whether compiler understands -xldscope=hidden,
|
||||
ac_cv_c_flag_xldscope_hidden,
|
||||
-xldscope=hidden,[
|
||||
int main(){}],
|
||||
[LDFLAGS="${LDFLAGS} -xldscope=hidden"],
|
||||
[XMP_TRY_COMPILE(whether compiler understands -fvisibility=hidden,
|
||||
ac_cv_c_flag_f_visibility_hidden,
|
||||
-fvisibility=hidden,[
|
||||
int main(){}],
|
||||
[LDFLAGS="${LDFLAGS} -fvisibility=hidden"
|
||||
LD_VERSCRIPT="-Wl,--version-script,libxmp.map"])]
|
||||
)
|
||||
|
||||
dnl for clang
|
||||
XMP_TRY_COMPILE(whether compiler understands -Wunknown-warning-option,
|
||||
ac_cv_c_flag_w_unknown_warning_option,
|
||||
-Wunknown-warning-option,[
|
||||
int main(){}],
|
||||
CFLAGS="${CFLAGS} -Wno-unknown-warning-option")
|
||||
|
||||
XMP_TRY_COMPILE(whether compiler understands -Wunused-but-set-variable,
|
||||
ac_cv_c_flag_w_unused_but_set_variable,
|
||||
-Wunused-but-set-variable,[
|
||||
int main(){}],
|
||||
CFLAGS="${CFLAGS} -Wno-unused-but-set-variable")
|
||||
|
||||
XMP_TRY_COMPILE(whether compiler understands -Wunused-result,
|
||||
ac_cv_c_flag_w_unused_result,
|
||||
-Wunused-result,[
|
||||
int main(){}],
|
||||
CFLAGS="${CFLAGS} -Wno-unused-result")
|
||||
|
||||
XMP_TRY_COMPILE(whether compiler understands -Warray-bounds,
|
||||
ac_cv_c_flag_w_array_bounds,
|
||||
-Warray-bounds,[
|
||||
int main(){}],
|
||||
CFLAGS="${CFLAGS} -Wno-array-bounds")
|
||||
|
||||
AC_CHECK_LIB(m,pow)
|
||||
AC_CHECK_FUNCS(strlcpy strlcat)
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([libxmp-lite.pc])
|
||||
AC_OUTPUT
|
12
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/include/libxmp-lite/Makefile
vendored
Normal file
12
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/include/libxmp-lite/Makefile
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
INCLUDE_DFILES = Makefile xmp.h
|
||||
|
||||
INCLUDE_PATH = include/libxmp-lite
|
||||
|
||||
install-include:
|
||||
$(INSTALL_DATA) xmp.h $(DESTDIR)$(INCLUDEDIR)
|
||||
|
||||
dist-include:
|
||||
mkdir -p $(DIST)/$(INCLUDE_PATH)
|
||||
cp -RPp $(addprefix $(INCLUDE_PATH)/,$(INCLUDE_DFILES)) $(DIST)/$(INCLUDE_PATH)
|
||||
|
361
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/include/libxmp-lite/xmp.h
vendored
Normal file
361
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/include/libxmp-lite/xmp.h
vendored
Normal file
|
@ -0,0 +1,361 @@
|
|||
#ifndef XMP_H
|
||||
#define XMP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define XMP_VERSION "4.4.1"
|
||||
#define XMP_VERCODE 0x040401
|
||||
#define XMP_VER_MAJOR 4
|
||||
#define XMP_VER_MINOR 4
|
||||
#define XMP_VER_RELEASE 1
|
||||
|
||||
#define EXPORT
|
||||
/*
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# if defined(BUILDING_STATIC)
|
||||
# define EXPORT
|
||||
# elif defined(BUILDING_DLL)
|
||||
# define EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#elif __GNUC__ >= 4 || defined(__HP_cc)
|
||||
# define EXPORT __attribute__((visibility ("default")))
|
||||
#elif defined(__SUNPRO_C)
|
||||
# define EXPORT __global
|
||||
#elif defined(EMSCRIPTEN)
|
||||
# define EXPORT EMSCRIPTEN_KEEPALIVE
|
||||
#else
|
||||
# define EXPORT
|
||||
#endif
|
||||
*/
|
||||
|
||||
#define XMP_NAME_SIZE 64 /* Size of module name and type */
|
||||
|
||||
#define XMP_KEY_OFF 0x81 /* Note number for key off event */
|
||||
#define XMP_KEY_CUT 0x82 /* Note number for key cut event */
|
||||
#define XMP_KEY_FADE 0x83 /* Note number for fade event */
|
||||
|
||||
/* mixer parameter macros */
|
||||
|
||||
/* sample format flags */
|
||||
#define XMP_FORMAT_8BIT (1 << 0) /* Mix to 8-bit instead of 16 */
|
||||
#define XMP_FORMAT_UNSIGNED (1 << 1) /* Mix to unsigned samples */
|
||||
#define XMP_FORMAT_MONO (1 << 2) /* Mix to mono instead of stereo */
|
||||
|
||||
/* player parameters */
|
||||
#define XMP_PLAYER_AMP 0 /* Amplification factor */
|
||||
#define XMP_PLAYER_MIX 1 /* Stereo mixing */
|
||||
#define XMP_PLAYER_INTERP 2 /* Interpolation type */
|
||||
#define XMP_PLAYER_DSP 3 /* DSP effect flags */
|
||||
#define XMP_PLAYER_FLAGS 4 /* Player flags */
|
||||
#define XMP_PLAYER_CFLAGS 5 /* Player flags for current module */
|
||||
#define XMP_PLAYER_SMPCTL 6 /* Sample control flags */
|
||||
#define XMP_PLAYER_VOLUME 7 /* Player module volume */
|
||||
#define XMP_PLAYER_STATE 8 /* Internal player state (read only) */
|
||||
#define XMP_PLAYER_SMIX_VOLUME 9 /* SMIX volume */
|
||||
#define XMP_PLAYER_DEFPAN 10 /* Default pan setting */
|
||||
#define XMP_PLAYER_MODE 11 /* Player personality */
|
||||
#define XMP_PLAYER_MIXER_TYPE 12 /* Current mixer (read only) */
|
||||
#define XMP_PLAYER_VOICES 13 /* Maximum number of mixer voices */
|
||||
|
||||
/* interpolation types */
|
||||
#define XMP_INTERP_NEAREST 0 /* Nearest neighbor */
|
||||
#define XMP_INTERP_LINEAR 1 /* Linear (default) */
|
||||
#define XMP_INTERP_SPLINE 2 /* Cubic spline */
|
||||
|
||||
/* dsp effect types */
|
||||
#define XMP_DSP_LOWPASS (1 << 0) /* Lowpass filter effect */
|
||||
#define XMP_DSP_ALL (XMP_DSP_LOWPASS)
|
||||
|
||||
/* player state */
|
||||
#define XMP_STATE_UNLOADED 0 /* Context created */
|
||||
#define XMP_STATE_LOADED 1 /* Module loaded */
|
||||
#define XMP_STATE_PLAYING 2 /* Module playing */
|
||||
|
||||
/* player flags */
|
||||
#define XMP_FLAGS_VBLANK (1 << 0) /* Use vblank timing */
|
||||
#define XMP_FLAGS_FX9BUG (1 << 1) /* Emulate FX9 bug */
|
||||
#define XMP_FLAGS_FIXLOOP (1 << 2) /* Emulate sample loop bug */
|
||||
#define XMP_FLAGS_A500 (1 << 3) /* Use Paula mixer in Amiga modules */
|
||||
|
||||
/* player modes */
|
||||
#define XMP_MODE_AUTO 0 /* Autodetect mode (default) */
|
||||
#define XMP_MODE_MOD 1 /* Play as a generic MOD player */
|
||||
#define XMP_MODE_NOISETRACKER 2 /* Play using Noisetracker quirks */
|
||||
#define XMP_MODE_PROTRACKER 3 /* Play using Protracker quirks */
|
||||
#define XMP_MODE_S3M 4 /* Play as a generic S3M player */
|
||||
#define XMP_MODE_ST3 5 /* Play using ST3 bug emulation */
|
||||
#define XMP_MODE_ST3GUS 6 /* Play using ST3+GUS quirks */
|
||||
#define XMP_MODE_XM 7 /* Play as a generic XM player */
|
||||
#define XMP_MODE_FT2 8 /* Play using FT2 bug emulation */
|
||||
#define XMP_MODE_IT 9 /* Play using IT quirks */
|
||||
#define XMP_MODE_ITSMP 10 /* Play using IT sample mode quirks */
|
||||
|
||||
/* mixer types */
|
||||
#define XMP_MIXER_STANDARD 0 /* Standard mixer */
|
||||
#define XMP_MIXER_A500 1 /* Amiga 500 */
|
||||
#define XMP_MIXER_A500F 2 /* Amiga 500 with led filter */
|
||||
|
||||
/* sample flags */
|
||||
#define XMP_SMPCTL_SKIP (1 << 0) /* Don't load samples */
|
||||
|
||||
/* limits */
|
||||
#define XMP_MAX_KEYS 121 /* Number of valid keys */
|
||||
#define XMP_MAX_ENV_POINTS 32 /* Max number of envelope points */
|
||||
#define XMP_MAX_MOD_LENGTH 256 /* Max number of patterns in module */
|
||||
#define XMP_MAX_CHANNELS 64 /* Max number of channels in module */
|
||||
#define XMP_MAX_SRATE 49170 /* max sampling rate (Hz) */
|
||||
#define XMP_MIN_SRATE 4000 /* min sampling rate (Hz) */
|
||||
#define XMP_MIN_BPM 20 /* min BPM */
|
||||
/* frame rate = (50 * bpm / 125) Hz */
|
||||
/* frame size = (sampling rate * channels * size) / frame rate */
|
||||
#define XMP_MAX_FRAMESIZE (5 * XMP_MAX_SRATE * 2 / XMP_MIN_BPM)
|
||||
|
||||
/* error codes */
|
||||
#define XMP_END 1
|
||||
#define XMP_ERROR_INTERNAL 2 /* Internal error */
|
||||
#define XMP_ERROR_FORMAT 3 /* Unsupported module format */
|
||||
#define XMP_ERROR_LOAD 4 /* Error loading file */
|
||||
#define XMP_ERROR_DEPACK 5 /* Error depacking file */
|
||||
#define XMP_ERROR_SYSTEM 6 /* System error */
|
||||
#define XMP_ERROR_INVALID 7 /* Invalid parameter */
|
||||
#define XMP_ERROR_STATE 8 /* Invalid player state */
|
||||
|
||||
struct xmp_channel {
|
||||
int pan; /* Channel pan (0x80 is center) */
|
||||
int vol; /* Channel volume */
|
||||
#define XMP_CHANNEL_SYNTH (1 << 0) /* Channel is synthesized */
|
||||
#define XMP_CHANNEL_MUTE (1 << 1) /* Channel is muted */
|
||||
#define XMP_CHANNEL_SPLIT (1 << 2) /* Split Amiga channel in bits 5-4 */
|
||||
#define XMP_CHANNEL_SURROUND (1 << 4) /* Surround channel */
|
||||
int flg; /* Channel flags */
|
||||
};
|
||||
|
||||
struct xmp_pattern {
|
||||
int rows; /* Number of rows */
|
||||
int index[1]; /* Track index */
|
||||
};
|
||||
|
||||
struct xmp_event {
|
||||
unsigned char note; /* Note number (0 means no note) */
|
||||
unsigned char ins; /* Patch number */
|
||||
unsigned char vol; /* Volume (0 to basevol) */
|
||||
unsigned char fxt; /* Effect type */
|
||||
unsigned char fxp; /* Effect parameter */
|
||||
unsigned char f2t; /* Secondary effect type */
|
||||
unsigned char f2p; /* Secondary effect parameter */
|
||||
unsigned char _flag; /* Internal (reserved) flags */
|
||||
};
|
||||
|
||||
struct xmp_track {
|
||||
int rows; /* Number of rows */
|
||||
struct xmp_event event[1]; /* Event data */
|
||||
};
|
||||
|
||||
struct xmp_envelope {
|
||||
#define XMP_ENVELOPE_ON (1 << 0) /* Envelope is enabled */
|
||||
#define XMP_ENVELOPE_SUS (1 << 1) /* Envelope has sustain point */
|
||||
#define XMP_ENVELOPE_LOOP (1 << 2) /* Envelope has loop */
|
||||
#define XMP_ENVELOPE_FLT (1 << 3) /* Envelope is used for filter */
|
||||
#define XMP_ENVELOPE_SLOOP (1 << 4) /* Envelope has sustain loop */
|
||||
#define XMP_ENVELOPE_CARRY (1 << 5) /* Don't reset envelope position */
|
||||
int flg; /* Flags */
|
||||
int npt; /* Number of envelope points */
|
||||
int scl; /* Envelope scaling */
|
||||
int sus; /* Sustain start point */
|
||||
int sue; /* Sustain end point */
|
||||
int lps; /* Loop start point */
|
||||
int lpe; /* Loop end point */
|
||||
short data[XMP_MAX_ENV_POINTS * 2];
|
||||
};
|
||||
|
||||
struct xmp_instrument {
|
||||
char name[32]; /* Instrument name */
|
||||
int vol; /* Instrument volume */
|
||||
int nsm; /* Number of samples */
|
||||
int rls; /* Release (fadeout) */
|
||||
struct xmp_envelope aei; /* Amplitude envelope info */
|
||||
struct xmp_envelope pei; /* Pan envelope info */
|
||||
struct xmp_envelope fei; /* Frequency envelope info */
|
||||
|
||||
struct {
|
||||
unsigned char ins; /* Instrument number for each key */
|
||||
signed char xpo; /* Instrument transpose for each key */
|
||||
} map[XMP_MAX_KEYS];
|
||||
|
||||
struct xmp_subinstrument {
|
||||
int vol; /* Default volume */
|
||||
int gvl; /* Global volume */
|
||||
int pan; /* Pan */
|
||||
int xpo; /* Transpose */
|
||||
int fin; /* Finetune */
|
||||
int vwf; /* Vibrato waveform */
|
||||
int vde; /* Vibrato depth */
|
||||
int vra; /* Vibrato rate */
|
||||
int vsw; /* Vibrato sweep */
|
||||
int rvv; /* Random volume/pan variation (IT) */
|
||||
int sid; /* Sample number */
|
||||
#define XMP_INST_NNA_CUT 0x00
|
||||
#define XMP_INST_NNA_CONT 0x01
|
||||
#define XMP_INST_NNA_OFF 0x02
|
||||
#define XMP_INST_NNA_FADE 0x03
|
||||
int nna; /* New note action */
|
||||
#define XMP_INST_DCT_OFF 0x00
|
||||
#define XMP_INST_DCT_NOTE 0x01
|
||||
#define XMP_INST_DCT_SMP 0x02
|
||||
#define XMP_INST_DCT_INST 0x03
|
||||
int dct; /* Duplicate check type */
|
||||
#define XMP_INST_DCA_CUT XMP_INST_NNA_CUT
|
||||
#define XMP_INST_DCA_OFF XMP_INST_NNA_OFF
|
||||
#define XMP_INST_DCA_FADE XMP_INST_NNA_FADE
|
||||
int dca; /* Duplicate check action */
|
||||
int ifc; /* Initial filter cutoff */
|
||||
int ifr; /* Initial filter resonance */
|
||||
} *sub;
|
||||
|
||||
void *extra; /* Extra fields */
|
||||
};
|
||||
|
||||
struct xmp_sample {
|
||||
char name[32]; /* Sample name */
|
||||
int len; /* Sample length */
|
||||
int lps; /* Loop start */
|
||||
int lpe; /* Loop end */
|
||||
#define XMP_SAMPLE_16BIT (1 << 0) /* 16bit sample */
|
||||
#define XMP_SAMPLE_LOOP (1 << 1) /* Sample is looped */
|
||||
#define XMP_SAMPLE_LOOP_BIDIR (1 << 2) /* Bidirectional sample loop */
|
||||
#define XMP_SAMPLE_LOOP_REVERSE (1 << 3) /* Backwards sample loop */
|
||||
#define XMP_SAMPLE_LOOP_FULL (1 << 4) /* Play full sample before looping */
|
||||
#define XMP_SAMPLE_SLOOP (1 << 5) /* Sample has sustain loop */
|
||||
#define XMP_SAMPLE_SLOOP_BIDIR (1 << 6) /* Bidirectional sustain loop */
|
||||
#define XMP_SAMPLE_SYNTH (1 << 15) /* Data contains synth patch */
|
||||
int flg; /* Flags */
|
||||
unsigned char *data; /* Sample data */
|
||||
};
|
||||
|
||||
struct xmp_sequence {
|
||||
int entry_point;
|
||||
int duration;
|
||||
};
|
||||
|
||||
struct xmp_module {
|
||||
char name[XMP_NAME_SIZE]; /* Module title */
|
||||
char type[XMP_NAME_SIZE]; /* Module format */
|
||||
int pat; /* Number of patterns */
|
||||
int trk; /* Number of tracks */
|
||||
int chn; /* Tracks per pattern */
|
||||
int ins; /* Number of instruments */
|
||||
int smp; /* Number of samples */
|
||||
int spd; /* Initial speed */
|
||||
int bpm; /* Initial BPM */
|
||||
int len; /* Module length in patterns */
|
||||
int rst; /* Restart position */
|
||||
int gvl; /* Global volume */
|
||||
|
||||
struct xmp_pattern **xxp; /* Patterns */
|
||||
struct xmp_track **xxt; /* Tracks */
|
||||
struct xmp_instrument *xxi; /* Instruments */
|
||||
struct xmp_sample *xxs; /* Samples */
|
||||
struct xmp_channel xxc[XMP_MAX_CHANNELS]; /* Channel info */
|
||||
unsigned char xxo[XMP_MAX_MOD_LENGTH]; /* Orders */
|
||||
};
|
||||
|
||||
struct xmp_test_info {
|
||||
char name[XMP_NAME_SIZE]; /* Module title */
|
||||
char type[XMP_NAME_SIZE]; /* Module format */
|
||||
};
|
||||
|
||||
struct xmp_module_info {
|
||||
unsigned char md5[16]; /* MD5 message digest */
|
||||
int vol_base; /* Volume scale */
|
||||
struct xmp_module *mod; /* Pointer to module data */
|
||||
char *comment; /* Comment text, if any */
|
||||
int num_sequences; /* Number of valid sequences */
|
||||
struct xmp_sequence *seq_data; /* Pointer to sequence data */
|
||||
};
|
||||
|
||||
struct xmp_frame_info { /* Current frame information */
|
||||
int pos; /* Current position */
|
||||
int pattern; /* Current pattern */
|
||||
int row; /* Current row in pattern */
|
||||
int num_rows; /* Number of rows in current pattern */
|
||||
int frame; /* Current frame */
|
||||
int speed; /* Current replay speed */
|
||||
int bpm; /* Current bpm */
|
||||
int time; /* Current module time in ms */
|
||||
int total_time; /* Estimated replay time in ms*/
|
||||
int frame_time; /* Frame replay time in us */
|
||||
void *buffer; /* Pointer to sound buffer */
|
||||
int buffer_size; /* Used buffer size */
|
||||
int total_size; /* Total buffer size */
|
||||
int volume; /* Current master volume */
|
||||
int loop_count; /* Loop counter */
|
||||
int virt_channels; /* Number of virtual channels */
|
||||
int virt_used; /* Used virtual channels */
|
||||
int sequence; /* Current sequence */
|
||||
|
||||
struct xmp_channel_info { /* Current channel information */
|
||||
unsigned int period; /* Sample period (* 4096) */
|
||||
unsigned int position; /* Sample position */
|
||||
short pitchbend; /* Linear bend from base note*/
|
||||
unsigned char note; /* Current base note number */
|
||||
unsigned char instrument; /* Current instrument number */
|
||||
unsigned char sample; /* Current sample number */
|
||||
unsigned char volume; /* Current volume */
|
||||
unsigned char pan; /* Current stereo pan */
|
||||
unsigned char reserved; /* Reserved */
|
||||
struct xmp_event event; /* Current track event */
|
||||
} channel_info[XMP_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
|
||||
typedef char *xmp_context;
|
||||
|
||||
EXPORT extern const char *xmp_version;
|
||||
EXPORT extern const unsigned int xmp_vercode;
|
||||
|
||||
EXPORT xmp_context xmp_create_context (void);
|
||||
EXPORT void xmp_free_context (xmp_context);
|
||||
EXPORT int xmp_test_module (char *, struct xmp_test_info *);
|
||||
EXPORT int xmp_load_module (xmp_context, char *);
|
||||
EXPORT void xmp_scan_module (xmp_context);
|
||||
EXPORT void xmp_release_module (xmp_context);
|
||||
EXPORT int xmp_start_player (xmp_context, int, int);
|
||||
EXPORT int xmp_play_frame (xmp_context);
|
||||
EXPORT int xmp_play_buffer (xmp_context, void *, int, int);
|
||||
EXPORT void xmp_get_frame_info (xmp_context, struct xmp_frame_info *);
|
||||
EXPORT void xmp_end_player (xmp_context);
|
||||
EXPORT void xmp_inject_event (xmp_context, int, struct xmp_event *);
|
||||
EXPORT void xmp_get_module_info (xmp_context, struct xmp_module_info *);
|
||||
EXPORT char **xmp_get_format_list (void);
|
||||
EXPORT int xmp_next_position (xmp_context);
|
||||
EXPORT int xmp_prev_position (xmp_context);
|
||||
EXPORT int xmp_set_position (xmp_context, int);
|
||||
EXPORT void xmp_stop_module (xmp_context);
|
||||
EXPORT void xmp_restart_module (xmp_context);
|
||||
EXPORT int xmp_seek_time (xmp_context, int);
|
||||
EXPORT int xmp_channel_mute (xmp_context, int, int);
|
||||
EXPORT int xmp_channel_vol (xmp_context, int, int);
|
||||
EXPORT int xmp_set_player (xmp_context, int, int);
|
||||
EXPORT int xmp_get_player (xmp_context, int);
|
||||
EXPORT int xmp_set_instrument_path (xmp_context, char *);
|
||||
EXPORT int xmp_load_module_from_memory (xmp_context, void *, long);
|
||||
//EXPORT int xmp_load_module_from_file (xmp_context, void *, long);
|
||||
|
||||
/* External sample mixer API */
|
||||
EXPORT int xmp_start_smix (xmp_context, int, int);
|
||||
EXPORT void xmp_end_smix (xmp_context);
|
||||
EXPORT int xmp_smix_play_instrument(xmp_context, int, int, int, int);
|
||||
EXPORT int xmp_smix_play_sample (xmp_context, int, int, int, int);
|
||||
EXPORT int xmp_smix_channel_pan (xmp_context, int, int);
|
||||
EXPORT int xmp_smix_load_sample (xmp_context, int, char *);
|
||||
EXPORT int xmp_smix_release_sample (xmp_context, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XMP_H */
|
520
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/install-sh
vendored
Normal file
520
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/install-sh
vendored
Normal file
|
@ -0,0 +1,520 @@
|
|||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dst_arg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
-*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test -z "$d" && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
17
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/jni/Android.mk
vendored
Normal file
17
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/jni/Android.mk
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
LOCAL_PATH := $(call my-dir)/..
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
include $(LOCAL_PATH)/src/Makefile
|
||||
include $(LOCAL_PATH)/src/loaders/Makefile
|
||||
|
||||
SRC_SOURCES := $(addprefix src/,$(SRC_OBJS))
|
||||
LOADERS_SOURCES := $(addprefix src/loaders/,$(LOADERS_OBJS))
|
||||
|
||||
LOCAL_MODULE := xmp
|
||||
LOCAL_CFLAGS := -O3 -DHAVE_MKSTEMP -DHAVE_FNMATCH -DLIBXMP_CORE_PLAYER \
|
||||
-I$(LOCAL_PATH)/include/libxmp-lite -I$(LOCAL_PATH)/src
|
||||
LOCAL_SRC_FILES := $(SRC_SOURCES:.o=.c.arm) \
|
||||
$(LOADERS_SOURCES:.o=.c)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
4
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/jni/Application.mk
vendored
Normal file
4
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/jni/Application.mk
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
APP_PROJECT_PATH := $(call my-dir)
|
||||
APP_MODULES := libxmp
|
||||
APP_ABI := armeabi armeabi-v7a x86
|
||||
APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/Android.mk
|
13
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/libxmp-lite.pc.in
vendored
Normal file
13
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/libxmp-lite.pc.in
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@/libxmp-lite
|
||||
|
||||
Name: libxmp-lite
|
||||
Description: Xmp lite module player library
|
||||
Version: 4.4.1
|
||||
|
||||
Requires:
|
||||
Libs: -L${libdir} -lxmp-lite
|
||||
Cflags: -I${includedir}
|
||||
Libs.private: -lm
|
65
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/libxmp.map
vendored
Normal file
65
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/libxmp.map
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
XMP_4.0 {
|
||||
global:
|
||||
xmp_version;
|
||||
xmp_vercode;
|
||||
xmp_get_format_list;
|
||||
xmp_create_context;
|
||||
xmp_free_context;
|
||||
xmp_test_module;
|
||||
xmp_load_module;
|
||||
xmp_release_module;
|
||||
xmp_scan_module;
|
||||
xmp_get_module_info;
|
||||
xmp_start_player;
|
||||
xmp_play_frame;
|
||||
xmp_get_frame_info;
|
||||
xmp_end_player;
|
||||
xmp_next_position;
|
||||
xmp_prev_position;
|
||||
xmp_set_position;
|
||||
xmp_stop_module;
|
||||
xmp_restart_module;
|
||||
xmp_seek_time;
|
||||
xmp_channel_mute;
|
||||
xmp_channel_vol;
|
||||
xmp_inject_event;
|
||||
xmp_set_player;
|
||||
xmp_get_player;
|
||||
xmp_set_instrument_path;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
XMP_4.1 {
|
||||
global:
|
||||
xmp_set_player;
|
||||
xmp_get_player;
|
||||
xmp_play_buffer;
|
||||
} XMP_4.0;
|
||||
|
||||
XMP_4.2 {
|
||||
global:
|
||||
xmp_get_player;
|
||||
xmp_load_module_from_memory;
|
||||
xmp_start_smix;
|
||||
xmp_end_smix;
|
||||
xmp_smix_play_instrument;
|
||||
xmp_smix_play_sample;
|
||||
xmp_smix_channel_pan;
|
||||
xmp_smix_load_sample;
|
||||
xmp_smix_release_sample;
|
||||
} XMP_4.1;
|
||||
|
||||
XMP_4.3 {
|
||||
global:
|
||||
xmp_set_player;
|
||||
xmp_get_player;
|
||||
xmp_load_module_from_file;
|
||||
} XMP_4.2;
|
||||
|
||||
XMP_4.4 {
|
||||
global:
|
||||
xmp_set_player;
|
||||
xmp_get_player;
|
||||
} XMP_4.3;
|
||||
|
21
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/Makefile
vendored
Normal file
21
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/Makefile
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
SRC_OBJS = virtual.o format.o period.o player.o read_event.o \
|
||||
dataio.o lfo.o scan.o control.o filter.o \
|
||||
effects.o mixer.o mix_all.o load_helpers.o load.o \
|
||||
hio.o smix.o memio.o
|
||||
|
||||
SRC_DFILES = Makefile $(SRC_OBJS:.o=.c) common.h effects.h \
|
||||
format.h lfo.h list.h mixer.h period.h player.h virtual.h \
|
||||
precomp_lut.h hio.h memio.h mdataio.h tempfile.h
|
||||
|
||||
SRC_PATH = src
|
||||
|
||||
OBJS += $(addprefix $(SRC_PATH)/,$(SRC_OBJS))
|
||||
|
||||
default-src::
|
||||
$(MAKE) -C ..
|
||||
|
||||
dist-src::
|
||||
mkdir -p $(DIST)/$(SRC_PATH)
|
||||
cp -RPp $(addprefix $(SRC_PATH)/,$(SRC_DFILES)) $(DIST)/$(SRC_PATH)
|
||||
|
411
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/common.h
vendored
Normal file
411
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/common.h
vendored
Normal file
|
@ -0,0 +1,411 @@
|
|||
#ifndef LIBXMP_COMMON_H
|
||||
#define LIBXMP_COMMON_H
|
||||
|
||||
#ifdef __AROS__
|
||||
#define __AMIGA__
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "xmp.h"
|
||||
/*
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#if !defined(WIN32) && !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__AMIGA__) && !defined(B_BEOS_VERSION) && !defined(__ATHEOS__) && !defined(EMSCRIPTEN) && !defined(__MINT__)
|
||||
#define USE_VERSIONED_SYMBOLS
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
/* AmigaOS fixes by Chris Young <cdyoung@ntlworld.com>, Nov 25, 2007
|
||||
*/
|
||||
#if defined B_BEOS_VERSION
|
||||
# include <SupportDefs.h>
|
||||
#elif defined __amigaos4__
|
||||
# include <exec/types.h>
|
||||
#else
|
||||
typedef signed char int8;
|
||||
typedef signed short int int16;
|
||||
typedef signed int int32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short int uint16;
|
||||
typedef unsigned int uint32;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER /* MSVC++6.0 has no long long */
|
||||
typedef signed __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#elif !defined B_BEOS_VERSION /* BeOS has its own int64 definition */
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed long long int64;
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
#define LIBXMP_PAULA_SIMULATOR
|
||||
#endif
|
||||
|
||||
/* Constants */
|
||||
#define PAL_RATE 250.0 /* 1 / (50Hz * 80us) */
|
||||
#define NTSC_RATE 208.0 /* 1 / (60Hz * 80us) */
|
||||
#define C4_PAL_RATE 8287 /* 7093789.2 / period (C4) * 2 */
|
||||
#define C4_NTSC_RATE 8363 /* 7159090.5 / period (C4) * 2 */
|
||||
|
||||
/* [Amiga] PAL color carrier frequency (PCCF) = 4.43361825 MHz */
|
||||
/* [Amiga] CPU clock = 1.6 * PCCF = 7.0937892 MHz */
|
||||
|
||||
#define DEFAULT_AMPLIFY 1
|
||||
#define DEFAULT_MIX 100
|
||||
|
||||
#define MSN(x) (((x)&0xf0)>>4)
|
||||
#define LSN(x) ((x)&0x0f)
|
||||
#define SET_FLAG(a,b) ((a)|=(b))
|
||||
#define RESET_FLAG(a,b) ((a)&=~(b))
|
||||
#define TEST_FLAG(a,b) !!((a)&(b))
|
||||
|
||||
#define CLAMP(x,a,b) do { \
|
||||
if ((x) < (a)) (x) = (a); \
|
||||
else if ((x) > (b)) (x) = (b); \
|
||||
} while (0)
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
#define TRACK_NUM(a,c) m->mod.xxp[a]->index[c]
|
||||
#define EVENT(a,c,r) m->mod.xxt[TRACK_NUM((a),(c))]->event[r]
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define D_CRIT " Error: "
|
||||
#define D_WARN "Warning: "
|
||||
#define D_INFO " Info: "
|
||||
#ifndef CLIB_DECL
|
||||
#define CLIB_DECL
|
||||
#endif
|
||||
// VS prior to VC7.1 does not support variadic macros. VC8.0 does not optimize unused parameters passing
|
||||
#if _MSC_VER < 1400
|
||||
void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); }
|
||||
#else
|
||||
#define D_(args, ...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#elif defined __ANDROID__
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <android/log.h>
|
||||
#define D_CRIT " Error: "
|
||||
#define D_WARN "Warning: "
|
||||
#define D_INFO " Info: "
|
||||
#define D_(args...) do { \
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "libxmp", args); \
|
||||
} while (0)
|
||||
#else
|
||||
#define D_(args...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef DEBUG
|
||||
#define D_INFO "\x1b[33m"
|
||||
#define D_CRIT "\x1b[31m"
|
||||
#define D_WARN "\x1b[36m"
|
||||
#define D_(args...) do { \
|
||||
printf("\x1b[33m%s \x1b[37m[%s:%d] " D_INFO, __FUNCTION__, \
|
||||
__FILE__, __LINE__); printf (args); printf ("\x1b[0m\n"); \
|
||||
} while (0)
|
||||
#else
|
||||
//#define D_(args...) do {} while (0)
|
||||
#define D_(...)
|
||||
#endif
|
||||
|
||||
#endif /* !_MSC_VER */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define dup _dup
|
||||
#define fileno _fileno
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#define strnicmp _strnicmp
|
||||
#define strdup _strdup
|
||||
#define fdopen _fdopen
|
||||
#define open _open
|
||||
#define close _close
|
||||
#define unlink _unlink
|
||||
#endif
|
||||
|
||||
/* Quirks */
|
||||
#define QUIRK_S3MLOOP (1 << 0) /* S3M loop mode */
|
||||
#define QUIRK_ENVFADE (1 << 1) /* Fade at end of envelope */
|
||||
#define QUIRK_PROTRACK (1 << 2) /* Use Protracker-specific quirks */
|
||||
#define QUIRK_ST3BUGS (1 << 4) /* Scream Tracker 3 bug compatibility */
|
||||
#define QUIRK_FINEFX (1 << 5) /* Enable 0xf/0xe for fine effects */
|
||||
#define QUIRK_VSALL (1 << 6) /* Volume slides in all frames */
|
||||
#define QUIRK_PBALL (1 << 7) /* Pitch bending in all frames */
|
||||
#define QUIRK_PERPAT (1 << 8) /* Cancel persistent fx at pat start */
|
||||
#define QUIRK_VOLPDN (1 << 9) /* Set priority to volume slide down */
|
||||
#define QUIRK_UNISLD (1 << 10) /* Unified pitch slide/portamento */
|
||||
#define QUIRK_ITVPOR (1 << 11) /* Disable fine bends in IT vol fx */
|
||||
#define QUIRK_FTMOD (1 << 12) /* Flag for multichannel mods */
|
||||
/*#define QUIRK_MODRNG (1 << 13)*/ /* Limit periods to MOD range */
|
||||
#define QUIRK_INSVOL (1 << 14) /* Use instrument volume */
|
||||
#define QUIRK_VIRTUAL (1 << 15) /* Enable virtual channels */
|
||||
#define QUIRK_FILTER (1 << 16) /* Enable filter */
|
||||
#define QUIRK_IGSTPOR (1 << 17) /* Ignore stray tone portamento */
|
||||
#define QUIRK_KEYOFF (1 << 18) /* Keyoff doesn't reset fadeout */
|
||||
#define QUIRK_VIBHALF (1 << 19) /* Vibrato is half as deep */
|
||||
#define QUIRK_VIBALL (1 << 20) /* Vibrato in all frames */
|
||||
#define QUIRK_VIBINV (1 << 21) /* Vibrato has inverse waveform */
|
||||
#define QUIRK_PRENV (1 << 22) /* Portamento resets envelope & fade */
|
||||
#define QUIRK_ITOLDFX (1 << 23) /* IT old effects mode */
|
||||
#define QUIRK_S3MRTG (1 << 24) /* S3M-style retrig when count == 0 */
|
||||
#define QUIRK_RTDELAY (1 << 25) /* Delay effect retrigs instrument */
|
||||
#define QUIRK_FT2BUGS (1 << 26) /* FT2 bug compatibility */
|
||||
#define QUIRK_MARKER (1 << 27) /* Patterns 0xfe and 0xff reserved */
|
||||
#define QUIRK_NOBPM (1 << 28) /* Adjust speed only, no BPM */
|
||||
#define QUIRK_ARPMEM (1 << 29) /* Arpeggio has memory (S3M_ARPEGGIO) */
|
||||
#define QUIRK_RSTCHN (1 << 30) /* Reset channel on sample end */
|
||||
|
||||
#define HAS_QUIRK(x) (m->quirk & (x))
|
||||
|
||||
|
||||
/* Format quirks */
|
||||
#define QUIRKS_ST3 (QUIRK_S3MLOOP | QUIRK_VOLPDN | QUIRK_FINEFX | \
|
||||
QUIRK_S3MRTG | QUIRK_MARKER | QUIRK_RSTCHN )
|
||||
#define QUIRKS_FT2 (QUIRK_RTDELAY | QUIRK_FINEFX )
|
||||
#define QUIRKS_IT (QUIRK_S3MLOOP | QUIRK_FINEFX | QUIRK_VIBALL | \
|
||||
QUIRK_ENVFADE | QUIRK_ITVPOR | QUIRK_KEYOFF | \
|
||||
QUIRK_VIRTUAL | QUIRK_FILTER | QUIRK_RSTCHN | \
|
||||
QUIRK_IGSTPOR | QUIRK_S3MRTG | QUIRK_MARKER )
|
||||
|
||||
/* DSP effects */
|
||||
#define DSP_EFFECT_CUTOFF 0x02
|
||||
#define DSP_EFFECT_RESONANCE 0x03
|
||||
#define DSP_EFFECT_FILTER_A0 0xb0
|
||||
#define DSP_EFFECT_FILTER_B0 0xb1
|
||||
#define DSP_EFFECT_FILTER_B1 0xb2
|
||||
|
||||
/* Time factor */
|
||||
#define DEFAULT_TIME_FACTOR 10.0
|
||||
#define MED_TIME_FACTOR 2.64
|
||||
|
||||
#define MAX_SEQUENCES 16
|
||||
#define MAX_SAMPLE_SIZE 0x10000000
|
||||
#define MAX_SAMPLES 1024
|
||||
|
||||
#define IS_PLAYER_MODE_MOD() (m->read_event_type == READ_EVENT_MOD)
|
||||
#define IS_PLAYER_MODE_FT2() (m->read_event_type == READ_EVENT_FT2)
|
||||
#define IS_PLAYER_MODE_ST3() (m->read_event_type == READ_EVENT_ST3)
|
||||
#define IS_PLAYER_MODE_IT() (m->read_event_type == READ_EVENT_IT)
|
||||
#define IS_PLAYER_MODE_MED() (m->read_event_type == READ_EVENT_MED)
|
||||
#define IS_PERIOD_MODRNG() (m->period_type == PERIOD_MODRNG)
|
||||
#define IS_PERIOD_LINEAR() (m->period_type == PERIOD_LINEAR)
|
||||
#define IS_PERIOD_CSPD() (m->period_type == PERIOD_CSPD)
|
||||
|
||||
#define IS_AMIGA_MOD() (IS_PLAYER_MODE_MOD() && IS_PERIOD_MODRNG())
|
||||
|
||||
struct ord_data {
|
||||
int speed;
|
||||
int bpm;
|
||||
int gvl;
|
||||
int time;
|
||||
int start_row;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
int st26_speed;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Context */
|
||||
|
||||
struct smix_data {
|
||||
int chn;
|
||||
int ins;
|
||||
int smp;
|
||||
struct xmp_instrument *xxi;
|
||||
struct xmp_sample *xxs;
|
||||
};
|
||||
|
||||
/* This will be added to the sample structure in the next API revision */
|
||||
struct extra_sample_data {
|
||||
double c5spd;
|
||||
};
|
||||
|
||||
struct module_data {
|
||||
struct xmp_module mod;
|
||||
|
||||
char *dirname; /* file dirname */
|
||||
char *basename; /* file basename */
|
||||
char *filename; /* Module file name */
|
||||
char *comment; /* Comments, if any */
|
||||
uint8 md5[16]; /* MD5 message digest */
|
||||
int size; /* File size */
|
||||
double rrate; /* Replay rate */
|
||||
double time_factor; /* Time conversion constant */
|
||||
int c4rate; /* C4 replay rate */
|
||||
int volbase; /* Volume base */
|
||||
int gvolbase; /* Global volume base */
|
||||
int gvol; /* Global volume */
|
||||
int *vol_table; /* Volume translation table */
|
||||
int quirk; /* player quirks */
|
||||
#define READ_EVENT_MOD 0
|
||||
#define READ_EVENT_FT2 1
|
||||
#define READ_EVENT_ST3 2
|
||||
#define READ_EVENT_IT 3
|
||||
#define READ_EVENT_MED 4
|
||||
int read_event_type;
|
||||
#define PERIOD_AMIGA 0
|
||||
#define PERIOD_MODRNG 1
|
||||
#define PERIOD_LINEAR 2
|
||||
#define PERIOD_CSPD 3
|
||||
int period_type;
|
||||
int smpctl; /* sample control flags */
|
||||
int defpan; /* default pan setting */
|
||||
struct ord_data xxo_info[XMP_MAX_MOD_LENGTH];
|
||||
int num_sequences;
|
||||
struct xmp_sequence seq_data[MAX_SEQUENCES];
|
||||
char *instrument_path;
|
||||
void *extra; /* format-specific extra fields */
|
||||
char **scan_cnt; /* scan counters */
|
||||
struct extra_sample_data *xtra;
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
struct xmp_sample *xsmp; /* sustain loop samples */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct player_data {
|
||||
int ord;
|
||||
int pos;
|
||||
int row;
|
||||
int frame;
|
||||
int speed;
|
||||
int bpm;
|
||||
int mode;
|
||||
int player_flags;
|
||||
int flags;
|
||||
|
||||
double current_time;
|
||||
double frame_time;
|
||||
|
||||
int loop_count;
|
||||
int sequence;
|
||||
unsigned char sequence_control[XMP_MAX_MOD_LENGTH];
|
||||
|
||||
int smix_vol; /* SFX volume */
|
||||
int master_vol; /* Music volume */
|
||||
int gvol;
|
||||
|
||||
struct flow_control {
|
||||
int pbreak;
|
||||
int jump;
|
||||
int delay;
|
||||
int jumpline;
|
||||
int loop_chn;
|
||||
|
||||
struct pattern_loop {
|
||||
int start;
|
||||
int count;
|
||||
} *loop;
|
||||
|
||||
int num_rows;
|
||||
int end_point;
|
||||
int rowdelay; /* For IT pattern row delay */
|
||||
int rowdelay_set;
|
||||
} flow;
|
||||
|
||||
struct {
|
||||
int time; /* replay time in ms */
|
||||
int ord;
|
||||
int row;
|
||||
int num;
|
||||
} scan[MAX_SEQUENCES];
|
||||
|
||||
struct channel_data *xc_data;
|
||||
|
||||
int channel_vol[XMP_MAX_CHANNELS];
|
||||
char channel_mute[XMP_MAX_CHANNELS];
|
||||
|
||||
struct virt_control {
|
||||
int num_tracks; /* Number of tracks */
|
||||
int virt_channels; /* Number of virtual channels */
|
||||
int virt_used; /* Number of voices currently in use */
|
||||
int maxvoc; /* Number of sound card voices */
|
||||
|
||||
struct virt_channel {
|
||||
int count;
|
||||
int map;
|
||||
} *virt_channel;
|
||||
|
||||
struct mixer_voice *voice_array;
|
||||
} virt;
|
||||
|
||||
struct xmp_event inject_event[XMP_MAX_CHANNELS];
|
||||
|
||||
struct {
|
||||
int consumed;
|
||||
int in_size;
|
||||
char *in_buffer;
|
||||
} buffer_data;
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
int st26_speed; /* For IceTracker speed effect */
|
||||
#endif
|
||||
int filter; /* Amiga led filter */
|
||||
};
|
||||
|
||||
struct mixer_data {
|
||||
int freq; /* sampling rate */
|
||||
int format; /* sample format */
|
||||
int amplify; /* amplification multiplier */
|
||||
int mix; /* percentage of channel separation */
|
||||
int interp; /* interpolation type */
|
||||
int dsp; /* dsp effect flags */
|
||||
char* buffer; /* output buffer */
|
||||
int32* buf32; /* temporary buffer for 32 bit samples */
|
||||
int numvoc; /* default softmixer voices number */
|
||||
int ticksize;
|
||||
int dtright; /* anticlick control, right channel */
|
||||
int dtleft; /* anticlick control, left channel */
|
||||
double pbase; /* period base */
|
||||
};
|
||||
|
||||
struct context_data {
|
||||
struct player_data p;
|
||||
struct mixer_data s;
|
||||
struct module_data m;
|
||||
struct smix_data smix;
|
||||
int state;
|
||||
};
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
char *libxmp_adjust_string (char *);
|
||||
int libxmp_exclude_match (char *);
|
||||
int libxmp_prepare_scan (struct context_data *);
|
||||
int libxmp_scan_sequences (struct context_data *);
|
||||
int libxmp_get_sequence (struct context_data *, int);
|
||||
int libxmp_set_player_mode (struct context_data *);
|
||||
|
||||
int8 read8s (FILE *, int *err);
|
||||
uint8 read8 (FILE *, int *err);
|
||||
uint16 read16l (FILE *, int *err);
|
||||
uint16 read16b (FILE *, int *err);
|
||||
uint32 read24l (FILE *, int *err);
|
||||
uint32 read24b (FILE *, int *err);
|
||||
uint32 read32l (FILE *, int *err);
|
||||
uint32 read32b (FILE *, int *err);
|
||||
void write8 (FILE *, uint8);
|
||||
void write16l (FILE *, uint16);
|
||||
void write16b (FILE *, uint16);
|
||||
void write32l (FILE *, uint32);
|
||||
void write32b (FILE *, uint32);
|
||||
int move_data (FILE *, FILE *, int);
|
||||
|
||||
uint16 readmem16l (uint8 *);
|
||||
uint16 readmem16b (uint8 *);
|
||||
uint32 readmem24l (uint8 *);
|
||||
uint32 readmem24b (uint8 *);
|
||||
uint32 readmem32l (uint8 *);
|
||||
uint32 readmem32b (uint8 *);
|
||||
|
||||
struct xmp_instrument *libxmp_get_instrument(struct context_data *, int);
|
||||
struct xmp_sample *libxmp_get_sample(struct context_data *, int);
|
||||
|
||||
#endif /* LIBXMP_COMMON_H */
|
529
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/control.c
vendored
Normal file
529
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/control.c
vendored
Normal file
|
@ -0,0 +1,529 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "format.h"
|
||||
#include "virtual.h"
|
||||
#include "mixer.h"
|
||||
|
||||
const char *xmp_version = XMP_VERSION;
|
||||
const unsigned int xmp_vercode = XMP_VERCODE;
|
||||
|
||||
xmp_context xmp_create_context()
|
||||
{
|
||||
struct context_data *ctx;
|
||||
|
||||
ctx = calloc(1, sizeof(struct context_data));
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->state = XMP_STATE_UNLOADED;
|
||||
ctx->m.defpan = 100;
|
||||
ctx->s.numvoc = SMIX_NUMVOC;
|
||||
|
||||
return (xmp_context)ctx;
|
||||
}
|
||||
|
||||
void xmp_free_context(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
|
||||
if (ctx->state > XMP_STATE_UNLOADED)
|
||||
xmp_release_module(opaque);
|
||||
|
||||
free(opaque);
|
||||
}
|
||||
|
||||
static void set_position(struct context_data *ctx, int pos, int dir)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct flow_control *f = &p->flow;
|
||||
int seq;
|
||||
int has_marker;
|
||||
|
||||
/* If dir is 0, we can jump to a different sequence */
|
||||
if (dir == 0) {
|
||||
seq = libxmp_get_sequence(ctx, pos);
|
||||
} else {
|
||||
seq = p->sequence;
|
||||
}
|
||||
|
||||
if (seq == 0xff) {
|
||||
return;
|
||||
}
|
||||
|
||||
has_marker = HAS_QUIRK(QUIRK_MARKER);
|
||||
|
||||
if (seq >= 0) {
|
||||
int start = m->seq_data[seq].entry_point;
|
||||
|
||||
p->sequence = seq;
|
||||
|
||||
if (pos >= 0) {
|
||||
int pat;
|
||||
|
||||
while (has_marker && mod->xxo[pos] == 0xfe) {
|
||||
if (dir < 0) {
|
||||
if (pos > start) {
|
||||
pos--;
|
||||
}
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
pat = mod->xxo[pos];
|
||||
|
||||
if (pat < mod->pat) {
|
||||
if (has_marker && pat == 0xff) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pos > p->scan[seq].ord) {
|
||||
f->end_point = 0;
|
||||
} else {
|
||||
f->num_rows = mod->xxp[pat]->rows;
|
||||
f->end_point = p->scan[seq].num;
|
||||
f->jumpline = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pos < mod->len) {
|
||||
if (pos == 0) {
|
||||
p->pos = -1;
|
||||
} else {
|
||||
p->pos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int xmp_next_position(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return -XMP_ERROR_STATE;
|
||||
|
||||
if (p->pos < m->mod.len)
|
||||
set_position(ctx, p->pos + 1, 1);
|
||||
|
||||
return p->pos;
|
||||
}
|
||||
|
||||
int xmp_prev_position(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return -XMP_ERROR_STATE;
|
||||
|
||||
if (p->pos == m->seq_data[p->sequence].entry_point) {
|
||||
set_position(ctx, -1, -1);
|
||||
} else if (p->pos > m->seq_data[p->sequence].entry_point) {
|
||||
set_position(ctx, p->pos - 1, -1);
|
||||
}
|
||||
return p->pos < 0 ? 0 : p->pos;
|
||||
}
|
||||
|
||||
int xmp_set_position(xmp_context opaque, int pos)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return -XMP_ERROR_STATE;
|
||||
|
||||
if (pos >= m->mod.len)
|
||||
return -XMP_ERROR_INVALID;
|
||||
|
||||
set_position(ctx, pos, 0);
|
||||
|
||||
return p->pos;
|
||||
}
|
||||
|
||||
void xmp_stop_module(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return;
|
||||
|
||||
p->pos = -2;
|
||||
}
|
||||
|
||||
void xmp_restart_module(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return;
|
||||
|
||||
p->loop_count = 0;
|
||||
p->pos = -1;
|
||||
}
|
||||
|
||||
int xmp_seek_time(xmp_context opaque, int time)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
int i, t;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return -XMP_ERROR_STATE;
|
||||
|
||||
for (i = m->mod.len - 1; i >= 0; i--) {
|
||||
int pat = m->mod.xxo[i];
|
||||
if (pat >= m->mod.pat) {
|
||||
continue;
|
||||
}
|
||||
if (libxmp_get_sequence(ctx, i) != p->sequence) {
|
||||
continue;
|
||||
}
|
||||
t = m->xxo_info[i].time;
|
||||
if (time >= t) {
|
||||
set_position(ctx, i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < 0) {
|
||||
xmp_set_position(opaque, 0);
|
||||
}
|
||||
|
||||
return p->pos < 0 ? 0 : p->pos;
|
||||
}
|
||||
|
||||
int xmp_channel_mute(xmp_context opaque, int chn, int status)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
int ret;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return -XMP_ERROR_STATE;
|
||||
|
||||
if (chn < 0 || chn >= XMP_MAX_CHANNELS) {
|
||||
return -XMP_ERROR_INVALID;
|
||||
}
|
||||
|
||||
ret = p->channel_mute[chn];
|
||||
|
||||
if (status >= 2) {
|
||||
p->channel_mute[chn] = !p->channel_mute[chn];
|
||||
} else if (status >= 0) {
|
||||
p->channel_mute[chn] = status;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xmp_channel_vol(xmp_context opaque, int chn, int vol)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
int ret;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return -XMP_ERROR_STATE;
|
||||
|
||||
if (chn < 0 || chn >= XMP_MAX_CHANNELS) {
|
||||
return -XMP_ERROR_INVALID;
|
||||
}
|
||||
|
||||
ret = p->channel_vol[chn];
|
||||
|
||||
if (vol >= 0 && vol <= 100) {
|
||||
p->channel_vol[chn] = vol;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_VERSIONED_SYMBOLS
|
||||
extern int xmp_set_player_v41__(xmp_context, int, int)
|
||||
__attribute__((alias("xmp_set_player_v40__")));
|
||||
extern int xmp_set_player_v43__(xmp_context, int, int)
|
||||
__attribute__((alias("xmp_set_player_v40__")));
|
||||
extern int xmp_set_player_v44__(xmp_context, int, int)
|
||||
__attribute__((alias("xmp_set_player_v40__")));
|
||||
|
||||
asm(".symver xmp_set_player_v40__, xmp_set_player@XMP_4.0");
|
||||
asm(".symver xmp_set_player_v41__, xmp_set_player@XMP_4.1");
|
||||
asm(".symver xmp_set_player_v43__, xmp_set_player@XMP_4.3");
|
||||
asm(".symver xmp_set_player_v44__, xmp_set_player@@XMP_4.4");
|
||||
|
||||
#define xmp_set_player__ xmp_set_player_v40__
|
||||
#else
|
||||
#define xmp_set_player__ xmp_set_player
|
||||
#endif
|
||||
|
||||
int xmp_set_player__(xmp_context opaque, int parm, int val)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct mixer_data *s = &ctx->s;
|
||||
int ret = -XMP_ERROR_INVALID;
|
||||
|
||||
|
||||
if (parm == XMP_PLAYER_SMPCTL || parm == XMP_PLAYER_DEFPAN) {
|
||||
/* these should be set before loading the module */
|
||||
if (ctx->state >= XMP_STATE_LOADED) {
|
||||
return -XMP_ERROR_STATE;
|
||||
}
|
||||
} else if (parm == XMP_PLAYER_VOICES) {
|
||||
/* these should be set before start playing */
|
||||
if (ctx->state >= XMP_STATE_PLAYING) {
|
||||
return -XMP_ERROR_STATE;
|
||||
}
|
||||
} else if (ctx->state < XMP_STATE_PLAYING) {
|
||||
return -XMP_ERROR_STATE;
|
||||
}
|
||||
|
||||
switch (parm) {
|
||||
case XMP_PLAYER_AMP:
|
||||
if (val >= 0 && val <= 3) {
|
||||
s->amplify = val;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case XMP_PLAYER_MIX:
|
||||
if (val >= -100 && val <= 100) {
|
||||
s->mix = val;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case XMP_PLAYER_INTERP:
|
||||
if (val >= XMP_INTERP_NEAREST && val <= XMP_INTERP_SPLINE) {
|
||||
s->interp = val;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case XMP_PLAYER_DSP:
|
||||
s->dsp = val;
|
||||
ret = 0;
|
||||
break;
|
||||
case XMP_PLAYER_FLAGS: {
|
||||
p->player_flags = val;
|
||||
ret = 0;
|
||||
break; }
|
||||
|
||||
/* 4.1 */
|
||||
case XMP_PLAYER_CFLAGS: {
|
||||
int vblank = p->flags & XMP_FLAGS_VBLANK;
|
||||
p->flags = val;
|
||||
if (vblank != (p->flags & XMP_FLAGS_VBLANK))
|
||||
libxmp_scan_sequences(ctx);
|
||||
ret = 0;
|
||||
break; }
|
||||
case XMP_PLAYER_SMPCTL:
|
||||
m->smpctl = val;
|
||||
ret = 0;
|
||||
break;
|
||||
case XMP_PLAYER_VOLUME:
|
||||
if (val >= 0 && val <= 200) {
|
||||
p->master_vol = val;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case XMP_PLAYER_SMIX_VOLUME:
|
||||
if (val >= 0 && val <= 200) {
|
||||
p->smix_vol = val;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
/* 4.3 */
|
||||
case XMP_PLAYER_DEFPAN:
|
||||
if (val >= 0 && val <= 100) {
|
||||
m->defpan = val;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
/* 4.4 */
|
||||
case XMP_PLAYER_MODE:
|
||||
p->mode = val;
|
||||
libxmp_set_player_mode(ctx);
|
||||
libxmp_scan_sequences(ctx);
|
||||
ret = 0;
|
||||
break;
|
||||
case XMP_PLAYER_VOICES:
|
||||
s->numvoc = val;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_VERSIONED_SYMBOLS
|
||||
extern int xmp_get_player_v41__(xmp_context, int)
|
||||
__attribute__((alias("xmp_get_player_v40__")));
|
||||
extern int xmp_get_player_v42__(xmp_context, int)
|
||||
__attribute__((alias("xmp_get_player_v40__")));
|
||||
extern int xmp_get_player_v43__(xmp_context, int)
|
||||
__attribute__((alias("xmp_get_player_v40__")));
|
||||
extern int xmp_get_player_v44__(xmp_context, int)
|
||||
__attribute__((alias("xmp_get_player_v40__")));
|
||||
|
||||
asm(".symver xmp_get_player_v40__, xmp_get_player@XMP_4.0");
|
||||
asm(".symver xmp_get_player_v41__, xmp_get_player@XMP_4.1");
|
||||
asm(".symver xmp_get_player_v42__, xmp_get_player@XMP_4.2");
|
||||
asm(".symver xmp_get_player_v43__, xmp_get_player@XMP_4.3");
|
||||
asm(".symver xmp_get_player_v44__, xmp_get_player@@XMP_4.4");
|
||||
|
||||
#define xmp_get_player__ xmp_get_player_v40__
|
||||
#else
|
||||
#define xmp_get_player__ xmp_get_player
|
||||
#endif
|
||||
|
||||
int xmp_get_player__(xmp_context opaque, int parm)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct mixer_data *s = &ctx->s;
|
||||
int ret = -XMP_ERROR_INVALID;
|
||||
|
||||
if (parm == XMP_PLAYER_SMPCTL || parm == XMP_PLAYER_DEFPAN) {
|
||||
// can read these at any time
|
||||
} else if (parm != XMP_PLAYER_STATE && ctx->state < XMP_STATE_PLAYING) {
|
||||
return -XMP_ERROR_STATE;
|
||||
}
|
||||
|
||||
switch (parm) {
|
||||
case XMP_PLAYER_AMP:
|
||||
ret = s->amplify;
|
||||
break;
|
||||
case XMP_PLAYER_MIX:
|
||||
ret = s->mix;
|
||||
break;
|
||||
case XMP_PLAYER_INTERP:
|
||||
ret = s->interp;
|
||||
break;
|
||||
case XMP_PLAYER_DSP:
|
||||
ret = s->dsp;
|
||||
break;
|
||||
case XMP_PLAYER_FLAGS:
|
||||
ret = p->player_flags;
|
||||
break;
|
||||
|
||||
/* 4.1 */
|
||||
case XMP_PLAYER_CFLAGS:
|
||||
ret = p->flags;
|
||||
break;
|
||||
case XMP_PLAYER_SMPCTL:
|
||||
ret = m->smpctl;
|
||||
break;
|
||||
case XMP_PLAYER_VOLUME:
|
||||
ret = p->master_vol;
|
||||
break;
|
||||
case XMP_PLAYER_SMIX_VOLUME:
|
||||
ret = p->smix_vol;
|
||||
break;
|
||||
|
||||
/* 4.2 */
|
||||
case XMP_PLAYER_STATE:
|
||||
ret = ctx->state;
|
||||
break;
|
||||
|
||||
/* 4.3 */
|
||||
case XMP_PLAYER_DEFPAN:
|
||||
ret = m->defpan;
|
||||
break;
|
||||
|
||||
/* 4.4 */
|
||||
case XMP_PLAYER_MODE:
|
||||
ret = p->mode;
|
||||
break;
|
||||
case XMP_PLAYER_MIXER_TYPE:
|
||||
ret = XMP_MIXER_STANDARD;
|
||||
if (p->flags & XMP_FLAGS_A500) {
|
||||
if (IS_AMIGA_MOD()) {
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
if (p->filter) {
|
||||
ret = XMP_MIXER_A500F;
|
||||
} else {
|
||||
ret = XMP_MIXER_A500;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XMP_PLAYER_VOICES:
|
||||
ret = s->numvoc;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **xmp_get_format_list()
|
||||
{
|
||||
return format_list();
|
||||
}
|
||||
|
||||
void xmp_inject_event(xmp_context opaque, int channel, struct xmp_event *e)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING)
|
||||
return;
|
||||
|
||||
memcpy(&p->inject_event[channel], e, sizeof(struct xmp_event));
|
||||
p->inject_event[channel]._flag = 1;
|
||||
}
|
||||
|
||||
int xmp_set_instrument_path(xmp_context opaque, char *path)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct module_data *m = &ctx->m;
|
||||
|
||||
if (m->instrument_path != NULL)
|
||||
free(m->instrument_path);
|
||||
|
||||
size_t length = strlen(path);
|
||||
m->instrument_path = malloc(length + 1);
|
||||
memcpy(m->instrument_path, path, length + 1);
|
||||
if (m->instrument_path == NULL) {
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
274
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/dataio.c
vendored
Normal file
274
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/dataio.c
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
|
||||
|
||||
#define read_byte(x) do { \
|
||||
(x) = fgetc(f); \
|
||||
if ((x) < 0) goto error; \
|
||||
} while (0)
|
||||
|
||||
#define set_error(x) do { \
|
||||
if (err != NULL) *err = (x); \
|
||||
} while (0)
|
||||
|
||||
|
||||
uint8 read8(FILE *f, int *err)
|
||||
{
|
||||
int a;
|
||||
|
||||
read_byte(a);
|
||||
set_error(0);
|
||||
return a;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
int8 read8s(FILE *f, int *err)
|
||||
{
|
||||
int a;
|
||||
|
||||
read_byte(a);
|
||||
set_error(0);
|
||||
return (int8)a;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 read16l(FILE *f, int *err)
|
||||
{
|
||||
int a, b;
|
||||
|
||||
read_byte(a);
|
||||
read_byte(b);
|
||||
|
||||
set_error(0);
|
||||
return ((uint16)b << 8) | a;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
uint16 read16b(FILE *f, int *err)
|
||||
{
|
||||
int a, b;
|
||||
|
||||
read_byte(a);
|
||||
read_byte(b);
|
||||
|
||||
set_error(0);
|
||||
return (a << 8) | b;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
uint32 read24l(FILE *f, int *err)
|
||||
{
|
||||
int a, b, c;
|
||||
|
||||
read_byte(a);
|
||||
read_byte(b);
|
||||
read_byte(c);
|
||||
|
||||
set_error(0);
|
||||
return (c << 16) | (b << 8) | a;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0xffffff;
|
||||
}
|
||||
|
||||
uint32 read24b(FILE *f, int *err)
|
||||
{
|
||||
int a, b, c;
|
||||
|
||||
read_byte(a);
|
||||
read_byte(b);
|
||||
read_byte(c);
|
||||
|
||||
set_error(0);
|
||||
return (a << 16) | (b << 8) | c;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0xffffff;
|
||||
}
|
||||
|
||||
uint32 read32l(FILE *f, int *err)
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
||||
read_byte(a);
|
||||
read_byte(b);
|
||||
read_byte(c);
|
||||
read_byte(d);
|
||||
|
||||
set_error(0);
|
||||
return (d << 24) | (c << 16) | (b << 8) | a;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
uint32 read32b(FILE *f, int *err)
|
||||
{
|
||||
int a, b, c, d;
|
||||
|
||||
read_byte(a);
|
||||
read_byte(b);
|
||||
read_byte(c);
|
||||
read_byte(d);
|
||||
|
||||
set_error(0);
|
||||
return (a << 24) | (b << 16) | (c << 8) | d;
|
||||
|
||||
error:
|
||||
set_error(ferror(f) ? errno : EOF);
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
uint16 readmem16l(uint8 *m)
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
a = m[0];
|
||||
b = m[1];
|
||||
|
||||
return (b << 8) | a;
|
||||
}
|
||||
|
||||
uint16 readmem16b(uint8 *m)
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
a = m[0];
|
||||
b = m[1];
|
||||
|
||||
return (a << 8) | b;
|
||||
}
|
||||
|
||||
uint32 readmem24l(uint8 *m)
|
||||
{
|
||||
uint32 a, b, c;
|
||||
|
||||
a = m[0];
|
||||
b = m[1];
|
||||
c = m[2];
|
||||
|
||||
return (c << 16) | (b << 8) | a;
|
||||
}
|
||||
|
||||
uint32 readmem24b(uint8 *m)
|
||||
{
|
||||
uint32 a, b, c;
|
||||
|
||||
a = m[0];
|
||||
b = m[1];
|
||||
c = m[2];
|
||||
|
||||
return (a << 16) | (b << 8) | c;
|
||||
}
|
||||
|
||||
uint32 readmem32l(uint8 *m)
|
||||
{
|
||||
uint32 a, b, c, d;
|
||||
|
||||
a = m[0];
|
||||
b = m[1];
|
||||
c = m[2];
|
||||
d = m[3];
|
||||
|
||||
return (d << 24) | (c << 16) | (b << 8) | a;
|
||||
}
|
||||
|
||||
uint32 readmem32b(uint8 *m)
|
||||
{
|
||||
uint32 a, b, c, d;
|
||||
|
||||
a = m[0];
|
||||
b = m[1];
|
||||
c = m[2];
|
||||
d = m[3];
|
||||
|
||||
return (a << 24) | (b << 16) | (c << 8) | d;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
inline void write8(FILE *f, uint8 b)
|
||||
{
|
||||
fputc(b, f);
|
||||
}
|
||||
|
||||
void write16l(FILE *f, uint16 w)
|
||||
{
|
||||
write8(f, w & 0x00ff);
|
||||
write8(f, (w & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
void write16b(FILE *f, uint16 w)
|
||||
{
|
||||
write8(f, (w & 0xff00) >> 8);
|
||||
write8(f, w & 0x00ff);
|
||||
}
|
||||
|
||||
void write32l(FILE *f, uint32 w)
|
||||
{
|
||||
write8(f, w & 0x000000ff);
|
||||
write8(f, (w & 0x0000ff00) >> 8);
|
||||
write8(f, (w & 0x00ff0000) >> 16);
|
||||
write8(f, (w & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
void write32b(FILE *f, uint32 w)
|
||||
{
|
||||
write8(f, (w & 0xff000000) >> 24);
|
||||
write8(f, (w & 0x00ff0000) >> 16);
|
||||
write8(f, (w & 0x0000ff00) >> 8);
|
||||
write8(f, w & 0x000000ff);
|
||||
}
|
||||
|
||||
int move_data(FILE *out, FILE *in, int len)
|
||||
{
|
||||
uint8 buf[1024];
|
||||
int l;
|
||||
|
||||
do {
|
||||
l = fread(buf, 1, len > 1024 ? 1024 : len, in);
|
||||
fwrite(buf, 1, l, out);
|
||||
len -= l;
|
||||
} while (l > 0 && len > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
1069
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/effects.c
vendored
Normal file
1069
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/effects.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
143
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/effects.h
vendored
Normal file
143
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/effects.h
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
#ifndef LIBXMP_EFFECTS_H
|
||||
#define LIBXMP_EFFECTS_H
|
||||
|
||||
/* Protracker effects */
|
||||
#define FX_ARPEGGIO 0x00
|
||||
#define FX_PORTA_UP 0x01
|
||||
#define FX_PORTA_DN 0x02
|
||||
#define FX_TONEPORTA 0x03
|
||||
#define FX_VIBRATO 0x04
|
||||
#define FX_TONE_VSLIDE 0x05
|
||||
#define FX_VIBRA_VSLIDE 0x06
|
||||
#define FX_TREMOLO 0x07
|
||||
#define FX_OFFSET 0x09
|
||||
#define FX_VOLSLIDE 0x0a
|
||||
#define FX_JUMP 0x0b
|
||||
#define FX_VOLSET 0x0c
|
||||
#define FX_BREAK 0x0d
|
||||
#define FX_EXTENDED 0x0e
|
||||
#define FX_SPEED 0x0f
|
||||
|
||||
/* Fast tracker effects */
|
||||
#define FX_SETPAN 0x08
|
||||
|
||||
/* Fast Tracker II effects */
|
||||
#define FX_GLOBALVOL 0x10
|
||||
#define FX_GVOL_SLIDE 0x11
|
||||
#define FX_KEYOFF 0x14
|
||||
#define FX_ENVPOS 0x15
|
||||
#define FX_PANSLIDE 0x19
|
||||
#define FX_MULTI_RETRIG 0x1b
|
||||
#define FX_TREMOR 0x1d
|
||||
#define FX_XF_PORTA 0x21
|
||||
|
||||
/* Protracker extended effects */
|
||||
#define EX_FILTER 0x00
|
||||
#define EX_F_PORTA_UP 0x01
|
||||
#define EX_F_PORTA_DN 0x02
|
||||
#define EX_GLISS 0x03
|
||||
#define EX_VIBRATO_WF 0x04
|
||||
#define EX_FINETUNE 0x05
|
||||
#define EX_PATTERN_LOOP 0x06
|
||||
#define EX_TREMOLO_WF 0x07
|
||||
#define EX_SETPAN 0x08
|
||||
#define EX_RETRIG 0x09
|
||||
#define EX_F_VSLIDE_UP 0x0a
|
||||
#define EX_F_VSLIDE_DN 0x0b
|
||||
#define EX_CUT 0x0c
|
||||
#define EX_DELAY 0x0d
|
||||
#define EX_PATT_DELAY 0x0e
|
||||
#define EX_INVLOOP 0x0f
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
/* Oktalyzer effects */
|
||||
#define FX_OKT_ARP3 0x70
|
||||
#define FX_OKT_ARP4 0x71
|
||||
#define FX_OKT_ARP5 0x72
|
||||
#define FX_NSLIDE2_DN 0x73
|
||||
#define FX_NSLIDE2_UP 0x74
|
||||
#define FX_F_NSLIDE_DN 0x75
|
||||
#define FX_F_NSLIDE_UP 0x76
|
||||
|
||||
/* Persistent effects -- for FNK and FAR */
|
||||
#define FX_PER_PORTA_DN 0x78
|
||||
#define FX_PER_PORTA_UP 0x79
|
||||
#define FX_PER_TPORTA 0x7a
|
||||
#define FX_PER_VIBRATO 0x7b
|
||||
#define FX_PER_VSLD_UP 0x7c
|
||||
#define FX_PER_VSLD_DN 0x7d
|
||||
#define FX_SPEED_CP 0x7e
|
||||
#define FX_PER_CANCEL 0x7f
|
||||
|
||||
/* 669 frequency based effects */
|
||||
#define FX_669_PORTA_UP 0x60
|
||||
#define FX_669_PORTA_DN 0x61
|
||||
#define FX_669_TPORTA 0x62
|
||||
#define FX_669_FINETUNE 0x63
|
||||
#define FX_669_VIBRATO 0x64
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
/* IT effects */
|
||||
#define FX_TRK_VOL 0x80
|
||||
#define FX_TRK_VSLIDE 0x81
|
||||
#define FX_TRK_FVSLIDE 0x82
|
||||
#define FX_IT_INSTFUNC 0x83
|
||||
#define FX_FLT_CUTOFF 0x84
|
||||
#define FX_FLT_RESN 0x85
|
||||
#define FX_IT_BPM 0x87
|
||||
#define FX_IT_ROWDELAY 0x88
|
||||
#define FX_IT_PANSLIDE 0x89
|
||||
#define FX_PANBRELLO 0x8a
|
||||
#define FX_PANBRELLO_WF 0x8b
|
||||
#define FX_HIOFFSET 0x8c
|
||||
#define FX_IT_BREAK 0x8e /* like FX_BREAK with hex parameter */
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
/* MED effects */
|
||||
#define FX_HOLD_DECAY 0x90
|
||||
#define FX_SETPITCH 0x91
|
||||
#define FX_VIBRATO2 0x92
|
||||
|
||||
/* PTM effects */
|
||||
#define FX_NSLIDE_DN 0x9c /* IMF/PTM note slide down */
|
||||
#define FX_NSLIDE_UP 0x9d /* IMF/PTM note slide up */
|
||||
#define FX_NSLIDE_R_UP 0x9e /* PTM note slide down with retrigger */
|
||||
#define FX_NSLIDE_R_DN 0x9f /* PTM note slide up with retrigger */
|
||||
|
||||
/* Extra effects */
|
||||
#define FX_VOLSLIDE_UP 0xa0 /* SFX, MDL */
|
||||
#define FX_VOLSLIDE_DN 0xa1
|
||||
#define FX_F_VSLIDE 0xa5 /* IMF/MDL */
|
||||
#define FX_CHORUS 0xa9 /* IMF */
|
||||
#define FX_ICE_SPEED 0xa2
|
||||
#define FX_REVERB 0xaa /* IMF */
|
||||
#define FX_MED_HOLD 0xb1 /* MMD hold/decay */
|
||||
#define FX_MEGAARP 0xb2 /* Smaksak effect 7: MegaArp */
|
||||
#define FX_VOL_ADD 0xb6 /* SFX change volume up */
|
||||
#define FX_VOL_SUB 0xb7 /* SFX change volume down */
|
||||
#define FX_PITCH_ADD 0xb8 /* SFX add steps to current note */
|
||||
#define FX_PITCH_SUB 0xb9 /* SFX add steps to current note */
|
||||
#endif
|
||||
|
||||
#define FX_SURROUND 0x8d /* S3M/IT */
|
||||
#define FX_S3M_SPEED 0xa3 /* S3M */
|
||||
#define FX_VOLSLIDE_2 0xa4
|
||||
#define FX_FINETUNE 0xa6
|
||||
#define FX_S3M_BPM 0xab /* S3M */
|
||||
#define FX_FINE_VIBRATO 0xac /* S3M/PTM/IMF/LIQ */
|
||||
#define FX_F_VSLIDE_UP 0xad /* MMD */
|
||||
#define FX_F_VSLIDE_DN 0xae /* MMD */
|
||||
#define FX_F_PORTA_UP 0xaf /* MMD */
|
||||
#define FX_F_PORTA_DN 0xb0 /* MMD */
|
||||
#define FX_PATT_DELAY 0xb3 /* MMD */
|
||||
#define FX_S3M_ARPEGGIO 0xb4
|
||||
#define FX_PANSL_NOMEM 0xb5 /* XM volume column */
|
||||
|
||||
#define FX_VSLIDE_UP_2 0xc0 /* IT volume column volume slide */
|
||||
#define FX_VSLIDE_DN_2 0xc1
|
||||
#define FX_F_VSLIDE_UP_2 0xc2
|
||||
#define FX_F_VSLIDE_DN_2 0xc3
|
||||
|
||||
#endif /* LIBXMP_EFFECTS_H */
|
102
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/filter.c
vendored
Normal file
102
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/filter.c
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Based on the public domain version by Olivier Lapicque
|
||||
* Rewritten for libxmp by Claudio Matsuoka
|
||||
*
|
||||
* Copyright (C) 2012 Claudio Matsuoka
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
#include <math.h>
|
||||
#include "xmp.h"
|
||||
#include "common.h"
|
||||
#include "mixer.h"
|
||||
|
||||
|
||||
/* LUT for 2 * damping factor */
|
||||
static const float resonance_table[128] = {
|
||||
1.0000000000000000f, 0.9786446094512940f, 0.9577452540397644f, 0.9372922182083130f,
|
||||
0.9172759056091309f, 0.8976871371269226f, 0.8785166740417481f, 0.8597555756568909f,
|
||||
0.8413951396942139f, 0.8234267830848694f, 0.8058421611785889f, 0.7886331081390381f,
|
||||
0.7717915177345276f, 0.7553095817565918f, 0.7391796708106995f, 0.7233941555023193f,
|
||||
0.7079457640647888f, 0.6928272843360901f, 0.6780316829681397f, 0.6635520458221436f,
|
||||
0.6493816375732422f, 0.6355138421058655f, 0.6219421625137329f, 0.6086603403091431f,
|
||||
0.5956621170043945f, 0.5829415321350098f, 0.5704925656318665f, 0.5583094954490662f,
|
||||
0.5463865399360657f, 0.5347182154655457f, 0.5232990980148315f, 0.5121238231658936f,
|
||||
0.5011872053146362f, 0.4904841780662537f, 0.4800096750259399f, 0.4697588682174683f,
|
||||
0.4597269892692566f, 0.4499093294143677f, 0.4403013288974762f, 0.4308985173702240f,
|
||||
0.4216965138912201f, 0.4126909971237183f, 0.4038778245449066f, 0.3952528536319733f,
|
||||
0.3868120610713959f, 0.3785515129566193f, 0.3704673945903778f, 0.3625559210777283f,
|
||||
0.3548133969306946f, 0.3472362160682678f, 0.3398208320140839f, 0.3325638175010681f,
|
||||
0.3254617750644684f, 0.3185114264488220f, 0.3117094635963440f, 0.3050527870655060f,
|
||||
0.2985382676124573f, 0.2921628654003143f, 0.2859236001968384f, 0.2798175811767578f,
|
||||
0.2738419771194458f, 0.2679939568042755f, 0.2622708380222321f, 0.2566699385643005f,
|
||||
0.2511886358261108f, 0.2458244115114212f, 0.2405747324228287f, 0.2354371547698975f,
|
||||
0.2304092943668366f, 0.2254888117313385f, 0.2206734120845795f, 0.2159608304500580f,
|
||||
0.2113489061594009f, 0.2068354636430740f, 0.2024184018373489f, 0.1980956792831421f,
|
||||
0.1938652694225311f, 0.1897251904010773f, 0.1856735348701477f, 0.1817083954811096f,
|
||||
0.1778279393911362f, 0.1740303486585617f, 0.1703138649463654f, 0.1666767448186874f,
|
||||
0.1631172895431519f, 0.1596338599920273f, 0.1562248021364212f, 0.1528885662555695f,
|
||||
0.1496235728263855f, 0.1464282870292664f, 0.1433012634515762f, 0.1402409970760346f,
|
||||
0.1372461020946503f, 0.1343151479959488f, 0.1314467936754227f, 0.1286396980285645f,
|
||||
0.1258925348520279f, 0.1232040524482727f, 0.1205729842185974f, 0.1179980933666229f,
|
||||
0.1154781952500343f, 0.1130121126770973f, 0.1105986908078194f, 0.1082368120551109f,
|
||||
0.1059253737330437f, 0.1036632955074310f, 0.1014495193958283f, 0.0992830246686935f,
|
||||
0.0971627980470657f, 0.0950878411531448f, 0.0930572077631950f, 0.0910699293017387f,
|
||||
0.0891250967979431f, 0.0872217938303947f, 0.0853591337800026f, 0.0835362523794174f,
|
||||
0.0817523002624512f, 0.0800064504146576f, 0.0782978758215904f, 0.0766257941722870f,
|
||||
0.0749894231557846f, 0.0733879879117012f, 0.0718207582831383f, 0.0702869966626167f,
|
||||
0.0687859877943993f, 0.0673170387744904f, 0.0658794566988945f, 0.0644725710153580f,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Simple 2-poles resonant filter
|
||||
*/
|
||||
#define FREQ_PARAM_MULT (128.0f / (24.0f * 256.0f))
|
||||
void libxmp_filter_setup(int srate, int cutoff, int res, int *a0, int *b0, int *b1)
|
||||
{
|
||||
float fc, fs = (float)srate;
|
||||
float fg, fb0, fb1;
|
||||
float r, d, e;
|
||||
|
||||
/* [0-255] => [100Hz-8000Hz] */
|
||||
CLAMP(cutoff, 0, 255);
|
||||
CLAMP(res, 0, 255);
|
||||
|
||||
fc = 110.0f * powf(2.0f, (float)cutoff * FREQ_PARAM_MULT + 0.25f);
|
||||
if (fc > fs / 2.0f) {
|
||||
fc = fs / 2.0f;
|
||||
}
|
||||
|
||||
r = fs / (2.0 * 3.14159265358979f * fc);
|
||||
d = resonance_table[res >> 1] * (r + 1.0) - 1.0;
|
||||
e = r * r;
|
||||
|
||||
fg = 1.0 / (1.0 + d + e);
|
||||
fb0 = (d + e + e) / (1.0 + d + e);
|
||||
fb1 = -e / (1.0 + d + e);
|
||||
|
||||
*a0 = (int)(fg * (1 << FILTER_SHIFT));
|
||||
*b0 = (int)(fb0 * (1 << FILTER_SHIFT));
|
||||
*b1 = (int)(fb1 * (1 << FILTER_SHIFT));
|
||||
}
|
||||
|
||||
#endif
|
62
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/format.c
vendored
Normal file
62
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/format.c
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
#include "loaders/prowizard/prowiz.h"
|
||||
#endif
|
||||
#include "format.h"
|
||||
|
||||
extern const struct format_loader libxmp_loader_xm;
|
||||
extern const struct format_loader libxmp_loader_mod;
|
||||
extern const struct format_loader libxmp_loader_it;
|
||||
extern const struct format_loader libxmp_loader_s3m;
|
||||
|
||||
extern const struct pw_format *const pw_format[];
|
||||
|
||||
const struct format_loader *const format_loader[5] = {
|
||||
&libxmp_loader_xm,
|
||||
&libxmp_loader_mod,
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
&libxmp_loader_it,
|
||||
#endif
|
||||
&libxmp_loader_s3m,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *_farray[5] = { NULL };
|
||||
|
||||
char **format_list()
|
||||
{
|
||||
int count, i;
|
||||
|
||||
if (_farray[0] == NULL) {
|
||||
for (count = i = 0; format_loader[i] != NULL; i++) {
|
||||
_farray[count++] = format_loader[i]->name;
|
||||
}
|
||||
|
||||
_farray[count] = NULL;
|
||||
}
|
||||
|
||||
return (char **)_farray;
|
||||
}
|
25
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/format.h
vendored
Normal file
25
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/format.h
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef LIBXMP_FORMAT_H
|
||||
#define LIBXMP_FORMAT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
#include "hio.h"
|
||||
|
||||
struct format_loader {
|
||||
const char *name;
|
||||
int (*const test)(HIO_HANDLE *, char *, const int);
|
||||
int (*const loader)(struct module_data *, HIO_HANDLE *, const int);
|
||||
};
|
||||
|
||||
char **format_list(void);
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
#define NUM_FORMATS 52
|
||||
#define NUM_PW_FORMATS 43
|
||||
|
||||
int pw_test_format(HIO_HANDLE *, char *, const int, struct xmp_test_info *);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
380
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/hio.c
vendored
Normal file
380
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/hio.c
vendored
Normal file
|
@ -0,0 +1,380 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "hio.h"
|
||||
#include "mdataio.h"
|
||||
|
||||
static long get_size(FILE *f)
|
||||
{
|
||||
long size, pos;
|
||||
|
||||
pos = ftell(f);
|
||||
if (pos >= 0) {
|
||||
if (fseek(f, 0, SEEK_END) < 0) {
|
||||
return -1;
|
||||
}
|
||||
size = ftell(f);
|
||||
if (fseek(f, pos, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return size;
|
||||
} else {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
int8 hio_read8s(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
int8 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read8s(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread8s(h->handle.mem);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8 hio_read8(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
uint8 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read8(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread8(h->handle.mem);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16 hio_read16l(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
uint16 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read16l(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread16l(h->handle.mem);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16 hio_read16b(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
uint16 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read16b(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread16b(h->handle.mem);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 hio_read24l(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
uint32 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read24l(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread24l(h->handle.mem);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 hio_read24b(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
uint32 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read24b(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread24b(h->handle.mem);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 hio_read32l(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
uint32 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read32l(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread32l(h->handle.mem);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 hio_read32b(HIO_HANDLE *h)
|
||||
{
|
||||
int err;
|
||||
uint32 ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = read32b(h->handle.file, &err);
|
||||
if (err != 0) {
|
||||
h->error = err;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread32b(h->handle.mem);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t hio_read(void *buf, size_t size, size_t num, HIO_HANDLE *h)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = fread(buf, size, num, h->handle.file);
|
||||
if (ret != num) {
|
||||
if (ferror(h->handle.file)) {
|
||||
h->error = errno;
|
||||
} else {
|
||||
h->error = feof(h->handle.file) ? EOF : -2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mread(buf, size, num, h->handle.mem);
|
||||
if (ret != num) {
|
||||
h->error = errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hio_seek(HIO_HANDLE *h, long offset, int whence)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = fseek(h->handle.file, offset, whence);
|
||||
if (ret < 0) {
|
||||
h->error = errno;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mseek(h->handle.mem, offset, whence);
|
||||
if (ret < 0) {
|
||||
h->error = errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
long hio_tell(HIO_HANDLE *h)
|
||||
{
|
||||
long ret = -1;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = ftell(h->handle.file);
|
||||
if (ret < 0) {
|
||||
h->error = errno;
|
||||
}
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mtell(h->handle.mem);
|
||||
if (ret < 0) {
|
||||
h->error = errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hio_eof(HIO_HANDLE *h)
|
||||
{
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
return feof(h->handle.file);
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
return meof(h->handle.mem);
|
||||
default:
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
int hio_error(HIO_HANDLE *h)
|
||||
{
|
||||
int error = h->error;
|
||||
h->error = 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
HIO_HANDLE *hio_open(void *path, char *mode)
|
||||
{
|
||||
HIO_HANDLE *h;
|
||||
|
||||
h = (HIO_HANDLE *)malloc(sizeof (HIO_HANDLE));
|
||||
if (h == NULL)
|
||||
goto err;
|
||||
|
||||
h->error = 0;
|
||||
h->type = HIO_HANDLE_TYPE_FILE;
|
||||
h->handle.file = fopen(path, mode);
|
||||
if (h->handle.file == NULL)
|
||||
goto err2;
|
||||
|
||||
h->size = get_size(h->handle.file);
|
||||
if (h->size < 0)
|
||||
goto err3;
|
||||
|
||||
return h;
|
||||
|
||||
err3:
|
||||
fclose(h->handle.file);
|
||||
err2:
|
||||
free(h);
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HIO_HANDLE *hio_open_mem(void *ptr, long size)
|
||||
{
|
||||
HIO_HANDLE *h;
|
||||
|
||||
h = (HIO_HANDLE *)malloc(sizeof (HIO_HANDLE));
|
||||
if (h == NULL)
|
||||
return NULL;
|
||||
|
||||
h->error = 0;
|
||||
h->type = HIO_HANDLE_TYPE_MEMORY;
|
||||
h->handle.mem = mopen(ptr, size);
|
||||
h->size = size;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
HIO_HANDLE *hio_open_file(FILE *f)
|
||||
{
|
||||
HIO_HANDLE *h;
|
||||
|
||||
h = (HIO_HANDLE *)malloc(sizeof (HIO_HANDLE));
|
||||
if (h == NULL)
|
||||
return NULL;
|
||||
|
||||
h->error = 0;
|
||||
h->type = HIO_HANDLE_TYPE_FILE;
|
||||
h->handle.file = f /*fdopen(fileno(f), "rb")*/;
|
||||
h->size = get_size(f);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
int hio_close(HIO_HANDLE *h)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (HIO_HANDLE_TYPE(h)) {
|
||||
case HIO_HANDLE_TYPE_FILE:
|
||||
ret = fclose(h->handle.file);
|
||||
break;
|
||||
case HIO_HANDLE_TYPE_MEMORY:
|
||||
ret = mclose(h->handle.mem);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(h);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long hio_size(HIO_HANDLE *h)
|
||||
{
|
||||
return h->size;
|
||||
}
|
42
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/hio.h
vendored
Normal file
42
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/hio.h
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef XMP_HIO_H
|
||||
#define XMP_HIO_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h>
|
||||
#include "memio.h"
|
||||
|
||||
#define HIO_HANDLE_TYPE(x) ((x)->type)
|
||||
|
||||
typedef struct {
|
||||
#define HIO_HANDLE_TYPE_FILE 0
|
||||
#define HIO_HANDLE_TYPE_MEMORY 1
|
||||
int type;
|
||||
long size;
|
||||
union {
|
||||
FILE *file;
|
||||
MFILE *mem;
|
||||
} handle;
|
||||
int error;
|
||||
} HIO_HANDLE;
|
||||
|
||||
int8 hio_read8s (HIO_HANDLE *);
|
||||
uint8 hio_read8 (HIO_HANDLE *);
|
||||
uint16 hio_read16l (HIO_HANDLE *);
|
||||
uint16 hio_read16b (HIO_HANDLE *);
|
||||
uint32 hio_read24l (HIO_HANDLE *);
|
||||
uint32 hio_read24b (HIO_HANDLE *);
|
||||
uint32 hio_read32l (HIO_HANDLE *);
|
||||
uint32 hio_read32b (HIO_HANDLE *);
|
||||
size_t hio_read (void *, size_t, size_t, HIO_HANDLE *);
|
||||
int hio_seek (HIO_HANDLE *, long, int);
|
||||
long hio_tell (HIO_HANDLE *);
|
||||
int hio_eof (HIO_HANDLE *);
|
||||
int hio_error (HIO_HANDLE *);
|
||||
HIO_HANDLE *hio_open (void *, char *);
|
||||
HIO_HANDLE *hio_open_mem (void *, long);
|
||||
HIO_HANDLE *hio_open_file (FILE *);
|
||||
int hio_close (HIO_HANDLE *);
|
||||
long hio_size (HIO_HANDLE *);
|
||||
|
||||
#endif
|
164
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/lfo.c
vendored
Normal file
164
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/lfo.c
vendored
Normal file
|
@ -0,0 +1,164 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "lfo.h"
|
||||
|
||||
#define WAVEFORM_SIZE 64
|
||||
|
||||
static const int sine_wave[WAVEFORM_SIZE] = {
|
||||
0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224,
|
||||
235, 244, 250, 253, 255, 253, 250, 244, 235, 224, 212, 197,
|
||||
180, 161, 141, 120, 97, 74, 49, 24, 0, -24, -49, -74,
|
||||
-97,-120,-141,-161,-180,-197,-212,-224,-235,-244,-250,-253,
|
||||
-255,-253,-250,-244,-235,-224,-212,-197,-180,-161,-141,-120,
|
||||
-97, -74, -49, -24
|
||||
};
|
||||
|
||||
/* LFO */
|
||||
|
||||
static int get_lfo_mod(struct lfo *lfo)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (lfo->rate == 0)
|
||||
return 0;
|
||||
|
||||
switch (lfo->type) {
|
||||
case 0: /* sine */
|
||||
val = sine_wave[lfo->phase];
|
||||
break;
|
||||
case 1: /* ramp down */
|
||||
val = 255 - (lfo->phase << 3);
|
||||
break;
|
||||
case 2: /* square */
|
||||
val = lfo->phase < WAVEFORM_SIZE / 2 ? 255 : -255;
|
||||
break;
|
||||
case 3: /* random */
|
||||
val = ((rand() & 0x1ff) - 256);
|
||||
break;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
case 669: /* 669 vibrato */
|
||||
val = lfo->phase & 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return val * lfo->depth;
|
||||
}
|
||||
|
||||
static int get_lfo_st3(struct lfo *lfo)
|
||||
{
|
||||
if (lfo->rate == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* S3M square */
|
||||
if (lfo->type == 2) {
|
||||
int val = lfo->phase < WAVEFORM_SIZE / 2 ? 255 : 0;
|
||||
return val * lfo->depth;
|
||||
}
|
||||
|
||||
return get_lfo_mod(lfo);
|
||||
}
|
||||
|
||||
/* From OpenMPT VibratoWaveforms.xm:
|
||||
* "Generally the vibrato and tremolo tables are identical to those that
|
||||
* ProTracker uses, but the vibrato’s “ramp down” table is upside down."
|
||||
*/
|
||||
static int get_lfo_ft2(struct lfo *lfo)
|
||||
{
|
||||
if (lfo->rate == 0)
|
||||
return 0;
|
||||
|
||||
/* FT2 ramp */
|
||||
if (lfo->type == 1) {
|
||||
int phase = (lfo->phase + (WAVEFORM_SIZE >> 1)) % WAVEFORM_SIZE;
|
||||
int val = (phase << 3) - 255;
|
||||
return val * lfo->depth;
|
||||
}
|
||||
|
||||
return get_lfo_mod(lfo);
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
|
||||
static int get_lfo_it(struct lfo *lfo)
|
||||
{
|
||||
if (lfo->rate == 0)
|
||||
return 0;
|
||||
|
||||
return get_lfo_st3(lfo);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int libxmp_lfo_get(struct context_data *ctx, struct lfo *lfo, int is_vibrato)
|
||||
{
|
||||
struct module_data *m = &ctx->m;
|
||||
|
||||
switch (m->read_event_type) {
|
||||
case READ_EVENT_ST3:
|
||||
return get_lfo_st3(lfo);
|
||||
case READ_EVENT_FT2:
|
||||
if (is_vibrato) {
|
||||
return get_lfo_ft2(lfo);
|
||||
} else {
|
||||
return get_lfo_mod(lfo);
|
||||
}
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
case READ_EVENT_IT:
|
||||
return get_lfo_it(lfo);
|
||||
#endif
|
||||
default:
|
||||
return get_lfo_mod(lfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void libxmp_lfo_update(struct lfo *lfo)
|
||||
{
|
||||
lfo->phase += lfo->rate;
|
||||
lfo->phase %= WAVEFORM_SIZE;
|
||||
}
|
||||
|
||||
void libxmp_lfo_set_phase(struct lfo *lfo, int phase)
|
||||
{
|
||||
lfo->phase = phase;
|
||||
}
|
||||
|
||||
void libxmp_lfo_set_depth(struct lfo *lfo, int depth)
|
||||
{
|
||||
lfo->depth = depth;
|
||||
}
|
||||
|
||||
void libxmp_lfo_set_rate(struct lfo *lfo, int rate)
|
||||
{
|
||||
lfo->rate = rate;
|
||||
}
|
||||
|
||||
void libxmp_lfo_set_waveform(struct lfo *lfo, int type)
|
||||
{
|
||||
lfo->type = type;
|
||||
}
|
20
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/lfo.h
vendored
Normal file
20
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/lfo.h
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef LIBXMP_LFO_H
|
||||
#define LIBXMP_LFO_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct lfo {
|
||||
int type;
|
||||
int rate;
|
||||
int depth;
|
||||
int phase;
|
||||
};
|
||||
|
||||
int libxmp_lfo_get(struct context_data *, struct lfo *, int);
|
||||
void libxmp_lfo_update(struct lfo *);
|
||||
void libxmp_lfo_set_phase(struct lfo *, int);
|
||||
void libxmp_lfo_set_depth(struct lfo *, int);
|
||||
void libxmp_lfo_set_rate(struct lfo *, int);
|
||||
void libxmp_lfo_set_waveform(struct lfo *, int);
|
||||
|
||||
#endif
|
143
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/list.h
vendored
Normal file
143
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/list.h
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
#ifndef LIBXMP_LIST_H
|
||||
#define LIBXMP_LIST_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __inline__ __inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simple doubly linked list implementation.
|
||||
*
|
||||
* Some of the internal functions ("__xxx") are useful when
|
||||
* manipulating whole lists rather than single entries, as
|
||||
* sometimes we already know the next/prev entries and we can
|
||||
* generate better code by using them directly rather than
|
||||
* using the generic single-entry routines.
|
||||
*/
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
|
||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define LIST_HEAD(name) \
|
||||
struct list_head name = LIST_HEAD_INIT(name)
|
||||
|
||||
#define INIT_LIST_HEAD(ptr) do { \
|
||||
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static __inline__ void __list_add(struct list_head *_new,
|
||||
struct list_head * prev,
|
||||
struct list_head * next)
|
||||
{
|
||||
next->prev = _new;
|
||||
_new->next = next;
|
||||
_new->prev = prev;
|
||||
prev->next = _new;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add - add a new entry
|
||||
* @_new: new entry to be added
|
||||
* @head: list head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static __inline__ void list_add(struct list_head *_new, struct list_head *head)
|
||||
{
|
||||
__list_add(_new, head, head->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add_tail - add a new entry
|
||||
* @_new: new entry to be added
|
||||
* @head: list head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*/
|
||||
static __inline__ void list_add_tail(struct list_head *_new, struct list_head *head)
|
||||
{
|
||||
__list_add(_new, head->prev, head);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a list entry by making the prev/next entries
|
||||
* point to each other.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static __inline__ void __list_del(struct list_head * prev,
|
||||
struct list_head * next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del - deletes entry from list.
|
||||
* @entry: the element to delete from the list.
|
||||
*/
|
||||
static __inline__ void list_del(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_empty - tests whether a list is empty
|
||||
* @head: the list to test.
|
||||
*/
|
||||
static __inline__ int list_empty(struct list_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice - join two lists
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static __inline__ void list_splice(struct list_head *list, struct list_head *head)
|
||||
{
|
||||
struct list_head *first = list->next;
|
||||
|
||||
if (first != list) {
|
||||
struct list_head *last = list->prev;
|
||||
struct list_head *at = head->next;
|
||||
|
||||
first->prev = head;
|
||||
head->next = first;
|
||||
|
||||
last->next = at;
|
||||
at->prev = last;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_entry - get the struct for this entry
|
||||
* @ptr: the &struct list_head pointer.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_entry(ptr, type, member) \
|
||||
((type *)((char *)(ptr)-(size_t)(&((type *)0)->member)))
|
||||
|
||||
/**
|
||||
* list_for_each - iterate over a list
|
||||
* @pos: the &struct list_head to use as a loop counter.
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
#endif
|
678
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/load.c
vendored
Normal file
678
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/load.c
vendored
Normal file
|
@ -0,0 +1,678 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#ifdef __native_client__
|
||||
#include <sys/syslimits.h>
|
||||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
#include "list.h"
|
||||
#include "hio.h"
|
||||
#include "tempfile.h"
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
#if !defined(HAVE_POPEN) && defined(WIN32)
|
||||
#include "win32/ptpopen.h"
|
||||
#endif
|
||||
#include "md5.h"
|
||||
#include "extras.h"
|
||||
#endif
|
||||
|
||||
|
||||
extern struct format_loader *format_loader[];
|
||||
|
||||
void libxmp_load_prologue(struct context_data *);
|
||||
void libxmp_load_epilogue(struct context_data *);
|
||||
int libxmp_prepare_scan(struct context_data *);
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
#include "depacker.h"
|
||||
|
||||
static struct depacker *depacker_list[] = {
|
||||
#if defined __AMIGA__ && !defined __AROS__
|
||||
&libxmp_depacker_xfd,
|
||||
#endif
|
||||
&libxmp_depacker_zip,
|
||||
&libxmp_depacker_lha,
|
||||
&libxmp_depacker_gzip,
|
||||
&libxmp_depacker_bzip2,
|
||||
&libxmp_depacker_xz,
|
||||
&libxmp_depacker_compress,
|
||||
&libxmp_depacker_pp,
|
||||
&libxmp_depacker_sqsh,
|
||||
&libxmp_depacker_arcfs,
|
||||
&libxmp_depacker_mmcmp,
|
||||
&libxmp_depacker_muse,
|
||||
&libxmp_depacker_lzx,
|
||||
&libxmp_depacker_s404,
|
||||
&libxmp_depacker_arc,
|
||||
NULL
|
||||
};
|
||||
|
||||
int test_oxm (FILE *);
|
||||
|
||||
#define BUFLEN 16384
|
||||
|
||||
static int execute_command(char *cmd, char *filename, FILE *t)
|
||||
{
|
||||
char line[1024], buf[BUFLEN];
|
||||
FILE *p;
|
||||
int n;
|
||||
|
||||
snprintf(line, 1024, cmd, filename);
|
||||
|
||||
#ifdef WIN32
|
||||
/* Note: The _popen function returns an invalid file opaque, if
|
||||
* used in a Windows program, that will cause the program to hang
|
||||
* indefinitely. _popen works properly in a Console application.
|
||||
* To create a Windows application that redirects input and output,
|
||||
* read the section "Creating a Child Process with Redirected Input
|
||||
* and Output" in the Win32 SDK. -- Mirko
|
||||
*/
|
||||
p = popen(line, "rb");
|
||||
#else
|
||||
/* Linux popen fails with "rb" */
|
||||
p = popen(line, "r");
|
||||
#endif
|
||||
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((n = fread(buf, 1, BUFLEN, p)) > 0) {
|
||||
fwrite(buf, 1, n, t);
|
||||
}
|
||||
|
||||
pclose (p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decrunch(HIO_HANDLE **h, char *filename, char **temp)
|
||||
{
|
||||
unsigned char b[1024];
|
||||
char *cmd;
|
||||
FILE *f, *t;
|
||||
int res;
|
||||
int headersize;
|
||||
int i;
|
||||
struct depacker *depacker = NULL;
|
||||
|
||||
cmd = NULL;
|
||||
res = 0;
|
||||
*temp = NULL;
|
||||
f = (*h)->handle.file;
|
||||
|
||||
headersize = fread(b, 1, 1024, f);
|
||||
if (headersize < 100) { /* minimum valid file size */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check built-in depackers */
|
||||
for (i = 0; depacker_list[i] != NULL; i++) {
|
||||
if (depacker_list[i]->test(b)) {
|
||||
depacker = depacker_list[i];
|
||||
D_(D_INFO "Use depacker %d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check external commands */
|
||||
if (depacker == NULL) {
|
||||
if (b[0] == 'M' && b[1] == 'O' && b[2] == '3') {
|
||||
/* MO3 */
|
||||
D_(D_INFO "mo3");
|
||||
cmd = "unmo3 -s \"%s\" STDOUT";
|
||||
} else if (memcmp(b, "Rar", 3) == 0) {
|
||||
/* rar */
|
||||
D_(D_INFO "rar");
|
||||
cmd = "unrar p -inul -xreadme -x*.diz -x*.nfo -x*.txt "
|
||||
"-x*.exe -x*.com \"%s\"";
|
||||
} else if (test_oxm(f) == 0) {
|
||||
/* oggmod */
|
||||
D_(D_INFO "oggmod");
|
||||
depacker = &libxmp_depacker_oxm;
|
||||
}
|
||||
}
|
||||
|
||||
if (fseek(f, 0, SEEK_SET) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (depacker == NULL && cmd == NULL) {
|
||||
D_(D_INFO "Not packed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined __ANDROID__ || defined __native_client__
|
||||
/* Don't use external helpers in android */
|
||||
if (cmd) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
D_(D_WARN "Depacking file... ");
|
||||
|
||||
if ((t = make_temp_file(temp)) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Depack file */
|
||||
if (cmd) {
|
||||
D_(D_INFO "External depacker: %s", cmd);
|
||||
if (execute_command(cmd, filename, t) < 0) {
|
||||
D_(D_CRIT "failed");
|
||||
goto err2;
|
||||
}
|
||||
} else if (depacker) {
|
||||
D_(D_INFO "Internal depacker");
|
||||
if (depacker->depack(f, t) < 0) {
|
||||
D_(D_CRIT "failed");
|
||||
goto err2;
|
||||
}
|
||||
}
|
||||
|
||||
D_(D_INFO "done");
|
||||
|
||||
if (fseek(t, 0, SEEK_SET) < 0) {
|
||||
D_(D_CRIT "fseek error");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
hio_close(*h);
|
||||
*h = hio_open_file(t);
|
||||
|
||||
return res;
|
||||
|
||||
err2:
|
||||
fclose(t);
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void set_md5sum(HIO_HANDLE *f, unsigned char *digest)
|
||||
{
|
||||
unsigned char buf[BUFLEN];
|
||||
MD5_CTX ctx;
|
||||
int bytes_read;
|
||||
|
||||
if (hio_size(f) <= 0) {
|
||||
memset(digest, 0, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
hio_seek(f, 0, SEEK_SET);
|
||||
|
||||
MD5Init(&ctx);
|
||||
while ((bytes_read = hio_read(buf, 1, BUFLEN, f)) > 0) {
|
||||
MD5Update(&ctx, buf, bytes_read);
|
||||
}
|
||||
MD5Final(digest, &ctx);
|
||||
}
|
||||
|
||||
static char *get_dirname(char *name)
|
||||
{
|
||||
char *div, *dirname;
|
||||
int len;
|
||||
|
||||
if ((div = strrchr(name, '/'))) {
|
||||
len = div - name + 1;
|
||||
dirname = malloc(len + 1);
|
||||
if (dirname != NULL) {
|
||||
memcpy(dirname, name, len);
|
||||
dirname[len] = 0;
|
||||
}
|
||||
} else {
|
||||
dirname = strdup("");
|
||||
}
|
||||
|
||||
return dirname;
|
||||
}
|
||||
|
||||
static char *get_basename(char *name)
|
||||
{
|
||||
char *div, *basename;
|
||||
|
||||
if ((div = strrchr(name, '/'))) {
|
||||
basename = strdup(div + 1);
|
||||
} else {
|
||||
basename = strdup(name);
|
||||
}
|
||||
|
||||
return basename;
|
||||
}
|
||||
#endif /* LIBXMP_CORE_PLAYER */
|
||||
|
||||
int xmp_test_module(char *path, struct xmp_test_info *info)
|
||||
{
|
||||
HIO_HANDLE *h;
|
||||
struct stat st;
|
||||
char buf[XMP_NAME_SIZE];
|
||||
int i;
|
||||
int ret = -XMP_ERROR_FORMAT;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
char *temp = NULL;
|
||||
#endif
|
||||
|
||||
if (stat(path, &st) < 0)
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
errno = EISDIR;
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((h = hio_open(path, "rb")) == NULL)
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (decrunch(&h, path, &temp) < 0) {
|
||||
ret = -XMP_ERROR_DEPACK;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* get size after decrunch */
|
||||
if (hio_size(h) < 256) { /* set minimum valid module size */
|
||||
ret = -XMP_ERROR_FORMAT;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (info != NULL) {
|
||||
*info->name = 0; /* reset name prior to testing */
|
||||
*info->type = 0; /* reset type prior to testing */
|
||||
}
|
||||
|
||||
for (i = 0; format_loader[i] != NULL; i++) {
|
||||
hio_seek(h, 0, SEEK_SET);
|
||||
if (format_loader[i]->test(h, buf, 0) == 0) {
|
||||
int is_prowizard = 0;
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (strcmp(format_loader[i]->name, "prowizard") == 0) {
|
||||
hio_seek(h, 0, SEEK_SET);
|
||||
pw_test_format(h, buf, 0, info);
|
||||
is_prowizard = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
fclose(h->handle.file);
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
unlink_temp_file(temp);
|
||||
#endif
|
||||
|
||||
if (info != NULL && !is_prowizard) {
|
||||
strncpy(info->name, buf, XMP_NAME_SIZE - 1);
|
||||
strncpy(info->type, format_loader[i]->name,
|
||||
XMP_NAME_SIZE - 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
err:
|
||||
hio_close(h);
|
||||
unlink_temp_file(temp);
|
||||
#else
|
||||
hio_close(h);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_module(xmp_context opaque, HIO_HANDLE *h)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i, j, ret;
|
||||
int test_result, load_result;
|
||||
|
||||
libxmp_load_prologue(ctx);
|
||||
|
||||
D_(D_WARN "load");
|
||||
test_result = load_result = -1;
|
||||
for (i = 0; format_loader[i] != NULL; i++) {
|
||||
hio_seek(h, 0, SEEK_SET);
|
||||
|
||||
if (hio_error(h)) {
|
||||
/* reset error flag */
|
||||
}
|
||||
|
||||
D_(D_WARN "test %s", format_loader[i]->name);
|
||||
test_result = format_loader[i]->test(h, NULL, 0);
|
||||
if (test_result == 0) {
|
||||
hio_seek(h, 0, SEEK_SET);
|
||||
D_(D_WARN "load format: %s", format_loader[i]->name);
|
||||
load_result = format_loader[i]->loader(m, h, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (test_result == 0 && load_result == 0)
|
||||
set_md5sum(h, m->md5);
|
||||
#endif
|
||||
|
||||
if (test_result < 0) {
|
||||
free(m->basename);
|
||||
free(m->dirname);
|
||||
return -XMP_ERROR_FORMAT;
|
||||
}
|
||||
|
||||
if (load_result < 0) {
|
||||
goto err_load;
|
||||
}
|
||||
|
||||
/* Sanity check: number of channels, module length */
|
||||
if (mod->chn > XMP_MAX_CHANNELS || mod->len > XMP_MAX_MOD_LENGTH) {
|
||||
goto err_load;
|
||||
}
|
||||
|
||||
/* Sanity check: channel pan */
|
||||
for (i = 0; i < mod->chn; i++) {
|
||||
if (mod->xxc[i].vol < 0 || mod->xxc[i].vol > 0xff) {
|
||||
goto err_load;
|
||||
}
|
||||
if (mod->xxc[i].pan < 0 || mod->xxc[i].pan > 0xff) {
|
||||
goto err_load;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check: patterns */
|
||||
if (mod->xxp == NULL) {
|
||||
goto err_load;
|
||||
}
|
||||
for (i = 0; i < mod->pat; i++) {
|
||||
if (mod->xxp[i] == NULL) {
|
||||
goto err_load;
|
||||
}
|
||||
for (j = 0; j < mod->chn; j++) {
|
||||
int t = mod->xxp[i]->index[j];
|
||||
if (t < 0 || t >= mod->trk || mod->xxt[t] == NULL) {
|
||||
goto err_load;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libxmp_adjust_string(mod->name);
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
libxmp_adjust_string(mod->xxi[i].name);
|
||||
}
|
||||
for (i = 0; i < mod->smp; i++) {
|
||||
libxmp_adjust_string(mod->xxs[i].name);
|
||||
}
|
||||
|
||||
libxmp_load_epilogue(ctx);
|
||||
|
||||
ret = libxmp_prepare_scan(ctx);
|
||||
if (ret < 0) {
|
||||
xmp_release_module(opaque);
|
||||
return ret;
|
||||
}
|
||||
|
||||
libxmp_scan_sequences(ctx);
|
||||
|
||||
ctx->state = XMP_STATE_LOADED;
|
||||
|
||||
return 0;
|
||||
|
||||
err_load:
|
||||
xmp_release_module(opaque);
|
||||
return -XMP_ERROR_LOAD;
|
||||
}
|
||||
|
||||
int xmp_load_module(xmp_context opaque, char *path)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
struct module_data *m = &ctx->m;
|
||||
long size;
|
||||
char *temp_name;
|
||||
#endif
|
||||
HIO_HANDLE *h;
|
||||
struct stat st;
|
||||
int ret;
|
||||
|
||||
D_(D_WARN "path = %s", path);
|
||||
|
||||
if (stat(path, &st) < 0) {
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
errno = EISDIR;
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((h = hio_open(path, "rb")) == NULL) {
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
D_(D_INFO "decrunch");
|
||||
if (decrunch(&h, path, &temp_name) < 0) {
|
||||
ret = -XMP_ERROR_DEPACK;
|
||||
goto err;
|
||||
}
|
||||
|
||||
size = hio_size(h);
|
||||
if (size < 256) { /* get size after decrunch */
|
||||
ret = -XMP_ERROR_FORMAT;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ctx->state > XMP_STATE_UNLOADED)
|
||||
xmp_release_module(opaque);
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
m->dirname = get_dirname(path);
|
||||
if (m->dirname == NULL) {
|
||||
ret = -XMP_ERROR_SYSTEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
m->basename = get_basename(path);
|
||||
if (m->basename == NULL) {
|
||||
ret = -XMP_ERROR_SYSTEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
m->filename = path; /* For ALM, SSMT, etc */
|
||||
m->size = size;
|
||||
#endif
|
||||
|
||||
ret = load_module(opaque, h);
|
||||
hio_close(h);
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
unlink_temp_file(temp_name);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
err:
|
||||
hio_close(h);
|
||||
unlink_temp_file(temp_name);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xmp_load_module_from_memory(xmp_context opaque, void *mem, long size)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct module_data *m = &ctx->m;
|
||||
HIO_HANDLE *h;
|
||||
int ret;
|
||||
|
||||
/* Use size < 0 for unknown/undetermined size */
|
||||
if (size == 0)
|
||||
size--;
|
||||
|
||||
if ((h = hio_open_mem(mem, size)) == NULL)
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
|
||||
if (ctx->state > XMP_STATE_UNLOADED)
|
||||
xmp_release_module(opaque);
|
||||
|
||||
m->filename = NULL;
|
||||
m->basename = NULL;
|
||||
m->dirname = NULL;
|
||||
m->size = size;
|
||||
|
||||
ret = load_module(opaque, h);
|
||||
|
||||
hio_close(h);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
int xmp_load_module_from_file(xmp_context opaque, void *file, long size)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct module_data *m = &ctx->m;
|
||||
HIO_HANDLE *h;
|
||||
FILE *f = fdopen(fileno((FILE *)file), "rb");
|
||||
int ret;
|
||||
|
||||
if ((h = hio_open_file(f)) == NULL)
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
|
||||
if (ctx->state > XMP_STATE_UNLOADED)
|
||||
xmp_release_module(opaque);
|
||||
|
||||
m->filename = NULL;
|
||||
m->basename = NULL;
|
||||
m->dirname = NULL;
|
||||
m->size = hio_size(h);
|
||||
|
||||
ret = load_module(opaque, h);
|
||||
|
||||
hio_close(h);
|
||||
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
void xmp_release_module(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i;
|
||||
|
||||
/* can't test this here, we must call release_module to clean up
|
||||
* load errors
|
||||
if (ctx->state < XMP_STATE_LOADED)
|
||||
return;
|
||||
*/
|
||||
|
||||
if (ctx->state > XMP_STATE_LOADED)
|
||||
xmp_end_player(opaque);
|
||||
|
||||
ctx->state = XMP_STATE_UNLOADED;
|
||||
|
||||
D_(D_INFO "Freeing memory");
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
libxmp_release_module_extras(ctx);
|
||||
#endif
|
||||
|
||||
if (mod->xxt != NULL) {
|
||||
for (i = 0; i < mod->trk; i++) {
|
||||
free(mod->xxt[i]);
|
||||
}
|
||||
free(mod->xxt);
|
||||
}
|
||||
|
||||
if (mod->xxp != NULL) {
|
||||
for (i = 0; i < mod->pat; i++) {
|
||||
free(mod->xxp[i]);
|
||||
}
|
||||
free(mod->xxp);
|
||||
}
|
||||
|
||||
if (mod->xxi != NULL) {
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
free(mod->xxi[i].sub);
|
||||
free(mod->xxi[i].extra);
|
||||
}
|
||||
free(mod->xxi);
|
||||
}
|
||||
|
||||
if (mod->xxs != NULL) {
|
||||
for (i = 0; i < mod->smp; i++) {
|
||||
if (mod->xxs[i].data != NULL) {
|
||||
free(mod->xxs[i].data - 4);
|
||||
}
|
||||
}
|
||||
free(mod->xxs);
|
||||
free(m->xtra);
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
if (m->xsmp != NULL) {
|
||||
for (i = 0; i < mod->smp; i++) {
|
||||
if (m->xsmp[i].data != NULL) {
|
||||
free(m->xsmp[i].data - 4);
|
||||
}
|
||||
}
|
||||
free(m->xsmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m->scan_cnt) {
|
||||
for (i = 0; i < mod->len; i++)
|
||||
free(m->scan_cnt[i]);
|
||||
free(m->scan_cnt);
|
||||
}
|
||||
|
||||
free(m->comment);
|
||||
|
||||
D_("free dirname/basename");
|
||||
free(m->dirname);
|
||||
free(m->basename);
|
||||
}
|
||||
|
||||
void xmp_scan_module(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
|
||||
if (ctx->state < XMP_STATE_LOADED)
|
||||
return;
|
||||
|
||||
libxmp_scan_sequences(ctx);
|
||||
}
|
425
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/load_helpers.c
vendored
Normal file
425
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/load_helpers.c
vendored
Normal file
|
@ -0,0 +1,425 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "common.h"
|
||||
#include "loaders/loader.h"
|
||||
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
/*
|
||||
* Handle special "module quirks" that can't be detected automatically
|
||||
* such as Protracker 2.x compatibility, vblank timing, etc.
|
||||
*/
|
||||
|
||||
struct module_quirk {
|
||||
uint8 md5[16];
|
||||
int flags;
|
||||
int mode;
|
||||
};
|
||||
|
||||
const struct module_quirk mq[] = {
|
||||
/* "No Mercy" by Alf/VTL (added by Martin Willers) */
|
||||
{
|
||||
{ 0x36, 0x6e, 0xc0, 0xfa, 0x96, 0x2a, 0xeb, 0xee,
|
||||
0x03, 0x4a, 0xa2, 0xdb, 0xaa, 0x49, 0xaa, 0xea },
|
||||
0, XMP_MODE_PROTRACKER
|
||||
},
|
||||
|
||||
/* mod.souvenir of china */
|
||||
{
|
||||
{ 0x93, 0xf1, 0x46, 0xae, 0xb7, 0x58, 0xc3, 0x9d,
|
||||
0x8b, 0x5f, 0xbc, 0x98, 0xbf, 0x23, 0x7a, 0x43 },
|
||||
XMP_FLAGS_FIXLOOP, XMP_MODE_AUTO
|
||||
},
|
||||
|
||||
/* "siedler ii" (added by Daniel Åkerud) */
|
||||
{
|
||||
{ 0x70, 0xaa, 0x03, 0x4d, 0xfb, 0x2f, 0x1f, 0x73,
|
||||
0xd9, 0xfd, 0xba, 0xfe, 0x13, 0x1b, 0xb7, 0x01 },
|
||||
XMP_FLAGS_VBLANK, XMP_MODE_AUTO
|
||||
},
|
||||
|
||||
/* "Klisje paa klisje" (added by Kjetil Torgrim Homme) */
|
||||
{
|
||||
{ 0xe9, 0x98, 0x01, 0x2c, 0x70, 0x0e, 0xb4, 0x3a,
|
||||
0xf0, 0x32, 0x17, 0x11, 0x30, 0x58, 0x29, 0xb2 },
|
||||
0, XMP_MODE_NOISETRACKER
|
||||
},
|
||||
|
||||
#if 0
|
||||
/* -- Already covered by Noisetracker fingerprinting -- */
|
||||
|
||||
/* Another version of Klisje paa klisje sent by Steve Fernandez */
|
||||
{
|
||||
{ 0x12, 0x19, 0x1c, 0x90, 0x41, 0xe3, 0xfd, 0x70,
|
||||
0xb7, 0xe6, 0xb3, 0x94, 0x8b, 0x21, 0x07, 0x63 },
|
||||
XMP_FLAGS_VBLANK
|
||||
},
|
||||
#endif
|
||||
|
||||
/* "((((( nebulos )))))" sent by Tero Auvinen (AMP version) */
|
||||
{
|
||||
{ 0x51, 0x6e, 0x8d, 0xcc, 0x35, 0x7d, 0x50, 0xde,
|
||||
0xa9, 0x85, 0xbe, 0xbf, 0x90, 0x2e, 0x42, 0xdc },
|
||||
0, XMP_MODE_NOISETRACKER
|
||||
},
|
||||
|
||||
/* Purple Motion's Sundance.mod, Music Channel BBS edit */
|
||||
{
|
||||
{ 0x5d, 0x3e, 0x1e, 0x08, 0x28, 0x52, 0x12, 0xc7,
|
||||
0x17, 0x64, 0x95, 0x75, 0x98, 0xe6, 0x95, 0xc1 },
|
||||
0, XMP_MODE_ST3
|
||||
},
|
||||
|
||||
/* Asle's Ode to Protracker */
|
||||
{
|
||||
{ 0x97, 0xa3, 0x7d, 0x30, 0xd7, 0xae, 0x6d, 0x50,
|
||||
0xc9, 0x62, 0xe9, 0xd8, 0x87, 0x1b, 0x7e, 0x8a },
|
||||
0, XMP_MODE_PROTRACKER
|
||||
},
|
||||
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
0, 0
|
||||
}
|
||||
};
|
||||
|
||||
static void module_quirks(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
int i;
|
||||
|
||||
for (i = 0; mq[i].flags != 0 || mq[i].mode != 0; i++) {
|
||||
if (!memcmp(m->md5, mq[i].md5, 16)) {
|
||||
p->flags |= mq[i].flags;
|
||||
p->mode = mq[i].mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the given string matches one of the blacklisted glob
|
||||
* patterns. Used to filter file names stored in archive files.
|
||||
*/
|
||||
int libxmp_exclude_match(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
static const char *const exclude[] = {
|
||||
"README", "readme",
|
||||
"*.DIZ", "*.diz",
|
||||
"*.NFO", "*.nfo",
|
||||
"*.DOC", "*.Doc", "*.doc",
|
||||
"*.INFO", "*.info", "*.Info",
|
||||
"*.TXT", "*.txt",
|
||||
"*.EXE", "*.exe",
|
||||
"*.COM", "*.com",
|
||||
"*.README", "*.readme", "*.Readme", "*.ReadMe",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (i = 0; exclude[i] != NULL; i++) {
|
||||
if (fnmatch(exclude[i], name, 0) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LIBXMP_CORE_PLAYER */
|
||||
|
||||
char *libxmp_adjust_string(char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < strlen(s); i++) {
|
||||
if (!isprint((int)s[i]) || ((uint8) s[i] > 127))
|
||||
s[i] = ' ';
|
||||
}
|
||||
|
||||
while (*s && (s[strlen(s) - 1] == ' ')) {
|
||||
s[strlen(s) - 1] = 0;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void check_envelope(struct xmp_envelope *env)
|
||||
{
|
||||
/* Disable envelope if invalid number of points */
|
||||
if (env->npt <= 0 || env->npt > XMP_MAX_ENV_POINTS) {
|
||||
env->flg &= ~XMP_ENVELOPE_ON;
|
||||
}
|
||||
|
||||
/* Disable envelope loop if invalid loop parameters */
|
||||
if (env->lps >= env->npt || env->lpe >= env->npt) {
|
||||
env->flg &= ~XMP_ENVELOPE_LOOP;
|
||||
}
|
||||
|
||||
/* Disable envelope loop if invalid sustain */
|
||||
if (env->sus >= env->npt) {
|
||||
env->flg &= ~XMP_ENVELOPE_ON;
|
||||
}
|
||||
}
|
||||
|
||||
void libxmp_load_prologue(struct context_data *ctx)
|
||||
{
|
||||
struct module_data *m = &ctx->m;
|
||||
int i;
|
||||
|
||||
/* Reset variables */
|
||||
memset(&m->mod, 0, sizeof (struct xmp_module));
|
||||
m->rrate = PAL_RATE;
|
||||
m->c4rate = C4_PAL_RATE;
|
||||
m->volbase = 0x40;
|
||||
m->gvol = m->gvolbase = 0x40;
|
||||
m->vol_table = NULL;
|
||||
m->quirk = 0;
|
||||
m->read_event_type = READ_EVENT_MOD;
|
||||
m->period_type = PERIOD_AMIGA;
|
||||
m->comment = NULL;
|
||||
m->scan_cnt = NULL;
|
||||
|
||||
/* Set defaults */
|
||||
m->mod.pat = 0;
|
||||
m->mod.trk = 0;
|
||||
m->mod.chn = 4;
|
||||
m->mod.ins = 0;
|
||||
m->mod.smp = 0;
|
||||
m->mod.spd = 6;
|
||||
m->mod.bpm = 125;
|
||||
m->mod.len = 0;
|
||||
m->mod.rst = 0;
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
m->extra = NULL;
|
||||
#endif
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
m->xsmp = NULL;
|
||||
#endif
|
||||
|
||||
m->time_factor = DEFAULT_TIME_FACTOR;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
int pan = (((i + 1) / 2) % 2) * 0xff;
|
||||
m->mod.xxc[i].pan = 0x80 + (pan - 0x80) * m->defpan / 100;
|
||||
m->mod.xxc[i].vol = 0x40;
|
||||
m->mod.xxc[i].flg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void libxmp_load_epilogue(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i, j;
|
||||
|
||||
mod->gvl = m->gvol;
|
||||
|
||||
/* Sanity check for module parameters */
|
||||
CLAMP(mod->len, 0, XMP_MAX_MOD_LENGTH);
|
||||
CLAMP(mod->pat, 0, 257); /* some formats have an extra pattern */
|
||||
CLAMP(mod->ins, 0, 255);
|
||||
CLAMP(mod->smp, 0, MAX_SAMPLES);
|
||||
CLAMP(mod->chn, 0, XMP_MAX_CHANNELS);
|
||||
|
||||
/* Fix cases where the restart value is invalid e.g. kc_fall8.xm
|
||||
* from http://aminet.net/mods/mvp/mvp_0002.lha (reported by
|
||||
* Ralf Hoffmann <ralf@boomerangsworld.de>)
|
||||
*/
|
||||
if (mod->rst >= mod->len) {
|
||||
mod->rst = 0;
|
||||
}
|
||||
|
||||
/* Sanity check for tempo and BPM */
|
||||
if (mod->spd <= 0 || mod->spd > 255) {
|
||||
mod->spd = 6;
|
||||
}
|
||||
CLAMP(mod->bpm, XMP_MIN_BPM, 255);
|
||||
|
||||
/* Set appropriate values for instrument volumes and subinstrument
|
||||
* global volumes when QUIRK_INSVOL is not set, to keep volume values
|
||||
* consistent if the user inspects struct xmp_module. We can later
|
||||
* set volumes in the loaders and eliminate the quirk.
|
||||
*/
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
if (~m->quirk & QUIRK_INSVOL) {
|
||||
mod->xxi[i].vol = m->volbase;
|
||||
}
|
||||
for (j = 0; j < mod->xxi[i].nsm; j++) {
|
||||
if (~m->quirk & QUIRK_INSVOL) {
|
||||
mod->xxi[i].sub[j].gvl = m->volbase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check for envelopes
|
||||
*/
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
check_envelope(&mod->xxi[i].aei);
|
||||
check_envelope(&mod->xxi[i].fei);
|
||||
check_envelope(&mod->xxi[i].pei);
|
||||
}
|
||||
|
||||
p->filter = 0;
|
||||
p->mode = XMP_MODE_AUTO;
|
||||
p->flags = p->player_flags;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
module_quirks(ctx);
|
||||
#endif
|
||||
libxmp_set_player_mode(ctx);
|
||||
}
|
||||
|
||||
int libxmp_prepare_scan(struct context_data *ctx)
|
||||
{
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i, ord;
|
||||
|
||||
if (mod->xxp == NULL || mod->xxt == NULL)
|
||||
return -XMP_ERROR_LOAD;
|
||||
ord = 0;
|
||||
while (ord < mod->len && mod->xxo[ord] >= mod->pat) {
|
||||
ord++;
|
||||
}
|
||||
|
||||
if (ord >= mod->len) {
|
||||
mod->len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
m->scan_cnt = calloc(sizeof (char *), mod->len);
|
||||
if (m->scan_cnt == NULL)
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
|
||||
for (i = 0; i < mod->len; i++) {
|
||||
int pat_idx = mod->xxo[i];
|
||||
struct xmp_pattern *pat;
|
||||
|
||||
/* Add pattern if referenced in orders */
|
||||
if (pat_idx < mod->pat && !mod->xxp[pat_idx]) {
|
||||
if (libxmp_alloc_pattern(mod, pat_idx) < 0) {
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
pat = pat_idx >= mod->pat ? NULL : mod->xxp[pat_idx];
|
||||
m->scan_cnt[i] = calloc(1, pat && pat->rows ? pat->rows : 1);
|
||||
if (m->scan_cnt[i] == NULL)
|
||||
return -XMP_ERROR_SYSTEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process player personality flags */
|
||||
int libxmp_set_player_mode(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
int q;
|
||||
|
||||
switch (p->mode) {
|
||||
case XMP_MODE_AUTO:
|
||||
break;
|
||||
case XMP_MODE_MOD:
|
||||
m->c4rate = C4_PAL_RATE;
|
||||
m->quirk = 0;
|
||||
m->read_event_type = READ_EVENT_MOD;
|
||||
m->period_type = PERIOD_AMIGA;
|
||||
break;
|
||||
case XMP_MODE_NOISETRACKER:
|
||||
m->c4rate = C4_PAL_RATE;
|
||||
m->quirk = QUIRK_NOBPM;
|
||||
m->read_event_type = READ_EVENT_MOD;
|
||||
m->period_type = PERIOD_MODRNG;
|
||||
break;
|
||||
case XMP_MODE_PROTRACKER:
|
||||
m->c4rate = C4_PAL_RATE;
|
||||
m->quirk = QUIRK_PROTRACK;
|
||||
m->read_event_type = READ_EVENT_MOD;
|
||||
m->period_type = PERIOD_MODRNG;
|
||||
break;
|
||||
case XMP_MODE_S3M:
|
||||
q = m->quirk & (QUIRK_VSALL | QUIRK_ARPMEM);
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->quirk = QUIRKS_ST3 | q;
|
||||
m->read_event_type = READ_EVENT_ST3;
|
||||
break;
|
||||
case XMP_MODE_ST3:
|
||||
q = m->quirk & (QUIRK_VSALL | QUIRK_ARPMEM);
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->quirk = QUIRKS_ST3 | QUIRK_ST3BUGS | q;
|
||||
m->read_event_type = READ_EVENT_ST3;
|
||||
break;
|
||||
case XMP_MODE_ST3GUS:
|
||||
q = m->quirk & (QUIRK_VSALL | QUIRK_ARPMEM);
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->quirk = QUIRKS_ST3 | QUIRK_ST3BUGS | q;
|
||||
m->quirk &= ~QUIRK_RSTCHN;
|
||||
m->read_event_type = READ_EVENT_ST3;
|
||||
break;
|
||||
case XMP_MODE_XM:
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->quirk = QUIRKS_FT2;
|
||||
m->read_event_type = READ_EVENT_FT2;
|
||||
break;
|
||||
case XMP_MODE_FT2:
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->quirk = QUIRKS_FT2 | QUIRK_FT2BUGS;
|
||||
m->read_event_type = READ_EVENT_FT2;
|
||||
break;
|
||||
case XMP_MODE_IT:
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->quirk = QUIRKS_IT | QUIRK_VIBHALF | QUIRK_VIBINV;
|
||||
m->read_event_type = READ_EVENT_IT;
|
||||
break;
|
||||
case XMP_MODE_ITSMP:
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->quirk = QUIRKS_IT | QUIRK_VIBHALF | QUIRK_VIBINV;
|
||||
m->quirk &= ~(QUIRK_VIRTUAL | QUIRK_RSTCHN);
|
||||
m->read_event_type = READ_EVENT_IT;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
15
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/Makefile
vendored
Normal file
15
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/Makefile
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
LOADERS = xm_load.o mod_load.o s3m_load.o it_load.o
|
||||
|
||||
LOADERS_OBJS = common.o itsex.o sample.o $(LOADERS)
|
||||
LOADERS_DFILES = Makefile $(LOADERS_OBJS:.o=.c) \
|
||||
it.h loader.h mod.h s3m.h xm.h
|
||||
LOADERS_PATH = src/loaders
|
||||
|
||||
OBJS += $(addprefix $(LOADERS_PATH)/,$(LOADERS_OBJS))
|
||||
|
||||
default:
|
||||
|
||||
dist-loaders::
|
||||
mkdir -p $(DIST)/$(LOADERS_PATH)
|
||||
cp -RPp $(addprefix $(LOADERS_PATH)/,$(LOADERS_DFILES)) $(DIST)/$(LOADERS_PATH)
|
364
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/common.c
vendored
Normal file
364
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/common.c
vendored
Normal file
|
@ -0,0 +1,364 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#ifndef WIN32
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include "xmp.h"
|
||||
#include "../common.h"
|
||||
#include "../period.h"
|
||||
#include "loader.h"
|
||||
|
||||
int libxmp_init_instrument(struct module_data *m)
|
||||
{
|
||||
struct xmp_module *mod = &m->mod;
|
||||
|
||||
if (mod->ins > 0) {
|
||||
mod->xxi = calloc(sizeof (struct xmp_instrument), mod->ins);
|
||||
if (mod->xxi == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mod->smp > 0) {
|
||||
int i;
|
||||
|
||||
mod->xxs = calloc(sizeof (struct xmp_sample), mod->smp);
|
||||
if (mod->xxs == NULL)
|
||||
return -1;
|
||||
m->xtra = calloc(sizeof (struct extra_sample_data), mod->smp);
|
||||
if (m->xtra == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < mod->smp; i++) {
|
||||
m->xtra[i].c5spd = m->c4rate;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxmp_alloc_subinstrument(struct xmp_module *mod, int i, int num)
|
||||
{
|
||||
if (num == 0)
|
||||
return 0;
|
||||
|
||||
mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), num);
|
||||
if (mod->xxi[i].sub == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxmp_init_pattern(struct xmp_module *mod)
|
||||
{
|
||||
mod->xxt = calloc(sizeof (struct xmp_track *), mod->trk);
|
||||
if (mod->xxt == NULL)
|
||||
return -1;
|
||||
|
||||
mod->xxp = calloc(sizeof (struct xmp_pattern *), mod->pat);
|
||||
if (mod->xxp == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxmp_alloc_pattern(struct xmp_module *mod, int num)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (num < 0 || num >= mod->pat || mod->xxp[num] != NULL)
|
||||
return -1;
|
||||
|
||||
mod->xxp[num] = calloc(1, sizeof (struct xmp_pattern) +
|
||||
sizeof (int) * (mod->chn - 1));
|
||||
if (mod->xxp[num] == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxmp_alloc_track(struct xmp_module *mod, int num, int rows)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (num < 0 || num >= mod->trk || mod->xxt[num] != NULL || rows <= 0)
|
||||
return -1;
|
||||
|
||||
mod->xxt[num] = calloc(sizeof (struct xmp_track) +
|
||||
sizeof (struct xmp_event) * (rows - 1), 1);
|
||||
if (mod->xxt[num] == NULL)
|
||||
return -1;
|
||||
|
||||
mod->xxt[num]->rows = rows;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxmp_alloc_tracks_in_pattern(struct xmp_module *mod, int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
D_(D_INFO "Alloc %d tracks of %d rows", mod->chn, mod->xxp[num]->rows);
|
||||
for (i = 0; i < mod->chn; i++) {
|
||||
int t = num * mod->chn + i;
|
||||
int rows = mod->xxp[num]->rows;
|
||||
|
||||
if (libxmp_alloc_track(mod, t, rows) < 0)
|
||||
return -1;
|
||||
|
||||
mod->xxp[num]->index[i] = t;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxmp_alloc_pattern_tracks(struct xmp_module *mod, int num, int rows)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (rows < 0 || rows > 256)
|
||||
return -1;
|
||||
|
||||
if (libxmp_alloc_pattern(mod, num) < 0)
|
||||
return -1;
|
||||
|
||||
mod->xxp[num]->rows = rows;
|
||||
|
||||
if (libxmp_alloc_tracks_in_pattern(mod, num) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sample number adjustment by Vitamin/CAIG */
|
||||
struct xmp_sample *libxmp_realloc_samples(struct xmp_sample *buf, int *size, int new_size)
|
||||
{
|
||||
buf = realloc(buf, sizeof (struct xmp_sample) * new_size);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
if (new_size > *size)
|
||||
memset(buf + *size, 0, sizeof (struct xmp_sample) * (new_size - *size));
|
||||
*size = new_size;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *libxmp_instrument_name(struct xmp_module *mod, int i, uint8 *r, int n)
|
||||
{
|
||||
CLAMP(n, 0, 31);
|
||||
|
||||
return libxmp_copy_adjust(mod->xxi[i].name, r, n);
|
||||
}
|
||||
|
||||
char *libxmp_copy_adjust(char *s, uint8 *r, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(s, 0, n + 1);
|
||||
strncpy(s, (char *)r, n);
|
||||
|
||||
for (i = 0; s[i] && i < n; i++) {
|
||||
if (!isprint((int)s[i]) || ((uint8)s[i] > 127))
|
||||
s[i] = '.';
|
||||
}
|
||||
|
||||
while (*s && (s[strlen(s) - 1] == ' '))
|
||||
s[strlen(s) - 1] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void libxmp_read_title(HIO_HANDLE *f, char *t, int s)
|
||||
{
|
||||
uint8 buf[XMP_NAME_SIZE];
|
||||
|
||||
if (t == NULL)
|
||||
return;
|
||||
|
||||
if (s >= XMP_NAME_SIZE)
|
||||
s = XMP_NAME_SIZE -1;
|
||||
|
||||
memset(t, 0, s + 1);
|
||||
|
||||
hio_read(buf, 1, s, f); /* coverity[check_return] */
|
||||
buf[s] = 0;
|
||||
libxmp_copy_adjust(t, buf, s);
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
int libxmp_test_name(uint8 *s, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* ACS_Team2.mod has a backspace in instrument name */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (s[i] > 0x7f)
|
||||
return -1;
|
||||
if (s[i] > 0 && s[i] < 32 && s[i] != 0x08)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Honor Noisetracker effects:
|
||||
*
|
||||
* 0 - arpeggio
|
||||
* 1 - portamento up
|
||||
* 2 - portamento down
|
||||
* 3 - Tone-portamento
|
||||
* 4 - Vibrato
|
||||
* A - Slide volume
|
||||
* B - Position jump
|
||||
* C - Set volume
|
||||
* D - Pattern break
|
||||
* E - Set filter (keep the led off, please!)
|
||||
* F - Set speed (now up to $1F)
|
||||
*
|
||||
* Pex Tufvesson's notes from http://www.livet.se/mahoney/:
|
||||
*
|
||||
* Note that some of the modules will have bugs in the playback with all
|
||||
* known PC module players. This is due to that in many demos where I synced
|
||||
* events in the demo with the music, I used commands that these newer PC
|
||||
* module players erroneously interpret as "newer-version-trackers commands".
|
||||
* Which they aren't.
|
||||
*/
|
||||
void libxmp_decode_noisetracker_event(struct xmp_event *event, uint8 *mod_event)
|
||||
{
|
||||
int fxt;
|
||||
|
||||
memset(event, 0, sizeof (struct xmp_event));
|
||||
event->note = libxmp_period_to_note((LSN(mod_event[0]) << 8) + mod_event[1]);
|
||||
event->ins = ((MSN(mod_event[0]) << 4) | MSN(mod_event[2]));
|
||||
fxt = LSN(mod_event[2]);
|
||||
|
||||
if (fxt <= 0x06 || (fxt >= 0x0a && fxt != 0x0e)) {
|
||||
event->fxt = fxt;
|
||||
event->fxp = mod_event[3];
|
||||
}
|
||||
|
||||
libxmp_disable_continue_fx(event);
|
||||
}
|
||||
#endif
|
||||
|
||||
void libxmp_decode_protracker_event(struct xmp_event *event, uint8 *mod_event)
|
||||
{
|
||||
int fxt = LSN(mod_event[2]);
|
||||
|
||||
memset(event, 0, sizeof (struct xmp_event));
|
||||
event->note = libxmp_period_to_note((LSN(mod_event[0]) << 8) + mod_event[1]);
|
||||
event->ins = ((MSN(mod_event[0]) << 4) | MSN(mod_event[2]));
|
||||
|
||||
if (fxt != 0x08) {
|
||||
event->fxt = fxt;
|
||||
event->fxp = mod_event[3];
|
||||
}
|
||||
|
||||
libxmp_disable_continue_fx(event);
|
||||
}
|
||||
|
||||
void libxmp_disable_continue_fx(struct xmp_event *event)
|
||||
{
|
||||
if (event->fxp == 0) {
|
||||
switch (event->fxt) {
|
||||
case 0x05:
|
||||
event->fxt = 0x03;
|
||||
break;
|
||||
case 0x06:
|
||||
event->fxt = 0x04;
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x0a:
|
||||
event->fxt = 0x00;
|
||||
}
|
||||
} else if (event->fxt == 0x0e) {
|
||||
if (event->fxp == 0xa0 || event->fxp == 0xb0) {
|
||||
event->fxt = event->fxp = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
#ifndef WIN32
|
||||
|
||||
/* Given a directory, see if file exists there, ignoring case */
|
||||
|
||||
int libxmp_check_filename_case(char *dir, char *name, char *new_name, int size)
|
||||
{
|
||||
int found = 0;
|
||||
DIR *dirfd;
|
||||
struct dirent *d;
|
||||
|
||||
dirfd = opendir(dir);
|
||||
if (dirfd == NULL)
|
||||
return 0;
|
||||
|
||||
while ((d = readdir(dirfd))) {
|
||||
if (!strcasecmp(d->d_name, name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
strncpy(new_name, d->d_name, size);
|
||||
|
||||
closedir(dirfd);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* FIXME: implement functionality for Win32 */
|
||||
|
||||
int libxmp_check_filename_case(char *dir, char *name, char *new_name, int size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void libxmp_get_instrument_path(struct module_data *m, char *path, int size)
|
||||
{
|
||||
if (m->instrument_path) {
|
||||
strncpy(path, m->instrument_path, size);
|
||||
} else if (getenv("XMP_INSTRUMENT_PATH")) {
|
||||
strncpy(path, getenv("XMP_INSTRUMENT_PATH"), size);
|
||||
} else {
|
||||
strncpy(path, ".", size);
|
||||
}
|
||||
}
|
||||
#endif /* LIBXMP_CORE_PLAYER */
|
||||
|
||||
void libxmp_set_type(struct module_data *m, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
vsnprintf(m->mod.type, XMP_NAME_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
181
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/it.h
vendored
Normal file
181
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/it.h
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* IT flags */
|
||||
#define IT_STEREO 0x01
|
||||
#define IT_VOL_OPT 0x02 /* Not recognized */
|
||||
#define IT_USE_INST 0x04
|
||||
#define IT_LINEAR_FREQ 0x08
|
||||
#define IT_OLD_FX 0x10
|
||||
#define IT_LINK_GXX 0x20
|
||||
|
||||
/* IT special */
|
||||
#define IT_HAS_MSG 0x01
|
||||
|
||||
/* IT instrument flags */
|
||||
#define IT_INST_SAMPLE 0x01
|
||||
#define IT_INST_16BIT 0x02
|
||||
#define IT_INST_STEREO 0x04
|
||||
#define IT_INST_LOOP 0x10
|
||||
#define IT_INST_SLOOP 0x20
|
||||
#define IT_INST_BLOOP 0x40
|
||||
#define IT_INST_BSLOOP 0x80
|
||||
|
||||
/* IT sample flags */
|
||||
#define IT_SMP_SAMPLE 0x01
|
||||
#define IT_SMP_16BIT 0x02
|
||||
#define IT_SMP_STEREO 0x04 /* unsupported */
|
||||
#define IT_SMP_COMP 0x08 /* unsupported */
|
||||
#define IT_SMP_LOOP 0x10
|
||||
#define IT_SMP_SLOOP 0x20
|
||||
#define IT_SMP_BLOOP 0x40
|
||||
#define IT_SMP_BSLOOP 0x80
|
||||
|
||||
/* IT sample conversion flags */
|
||||
#define IT_CVT_SIGNED 0x01
|
||||
#define IT_CVT_BIGEND 0x02 /* 'safe to ignore' according to ittech.txt */
|
||||
#define IT_CVT_DIFF 0x04 /* Compressed sample flag */
|
||||
#define IT_CVT_BYTEDIFF 0x08 /* 'safe to ignore' according to ittech.txt */
|
||||
#define IT_CVT_12BIT 0x10 /* 'safe to ignore' according to ittech.txt */
|
||||
|
||||
/* IT envelope flags */
|
||||
#define IT_ENV_ON 0x01
|
||||
#define IT_ENV_LOOP 0x02
|
||||
#define IT_ENV_SLOOP 0x04
|
||||
#define IT_ENV_CARRY 0x08
|
||||
#define IT_ENV_FILTER 0x80
|
||||
|
||||
|
||||
struct it_file_header {
|
||||
uint32 magic; /* 'IMPM' */
|
||||
uint8 name[26]; /* ASCIIZ Song name */
|
||||
uint8 hilite_min; /* Pattern editor highlight */
|
||||
uint8 hilite_maj; /* Pattern editor highlight */
|
||||
uint16 ordnum; /* Number of orders (must be even) */
|
||||
uint16 insnum; /* Number of instruments */
|
||||
uint16 smpnum; /* Number of samples */
|
||||
uint16 patnum; /* Number of patterns */
|
||||
uint16 cwt; /* Tracker ID and version */
|
||||
uint16 cmwt; /* Format version */
|
||||
uint16 flags; /* Flags */
|
||||
uint16 special; /* More flags */
|
||||
uint8 gv; /* Global volume */
|
||||
uint8 mv; /* Master volume */
|
||||
uint8 is; /* Initial speed */
|
||||
uint8 it; /* Initial tempo */
|
||||
uint8 sep; /* Panning separation */
|
||||
uint8 pwd; /* Pitch wheel depth */
|
||||
uint16 msglen; /* Message length */
|
||||
uint32 msgofs; /* Message offset */
|
||||
uint32 rsvd; /* Reserved */
|
||||
uint8 chpan[64]; /* Channel pan settings */
|
||||
uint8 chvol[64]; /* Channel volume settings */
|
||||
};
|
||||
|
||||
struct it_instrument1_header {
|
||||
uint32 magic; /* 'IMPI' */
|
||||
uint8 dosname[12]; /* DOS filename */
|
||||
uint8 zero; /* Always zero */
|
||||
uint8 flags; /* Instrument flags */
|
||||
uint8 vls; /* Volume loop start */
|
||||
uint8 vle; /* Volume loop end */
|
||||
uint8 sls; /* Sustain loop start */
|
||||
uint8 sle; /* Sustain loop end */
|
||||
uint16 rsvd1; /* Reserved */
|
||||
uint16 fadeout; /* Fadeout (release) */
|
||||
uint8 nna; /* New note action */
|
||||
uint8 dnc; /* Duplicate note check */
|
||||
uint16 trkvers; /* Tracker version */
|
||||
uint8 nos; /* Number of samples */
|
||||
uint8 rsvd2; /* Reserved */
|
||||
uint8 name[26]; /* ASCIIZ Instrument name */
|
||||
uint8 rsvd3[6]; /* Reserved */
|
||||
uint8 keys[240];
|
||||
uint8 epoint[200];
|
||||
uint8 enode[50];
|
||||
};
|
||||
|
||||
struct it_instrument2_header {
|
||||
uint32 magic; /* 'IMPI' */
|
||||
uint8 dosname[12]; /* DOS filename */
|
||||
uint8 zero; /* Always zero */
|
||||
uint8 nna; /* New Note Action */
|
||||
uint8 dct; /* Duplicate Check Type */
|
||||
uint8 dca; /* Duplicate Check Action */
|
||||
uint16 fadeout;
|
||||
uint8 pps; /* Pitch-Pan Separation */
|
||||
uint8 ppc; /* Pitch-Pan Center */
|
||||
uint8 gbv; /* Global Volume */
|
||||
uint8 dfp; /* Default pan */
|
||||
uint8 rv; /* Random volume variation */
|
||||
uint8 rp; /* Random pan variation */
|
||||
uint16 trkvers; /* Not used: tracked version */
|
||||
uint8 nos; /* Not used: number of samples */
|
||||
uint8 rsvd1; /* Reserved */
|
||||
uint8 name[26]; /* ASCIIZ Instrument name */
|
||||
uint8 ifc; /* Initial filter cutoff */
|
||||
uint8 ifr; /* Initial filter resonance */
|
||||
uint8 mch; /* MIDI channel */
|
||||
uint8 mpr; /* MIDI program */
|
||||
uint16 mbnk; /* MIDI bank */
|
||||
uint8 keys[240];
|
||||
};
|
||||
|
||||
struct it_envelope_node {
|
||||
int8 y;
|
||||
uint16 x;
|
||||
};
|
||||
|
||||
struct it_envelope {
|
||||
uint8 flg; /* Flags */
|
||||
uint8 num; /* Number of node points */
|
||||
uint8 lpb; /* Loop beginning */
|
||||
uint8 lpe; /* Loop end */
|
||||
uint8 slb; /* Sustain loop beginning */
|
||||
uint8 sle; /* Sustain loop end */
|
||||
struct it_envelope_node node[25];
|
||||
uint8 unused;
|
||||
};
|
||||
|
||||
struct it_sample_header {
|
||||
uint32 magic; /* 'IMPS' */
|
||||
uint8 dosname[12]; /* DOS filename */
|
||||
uint8 zero; /* Always zero */
|
||||
uint8 gvl; /* Global volume for instrument */
|
||||
uint8 flags; /* Sample flags */
|
||||
uint8 vol; /* Volume */
|
||||
uint8 name[26]; /* ASCIIZ sample name */
|
||||
uint8 convert; /* Sample flags */
|
||||
uint8 dfp; /* Default pan */
|
||||
uint32 length; /* Length */
|
||||
uint32 loopbeg; /* Loop begin */
|
||||
uint32 loopend; /* Loop end */
|
||||
uint32 c5spd; /* C 5 speed */
|
||||
uint32 sloopbeg; /* SusLoop begin */
|
||||
uint32 sloopend; /* SusLoop end */
|
||||
uint32 sample_ptr; /* Sample pointer */
|
||||
uint8 vis; /* Vibrato speed */
|
||||
uint8 vid; /* Vibrato depth */
|
||||
uint8 vir; /* Vibrato rate */
|
||||
uint8 vit; /* Vibrato waveform */
|
||||
};
|
||||
|
1387
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/it_load.c
vendored
Normal file
1387
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/it_load.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
232
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/itsex.c
vendored
Normal file
232
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/itsex.c
vendored
Normal file
|
@ -0,0 +1,232 @@
|
|||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
|
||||
/* Public domain IT sample decompressor by Olivier Lapicque */
|
||||
|
||||
#include "loader.h"
|
||||
|
||||
static inline uint32 read_bits(HIO_HANDLE *ibuf, uint32 *bitbuf, int *bitnum, int n)
|
||||
{
|
||||
uint32 retval = 0;
|
||||
int i = n;
|
||||
int bnum = *bitnum, bbuf = *bitbuf;
|
||||
|
||||
if (n > 0) {
|
||||
do {
|
||||
if (bnum == 0) {
|
||||
bbuf = hio_read8(ibuf);
|
||||
bnum = 8;
|
||||
}
|
||||
retval >>= 1;
|
||||
retval |= bbuf << 31;
|
||||
bbuf >>= 1;
|
||||
bnum--;
|
||||
i--;
|
||||
} while (i != 0);
|
||||
|
||||
i = n;
|
||||
|
||||
*bitnum = bnum;
|
||||
*bitbuf = bbuf;
|
||||
}
|
||||
|
||||
return (retval >> (32 - i));
|
||||
}
|
||||
|
||||
|
||||
int itsex_decompress8(HIO_HANDLE *src, uint8 *dst, int len, int it215)
|
||||
{
|
||||
/* uint32 size = 0; */
|
||||
uint32 block_count = 0;
|
||||
uint32 bitbuf = 0;
|
||||
int bitnum = 0;
|
||||
uint8 left = 0, temp = 0, temp2 = 0;
|
||||
uint32 d, pos;
|
||||
|
||||
while (len) {
|
||||
if (!block_count) {
|
||||
block_count = 0x8000;
|
||||
/*size =*/ hio_read16l(src);
|
||||
left = 9;
|
||||
temp = temp2 = 0;
|
||||
bitbuf = bitnum = 0;
|
||||
}
|
||||
|
||||
d = block_count;
|
||||
if (d > len)
|
||||
d = len;
|
||||
|
||||
/* Unpacking */
|
||||
pos = 0;
|
||||
do {
|
||||
uint16 bits = read_bits(src, &bitbuf, &bitnum, left);
|
||||
if (hio_eof(src))
|
||||
return -1;
|
||||
|
||||
if (left < 7) {
|
||||
uint32 i = 1 << (left - 1);
|
||||
uint32 j = bits & 0xffff;
|
||||
if (i != j)
|
||||
goto unpack_byte;
|
||||
bits = (read_bits(src, &bitbuf, &bitnum, 3)
|
||||
+ 1) & 0xff;
|
||||
if (hio_eof(src))
|
||||
return -1;
|
||||
|
||||
left = ((uint8)bits < left) ? (uint8)bits :
|
||||
(uint8)((bits + 1) & 0xff);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (left < 9) {
|
||||
uint16 i = (0xff >> (9 - left)) + 4;
|
||||
uint16 j = i - 8;
|
||||
|
||||
if ((bits <= j) || (bits > i))
|
||||
goto unpack_byte;
|
||||
|
||||
bits -= j;
|
||||
left = ((uint8)(bits & 0xff) < left) ?
|
||||
(uint8)(bits & 0xff) :
|
||||
(uint8)((bits + 1) & 0xff);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (left >= 10)
|
||||
goto skip_byte;
|
||||
|
||||
if (bits >= 256) {
|
||||
left = (uint8) (bits + 1) & 0xff;
|
||||
goto next;
|
||||
}
|
||||
|
||||
unpack_byte:
|
||||
if (left < 8) {
|
||||
uint8 shift = 8 - left;
|
||||
signed char c = (signed char)(bits << shift);
|
||||
c >>= shift;
|
||||
bits = (uint16) c;
|
||||
}
|
||||
bits += temp;
|
||||
temp = (uint8)bits;
|
||||
temp2 += temp;
|
||||
dst[pos] = it215 ? temp2 : temp;
|
||||
|
||||
skip_byte:
|
||||
pos++;
|
||||
|
||||
next:
|
||||
/* if (slen <= 0)
|
||||
return -1 */;
|
||||
} while (pos < d);
|
||||
|
||||
/* Move On */
|
||||
block_count -= d;
|
||||
len -= d;
|
||||
dst += d;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int itsex_decompress16(HIO_HANDLE *src, int16 *dst, int len, int it215)
|
||||
{
|
||||
/* uint32 size = 0; */
|
||||
uint32 block_count = 0;
|
||||
uint32 bitbuf = 0;
|
||||
int bitnum = 0;
|
||||
uint8 left = 0;
|
||||
int16 temp = 0, temp2 = 0;
|
||||
uint32 d, pos;
|
||||
|
||||
while (len) {
|
||||
if (!block_count) {
|
||||
block_count = 0x4000;
|
||||
/*size =*/ hio_read16l(src);
|
||||
left = 17;
|
||||
temp = temp2 = 0;
|
||||
bitbuf = bitnum = 0;
|
||||
}
|
||||
|
||||
d = block_count;
|
||||
if (d > len)
|
||||
d = len;
|
||||
|
||||
/* Unpacking */
|
||||
pos = 0;
|
||||
do {
|
||||
uint32 bits = read_bits(src, &bitbuf, &bitnum, left);
|
||||
if (hio_eof(src))
|
||||
return -1;
|
||||
|
||||
if (left < 7) {
|
||||
uint32 i = 1 << (left - 1);
|
||||
uint32 j = bits;
|
||||
|
||||
if (i != j)
|
||||
goto unpack_byte;
|
||||
|
||||
bits = read_bits(src, &bitbuf, &bitnum, 4) + 1;
|
||||
|
||||
if (hio_eof(src))
|
||||
return -1;
|
||||
|
||||
left = ((uint8)(bits & 0xff) < left) ?
|
||||
(uint8)(bits & 0xff) :
|
||||
(uint8)((bits + 1) & 0xff);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (left < 17) {
|
||||
uint32 i = (0xffff >> (17 - left)) + 8;
|
||||
uint32 j = (i - 16) & 0xffff;
|
||||
|
||||
if ((bits <= j) || (bits > (i & 0xffff)))
|
||||
goto unpack_byte;
|
||||
|
||||
bits -= j;
|
||||
left = ((uint8)(bits & 0xff) < left) ?
|
||||
(uint8)(bits & 0xff) :
|
||||
(uint8)((bits + 1) & 0xff);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (left >= 18)
|
||||
goto skip_byte;
|
||||
|
||||
if (bits >= 0x10000) {
|
||||
left = (uint8)(bits + 1) & 0xff;
|
||||
goto next;
|
||||
}
|
||||
|
||||
unpack_byte:
|
||||
if (left < 16) {
|
||||
uint8 shift = 16 - left;
|
||||
int16 c = (int16)(bits << shift);
|
||||
c >>= shift;
|
||||
bits = (uint32) c;
|
||||
}
|
||||
bits += temp;
|
||||
temp = (int16)bits;
|
||||
temp2 += temp;
|
||||
dst[pos] = (it215) ? temp2 : temp;
|
||||
|
||||
skip_byte:
|
||||
pos++;
|
||||
|
||||
next:
|
||||
/* if (slen <= 0)
|
||||
return -1 */;
|
||||
} while (pos < d);
|
||||
|
||||
/* Move On */
|
||||
block_count -= d;
|
||||
len -= d;
|
||||
dst += d;
|
||||
if (len <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LIBXMP_CORE_DISABLE_IT */
|
64
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/loader.h
vendored
Normal file
64
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/loader.h
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
#ifndef XMP_LOADER_H
|
||||
#define XMP_LOADER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../common.h"
|
||||
#include "../effects.h"
|
||||
#include "../format.h"
|
||||
#include "../hio.h"
|
||||
|
||||
/* Sample flags */
|
||||
#define SAMPLE_FLAG_DIFF 0x0001 /* Differential */
|
||||
#define SAMPLE_FLAG_UNS 0x0002 /* Unsigned */
|
||||
#define SAMPLE_FLAG_8BDIFF 0x0004
|
||||
#define SAMPLE_FLAG_7BIT 0x0008
|
||||
#define SAMPLE_FLAG_NOLOAD 0x0010 /* Get from buffer, don't load */
|
||||
#define SAMPLE_FLAG_BIGEND 0x0040 /* Big-endian */
|
||||
#define SAMPLE_FLAG_VIDC 0x0080 /* Archimedes VIDC logarithmic */
|
||||
/*#define SAMPLE_FLAG_STEREO 0x0100 Interleaved stereo sample */
|
||||
#define SAMPLE_FLAG_FULLREP 0x0200 /* Play full sample before looping */
|
||||
#define SAMPLE_FLAG_ADLIB 0x1000 /* Adlib synth instrument */
|
||||
#define SAMPLE_FLAG_HSC 0x2000 /* HSC Adlib synth instrument */
|
||||
#define SAMPLE_FLAG_ADPCM 0x4000 /* ADPCM4 encoded samples */
|
||||
|
||||
#define DEFPAN(x) (0x80 + ((x) - 0x80) * m->defpan / 100)
|
||||
|
||||
int libxmp_init_instrument (struct module_data *);
|
||||
int libxmp_alloc_subinstrument (struct xmp_module *, int, int);
|
||||
int libxmp_init_pattern (struct xmp_module *);
|
||||
int libxmp_alloc_pattern (struct xmp_module *, int);
|
||||
int libxmp_alloc_track (struct xmp_module *, int, int);
|
||||
int libxmp_alloc_tracks_in_pattern (struct xmp_module *, int);
|
||||
int libxmp_alloc_pattern_tracks (struct xmp_module *, int, int);
|
||||
char *libxmp_instrument_name (struct xmp_module *, int, uint8 *, int);
|
||||
struct xmp_sample* libxmp_realloc_samples(struct xmp_sample *, int *, int);
|
||||
|
||||
char *libxmp_copy_adjust (char *, uint8 *, int);
|
||||
int libxmp_test_name (uint8 *, int);
|
||||
void libxmp_read_title (HIO_HANDLE *, char *, int);
|
||||
void libxmp_set_xxh_defaults (struct xmp_module *);
|
||||
void libxmp_decode_protracker_event (struct xmp_event *, uint8 *);
|
||||
void libxmp_decode_noisetracker_event(struct xmp_event *, uint8 *);
|
||||
void libxmp_disable_continue_fx (struct xmp_event *);
|
||||
int libxmp_check_filename_case (char *, char *, char *, int);
|
||||
void libxmp_get_instrument_path (struct module_data *, char *, int);
|
||||
void libxmp_set_type (struct module_data *, char *, ...);
|
||||
int libxmp_load_sample (struct module_data *, HIO_HANDLE *, int,
|
||||
struct xmp_sample *, void *);
|
||||
|
||||
extern uint8 libxmp_ord_xlat[];
|
||||
extern const int libxmp_arch_vol_table[];
|
||||
|
||||
#define MAGIC4(a,b,c,d) \
|
||||
(((uint32)(a)<<24)|((uint32)(b)<<16)|((uint32)(c)<<8)|(d))
|
||||
|
||||
#define LOAD_INIT()
|
||||
|
||||
#define MODULE_INFO() do { \
|
||||
D_(D_WARN "Module title: \"%s\"", m->mod.name); \
|
||||
D_(D_WARN "Module type: %s", m->mod.type); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
55
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/mod.h
vendored
Normal file
55
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/mod.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
struct mod_instrument {
|
||||
uint8 name[22]; /* Instrument name */
|
||||
uint16 size; /* Sample length in 16-bit words */
|
||||
int8 finetune; /* Finetune (signed nibble) */
|
||||
int8 volume; /* Linear playback volume */
|
||||
uint16 loop_start; /* Loop start in 16-bit words */
|
||||
uint16 loop_size; /* Loop length in 16-bit words */
|
||||
};
|
||||
|
||||
struct mod_header {
|
||||
uint8 name[20];
|
||||
struct mod_instrument ins[31];
|
||||
uint8 len;
|
||||
uint8 restart; /* Number of patterns in Soundtracker,
|
||||
* Restart in Noisetracker/Startrekker,
|
||||
* 0x7F in Protracker
|
||||
*/
|
||||
uint8 order[128];
|
||||
uint8 magic[4];
|
||||
};
|
||||
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
/* Soundtracker 15-instrument module header */
|
||||
|
||||
struct st_header {
|
||||
uint8 name[20];
|
||||
struct mod_instrument ins[15];
|
||||
uint8 len;
|
||||
uint8 restart;
|
||||
uint8 order[128];
|
||||
};
|
||||
#endif
|
233
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/mod_load.c
vendored
Normal file
233
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/mod_load.c
vendored
Normal file
|
@ -0,0 +1,233 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This loader recognizes the following variants of the Protracker
|
||||
* module format:
|
||||
*
|
||||
* - Protracker M.K.
|
||||
* - Fasttracker ?CHN and ??CH
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include "loader.h"
|
||||
#include "mod.h"
|
||||
|
||||
|
||||
static int mod_test (HIO_HANDLE *, char *, const int);
|
||||
static int mod_load (struct module_data *, HIO_HANDLE *, const int);
|
||||
|
||||
const struct format_loader libxmp_loader_mod = {
|
||||
"Protracker",
|
||||
mod_test,
|
||||
mod_load
|
||||
};
|
||||
|
||||
static int mod_test(HIO_HANDLE *f, char *t, const int start)
|
||||
{
|
||||
int i;
|
||||
char buf[4];
|
||||
|
||||
hio_seek(f, start + 1080, SEEK_SET);
|
||||
if (hio_read(buf, 1, 4, f) < 4)
|
||||
return -1;
|
||||
|
||||
if (!strncmp(buf + 2, "CH", 2) && isdigit((int)buf[0]) && isdigit((int)buf[1])) {
|
||||
i = (buf[0] - '0') * 10 + buf[1] - '0';
|
||||
if (i > 0 && i <= 32) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(buf + 1, "CHN", 3) && isdigit((int)*buf)) {
|
||||
if (*buf >= '0' && *buf <='9') {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(buf, "M.K.", 4))
|
||||
return -1;
|
||||
|
||||
found:
|
||||
hio_seek(f, start + 0, SEEK_SET);
|
||||
libxmp_read_title(f, t, 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
|
||||
{
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i, j;
|
||||
struct xmp_event *event;
|
||||
struct mod_header mh;
|
||||
uint8 mod_event[4];
|
||||
char magic[8];
|
||||
int ptkloop = 0; /* Protracker loop */
|
||||
|
||||
LOAD_INIT();
|
||||
|
||||
mod->ins = 31;
|
||||
mod->smp = mod->ins;
|
||||
mod->chn = 0;
|
||||
|
||||
m->quirk |= QUIRK_PROTRACK;
|
||||
m->period_type = PERIOD_MODRNG;
|
||||
|
||||
hio_read(&mh.name, 20, 1, f);
|
||||
for (i = 0; i < 31; i++) {
|
||||
hio_read(&mh.ins[i].name, 22, 1, f); /* Instrument name */
|
||||
mh.ins[i].size = hio_read16b(f); /* Length in 16-bit words */
|
||||
mh.ins[i].finetune = hio_read8(f); /* Finetune (signed nibble) */
|
||||
mh.ins[i].volume = hio_read8(f); /* Linear playback volume */
|
||||
mh.ins[i].loop_start = hio_read16b(f); /* Loop start in 16-bit words */
|
||||
mh.ins[i].loop_size = hio_read16b(f); /* Loop size in 16-bit words */
|
||||
}
|
||||
mh.len = hio_read8(f);
|
||||
mh.restart = hio_read8(f);
|
||||
hio_read(&mh.order, 128, 1, f);
|
||||
memset(magic, 0, 8);
|
||||
hio_read(magic, 4, 1, f);
|
||||
|
||||
if (!memcmp(magic, "M.K.", 4)) {
|
||||
mod->chn = 4;
|
||||
} else if (!strncmp(magic + 2, "CH", 2) &&
|
||||
isdigit((int)magic[0]) && isdigit((int)magic[1])) {
|
||||
mod->chn = (*magic - '0') * 10 + magic[1] - '0';
|
||||
} else if (!strncmp(magic + 1, "CHN", 3) && isdigit((int)*magic)) {
|
||||
mod->chn = *magic - '0';
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(mod->name, (char *)mh.name, 20);
|
||||
|
||||
mod->len = mh.len;
|
||||
/* mod->rst = mh.restart; */
|
||||
|
||||
if (mod->rst >= mod->len)
|
||||
mod->rst = 0;
|
||||
memcpy(mod->xxo, mh.order, 128);
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
/* This fixes dragnet.mod (garbage in the order list) */
|
||||
if (mod->xxo[i] > 0x7f)
|
||||
break;
|
||||
if (mod->xxo[i] > mod->pat)
|
||||
mod->pat = mod->xxo[i];
|
||||
}
|
||||
mod->pat++;
|
||||
|
||||
if (libxmp_init_instrument(m) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
struct xmp_instrument *xxi;
|
||||
struct xmp_subinstrument *sub;
|
||||
struct xmp_sample *xxs;
|
||||
|
||||
if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
|
||||
return -1;
|
||||
|
||||
xxi = &mod->xxi[i];
|
||||
sub = &xxi->sub[0];
|
||||
xxs = &mod->xxs[i];
|
||||
|
||||
xxs->len = 2 * mh.ins[i].size;
|
||||
xxs->lps = 2 * mh.ins[i].loop_start;
|
||||
xxs->lpe = xxs->lps + 2 * mh.ins[i].loop_size;
|
||||
if (xxs->lpe > xxs->len) {
|
||||
xxs->lpe = xxs->len;
|
||||
}
|
||||
xxs->flg = (mh.ins[i].loop_size > 1 && xxs->lpe >= 4) ?
|
||||
XMP_SAMPLE_LOOP : 0;
|
||||
sub->fin = (int8)(mh.ins[i].finetune << 4);
|
||||
sub->vol = mh.ins[i].volume;
|
||||
sub->pan = 0x80;
|
||||
sub->sid = i;
|
||||
libxmp_instrument_name(mod, i, mh.ins[i].name, 22);
|
||||
|
||||
if (xxs->len > 0) {
|
||||
xxi->nsm = 1;
|
||||
}
|
||||
}
|
||||
|
||||
mod->trk = mod->chn * mod->pat;
|
||||
|
||||
libxmp_set_type(m, mod->chn == 4 ? "Protracker" : "Fasttracker");
|
||||
|
||||
MODULE_INFO();
|
||||
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d %c\n",
|
||||
i, mod->xxi[i].name,
|
||||
mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
|
||||
(mh.ins[i].loop_size > 1 && mod->xxs[i].lpe > 8) ?
|
||||
'L' : ' ', mod->xxi[i].sub[0].vol,
|
||||
mod->xxi[i].sub[0].fin >> 4,
|
||||
ptkloop && mod->xxs[i].lps == 0 && mh.ins[i].loop_size > 1 &&
|
||||
mod->xxs[i].len > mod->xxs[i].lpe ? '!' : ' ');
|
||||
}
|
||||
|
||||
if (libxmp_init_pattern(mod) < 0)
|
||||
return -1;
|
||||
|
||||
/* Load and convert patterns */
|
||||
D_(D_INFO "Stored patterns: %d", mod->pat);
|
||||
|
||||
for (i = 0; i < mod->pat; i++) {
|
||||
if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
|
||||
return -1;
|
||||
|
||||
for (j = 0; j < (64 * mod->chn); j++) {
|
||||
event = &EVENT (i, j % mod->chn, j / mod->chn);
|
||||
hio_read (mod_event, 1, 4, f);
|
||||
libxmp_decode_protracker_event(event, mod_event);
|
||||
}
|
||||
}
|
||||
|
||||
/* Load samples */
|
||||
|
||||
D_(D_INFO "Stored samples: %d", mod->smp);
|
||||
|
||||
for (i = 0; i < mod->smp; i++) {
|
||||
int flags;
|
||||
|
||||
if (!mod->xxs[i].len)
|
||||
continue;
|
||||
|
||||
flags = ptkloop ? SAMPLE_FLAG_FULLREP : 0;
|
||||
|
||||
if (libxmp_load_sample(m, f, flags, &mod->xxs[i], NULL) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mod->chn > 4) {
|
||||
m->quirk &= ~QUIRK_PROTRACK;
|
||||
m->quirk |= QUIRKS_FT2 | QUIRK_FTMOD;
|
||||
m->read_event_type = READ_EVENT_FT2;
|
||||
m->period_type = PERIOD_AMIGA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
116
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/s3m.h
vendored
Normal file
116
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/s3m.h
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* S3M packed pattern macros */
|
||||
#define S3M_EOR 0 /* End of row */
|
||||
#define S3M_CH_MASK 0x1f /* Channel */
|
||||
#define S3M_NI_FOLLOW 0x20 /* Note and instrument follow */
|
||||
#define S3M_VOL_FOLLOWS 0x40 /* Volume follows */
|
||||
#define S3M_FX_FOLLOWS 0x80 /* Effect and parameter follow */
|
||||
|
||||
/* S3M channel info macros */
|
||||
#define S3M_CH_ON 0x80 /* Psi says it's bit 8, I'll assume bit 7 */
|
||||
#define S3M_CH_OFF 0xff
|
||||
#define S3M_CH_PAN 0x7f /* Left/Right */
|
||||
|
||||
/* S3M channel pan macros */
|
||||
#define S3M_PAN_SET 0x20
|
||||
#define S3M_PAN_MASK 0x0f
|
||||
|
||||
/* S3M flags */
|
||||
#define S3M_ST2_VIB 0x01 /* Not recognized */
|
||||
#define S3M_ST2_TEMPO 0x02 /* Not recognized */
|
||||
#define S3M_AMIGA_SLIDE 0x04 /* Not recognized */
|
||||
#define S3M_VOL_OPT 0x08 /* Not recognized */
|
||||
#define S3M_AMIGA_RANGE 0x10
|
||||
#define S3M_SB_FILTER 0x20 /* Not recognized */
|
||||
#define S3M_ST300_VOLS 0x40
|
||||
#define S3M_CUSTOM_DATA 0x80 /* Not recognized */
|
||||
|
||||
/* S3M Adlib instrument types */
|
||||
#define S3M_INST_SAMPLE 0x01
|
||||
#define S3M_INST_AMEL 0x02
|
||||
#define S3M_INST_ABD 0x03
|
||||
#define S3M_INST_ASNARE 0x04
|
||||
#define S3M_INST_ATOM 0x05
|
||||
#define S3M_INST_ACYM 0x06
|
||||
#define S3M_INST_AHIHAT 0x07
|
||||
|
||||
struct s3m_file_header {
|
||||
uint8 name[28]; /* Song name */
|
||||
uint8 doseof; /* 0x1a */
|
||||
uint8 type; /* File type */
|
||||
uint8 rsvd1[2]; /* Reserved */
|
||||
uint16 ordnum; /* Number of orders (must be even) */
|
||||
uint16 insnum; /* Number of instruments */
|
||||
uint16 patnum; /* Number of patterns */
|
||||
uint16 flags; /* Flags */
|
||||
uint16 version; /* Tracker ID and version */
|
||||
uint16 ffi; /* File format information */
|
||||
uint32 magic; /* 'SCRM' */
|
||||
uint8 gv; /* Global volume */
|
||||
uint8 is; /* Initial speed */
|
||||
uint8 it; /* Initial tempo */
|
||||
uint8 mv; /* Master volume */
|
||||
uint8 uc; /* Ultra click removal */
|
||||
uint8 dp; /* Default pan positions if 0xfc */
|
||||
uint8 rsvd2[8]; /* Reserved */
|
||||
uint16 special; /* Ptr to special custom data */
|
||||
uint8 chset[32]; /* Channel settings */
|
||||
};
|
||||
|
||||
struct s3m_instrument_header {
|
||||
uint8 dosname[13]; /* DOS file name */
|
||||
uint16 memseg; /* Pointer to sample data */
|
||||
uint32 length; /* Length */
|
||||
uint32 loopbeg; /* Loop begin */
|
||||
uint32 loopend; /* Loop end */
|
||||
uint8 vol; /* Volume */
|
||||
uint8 rsvd1; /* Reserved */
|
||||
uint8 pack; /* Packing type (not used) */
|
||||
uint8 flags; /* Loop/stereo/16bit samples flags */
|
||||
uint16 c2spd; /* C 4 speed */
|
||||
uint16 rsvd2; /* Reserved */
|
||||
uint8 rsvd3[4]; /* Reserved */
|
||||
uint16 int_gp; /* Internal - GUS pointer */
|
||||
uint16 int_512; /* Internal - SB pointer */
|
||||
uint32 int_last; /* Internal - SB index */
|
||||
uint8 name[28]; /* Instrument name */
|
||||
uint32 magic; /* 'SCRS' */
|
||||
};
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
struct s3m_adlib_header {
|
||||
uint8 dosname[12]; /* DOS file name */
|
||||
uint8 rsvd1[3]; /* 0x00 0x00 0x00 */
|
||||
uint8 reg[12]; /* Adlib registers */
|
||||
uint8 vol;
|
||||
uint8 dsk;
|
||||
uint8 rsvd2[2];
|
||||
uint16 c2spd; /* C 4 speed */
|
||||
uint16 rsvd3; /* Reserved */
|
||||
uint8 rsvd4[12]; /* Reserved */
|
||||
uint8 name[28]; /* Instrument name */
|
||||
uint32 magic; /* 'SCRI' */
|
||||
};
|
||||
#endif
|
||||
|
659
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/s3m_load.c
vendored
Normal file
659
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/s3m_load.c
vendored
Normal file
|
@ -0,0 +1,659 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Tue, 30 Jun 1998 20:23:11 +0200
|
||||
* Reported by John v/d Kamp <blade_@dds.nl>:
|
||||
* I have this song from Purple Motion called wcharts.s3m, the global
|
||||
* volume was set to 0, creating a devide by 0 error in xmp. There should
|
||||
* be an extra test if it's 0 or not.
|
||||
*
|
||||
* Claudio's fix: global volume ignored
|
||||
*/
|
||||
|
||||
/*
|
||||
* Sat, 29 Aug 1998 18:50:43 -0500 (CDT)
|
||||
* Reported by Joel Jordan <scriber@usa.net>:
|
||||
* S3M files support tempos outside the ranges defined by xmp (that is,
|
||||
* the MOD/XM tempo ranges). S3M's can have tempos from 0 to 255 and speeds
|
||||
* from 0 to 255 as well, since these are handled with separate effects
|
||||
* unlike the MOD format. This becomes an issue in such songs as Skaven's
|
||||
* "Catch that Goblin", which uses speeds above 0x1f.
|
||||
*
|
||||
* Claudio's fix: FX_S3M_SPEED added. S3M supports speeds from 0 to 255 and
|
||||
* tempos from 32 to 255 (S3M speed == xmp tempo, S3M tempo == xmp BPM).
|
||||
*/
|
||||
|
||||
/* Wed, 21 Oct 1998 15:03:44 -0500 Geoff Reedy <vader21@imsa.edu>
|
||||
* It appears that xmp has issues loading/playing a specific instrument
|
||||
* used in LUCCA.S3M.
|
||||
* (Fixed by Hipolito in xmp-2.0.0dev34)
|
||||
*/
|
||||
|
||||
/*
|
||||
* From http://code.pui.ch/2007/02/18/turn-demoscene-modules-into-mp3s/
|
||||
* The only flaw I noticed [in xmp] is a problem with portamento in Purple
|
||||
* Motion's second reality soundtrack (1:06-1:17)
|
||||
*
|
||||
* Claudio's note: that's a dissonant beating between channels 6 and 7
|
||||
* starting at pos12, caused by pitchbending effect F25.
|
||||
*/
|
||||
|
||||
/*
|
||||
* From: Ralf Hoffmann <ralf@boomerangsworld.de>
|
||||
* Date: Wed, 26 Sep 2007 17:12:41 +0200
|
||||
* ftp://ftp.scenesp.org/pub/compilations/modplanet/normal/bonuscd/artists/
|
||||
* Iq/return%20of%20litmus.s3m doesn't start playing, just uses 100% cpu,
|
||||
* the number of patterns is unusually high
|
||||
*
|
||||
* Claudio's fix: this module seems to be a bad conversion, bad rip or
|
||||
* simply corrupted since it has many instances of 0x87 instead of 0x00
|
||||
* in the module and instrument headers. I'm adding a simple workaround
|
||||
* to be able to load/play the module as is, see the fix87() macro below.
|
||||
*/
|
||||
|
||||
#include "loader.h"
|
||||
#include "s3m.h"
|
||||
#include "../period.h"
|
||||
|
||||
#define MAGIC_SCRM MAGIC4('S','C','R','M')
|
||||
#define MAGIC_SCRI MAGIC4('S','C','R','I')
|
||||
#define MAGIC_SCRS MAGIC4('S','C','R','S')
|
||||
|
||||
static int s3m_test(HIO_HANDLE *, char *, const int);
|
||||
static int s3m_load(struct module_data *, HIO_HANDLE *, const int);
|
||||
|
||||
const struct format_loader libxmp_loader_s3m = {
|
||||
"Scream Tracker 3",
|
||||
s3m_test,
|
||||
s3m_load
|
||||
};
|
||||
|
||||
static int s3m_test(HIO_HANDLE *f, char *t, const int start)
|
||||
{
|
||||
hio_seek(f, start + 44, SEEK_SET);
|
||||
if (hio_read32b(f) != MAGIC_SCRM)
|
||||
return -1;
|
||||
|
||||
hio_seek(f, start + 29, SEEK_SET);
|
||||
if (hio_read8(f) != 0x10)
|
||||
return -1;
|
||||
|
||||
hio_seek(f, start + 0, SEEK_SET);
|
||||
libxmp_read_title(f, t, 28);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NONE 0xff
|
||||
#define FX_S3M_EXTENDED 0xfe
|
||||
|
||||
#define fix87(x) do { \
|
||||
int i; for (i = 0; i < sizeof(x); i++) { \
|
||||
if (*((uint8 *)&x + i) == 0x87) *((uint8 *)&x + i) = 0; } \
|
||||
} while (0)
|
||||
|
||||
/* Effect conversion table */
|
||||
static const uint8 fx[] = {
|
||||
NONE,
|
||||
FX_S3M_SPEED, /* Axx Set speed to xx (the default is 06) */
|
||||
FX_JUMP, /* Bxx Jump to order xx (hexadecimal) */
|
||||
FX_BREAK, /* Cxx Break pattern to row xx (decimal) */
|
||||
FX_VOLSLIDE, /* Dxy Volume slide down by y/up by x */
|
||||
FX_PORTA_DN, /* Exx Slide down by xx */
|
||||
FX_PORTA_UP, /* Fxx Slide up by xx */
|
||||
FX_TONEPORTA, /* Gxx Tone portamento with speed xx */
|
||||
FX_VIBRATO, /* Hxy Vibrato with speed x and depth y */
|
||||
FX_TREMOR, /* Ixy Tremor with ontime x and offtime y */
|
||||
FX_S3M_ARPEGGIO, /* Jxy Arpeggio with halfnote additions */
|
||||
FX_VIBRA_VSLIDE, /* Kxy Dual command: H00 and Dxy */
|
||||
FX_TONE_VSLIDE, /* Lxy Dual command: G00 and Dxy */
|
||||
NONE,
|
||||
NONE,
|
||||
FX_OFFSET, /* Oxy Set sample offset */
|
||||
NONE,
|
||||
FX_MULTI_RETRIG, /* Qxy Retrig (+volumeslide) note */
|
||||
FX_TREMOLO, /* Rxy Tremolo with speed x and depth y */
|
||||
FX_S3M_EXTENDED, /* Sxx (misc effects) */
|
||||
FX_S3M_BPM, /* Txx Tempo = xx (hex) */
|
||||
FX_FINE_VIBRATO, /* Uxx Fine vibrato */
|
||||
FX_GLOBALVOL, /* Vxx Set global volume */
|
||||
NONE,
|
||||
FX_SETPAN, /* Xxx Set pan */
|
||||
NONE,
|
||||
NONE
|
||||
};
|
||||
|
||||
/* Effect translation */
|
||||
static void xlat_fx(int c, struct xmp_event *e)
|
||||
{
|
||||
uint8 h = MSN(e->fxp), l = LSN(e->fxp);
|
||||
|
||||
if (e->fxt > 26) {
|
||||
D_(D_WARN "invalid effect %02x", e->fxt);
|
||||
e->fxt = e->fxp = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e->fxt = fx[e->fxt]) {
|
||||
case FX_S3M_BPM:
|
||||
if (e->fxp < 0x20) {
|
||||
e->fxp = e->fxt = 0;
|
||||
}
|
||||
break;
|
||||
case FX_S3M_EXTENDED: /* Extended effects */
|
||||
e->fxt = FX_EXTENDED;
|
||||
switch (h) {
|
||||
case 0x1: /* Glissando */
|
||||
e->fxp = LSN(e->fxp) | (EX_GLISS << 4);
|
||||
break;
|
||||
case 0x2: /* Finetune */
|
||||
e->fxp =
|
||||
((LSN(e->fxp) - 8) & 0x0f) | (EX_FINETUNE << 4);
|
||||
break;
|
||||
case 0x3: /* Vibrato wave */
|
||||
e->fxp = LSN(e->fxp) | (EX_VIBRATO_WF << 4);
|
||||
break;
|
||||
case 0x4: /* Tremolo wave */
|
||||
e->fxp = LSN(e->fxp) | (EX_TREMOLO_WF << 4);
|
||||
break;
|
||||
case 0x5:
|
||||
case 0x6:
|
||||
case 0x7:
|
||||
case 0x9:
|
||||
case 0xa: /* Ignore */
|
||||
e->fxt = e->fxp = 0;
|
||||
break;
|
||||
case 0x8: /* Set pan */
|
||||
e->fxt = FX_SETPAN;
|
||||
e->fxp = l << 4;
|
||||
break;
|
||||
case 0xb: /* Pattern loop */
|
||||
e->fxp = LSN(e->fxp) | (EX_PATTERN_LOOP << 4);
|
||||
break;
|
||||
case 0xc:
|
||||
if (!l)
|
||||
e->fxt = e->fxp = 0;
|
||||
}
|
||||
break;
|
||||
case FX_SETPAN:
|
||||
/* Saga Musix says: "The X effect in S3M files is not
|
||||
* exclusive to IT and clones. You will find tons of S3Ms made
|
||||
* with ST3 itself using this effect (and relying on an
|
||||
* external player being used). X in S3M also behaves
|
||||
* differently than in IT, which your code does not seem to
|
||||
* handle: X00 - X80 is left... right, XA4 is surround (like
|
||||
* S91 in IT), other values are not supposed to do anything.
|
||||
*/
|
||||
if (e->fxp == 0xa4) {
|
||||
// surround
|
||||
e->fxt = FX_SURROUND;
|
||||
e->fxp = 1;
|
||||
} else {
|
||||
int pan = ((int)e->fxp) << 1;
|
||||
if (pan > 0xff) {
|
||||
pan = 0xff;
|
||||
}
|
||||
e->fxp = pan;
|
||||
}
|
||||
break;
|
||||
case NONE: /* No effect */
|
||||
e->fxt = e->fxp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int s3m_load(struct module_data *m, HIO_HANDLE * f, const int start)
|
||||
{
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int c, r, i;
|
||||
struct xmp_event *event = 0, dummy;
|
||||
struct s3m_file_header sfh;
|
||||
struct s3m_instrument_header sih;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
struct s3m_adlib_header sah;
|
||||
char tracker_name[40];
|
||||
int quirk87 = 0;
|
||||
#endif
|
||||
int pat_len;
|
||||
uint8 n, b, x8;
|
||||
uint16 *pp_ins; /* Parapointers to instruments */
|
||||
uint16 *pp_pat; /* Parapointers to patterns */
|
||||
int ret;
|
||||
|
||||
LOAD_INIT();
|
||||
|
||||
hio_read(&sfh.name, 28, 1, f); /* Song name */
|
||||
hio_read8(f); /* 0x1a */
|
||||
sfh.type = hio_read8(f); /* File type */
|
||||
hio_read16l(f); /* Reserved */
|
||||
sfh.ordnum = hio_read16l(f); /* Number of orders (must be even) */
|
||||
sfh.insnum = hio_read16l(f); /* Number of instruments */
|
||||
sfh.patnum = hio_read16l(f); /* Number of patterns */
|
||||
sfh.flags = hio_read16l(f); /* Flags */
|
||||
sfh.version = hio_read16l(f); /* Tracker ID and version */
|
||||
sfh.ffi = hio_read16l(f); /* File format information */
|
||||
|
||||
/* Sanity check */
|
||||
if (hio_error(f)) {
|
||||
goto err;
|
||||
}
|
||||
if (sfh.ffi != 1 && sfh.ffi != 2) {
|
||||
goto err;
|
||||
}
|
||||
if (sfh.ordnum > 255 || sfh.insnum > 255 || sfh.patnum > 255) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
sfh.magic = hio_read32b(f); /* 'SCRM' */
|
||||
sfh.gv = hio_read8(f); /* Global volume */
|
||||
sfh.is = hio_read8(f); /* Initial speed */
|
||||
sfh.it = hio_read8(f); /* Initial tempo */
|
||||
sfh.mv = hio_read8(f); /* Master volume */
|
||||
sfh.uc = hio_read8(f); /* Ultra click removal */
|
||||
sfh.dp = hio_read8(f); /* Default pan positions if 0xfc */
|
||||
hio_read32l(f); /* Reserved */
|
||||
hio_read32l(f); /* Reserved */
|
||||
sfh.special = hio_read16l(f); /* Ptr to special custom data */
|
||||
hio_read(sfh.chset, 32, 1, f); /* Channel settings */
|
||||
|
||||
if (hio_error(f)) {
|
||||
goto err;
|
||||
}
|
||||
#if 0
|
||||
if (sfh.magic != MAGIC_SCRM)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
/* S3M anomaly in return_of_litmus.s3m */
|
||||
if (sfh.version == 0x1301 && sfh.name[27] == 0x87)
|
||||
quirk87 = 1;
|
||||
|
||||
if (quirk87) {
|
||||
fix87(sfh.name);
|
||||
fix87(sfh.patnum);
|
||||
fix87(sfh.flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
libxmp_copy_adjust(mod->name, sfh.name, 28);
|
||||
|
||||
pp_ins = calloc(2, sfh.insnum);
|
||||
if (pp_ins == NULL)
|
||||
goto err;
|
||||
|
||||
pp_pat = calloc(2, sfh.patnum);
|
||||
if (pp_pat == NULL)
|
||||
goto err2;
|
||||
|
||||
if (sfh.flags & S3M_AMIGA_RANGE)
|
||||
m->period_type = PERIOD_MODRNG;
|
||||
if (sfh.flags & S3M_ST300_VOLS)
|
||||
m->quirk |= QUIRK_VSALL;
|
||||
/* m->volbase = 4096 / sfh.gv; */
|
||||
mod->spd = sfh.is;
|
||||
mod->bpm = sfh.it;
|
||||
mod->chn = 0;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (sfh.chset[i] == S3M_CH_OFF)
|
||||
continue;
|
||||
|
||||
mod->chn = i + 1;
|
||||
|
||||
if (sfh.mv & 0x80) { /* stereo */
|
||||
int x = sfh.chset[i] & S3M_CH_PAN;
|
||||
mod->xxc[i].pan = (x & 0x0f) < 8 ? 0x30 : 0xc0;
|
||||
} else {
|
||||
mod->xxc[i].pan = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
if (sfh.ordnum <= XMP_MAX_MOD_LENGTH) {
|
||||
mod->len = sfh.ordnum;
|
||||
hio_read(mod->xxo, 1, mod->len, f);
|
||||
} else {
|
||||
mod->len = XMP_MAX_MOD_LENGTH;
|
||||
hio_read(mod->xxo, 1, mod->len, f);
|
||||
hio_seek(f, sfh.ordnum - XMP_MAX_MOD_LENGTH, SEEK_CUR);
|
||||
}
|
||||
if (hio_error(f)) {
|
||||
goto err3;
|
||||
}
|
||||
|
||||
/* Don't trust sfh.patnum */
|
||||
mod->pat = -1;
|
||||
for (i = 0; i < mod->len; ++i) {
|
||||
if (mod->xxo[i] < 0xfe && mod->xxo[i] > mod->pat) {
|
||||
mod->pat = mod->xxo[i];
|
||||
}
|
||||
}
|
||||
mod->pat++;
|
||||
if (mod->pat > sfh.patnum)
|
||||
mod->pat = sfh.patnum;
|
||||
if (mod->pat == 0)
|
||||
goto err3;
|
||||
|
||||
mod->trk = mod->pat * mod->chn;
|
||||
/* Load and convert header */
|
||||
mod->ins = sfh.insnum;
|
||||
mod->smp = mod->ins;
|
||||
|
||||
for (i = 0; i < sfh.insnum; i++)
|
||||
pp_ins[i] = hio_read16l(f);
|
||||
|
||||
for (i = 0; i < sfh.patnum; i++)
|
||||
pp_pat[i] = hio_read16l(f);
|
||||
|
||||
/* Default pan positions */
|
||||
|
||||
for (i = 0, sfh.dp -= 0xfc; !sfh.dp /* && n */ && (i < 32); i++) {
|
||||
uint8 x = hio_read8(f);
|
||||
if (x & S3M_PAN_SET) {
|
||||
mod->xxc[i].pan = (x << 4) & 0xff;
|
||||
} else {
|
||||
mod->xxc[i].pan =
|
||||
sfh.mv % 0x80 ? 0x30 + 0xa0 * (i & 1) : 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
|
||||
if (sfh.version == 0x1300) {
|
||||
m->quirk |= QUIRK_VSALL;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
switch (sfh.version >> 12) {
|
||||
case 1:
|
||||
snprintf(tracker_name, 40, "Scream Tracker %d.%02x",
|
||||
(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
|
||||
m->quirk |= QUIRK_ST3BUGS;
|
||||
break;
|
||||
case 2:
|
||||
snprintf(tracker_name, 40, "Imago Orpheus %d.%02x",
|
||||
(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
|
||||
break;
|
||||
case 3:
|
||||
if (sfh.version == 0x3216) {
|
||||
strcpy(tracker_name, "Impulse Tracker 2.14v3");
|
||||
} else if (sfh.version == 0x3217) {
|
||||
strcpy(tracker_name, "Impulse Tracker 2.14v5");
|
||||
} else {
|
||||
snprintf(tracker_name, 40, "Impulse Tracker %d.%02x",
|
||||
(sfh.version & 0x0f00) >> 8,
|
||||
sfh.version & 0xff);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
snprintf(tracker_name, 40, "OpenMPT %d.%02x",
|
||||
(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
|
||||
m->quirk |= QUIRK_ST3BUGS;
|
||||
break;
|
||||
case 4:
|
||||
if (sfh.version != 0x4100) {
|
||||
snprintf(tracker_name, 40, "Schism Tracker %d.%02x",
|
||||
(sfh.version & 0x0f00) >> 8,
|
||||
sfh.version & 0xff);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case 6:
|
||||
snprintf(tracker_name, 40, "BeRoTracker %d.%02x",
|
||||
(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
|
||||
break;
|
||||
default:
|
||||
snprintf(tracker_name, 40, "unknown (%04x)", sfh.version);
|
||||
}
|
||||
|
||||
libxmp_set_type(m, "%s S3M", tracker_name);
|
||||
#else
|
||||
libxmp_set_type(m, "Scream Tracker 3");
|
||||
m->quirk |= QUIRK_ST3BUGS;
|
||||
#endif
|
||||
|
||||
MODULE_INFO();
|
||||
|
||||
if (libxmp_init_pattern(mod) < 0)
|
||||
goto err3;
|
||||
|
||||
/* Read patterns */
|
||||
|
||||
D_(D_INFO "Stored patterns: %d", mod->pat);
|
||||
|
||||
for (i = 0; i < mod->pat; i++) {
|
||||
if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
|
||||
goto err3;
|
||||
|
||||
if (pp_pat[i] == 0)
|
||||
continue;
|
||||
|
||||
hio_seek(f, start + pp_pat[i] * 16, SEEK_SET);
|
||||
r = 0;
|
||||
pat_len = hio_read16l(f) - 2;
|
||||
|
||||
while (pat_len >= 0 && r < mod->xxp[i]->rows) {
|
||||
b = hio_read8(f);
|
||||
|
||||
if (hio_error(f)) {
|
||||
goto err3;
|
||||
}
|
||||
|
||||
if (b == S3M_EOR) {
|
||||
r++;
|
||||
continue;
|
||||
}
|
||||
|
||||
c = b & S3M_CH_MASK;
|
||||
event = c >= mod->chn ? &dummy : &EVENT(i, c, r);
|
||||
|
||||
if (b & S3M_NI_FOLLOW) {
|
||||
switch (n = hio_read8(f)) {
|
||||
case 255:
|
||||
n = 0;
|
||||
break; /* Empty note */
|
||||
case 254:
|
||||
n = XMP_KEY_OFF;
|
||||
break; /* Key off */
|
||||
default:
|
||||
n = 13 + 12 * MSN(n) + LSN(n);
|
||||
}
|
||||
event->note = n;
|
||||
event->ins = hio_read8(f);
|
||||
pat_len -= 2;
|
||||
}
|
||||
|
||||
if (b & S3M_VOL_FOLLOWS) {
|
||||
event->vol = hio_read8(f) + 1;
|
||||
pat_len--;
|
||||
}
|
||||
|
||||
if (b & S3M_FX_FOLLOWS) {
|
||||
event->fxt = hio_read8(f);
|
||||
event->fxp = hio_read8(f);
|
||||
xlat_fx(c, event);
|
||||
|
||||
pat_len -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D_(D_INFO "Stereo enabled: %s", sfh.mv & 0x80 ? "yes" : "no");
|
||||
D_(D_INFO "Pan settings: %s", sfh.dp ? "no" : "yes");
|
||||
|
||||
if (libxmp_init_instrument(m) < 0)
|
||||
goto err3;
|
||||
|
||||
/* Read and convert instruments and samples */
|
||||
|
||||
D_(D_INFO "Instruments: %d", mod->ins);
|
||||
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
struct xmp_instrument *xxi = &mod->xxi[i];
|
||||
struct xmp_sample *xxs = &mod->xxs[i];
|
||||
struct xmp_subinstrument *sub;
|
||||
|
||||
xxi->sub = calloc(sizeof(struct xmp_subinstrument), 1);
|
||||
if (xxi->sub == NULL) {
|
||||
goto err3;
|
||||
}
|
||||
|
||||
sub = &xxi->sub[0];
|
||||
|
||||
hio_seek(f, start + pp_ins[i] * 16, SEEK_SET);
|
||||
x8 = hio_read8(f);
|
||||
sub->pan = 0x80;
|
||||
sub->sid = i;
|
||||
|
||||
if (x8 >= 2) {
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
/* OPL2 FM instrument */
|
||||
|
||||
hio_read(&sah.dosname, 12, 1, f); /* DOS file name */
|
||||
hio_read(&sah.rsvd1, 3, 1, f); /* 0x00 0x00 0x00 */
|
||||
hio_read(&sah.reg, 12, 1, f); /* Adlib registers */
|
||||
sah.vol = hio_read8(f);
|
||||
sah.dsk = hio_read8(f);
|
||||
hio_read16l(f);
|
||||
sah.c2spd = hio_read16l(f); /* C 4 speed */
|
||||
hio_read16l(f);
|
||||
hio_read(&sah.rsvd4, 12, 1, f); /* Reserved */
|
||||
hio_read(&sah.name, 28, 1, f); /* Instrument name */
|
||||
sah.magic = hio_read32b(f); /* 'SCRI' */
|
||||
|
||||
if (sah.magic != MAGIC_SCRI) {
|
||||
D_(D_CRIT "error: FM instrument magic");
|
||||
goto err3;
|
||||
}
|
||||
sah.magic = 0;
|
||||
|
||||
libxmp_instrument_name(mod, i, sah.name, 28);
|
||||
|
||||
xxi->nsm = 1;
|
||||
sub->vol = sah.vol;
|
||||
libxmp_c2spd_to_note(sah.c2spd, &sub->xpo, &sub->fin);
|
||||
sub->xpo += 12;
|
||||
ret =
|
||||
libxmp_load_sample(m, f, SAMPLE_FLAG_ADLIB, xxs,
|
||||
(char *)&sah.reg);
|
||||
if (ret < 0)
|
||||
goto err3;
|
||||
|
||||
D_(D_INFO "[%2X] %-28.28s", i, xxi->name);
|
||||
|
||||
continue;
|
||||
#else
|
||||
goto err3;
|
||||
#endif
|
||||
}
|
||||
|
||||
hio_read(&sih.dosname, 13, 1, f); /* DOS file name */
|
||||
sih.memseg = hio_read16l(f); /* Pointer to sample data */
|
||||
sih.length = hio_read32l(f); /* Length */
|
||||
|
||||
#if 0
|
||||
/* ST3 limit */
|
||||
if ((sfh.version >> 12) == 1 && sih.length > 64000)
|
||||
sih.length = 64000;
|
||||
#endif
|
||||
|
||||
if (sih.length > MAX_SAMPLE_SIZE) {
|
||||
goto err3;
|
||||
}
|
||||
|
||||
sih.loopbeg = hio_read32l(f); /* Loop begin */
|
||||
sih.loopend = hio_read32l(f); /* Loop end */
|
||||
sih.vol = hio_read8(f); /* Volume */
|
||||
sih.rsvd1 = hio_read8(f); /* Reserved */
|
||||
sih.pack = hio_read8(f); /* Packing type (not used) */
|
||||
sih.flags = hio_read8(f); /* Loop/stereo/16bit flags */
|
||||
sih.c2spd = hio_read16l(f); /* C 4 speed */
|
||||
sih.rsvd2 = hio_read16l(f); /* Reserved */
|
||||
hio_read(&sih.rsvd3, 4, 1, f); /* Reserved */
|
||||
sih.int_gp = hio_read16l(f); /* Internal - GUS pointer */
|
||||
sih.int_512 = hio_read16l(f); /* Internal - SB pointer */
|
||||
sih.int_last = hio_read32l(f); /* Internal - SB index */
|
||||
hio_read(&sih.name, 28, 1, f); /* Instrument name */
|
||||
sih.magic = hio_read32b(f); /* 'SCRS' */
|
||||
|
||||
if (x8 == 1 && sih.magic != MAGIC_SCRS) {
|
||||
D_(D_CRIT "error: instrument magic");
|
||||
goto err3;
|
||||
}
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (quirk87) {
|
||||
fix87(sih.length);
|
||||
fix87(sih.loopbeg);
|
||||
fix87(sih.loopend);
|
||||
fix87(sih.flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
xxs->len = sih.length;
|
||||
xxi->nsm = sih.length > 0 ? 1 : 0;
|
||||
xxs->lps = sih.loopbeg;
|
||||
xxs->lpe = sih.loopend;
|
||||
|
||||
xxs->flg = sih.flags & 1 ? XMP_SAMPLE_LOOP : 0;
|
||||
|
||||
if (sih.flags & 4) {
|
||||
xxs->flg |= XMP_SAMPLE_16BIT;
|
||||
}
|
||||
|
||||
sub->vol = sih.vol;
|
||||
sih.magic = 0;
|
||||
|
||||
libxmp_instrument_name(mod, i, sih.name, 28);
|
||||
|
||||
D_(D_INFO "[%2X] %-28.28s %04x%c%04x %04x %c V%02x %5d",
|
||||
i, mod->xxi[i].name, mod->xxs[i].len,
|
||||
xxs->flg & XMP_SAMPLE_16BIT ? '+' : ' ',
|
||||
xxs->lps, mod->xxs[i].lpe,
|
||||
xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ', sub->vol, sih.c2spd);
|
||||
|
||||
libxmp_c2spd_to_note(sih.c2spd, &sub->xpo, &sub->fin);
|
||||
|
||||
hio_seek(f, start + 16L * sih.memseg, SEEK_SET);
|
||||
|
||||
ret = libxmp_load_sample(m, f, sfh.ffi == 1 ? 0 : SAMPLE_FLAG_UNS,
|
||||
xxs, NULL);
|
||||
if (ret < 0) {
|
||||
goto err3;
|
||||
}
|
||||
}
|
||||
|
||||
free(pp_pat);
|
||||
free(pp_ins);
|
||||
|
||||
m->quirk |= QUIRKS_ST3 | QUIRK_ARPMEM;
|
||||
m->read_event_type = READ_EVENT_ST3;
|
||||
|
||||
return 0;
|
||||
|
||||
err3:
|
||||
free(pp_pat);
|
||||
err2:
|
||||
free(pp_ins);
|
||||
err:
|
||||
return -1;
|
||||
}
|
416
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/sample.c
vendored
Normal file
416
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/sample.c
vendored
Normal file
|
@ -0,0 +1,416 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../common.h"
|
||||
#include "loader.h"
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
/*
|
||||
* From the Audio File Formats (version 2.5)
|
||||
* Submitted-by: Guido van Rossum <guido@cwi.nl>
|
||||
* Last-modified: 27-Aug-1992
|
||||
*
|
||||
* The Acorn Archimedes uses a variation on U-LAW with the bit order
|
||||
* reversed and the sign bit in bit 0. Being a 'minority' architecture,
|
||||
* Arc owners are quite adept at converting sound/image formats from
|
||||
* other machines, and it is unlikely that you'll ever encounter sound in
|
||||
* one of the Arc's own formats (there are several).
|
||||
*/
|
||||
static const int8 vdic_table[128] = {
|
||||
/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 16 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 24 */ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 32 */ 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
/* 40 */ 2, 2, 2, 2, 3, 3, 3, 3,
|
||||
/* 48 */ 3, 3, 4, 4, 4, 4, 5, 5,
|
||||
/* 56 */ 5, 5, 6, 6, 6, 6, 7, 7,
|
||||
/* 64 */ 7, 8, 8, 9, 9, 10, 10, 11,
|
||||
/* 72 */ 11, 12, 12, 13, 13, 14, 14, 15,
|
||||
/* 80 */ 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
/* 88 */ 23, 24, 25, 26, 27, 28, 29, 30,
|
||||
/* 96 */ 31, 33, 34, 36, 38, 40, 42, 44,
|
||||
/* 104 */ 46, 48, 50, 52, 54, 56, 58, 60,
|
||||
/* 112 */ 62, 65, 68, 72, 77, 80, 84, 91,
|
||||
/* 120 */ 95, 98, 103, 109, 114, 120, 126, 127
|
||||
};
|
||||
|
||||
|
||||
/* Convert 7 bit samples to 8 bit */
|
||||
static void convert_7bit_to_8bit(uint8 *p, int l)
|
||||
{
|
||||
for (; l--; p++) {
|
||||
*p <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert Archimedes VIDC samples to linear */
|
||||
static void convert_vidc_to_linear(uint8 *p, int l)
|
||||
{
|
||||
int i;
|
||||
uint8 x;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
x = p[i];
|
||||
p[i] = vdic_table[x >> 1];
|
||||
if (x & 0x01)
|
||||
p[i] *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void adpcm4_decoder(uint8 *inp, uint8 *outp, char *tab, int len)
|
||||
{
|
||||
char delta = 0;
|
||||
uint8 b0, b1;
|
||||
int i;
|
||||
|
||||
len = (len + 1) / 2;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
b0 = *inp;
|
||||
b1 = *inp++ >> 4;
|
||||
delta += tab[b0 & 0x0f];
|
||||
*outp++ = delta;
|
||||
delta += tab[b1 & 0x0f];
|
||||
*outp++ = delta;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Convert differential to absolute sample data */
|
||||
static void convert_delta(uint8 *p, int l, int r)
|
||||
{
|
||||
uint16 *w = (uint16 *)p;
|
||||
uint16 abs = 0;
|
||||
|
||||
if (r) {
|
||||
for (; l--;) {
|
||||
abs = *w + abs;
|
||||
*w++ = abs;
|
||||
}
|
||||
} else {
|
||||
for (; l--;) {
|
||||
abs = *p + abs;
|
||||
*p++ = (uint8) abs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert signed to unsigned sample data */
|
||||
static void convert_signal(uint8 *p, int l, int r)
|
||||
{
|
||||
uint16 *w = (uint16 *)p;
|
||||
|
||||
if (r) {
|
||||
for (; l--; w++)
|
||||
*w += 0x8000;
|
||||
} else {
|
||||
for (; l--; p++)
|
||||
*p += (char)0x80; /* cast needed by MSVC++ */
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert little-endian 16 bit samples to big-endian */
|
||||
static void convert_endian(uint8 *p, int l)
|
||||
{
|
||||
uint8 b;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
b = p[0];
|
||||
p[0] = p[1];
|
||||
p[1] = b;
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Downmix stereo samples to mono */
|
||||
static void convert_stereo_to_mono(uint8 *p, int l, int r)
|
||||
{
|
||||
int16 *b = (int16 *)p;
|
||||
int i;
|
||||
|
||||
if (r) {
|
||||
l /= 2;
|
||||
for (i = 0; i < l; i++)
|
||||
b[i] = (b[i * 2] + b[i * 2 + 1]) / 2;
|
||||
} else {
|
||||
for (i = 0; i < l; i++)
|
||||
p[i] = (p[i * 2] + p[i * 2 + 1]) / 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void unroll_loop(struct xmp_sample *xxs)
|
||||
{
|
||||
int8 *s8;
|
||||
int16 *s16;
|
||||
int start, loop_size;
|
||||
int i;
|
||||
|
||||
s16 = (int16 *)xxs->data;
|
||||
s8 = (int8 *)xxs->data;
|
||||
|
||||
if (xxs->len > xxs->lpe) {
|
||||
start = xxs->lpe;
|
||||
} else {
|
||||
start = xxs->len;
|
||||
}
|
||||
|
||||
loop_size = xxs->lpe - xxs->lps;
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
s16 += start;
|
||||
for (i = 0; i < loop_size; i++) {
|
||||
*(s16 + i) = *(s16 - i - 1);
|
||||
}
|
||||
} else {
|
||||
s8 += start;
|
||||
for (i = 0; i < loop_size; i++) {
|
||||
*(s8 + i) = *(s8 - i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int libxmp_load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_sample *xxs, void *buffer)
|
||||
{
|
||||
int bytelen, extralen, unroll_extralen, i;
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
/* Adlib FM patches */
|
||||
if (flags & SAMPLE_FLAG_ADLIB) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Empty or invalid samples
|
||||
*/
|
||||
if (xxs->len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Skip sample loading
|
||||
* FIXME: fails for ADPCM samples
|
||||
*
|
||||
* + Sanity check: skip huge samples (likely corrupt module)
|
||||
*/
|
||||
if (xxs->len > MAX_SAMPLE_SIZE || (m && m->smpctl & XMP_SMPCTL_SKIP)) {
|
||||
if (~flags & SAMPLE_FLAG_NOLOAD) {
|
||||
/* coverity[check_return] */
|
||||
hio_seek(f, xxs->len, SEEK_CUR);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Loop parameters sanity check
|
||||
*/
|
||||
if (xxs->lps < 0) {
|
||||
xxs->lps = 0;
|
||||
}
|
||||
if (xxs->lpe > xxs->len) {
|
||||
xxs->lpe = xxs->len;
|
||||
}
|
||||
if (xxs->lps >= xxs->len || xxs->lps >= xxs->lpe) {
|
||||
xxs->lps = xxs->lpe = 0;
|
||||
xxs->flg &= ~(XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR);
|
||||
}
|
||||
|
||||
/* Patches with samples
|
||||
* Allocate extra sample for interpolation.
|
||||
*/
|
||||
bytelen = xxs->len;
|
||||
extralen = 4;
|
||||
unroll_extralen = 0;
|
||||
|
||||
/* Disable birectional loop flag if sample is not looped
|
||||
*/
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
if (~xxs->flg & XMP_SAMPLE_LOOP)
|
||||
xxs->flg &= ~XMP_SAMPLE_LOOP_BIDIR;
|
||||
}
|
||||
/* Unroll bidirectional loops
|
||||
*/
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
unroll_extralen = (xxs->lpe - xxs->lps) -
|
||||
(xxs->len - xxs->lpe);
|
||||
|
||||
if (unroll_extralen < 0) {
|
||||
unroll_extralen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
bytelen *= 2;
|
||||
extralen *= 2;
|
||||
unroll_extralen *= 2;
|
||||
}
|
||||
|
||||
/* add guard bytes before the buffer for higher order interpolation */
|
||||
xxs->data = malloc(bytelen + extralen + unroll_extralen + 4);
|
||||
if (xxs->data == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
*(uint32 *)xxs->data = 0;
|
||||
xxs->data += 4;
|
||||
|
||||
if (flags & SAMPLE_FLAG_NOLOAD) {
|
||||
memcpy(xxs->data, buffer, bytelen);
|
||||
} else
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (flags & SAMPLE_FLAG_ADPCM) {
|
||||
int x2 = (bytelen + 1) >> 1;
|
||||
char table[16];
|
||||
|
||||
if (hio_read(table, 1, 16, f) != 16) {
|
||||
goto err2;
|
||||
}
|
||||
if (hio_read(xxs->data + x2, 1, x2, f) != x2) {
|
||||
goto err2;
|
||||
}
|
||||
adpcm4_decoder((uint8 *)xxs->data + x2,
|
||||
(uint8 *)xxs->data, table, bytelen);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
int x = hio_read(xxs->data, 1, bytelen, f);
|
||||
if (x != bytelen) {
|
||||
D_(D_WARN "short read (%d) in sample load", x - bytelen);
|
||||
memset(xxs->data + x, 0, bytelen - x);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (flags & SAMPLE_FLAG_7BIT) {
|
||||
convert_7bit_to_8bit(xxs->data, xxs->len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fix endianism if needed */
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (~flags & SAMPLE_FLAG_BIGEND)
|
||||
convert_endian(xxs->data, xxs->len);
|
||||
#else
|
||||
if (flags & SAMPLE_FLAG_BIGEND)
|
||||
convert_endian(xxs->data, xxs->len);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Convert delta samples */
|
||||
if (flags & SAMPLE_FLAG_DIFF) {
|
||||
convert_delta(xxs->data, xxs->len, xxs->flg & XMP_SAMPLE_16BIT);
|
||||
} else if (flags & SAMPLE_FLAG_8BDIFF) {
|
||||
int len = xxs->len;
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
len *= 2;
|
||||
}
|
||||
convert_delta(xxs->data, len, 0);
|
||||
}
|
||||
|
||||
/* Convert samples to signed */
|
||||
if (flags & SAMPLE_FLAG_UNS) {
|
||||
convert_signal(xxs->data, xxs->len,
|
||||
xxs->flg & XMP_SAMPLE_16BIT);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Downmix stereo samples */
|
||||
if (flags & SAMPLE_FLAG_STEREO) {
|
||||
convert_stereo_to_mono(xxs->data, xxs->len,
|
||||
xxs->flg & XMP_SAMPLE_16BIT);
|
||||
xxs->len /= 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (flags & SAMPLE_FLAG_VIDC) {
|
||||
convert_vidc_to_linear(xxs->data, xxs->len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check for full loop samples */
|
||||
if (flags & SAMPLE_FLAG_FULLREP) {
|
||||
if (xxs->lps == 0 && xxs->len > xxs->lpe)
|
||||
xxs->flg |= XMP_SAMPLE_LOOP_FULL;
|
||||
}
|
||||
|
||||
/* Unroll bidirectional loops */
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
unroll_loop(xxs);
|
||||
bytelen += unroll_extralen;
|
||||
}
|
||||
|
||||
/* Add extra samples at end */
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
xxs->data[bytelen + i] = xxs->data[bytelen - 2 + i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
xxs->data[bytelen + i] = xxs->data[bytelen - 1 + i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Add extra samples at start */
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
xxs->data[-2] = xxs->data[0];
|
||||
xxs->data[-1] = xxs->data[1];
|
||||
} else {
|
||||
xxs->data[-1] = xxs->data[0];
|
||||
}
|
||||
|
||||
/* Fix sample at loop */
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP) {
|
||||
int lpe = xxs->lpe;
|
||||
int lps = xxs->lps;
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
lpe += lpe - lps;
|
||||
}
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
lpe <<= 1;
|
||||
lps <<= 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
xxs->data[lpe + i] = xxs->data[lps + i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
xxs->data[lpe + i] = xxs->data[lps + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
err2:
|
||||
free(xxs->data - 4);
|
||||
#endif
|
||||
err:
|
||||
return -1;
|
||||
}
|
101
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/xm.h
vendored
Normal file
101
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/xm.h
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
#ifndef LIBXMP_LOADERS_XM_H
|
||||
#define LIBXMP_LOADERS_XM_H
|
||||
|
||||
#define XM_EVENT_PACKING 0x80
|
||||
#define XM_EVENT_PACK_MASK 0x7f
|
||||
#define XM_EVENT_NOTE_FOLLOWS 0x01
|
||||
#define XM_EVENT_INSTRUMENT_FOLLOWS 0x02
|
||||
#define XM_EVENT_VOLUME_FOLLOWS 0x04
|
||||
#define XM_EVENT_FXTYPE_FOLLOWS 0x08
|
||||
#define XM_EVENT_FXPARM_FOLLOWS 0x10
|
||||
#define XM_LINEAR_FREQ 0x01
|
||||
#define XM_LOOP_MASK 0x03
|
||||
#define XM_LOOP_NONE 0
|
||||
#define XM_LOOP_FORWARD 1
|
||||
#define XM_LOOP_PINGPONG 2
|
||||
#define XM_SAMPLE_16BIT 0x10
|
||||
#define XM_ENVELOPE_ON 0x01
|
||||
#define XM_ENVELOPE_SUSTAIN 0x02
|
||||
#define XM_ENVELOPE_LOOP 0x04
|
||||
#define XM_LINEAR_PERIOD_MODE 0x01
|
||||
|
||||
|
||||
struct xm_file_header {
|
||||
uint8 id[17]; /* ID text: "Extended module: " */
|
||||
uint8 name[20]; /* Module name, padded with zeroes */
|
||||
uint8 doseof; /* 0x1a */
|
||||
uint8 tracker[20]; /* Tracker name */
|
||||
uint16 version; /* Version number, minor-major */
|
||||
uint32 headersz; /* Header size */
|
||||
uint16 songlen; /* Song length (in patten order table) */
|
||||
uint16 restart; /* Restart position */
|
||||
uint16 channels; /* Number of channels (2,4,6,8,10,...,32) */
|
||||
uint16 patterns; /* Number of patterns (max 256) */
|
||||
uint16 instruments; /* Number of instruments (max 128) */
|
||||
uint16 flags; /* bit 0: 0=Amiga freq table, 1=Linear */
|
||||
uint16 tempo; /* Default tempo */
|
||||
uint16 bpm; /* Default BPM */
|
||||
uint8 order[256]; /* Pattern order table */
|
||||
};
|
||||
|
||||
struct xm_pattern_header {
|
||||
uint32 length; /* Pattern header length */
|
||||
uint8 packing; /* Packing type (always 0) */
|
||||
uint16 rows; /* Number of rows in pattern (1..256) */
|
||||
uint16 datasize; /* Packed patterndata size */
|
||||
};
|
||||
|
||||
struct xm_instrument_header {
|
||||
uint32 size; /* Instrument size */
|
||||
uint8 name[22]; /* Instrument name */
|
||||
uint8 type; /* Instrument type (always 0) */
|
||||
uint16 samples; /* Number of samples in instrument */
|
||||
uint32 sh_size; /* Sample header size */
|
||||
};
|
||||
|
||||
struct xm_instrument {
|
||||
uint8 sample[96]; /* Sample number for all notes */
|
||||
uint16 v_env[24]; /* Points for volume envelope */
|
||||
uint16 p_env[24]; /* Points for panning envelope */
|
||||
uint8 v_pts; /* Number of volume points */
|
||||
uint8 p_pts; /* Number of panning points */
|
||||
uint8 v_sus; /* Volume sustain point */
|
||||
uint8 v_start; /* Volume loop start point */
|
||||
uint8 v_end; /* Volume loop end point */
|
||||
uint8 p_sus; /* Panning sustain point */
|
||||
uint8 p_start; /* Panning loop start point */
|
||||
uint8 p_end; /* Panning loop end point */
|
||||
uint8 v_type; /* Bit 0: On; 1: Sustain; 2: Loop */
|
||||
uint8 p_type; /* Bit 0: On; 1: Sustain; 2: Loop */
|
||||
uint8 y_wave; /* Vibrato waveform */
|
||||
uint8 y_sweep; /* Vibrato sweep */
|
||||
uint8 y_depth; /* Vibrato depth */
|
||||
uint8 y_rate; /* Vibrato rate */
|
||||
uint16 v_fade; /* Volume fadeout */
|
||||
#if 0
|
||||
uint8 reserved[22]; /* Reserved; 2 bytes in specs, 22 in 1.04 */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct xm_sample_header {
|
||||
uint32 length; /* Sample length */
|
||||
uint32 loop_start; /* Sample loop start */
|
||||
uint32 loop_length; /* Sample loop length */
|
||||
uint8 volume; /* Volume */
|
||||
int8 finetune; /* Finetune (signed byte -128..+127) */
|
||||
uint8 type; /* 0=No loop,1=Fwd loop,2=Ping-pong,16-bit */
|
||||
uint8 pan; /* Panning (0-255) */
|
||||
int8 relnote; /* Relative note number (signed byte) */
|
||||
uint8 reserved; /* Reserved */
|
||||
uint8 name[22]; /* Sample_name */
|
||||
};
|
||||
|
||||
struct xm_event {
|
||||
uint8 note; /* Note (0-71, 0 = C-0) */
|
||||
uint8 instrument; /* Instrument (0-128) */
|
||||
uint8 volume; /* Volume column byte */
|
||||
uint8 fx_type; /* Effect type */
|
||||
uint8 fx_parm; /* Effect parameter */
|
||||
};
|
||||
|
||||
#endif
|
729
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/xm_load.c
vendored
Normal file
729
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/loaders/xm_load.c
vendored
Normal file
|
@ -0,0 +1,729 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fri, 26 Jun 1998 17:45:59 +1000 Andrew Leahy <alf@cit.nepean.uws.edu.au>
|
||||
* Finally got it working on the DEC Alpha running DEC UNIX! In the pattern
|
||||
* reading loop I found I was getting "0" for (p-patbuf) and "0" for
|
||||
* xph.datasize, the next if statement (where it tries to read the patbuf)
|
||||
* would then cause a seg_fault.
|
||||
*
|
||||
* Sun Sep 27 12:07:12 EST 1998 Claudio Matsuoka <claudio@pos.inf.ufpr.br>
|
||||
* Extended Module 1.02 stores data in a different order, we must handle
|
||||
* this accordingly. MAX_SAMP used as a workaround to check the number of
|
||||
* samples recognized by the player.
|
||||
*/
|
||||
|
||||
#include "loader.h"
|
||||
#include "xm.h"
|
||||
|
||||
static int xm_test(HIO_HANDLE *, char *, const int);
|
||||
static int xm_load(struct module_data *, HIO_HANDLE *, const int);
|
||||
|
||||
const struct format_loader libxmp_loader_xm = {
|
||||
"Fast Tracker II",
|
||||
xm_test,
|
||||
xm_load
|
||||
};
|
||||
|
||||
static int xm_test(HIO_HANDLE *f, char *t, const int start)
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
if (hio_read(buf, 1, 17, f) < 17) /* ID text */
|
||||
return -1;
|
||||
|
||||
if (memcmp(buf, "Extended Module: ", 17))
|
||||
return -1;
|
||||
|
||||
libxmp_read_title(f, t, 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_xm_pattern(struct module_data *m, int num, int version, HIO_HANDLE *f)
|
||||
{
|
||||
const int headsize = version > 0x0102 ? 9 : 8;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct xm_pattern_header xph;
|
||||
struct xmp_event *event;
|
||||
uint8 *patbuf, *pat, b;
|
||||
int j, r;
|
||||
int size;
|
||||
|
||||
xph.length = hio_read32l(f);
|
||||
xph.packing = hio_read8(f);
|
||||
xph.rows = version > 0x0102 ? hio_read16l(f) : hio_read8(f) + 1;
|
||||
|
||||
/* Sanity check */
|
||||
if (xph.rows > 256) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
xph.datasize = hio_read16l(f);
|
||||
hio_seek(f, xph.length - headsize, SEEK_CUR);
|
||||
if (hio_error(f)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = xph.rows;
|
||||
if (r == 0) {
|
||||
r = 0x100;
|
||||
}
|
||||
|
||||
if (libxmp_alloc_pattern_tracks(mod, num, r) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (xph.datasize == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = xph.datasize;
|
||||
|
||||
pat = patbuf = calloc(1, size);
|
||||
if (patbuf == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
hio_read(patbuf, 1, size, f);
|
||||
for (j = 0; j < (mod->chn * r); j++) {
|
||||
|
||||
/*if ((pat - patbuf) >= xph.datasize)
|
||||
break; */
|
||||
|
||||
event = &EVENT(num, j % mod->chn, j / mod->chn);
|
||||
|
||||
if (--size < 0) {
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if ((b = *pat++) & XM_EVENT_PACKING) {
|
||||
if (b & XM_EVENT_NOTE_FOLLOWS) {
|
||||
if (--size < 0)
|
||||
goto err2;
|
||||
event->note = *pat++;
|
||||
}
|
||||
if (b & XM_EVENT_INSTRUMENT_FOLLOWS) {
|
||||
if (--size < 0)
|
||||
goto err2;
|
||||
event->ins = *pat++;
|
||||
}
|
||||
if (b & XM_EVENT_VOLUME_FOLLOWS) {
|
||||
if (--size < 0)
|
||||
goto err2;
|
||||
event->vol = *pat++;
|
||||
}
|
||||
if (b & XM_EVENT_FXTYPE_FOLLOWS) {
|
||||
if (--size < 0)
|
||||
goto err2;
|
||||
event->fxt = *pat++;
|
||||
}
|
||||
if (b & XM_EVENT_FXPARM_FOLLOWS) {
|
||||
if (--size < 0)
|
||||
goto err2;
|
||||
event->fxp = *pat++;
|
||||
}
|
||||
} else {
|
||||
size -= 4;
|
||||
if (size < 0)
|
||||
goto err2;
|
||||
event->note = b;
|
||||
event->ins = *pat++;
|
||||
event->vol = *pat++;
|
||||
event->fxt = *pat++;
|
||||
event->fxp = *pat++;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
switch (event->fxt) {
|
||||
case 18:
|
||||
case 19:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 26:
|
||||
case 28:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
event->fxt = 0;
|
||||
}
|
||||
if (event->fxt > 34) {
|
||||
event->fxt = 0;
|
||||
}
|
||||
|
||||
if (event->note == 0x61) {
|
||||
/* See OpenMPT keyoff+instr.xm test case */
|
||||
if (event->fxt == 0x0e && MSN(event->fxp) == 0x0d) {
|
||||
event->note = XMP_KEY_OFF;
|
||||
} else {
|
||||
event->note =
|
||||
event->ins ? XMP_KEY_FADE : XMP_KEY_OFF;
|
||||
}
|
||||
} else if (event->note > 0) {
|
||||
event->note += 12;
|
||||
}
|
||||
|
||||
if (event->fxt == 0x0e) {
|
||||
if (MSN(event->fxp) == EX_FINETUNE) {
|
||||
unsigned char val = (LSN(event->fxp) - 8) & 0xf;
|
||||
event->fxp = (EX_FINETUNE << 4) | val;
|
||||
}
|
||||
switch (event->fxp) {
|
||||
case 0x43:
|
||||
case 0x73:
|
||||
event->fxp--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!event->vol) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Volume set */
|
||||
if ((event->vol >= 0x10) && (event->vol <= 0x50)) {
|
||||
event->vol -= 0x0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Volume column effects */
|
||||
switch (event->vol >> 4) {
|
||||
case 0x06: /* Volume slide down */
|
||||
event->f2t = FX_VOLSLIDE_2;
|
||||
event->f2p = event->vol - 0x60;
|
||||
break;
|
||||
case 0x07: /* Volume slide up */
|
||||
event->f2t = FX_VOLSLIDE_2;
|
||||
event->f2p = (event->vol - 0x70) << 4;
|
||||
break;
|
||||
case 0x08: /* Fine volume slide down */
|
||||
event->f2t = FX_EXTENDED;
|
||||
event->f2p =
|
||||
(EX_F_VSLIDE_DN << 4) | (event->vol - 0x80);
|
||||
break;
|
||||
case 0x09: /* Fine volume slide up */
|
||||
event->f2t = FX_EXTENDED;
|
||||
event->f2p =
|
||||
(EX_F_VSLIDE_UP << 4) | (event->vol - 0x90);
|
||||
break;
|
||||
case 0x0a: /* Set vibrato speed */
|
||||
event->f2t = FX_VIBRATO;
|
||||
event->f2p = (event->vol - 0xa0) << 4;
|
||||
break;
|
||||
case 0x0b: /* Vibrato */
|
||||
event->f2t = FX_VIBRATO;
|
||||
event->f2p = event->vol - 0xb0;
|
||||
break;
|
||||
case 0x0c: /* Set panning */
|
||||
event->f2t = FX_SETPAN;
|
||||
event->f2p = (event->vol - 0xc0) << 4;
|
||||
break;
|
||||
case 0x0d: /* Pan slide left */
|
||||
event->f2t = FX_PANSL_NOMEM;
|
||||
event->f2p = (event->vol - 0xd0) << 4;
|
||||
break;
|
||||
case 0x0e: /* Pan slide right */
|
||||
event->f2t = FX_PANSL_NOMEM;
|
||||
event->f2p = event->vol - 0xe0;
|
||||
break;
|
||||
case 0x0f: /* Tone portamento */
|
||||
event->f2t = FX_TONEPORTA;
|
||||
event->f2p = (event->vol - 0xf0) << 4;
|
||||
|
||||
/* From OpenMPT TonePortamentoMemory.xm:
|
||||
* "Another nice bug (...) is the combination of both
|
||||
* portamento commands (Mx and 3xx) in the same cell:
|
||||
* The 3xx parameter is ignored completely, and the Mx
|
||||
* parameter is doubled. (M2 3FF is the same as M4 000)
|
||||
*/
|
||||
if (event->fxt == FX_TONEPORTA
|
||||
|| event->fxt == FX_TONE_VSLIDE) {
|
||||
if (event->fxt == FX_TONEPORTA) {
|
||||
event->fxt = 0;
|
||||
} else {
|
||||
event->fxt = FX_VOLSLIDE;
|
||||
}
|
||||
event->fxp = 0;
|
||||
|
||||
if (event->f2p < 0x80) {
|
||||
event->f2p <<= 1;
|
||||
} else {
|
||||
event->f2p = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/* From OpenMPT porta-offset.xm:
|
||||
* "If there is a portamento command next to an offset
|
||||
* command, the offset command is ignored completely. In
|
||||
* particular, the offset parameter is not memorized."
|
||||
*/
|
||||
if (event->fxt == FX_OFFSET
|
||||
&& event->f2t == FX_TONEPORTA) {
|
||||
event->fxt = event->fxp = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
event->vol = 0;
|
||||
}
|
||||
free(patbuf);
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
free(patbuf);
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int load_patterns(struct module_data *m, int version, HIO_HANDLE *f)
|
||||
{
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i, j;
|
||||
|
||||
mod->pat++;
|
||||
if (libxmp_init_pattern(mod) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
D_(D_INFO "Stored patterns: %d", mod->pat - 1);
|
||||
|
||||
for (i = 0; i < mod->pat - 1; i++) {
|
||||
if (load_xm_pattern(m, i, version, f) < 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Alloc one extra pattern */
|
||||
{
|
||||
int t = i * mod->chn;
|
||||
|
||||
if (libxmp_alloc_pattern(mod, i) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
mod->xxp[i]->rows = 64;
|
||||
|
||||
if (libxmp_alloc_track(mod, t, 64) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (j = 0; j < mod->chn; j++) {
|
||||
mod->xxp[i]->index[j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Packed structures size */
|
||||
#define XM_INST_HEADER_SIZE 33
|
||||
#define XM_INST_SIZE 208
|
||||
|
||||
static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
|
||||
{
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct xm_instrument_header xih;
|
||||
struct xm_instrument xi;
|
||||
struct xm_sample_header xsh[16];
|
||||
int sample_num = 0;
|
||||
int i, j;
|
||||
|
||||
D_(D_INFO "Instruments: %d", mod->ins);
|
||||
|
||||
/* ESTIMATED value! We don't know the actual value at this point */
|
||||
mod->smp = MAX_SAMPLES;
|
||||
|
||||
if (libxmp_init_instrument(m) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
struct xmp_instrument *xxi = &mod->xxi[i];
|
||||
|
||||
xih.size = hio_read32l(f); /* Instrument size */
|
||||
|
||||
/* Modules converted with MOD2XM 1.0 always say we have 31
|
||||
* instruments, but file may end abruptly before that. This test
|
||||
* will not work if file has trailing garbage.
|
||||
*/
|
||||
if (hio_eof(f)) {
|
||||
break;
|
||||
}
|
||||
|
||||
hio_read(&xih.name, 22, 1, f); /* Instrument name */
|
||||
xih.type = hio_read8(f); /* Instrument type (always 0) */
|
||||
xih.samples = hio_read16l(f); /* Number of samples */
|
||||
xih.sh_size = hio_read32l(f); /* Sample header size */
|
||||
|
||||
/* Sanity check */
|
||||
if (xih.samples > 0x10 || (xih.samples > 0 && xih.sh_size > 0x100)) {
|
||||
D_(D_CRIT "Sanity check: %d %d", xih.samples, xih.sh_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
libxmp_instrument_name(mod, i, xih.name, 22);
|
||||
|
||||
xxi->nsm = xih.samples;
|
||||
if (xxi->nsm > 16)
|
||||
xxi->nsm = 16;
|
||||
|
||||
D_(D_INFO "[%2X] %-22.22s %2d", i, xxi->name, xxi->nsm);
|
||||
|
||||
if (xxi->nsm) {
|
||||
if (libxmp_alloc_subinstrument(mod, i, xxi->nsm) < 0)
|
||||
return -1;
|
||||
if (xih.size < XM_INST_HEADER_SIZE)
|
||||
return -1;
|
||||
|
||||
/* for BoobieSqueezer (see http://boobie.rotfl.at/)
|
||||
* It works pretty much the same way as Impulse Tracker's sample
|
||||
* only mode, where it will strip off the instrument data.
|
||||
*/
|
||||
if (xih.size < XM_INST_HEADER_SIZE + XM_INST_SIZE) {
|
||||
memset(&xi, 0, sizeof (struct xm_instrument));
|
||||
hio_seek(f, xih.size - XM_INST_HEADER_SIZE, SEEK_CUR);
|
||||
} else {
|
||||
hio_read(&xi.sample, 96, 1, f); /* Sample map */
|
||||
for (j = 0; j < 24; j++)
|
||||
xi.v_env[j] = hio_read16l(f); /* Points for volume envelope */
|
||||
for (j = 0; j < 24; j++)
|
||||
xi.p_env[j] = hio_read16l(f); /* Points for pan envelope */
|
||||
xi.v_pts = hio_read8(f); /* Number of volume points */
|
||||
xi.p_pts = hio_read8(f); /* Number of pan points */
|
||||
xi.v_sus = hio_read8(f); /* Volume sustain point */
|
||||
xi.v_start = hio_read8(f); /* Volume loop start point */
|
||||
xi.v_end = hio_read8(f); /* Volume loop end point */
|
||||
xi.p_sus = hio_read8(f); /* Pan sustain point */
|
||||
xi.p_start = hio_read8(f); /* Pan loop start point */
|
||||
xi.p_end = hio_read8(f); /* Pan loop end point */
|
||||
xi.v_type = hio_read8(f); /* Bit 0:On 1:Sustain 2:Loop */
|
||||
xi.p_type = hio_read8(f); /* Bit 0:On 1:Sustain 2:Loop */
|
||||
xi.y_wave = hio_read8(f); /* Vibrato waveform */
|
||||
xi.y_sweep = hio_read8(f); /* Vibrato sweep */
|
||||
xi.y_depth = hio_read8(f); /* Vibrato depth */
|
||||
xi.y_rate = hio_read8(f); /* Vibrato rate */
|
||||
xi.v_fade = hio_read16l(f); /* Volume fadeout */
|
||||
|
||||
/* Skip reserved space */
|
||||
hio_seek(f, (int)xih.size - (XM_INST_HEADER_SIZE + XM_INST_SIZE), SEEK_CUR);
|
||||
|
||||
/* Envelope */
|
||||
xxi->rls = xi.v_fade << 1;
|
||||
xxi->aei.npt = xi.v_pts;
|
||||
xxi->aei.sus = xi.v_sus;
|
||||
xxi->aei.lps = xi.v_start;
|
||||
xxi->aei.lpe = xi.v_end;
|
||||
xxi->aei.flg = xi.v_type;
|
||||
xxi->pei.npt = xi.p_pts;
|
||||
xxi->pei.sus = xi.p_sus;
|
||||
xxi->pei.lps = xi.p_start;
|
||||
xxi->pei.lpe = xi.p_end;
|
||||
xxi->pei.flg = xi.p_type;
|
||||
|
||||
if (xxi->aei.npt <= 0 || xxi->aei.npt > 12 /*XMP_MAX_ENV_POINTS*/)
|
||||
xxi->aei.flg &= ~XMP_ENVELOPE_ON;
|
||||
else
|
||||
memcpy(xxi->aei.data, xi.v_env, xxi->aei.npt * 4);
|
||||
|
||||
if (xxi->pei.npt <= 0 || xxi->pei.npt > 12 /*XMP_MAX_ENV_POINTS*/)
|
||||
xxi->pei.flg &= ~XMP_ENVELOPE_ON;
|
||||
else
|
||||
memcpy(xxi->pei.data, xi.p_env, xxi->pei.npt * 4);
|
||||
|
||||
for (j = 12; j < 108; j++) {
|
||||
xxi->map[j].ins = xi.sample[j - 12];
|
||||
if (xxi->map[j].ins >= xxi->nsm)
|
||||
xxi->map[j].ins = -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < xxi->nsm; j++, sample_num++) {
|
||||
struct xmp_subinstrument *sub = &xxi->sub[j];
|
||||
struct xmp_sample *xxs;
|
||||
|
||||
if (sample_num >= mod->smp) {
|
||||
mod->xxs = libxmp_realloc_samples(mod->xxs, &mod->smp, mod->smp * 3 / 2);
|
||||
if (mod->xxs == NULL)
|
||||
return -1;
|
||||
}
|
||||
xxs = &mod->xxs[sample_num];
|
||||
|
||||
xsh[j].length = hio_read32l(f); /* Sample length */
|
||||
|
||||
/* Sanity check */
|
||||
if (xsh[j].length > MAX_SAMPLE_SIZE)
|
||||
return -1;
|
||||
|
||||
xsh[j].loop_start = hio_read32l(f); /* Sample loop start */
|
||||
xsh[j].loop_length = hio_read32l(f); /* Sample loop length */
|
||||
xsh[j].volume = hio_read8(f); /* Volume */
|
||||
xsh[j].finetune = hio_read8s(f); /* Finetune (-128..+127) */
|
||||
xsh[j].type = hio_read8(f); /* Flags */
|
||||
xsh[j].pan = hio_read8(f); /* Panning (0-255) */
|
||||
xsh[j].relnote = hio_read8s(f); /* Relative note number */
|
||||
xsh[j].reserved = hio_read8(f);
|
||||
hio_read(&xsh[j].name, 22, 1, f); /* Sample_name */
|
||||
|
||||
sub->vol = xsh[j].volume;
|
||||
sub->pan = xsh[j].pan;
|
||||
sub->xpo = xsh[j].relnote;
|
||||
sub->fin = xsh[j].finetune;
|
||||
sub->vwf = xi.y_wave;
|
||||
sub->vde = xi.y_depth << 2;
|
||||
sub->vra = xi.y_rate;
|
||||
sub->vsw = xi.y_sweep;
|
||||
sub->sid = sample_num;
|
||||
|
||||
libxmp_copy_adjust(xxs->name, xsh[j].name, 22);
|
||||
|
||||
xxs->len = xsh[j].length;
|
||||
xxs->lps = xsh[j].loop_start;
|
||||
xxs->lpe = xsh[j].loop_start + xsh[j].loop_length;
|
||||
|
||||
xxs->flg = 0;
|
||||
if (xsh[j].type & XM_SAMPLE_16BIT) {
|
||||
xxs->flg |= XMP_SAMPLE_16BIT;
|
||||
xxs->len >>= 1;
|
||||
xxs->lps >>= 1;
|
||||
xxs->lpe >>= 1;
|
||||
}
|
||||
|
||||
xxs->flg |= xsh[j].type & XM_LOOP_FORWARD ?
|
||||
XMP_SAMPLE_LOOP : 0;
|
||||
xxs->flg |= xsh[j].type & XM_LOOP_PINGPONG ?
|
||||
XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR : 0;
|
||||
}
|
||||
for (j = 0; j < xxi->nsm; j++) {
|
||||
struct xmp_subinstrument *sub = &xxi->sub[j];
|
||||
int flags;
|
||||
|
||||
D_(D_INFO " %1x: %06x%c%06x %06x %c V%02x F%+04d P%02x R%+03d",
|
||||
j, mod->xxs[sub->sid].len,
|
||||
mod->xxs[sub->sid].flg & XMP_SAMPLE_16BIT ? '+' : ' ',
|
||||
mod->xxs[sub->sid].lps,
|
||||
mod->xxs[sub->sid].lpe,
|
||||
mod->xxs[sub->sid].flg & XMP_SAMPLE_LOOP_BIDIR ? 'B' :
|
||||
mod->xxs[sub->sid].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
|
||||
sub->vol, sub->fin,
|
||||
sub->pan, sub->xpo);
|
||||
|
||||
flags = SAMPLE_FLAG_DIFF;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (xsh[j].reserved == 0xad) {
|
||||
flags = SAMPLE_FLAG_ADPCM;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (version > 0x0103) {
|
||||
if (libxmp_load_sample(m, f, flags,
|
||||
&mod->xxs[sub->sid], NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Sample size should be in struct xm_instrument according to
|
||||
* the official format description, but FT2 actually puts it in
|
||||
* struct xm_instrument header. There's a tracker or converter
|
||||
* that follow the specs, so we must handle both cases (see
|
||||
* "Braintomb" by Jazztiz/ART).
|
||||
*/
|
||||
|
||||
/* Umm, Cyke O'Path <cyker@heatwave.co.uk> sent me a couple of
|
||||
* mods ("Breath of the Wind" and "Broken Dimension") that
|
||||
* reserve the instrument data space after the instrument header
|
||||
* even if the number of instruments is set to 0. In these modules
|
||||
* the instrument header size is marked as 263. The following
|
||||
* generalization should take care of both cases.
|
||||
*/
|
||||
|
||||
hio_seek(f, (int)xih.size - XM_INST_HEADER_SIZE, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Final sample number adjustment */
|
||||
mod->xxs = libxmp_realloc_samples(mod->xxs, &mod->smp, sample_num);
|
||||
if (mod->xxs == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xm_load(struct module_data *m, HIO_HANDLE * f, const int start)
|
||||
{
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i, j;
|
||||
struct xm_file_header xfh;
|
||||
char tracker_name[21];
|
||||
int len;
|
||||
|
||||
LOAD_INIT();
|
||||
|
||||
hio_read(&xfh.id, 17, 1, f); /* ID text */
|
||||
hio_read(&xfh.name, 20, 1, f); /* Module name */
|
||||
hio_read8(f); /* 0x1a */
|
||||
hio_read(&xfh.tracker, 20, 1, f); /* Tracker name */
|
||||
xfh.version = hio_read16l(f); /* Version number, minor-major */
|
||||
xfh.headersz = hio_read32l(f); /* Header size */
|
||||
xfh.songlen = hio_read16l(f); /* Song length */
|
||||
xfh.restart = hio_read16l(f); /* Restart position */
|
||||
xfh.channels = hio_read16l(f); /* Number of channels */
|
||||
xfh.patterns = hio_read16l(f); /* Number of patterns */
|
||||
xfh.instruments = hio_read16l(f); /* Number of instruments */
|
||||
xfh.flags = hio_read16l(f); /* 0=Amiga freq table, 1=Linear */
|
||||
xfh.tempo = hio_read16l(f); /* Default tempo */
|
||||
xfh.bpm = hio_read16l(f); /* Default BPM */
|
||||
|
||||
/* Sanity checks */
|
||||
if (xfh.songlen > 256 || xfh.patterns > 256 || xfh.instruments > 255) {
|
||||
D_(D_CRIT "Sanity check: %d %d %d", xfh.songlen, xfh.patterns,
|
||||
xfh.instruments);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xfh.restart > 255 || xfh.channels > XMP_MAX_CHANNELS) {
|
||||
D_(D_CRIT "Sanity check: %d %d", xfh.restart, xfh.channels);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xfh.tempo >= 32 || xfh.bpm < 32 || xfh.bpm > 255) {
|
||||
if (memcmp("MED2XM", xfh.tracker, 6)) {
|
||||
D_(D_CRIT "Sanity check: %d %d", xfh.tempo, xfh.bpm);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
len = xfh.headersz - 0x14;
|
||||
if (len < 0 || len > 256) {
|
||||
D_(D_CRIT "Sanity check: %d", len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Honor header size -- needed by BoobieSqueezer XMs */
|
||||
hio_read(&xfh.order, len, 1, f); /* Pattern order table */
|
||||
|
||||
strncpy(mod->name, (char *)xfh.name, 20);
|
||||
|
||||
mod->len = xfh.songlen;
|
||||
mod->chn = xfh.channels;
|
||||
mod->pat = xfh.patterns;
|
||||
mod->ins = xfh.instruments;
|
||||
mod->rst = xfh.restart;
|
||||
mod->spd = xfh.tempo;
|
||||
mod->bpm = xfh.bpm;
|
||||
mod->trk = mod->chn * mod->pat + 1;
|
||||
|
||||
m->c4rate = C4_NTSC_RATE;
|
||||
m->period_type = xfh.flags & XM_LINEAR_PERIOD_MODE ?
|
||||
PERIOD_LINEAR : PERIOD_AMIGA;
|
||||
|
||||
memcpy(mod->xxo, xfh.order, mod->len);
|
||||
/*tracker_name[20] = 0;*/
|
||||
snprintf(tracker_name, 21, "%-20.20s", xfh.tracker);
|
||||
for (i = 20; i >= 0; i--) {
|
||||
if (tracker_name[i] == 0x20)
|
||||
tracker_name[i] = 0;
|
||||
if (tracker_name[i])
|
||||
break;
|
||||
}
|
||||
|
||||
/* OpenMPT accurately emulates weird FT2 bugs */
|
||||
if (!strncmp(tracker_name, "FastTracker v2.00", 17) ||
|
||||
!strncmp(tracker_name, "OpenMPT ", 8)) {
|
||||
m->quirk |= QUIRK_FT2BUGS;
|
||||
}
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (xfh.headersz == 0x0113) {
|
||||
strcpy(tracker_name, "unknown tracker");
|
||||
m->quirk &= ~QUIRK_FT2BUGS;
|
||||
} else if (*tracker_name == 0) {
|
||||
strcpy(tracker_name, "Digitrakker"); /* best guess */
|
||||
m->quirk &= ~QUIRK_FT2BUGS;
|
||||
}
|
||||
|
||||
/* See MMD1 loader for explanation */
|
||||
if (!strncmp(tracker_name, "MED2XM by J.Pynnone", 19)) {
|
||||
if (mod->bpm <= 10)
|
||||
mod->bpm = 125 * (0x35 - mod->bpm * 2) / 33;
|
||||
m->quirk &= ~QUIRK_FT2BUGS;
|
||||
}
|
||||
|
||||
if (!strncmp(tracker_name, "FastTracker v 2.00", 18)) {
|
||||
strcpy(tracker_name, "old ModPlug Tracker");
|
||||
m->quirk &= ~QUIRK_FT2BUGS;
|
||||
}
|
||||
|
||||
libxmp_set_type(m, "%s XM %d.%02d", tracker_name,
|
||||
xfh.version >> 8, xfh.version & 0xff);
|
||||
#else
|
||||
libxmp_set_type(m, tracker_name);
|
||||
#endif
|
||||
|
||||
MODULE_INFO();
|
||||
|
||||
/* Honor header size */
|
||||
|
||||
hio_seek(f, start + xfh.headersz + 60, SEEK_SET);
|
||||
|
||||
/* XM 1.02/1.03 has a different patterns and instruments order */
|
||||
|
||||
if (xfh.version <= 0x0103) {
|
||||
if (load_instruments(m, xfh.version, f) < 0)
|
||||
return -1;
|
||||
if (load_patterns(m, xfh.version, f) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (load_patterns(m, xfh.version, f) < 0)
|
||||
return -1;
|
||||
if (load_instruments(m, xfh.version, f) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
D_(D_INFO "Stored samples: %d", mod->smp);
|
||||
|
||||
/* XM 1.02 stores all samples after the patterns */
|
||||
|
||||
if (xfh.version <= 0x0103) {
|
||||
for (i = 0; i < mod->ins; i++) {
|
||||
for (j = 0; j < mod->xxi[i].nsm; j++) {
|
||||
int sid = mod->xxi[i].sub[j].sid;
|
||||
if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF,
|
||||
&mod->xxs[sid], NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < mod->chn; i++) {
|
||||
mod->xxc[i].pan = 0x80;
|
||||
}
|
||||
|
||||
m->quirk |= QUIRKS_FT2;
|
||||
m->read_event_type = READ_EVENT_FT2;
|
||||
|
||||
return 0;
|
||||
}
|
105
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mdataio.h
vendored
Normal file
105
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mdataio.h
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
#ifndef LIBXMP_MDATAIO_H
|
||||
#define LIBXMP_MDATAIO_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "common.h"
|
||||
|
||||
static inline ptrdiff_t CAN_READ(MFILE *m)
|
||||
{
|
||||
if (m->size >= 0)
|
||||
return m->pos >= 0 ? m->size - m->pos : 0;
|
||||
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
static inline uint8 mread8(MFILE *m)
|
||||
{
|
||||
uint8 x = 0xff;
|
||||
mread(&x, 1, 1, m);
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline int8 mread8s(MFILE *m)
|
||||
{
|
||||
return (int8)mgetc(m);
|
||||
}
|
||||
|
||||
static inline uint16 mread16l(MFILE *m)
|
||||
{
|
||||
ptrdiff_t can_read = CAN_READ(m);
|
||||
if (can_read >= 2) {
|
||||
uint16 n = readmem16l(m->start + m->pos);
|
||||
m->pos += 2;
|
||||
return n;
|
||||
} else {
|
||||
m->pos += can_read;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint16 mread16b(MFILE *m)
|
||||
{
|
||||
ptrdiff_t can_read = CAN_READ(m);
|
||||
if (can_read >= 2) {
|
||||
uint16 n = readmem16b(m->start + m->pos);
|
||||
m->pos += 2;
|
||||
return n;
|
||||
} else {
|
||||
m->pos += can_read;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32 mread24l(MFILE *m)
|
||||
{
|
||||
ptrdiff_t can_read = CAN_READ(m);
|
||||
if (can_read >= 3) {
|
||||
uint32 n = readmem24l(m->start + m->pos);
|
||||
m->pos += 3;
|
||||
return n;
|
||||
} else {
|
||||
m->pos += can_read;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32 mread24b(MFILE *m)
|
||||
{
|
||||
ptrdiff_t can_read = CAN_READ(m);
|
||||
if (can_read >= 3) {
|
||||
uint32 n = readmem24b(m->start + m->pos);
|
||||
m->pos += 3;
|
||||
return n;
|
||||
} else {
|
||||
m->pos += can_read;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32 mread32l(MFILE *m)
|
||||
{
|
||||
ptrdiff_t can_read = CAN_READ(m);
|
||||
if (can_read >= 4) {
|
||||
uint32 n = readmem32l(m->start + m->pos);
|
||||
m->pos += 4;
|
||||
return n;
|
||||
} else {
|
||||
m->pos += can_read;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32 mread32b(MFILE *m)
|
||||
{
|
||||
ptrdiff_t can_read = CAN_READ(m);
|
||||
if (can_read >= 4) {
|
||||
uint32 n = readmem32b(m->start + m->pos);
|
||||
m->pos += 4;
|
||||
return n;
|
||||
} else {
|
||||
m->pos += can_read;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
136
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/memio.c
vendored
Normal file
136
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/memio.c
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "memio.h"
|
||||
|
||||
static inline ptrdiff_t CAN_READ(MFILE *m)
|
||||
{
|
||||
if (m->size >= 0)
|
||||
return m->pos >= 0 ? m->size - m->pos : 0;
|
||||
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
|
||||
int mgetc(MFILE *m)
|
||||
{
|
||||
if (CAN_READ(m) >= 1)
|
||||
return *(uint8 *)(m->start + m->pos++);
|
||||
else
|
||||
return EOF;
|
||||
}
|
||||
|
||||
size_t mread(void *buf, size_t size, size_t num, MFILE *m)
|
||||
{
|
||||
size_t should_read = size * num;
|
||||
ptrdiff_t can_read = CAN_READ(m);
|
||||
|
||||
if (size <= 0 || num <= 0 || can_read <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (should_read > can_read) {
|
||||
should_read = can_read;
|
||||
}
|
||||
|
||||
memcpy(buf, m->start + m->pos, should_read);
|
||||
m->pos += should_read;
|
||||
|
||||
return should_read / size;
|
||||
}
|
||||
|
||||
|
||||
int mseek(MFILE *m, long offset, int whence)
|
||||
{
|
||||
switch (whence) {
|
||||
default:
|
||||
case SEEK_SET:
|
||||
if (m->size >= 0 && (offset > m->size || offset < 0))
|
||||
return -1;
|
||||
m->pos = offset;
|
||||
return 0;
|
||||
case SEEK_CUR:
|
||||
if (m->size >= 0 && (offset > CAN_READ(m) || offset < -m->pos))
|
||||
return -1;
|
||||
m->pos += offset;
|
||||
return 0;
|
||||
case SEEK_END:
|
||||
if (m->size < 0)
|
||||
return -1;
|
||||
m->pos = m->size + offset;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
long mtell(MFILE *m)
|
||||
{
|
||||
return (long)m->pos;
|
||||
}
|
||||
|
||||
int meof(MFILE *m)
|
||||
{
|
||||
if (m->size <= 0)
|
||||
return 0;
|
||||
else
|
||||
return CAN_READ(m) <= 0;
|
||||
}
|
||||
|
||||
MFILE *mopen(void *ptr, long size)
|
||||
{
|
||||
MFILE *m;
|
||||
|
||||
m = (MFILE *)malloc(sizeof (MFILE));
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
m->start = ptr;
|
||||
m->pos = 0;
|
||||
m->size = size;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
int mclose(MFILE *m)
|
||||
{
|
||||
free(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
int mstat(MFILE *m, struct stat *st)
|
||||
{
|
||||
memset(st, 0, sizeof (struct stat));
|
||||
st->st_size = m->size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
31
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/memio.h
vendored
Normal file
31
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/memio.h
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef LIBXMP_MEMIO_H
|
||||
#define LIBXMP_MEMIO_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned char *start;
|
||||
ptrdiff_t pos;
|
||||
ptrdiff_t size;
|
||||
} MFILE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MFILE *mopen(void *, long);
|
||||
int mgetc(MFILE *stream);
|
||||
size_t mread(void *, size_t, size_t, MFILE *);
|
||||
int mseek(MFILE *, long, int);
|
||||
long mtell(MFILE *);
|
||||
int mclose(MFILE *);
|
||||
int meof(MFILE *);
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
int mstat(MFILE *, struct stat *);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
439
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mix_all.c
vendored
Normal file
439
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mix_all.c
vendored
Normal file
|
@ -0,0 +1,439 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "virtual.h"
|
||||
#include "mixer.h"
|
||||
#include "precomp_lut.h"
|
||||
|
||||
/* Mixers
|
||||
*
|
||||
* To increase performance eight mixers are defined, one for each
|
||||
* combination of the following parameters: interpolation, resolution
|
||||
* and number of channels.
|
||||
*/
|
||||
#define NEAREST_NEIGHBOR() do { \
|
||||
smp_in = ((int16)sptr[pos] << 8); \
|
||||
} while (0)
|
||||
|
||||
#define NEAREST_NEIGHBOR_16BIT() do { \
|
||||
smp_in = sptr[pos]; \
|
||||
} while (0)
|
||||
|
||||
#define LINEAR_INTERP() do { \
|
||||
smp_l1 = ((int16)sptr[pos] << 8); \
|
||||
smp_dt = ((int16)sptr[pos + 1] << 8) - smp_l1; \
|
||||
smp_in = smp_l1 + (((frac >> 1) * smp_dt) >> (SMIX_SHIFT - 1)); \
|
||||
} while (0)
|
||||
|
||||
#define LINEAR_INTERP_16BIT() do { \
|
||||
smp_l1 = sptr[pos]; \
|
||||
smp_dt = sptr[pos + 1] - smp_l1; \
|
||||
smp_in = smp_l1 + (((frac >> 1) * smp_dt) >> (SMIX_SHIFT - 1)); \
|
||||
} while (0)
|
||||
|
||||
/* The following lut settings are PRECOMPUTED. If you plan on changing these
|
||||
* settings, you MUST also regenerate the arrays.
|
||||
*/
|
||||
/* number of bits used to scale spline coefs */
|
||||
#define SPLINE_QUANTBITS 14
|
||||
#define SPLINE_SHIFT (SPLINE_QUANTBITS)
|
||||
|
||||
/* log2(number) of precalculated splines (range is [4..14]) */
|
||||
#define SPLINE_FRACBITS 10
|
||||
#define SPLINE_LUTLEN (1L<<SPLINE_FRACBITS)
|
||||
|
||||
#define SPLINE_FRACSHIFT ((16 - SPLINE_FRACBITS) - 2)
|
||||
#define SPLINE_FRACMASK (((1L << (16 - SPLINE_FRACSHIFT)) - 1) & ~3)
|
||||
|
||||
#define SPLINE_INTERP() do { \
|
||||
int f = frac >> 6; \
|
||||
smp_in = (cubic_spline_lut0[f] * sptr[(int)pos - 1] + \
|
||||
cubic_spline_lut1[f] * sptr[pos ] + \
|
||||
cubic_spline_lut3[f] * sptr[pos + 2] + \
|
||||
cubic_spline_lut2[f] * sptr[pos + 1]) >> (SPLINE_SHIFT - 8); \
|
||||
} while (0)
|
||||
|
||||
#define SPLINE_INTERP_16BIT() do { \
|
||||
int f = frac >> 6; \
|
||||
smp_in = (cubic_spline_lut0[f] * sptr[(int)pos - 1] + \
|
||||
cubic_spline_lut1[f] * sptr[pos ] + \
|
||||
cubic_spline_lut3[f] * sptr[pos + 2] + \
|
||||
cubic_spline_lut2[f] * sptr[pos + 1]) >> SPLINE_SHIFT; \
|
||||
} while (0)
|
||||
|
||||
#define LOOP_AC for (; count > ramp; count--)
|
||||
|
||||
#define LOOP for (; count; count--)
|
||||
|
||||
#define UPDATE_POS() do { \
|
||||
frac += step; \
|
||||
pos += frac >> SMIX_SHIFT; \
|
||||
frac &= SMIX_MASK; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_MONO() do { \
|
||||
*(buffer++) += smp_in * vl; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_MONO_AC() do { \
|
||||
*(buffer++) += smp_in * (old_vl >> 8); old_vl += delta_l; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_MONO_FILTER() do { \
|
||||
sl = (a0 * smp_in * vl + b0 * fl1 + b1 * fl2) >> FILTER_SHIFT; \
|
||||
fl2 = fl1; fl1 = sl; \
|
||||
*(buffer++) += sl; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_MONO_FILTER_AC() do { \
|
||||
int vl = old_vl >> 8; \
|
||||
MIX_MONO_FILTER(); \
|
||||
old_vl += delta_l; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_STEREO() do { \
|
||||
*(buffer++) += smp_in * vr; \
|
||||
*(buffer++) += smp_in * vl; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_STEREO_AC() do { \
|
||||
*(buffer++) += smp_in * (old_vr >> 8); old_vr += delta_r; \
|
||||
*(buffer++) += smp_in * (old_vl >> 8); old_vl += delta_l; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_STEREO_FILTER() do { \
|
||||
sr = (a0 * smp_in * vr + b0 * fr1 + b1 * fr2) >> FILTER_SHIFT; \
|
||||
fr2 = fr1; fr1 = sr; \
|
||||
sl = (a0 * smp_in * vl + b0 * fl1 + b1 * fl2) >> FILTER_SHIFT; \
|
||||
fl2 = fl1; fl1 = sl; \
|
||||
*(buffer++) += sr; \
|
||||
*(buffer++) += sl; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_STEREO_FILTER_AC() do { \
|
||||
int vr = old_vr >> 8; \
|
||||
int vl = old_vl >> 8; \
|
||||
MIX_STEREO_FILTER(); \
|
||||
old_vr += delta_r; \
|
||||
old_vl += delta_l; \
|
||||
} while (0)
|
||||
|
||||
#define MIX_STEREO_FILTER_AC() do { \
|
||||
int vr = old_vr >> 8; \
|
||||
int vl = old_vl >> 8; \
|
||||
MIX_STEREO_FILTER(); \
|
||||
old_vr += delta_r; \
|
||||
old_vl += delta_l; \
|
||||
} while (0)
|
||||
|
||||
#define VAR_NORM(x) \
|
||||
register int smp_in; \
|
||||
x *sptr = vi->sptr; \
|
||||
unsigned int pos = vi->pos; \
|
||||
int frac = (1 << SMIX_SHIFT) * (vi->pos - (int)vi->pos)
|
||||
|
||||
#define VAR_LINEAR_MONO(x) \
|
||||
VAR_NORM(x); \
|
||||
int old_vl = vi->old_vl; \
|
||||
int smp_l1, smp_dt
|
||||
|
||||
#define VAR_LINEAR_STEREO(x) \
|
||||
VAR_LINEAR_MONO(x); \
|
||||
int old_vr = vi->old_vr
|
||||
|
||||
#define VAR_SPLINE_MONO(x) \
|
||||
int old_vl = vi->old_vl; \
|
||||
VAR_NORM(x)
|
||||
|
||||
#define VAR_SPLINE_STEREO(x); \
|
||||
VAR_SPLINE_MONO(x); \
|
||||
int old_vr = vi->old_vr; \
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
|
||||
#define VAR_FILTER_MONO \
|
||||
int fl1 = vi->filter.l1, fl2 = vi->filter.l2; \
|
||||
int64 a0 = vi->filter.a0, b0 = vi->filter.b0, b1 = vi->filter.b1; \
|
||||
int sl
|
||||
|
||||
#define VAR_FILTER_STEREO \
|
||||
VAR_FILTER_MONO; \
|
||||
int fr1 = vi->filter.r1, fr2 = vi->filter.r2; \
|
||||
int sr
|
||||
|
||||
#define SAVE_FILTER_MONO() do { \
|
||||
vi->filter.l1 = fl1; \
|
||||
vi->filter.l2 = fl2; \
|
||||
} while (0)
|
||||
|
||||
#define SAVE_FILTER_STEREO() do { \
|
||||
SAVE_FILTER_MONO(); \
|
||||
vi->filter.r1 = fr1; \
|
||||
vi->filter.r2 = fr2; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Nearest neighbor mixers
|
||||
*/
|
||||
|
||||
/* Handler for 8 bit samples, nearest neighbor mono output
|
||||
*/
|
||||
MIXER(mono_8bit_nearest)
|
||||
{
|
||||
VAR_NORM(int8);
|
||||
|
||||
LOOP { NEAREST_NEIGHBOR(); MIX_MONO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
|
||||
/* Handler for 16 bit samples, nearest neighbor mono output
|
||||
*/
|
||||
MIXER(mono_16bit_nearest)
|
||||
{
|
||||
VAR_NORM(int16);
|
||||
|
||||
LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_MONO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 8 bit samples, nearest neighbor stereo output
|
||||
*/
|
||||
MIXER(stereo_8bit_nearest)
|
||||
{
|
||||
VAR_NORM(int8);
|
||||
|
||||
LOOP { NEAREST_NEIGHBOR(); MIX_STEREO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, nearest neighbor stereo output
|
||||
*/
|
||||
MIXER(stereo_16bit_nearest)
|
||||
{
|
||||
VAR_NORM(int16);
|
||||
|
||||
LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_STEREO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Linear mixers
|
||||
*/
|
||||
|
||||
/* Handler for 8 bit samples, linear interpolated mono output
|
||||
*/
|
||||
MIXER(mono_8bit_linear)
|
||||
{
|
||||
VAR_LINEAR_MONO(int8);
|
||||
|
||||
LOOP_AC { LINEAR_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP(); MIX_MONO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, linear interpolated mono output
|
||||
*/
|
||||
MIXER(mono_16bit_linear)
|
||||
{
|
||||
VAR_LINEAR_MONO(int16);
|
||||
|
||||
LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 8 bit samples, linear interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_8bit_linear)
|
||||
{
|
||||
VAR_LINEAR_STEREO(int8);
|
||||
|
||||
LOOP_AC { LINEAR_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP(); MIX_STEREO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, linear interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_16bit_linear)
|
||||
{
|
||||
VAR_LINEAR_STEREO(int16);
|
||||
|
||||
LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
|
||||
/* Handler for 8 bit samples, filtered linear interpolated mono output
|
||||
*/
|
||||
MIXER(mono_8bit_linear_filter)
|
||||
{
|
||||
VAR_LINEAR_MONO(int8);
|
||||
VAR_FILTER_MONO;
|
||||
|
||||
LOOP_AC { LINEAR_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_MONO();
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, filtered linear interpolated mono output
|
||||
*/
|
||||
MIXER(mono_16bit_linear_filter)
|
||||
{
|
||||
VAR_LINEAR_MONO(int16);
|
||||
VAR_FILTER_MONO;
|
||||
|
||||
LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_MONO();
|
||||
}
|
||||
|
||||
/* Handler for 8 bit samples, filtered linear interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_8bit_linear_filter)
|
||||
{
|
||||
VAR_LINEAR_STEREO(int8);
|
||||
VAR_FILTER_STEREO;
|
||||
|
||||
LOOP_AC { LINEAR_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_STEREO();
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, filtered linear interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_16bit_linear_filter)
|
||||
{
|
||||
VAR_LINEAR_STEREO(int16);
|
||||
VAR_FILTER_STEREO;
|
||||
|
||||
LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_STEREO();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Spline mixers
|
||||
*/
|
||||
|
||||
/* Handler for 8 bit samples, spline interpolated mono output
|
||||
*/
|
||||
MIXER(mono_8bit_spline)
|
||||
{
|
||||
VAR_SPLINE_MONO(int8);
|
||||
|
||||
LOOP_AC { SPLINE_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP(); MIX_MONO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, spline interpolated mono output
|
||||
*/
|
||||
MIXER(mono_16bit_spline)
|
||||
{
|
||||
VAR_SPLINE_MONO(int16);
|
||||
|
||||
LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 8 bit samples, spline interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_8bit_spline)
|
||||
{
|
||||
VAR_SPLINE_STEREO(int8);
|
||||
|
||||
LOOP_AC { SPLINE_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP(); MIX_STEREO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, spline interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_16bit_spline)
|
||||
{
|
||||
VAR_SPLINE_STEREO(int16);
|
||||
|
||||
LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
|
||||
/* Handler for 8 bit samples, filtered spline interpolated mono output
|
||||
*/
|
||||
MIXER(mono_8bit_spline_filter)
|
||||
{
|
||||
VAR_SPLINE_MONO(int8);
|
||||
VAR_FILTER_MONO;
|
||||
|
||||
LOOP_AC { SPLINE_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_MONO();
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, filtered spline interpolated mono output
|
||||
*/
|
||||
MIXER(mono_16bit_spline_filter)
|
||||
{
|
||||
VAR_SPLINE_MONO(int16);
|
||||
VAR_FILTER_MONO;
|
||||
|
||||
LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_MONO();
|
||||
}
|
||||
|
||||
/* Handler for 8 bit samples, filtered spline interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_8bit_spline_filter)
|
||||
{
|
||||
VAR_SPLINE_STEREO(int8);
|
||||
VAR_FILTER_STEREO;
|
||||
|
||||
LOOP_AC { SPLINE_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_STEREO();
|
||||
}
|
||||
|
||||
/* Handler for 16 bit samples, filtered spline interpolated stereo output
|
||||
*/
|
||||
MIXER(stereo_16bit_spline_filter)
|
||||
{
|
||||
VAR_SPLINE_STEREO(int16);
|
||||
VAR_FILTER_STEREO;
|
||||
|
||||
LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
|
||||
LOOP { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
|
||||
|
||||
SAVE_FILTER_STEREO();
|
||||
}
|
||||
|
||||
#endif
|
840
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mixer.c
vendored
Normal file
840
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mixer.c
vendored
Normal file
|
@ -0,0 +1,840 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "common.h"
|
||||
#include "virtual.h"
|
||||
#include "mixer.h"
|
||||
#include "period.h"
|
||||
#include "player.h" /* for set_sample_end() */
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
#include "paula.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define FLAG_16_BITS 0x01
|
||||
#define FLAG_STEREO 0x02
|
||||
#define FLAG_FILTER 0x04
|
||||
#define FLAG_ACTIVE 0x10
|
||||
/* #define FLAG_SYNTH 0x20 */
|
||||
#define FIDX_FLAGMASK (FLAG_16_BITS | FLAG_STEREO | FLAG_FILTER)
|
||||
|
||||
#define DOWNMIX_SHIFT 12
|
||||
#define LIM8_HI 127
|
||||
#define LIM8_LO -128
|
||||
#define LIM16_HI 32767
|
||||
#define LIM16_LO -32768
|
||||
|
||||
#define MIX_FN(x) void libxmp_mix_##x(struct mixer_voice *, int *, int, int, int, int, int, int, int)
|
||||
|
||||
MIX_FN(mono_8bit_nearest);
|
||||
MIX_FN(mono_8bit_linear);
|
||||
MIX_FN(mono_16bit_nearest);
|
||||
MIX_FN(mono_16bit_linear);
|
||||
MIX_FN(stereo_8bit_nearest);
|
||||
MIX_FN(stereo_8bit_linear);
|
||||
MIX_FN(stereo_16bit_nearest);
|
||||
MIX_FN(stereo_16bit_linear);
|
||||
MIX_FN(mono_8bit_spline);
|
||||
MIX_FN(mono_16bit_spline);
|
||||
MIX_FN(stereo_8bit_spline);
|
||||
MIX_FN(stereo_16bit_spline);
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
MIX_FN(mono_8bit_linear_filter);
|
||||
MIX_FN(mono_16bit_linear_filter);
|
||||
MIX_FN(stereo_8bit_linear_filter);
|
||||
MIX_FN(stereo_16bit_linear_filter);
|
||||
MIX_FN(mono_8bit_spline_filter);
|
||||
MIX_FN(mono_16bit_spline_filter);
|
||||
MIX_FN(stereo_8bit_spline_filter);
|
||||
MIX_FN(stereo_16bit_spline_filter);
|
||||
#endif
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
MIX_FN(mono_a500);
|
||||
MIX_FN(mono_a500_filter);
|
||||
MIX_FN(stereo_a500);
|
||||
MIX_FN(stereo_a500_filter);
|
||||
#endif
|
||||
|
||||
/* Mixers array index:
|
||||
*
|
||||
* bit 0: 0=8 bit sample, 1=16 bit sample
|
||||
* bit 1: 0=mono output, 1=stereo output
|
||||
* bit 2: 0=unfiltered, 1=filtered
|
||||
*/
|
||||
|
||||
typedef void (*mixer_set[])(struct mixer_voice *, int *, int, int, int, int, int, int, int);
|
||||
|
||||
static mixer_set nearest_mixers = {
|
||||
libxmp_mix_mono_8bit_nearest,
|
||||
libxmp_mix_mono_16bit_nearest,
|
||||
libxmp_mix_stereo_8bit_nearest,
|
||||
libxmp_mix_stereo_16bit_nearest,
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
libxmp_mix_mono_8bit_nearest,
|
||||
libxmp_mix_mono_16bit_nearest,
|
||||
libxmp_mix_stereo_8bit_nearest,
|
||||
libxmp_mix_stereo_16bit_nearest,
|
||||
#endif
|
||||
};
|
||||
|
||||
static mixer_set linear_mixers = {
|
||||
libxmp_mix_mono_8bit_linear,
|
||||
libxmp_mix_mono_16bit_linear,
|
||||
libxmp_mix_stereo_8bit_linear,
|
||||
libxmp_mix_stereo_16bit_linear,
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
libxmp_mix_mono_8bit_linear_filter,
|
||||
libxmp_mix_mono_16bit_linear_filter,
|
||||
libxmp_mix_stereo_8bit_linear_filter,
|
||||
libxmp_mix_stereo_16bit_linear_filter
|
||||
#endif
|
||||
};
|
||||
|
||||
static mixer_set spline_mixers = {
|
||||
libxmp_mix_mono_8bit_spline,
|
||||
libxmp_mix_mono_16bit_spline,
|
||||
libxmp_mix_stereo_8bit_spline,
|
||||
libxmp_mix_stereo_16bit_spline,
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
libxmp_mix_mono_8bit_spline_filter,
|
||||
libxmp_mix_mono_16bit_spline_filter,
|
||||
libxmp_mix_stereo_8bit_spline_filter,
|
||||
libxmp_mix_stereo_16bit_spline_filter
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
static mixer_set a500_mixers = {
|
||||
libxmp_mix_mono_a500,
|
||||
NULL,
|
||||
libxmp_mix_stereo_a500,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static mixer_set a500led_mixers = {
|
||||
libxmp_mix_mono_a500_filter,
|
||||
NULL,
|
||||
libxmp_mix_stereo_a500_filter,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* Downmix 32bit samples to 8bit, signed or unsigned, mono or stereo output */
|
||||
static void downmix_int_8bit(char *dest, int32 *src, int num, int amp, int offs)
|
||||
{
|
||||
int smp;
|
||||
int shift = DOWNMIX_SHIFT + 8 - amp;
|
||||
|
||||
for (; num--; src++, dest++) {
|
||||
smp = *src >> shift;
|
||||
if (smp > LIM8_HI) {
|
||||
*dest = LIM8_HI;
|
||||
} else if (smp < LIM8_LO) {
|
||||
*dest = LIM8_LO;
|
||||
} else {
|
||||
*dest = smp;
|
||||
}
|
||||
|
||||
if (offs) *dest += offs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Downmix 32bit samples to 16bit, signed or unsigned, mono or stereo output */
|
||||
static void downmix_int_16bit(int16 *dest, int32 *src, int num, int amp, int offs)
|
||||
{
|
||||
int smp;
|
||||
int shift = DOWNMIX_SHIFT - amp;
|
||||
|
||||
for (; num--; src++, dest++) {
|
||||
smp = *src >> shift;
|
||||
if (smp > LIM16_HI) {
|
||||
*dest = LIM16_HI;
|
||||
} else if (smp < LIM16_LO) {
|
||||
*dest = LIM16_LO;
|
||||
} else {
|
||||
*dest = smp;
|
||||
}
|
||||
|
||||
if (offs) *dest += offs;
|
||||
}
|
||||
}
|
||||
|
||||
static void anticlick(struct mixer_voice *vi)
|
||||
{
|
||||
vi->flags |= ANTICLICK;
|
||||
vi->old_vl = 0;
|
||||
vi->old_vr = 0;
|
||||
}
|
||||
|
||||
/* Ok, it's messy, but it works :-) Hipolito */
|
||||
static void do_anticlick(struct context_data *ctx, int voc, int32 *buf, int count)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_data *s = &ctx->s;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
int smp_l, smp_r, max_x2;
|
||||
int discharge = s->ticksize >> ANTICLICK_SHIFT;
|
||||
|
||||
smp_r = vi->sright;
|
||||
smp_l = vi->sleft;
|
||||
vi->sright = vi->sleft = 0;
|
||||
|
||||
if (smp_l == 0 && smp_r == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf == NULL) {
|
||||
buf = s->buf32;
|
||||
count = discharge;
|
||||
} else if (count > discharge) {
|
||||
count = discharge;
|
||||
}
|
||||
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
max_x2 = count * count;
|
||||
|
||||
while (count--) {
|
||||
if (~s->format & XMP_FORMAT_MONO) {
|
||||
*buf++ += (count * (smp_r >> 10) / max_x2 * count) << 10;
|
||||
}
|
||||
|
||||
*buf++ += (count * (smp_l >> 10) / max_x2 * count) << 10;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_sample_end(struct context_data *ctx, int voc, int end)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
struct channel_data *xc;
|
||||
|
||||
if ((uint32)voc >= p->virt.maxvoc)
|
||||
return;
|
||||
|
||||
xc = &p->xc_data[vi->chn];
|
||||
|
||||
if (end) {
|
||||
SET_NOTE(NOTE_SAMPLE_END);
|
||||
if (HAS_QUIRK(QUIRK_RSTCHN)) {
|
||||
libxmp_virt_resetvoice(ctx, voc, 0);
|
||||
}
|
||||
} else {
|
||||
RESET_NOTE(NOTE_SAMPLE_END);
|
||||
}
|
||||
}
|
||||
|
||||
static void adjust_voice_end(struct mixer_voice *vi, struct xmp_sample *xxs)
|
||||
{
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP) {
|
||||
if ((xxs->flg & XMP_SAMPLE_LOOP_FULL) && (~vi->flags & SAMPLE_LOOP)) {
|
||||
vi->end = xxs->len;
|
||||
} else {
|
||||
vi->end = xxs->lpe;
|
||||
}
|
||||
} else {
|
||||
vi->end = xxs->len;
|
||||
}
|
||||
}
|
||||
|
||||
static void loop_reposition(struct context_data *ctx, struct mixer_voice *vi, struct xmp_sample *xxs)
|
||||
{
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
struct module_data *m = &ctx->m;
|
||||
#endif
|
||||
int loop_size = xxs->lpe - xxs->lps;
|
||||
|
||||
/* Reposition for next loop */
|
||||
vi->pos -= loop_size; /* forward loop */
|
||||
vi->end = xxs->lpe;
|
||||
vi->flags |= SAMPLE_LOOP;
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
vi->end += loop_size; /* unrolled loop */
|
||||
vi->pos -= loop_size; /* forward loop */
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
/* OpenMPT Bidi-Loops.it: "In Impulse Tracker’s software mixer,
|
||||
* ping-pong loops are shortened by one sample.
|
||||
*/
|
||||
if (IS_PLAYER_MODE_IT()) {
|
||||
vi->end--;
|
||||
vi->pos++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Prepare the mixer for the next tick */
|
||||
void libxmp_mixer_prepare(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct mixer_data *s = &ctx->s;
|
||||
int bytelen;
|
||||
|
||||
s->ticksize = s->freq * m->time_factor * m->rrate / p->bpm / 1000;
|
||||
|
||||
bytelen = s->ticksize * sizeof(int);
|
||||
if (~s->format & XMP_FORMAT_MONO) {
|
||||
bytelen *= 2;
|
||||
}
|
||||
memset(s->buf32, 0, bytelen);
|
||||
}
|
||||
/* Fill the output buffer calling one of the handlers. The buffer contains
|
||||
* sound for one tick (a PAL frame or 1/50s for standard vblank-timed mods)
|
||||
*/
|
||||
void libxmp_mixer_softmixer(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_data *s = &ctx->s;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct xmp_sample *xxs;
|
||||
struct mixer_voice *vi;
|
||||
double step;
|
||||
int samples, size;
|
||||
int vol_l, vol_r, voc, usmp;
|
||||
int prev_l, prev_r = 0;
|
||||
int lps, lpe;
|
||||
int32 *buf_pos;
|
||||
void (*mix_fn)(struct mixer_voice *, int *, int, int, int, int, int, int, int);
|
||||
mixer_set *mixers;
|
||||
|
||||
switch (s->interp) {
|
||||
case XMP_INTERP_NEAREST:
|
||||
mixers = &nearest_mixers;
|
||||
break;
|
||||
case XMP_INTERP_LINEAR:
|
||||
mixers = &linear_mixers;
|
||||
break;
|
||||
case XMP_INTERP_SPLINE:
|
||||
mixers = &spline_mixers;
|
||||
break;
|
||||
default:
|
||||
mixers = &linear_mixers;
|
||||
}
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
if (p->flags & XMP_FLAGS_A500) {
|
||||
if (IS_AMIGA_MOD()) {
|
||||
if (p->filter) {
|
||||
mixers = &a500led_mixers;
|
||||
} else {
|
||||
mixers = &a500_mixers;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
libxmp_mixer_prepare(ctx);
|
||||
|
||||
for (voc = 0; voc < p->virt.maxvoc; voc++) {
|
||||
int c5spd;
|
||||
|
||||
vi = &p->virt.voice_array[voc];
|
||||
|
||||
if (vi->flags & ANTICLICK) {
|
||||
if (s->interp > XMP_INTERP_NEAREST) {
|
||||
do_anticlick(ctx, voc, NULL, 0);
|
||||
}
|
||||
vi->flags &= ~ANTICLICK;
|
||||
}
|
||||
|
||||
if (vi->chn < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vi->period < 1) {
|
||||
libxmp_virt_resetvoice(ctx, voc, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
vi->pos0 = vi->pos;
|
||||
|
||||
buf_pos = s->buf32;
|
||||
if (vi->pan == PAN_SURROUND) {
|
||||
vol_r = vi->vol * 0x80;
|
||||
vol_l = -vi->vol * 0x80;
|
||||
} else {
|
||||
vol_r = vi->vol * (0x80 - vi->pan);
|
||||
vol_l = vi->vol * (0x80 + vi->pan);
|
||||
}
|
||||
|
||||
if (vi->smp < mod->smp) {
|
||||
xxs = &mod->xxs[vi->smp];
|
||||
c5spd = m->xtra[vi->smp].c5spd;
|
||||
} else {
|
||||
xxs = &ctx->smix.xxs[vi->smp - mod->smp];
|
||||
c5spd = m->c4rate;
|
||||
}
|
||||
|
||||
step = C4_PERIOD * c5spd / s->freq / vi->period;
|
||||
|
||||
if (step < 0.001) { /* otherwise m5v-nwlf.it crashes */
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
if (xxs->flg & XMP_SAMPLE_SLOOP && vi->smp < mod->smp) {
|
||||
if (~vi->flags & VOICE_RELEASE) {
|
||||
if (vi->pos < m->xsmp[vi->smp].lpe) {
|
||||
xxs = &m->xsmp[vi->smp];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adjust_voice_end(vi, xxs);
|
||||
#endif
|
||||
|
||||
lps = xxs->lps;
|
||||
lpe = xxs->lpe;
|
||||
|
||||
if (p->flags & XMP_FLAGS_FIXLOOP) {
|
||||
lps >>= 1;
|
||||
}
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
vi->end += lpe - lps;
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
if (IS_PLAYER_MODE_IT()) {
|
||||
vi->end--;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int rampsize = s->ticksize >> ANTICLICK_SHIFT;
|
||||
int delta_l = (vol_l - vi->old_vl) / rampsize;
|
||||
int delta_r = (vol_r - vi->old_vr) / rampsize;
|
||||
|
||||
usmp = 0;
|
||||
for (size = s->ticksize; size > 0; ) {
|
||||
int split_noloop = 0;
|
||||
|
||||
if (p->xc_data[vi->chn].split) {
|
||||
split_noloop = 1;
|
||||
}
|
||||
|
||||
/* How many samples we can write before the loop break
|
||||
* or sample end... */
|
||||
if (vi->pos >= vi->end) {
|
||||
samples = 0;
|
||||
usmp = 1;
|
||||
} else {
|
||||
int s = ceil(((double)vi->end - vi->pos) / step);
|
||||
/* ...inside the tick boundaries */
|
||||
if (s > size) {
|
||||
s = size;
|
||||
}
|
||||
|
||||
samples = s;
|
||||
if (samples > 0) {
|
||||
usmp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (vi->vol) {
|
||||
int mix_size = samples;
|
||||
int mixer = vi->fidx & FIDX_FLAGMASK;
|
||||
|
||||
if (~s->format & XMP_FORMAT_MONO) {
|
||||
mix_size *= 2;
|
||||
}
|
||||
|
||||
/* For Hipolito's anticlick routine */
|
||||
if (samples > 0) {
|
||||
if (~s->format & XMP_FORMAT_MONO) {
|
||||
prev_r = buf_pos[mix_size - 2];
|
||||
}
|
||||
prev_l = buf_pos[mix_size - 1];
|
||||
} else {
|
||||
prev_r = prev_l = 0;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
/* See OpenMPT env-flt-max.it */
|
||||
if (vi->filter.cutoff >= 0xfe &&
|
||||
vi->filter.resonance == 0) {
|
||||
mixer &= ~FLAG_FILTER;
|
||||
}
|
||||
#endif
|
||||
|
||||
mix_fn = (*mixers)[mixer];
|
||||
|
||||
/* Call the output handler */
|
||||
if (samples > 0 && vi->sptr != NULL) {
|
||||
int rsize = 0;
|
||||
|
||||
if (rampsize > samples) {
|
||||
rampsize -= samples;
|
||||
} else {
|
||||
rsize = samples - rampsize;
|
||||
rampsize = 0;
|
||||
}
|
||||
|
||||
if (delta_l == 0 && delta_r == 0) {
|
||||
/* no need to ramp */
|
||||
rsize = samples;
|
||||
}
|
||||
|
||||
if (mix_fn != NULL) {
|
||||
mix_fn(vi, buf_pos, samples,
|
||||
vol_l >> 8, vol_r >> 8, step * (1 << SMIX_SHIFT), rsize, delta_l, delta_r);
|
||||
}
|
||||
|
||||
buf_pos += mix_size;
|
||||
vi->old_vl += samples * delta_l;
|
||||
vi->old_vr += samples * delta_r;
|
||||
|
||||
|
||||
/* For Hipolito's anticlick routine */
|
||||
if (~s->format & XMP_FORMAT_MONO) {
|
||||
vi->sright = buf_pos[-2] - prev_r;
|
||||
}
|
||||
vi->sleft = buf_pos[-1] - prev_l;
|
||||
}
|
||||
}
|
||||
|
||||
vi->pos += step * samples;
|
||||
|
||||
/* No more samples in this tick */
|
||||
size -= samples + usmp;
|
||||
if (size <= 0) {
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP) {
|
||||
if (vi->pos + step > vi->end) {
|
||||
vi->pos += step;
|
||||
loop_reposition(ctx, vi, xxs);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* First sample loop run */
|
||||
if ((~xxs->flg & XMP_SAMPLE_LOOP) || split_noloop) {
|
||||
do_anticlick(ctx, voc, buf_pos, size);
|
||||
set_sample_end(ctx, voc, 1);
|
||||
size = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
loop_reposition(ctx, vi, xxs);
|
||||
}
|
||||
|
||||
vi->old_vl = vol_l;
|
||||
vi->old_vr = vol_r;
|
||||
}
|
||||
|
||||
/* Render final frame */
|
||||
|
||||
size = s->ticksize;
|
||||
if (~s->format & XMP_FORMAT_MONO) {
|
||||
size *= 2;
|
||||
}
|
||||
|
||||
if (size > XMP_MAX_FRAMESIZE) {
|
||||
size = XMP_MAX_FRAMESIZE;
|
||||
}
|
||||
|
||||
if (s->format & XMP_FORMAT_8BIT) {
|
||||
downmix_int_8bit(s->buffer, s->buf32, size, s->amplify,
|
||||
s->format & XMP_FORMAT_UNSIGNED ? 0x80 : 0);
|
||||
} else {
|
||||
downmix_int_16bit((int16 *)s->buffer, s->buf32, size,s->amplify,
|
||||
s->format & XMP_FORMAT_UNSIGNED ? 0x8000 : 0);
|
||||
}
|
||||
|
||||
s->dtright = s->dtleft = 0;
|
||||
}
|
||||
|
||||
void libxmp_mixer_voicepos(struct context_data *ctx, int voc, double pos, int ac)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
struct xmp_sample *xxs;
|
||||
int lps;
|
||||
|
||||
if (vi->smp < m->mod.smp) {
|
||||
xxs = &m->mod.xxs[vi->smp];
|
||||
} else {
|
||||
xxs = &ctx->smix.xxs[vi->smp - m->mod.smp];
|
||||
}
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_SYNTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
vi->pos = pos;
|
||||
|
||||
adjust_voice_end(vi, xxs);
|
||||
|
||||
if (vi->pos >= vi->end) {
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP) {
|
||||
vi->pos = xxs->lps;
|
||||
} else {
|
||||
vi->pos = xxs->len;
|
||||
}
|
||||
}
|
||||
|
||||
lps = xxs->lps;
|
||||
if (p->flags & XMP_FLAGS_FIXLOOP) {
|
||||
lps >>= 1;
|
||||
}
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
vi->end += (xxs->lpe - lps);
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
if (IS_PLAYER_MODE_IT()) {
|
||||
vi->end--;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ac) {
|
||||
anticlick(vi);
|
||||
}
|
||||
}
|
||||
|
||||
double libxmp_mixer_getvoicepos(struct context_data *ctx, int voc)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
struct xmp_sample *xxs;
|
||||
|
||||
xxs = libxmp_get_sample(ctx, vi->smp);
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_SYNTH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
|
||||
if (vi->pos >= xxs->lpe) {
|
||||
return xxs->lpe - (vi->pos - xxs->lpe) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return vi->pos;
|
||||
}
|
||||
|
||||
void libxmp_mixer_setpatch(struct context_data *ctx, int voc, int smp, int ac)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
struct module_data *m = &ctx->m;
|
||||
#endif
|
||||
struct mixer_data *s = &ctx->s;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
struct xmp_sample *xxs;
|
||||
|
||||
xxs = libxmp_get_sample(ctx, smp);
|
||||
|
||||
vi->smp = smp;
|
||||
vi->vol = 0;
|
||||
vi->pan = 0;
|
||||
vi->flags &= ~SAMPLE_LOOP;
|
||||
|
||||
vi->fidx = 0;
|
||||
|
||||
if (~s->format & XMP_FORMAT_MONO) {
|
||||
vi->fidx |= FLAG_STEREO;
|
||||
}
|
||||
|
||||
set_sample_end(ctx, voc, 0);
|
||||
|
||||
/*mixer_setvol(ctx, voc, 0);*/
|
||||
|
||||
vi->sptr = xxs->data;
|
||||
vi->fidx |= FLAG_ACTIVE;
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
if (HAS_QUIRK(QUIRK_FILTER) && s->dsp & XMP_DSP_LOWPASS) {
|
||||
vi->fidx |= FLAG_FILTER;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (xxs->flg & XMP_SAMPLE_16BIT) {
|
||||
vi->fidx |= FLAG_16_BITS;
|
||||
}
|
||||
|
||||
libxmp_mixer_voicepos(ctx, voc, 0, ac);
|
||||
}
|
||||
|
||||
void libxmp_mixer_setnote(struct context_data *ctx, int voc, int note)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
|
||||
/* FIXME: Workaround for crash on notes that are too high
|
||||
* see 6nations.it (+114 transposition on instrument 16)
|
||||
*/
|
||||
if (note > 149) {
|
||||
note = 149;
|
||||
}
|
||||
|
||||
vi->note = note;
|
||||
vi->period = libxmp_note_to_period_mix(note, 0);
|
||||
|
||||
anticlick(vi);
|
||||
}
|
||||
|
||||
void libxmp_mixer_setperiod(struct context_data *ctx, int voc, double period)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
|
||||
vi->period = period;
|
||||
}
|
||||
|
||||
void libxmp_mixer_setvol(struct context_data *ctx, int voc, int vol)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
|
||||
if (vol == 0) {
|
||||
anticlick(vi);
|
||||
}
|
||||
|
||||
vi->vol = vol;
|
||||
}
|
||||
|
||||
void libxmp_mixer_release(struct context_data *ctx, int voc, int rel)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
|
||||
if (rel) {
|
||||
vi->flags |= VOICE_RELEASE;
|
||||
} else {
|
||||
vi->flags &= ~VOICE_RELEASE;
|
||||
}
|
||||
}
|
||||
|
||||
void libxmp_mixer_seteffect(struct context_data *ctx, int voc, int type, int val)
|
||||
{
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
|
||||
switch (type) {
|
||||
case DSP_EFFECT_CUTOFF:
|
||||
vi->filter.cutoff = val;
|
||||
break;
|
||||
case DSP_EFFECT_RESONANCE:
|
||||
vi->filter.resonance = val;
|
||||
break;
|
||||
case DSP_EFFECT_FILTER_A0:
|
||||
vi->filter.a0 = val;
|
||||
break;
|
||||
case DSP_EFFECT_FILTER_B0:
|
||||
vi->filter.b0 = val;
|
||||
break;
|
||||
case DSP_EFFECT_FILTER_B1:
|
||||
vi->filter.b1 = val;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void libxmp_mixer_setpan(struct context_data *ctx, int voc, int pan)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
|
||||
vi->pan = pan;
|
||||
}
|
||||
|
||||
int libxmp_mixer_numvoices(struct context_data *ctx, int num)
|
||||
{
|
||||
struct mixer_data *s = &ctx->s;
|
||||
|
||||
if (num > s->numvoc || num < 0) {
|
||||
return s->numvoc;
|
||||
} else {
|
||||
return num;
|
||||
}
|
||||
}
|
||||
|
||||
int libxmp_mixer_on(struct context_data *ctx, int rate, int format, int c4rate)
|
||||
{
|
||||
struct mixer_data *s = &ctx->s;
|
||||
|
||||
s->buffer = calloc(2, XMP_MAX_FRAMESIZE);
|
||||
if (s->buffer == NULL)
|
||||
goto err;
|
||||
|
||||
s->buf32 = calloc(sizeof(int), XMP_MAX_FRAMESIZE);
|
||||
if (s->buf32 == NULL)
|
||||
goto err1;
|
||||
|
||||
s->freq = rate;
|
||||
s->format = format;
|
||||
s->amplify = DEFAULT_AMPLIFY;
|
||||
s->mix = DEFAULT_MIX;
|
||||
/* s->pbase = C4_PERIOD * c4rate / s->freq; */
|
||||
s->interp = XMP_INTERP_LINEAR; /* default interpolation type */
|
||||
s->dsp = XMP_DSP_LOWPASS; /* enable filters by default */
|
||||
/* s->numvoc = SMIX_NUMVOC; */
|
||||
s->dtright = s->dtleft = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
free(s->buffer);
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void libxmp_mixer_off(struct context_data *ctx)
|
||||
{
|
||||
struct mixer_data *s = &ctx->s;
|
||||
|
||||
free(s->buffer);
|
||||
free(s->buf32);
|
||||
s->buf32 = NULL;
|
||||
s->buffer = NULL;
|
||||
}
|
78
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mixer.h
vendored
Normal file
78
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/mixer.h
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
#ifndef LIBXMP_MIXER_H
|
||||
#define LIBXMP_MIXER_H
|
||||
|
||||
#define C4_PERIOD 428.0
|
||||
|
||||
#define SMIX_NUMVOC 128 /* default number of softmixer voices */
|
||||
#define SMIX_SHIFT 16
|
||||
#define SMIX_MASK 0xffff
|
||||
|
||||
#define FILTER_SHIFT 16
|
||||
#define ANTICLICK_SHIFT 3
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
#include "paula.h"
|
||||
#endif
|
||||
|
||||
#define MIXER(f) void libxmp_mix_##f(struct mixer_voice *vi, int *buffer, \
|
||||
int count, int vl, int vr, int step, int ramp, int delta_l, int delta_r)
|
||||
|
||||
struct mixer_voice {
|
||||
int chn; /* channel number */
|
||||
int root; /* */
|
||||
int note; /* */
|
||||
#define PAN_SURROUND 0x8000
|
||||
int pan; /* */
|
||||
int vol; /* */
|
||||
double period; /* current period */
|
||||
double pos; /* position in sample */
|
||||
int pos0; /* position in sample before mixing */
|
||||
int fidx; /* mixer function index */
|
||||
int ins; /* instrument number */
|
||||
int smp; /* sample number */
|
||||
int end; /* loop end */
|
||||
int act; /* nna info & status of voice */
|
||||
int old_vl; /* previous volume, left channel */
|
||||
int old_vr; /* previous volume, right channel */
|
||||
int sleft; /* last left sample output, in 32bit */
|
||||
int sright; /* last right sample output, in 32bit */
|
||||
#define VOICE_RELEASE (1 << 0)
|
||||
#define ANTICLICK (1 << 1)
|
||||
#define SAMPLE_LOOP (1 << 2)
|
||||
int flags; /* flags */
|
||||
void *sptr; /* sample pointer */
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
struct paula_state *paula; /* paula simulation state */
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
struct {
|
||||
int r1; /* filter variables */
|
||||
int r2;
|
||||
int l1;
|
||||
int l2;
|
||||
int a0;
|
||||
int b0;
|
||||
int b1;
|
||||
int cutoff;
|
||||
int resonance;
|
||||
} filter;
|
||||
#endif
|
||||
};
|
||||
|
||||
int libxmp_mixer_on (struct context_data *, int, int, int);
|
||||
void libxmp_mixer_off (struct context_data *);
|
||||
void libxmp_mixer_setvol (struct context_data *, int, int);
|
||||
void libxmp_mixer_seteffect (struct context_data *, int, int, int);
|
||||
void libxmp_mixer_setpan (struct context_data *, int, int);
|
||||
int libxmp_mixer_numvoices (struct context_data *, int);
|
||||
void libxmp_mixer_softmixer (struct context_data *);
|
||||
void libxmp_mixer_reset (struct context_data *);
|
||||
void libxmp_mixer_setpatch (struct context_data *, int, int, int);
|
||||
void libxmp_mixer_voicepos (struct context_data *, int, double, int);
|
||||
double libxmp_mixer_getvoicepos(struct context_data *, int);
|
||||
void libxmp_mixer_setnote (struct context_data *, int, int);
|
||||
void libxmp_mixer_setperiod (struct context_data *, int, double);
|
||||
void libxmp_mixer_release (struct context_data *, int, int);
|
||||
|
||||
#endif /* LIBXMP_MIXER_H */
|
264
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/period.c
vendored
Normal file
264
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/period.c
vendored
Normal file
|
@ -0,0 +1,264 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "period.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.693147180559945309417
|
||||
#endif
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
/*
|
||||
* Period table from the Protracker V2.1A play routine
|
||||
*/
|
||||
static uint16 pt_period_table[16][36] = {
|
||||
/* Tuning 0, Normal */
|
||||
{
|
||||
856,808,762,720,678,640,604,570,538,508,480,453,
|
||||
428,404,381,360,339,320,302,285,269,254,240,226,
|
||||
214,202,190,180,170,160,151,143,135,127,120,113
|
||||
},
|
||||
/* Tuning 1 */
|
||||
{
|
||||
850,802,757,715,674,637,601,567,535,505,477,450,
|
||||
425,401,379,357,337,318,300,284,268,253,239,225,
|
||||
213,201,189,179,169,159,150,142,134,126,119,113
|
||||
},
|
||||
/* Tuning 2 */
|
||||
{
|
||||
844,796,752,709,670,632,597,563,532,502,474,447,
|
||||
422,398,376,355,335,316,298,282,266,251,237,224,
|
||||
211,199,188,177,167,158,149,141,133,125,118,112
|
||||
},
|
||||
/* Tuning 3 */
|
||||
{
|
||||
838,791,746,704,665,628,592,559,528,498,470,444,
|
||||
419,395,373,352,332,314,296,280,264,249,235,222,
|
||||
209,198,187,176,166,157,148,140,132,125,118,111
|
||||
},
|
||||
/* Tuning 4 */
|
||||
{
|
||||
832,785,741,699,660,623,588,555,524,495,467,441,
|
||||
416,392,370,350,330,312,294,278,262,247,233,220,
|
||||
208,196,185,175,165,156,147,139,131,124,117,110
|
||||
},
|
||||
/* Tuning 5 */
|
||||
{
|
||||
826,779,736,694,655,619,584,551,520,491,463,437,
|
||||
413,390,368,347,328,309,292,276,260,245,232,219,
|
||||
206,195,184,174,164,155,146,138,130,123,116,109
|
||||
},
|
||||
/* Tuning 6 */
|
||||
{
|
||||
820,774,730,689,651,614,580,547,516,487,460,434,
|
||||
410,387,365,345,325,307,290,274,258,244,230,217,
|
||||
205,193,183,172,163,154,145,137,129,122,115,109
|
||||
},
|
||||
/* Tuning 7 */
|
||||
{
|
||||
814,768,725,684,646,610,575,543,513,484,457,431,
|
||||
407,384,363,342,323,305,288,272,256,242,228,216,
|
||||
204,192,181,171,161,152,144,136,128,121,114,108
|
||||
},
|
||||
/* Tuning -8 */
|
||||
{
|
||||
907,856,808,762,720,678,640,604,570,538,508,480,
|
||||
453,428,404,381,360,339,320,302,285,269,254,240,
|
||||
226,214,202,190,180,170,160,151,143,135,127,120
|
||||
},
|
||||
/* Tuning -7 */
|
||||
{
|
||||
900,850,802,757,715,675,636,601,567,535,505,477,
|
||||
450,425,401,379,357,337,318,300,284,268,253,238,
|
||||
225,212,200,189,179,169,159,150,142,134,126,119
|
||||
},
|
||||
/* Tuning -6 */
|
||||
{
|
||||
894,844,796,752,709,670,632,597,563,532,502,474,
|
||||
447,422,398,376,355,335,316,298,282,266,251,237,
|
||||
223,211,199,188,177,167,158,149,141,133,125,118
|
||||
},
|
||||
/* Tuning -5 */
|
||||
{
|
||||
887,838,791,746,704,665,628,592,559,528,498,470,
|
||||
444,419,395,373,352,332,314,296,280,264,249,235,
|
||||
222,209,198,187,176,166,157,148,140,132,125,118
|
||||
},
|
||||
/* Tuning -4 */
|
||||
{
|
||||
881,832,785,741,699,660,623,588,555,524,494,467,
|
||||
441,416,392,370,350,330,312,294,278,262,247,233,
|
||||
220,208,196,185,175,165,156,147,139,131,123,117
|
||||
},
|
||||
/* Tuning -3 */
|
||||
{
|
||||
875,826,779,736,694,655,619,584,551,520,491,463,
|
||||
437,413,390,368,347,328,309,292,276,260,245,232,
|
||||
219,206,195,184,174,164,155,146,138,130,123,116
|
||||
},
|
||||
/* Tuning -2 */
|
||||
{
|
||||
868,820,774,730,689,651,614,580,547,516,487,460,
|
||||
434,410,387,365,345,325,307,290,274,258,244,230,
|
||||
217,205,193,183,172,163,154,145,137,129,122,115
|
||||
},
|
||||
/* Tuning -1 */
|
||||
{
|
||||
862,814,768,725,684,646,610,575,543,513,484,457,
|
||||
431,407,384,363,342,323,305,288,272,256,242,228,
|
||||
216,203,192,181,171,161,152,144,136,128,121,114
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static inline double round(double val)
|
||||
{
|
||||
return floor(val + 0.5);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
/* Get period from note using Protracker tuning */
|
||||
static inline int libxmp_note_to_period_pt(int n, int f)
|
||||
{
|
||||
if (n < MIN_NOTE_MOD || n > MAX_NOTE_MOD) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
n -= 48;
|
||||
f >>= 4;
|
||||
if (f < -8 || f > 7) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (f < 0) {
|
||||
f += 16;
|
||||
}
|
||||
|
||||
return (int)pt_period_table[f][n];
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get period from note */
|
||||
double libxmp_note_to_period(struct context_data *ctx, int n, int f, double adj)
|
||||
{
|
||||
double d, per;
|
||||
struct module_data *m = &ctx->m;
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
struct player_data *p = &ctx->p;
|
||||
|
||||
/* If mod replayer, modrng and Amiga mixing are active */
|
||||
if (p->flags & XMP_FLAGS_A500) {
|
||||
if (IS_AMIGA_MOD()) {
|
||||
return libxmp_note_to_period_pt(n, f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
d = (double)n + (double)f / 128;
|
||||
|
||||
switch (m->period_type) {
|
||||
case PERIOD_LINEAR:
|
||||
per = (240.0 - d) * 16; /* Linear */
|
||||
break;
|
||||
case PERIOD_CSPD:
|
||||
per = 8363.0 * pow(2, n / 12) / 32 + f; /* Hz */
|
||||
break;
|
||||
default:
|
||||
per = PERIOD_BASE / pow(2, d / 12); /* Amiga */
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (adj > 0.1) {
|
||||
per *= adj;
|
||||
}
|
||||
#endif
|
||||
|
||||
return per;
|
||||
}
|
||||
|
||||
/* For the software mixer */
|
||||
double libxmp_note_to_period_mix(int n, int b)
|
||||
{
|
||||
double d = (double)n + (double)b / 12800;
|
||||
return PERIOD_BASE / pow(2, d / 12);
|
||||
}
|
||||
|
||||
/* Get note from period */
|
||||
/* This function is used only by the MOD loader */
|
||||
int libxmp_period_to_note(int p)
|
||||
{
|
||||
if (p <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return round(12.0 * log(PERIOD_BASE / p) / M_LN2) + 1;
|
||||
}
|
||||
|
||||
/* Get pitchbend from base note and amiga period */
|
||||
int libxmp_period_to_bend(struct context_data *ctx, double p, int n, double adj)
|
||||
{
|
||||
struct module_data *m = &ctx->m;
|
||||
double d;
|
||||
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (m->period_type) {
|
||||
case PERIOD_LINEAR:
|
||||
return 100 * (8 * (((240 - n) << 4) - p));
|
||||
case PERIOD_CSPD:
|
||||
d = libxmp_note_to_period(ctx, n, 0, adj);
|
||||
return round(100.0 * (1536.0 / M_LN2) * log(p / d));
|
||||
default:
|
||||
/* Amiga */
|
||||
d = libxmp_note_to_period(ctx, n, 0, adj);
|
||||
return round(100.0 * (1536.0 / M_LN2) * log(d / p));
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert finetune = 1200 * log2(C2SPD/8363))
|
||||
*
|
||||
* c = (1200.0 * log(c2spd) - 1200.0 * log(c4_rate)) / M_LN2;
|
||||
* xpo = c/100;
|
||||
* fin = 128 * (c%100) / 100;
|
||||
*/
|
||||
void libxmp_c2spd_to_note(int c2spd, int *n, int *f)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (c2spd == 0) {
|
||||
*n = *f = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
c = (int)(1536.0 * log((double)c2spd / 8363) / M_LN2);
|
||||
*n = c / 128;
|
||||
*f = c % 128;
|
||||
}
|
24
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/period.h
vendored
Normal file
24
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/period.h
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef LIBXMP_PERIOD_H
|
||||
#define LIBXMP_PERIOD_H
|
||||
|
||||
#define PERIOD_BASE 13696.0 /* C0 period */
|
||||
|
||||
/* Macros for period conversion */
|
||||
#define NOTE_B0 11
|
||||
#define NOTE_Bb0 (NOTE_B0 + 1)
|
||||
#define MAX_NOTE (NOTE_B0 * 8)
|
||||
#define MAX_PERIOD 0x1c56
|
||||
#define MIN_PERIOD_A 0x0071
|
||||
#define MAX_PERIOD_A 0x0358
|
||||
#define MIN_PERIOD_L 0x0000
|
||||
#define MAX_PERIOD_L 0x1e00
|
||||
#define MIN_NOTE_MOD 48
|
||||
#define MAX_NOTE_MOD 83
|
||||
|
||||
double libxmp_note_to_period (struct context_data *, int, int, double);
|
||||
double libxmp_note_to_period_mix (int, int);
|
||||
int libxmp_period_to_note (int);
|
||||
int libxmp_period_to_bend (struct context_data *, double, int, double);
|
||||
void libxmp_c2spd_to_note (int, int *, int *);
|
||||
|
||||
#endif /* LIBXMP_PERIOD_H */
|
1899
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/player.c
vendored
Normal file
1899
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/player.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
258
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/player.h
vendored
Normal file
258
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/player.h
vendored
Normal file
|
@ -0,0 +1,258 @@
|
|||
#ifndef LIBXMP_PLAYER_H
|
||||
#define LIBXMP_PLAYER_H
|
||||
|
||||
#include "lfo.h"
|
||||
|
||||
/* Quirk control */
|
||||
#define HAS_QUIRK(x) (m->quirk & (x))
|
||||
|
||||
/* Channel flag control */
|
||||
#define SET(f) SET_FLAG(xc->flags,(f))
|
||||
#define RESET(f) RESET_FLAG(xc->flags,(f))
|
||||
#define TEST(f) TEST_FLAG(xc->flags,(f))
|
||||
|
||||
/* Persistent effect flag control */
|
||||
#define SET_PER(f) SET_FLAG(xc->per_flags,(f))
|
||||
#define RESET_PER(f) RESET_FLAG(xc->per_flags,(f))
|
||||
#define TEST_PER(f) TEST_FLAG(xc->per_flags,(f))
|
||||
|
||||
/* Note flag control */
|
||||
#define SET_NOTE(f) SET_FLAG(xc->note_flags,(f))
|
||||
#define RESET_NOTE(f) RESET_FLAG(xc->note_flags,(f))
|
||||
#define TEST_NOTE(f) TEST_FLAG(xc->note_flags,(f))
|
||||
|
||||
struct retrig_control {
|
||||
int s;
|
||||
int m;
|
||||
int d;
|
||||
};
|
||||
|
||||
/* The following macros are used to set the flags for each channel */
|
||||
#define VOL_SLIDE (1 << 0)
|
||||
#define PAN_SLIDE (1 << 1)
|
||||
#define TONEPORTA (1 << 2)
|
||||
#define PITCHBEND (1 << 3)
|
||||
#define VIBRATO (1 << 4)
|
||||
#define TREMOLO (1 << 5)
|
||||
#define FINE_VOLS (1 << 6)
|
||||
#define FINE_BEND (1 << 7)
|
||||
#define OFFSET (1 << 8)
|
||||
#define TRK_VSLIDE (1 << 9)
|
||||
#define TRK_FVSLIDE (1 << 10)
|
||||
#define NEW_INS (1 << 11)
|
||||
#define NEW_VOL (1 << 12)
|
||||
#define VOL_SLIDE_2 (1 << 13)
|
||||
#define NOTE_SLIDE (1 << 14)
|
||||
#define FINE_NSLIDE (1 << 15)
|
||||
#define NEW_NOTE (1 << 16)
|
||||
#define FINE_TPORTA (1 << 17)
|
||||
#define RETRIG (1 << 18)
|
||||
#define PANBRELLO (1 << 19)
|
||||
#define GVOL_SLIDE (1 << 20)
|
||||
#define TEMPO_SLIDE (1 << 21)
|
||||
#define VENV_PAUSE (1 << 22)
|
||||
#define PENV_PAUSE (1 << 23)
|
||||
#define FENV_PAUSE (1 << 24)
|
||||
#define FINE_VOLS_2 (1 << 25)
|
||||
#define KEY_OFF (1 << 26) /* for IT release on envloop end */
|
||||
#define TREMOR (1 << 27) /* for XM tremor */
|
||||
|
||||
#define NOTE_FADEOUT (1 << 0)
|
||||
#define NOTE_RELEASE (1 << 1)
|
||||
#define NOTE_END (1 << 2)
|
||||
#define NOTE_CUT (1 << 3)
|
||||
#define NOTE_ENV_END (1 << 4)
|
||||
#define NOTE_SAMPLE_END (1 << 5)
|
||||
#define NOTE_SET (1 << 6) /* for IT portamento after keyoff */
|
||||
#define NOTE_SUSEXIT (1 << 7) /* for delayed note release */
|
||||
#define NOTE_KEY_CUT (1 << 8) /* note cut with XMP_KEY_CUT event */
|
||||
#define NOTE_GLISSANDO (1 << 9)
|
||||
|
||||
#define IS_VALID_INSTRUMENT(x) ((uint32)(x) < mod->ins && mod->xxi[(x)].nsm > 0)
|
||||
#define IS_VALID_INSTRUMENT_OR_SFX(x) (((uint32)(x) < mod->ins && mod->xxi[(x)].nsm > 0) || (smix->ins > 0 && (uint32)(x) < mod->ins + smix->ins))
|
||||
|
||||
struct instrument_vibrato {
|
||||
int phase;
|
||||
int sweep;
|
||||
};
|
||||
|
||||
struct channel_data {
|
||||
int flags; /* Channel flags */
|
||||
int per_flags; /* Persistent effect channel flags */
|
||||
int note_flags; /* Note release, fadeout or end */
|
||||
int note; /* Note number */
|
||||
int key; /* Key number */
|
||||
double period; /* Amiga or linear period */
|
||||
double per_adj; /* MED period/pitch adjustment factor hack */
|
||||
int finetune; /* Guess what */
|
||||
int ins; /* Instrument number */
|
||||
int old_ins; /* Last instruemnt */
|
||||
int smp; /* Sample number */
|
||||
int mastervol; /* Master vol -- for IT track vol effect */
|
||||
int delay; /* Note delay in frames */
|
||||
int keyoff; /* Key off counter */
|
||||
int fadeout; /* Current fadeout (release) value */
|
||||
int ins_fade; /* Instrument fadeout value */
|
||||
int volume; /* Current volume */
|
||||
int gvl; /* Global volume for instrument for IT */
|
||||
|
||||
int rvv; /* Random volume variation */
|
||||
int rpv; /* Random pan variation */
|
||||
|
||||
uint8 split; /* Split channel */
|
||||
uint8 pair; /* Split channel pair */
|
||||
|
||||
int v_idx; /* Volume envelope index */
|
||||
int p_idx; /* Pan envelope index */
|
||||
int f_idx; /* Freq envelope index */
|
||||
|
||||
int key_porta; /* Key number for portamento target
|
||||
* -- needed to handle IT portamento xpo */
|
||||
struct {
|
||||
struct lfo lfo;
|
||||
int memory;
|
||||
} vibrato;
|
||||
|
||||
struct {
|
||||
struct lfo lfo;
|
||||
int memory;
|
||||
} tremolo;
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
struct {
|
||||
struct lfo lfo;
|
||||
int memory;
|
||||
} panbrello;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
int8 val[16]; /* 16 for Smaksak MegaArps */
|
||||
int size;
|
||||
int count;
|
||||
int memory;
|
||||
} arpeggio;
|
||||
|
||||
struct {
|
||||
struct lfo lfo;
|
||||
int sweep;
|
||||
} insvib;
|
||||
|
||||
struct {
|
||||
int val;
|
||||
int val2; /* For fx9 bug emulation */
|
||||
int memory;
|
||||
} offset;
|
||||
|
||||
struct {
|
||||
int val; /* Retrig value */
|
||||
int count; /* Retrig counter */
|
||||
int type; /* Retrig type */
|
||||
} retrig;
|
||||
|
||||
struct {
|
||||
uint8 up,down; /* Tremor value */
|
||||
uint8 count; /* Tremor counter */
|
||||
uint8 memory; /* Tremor memory */
|
||||
} tremor;
|
||||
|
||||
struct {
|
||||
int slide; /* Volume slide value */
|
||||
int fslide; /* Fine volume slide value */
|
||||
int slide2; /* Volume slide value */
|
||||
int memory; /* Volume slide effect memory */
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
int fslide2;
|
||||
int memory2; /* Volume slide effect memory */
|
||||
#endif
|
||||
} vol;
|
||||
|
||||
struct {
|
||||
int up_memory; /* Fine volume slide up memory (XM) */
|
||||
int down_memory;/* Fine volume slide up memory (XM) */
|
||||
} fine_vol;
|
||||
|
||||
struct {
|
||||
int slide; /* Global volume slide value */
|
||||
int fslide; /* Fine global volume slide value */
|
||||
int memory; /* Global volume memory is saved per channel */
|
||||
} gvol;
|
||||
|
||||
struct {
|
||||
int slide; /* Track volume slide value */
|
||||
int fslide; /* Track fine volume slide value */
|
||||
int memory; /* Track volume slide effect memory */
|
||||
} trackvol;
|
||||
|
||||
struct {
|
||||
int slide; /* Frequency slide value */
|
||||
double fslide; /* Fine frequency slide value */
|
||||
int memory; /* Portamento effect memory */
|
||||
} freq;
|
||||
|
||||
struct {
|
||||
double target; /* Target period for tone portamento */
|
||||
int dir; /* Tone portamento up/down directionh */
|
||||
int slide; /* Delta for tone portamento */
|
||||
int memory; /* Tone portamento effect memory */
|
||||
} porta;
|
||||
|
||||
struct {
|
||||
int up_memory; /* FT2 has separate memories for these */
|
||||
int down_memory;/* cases (see Porta-LinkMem.xm) */
|
||||
} fine_porta;
|
||||
|
||||
struct {
|
||||
int val; /* Current pan value */
|
||||
int slide; /* Pan slide value */
|
||||
int fslide; /* Pan fine slide value */
|
||||
int memory; /* Pan slide effect memory */
|
||||
int surround; /* Surround channel flag */
|
||||
} pan;
|
||||
|
||||
struct {
|
||||
int speed;
|
||||
int count;
|
||||
int pos;
|
||||
} invloop;
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
struct {
|
||||
int slide; /* IT tempo slide */
|
||||
} tempo;
|
||||
|
||||
struct {
|
||||
int cutoff; /* IT filter cutoff frequency */
|
||||
int resonance; /* IT filter resonance */
|
||||
int envelope; /* IT filter envelope */
|
||||
} filter;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
struct {
|
||||
int slide; /* PTM note slide amount */
|
||||
int fslide; /* OKT fine note slide amount */
|
||||
int speed; /* PTM note slide speed */
|
||||
int count; /* PTM note slide counter */
|
||||
} noteslide;
|
||||
|
||||
void *extra;
|
||||
#endif
|
||||
|
||||
struct xmp_event delayed_event;
|
||||
int delayed_ins; /* IT save instrument emulation */
|
||||
|
||||
int info_period; /* Period */
|
||||
int info_pitchbend; /* Linear pitchbend */
|
||||
int info_position; /* Position before mixing */
|
||||
int info_finalvol; /* Final volume including envelopes */
|
||||
int info_finalpan; /* Final pan including envelopes */
|
||||
};
|
||||
|
||||
|
||||
void libxmp_process_fx (struct context_data *, struct channel_data *,
|
||||
int, struct xmp_event *, int);
|
||||
void libxmp_filter_setup (int, int, int, int*, int*, int *);
|
||||
int libxmp_read_event (struct context_data *, struct xmp_event *, int);
|
||||
|
||||
#endif /* LIBXMP_PLAYER_H */
|
524
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/precomp_lut.h
vendored
Normal file
524
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/precomp_lut.h
vendored
Normal file
|
@ -0,0 +1,524 @@
|
|||
static int16 cubic_spline_lut0[1024] = {
|
||||
0, -8, -16, -24, -32, -40, -47, -55,
|
||||
-63, -71, -78, -86, -94, -101, -109, -117,
|
||||
-124, -132, -139, -146, -154, -161, -169, -176,
|
||||
-183, -190, -198, -205, -212, -219, -226, -233,
|
||||
-240, -247, -254, -261, -268, -275, -282, -289,
|
||||
-295, -302, -309, -316, -322, -329, -336, -342,
|
||||
-349, -355, -362, -368, -375, -381, -388, -394,
|
||||
-400, -407, -413, -419, -425, -432, -438, -444,
|
||||
-450, -456, -462, -468, -474, -480, -486, -492,
|
||||
-498, -504, -510, -515, -521, -527, -533, -538,
|
||||
-544, -550, -555, -561, -566, -572, -577, -583,
|
||||
-588, -594, -599, -604, -610, -615, -620, -626,
|
||||
-631, -636, -641, -646, -651, -656, -662, -667,
|
||||
-672, -677, -682, -686, -691, -696, -701, -706,
|
||||
-711, -715, -720, -725, -730, -734, -739, -744,
|
||||
-748, -753, -757, -762, -766, -771, -775, -780,
|
||||
-784, -788, -793, -797, -801, -806, -810, -814,
|
||||
-818, -822, -826, -831, -835, -839, -843, -847,
|
||||
-851, -855, -859, -863, -866, -870, -874, -878,
|
||||
-882, -886, -889, -893, -897, -900, -904, -908,
|
||||
-911, -915, -918, -922, -925, -929, -932, -936,
|
||||
-939, -943, -946, -949, -953, -956, -959, -962,
|
||||
-966, -969, -972, -975, -978, -981, -984, -987,
|
||||
-991, -994, -997, -999, -1002, -1005, -1008, -1011,
|
||||
-1014, -1017, -1020, -1022, -1025, -1028, -1031, -1033,
|
||||
-1036, -1039, -1041, -1044, -1047, -1049, -1052, -1054,
|
||||
-1057, -1059, -1062, -1064, -1066, -1069, -1071, -1074,
|
||||
-1076, -1078, -1080, -1083, -1085, -1087, -1089, -1092,
|
||||
-1094, -1096, -1098, -1100, -1102, -1104, -1106, -1108,
|
||||
-1110, -1112, -1114, -1116, -1118, -1120, -1122, -1124,
|
||||
-1125, -1127, -1129, -1131, -1133, -1134, -1136, -1138,
|
||||
-1139, -1141, -1143, -1144, -1146, -1147, -1149, -1150,
|
||||
-1152, -1153, -1155, -1156, -1158, -1159, -1161, -1162,
|
||||
-1163, -1165, -1166, -1167, -1169, -1170, -1171, -1172,
|
||||
-1174, -1175, -1176, -1177, -1178, -1179, -1180, -1181,
|
||||
-1182, -1184, -1185, -1186, -1187, -1187, -1188, -1189,
|
||||
-1190, -1191, -1192, -1193, -1194, -1195, -1195, -1196,
|
||||
-1197, -1198, -1198, -1199, -1200, -1200, -1201, -1202,
|
||||
-1202, -1203, -1204, -1204, -1205, -1205, -1206, -1206,
|
||||
-1207, -1207, -1208, -1208, -1208, -1209, -1209, -1210,
|
||||
-1210, -1210, -1211, -1211, -1211, -1212, -1212, -1212,
|
||||
-1212, -1212, -1213, -1213, -1213, -1213, -1213, -1213,
|
||||
-1213, -1213, -1214, -1214, -1214, -1214, -1214, -1214,
|
||||
-1214, -1214, -1213, -1213, -1213, -1213, -1213, -1213,
|
||||
-1213, -1213, -1212, -1212, -1212, -1212, -1211, -1211,
|
||||
-1211, -1211, -1210, -1210, -1210, -1209, -1209, -1209,
|
||||
-1208, -1208, -1207, -1207, -1207, -1206, -1206, -1205,
|
||||
-1205, -1204, -1204, -1203, -1202, -1202, -1201, -1201,
|
||||
-1200, -1199, -1199, -1198, -1197, -1197, -1196, -1195,
|
||||
-1195, -1194, -1193, -1192, -1192, -1191, -1190, -1189,
|
||||
-1188, -1187, -1187, -1186, -1185, -1184, -1183, -1182,
|
||||
-1181, -1180, -1179, -1178, -1177, -1176, -1175, -1174,
|
||||
-1173, -1172, -1171, -1170, -1169, -1168, -1167, -1166,
|
||||
-1165, -1163, -1162, -1161, -1160, -1159, -1158, -1156,
|
||||
-1155, -1154, -1153, -1151, -1150, -1149, -1148, -1146,
|
||||
-1145, -1144, -1142, -1141, -1140, -1138, -1137, -1135,
|
||||
-1134, -1133, -1131, -1130, -1128, -1127, -1125, -1124,
|
||||
-1122, -1121, -1119, -1118, -1116, -1115, -1113, -1112,
|
||||
-1110, -1109, -1107, -1105, -1104, -1102, -1101, -1099,
|
||||
-1097, -1096, -1094, -1092, -1091, -1089, -1087, -1085,
|
||||
-1084, -1082, -1080, -1079, -1077, -1075, -1073, -1071,
|
||||
-1070, -1068, -1066, -1064, -1062, -1061, -1059, -1057,
|
||||
-1055, -1053, -1051, -1049, -1047, -1046, -1044, -1042,
|
||||
-1040, -1038, -1036, -1034, -1032, -1030, -1028, -1026,
|
||||
-1024, -1022, -1020, -1018, -1016, -1014, -1012, -1010,
|
||||
-1008, -1006, -1004, -1002, -999, -997, -995, -993,
|
||||
-991, -989, -987, -985, -982, -980, -978, -976,
|
||||
-974, -972, -969, -967, -965, -963, -961, -958,
|
||||
-956, -954, -952, -950, -947, -945, -943, -941,
|
||||
-938, -936, -934, -931, -929, -927, -924, -922,
|
||||
-920, -918, -915, -913, -911, -908, -906, -903,
|
||||
-901, -899, -896, -894, -892, -889, -887, -884,
|
||||
-882, -880, -877, -875, -872, -870, -867, -865,
|
||||
-863, -860, -858, -855, -853, -850, -848, -845,
|
||||
-843, -840, -838, -835, -833, -830, -828, -825,
|
||||
-823, -820, -818, -815, -813, -810, -808, -805,
|
||||
-803, -800, -798, -795, -793, -790, -787, -785,
|
||||
-782, -780, -777, -775, -772, -769, -767, -764,
|
||||
-762, -759, -757, -754, -751, -749, -746, -744,
|
||||
-741, -738, -736, -733, -730, -728, -725, -723,
|
||||
-720, -717, -715, -712, -709, -707, -704, -702,
|
||||
-699, -696, -694, -691, -688, -686, -683, -680,
|
||||
-678, -675, -672, -670, -667, -665, -662, -659,
|
||||
-657, -654, -651, -649, -646, -643, -641, -638,
|
||||
-635, -633, -630, -627, -625, -622, -619, -617,
|
||||
-614, -611, -609, -606, -603, -601, -598, -595,
|
||||
-593, -590, -587, -585, -582, -579, -577, -574,
|
||||
-571, -569, -566, -563, -561, -558, -555, -553,
|
||||
-550, -547, -545, -542, -539, -537, -534, -531,
|
||||
-529, -526, -523, -521, -518, -516, -513, -510,
|
||||
-508, -505, -502, -500, -497, -495, -492, -489,
|
||||
-487, -484, -481, -479, -476, -474, -471, -468,
|
||||
-466, -463, -461, -458, -455, -453, -450, -448,
|
||||
-445, -442, -440, -437, -435, -432, -430, -427,
|
||||
-424, -422, -419, -417, -414, -412, -409, -407,
|
||||
-404, -402, -399, -397, -394, -392, -389, -387,
|
||||
-384, -382, -379, -377, -374, -372, -369, -367,
|
||||
-364, -362, -359, -357, -354, -352, -349, -347,
|
||||
-345, -342, -340, -337, -335, -332, -330, -328,
|
||||
-325, -323, -320, -318, -316, -313, -311, -309,
|
||||
-306, -304, -302, -299, -297, -295, -292, -290,
|
||||
-288, -285, -283, -281, -278, -276, -274, -272,
|
||||
-269, -267, -265, -263, -260, -258, -256, -254,
|
||||
-251, -249, -247, -245, -243, -240, -238, -236,
|
||||
-234, -232, -230, -228, -225, -223, -221, -219,
|
||||
-217, -215, -213, -211, -209, -207, -205, -202,
|
||||
-200, -198, -196, -194, -192, -190, -188, -186,
|
||||
-184, -182, -180, -178, -176, -175, -173, -171,
|
||||
-169, -167, -165, -163, -161, -159, -157, -156,
|
||||
-154, -152, -150, -148, -146, -145, -143, -141,
|
||||
-139, -137, -136, -134, -132, -130, -129, -127,
|
||||
-125, -124, -122, -120, -119, -117, -115, -114,
|
||||
-112, -110, -109, -107, -106, -104, -102, -101,
|
||||
-99, -98, -96, -95, -93, -92, -90, -89,
|
||||
-87, -86, -84, -83, -82, -80, -79, -77,
|
||||
-76, -75, -73, -72, -70, -69, -68, -67,
|
||||
-65, -64, -63, -61, -60, -59, -58, -57,
|
||||
-55, -54, -53, -52, -51, -49, -48, -47,
|
||||
-46, -45, -44, -43, -42, -41, -40, -39,
|
||||
-38, -37, -36, -35, -34, -33, -32, -31,
|
||||
-30, -29, -28, -27, -26, -26, -25, -24,
|
||||
-23, -22, -22, -21, -20, -19, -19, -18,
|
||||
-17, -16, -16, -15, -14, -14, -13, -13,
|
||||
-12, -11, -11, -10, -10, -9, -9, -8,
|
||||
-8, -7, -7, -6, -6, -6, -5, -5,
|
||||
-4, -4, -4, -3, -3, -3, -2, -2,
|
||||
-2, -2, -2, -1, -1, -1, -1, -1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static int16 cubic_spline_lut1[1024] = {
|
||||
16384, 16384, 16384, 16384, 16384, 16383, 16382, 16381,
|
||||
16381, 16381, 16380, 16379, 16379, 16377, 16377, 16376,
|
||||
16374, 16373, 16371, 16370, 16369, 16366, 16366, 16364,
|
||||
16361, 16360, 16358, 16357, 16354, 16351, 16349, 16347,
|
||||
16345, 16342, 16340, 16337, 16335, 16331, 16329, 16326,
|
||||
16322, 16320, 16317, 16314, 16309, 16307, 16304, 16299,
|
||||
16297, 16293, 16290, 16285, 16282, 16278, 16274, 16269,
|
||||
16265, 16262, 16257, 16253, 16247, 16244, 16239, 16235,
|
||||
16230, 16225, 16220, 16216, 16211, 16206, 16201, 16196,
|
||||
16191, 16185, 16180, 16174, 16169, 16163, 16158, 16151,
|
||||
16146, 16140, 16133, 16128, 16122, 16116, 16109, 16104,
|
||||
16097, 16092, 16085, 16077, 16071, 16064, 16058, 16052,
|
||||
16044, 16038, 16030, 16023, 16015, 16009, 16002, 15995,
|
||||
15988, 15980, 15973, 15964, 15957, 15949, 15941, 15934,
|
||||
15926, 15918, 15910, 15903, 15894, 15886, 15877, 15870,
|
||||
15861, 15853, 15843, 15836, 15827, 15818, 15810, 15801,
|
||||
15792, 15783, 15774, 15765, 15756, 15747, 15738, 15729,
|
||||
15719, 15709, 15700, 15691, 15681, 15672, 15662, 15652,
|
||||
15642, 15633, 15623, 15613, 15602, 15592, 15582, 15572,
|
||||
15562, 15552, 15540, 15530, 15520, 15509, 15499, 15489,
|
||||
15478, 15467, 15456, 15446, 15433, 15423, 15412, 15401,
|
||||
15390, 15379, 15367, 15356, 15345, 15333, 15321, 15310,
|
||||
15299, 15287, 15276, 15264, 15252, 15240, 15228, 15216,
|
||||
15205, 15192, 15180, 15167, 15155, 15143, 15131, 15118,
|
||||
15106, 15094, 15081, 15067, 15056, 15043, 15031, 15017,
|
||||
15004, 14992, 14979, 14966, 14953, 14940, 14927, 14913,
|
||||
14900, 14887, 14874, 14860, 14846, 14833, 14819, 14806,
|
||||
14793, 14778, 14764, 14752, 14737, 14723, 14709, 14696,
|
||||
14681, 14668, 14653, 14638, 14625, 14610, 14595, 14582,
|
||||
14567, 14553, 14538, 14523, 14509, 14494, 14480, 14465,
|
||||
14450, 14435, 14420, 14406, 14391, 14376, 14361, 14346,
|
||||
14330, 14316, 14301, 14285, 14270, 14254, 14239, 14223,
|
||||
14208, 14192, 14177, 14161, 14146, 14130, 14115, 14099,
|
||||
14082, 14067, 14051, 14035, 14019, 14003, 13986, 13971,
|
||||
13955, 13939, 13923, 13906, 13890, 13873, 13857, 13840,
|
||||
13823, 13808, 13791, 13775, 13758, 13741, 13724, 13707,
|
||||
13691, 13673, 13657, 13641, 13623, 13607, 13589, 13572,
|
||||
13556, 13538, 13521, 13504, 13486, 13469, 13451, 13435,
|
||||
13417, 13399, 13383, 13365, 13347, 13330, 13312, 13294,
|
||||
13277, 13258, 13241, 13224, 13205, 13188, 13170, 13152,
|
||||
13134, 13116, 13098, 13080, 13062, 13044, 13026, 13008,
|
||||
12989, 12971, 12953, 12934, 12916, 12898, 12879, 12860,
|
||||
12842, 12823, 12806, 12787, 12768, 12750, 12731, 12712,
|
||||
12694, 12675, 12655, 12637, 12618, 12599, 12580, 12562,
|
||||
12542, 12524, 12504, 12485, 12466, 12448, 12427, 12408,
|
||||
12390, 12370, 12351, 12332, 12312, 12293, 12273, 12254,
|
||||
12235, 12215, 12195, 12176, 12157, 12137, 12118, 12097,
|
||||
12079, 12059, 12039, 12019, 11998, 11980, 11960, 11940,
|
||||
11920, 11900, 11880, 11860, 11839, 11821, 11801, 11780,
|
||||
11761, 11741, 11720, 11700, 11680, 11660, 11640, 11619,
|
||||
11599, 11578, 11559, 11538, 11518, 11498, 11477, 11457,
|
||||
11436, 11415, 11394, 11374, 11354, 11333, 11313, 11292,
|
||||
11272, 11251, 11231, 11209, 11189, 11168, 11148, 11127,
|
||||
11107, 11084, 11064, 11043, 11023, 11002, 10982, 10959,
|
||||
10939, 10918, 10898, 10876, 10856, 10834, 10814, 10792,
|
||||
10772, 10750, 10728, 10708, 10687, 10666, 10644, 10623,
|
||||
10602, 10581, 10560, 10538, 10517, 10496, 10474, 10453,
|
||||
10431, 10410, 10389, 10368, 10346, 10325, 10303, 10283,
|
||||
10260, 10239, 10217, 10196, 10175, 10152, 10132, 10110,
|
||||
10088, 10068, 10045, 10023, 10002, 9981, 9959, 9936,
|
||||
9915, 9893, 9872, 9851, 9829, 9806, 9784, 9763,
|
||||
9742, 9720, 9698, 9676, 9653, 9633, 9611, 9589,
|
||||
9567, 9545, 9523, 9501, 9479, 9458, 9436, 9414,
|
||||
9392, 9370, 9348, 9326, 9304, 9282, 9260, 9238,
|
||||
9216, 9194, 9172, 9150, 9128, 9106, 9084, 9062,
|
||||
9040, 9018, 8996, 8974, 8951, 8929, 8907, 8885,
|
||||
8863, 8841, 8819, 8797, 8775, 8752, 8730, 8708,
|
||||
8686, 8664, 8642, 8620, 8597, 8575, 8553, 8531,
|
||||
8509, 8487, 8464, 8442, 8420, 8398, 8376, 8353,
|
||||
8331, 8309, 8287, 8265, 8242, 8220, 8198, 8176,
|
||||
8154, 8131, 8109, 8087, 8065, 8042, 8020, 7998,
|
||||
7976, 7954, 7931, 7909, 7887, 7865, 7842, 7820,
|
||||
7798, 7776, 7754, 7731, 7709, 7687, 7665, 7643,
|
||||
7620, 7598, 7576, 7554, 7531, 7509, 7487, 7465,
|
||||
7443, 7421, 7398, 7376, 7354, 7332, 7310, 7288,
|
||||
7265, 7243, 7221, 7199, 7177, 7155, 7132, 7110,
|
||||
7088, 7066, 7044, 7022, 7000, 6978, 6956, 6934,
|
||||
6911, 6889, 6867, 6845, 6823, 6801, 6779, 6757,
|
||||
6735, 6713, 6691, 6669, 6647, 6625, 6603, 6581,
|
||||
6559, 6537, 6515, 6493, 6472, 6450, 6428, 6406,
|
||||
6384, 6362, 6340, 6318, 6297, 6275, 6253, 6231,
|
||||
6209, 6188, 6166, 6144, 6122, 6101, 6079, 6057,
|
||||
6035, 6014, 5992, 5970, 5949, 5927, 5905, 5884,
|
||||
5862, 5841, 5819, 5797, 5776, 5754, 5733, 5711,
|
||||
5690, 5668, 5647, 5625, 5604, 5582, 5561, 5540,
|
||||
5518, 5497, 5476, 5454, 5433, 5412, 5390, 5369,
|
||||
5348, 5327, 5305, 5284, 5263, 5242, 5221, 5199,
|
||||
5178, 5157, 5136, 5115, 5094, 5073, 5052, 5031,
|
||||
5010, 4989, 4968, 4947, 4926, 4905, 4885, 4864,
|
||||
4843, 4822, 4801, 4780, 4760, 4739, 4718, 4698,
|
||||
4677, 4656, 4636, 4615, 4595, 4574, 4553, 4533,
|
||||
4512, 4492, 4471, 4451, 4431, 4410, 4390, 4370,
|
||||
4349, 4329, 4309, 4288, 4268, 4248, 4228, 4208,
|
||||
4188, 4167, 4147, 4127, 4107, 4087, 4067, 4047,
|
||||
4027, 4007, 3988, 3968, 3948, 3928, 3908, 3889,
|
||||
3869, 3849, 3829, 3810, 3790, 3771, 3751, 3732,
|
||||
3712, 3693, 3673, 3654, 3634, 3615, 3595, 3576,
|
||||
3557, 3538, 3518, 3499, 3480, 3461, 3442, 3423,
|
||||
3404, 3385, 3366, 3347, 3328, 3309, 3290, 3271,
|
||||
3252, 3233, 3215, 3196, 3177, 3159, 3140, 3121,
|
||||
3103, 3084, 3066, 3047, 3029, 3010, 2992, 2974,
|
||||
2955, 2937, 2919, 2901, 2882, 2864, 2846, 2828,
|
||||
2810, 2792, 2774, 2756, 2738, 2720, 2702, 2685,
|
||||
2667, 2649, 2631, 2614, 2596, 2579, 2561, 2543,
|
||||
2526, 2509, 2491, 2474, 2456, 2439, 2422, 2405,
|
||||
2387, 2370, 2353, 2336, 2319, 2302, 2285, 2268,
|
||||
2251, 2234, 2218, 2201, 2184, 2167, 2151, 2134,
|
||||
2117, 2101, 2084, 2068, 2052, 2035, 2019, 2003,
|
||||
1986, 1970, 1954, 1938, 1922, 1906, 1890, 1874,
|
||||
1858, 1842, 1826, 1810, 1794, 1779, 1763, 1747,
|
||||
1732, 1716, 1701, 1685, 1670, 1654, 1639, 1624,
|
||||
1608, 1593, 1578, 1563, 1548, 1533, 1518, 1503,
|
||||
1488, 1473, 1458, 1444, 1429, 1414, 1400, 1385,
|
||||
1370, 1356, 1342, 1327, 1313, 1298, 1284, 1270,
|
||||
1256, 1242, 1228, 1214, 1200, 1186, 1172, 1158,
|
||||
1144, 1131, 1117, 1103, 1090, 1076, 1063, 1049,
|
||||
1036, 1022, 1009, 996, 983, 970, 956, 943,
|
||||
930, 917, 905, 892, 879, 866, 854, 841,
|
||||
828, 816, 803, 791, 778, 766, 754, 742,
|
||||
729, 717, 705, 693, 681, 669, 658, 646,
|
||||
634, 622, 611, 599, 588, 576, 565, 553,
|
||||
542, 531, 520, 508, 497, 486, 475, 464,
|
||||
453, 443, 432, 421, 411, 400, 389, 379,
|
||||
369, 358, 348, 338, 327, 317, 307, 297,
|
||||
287, 277, 268, 258, 248, 238, 229, 219,
|
||||
210, 200, 191, 182, 172, 163, 154, 145,
|
||||
136, 127, 118, 109, 100, 92, 83, 75,
|
||||
66, 58, 49, 41, 32, 24, 16, 8,
|
||||
};
|
||||
|
||||
static int16 cubic_spline_lut2[1024] = {
|
||||
0, 8, 16, 24, 32, 41, 49, 58,
|
||||
66, 75, 83, 92, 100, 109, 118, 127,
|
||||
136, 145, 154, 163, 172, 182, 191, 200,
|
||||
210, 219, 229, 238, 248, 258, 268, 277,
|
||||
287, 297, 307, 317, 327, 338, 348, 358,
|
||||
369, 379, 389, 400, 411, 421, 432, 443,
|
||||
453, 464, 475, 486, 497, 508, 520, 531,
|
||||
542, 553, 565, 576, 588, 599, 611, 622,
|
||||
634, 646, 658, 669, 681, 693, 705, 717,
|
||||
729, 742, 754, 766, 778, 791, 803, 816,
|
||||
828, 841, 854, 866, 879, 892, 905, 917,
|
||||
930, 943, 956, 970, 983, 996, 1009, 1022,
|
||||
1036, 1049, 1063, 1076, 1090, 1103, 1117, 1131,
|
||||
1144, 1158, 1172, 1186, 1200, 1214, 1228, 1242,
|
||||
1256, 1270, 1284, 1298, 1313, 1327, 1342, 1356,
|
||||
1370, 1385, 1400, 1414, 1429, 1444, 1458, 1473,
|
||||
1488, 1503, 1518, 1533, 1548, 1563, 1578, 1593,
|
||||
1608, 1624, 1639, 1654, 1670, 1685, 1701, 1716,
|
||||
1732, 1747, 1763, 1779, 1794, 1810, 1826, 1842,
|
||||
1858, 1874, 1890, 1906, 1922, 1938, 1954, 1970,
|
||||
1986, 2003, 2019, 2035, 2052, 2068, 2084, 2101,
|
||||
2117, 2134, 2151, 2167, 2184, 2201, 2218, 2234,
|
||||
2251, 2268, 2285, 2302, 2319, 2336, 2353, 2370,
|
||||
2387, 2405, 2422, 2439, 2456, 2474, 2491, 2509,
|
||||
2526, 2543, 2561, 2579, 2596, 2614, 2631, 2649,
|
||||
2667, 2685, 2702, 2720, 2738, 2756, 2774, 2792,
|
||||
2810, 2828, 2846, 2864, 2882, 2901, 2919, 2937,
|
||||
2955, 2974, 2992, 3010, 3029, 3047, 3066, 3084,
|
||||
3103, 3121, 3140, 3159, 3177, 3196, 3215, 3233,
|
||||
3252, 3271, 3290, 3309, 3328, 3347, 3366, 3385,
|
||||
3404, 3423, 3442, 3461, 3480, 3499, 3518, 3538,
|
||||
3557, 3576, 3595, 3615, 3634, 3654, 3673, 3693,
|
||||
3712, 3732, 3751, 3771, 3790, 3810, 3829, 3849,
|
||||
3869, 3889, 3908, 3928, 3948, 3968, 3988, 4007,
|
||||
4027, 4047, 4067, 4087, 4107, 4127, 4147, 4167,
|
||||
4188, 4208, 4228, 4248, 4268, 4288, 4309, 4329,
|
||||
4349, 4370, 4390, 4410, 4431, 4451, 4471, 4492,
|
||||
4512, 4533, 4553, 4574, 4595, 4615, 4636, 4656,
|
||||
4677, 4698, 4718, 4739, 4760, 4780, 4801, 4822,
|
||||
4843, 4864, 4885, 4905, 4926, 4947, 4968, 4989,
|
||||
5010, 5031, 5052, 5073, 5094, 5115, 5136, 5157,
|
||||
5178, 5199, 5221, 5242, 5263, 5284, 5305, 5327,
|
||||
5348, 5369, 5390, 5412, 5433, 5454, 5476, 5497,
|
||||
5518, 5540, 5561, 5582, 5604, 5625, 5647, 5668,
|
||||
5690, 5711, 5733, 5754, 5776, 5797, 5819, 5841,
|
||||
5862, 5884, 5905, 5927, 5949, 5970, 5992, 6014,
|
||||
6035, 6057, 6079, 6101, 6122, 6144, 6166, 6188,
|
||||
6209, 6231, 6253, 6275, 6297, 6318, 6340, 6362,
|
||||
6384, 6406, 6428, 6450, 6472, 6493, 6515, 6537,
|
||||
6559, 6581, 6603, 6625, 6647, 6669, 6691, 6713,
|
||||
6735, 6757, 6779, 6801, 6823, 6845, 6867, 6889,
|
||||
6911, 6934, 6956, 6978, 7000, 7022, 7044, 7066,
|
||||
7088, 7110, 7132, 7155, 7177, 7199, 7221, 7243,
|
||||
7265, 7288, 7310, 7332, 7354, 7376, 7398, 7421,
|
||||
7443, 7465, 7487, 7509, 7531, 7554, 7576, 7598,
|
||||
7620, 7643, 7665, 7687, 7709, 7731, 7754, 7776,
|
||||
7798, 7820, 7842, 7865, 7887, 7909, 7931, 7954,
|
||||
7976, 7998, 8020, 8042, 8065, 8087, 8109, 8131,
|
||||
8154, 8176, 8198, 8220, 8242, 8265, 8287, 8309,
|
||||
8331, 8353, 8376, 8398, 8420, 8442, 8464, 8487,
|
||||
8509, 8531, 8553, 8575, 8597, 8620, 8642, 8664,
|
||||
8686, 8708, 8730, 8752, 8775, 8797, 8819, 8841,
|
||||
8863, 8885, 8907, 8929, 8951, 8974, 8996, 9018,
|
||||
9040, 9062, 9084, 9106, 9128, 9150, 9172, 9194,
|
||||
9216, 9238, 9260, 9282, 9304, 9326, 9348, 9370,
|
||||
9392, 9414, 9436, 9458, 9479, 9501, 9523, 9545,
|
||||
9567, 9589, 9611, 9633, 9653, 9676, 9698, 9720,
|
||||
9742, 9763, 9784, 9806, 9829, 9851, 9872, 9893,
|
||||
9915, 9936, 9959, 9981, 10002, 10023, 10045, 10068,
|
||||
10088, 10110, 10132, 10152, 10175, 10196, 10217, 10239,
|
||||
10260, 10283, 10303, 10325, 10346, 10368, 10389, 10410,
|
||||
10431, 10453, 10474, 10496, 10517, 10538, 10560, 10581,
|
||||
10602, 10623, 10644, 10666, 10687, 10708, 10728, 10750,
|
||||
10772, 10792, 10814, 10834, 10856, 10876, 10898, 10918,
|
||||
10939, 10959, 10982, 11002, 11023, 11043, 11064, 11084,
|
||||
11107, 11127, 11148, 11168, 11189, 11209, 11231, 11251,
|
||||
11272, 11292, 11313, 11333, 11354, 11374, 11394, 11415,
|
||||
11436, 11457, 11477, 11498, 11518, 11538, 11559, 11578,
|
||||
11599, 11619, 11640, 11660, 11680, 11700, 11720, 11741,
|
||||
11761, 11780, 11801, 11821, 11839, 11860, 11880, 11900,
|
||||
11920, 11940, 11960, 11980, 11998, 12019, 12039, 12059,
|
||||
12079, 12097, 12118, 12137, 12157, 12176, 12195, 12215,
|
||||
12235, 12254, 12273, 12293, 12312, 12332, 12351, 12370,
|
||||
12390, 12408, 12427, 12448, 12466, 12485, 12504, 12524,
|
||||
12542, 12562, 12580, 12599, 12618, 12637, 12655, 12675,
|
||||
12694, 12712, 12731, 12750, 12768, 12787, 12806, 12823,
|
||||
12842, 12860, 12879, 12898, 12916, 12934, 12953, 12971,
|
||||
12989, 13008, 13026, 13044, 13062, 13080, 13098, 13116,
|
||||
13134, 13152, 13170, 13188, 13205, 13224, 13241, 13258,
|
||||
13277, 13294, 13312, 13330, 13347, 13365, 13383, 13399,
|
||||
13417, 13435, 13451, 13469, 13486, 13504, 13521, 13538,
|
||||
13556, 13572, 13589, 13607, 13623, 13641, 13657, 13673,
|
||||
13691, 13707, 13724, 13741, 13758, 13775, 13791, 13808,
|
||||
13823, 13840, 13857, 13873, 13890, 13906, 13923, 13939,
|
||||
13955, 13971, 13986, 14003, 14019, 14035, 14051, 14067,
|
||||
14082, 14099, 14115, 14130, 14146, 14161, 14177, 14192,
|
||||
14208, 14223, 14239, 14254, 14270, 14285, 14301, 14316,
|
||||
14330, 14346, 14361, 14376, 14391, 14406, 14420, 14435,
|
||||
14450, 14465, 14480, 14494, 14509, 14523, 14538, 14553,
|
||||
14567, 14582, 14595, 14610, 14625, 14638, 14653, 14668,
|
||||
14681, 14696, 14709, 14723, 14737, 14752, 14764, 14778,
|
||||
14793, 14806, 14819, 14833, 14846, 14860, 14874, 14887,
|
||||
14900, 14913, 14927, 14940, 14953, 14966, 14979, 14992,
|
||||
15004, 15017, 15031, 15043, 15056, 15067, 15081, 15094,
|
||||
15106, 15118, 15131, 15143, 15155, 15167, 15180, 15192,
|
||||
15205, 15216, 15228, 15240, 15252, 15264, 15276, 15287,
|
||||
15299, 15310, 15321, 15333, 15345, 15356, 15367, 15379,
|
||||
15390, 15401, 15412, 15423, 15433, 15446, 15456, 15467,
|
||||
15478, 15489, 15499, 15509, 15520, 15530, 15540, 15552,
|
||||
15562, 15572, 15582, 15592, 15602, 15613, 15623, 15633,
|
||||
15642, 15652, 15662, 15672, 15681, 15691, 15700, 15709,
|
||||
15719, 15729, 15738, 15747, 15756, 15765, 15774, 15783,
|
||||
15792, 15801, 15810, 15818, 15827, 15836, 15843, 15853,
|
||||
15861, 15870, 15877, 15886, 15894, 15903, 15910, 15918,
|
||||
15926, 15934, 15941, 15949, 15957, 15964, 15973, 15980,
|
||||
15988, 15995, 16002, 16009, 16015, 16023, 16030, 16038,
|
||||
16044, 16052, 16058, 16064, 16071, 16077, 16085, 16092,
|
||||
16097, 16104, 16109, 16116, 16122, 16128, 16133, 16140,
|
||||
16146, 16151, 16158, 16163, 16169, 16174, 16180, 16185,
|
||||
16191, 16196, 16201, 16206, 16211, 16216, 16220, 16225,
|
||||
16230, 16235, 16239, 16244, 16247, 16253, 16257, 16262,
|
||||
16265, 16269, 16274, 16278, 16282, 16285, 16290, 16293,
|
||||
16297, 16299, 16304, 16307, 16309, 16314, 16317, 16320,
|
||||
16322, 16326, 16329, 16331, 16335, 16337, 16340, 16342,
|
||||
16345, 16347, 16349, 16351, 16354, 16357, 16358, 16360,
|
||||
16361, 16364, 16366, 16366, 16369, 16370, 16371, 16373,
|
||||
16374, 16376, 16377, 16377, 16379, 16379, 16380, 16381,
|
||||
16381, 16381, 16382, 16383, 16384, 16384, 16384, 16384,
|
||||
};
|
||||
|
||||
static int16 cubic_spline_lut3[1024] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, -1, -1, -1, -1, -1, -2, -2,
|
||||
-2, -2, -2, -3, -3, -3, -4, -4,
|
||||
-4, -5, -5, -6, -6, -6, -7, -7,
|
||||
-8, -8, -9, -9, -10, -10, -11, -11,
|
||||
-12, -13, -13, -14, -14, -15, -16, -16,
|
||||
-17, -18, -19, -19, -20, -21, -22, -22,
|
||||
-23, -24, -25, -26, -26, -27, -28, -29,
|
||||
-30, -31, -32, -33, -34, -35, -36, -37,
|
||||
-38, -39, -40, -41, -42, -43, -44, -45,
|
||||
-46, -47, -48, -49, -51, -52, -53, -54,
|
||||
-55, -57, -58, -59, -60, -61, -63, -64,
|
||||
-65, -67, -68, -69, -70, -72, -73, -75,
|
||||
-76, -77, -79, -80, -82, -83, -84, -86,
|
||||
-87, -89, -90, -92, -93, -95, -96, -98,
|
||||
-99, -101, -102, -104, -106, -107, -109, -110,
|
||||
-112, -114, -115, -117, -119, -120, -122, -124,
|
||||
-125, -127, -129, -130, -132, -134, -136, -137,
|
||||
-139, -141, -143, -145, -146, -148, -150, -152,
|
||||
-154, -156, -157, -159, -161, -163, -165, -167,
|
||||
-169, -171, -173, -175, -176, -178, -180, -182,
|
||||
-184, -186, -188, -190, -192, -194, -196, -198,
|
||||
-200, -202, -205, -207, -209, -211, -213, -215,
|
||||
-217, -219, -221, -223, -225, -228, -230, -232,
|
||||
-234, -236, -238, -240, -243, -245, -247, -249,
|
||||
-251, -254, -256, -258, -260, -263, -265, -267,
|
||||
-269, -272, -274, -276, -278, -281, -283, -285,
|
||||
-288, -290, -292, -295, -297, -299, -302, -304,
|
||||
-306, -309, -311, -313, -316, -318, -320, -323,
|
||||
-325, -328, -330, -332, -335, -337, -340, -342,
|
||||
-345, -347, -349, -352, -354, -357, -359, -362,
|
||||
-364, -367, -369, -372, -374, -377, -379, -382,
|
||||
-384, -387, -389, -392, -394, -397, -399, -402,
|
||||
-404, -407, -409, -412, -414, -417, -419, -422,
|
||||
-424, -427, -430, -432, -435, -437, -440, -442,
|
||||
-445, -448, -450, -453, -455, -458, -461, -463,
|
||||
-466, -468, -471, -474, -476, -479, -481, -484,
|
||||
-487, -489, -492, -495, -497, -500, -502, -505,
|
||||
-508, -510, -513, -516, -518, -521, -523, -526,
|
||||
-529, -531, -534, -537, -539, -542, -545, -547,
|
||||
-550, -553, -555, -558, -561, -563, -566, -569,
|
||||
-571, -574, -577, -579, -582, -585, -587, -590,
|
||||
-593, -595, -598, -601, -603, -606, -609, -611,
|
||||
-614, -617, -619, -622, -625, -627, -630, -633,
|
||||
-635, -638, -641, -643, -646, -649, -651, -654,
|
||||
-657, -659, -662, -665, -667, -670, -672, -675,
|
||||
-678, -680, -683, -686, -688, -691, -694, -696,
|
||||
-699, -702, -704, -707, -709, -712, -715, -717,
|
||||
-720, -723, -725, -728, -730, -733, -736, -738,
|
||||
-741, -744, -746, -749, -751, -754, -757, -759,
|
||||
-762, -764, -767, -769, -772, -775, -777, -780,
|
||||
-782, -785, -787, -790, -793, -795, -798, -800,
|
||||
-803, -805, -808, -810, -813, -815, -818, -820,
|
||||
-823, -825, -828, -830, -833, -835, -838, -840,
|
||||
-843, -845, -848, -850, -853, -855, -858, -860,
|
||||
-863, -865, -867, -870, -872, -875, -877, -880,
|
||||
-882, -884, -887, -889, -892, -894, -896, -899,
|
||||
-901, -903, -906, -908, -911, -913, -915, -918,
|
||||
-920, -922, -924, -927, -929, -931, -934, -936,
|
||||
-938, -941, -943, -945, -947, -950, -952, -954,
|
||||
-956, -958, -961, -963, -965, -967, -969, -972,
|
||||
-974, -976, -978, -980, -982, -985, -987, -989,
|
||||
-991, -993, -995, -997, -999, -1002, -1004, -1006,
|
||||
-1008, -1010, -1012, -1014, -1016, -1018, -1020, -1022,
|
||||
-1024, -1026, -1028, -1030, -1032, -1034, -1036, -1038,
|
||||
-1040, -1042, -1044, -1046, -1047, -1049, -1051, -1053,
|
||||
-1055, -1057, -1059, -1061, -1062, -1064, -1066, -1068,
|
||||
-1070, -1071, -1073, -1075, -1077, -1079, -1080, -1082,
|
||||
-1084, -1085, -1087, -1089, -1091, -1092, -1094, -1096,
|
||||
-1097, -1099, -1101, -1102, -1104, -1105, -1107, -1109,
|
||||
-1110, -1112, -1113, -1115, -1116, -1118, -1119, -1121,
|
||||
-1122, -1124, -1125, -1127, -1128, -1130, -1131, -1133,
|
||||
-1134, -1135, -1137, -1138, -1140, -1141, -1142, -1144,
|
||||
-1145, -1146, -1148, -1149, -1150, -1151, -1153, -1154,
|
||||
-1155, -1156, -1158, -1159, -1160, -1161, -1162, -1163,
|
||||
-1165, -1166, -1167, -1168, -1169, -1170, -1171, -1172,
|
||||
-1173, -1174, -1175, -1176, -1177, -1178, -1179, -1180,
|
||||
-1181, -1182, -1183, -1184, -1185, -1186, -1187, -1187,
|
||||
-1188, -1189, -1190, -1191, -1192, -1192, -1193, -1194,
|
||||
-1195, -1195, -1196, -1197, -1197, -1198, -1199, -1199,
|
||||
-1200, -1201, -1201, -1202, -1202, -1203, -1204, -1204,
|
||||
-1205, -1205, -1206, -1206, -1207, -1207, -1207, -1208,
|
||||
-1208, -1209, -1209, -1209, -1210, -1210, -1210, -1211,
|
||||
-1211, -1211, -1211, -1212, -1212, -1212, -1212, -1213,
|
||||
-1213, -1213, -1213, -1213, -1213, -1213, -1213, -1214,
|
||||
-1214, -1214, -1214, -1214, -1214, -1214, -1214, -1213,
|
||||
-1213, -1213, -1213, -1213, -1213, -1213, -1213, -1212,
|
||||
-1212, -1212, -1212, -1212, -1211, -1211, -1211, -1210,
|
||||
-1210, -1210, -1209, -1209, -1208, -1208, -1208, -1207,
|
||||
-1207, -1206, -1206, -1205, -1205, -1204, -1204, -1203,
|
||||
-1202, -1202, -1201, -1200, -1200, -1199, -1198, -1198,
|
||||
-1197, -1196, -1195, -1195, -1194, -1193, -1192, -1191,
|
||||
-1190, -1189, -1188, -1187, -1187, -1186, -1185, -1184,
|
||||
-1182, -1181, -1180, -1179, -1178, -1177, -1176, -1175,
|
||||
-1174, -1172, -1171, -1170, -1169, -1167, -1166, -1165,
|
||||
-1163, -1162, -1161, -1159, -1158, -1156, -1155, -1153,
|
||||
-1152, -1150, -1149, -1147, -1146, -1144, -1143, -1141,
|
||||
-1139, -1138, -1136, -1134, -1133, -1131, -1129, -1127,
|
||||
-1125, -1124, -1122, -1120, -1118, -1116, -1114, -1112,
|
||||
-1110, -1108, -1106, -1104, -1102, -1100, -1098, -1096,
|
||||
-1094, -1092, -1089, -1087, -1085, -1083, -1080, -1078,
|
||||
-1076, -1074, -1071, -1069, -1066, -1064, -1062, -1059,
|
||||
-1057, -1054, -1052, -1049, -1047, -1044, -1041, -1039,
|
||||
-1036, -1033, -1031, -1028, -1025, -1022, -1020, -1017,
|
||||
-1014, -1011, -1008, -1005, -1002, -999, -997, -994,
|
||||
-991, -987, -984, -981, -978, -975, -972, -969,
|
||||
-966, -962, -959, -956, -953, -949, -946, -943,
|
||||
-939, -936, -932, -929, -925, -922, -918, -915,
|
||||
-911, -908, -904, -900, -897, -893, -889, -886,
|
||||
-882, -878, -874, -870, -866, -863, -859, -855,
|
||||
-851, -847, -843, -839, -835, -831, -826, -822,
|
||||
-818, -814, -810, -806, -801, -797, -793, -788,
|
||||
-784, -780, -775, -771, -766, -762, -757, -753,
|
||||
-748, -744, -739, -734, -730, -725, -720, -715,
|
||||
-711, -706, -701, -696, -691, -686, -682, -677,
|
||||
-672, -667, -662, -656, -651, -646, -641, -636,
|
||||
-631, -626, -620, -615, -610, -604, -599, -594,
|
||||
-588, -583, -577, -572, -566, -561, -555, -550,
|
||||
-544, -538, -533, -527, -521, -515, -510, -504,
|
||||
-498, -492, -486, -480, -474, -468, -462, -456,
|
||||
-450, -444, -438, -432, -425, -419, -413, -407,
|
||||
-400, -394, -388, -381, -375, -368, -362, -355,
|
||||
-349, -342, -336, -329, -322, -316, -309, -302,
|
||||
-295, -289, -282, -275, -268, -261, -254, -247,
|
||||
-240, -233, -226, -219, -212, -205, -198, -190,
|
||||
-183, -176, -169, -161, -154, -146, -139, -132,
|
||||
-124, -117, -109, -101, -94, -86, -78, -71,
|
||||
-63, -55, -47, -40, -32, -24, -16, -8,
|
||||
};
|
||||
|
1612
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/read_event.c
vendored
Normal file
1612
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/read_event.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
549
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/scan.c
vendored
Normal file
549
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/scan.c
vendored
Normal file
|
@ -0,0 +1,549 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Sun, 31 May 1998 17:50:02 -0600
|
||||
* Reported by ToyKeeper <scriven@CS.ColoState.EDU>:
|
||||
* For loop-prevention, I know a way to do it which lets most songs play
|
||||
* fine once through even if they have backward-jumps. Just keep a small
|
||||
* array (256 bytes, or even bits) of flags, each entry determining if a
|
||||
* pattern in the song order has been played. If you get to an entry which
|
||||
* is already non-zero, skip to the next song (assuming looping is off).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Tue, 6 Oct 1998 21:23:17 +0200 (CEST)
|
||||
* Reported by John v/d Kamp <blade_@dds.nl>:
|
||||
* scan.c was hanging when it jumps to an invalid restart value.
|
||||
* (Fixed by hipolito)
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "effects.h"
|
||||
#include "mixer.h"
|
||||
|
||||
#define S3M_END 0xff
|
||||
#define S3M_SKIP 0xfe
|
||||
|
||||
|
||||
static int scan_module(struct context_data *ctx, int ep, int chain)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int parm, gvol_memory, f1, f2, p1, p2, ord, ord2;
|
||||
int row, last_row, break_row, row_count;
|
||||
int gvl, bpm, speed, base_time, chn;
|
||||
int frame_count;
|
||||
double time, start_time;
|
||||
int loop_chn, loop_num, inside_loop;
|
||||
int pdelay = 0;
|
||||
int loop_count[XMP_MAX_CHANNELS];
|
||||
int loop_row[XMP_MAX_CHANNELS];
|
||||
struct xmp_event* event;
|
||||
int i, pat;
|
||||
int has_marker;
|
||||
struct ord_data *info;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
int st26_speed;
|
||||
#endif
|
||||
|
||||
if (mod->len == 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < mod->len; i++) {
|
||||
int pat = mod->xxo[i];
|
||||
memset(m->scan_cnt[i], 0, pat >= mod->pat ? 1 :
|
||||
mod->xxp[pat]->rows ? mod->xxp[pat]->rows : 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < mod->chn; i++) {
|
||||
loop_count[i] = 0;
|
||||
loop_row[i] = -1;
|
||||
}
|
||||
loop_num = 0;
|
||||
loop_chn = -1;
|
||||
|
||||
gvl = mod->gvl;
|
||||
bpm = mod->bpm;
|
||||
|
||||
speed = mod->spd;
|
||||
base_time = m->rrate;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
st26_speed = 0;
|
||||
#endif
|
||||
|
||||
has_marker = HAS_QUIRK(QUIRK_MARKER);
|
||||
|
||||
/* By erlk ozlr <erlk.ozlr@gmail.com>
|
||||
*
|
||||
* xmp doesn't handle really properly the "start" option (-s for the
|
||||
* command-line) for DeusEx's .umx files. These .umx files contain
|
||||
* several loop "tracks" that never join together. That's how they put
|
||||
* multiple musics on each level with a file per level. Each "track"
|
||||
* starts at the same order in all files. The problem is that xmp starts
|
||||
* decoding the module at order 0 and not at the order specified with
|
||||
* the start option. If we have a module that does "0 -> 2 -> 0 -> ...",
|
||||
* we cannot play order 1, even with the supposed right option.
|
||||
*
|
||||
* was: ord2 = ord = -1;
|
||||
*
|
||||
* CM: Fixed by using different "sequences" for each loop or subsong.
|
||||
* Each sequence has its entry point. Sequences don't overlap.
|
||||
*/
|
||||
ord2 = -1;
|
||||
ord = ep - 1;
|
||||
|
||||
gvol_memory = break_row = row_count = frame_count = 0;
|
||||
start_time = time = 0.0;
|
||||
inside_loop = 0;
|
||||
|
||||
while (42) {
|
||||
if ((uint32)++ord >= mod->len) {
|
||||
if (mod->rst > mod->len || mod->xxo[mod->rst] >= mod->pat) {
|
||||
ord = ep;
|
||||
} else {
|
||||
if (libxmp_get_sequence(ctx, mod->rst) == chain) {
|
||||
ord = mod->rst;
|
||||
} else {
|
||||
ord = ep;
|
||||
}
|
||||
}
|
||||
|
||||
pat = mod->xxo[ord];
|
||||
if (has_marker && pat == S3M_END) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pat = mod->xxo[ord];
|
||||
info = &m->xxo_info[ord];
|
||||
|
||||
/* Allow more complex order reuse only in main sequence */
|
||||
if (ep != 0 && p->sequence_control[ord] != 0xff) {
|
||||
break;
|
||||
}
|
||||
p->sequence_control[ord] = chain;
|
||||
|
||||
/* All invalid patterns skipped, only S3M_END aborts replay */
|
||||
if (pat >= mod->pat) {
|
||||
if (has_marker && pat == S3M_END) {
|
||||
ord = mod->len;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (break_row >= mod->xxp[pat]->rows) {
|
||||
break_row = 0;
|
||||
}
|
||||
|
||||
/* Loops can cross pattern boundaries, so check if we're not looping */
|
||||
if (m->scan_cnt[ord][break_row] && !inside_loop) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't update pattern information if we're inside a loop, otherwise
|
||||
* a loop containing e.g. a global volume fade can make the pattern
|
||||
* start with the wrong volume.
|
||||
*/
|
||||
if (!inside_loop && info->gvl < 0) {
|
||||
info->gvl = gvl;
|
||||
info->bpm = bpm;
|
||||
info->speed = speed;
|
||||
info->time = time + m->time_factor * frame_count * base_time / bpm;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
info->st26_speed = st26_speed;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (info->start_row == 0 && ord != 0) {
|
||||
if (ord == ep) {
|
||||
start_time = time + m->time_factor * frame_count * base_time / bpm;
|
||||
}
|
||||
|
||||
info->start_row = break_row;
|
||||
}
|
||||
|
||||
last_row = mod->xxp[pat]->rows;
|
||||
for (row = break_row, break_row = 0; row < last_row; row++, row_count++) {
|
||||
/* Prevent crashes caused by large softmixer frames */
|
||||
if (bpm < XMP_MIN_BPM) {
|
||||
bpm = XMP_MIN_BPM;
|
||||
}
|
||||
|
||||
/* Date: Sat, 8 Sep 2007 04:01:06 +0200
|
||||
* Reported by Zbigniew Luszpinski <zbiggy@o2.pl>
|
||||
* The scan routine falls into infinite looping and doesn't let
|
||||
* xmp play jos-dr4k.xm.
|
||||
* Claudio's workaround: we'll break infinite loops here.
|
||||
*
|
||||
* Date: Oct 27, 2007 8:05 PM
|
||||
* From: Adric Riedel <adric.riedel@gmail.com>
|
||||
* Jesper Kyd: Global Trash 3.mod (the 'Hardwired' theme) only
|
||||
* plays the first 4:41 of what should be a 10 minute piece.
|
||||
* (...) it dies at the end of position 2F
|
||||
*/
|
||||
|
||||
if (row_count > 512) /* was 255, but Global trash goes to 318 */
|
||||
goto end_module;
|
||||
|
||||
if (!loop_num && m->scan_cnt[ord][row]) {
|
||||
row_count--;
|
||||
goto end_module;
|
||||
}
|
||||
m->scan_cnt[ord][row]++;
|
||||
|
||||
pdelay = 0;
|
||||
|
||||
for (chn = 0; chn < mod->chn; chn++) {
|
||||
if (row >= mod->xxt[mod->xxp[pat]->index[chn]]->rows)
|
||||
continue;
|
||||
|
||||
event = &EVENT(mod->xxo[ord], chn, row);
|
||||
|
||||
f1 = event->fxt;
|
||||
p1 = event->fxp;
|
||||
f2 = event->f2t;
|
||||
p2 = event->f2p;
|
||||
|
||||
if (f1 == FX_GLOBALVOL || f2 == FX_GLOBALVOL) {
|
||||
gvl = (f1 == FX_GLOBALVOL) ? p1 : p2;
|
||||
gvl = gvl > m->gvolbase ? m->gvolbase : gvl < 0 ? 0 : gvl;
|
||||
}
|
||||
|
||||
/* Process fine global volume slide */
|
||||
if (f1 == FX_GVOL_SLIDE || f2 == FX_GVOL_SLIDE) {
|
||||
int h, l;
|
||||
parm = (f1 == FX_GVOL_SLIDE) ? p1 : p2;
|
||||
|
||||
process_gvol:
|
||||
if (parm) {
|
||||
gvol_memory = parm;
|
||||
h = MSN(parm);
|
||||
l = LSN(parm);
|
||||
|
||||
if (HAS_QUIRK(QUIRK_FINEFX)) {
|
||||
if (l == 0xf && h != 0) {
|
||||
gvl += h;
|
||||
} else if (h == 0xf && l != 0) {
|
||||
gvl -= l;
|
||||
} else {
|
||||
if (m->quirk & QUIRK_VSALL) {
|
||||
gvl += (h - l) * speed;
|
||||
} else {
|
||||
gvl += (h - l) * (speed - 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m->quirk & QUIRK_VSALL) {
|
||||
gvl += (h - l) * speed;
|
||||
} else {
|
||||
gvl += (h - l) * (speed - 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((parm = gvol_memory) != 0)
|
||||
goto process_gvol;
|
||||
}
|
||||
}
|
||||
|
||||
if ((f1 == FX_SPEED && p1) || (f2 == FX_SPEED && p2)) {
|
||||
parm = (f1 == FX_SPEED) ? p1 : p2;
|
||||
frame_count += row_count * speed;
|
||||
row_count = 0;
|
||||
if (parm) {
|
||||
if (HAS_QUIRK(QUIRK_NOBPM) || p->flags & XMP_FLAGS_VBLANK || parm < 0x20) {
|
||||
if (parm > 0) {
|
||||
speed = parm;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
st26_speed = 0;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
time += m->time_factor * frame_count * base_time / bpm;
|
||||
frame_count = 0;
|
||||
bpm = parm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (f1 == FX_SPEED_CP) {
|
||||
f1 = FX_S3M_SPEED;
|
||||
}
|
||||
if (f2 == FX_SPEED_CP) {
|
||||
f2 = FX_S3M_SPEED;
|
||||
}
|
||||
|
||||
/* ST2.6 speed processing */
|
||||
|
||||
if (f1 == FX_ICE_SPEED && p1) {
|
||||
if (LSN(p1)) {
|
||||
st26_speed = (MSN(p1) << 8) | LSN(p1);
|
||||
} else {
|
||||
st26_speed = MSN(p1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((f1 == FX_S3M_SPEED && p1) || (f2 == FX_S3M_SPEED && p2)) {
|
||||
parm = (f1 == FX_S3M_SPEED) ? p1 : p2;
|
||||
if (parm > 0) {
|
||||
frame_count += row_count * speed;
|
||||
row_count = 0;
|
||||
speed = parm;
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
st26_speed = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ((f1 == FX_S3M_BPM && p1) || (f2 == FX_S3M_BPM && p2)) {
|
||||
parm = (f1 == FX_S3M_BPM) ? p1 : p2;
|
||||
if (parm >= 0x20) {
|
||||
frame_count += row_count * speed;
|
||||
row_count = 0;
|
||||
time += m->time_factor * frame_count * base_time / bpm;
|
||||
frame_count = 0;
|
||||
bpm = parm;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
if ((f1 == FX_IT_BPM && p1) || (f2 == FX_IT_BPM && p2)) {
|
||||
parm = (f1 == FX_IT_BPM) ? p1 : p2;
|
||||
frame_count += row_count * speed;
|
||||
row_count = 0;
|
||||
time += m->time_factor * frame_count * base_time / bpm;
|
||||
frame_count = 0;
|
||||
|
||||
if (MSN(parm) == 0) {
|
||||
time += m->time_factor * base_time / bpm;
|
||||
for (i = 1; i < speed; i++) {
|
||||
bpm -= LSN(parm);
|
||||
if (bpm < 0x20)
|
||||
bpm = 0x20;
|
||||
time += m->time_factor * base_time / bpm;
|
||||
}
|
||||
|
||||
/* remove one row at final bpm */
|
||||
time -= m->time_factor * speed * base_time / bpm;
|
||||
|
||||
} else if (MSN(parm) == 1) {
|
||||
time += m->time_factor * base_time / bpm;
|
||||
for (i = 1; i < speed; i++) {
|
||||
bpm += LSN(parm);
|
||||
if (bpm > 0xff)
|
||||
bpm = 0xff;
|
||||
time += m->time_factor * base_time / bpm;
|
||||
}
|
||||
|
||||
/* remove one row at final bpm */
|
||||
time -= m->time_factor * speed * base_time / bpm;
|
||||
|
||||
} else {
|
||||
bpm = parm;
|
||||
}
|
||||
}
|
||||
|
||||
if (f1 == FX_IT_ROWDELAY) {
|
||||
m->scan_cnt[ord][row] += p1 & 0x0f;
|
||||
frame_count += (p1 & 0x0f) * speed;
|
||||
}
|
||||
|
||||
if (f1 == FX_IT_BREAK) {
|
||||
break_row = p1;
|
||||
last_row = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (f1 == FX_JUMP || f2 == FX_JUMP) {
|
||||
ord2 = (f1 == FX_JUMP) ? p1 : p2;
|
||||
break_row = 0;
|
||||
last_row = 0;
|
||||
|
||||
/* prevent infinite loop, see OpenMPT PatLoop-Various.xm */
|
||||
inside_loop = 0;
|
||||
}
|
||||
|
||||
if (f1 == FX_BREAK || f2 == FX_BREAK) {
|
||||
parm = (f1 == FX_BREAK) ? p1 : p2;
|
||||
break_row = 10 * MSN(parm) + LSN(parm);
|
||||
last_row = 0;
|
||||
}
|
||||
|
||||
if (f1 == FX_EXTENDED || f2 == FX_EXTENDED) {
|
||||
parm = (f1 == FX_EXTENDED) ? p1 : p2;
|
||||
|
||||
if ((parm >> 4) == EX_PATT_DELAY) {
|
||||
if (m->read_event_type != READ_EVENT_ST3 || !pdelay) {
|
||||
pdelay = parm & 0x0f;
|
||||
frame_count += pdelay * speed;
|
||||
}
|
||||
}
|
||||
|
||||
if ((parm >> 4) == EX_PATTERN_LOOP) {
|
||||
if (parm &= 0x0f) {
|
||||
/* Loop end */
|
||||
if (loop_count[chn]) {
|
||||
if (--loop_count[chn]) {
|
||||
/* next iteraction */
|
||||
loop_chn = chn;
|
||||
} else {
|
||||
/* finish looping */
|
||||
loop_num--;
|
||||
inside_loop = 0;
|
||||
if (m->quirk & QUIRK_S3MLOOP)
|
||||
loop_row[chn] = row;
|
||||
}
|
||||
} else {
|
||||
loop_count[chn] = parm;
|
||||
loop_chn = chn;
|
||||
loop_num++;
|
||||
}
|
||||
} else {
|
||||
/* Loop start */
|
||||
loop_row[chn] = row - 1;
|
||||
inside_loop = 1;
|
||||
if (HAS_QUIRK(QUIRK_FT2BUGS))
|
||||
break_row = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (loop_chn >= 0) {
|
||||
row = loop_row[loop_chn];
|
||||
loop_chn = -1;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
if (st26_speed) {
|
||||
frame_count += row_count * speed;
|
||||
row_count = 0;
|
||||
if (st26_speed & 0x10000) {
|
||||
speed = (st26_speed & 0xff00) >> 8;
|
||||
} else {
|
||||
speed = st26_speed & 0xff;
|
||||
}
|
||||
st26_speed ^= 0x10000;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (break_row && pdelay) {
|
||||
break_row++;
|
||||
}
|
||||
|
||||
if (ord2 >= 0) {
|
||||
ord = ord2 - 1;
|
||||
ord2 = -1;
|
||||
}
|
||||
|
||||
frame_count += row_count * speed;
|
||||
row_count = 0;
|
||||
}
|
||||
row = break_row;
|
||||
|
||||
end_module:
|
||||
|
||||
/* Sanity check */
|
||||
{
|
||||
pat = mod->xxo[ord];
|
||||
if (pat >= mod->pat || row >= mod->xxp[pat]->rows) {
|
||||
row = 0;
|
||||
}
|
||||
}
|
||||
|
||||
p->scan[chain].num = m->scan_cnt[ord][row];
|
||||
p->scan[chain].row = row;
|
||||
p->scan[chain].ord = ord;
|
||||
|
||||
time -= start_time;
|
||||
frame_count += row_count * speed;
|
||||
|
||||
return (time + m->time_factor * frame_count * base_time / bpm);
|
||||
}
|
||||
|
||||
int libxmp_get_sequence(struct context_data *ctx, int ord)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
return p->sequence_control[ord];
|
||||
}
|
||||
|
||||
int libxmp_scan_sequences(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
int i, ep;
|
||||
int seq;
|
||||
unsigned char temp_ep[XMP_MAX_MOD_LENGTH];
|
||||
|
||||
/* Initialize order data to prevent overwrite when a position is used
|
||||
* multiple times at different starting points (see janosik.xm).
|
||||
*/
|
||||
for (i = 0; i < XMP_MAX_MOD_LENGTH; i++) {
|
||||
m->xxo_info[i].gvl = -1;
|
||||
}
|
||||
|
||||
ep = 0;
|
||||
memset(p->sequence_control, 0xff, XMP_MAX_MOD_LENGTH);
|
||||
temp_ep[0] = 0;
|
||||
p->scan[0].time = scan_module(ctx, ep, 0);
|
||||
seq = 1;
|
||||
|
||||
while (1) {
|
||||
/* Scan song starting at given entry point */
|
||||
/* Check if any patterns left */
|
||||
for (i = 0; i < mod->len; i++) {
|
||||
if (p->sequence_control[i] == 0xff) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != mod->len && seq < MAX_SEQUENCES) {
|
||||
/* New entry point */
|
||||
ep = i;
|
||||
temp_ep[seq] = ep;
|
||||
p->scan[seq].time = scan_module(ctx, ep, seq);
|
||||
if (p->scan[seq].time > 0)
|
||||
seq++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m->num_sequences = seq;
|
||||
|
||||
/* Now place entry points in the public accessible array */
|
||||
for (i = 0; i < m->num_sequences; i++) {
|
||||
m->seq_data[i].entry_point = temp_ep[i];
|
||||
m->seq_data[i].duration = p->scan[i].time;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
322
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/smix.c
vendored
Normal file
322
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/smix.c
vendored
Normal file
|
@ -0,0 +1,322 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "common.h"
|
||||
#include "period.h"
|
||||
#include "player.h"
|
||||
#include "hio.h"
|
||||
|
||||
|
||||
struct xmp_instrument *libxmp_get_instrument(struct context_data *ctx, int ins)
|
||||
{
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct xmp_instrument *xxi;
|
||||
|
||||
if (ins < mod->ins) {
|
||||
xxi = &mod->xxi[ins];
|
||||
} else if (ins < mod->ins + smix->ins) {
|
||||
xxi = &smix->xxi[ins - mod->ins];
|
||||
} else {
|
||||
xxi = NULL;
|
||||
}
|
||||
|
||||
return xxi;
|
||||
}
|
||||
|
||||
struct xmp_sample *libxmp_get_sample(struct context_data *ctx, int smp)
|
||||
{
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct xmp_sample *xxs;
|
||||
|
||||
if (smp < mod->smp) {
|
||||
xxs = &mod->xxs[smp];
|
||||
} else if (smp < mod->smp + smix->smp) {
|
||||
xxs = &smix->xxs[smp - mod->smp];
|
||||
} else {
|
||||
xxs = NULL;
|
||||
}
|
||||
|
||||
return xxs;
|
||||
}
|
||||
|
||||
int xmp_start_smix(xmp_context opaque, int chn, int smp)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
|
||||
if (ctx->state > XMP_STATE_LOADED) {
|
||||
return -XMP_ERROR_STATE;
|
||||
}
|
||||
|
||||
smix->xxi = calloc(sizeof (struct xmp_instrument), smp);
|
||||
if (smix->xxi == NULL) {
|
||||
goto err;
|
||||
}
|
||||
smix->xxs = calloc(sizeof (struct xmp_sample), smp);
|
||||
if (smix->xxs == NULL) {
|
||||
goto err1;
|
||||
}
|
||||
|
||||
smix->chn = chn;
|
||||
smix->ins = smix->smp = smp;
|
||||
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
free(smix->xxi);
|
||||
err:
|
||||
return -XMP_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
int xmp_smix_play_instrument(xmp_context opaque, int ins, int note, int vol, int chn)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct xmp_event *event;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING) {
|
||||
return -XMP_ERROR_STATE;
|
||||
}
|
||||
|
||||
if (chn >= smix->chn || ins >= mod->ins) {
|
||||
return -XMP_ERROR_INVALID;
|
||||
}
|
||||
|
||||
if (note == 0) {
|
||||
note = 60; /* middle C note number */
|
||||
}
|
||||
|
||||
event = &p->inject_event[mod->chn + chn];
|
||||
memset(event, 0, sizeof (struct xmp_event));
|
||||
event->note = note + 1;
|
||||
event->ins = ins + 1;
|
||||
event->vol = vol + 1;
|
||||
event->_flag = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xmp_smix_play_sample(xmp_context opaque, int ins, int note, int vol, int chn)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_module *mod = &m->mod;
|
||||
struct xmp_event *event;
|
||||
|
||||
if (ctx->state < XMP_STATE_PLAYING) {
|
||||
return -XMP_ERROR_STATE;
|
||||
}
|
||||
|
||||
if (chn >= smix->chn || ins >= smix->ins) {
|
||||
return -XMP_ERROR_INVALID;
|
||||
}
|
||||
|
||||
if (note == 0) {
|
||||
note = 60; /* middle C note number */
|
||||
}
|
||||
|
||||
event = &p->inject_event[mod->chn + chn];
|
||||
memset(event, 0, sizeof (struct xmp_event));
|
||||
event->note = note + 1;
|
||||
event->ins = mod->ins + ins + 1;
|
||||
event->vol = vol + 1;
|
||||
event->_flag = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xmp_smix_channel_pan(xmp_context opaque, int chn, int pan)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct player_data *p = &ctx->p;
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct channel_data *xc;
|
||||
|
||||
if (chn >= smix->chn || pan < 0 || pan > 255) {
|
||||
return -XMP_ERROR_INVALID;
|
||||
}
|
||||
|
||||
xc = &p->xc_data[m->mod.chn + chn];
|
||||
xc->pan.val = pan;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
struct module_data *m = &ctx->m;
|
||||
struct xmp_instrument *xxi;
|
||||
struct xmp_sample *xxs;
|
||||
HIO_HANDLE *h;
|
||||
uint32 magic;
|
||||
int chn, rate, bits, size;
|
||||
int retval = -XMP_ERROR_INTERNAL;
|
||||
|
||||
if (num >= smix->ins) {
|
||||
retval = -XMP_ERROR_INVALID;
|
||||
goto err;
|
||||
}
|
||||
|
||||
xxi = &smix->xxi[num];
|
||||
xxs = &smix->xxs[num];
|
||||
|
||||
h = hio_open(path, "rb");
|
||||
if (h == NULL) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Init instrument */
|
||||
|
||||
xxi->sub = calloc(sizeof(struct xmp_subinstrument), 1);
|
||||
if (xxi->sub == NULL) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
xxi->vol = m->volbase;
|
||||
xxi->nsm = 1;
|
||||
xxi->sub[0].sid = num;
|
||||
xxi->sub[0].vol = xxi->vol;
|
||||
xxi->sub[0].pan = 0x80;
|
||||
|
||||
/* Load sample */
|
||||
|
||||
magic = hio_read32b(h);
|
||||
if (magic != 0x52494646) { /* RIFF */
|
||||
retval = -XMP_ERROR_FORMAT;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (hio_seek(h, 22, SEEK_SET) < 0) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err2;
|
||||
}
|
||||
chn = hio_read16l(h);
|
||||
if (chn != 1) {
|
||||
retval = -XMP_ERROR_FORMAT;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
rate = hio_read32l(h);
|
||||
if (rate == 0) {
|
||||
retval = -XMP_ERROR_FORMAT;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (hio_seek(h, 34, SEEK_SET) < 0) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err2;
|
||||
}
|
||||
bits = hio_read16l(h);
|
||||
if (bits == 0) {
|
||||
retval = -XMP_ERROR_FORMAT;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (hio_seek(h, 40, SEEK_SET) < 0) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err2;
|
||||
}
|
||||
size = hio_read32l(h) / (bits / 8);
|
||||
if (size == 0) {
|
||||
retval = -XMP_ERROR_FORMAT;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
libxmp_c2spd_to_note(rate, &xxi->sub[0].xpo, &xxi->sub[0].fin);
|
||||
|
||||
xxs->len = 8 * size / bits;
|
||||
xxs->lps = 0;
|
||||
xxs->lpe = 0;
|
||||
xxs->flg = bits == 16 ? XMP_SAMPLE_16BIT : 0;
|
||||
|
||||
xxs->data = malloc(size);
|
||||
if (xxs->data == NULL) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err2;
|
||||
}
|
||||
if (hio_seek(h, 44, SEEK_SET) < 0) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err2;
|
||||
}
|
||||
if (hio_read(xxs->data, 1, size, h) != size) {
|
||||
retval = -XMP_ERROR_SYSTEM;
|
||||
goto err2;
|
||||
}
|
||||
hio_close(h);
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
free(xxi->sub);
|
||||
xxi->sub = NULL;
|
||||
err1:
|
||||
hio_close(h);
|
||||
err:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int xmp_smix_release_sample(xmp_context opaque, int num)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
|
||||
if (num >= smix->ins) {
|
||||
return -XMP_ERROR_INVALID;
|
||||
}
|
||||
|
||||
free(smix->xxs[num].data);
|
||||
free(smix->xxi[num].sub);
|
||||
|
||||
smix->xxs[num].data = NULL;
|
||||
smix->xxi[num].sub = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xmp_end_smix(xmp_context opaque)
|
||||
{
|
||||
struct context_data *ctx = (struct context_data *)opaque;
|
||||
struct smix_data *smix = &ctx->smix;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < smix->smp; i++) {
|
||||
xmp_smix_release_sample(opaque, i);
|
||||
}
|
||||
|
||||
free(smix->xxs);
|
||||
free(smix->xxi);
|
||||
}
|
7
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/tempfile.h
vendored
Normal file
7
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/tempfile.h
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef XMP_PLATFORM_H
|
||||
#define XMP_PLATFORM_H
|
||||
|
||||
FILE *make_temp_file(char **);
|
||||
void unlink_temp_file(char *);
|
||||
|
||||
#endif
|
597
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/virtual.c
vendored
Normal file
597
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/virtual.c
vendored
Normal file
|
@ -0,0 +1,597 @@
|
|||
/* Extended Module Player
|
||||
* Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "common.h"
|
||||
#include "virtual.h"
|
||||
#include "mixer.h"
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
#include "paula.h"
|
||||
#endif
|
||||
|
||||
#define FREE -1
|
||||
|
||||
/* For virt_pastnote() */
|
||||
void libxmp_player_set_release(struct context_data *, int);
|
||||
void libxmp_player_set_fadeout(struct context_data *, int);
|
||||
|
||||
|
||||
/* Get parent channel */
|
||||
int libxmp_virt_getroot(struct context_data *ctx, int chn)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi;
|
||||
int voc;
|
||||
|
||||
voc = p->virt.virt_channel[chn].map;
|
||||
if (voc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
vi = &p->virt.voice_array[voc];
|
||||
|
||||
return vi->root;
|
||||
}
|
||||
|
||||
void libxmp_virt_resetvoice(struct context_data *ctx, int voc, int mute)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[voc];
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
struct paula_state *paula;
|
||||
#endif
|
||||
|
||||
if ((uint32)voc >= p->virt.maxvoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mute) {
|
||||
libxmp_mixer_setvol(ctx, voc, 0);
|
||||
}
|
||||
|
||||
p->virt.virt_used--;
|
||||
p->virt.virt_channel[vi->root].count--;
|
||||
p->virt.virt_channel[vi->chn].map = FREE;
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
paula = vi->paula;
|
||||
#endif
|
||||
memset(vi, 0, sizeof(struct mixer_voice));
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
vi->paula = paula;
|
||||
#endif
|
||||
vi->chn = vi->root = FREE;
|
||||
}
|
||||
|
||||
/* virt_on (number of tracks) */
|
||||
int libxmp_virt_on(struct context_data *ctx, int num)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct module_data *m = &ctx->m;
|
||||
int i;
|
||||
|
||||
p->virt.num_tracks = num;
|
||||
num = libxmp_mixer_numvoices(ctx, -1);
|
||||
|
||||
p->virt.virt_channels = p->virt.num_tracks;
|
||||
|
||||
if (HAS_QUIRK(QUIRK_VIRTUAL)) {
|
||||
p->virt.virt_channels += num;
|
||||
} else if (num > p->virt.virt_channels) {
|
||||
num = p->virt.virt_channels;
|
||||
}
|
||||
|
||||
p->virt.maxvoc = libxmp_mixer_numvoices(ctx, num);
|
||||
|
||||
p->virt.voice_array = calloc(p->virt.maxvoc,
|
||||
sizeof(struct mixer_voice));
|
||||
if (p->virt.voice_array == NULL)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
p->virt.voice_array[i].chn = FREE;
|
||||
p->virt.voice_array[i].root = FREE;
|
||||
}
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
/* Initialize Paula simulator */
|
||||
if (IS_AMIGA_MOD()) {
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
p->virt.voice_array[i].paula = calloc(1, sizeof (struct paula_state));
|
||||
if (p->virt.voice_array[i].paula == NULL) {
|
||||
goto err2;
|
||||
}
|
||||
libxmp_paula_init(ctx, p->virt.voice_array[i].paula);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
p->virt.virt_channel = malloc(p->virt.virt_channels *
|
||||
sizeof(struct virt_channel));
|
||||
if (p->virt.virt_channel == NULL)
|
||||
goto err2;
|
||||
|
||||
for (i = 0; i < p->virt.virt_channels; i++) {
|
||||
p->virt.virt_channel[i].map = FREE;
|
||||
p->virt.virt_channel[i].count = 0;
|
||||
}
|
||||
|
||||
p->virt.virt_used = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
if (IS_AMIGA_MOD()) {
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
free(p->virt.voice_array[i].paula);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
free(p->virt.voice_array);
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void libxmp_virt_off(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
struct module_data *m = &ctx->m;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
/* Free Paula simulator state */
|
||||
if (IS_AMIGA_MOD()) {
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
free(p->virt.voice_array[i].paula);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
p->virt.virt_used = p->virt.maxvoc = 0;
|
||||
p->virt.virt_channels = 0;
|
||||
p->virt.num_tracks = 0;
|
||||
|
||||
free(p->virt.voice_array);
|
||||
free(p->virt.virt_channel);
|
||||
}
|
||||
|
||||
void libxmp_virt_reset(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int i;
|
||||
|
||||
if (p->virt.virt_channels < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* CID 129203 (#1 of 1): Useless call (USELESS_CALL)
|
||||
* Call is only useful for its return value, which is ignored.
|
||||
*
|
||||
* libxmp_mixer_numvoices(ctx, p->virt.maxvoc);
|
||||
*/
|
||||
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
struct mixer_voice *vi = &p->virt.voice_array[i];
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
struct paula_state *paula = vi->paula;
|
||||
#endif
|
||||
memset(vi, 0, sizeof(struct mixer_voice));
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
vi->paula = paula;
|
||||
#endif
|
||||
vi->chn = FREE;
|
||||
vi->root = FREE;
|
||||
}
|
||||
|
||||
for (i = 0; i < p->virt.virt_channels; i++) {
|
||||
p->virt.virt_channel[i].map = FREE;
|
||||
p->virt.virt_channel[i].count = 0;
|
||||
}
|
||||
|
||||
p->virt.virt_used = 0;
|
||||
}
|
||||
|
||||
static int free_voice(struct context_data *ctx)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int i, num, vol;
|
||||
|
||||
/* Find background voice with lowest volume*/
|
||||
num = FREE;
|
||||
vol = INT_MAX;
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
struct mixer_voice *vi = &p->virt.voice_array[i];
|
||||
|
||||
if (vi->chn >= p->virt.num_tracks && vi->vol < vol) {
|
||||
num = i;
|
||||
vol = vi->vol;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free voice */
|
||||
if (num >= 0) {
|
||||
p->virt.virt_channel[p->virt.voice_array[num].chn].map = FREE;
|
||||
p->virt.virt_channel[p->virt.voice_array[num].root].count--;
|
||||
p->virt.virt_used--;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static int alloc_voice(struct context_data *ctx, int chn)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int i;
|
||||
|
||||
/* Find free voice */
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
if (p->virt.voice_array[i].chn == FREE)
|
||||
break;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
if (i == p->virt.maxvoc) {
|
||||
i = free_voice(ctx);
|
||||
}
|
||||
|
||||
if (i >= 0) {
|
||||
p->virt.virt_channel[chn].count++;
|
||||
p->virt.virt_used++;
|
||||
|
||||
p->virt.voice_array[i].chn = chn;
|
||||
p->virt.voice_array[i].root = chn;
|
||||
p->virt.virt_channel[chn].map = i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int map_virt_channel(struct player_data *p, int chn)
|
||||
{
|
||||
int voc;
|
||||
|
||||
if ((uint32)chn >= p->virt.virt_channels)
|
||||
return -1;
|
||||
|
||||
voc = p->virt.virt_channel[chn].map;
|
||||
|
||||
if ((uint32)voc >= p->virt.maxvoc)
|
||||
return -1;
|
||||
|
||||
return voc;
|
||||
}
|
||||
|
||||
int libxmp_virt_mapchannel(struct context_data *ctx, int chn)
|
||||
{
|
||||
return map_virt_channel(&ctx->p, chn);
|
||||
}
|
||||
|
||||
void libxmp_virt_resetchannel(struct context_data *ctx, int chn)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi;
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
struct paula_state *paula;
|
||||
#endif
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0)
|
||||
return;
|
||||
|
||||
libxmp_mixer_setvol(ctx, voc, 0);
|
||||
|
||||
p->virt.virt_used--;
|
||||
p->virt.virt_channel[p->virt.voice_array[voc].root].count--;
|
||||
p->virt.virt_channel[chn].map = FREE;
|
||||
|
||||
vi = &p->virt.voice_array[voc];
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
paula = vi->paula;
|
||||
#endif
|
||||
memset(vi, 0, sizeof(struct mixer_voice));
|
||||
#ifdef LIBXMP_PAULA_SIMULATOR
|
||||
vi->paula = paula;
|
||||
#endif
|
||||
vi->chn = vi->root = FREE;
|
||||
}
|
||||
|
||||
void libxmp_virt_setvol(struct context_data *ctx, int chn, int vol)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc, root;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
root = p->virt.voice_array[voc].root;
|
||||
if (root < XMP_MAX_CHANNELS && p->channel_mute[root]) {
|
||||
vol = 0;
|
||||
}
|
||||
|
||||
libxmp_mixer_setvol(ctx, voc, vol);
|
||||
|
||||
if (vol == 0 && chn >= p->virt.num_tracks) {
|
||||
libxmp_virt_resetvoice(ctx, voc, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void libxmp_virt_release(struct context_data *ctx, int chn, int rel)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
libxmp_mixer_release(ctx, voc, rel);
|
||||
}
|
||||
|
||||
void libxmp_virt_setpan(struct context_data *ctx, int chn, int pan)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
libxmp_mixer_setpan(ctx, voc, pan);
|
||||
}
|
||||
|
||||
void libxmp_virt_seteffect(struct context_data *ctx, int chn, int type, int val)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
libxmp_mixer_seteffect(ctx, voc, type, val);
|
||||
}
|
||||
|
||||
double libxmp_virt_getvoicepos(struct context_data *ctx, int chn)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return libxmp_mixer_getvoicepos(ctx, voc);
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_PLAYER
|
||||
|
||||
void libxmp_virt_setsmp(struct context_data *ctx, int chn, int smp)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi;
|
||||
double pos;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
vi = &p->virt.voice_array[voc];
|
||||
if (vi->smp == smp) {
|
||||
return;
|
||||
}
|
||||
|
||||
pos = libxmp_mixer_getvoicepos(ctx, voc);
|
||||
libxmp_mixer_setpatch(ctx, voc, smp, 0);
|
||||
libxmp_mixer_voicepos(ctx, voc, pos, 0); /* Restore old position */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
|
||||
void libxmp_virt_setnna(struct context_data *ctx, int chn, int nna)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
p->virt.voice_array[voc].act = nna;
|
||||
}
|
||||
|
||||
static void check_dct(struct context_data *ctx, int i, int chn, int ins,
|
||||
int smp, int note, int dct, int dca)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
struct mixer_voice *vi = &p->virt.voice_array[i];
|
||||
int voc;
|
||||
|
||||
voc = p->virt.virt_channel[chn].map;
|
||||
|
||||
if (vi->root == chn && vi->ins == ins) {
|
||||
if (dct == XMP_INST_DCT_INST ||
|
||||
(dct == XMP_INST_DCT_SMP && vi->smp == smp) ||
|
||||
(dct == XMP_INST_DCT_NOTE && vi->note == note)) {
|
||||
|
||||
if (dca) {
|
||||
if (i != voc || vi->act)
|
||||
vi->act = dca;
|
||||
} else {
|
||||
libxmp_virt_resetvoice(ctx, i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* For note slides */
|
||||
void libxmp_virt_setnote(struct context_data *ctx, int chn, int note)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
libxmp_mixer_setnote(ctx, voc, note);
|
||||
}
|
||||
|
||||
int libxmp_virt_setpatch(struct context_data *ctx, int chn, int ins, int smp,
|
||||
int note, int nna, int dct, int dca)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc, vfree;
|
||||
|
||||
if ((uint32)chn >= p->virt.virt_channels) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ins < 0) {
|
||||
smp = -1;
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
if (dct) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < p->virt.maxvoc; i++) {
|
||||
check_dct(ctx, i, chn, ins, smp, note, dct, dca);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
voc = p->virt.virt_channel[chn].map;
|
||||
|
||||
if (voc > FREE) {
|
||||
if (p->virt.voice_array[voc].act) {
|
||||
vfree = alloc_voice(ctx, chn);
|
||||
|
||||
if (vfree < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (chn = p->virt.num_tracks;
|
||||
p->virt.virt_channel[chn++].map > FREE;) ;
|
||||
|
||||
p->virt.voice_array[voc].chn = --chn;
|
||||
p->virt.virt_channel[chn].map = voc;
|
||||
voc = vfree;
|
||||
}
|
||||
} else {
|
||||
voc = alloc_voice(ctx, chn);
|
||||
if (voc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (smp < 0) {
|
||||
libxmp_virt_resetvoice(ctx, voc, 1);
|
||||
return chn; /* was -1 */
|
||||
}
|
||||
|
||||
libxmp_mixer_setpatch(ctx, voc, smp, 1);
|
||||
libxmp_mixer_setnote(ctx, voc, note);
|
||||
p->virt.voice_array[voc].ins = ins;
|
||||
p->virt.voice_array[voc].act = nna;
|
||||
|
||||
return chn;
|
||||
}
|
||||
|
||||
void libxmp_virt_setperiod(struct context_data *ctx, int chn, double period)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
libxmp_mixer_setperiod(ctx, voc, period);
|
||||
}
|
||||
|
||||
void libxmp_virt_voicepos(struct context_data *ctx, int chn, double pos)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
libxmp_mixer_voicepos(ctx, voc, pos, 1);
|
||||
}
|
||||
|
||||
#ifndef LIBXMP_CORE_DISABLE_IT
|
||||
|
||||
void libxmp_virt_pastnote(struct context_data *ctx, int chn, int act)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int c, voc;
|
||||
|
||||
for (c = p->virt.num_tracks; c < p->virt.virt_channels; c++) {
|
||||
if ((voc = map_virt_channel(p, c)) < 0)
|
||||
continue;
|
||||
|
||||
if (p->virt.voice_array[voc].root == chn) {
|
||||
switch (act) {
|
||||
case VIRT_ACTION_CUT:
|
||||
libxmp_virt_resetvoice(ctx, voc, 1);
|
||||
break;
|
||||
case VIRT_ACTION_OFF:
|
||||
libxmp_player_set_release(ctx, c);
|
||||
break;
|
||||
case VIRT_ACTION_FADE:
|
||||
libxmp_player_set_fadeout(ctx, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int libxmp_virt_cstat(struct context_data *ctx, int chn)
|
||||
{
|
||||
struct player_data *p = &ctx->p;
|
||||
int voc;
|
||||
|
||||
if ((voc = map_virt_channel(p, chn)) < 0) {
|
||||
return VIRT_INVALID;
|
||||
}
|
||||
|
||||
if (chn < p->virt.num_tracks) {
|
||||
return VIRT_ACTIVE;
|
||||
}
|
||||
|
||||
return p->virt.voice_array[voc].act;
|
||||
}
|
38
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/virtual.h
vendored
Normal file
38
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/src/virtual.h
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef LIBXMP_VIRTUAL_H
|
||||
#define LIBXMP_VIRTUAL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define VIRT_ACTION_CUT XMP_INST_NNA_CUT
|
||||
#define VIRT_ACTION_CONT XMP_INST_NNA_CONT
|
||||
#define VIRT_ACTION_OFF XMP_INST_NNA_OFF
|
||||
#define VIRT_ACTION_FADE XMP_INST_NNA_FADE
|
||||
|
||||
#define VIRT_ACTIVE 0x100
|
||||
#define VIRT_INVALID -1
|
||||
|
||||
int libxmp_virt_on (struct context_data *, int);
|
||||
void libxmp_virt_off (struct context_data *);
|
||||
int libxmp_virt_mute (struct context_data *, int, int);
|
||||
int libxmp_virt_setpatch (struct context_data *, int, int, int, int,
|
||||
int, int, int);
|
||||
int libxmp_virt_cvt8bit (void);
|
||||
void libxmp_virt_setnote (struct context_data *, int, int);
|
||||
void libxmp_virt_setsmp (struct context_data *, int, int);
|
||||
void libxmp_virt_setnna (struct context_data *, int, int);
|
||||
void libxmp_virt_pastnote (struct context_data *, int, int);
|
||||
void libxmp_virt_setvol (struct context_data *, int, int);
|
||||
void libxmp_virt_voicepos (struct context_data *, int, double);
|
||||
double libxmp_virt_getvoicepos (struct context_data *, int);
|
||||
void libxmp_virt_setperiod (struct context_data *, int, double);
|
||||
void libxmp_virt_setpan (struct context_data *, int, int);
|
||||
void libxmp_virt_seteffect (struct context_data *, int, int, int);
|
||||
int libxmp_virt_cstat (struct context_data *, int);
|
||||
int libxmp_virt_mapchannel (struct context_data *, int);
|
||||
void libxmp_virt_resetchannel(struct context_data *, int);
|
||||
void libxmp_virt_resetvoice (struct context_data *, int, int);
|
||||
void libxmp_virt_reset (struct context_data *);
|
||||
void libxmp_virt_release (struct context_data *, int, int);
|
||||
int libxmp_virt_getroot (struct context_data *, int);
|
||||
|
||||
#endif /* LIBXMP_VIRTUAL_H */
|
22
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/test/Makefile
vendored
Normal file
22
external/clownaudio/src/decoding/decoders/libs/libxmp-lite/test/Makefile
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
TEST_OBJS = test.o md5.o
|
||||
TEST_DFILES = Makefile $(TEST_OBJS:.o=.c) test.it md5.h
|
||||
TEST_PATH = test
|
||||
|
||||
T_OBJS = $(addprefix $(TEST_PATH)/,$(TEST_OBJS))
|
||||
|
||||
default:
|
||||
$(MAKE) -C .. check
|
||||
|
||||
dist-test:
|
||||
mkdir -p $(DIST)/$(TEST_PATH)
|
||||
cp -RPp $(addprefix $(TEST_PATH)/,$(TEST_DFILES)) $(DIST)/$(TEST_PATH)
|
||||
|
||||
check: $(TEST_PATH)/libxmp-test
|
||||
cd $(TEST_PATH); LD_LIBRARY_PATH=../lib DYLD_LIBRARY_PATH=../lib LIBRARY_PATH=../lib:$$LIBRARY_PATH PATH=$$PATH:../lib ./libxmp-test
|
||||
|
||||
$(TEST_PATH)/libxmp-test: $(T_OBJS)
|
||||
@CMD='$(LD) -o $@ $(T_OBJS) $(LIBS) -Llib -lxmp-lite'; \
|
||||
if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo LD $@ ; fi; \
|
||||
eval $$CMD
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue