Compare commits

..

23 Commits

Author SHA1 Message Date
Sven Balzer f8f82bc653 add missing tile variations for water 2026-05-13 18:18:28 +02:00
Sven Balzer 8bc6f68b3b convert gpu map format from buffer to texture2d 2026-05-01 19:55:39 +02:00
Sven Balzer fa9190b0e5 remove vertex and index buffer from world shader 2026-05-01 19:27:57 +02:00
Sven Balzer 7cb6dbc3e6 remove rotation from world tiles and instead apply it on load into atlas 2026-05-01 19:15:03 +02:00
Sven Balzer 59cb6fb6c1 replace the name ground with dirt
append TILEKIND_ to every argument of TILE_CORNER_INFO for better readability
2026-05-01 18:31:16 +02:00
Sven Balzer 3d85440aac stop recreating the framebuffer every frame if the aspect ratio is not 1:1 2026-05-01 18:25:15 +02:00
Sven Balzer 2adf75973a update tracy from 11.0 to 13.1 and fix build with tracy enabled 2026-05-01 18:24:04 +02:00
Sven Balzer 7fa5294e02 move game settings into their own file 2026-05-01 18:13:05 +02:00
Sven Balzer 91a4a2079b decouple grid from tile picker and make it toggleable 2026-05-01 17:53:55 +02:00
Sven Balzer 2af0361ac5 fix mouse wheel zooming map when hovering imgui windows 2026-05-01 17:49:10 +02:00
Sven Balzer 7e1894984c add zoom to editor 2026-04-18 14:52:11 +02:00
Sven Balzer 53a7ed7890 make editor camera independent of player camera 2026-04-18 13:33:01 +02:00
Sven Balzer 6305d0b096 split editor and game 2026-04-17 17:22:50 +02:00
Sven Balzer ae9571d270 replace log.c/h with SDL_Log* 2026-04-15 13:29:47 +02:00
Sven Balzer ba39a0e5eb replace map width/height and player pos_x/pos_y with i32vec2 size and position respectively 2026-04-15 11:27:08 +02:00
Sven Balzer 4ec664c8db replace math_graphics with glm version 1.0.3 2026-04-15 10:50:41 +02:00
Sven Balzer 07af9deb6a update wgpu-native from v25.0.2.2 to v29.0.0.0 2026-04-14 14:12:27 +02:00
Sven Balzer 6dc54f9ef6 change map.name to be an array 2026-04-14 09:37:23 +02:00
Sven Balzer 6ac2b1fde0 set SDLMIXER_VENDORED to ON and vendor the required libraries into libs/SDL3_mixer/external
disable SDLMIXER_VORBIS_VORBISFILE
add ogg v1.3.5-SDL
add opus v1.4.x-SDL
add opusfile v0.13-git-SDL
2026-04-13 11:20:08 +02:00
Sven Balzer 85d1832a0c update dear imgui from 1.92.6-docking to 1.92.7-docking 2026-04-02 20:22:14 +02:00
Sven Balzer b549728a24 change world tiles texture from texture_2d_array to an atlas texture_2d 2026-04-02 17:52:28 +02:00
Sven Balzer 9dd37f6d40 replace the x64 specific change_map_tile() with a generic c implementation 2026-04-02 17:02:16 +02:00
Sven Balzer 8a5caf5c0d update SDL_mixer to SDL3_mixer 3.2.0 2026-04-02 16:52:07 +02:00
3283 changed files with 693175 additions and 202960 deletions
+21 -15
View File
@@ -8,6 +8,10 @@ set(CMAKE_CXX_EXTENSIONS OFF)
option(TRACY_ENABLE "Enable Tracy profiling" OFF) option(TRACY_ENABLE "Enable Tracy profiling" OFF)
# glm
add_subdirectory(libs/glm)
target_compile_definitions(glm PUBLIC GLM_FORCE_SWIZZLE GLM_FORCE_XYZW_ONLY)
# SDL # SDL
set(SDL_SHARED OFF) set(SDL_SHARED OFF)
set(SDL_STATIC ON) set(SDL_STATIC ON)
@@ -16,20 +20,23 @@ add_subdirectory(libs/SDL3)
# wgpu # wgpu
add_subdirectory(libs/wgpu) add_subdirectory(libs/wgpu)
# SDL_mixer # SDL3_mixer
set(BUILD_SHARED_LIBS ${SDL_SHARED}) set(BUILD_SHARED_LIBS ${SDL_SHARED})
set(SDLMIXER_DEPS_SHARED OFF) set(SDLMIXER_DEPS_SHARED OFF)
set(SDLMIXER_VENDORED ON) set(SDLMIXER_VENDORED ON)
set(SDLMIXER_FLAC OFF) set(SDLMIXER_OPUS ON)
set(SDLMIXER_GME OFF) set(SDLMIXER_VORBIS_VORBISFILE OFF)
set(SDLMIXER_MIDI OFF) set(SDLMIXER_AIFF OFF)
set(SDLMIXER_MOD OFF) set(SDLMIXER_WAVE OFF)
set(SDLMIXER_MP3 OFF) set(SDLMIXER_VOC OFF)
set(SDLMIXER_OPUS ON) set(SDLMIXER_AU OFF)
set(SDLMIXER_VORBIS OFF) set(SDLMIXER_FLAC OFF)
set(SDLMIXER_WAVE ON) set(SDLMIXER_GME OFF)
set(SDLMIXER_WAVPACK OFF) set(SDLMIXER_MOD OFF)
add_subdirectory(libs/SDL_mixer) set(SDLMIXER_MP3 OFF)
set(SDLMIXER_MIDI OFF)
set(SDLMIXER_WAVPACK OFF)
add_subdirectory(libs/SDL3_mixer)
# Dear ImGui # Dear ImGui
add_library(imgui STATIC add_library(imgui STATIC
@@ -57,15 +64,14 @@ option(TRACY_ONLY_LOCALHOST "" ON)
add_subdirectory(libs/tracy) add_subdirectory(libs/tracy)
add_executable(mikemon add_executable(mikemon
src/log.cpp
src/smol-atlas.cpp src/smol-atlas.cpp
src/math_graphics.cpp
src/change_directory.c src/change_directory.c
src/shaders/shaders.c src/shaders/shaders.c
src/main.cpp src/main.cpp
) )
target_link_libraries(mikemon target_link_libraries(mikemon
PRIVATE PRIVATE
glm
SDL3::SDL3 SDL3::SDL3
SDL3_mixer::SDL3_mixer SDL3_mixer::SDL3_mixer
stb_image stb_image
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Before

Width:  |  Height:  |  Size: 206 B

After

Width:  |  Height:  |  Size: 206 B

Before

Width:  |  Height:  |  Size: 114 B

After

Width:  |  Height:  |  Size: 114 B

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 354 B

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 420 B

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 441 B

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 439 B

Before

Width:  |  Height:  |  Size: 428 B

After

Width:  |  Height:  |  Size: 428 B

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 382 B

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

Before

Width:  |  Height:  |  Size: 561 B

After

Width:  |  Height:  |  Size: 561 B

+1
View File
@@ -0,0 +1 @@
cedfeef30e93db35eee6b25759117da63f8e5a4f
@@ -13,11 +13,11 @@
[submodule "external/opus"] [submodule "external/opus"]
path = external/opus path = external/opus
url = https://github.com/libsdl-org/opus.git url = https://github.com/libsdl-org/opus.git
branch = v1.4-SDL branch = v1.4.x-SDL
[submodule "external/opusfile"] [submodule "external/opusfile"]
path = external/opusfile path = external/opusfile
url = https://github.com/libsdl-org/opusfile.git url = https://github.com/libsdl-org/opusfile.git
branch = v0.12-SDL branch = v0.13-git-SDL
[submodule "external/tremor"] [submodule "external/tremor"]
path = external/tremor path = external/tremor
url = https://github.com/libsdl-org/tremor.git url = https://github.com/libsdl-org/tremor.git
@@ -25,15 +25,15 @@
[submodule "external/mpg123"] [submodule "external/mpg123"]
path = external/mpg123 path = external/mpg123
url = https://github.com/libsdl-org/mpg123.git url = https://github.com/libsdl-org/mpg123.git
branch = v1.31.3-SDL branch = v1.33.4-SDL
[submodule "libxmp"] [submodule "external/libxmp"]
path = external/libxmp path = external/libxmp
url = https://github.com/libsdl-org/libxmp.git url = https://github.com/libsdl-org/libxmp.git
branch = 4.6.2-SDL branch = 4.7.0-SDL
[submodule "external/wavpack"] [submodule "external/wavpack"]
path = external/wavpack path = external/wavpack
url = https://github.com/libsdl-org/wavpack.git url = https://github.com/libsdl-org/wavpack.git
branch = 5.7.0-sdl branch = 5.9.0-SDL
[submodule "external/libgme"] [submodule "external/libgme"]
path = external/libgme path = external/libgme
url = https://github.com/libsdl-org/game-music-emu.git url = https://github.com/libsdl-org/game-music-emu.git
@@ -2,21 +2,23 @@ projectfullname = SDL_mixer
projectshortname = SDL_mixer projectshortname = SDL_mixer
incsubdir = include/SDL3_mixer incsubdir = include/SDL3_mixer
wikisubdir = SDL3_mixer wikisubdir = SDL3_mixer
apiprefixregex = (Mix_|MIX_) apiprefixregex = (MIX_|SDL_MIXER_)
apipropertyregex = \A\s*\#\s*define\s+MIX_PROP_
mainincludefname = SDL3_mixer/SDL_mixer.h mainincludefname = SDL3_mixer/SDL_mixer.h
versionfname = include/SDL3_mixer/SDL_mixer.h versionfname = include/SDL3_mixer/SDL_mixer.h
versionmajorregex = \A\#define\s+SDL_MIXER_MAJOR_VERSION\s+(\d+)\Z versionmajorregex = \A\#define\s+SDL_MIXER_MAJOR_VERSION\s+(\d+)\Z
versionminorregex = \A\#define\s+SDL_MIXER_MINOR_VERSION\s+(\d+)\Z versionminorregex = \A\#define\s+SDL_MIXER_MINOR_VERSION\s+(\d+)\Z
versionmicroregex = \A\#define\s+SDL_MIXER_MICRO_VERSION\s+(\d+)\Z versionmicroregex = \A\#define\s+SDL_MIXER_MICRO_VERSION\s+(\d+)\Z
selectheaderregex = \ASDL_mixer\.h\Z selectheaderregex = \ASDL_mixer\.h\Z
projecturl = https://libsdl.org/projects/SDL_mixer projecturl = https://libsdl.org/projects/SDL_mixer/
wikiurl = https://wiki.libsdl.org/SDL_mixer wikiurl = https://wiki.libsdl.org/SDL3_mixer
bugreporturl = https://github.com/libsdl-org/sdlwiki/issues/new bugreporturl = https://github.com/libsdl-org/sdlwiki/issues/new
readmesubdir = docs
warn_about_missing = 0 warn_about_missing = 0
wikipreamble = (This function is part of SDL_mixer, a separate library from SDL.) wikipreamble = (This function is part of SDL_mixer, a separate library from SDL.)
wikiheaderfiletext = Defined in [<SDL3_mixer/%fname%>](https://github.com/libsdl-org/SDL_mixer/blob/main/include/SDL3_mixer/%fname%) wikiheaderfiletext = Defined in [<SDL3_mixer/%fname%>](https://github.com/libsdl-org/SDL_mixer/blob/main/include/SDL3_mixer/%fname%)
manpageheaderfiletext = Defined in SDL3_mixer/%fname% manpageheaderfiletext = Defined in SDL3_mixer/%fname%
quickrefenabled = 1 quickrefenabled = 1
quickreftitle = SDL3_mixer API Quick Reference quickreftitle = SDL3_mixer API Quick Reference
quickrefurl = https://libsdl.org/ quickrefurl = https://libsdl.org/projects/SDL_mixer/
quickrefdesc = The latest version of this document can be found at https://wiki.libsdl.org/SDL3_mixer/QuickReference quickrefdesc = The latest version of this document can be found at https://wiki.libsdl.org/SDL3_mixer/QuickReference
@@ -12,12 +12,15 @@ SUPPORT_FLAC_LIBFLAC ?= false
FLAC_LIBRARY_PATH := external/flac FLAC_LIBRARY_PATH := external/flac
# Enable this if you want to support loading OGG Vorbis music via stb_vorbis # Enable this if you want to support loading OGG Vorbis music via stb_vorbis
SUPPORT_OGG_STB ?= true SUPPORT_VORBIS_STB ?= true
# Enable this if you want to support loading OGG Vorbis music via Tremor # Enable this if you want to support loading OGG Vorbis music via libvorbis
SUPPORT_OGG ?= false SUPPORT_VORBIS_LIBVORBIS ?= false
OGG_LIBRARY_PATH := external/ogg LIBVORBIS_LIBRARY_PATH := external/vorbis
VORBIS_LIBRARY_PATH := external/tremor
# Enable this if you want to support loading OGG Vorbis music via Tremor (FOR ARM DEVICES WITHOUT A HARDWARE FLOATING POINT UNIT ONLY!)
SUPPORT_VORBIS_LIBTREMOR ?= false
LIBTREMOR_LIBRARY_PATH := external/tremor
# Enable this if you want to support loading MP3 music via dr_mp3 # Enable this if you want to support loading MP3 music via dr_mp3
SUPPORT_MP3_DRMP3 ?= true SUPPORT_MP3_DRMP3 ?= true
@@ -31,17 +34,44 @@ SUPPORT_WAVPACK ?= true
WAVPACK_LIBRARY_PATH := external/wavpack WAVPACK_LIBRARY_PATH := external/wavpack
# Enable this if you want to support loading music via libgme # Enable this if you want to support loading music via libgme
SUPPORT_GME ?= true SUPPORT_GME ?= false
GME_LIBRARY_PATH := external/libgme GME_LIBRARY_PATH := external/libgme
# Enable this if you want to support loading MOD music via XMP-lite # Enable this if you want to support loading MOD music via libxmp
SUPPORT_MOD_XMP ?= false SUPPORT_MOD_XMP ?= false
XMP_LIBRARY_PATH := external/libxmp XMP_LIBRARY_PATH := external/libxmp
# Enable this if you want to support TiMidity # Enable this if you want to support TiMidity
SUPPORT_MID_TIMIDITY ?= false SUPPORT_MID_TIMIDITY ?= false
TIMIDITY_LIBRARY_PATH := src/codecs/timidity TIMIDITY_LIBRARY_PATH := src/timidity
# Enable this if you want to support Opus via libopus
SUPPORT_OPUS ?= false
OPUS_LIBRARY_PATH := external/opus
OPUSFILE_LIBRARY_PATH := external/opusfile
# Make sure we don't build both libtremor and libvorbis. Different implementations of same API.
ifeq ($(SUPPORT_VORBIS_LIBTREMOR),true)
ifeq ($(SUPPORT_VORBIS_LIBVORBIS),true)
$(error Both libtremor and libvorbis support are enabled. Please choose one)
endif
endif
# Multiple things need libogg.
SUPPORT_LIBOGG := false
OGG_LIBRARY_PATH := external/ogg
ifeq ($(SUPPORT_FLAC_LIBFLAC),true)
SUPPORT_LIBOGG := true
endif
ifeq ($(SUPPORT_VORBIS_LIBTREMOR),true)
SUPPORT_LIBOGG := true
VORBIS_LIBRARY_PATH := $(LIBTREMOR_LIBRARY_PATH)
endif
ifeq ($(SUPPORT_VORBIS_LIBVORBIS),true)
SUPPORT_LIBOGG := true
VORBIS_LIBRARY_PATH := $(LIBVORBIS_LIBRARY_PATH)
endif
# Build the library # Build the library
ifeq ($(SUPPORT_FLAC_LIBFLAC),true) ifeq ($(SUPPORT_FLAC_LIBFLAC),true)
@@ -49,8 +79,12 @@ ifeq ($(SUPPORT_FLAC_LIBFLAC),true)
endif endif
# Build the library # Build the library
ifeq ($(SUPPORT_OGG),true) ifeq ($(SUPPORT_LIBOGG),true)
include $(SDL_MIXER_LOCAL_PATH)/$(OGG_LIBRARY_PATH)/Android.mk include $(SDL_MIXER_LOCAL_PATH)/$(OGG_LIBRARY_PATH)/Android.mk
endif
# Build the library (libvorbis or libtremor)
ifneq ($(VORBIS_LIBRARY_PATH),)
include $(SDL_MIXER_LOCAL_PATH)/$(VORBIS_LIBRARY_PATH)/Android.mk include $(SDL_MIXER_LOCAL_PATH)/$(VORBIS_LIBRARY_PATH)/Android.mk
endif endif
@@ -79,6 +113,12 @@ ifeq ($(SUPPORT_MID_TIMIDITY),true)
include $(SDL_MIXER_LOCAL_PATH)/$(TIMIDITY_LIBRARY_PATH)/Android.mk include $(SDL_MIXER_LOCAL_PATH)/$(TIMIDITY_LIBRARY_PATH)/Android.mk
endif endif
# Build the library
ifeq ($(SUPPORT_OPUS),true)
include $(SDL_MIXER_LOCAL_PATH)/$(OPUS_LIBRARY_PATH)/Android.mk
include $(SDL_MIXER_LOCAL_PATH)/$(OPUSFILE_LIBRARY_PATH)/Android.mk
endif
# Restore local path # Restore local path
LOCAL_PATH := $(SDL_MIXER_LOCAL_PATH) LOCAL_PATH := $(SDL_MIXER_LOCAL_PATH)
@@ -86,16 +126,11 @@ include $(CLEAR_VARS)
LOCAL_MODULE := SDL3_mixer LOCAL_MODULE := SDL3_mixer
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/src/ \
$(LOCAL_PATH)/src/codecs \
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
$(subst $(LOCAL_PATH)/,, \ $(subst $(LOCAL_PATH)/,, \
$(wildcard $(LOCAL_PATH)/src/*.c) \ $(wildcard $(LOCAL_PATH)/src/*.c) \
$(wildcard $(LOCAL_PATH)/src/codecs/*.c) \
) )
LOCAL_CFLAGS := LOCAL_CFLAGS :=
@@ -105,63 +140,81 @@ LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := SDL3 LOCAL_SHARED_LIBRARIES := SDL3
ifeq ($(SUPPORT_WAV),true) ifeq ($(SUPPORT_WAV),true)
LOCAL_CFLAGS += -DMUSIC_WAV LOCAL_CFLAGS += -DDECODER_WAV
endif endif
ifeq ($(SUPPORT_FLAC_DRFLAC),true) ifeq ($(SUPPORT_FLAC_DRFLAC),true)
LOCAL_CFLAGS += -DMUSIC_FLAC_DRFLAC LOCAL_CFLAGS += -DDECODER_FLAC_DRFLAC
endif endif
ifeq ($(SUPPORT_FLAC_LIBFLAC),true) ifeq ($(SUPPORT_FLAC_LIBFLAC),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(FLAC_LIBRARY_PATH)/include LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(FLAC_LIBRARY_PATH)/include
LOCAL_CFLAGS += -DMUSIC_FLAC_LIBFLAC LOCAL_CFLAGS += -DDECODER_FLAC_LIBFLAC
LOCAL_STATIC_LIBRARIES += libFLAC LOCAL_STATIC_LIBRARIES += libFLAC
endif endif
ifeq ($(SUPPORT_OGG_STB),true) ifeq ($(SUPPORT_VORBIS_STB),true)
LOCAL_CFLAGS += -DMUSIC_OGG -DOGG_USE_STB LOCAL_CFLAGS += -DDECODER_OGGVORBIS_STB
endif endif
ifeq ($(SUPPORT_OGG),true) ifeq ($(SUPPORT_LIBOGG),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(OGG_LIBRARY_PATH)/include LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(OGG_LIBRARY_PATH)/include
LOCAL_STATIC_LIBRARIES += ogg
endif
ifeq ($(SUPPORT_VORBIS_LIBTREMOR),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(VORBIS_LIBRARY_PATH) LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(VORBIS_LIBRARY_PATH)
LOCAL_CFLAGS += -DMUSIC_OGG -DOGG_USE_TREMOR -DOGG_HEADER="<ivorbisfile.h>" LOCAL_CFLAGS += -DDECODER_OGGVORBIS_VORBISFILE -DVORBIS_USE_TREMOR -DVORBIS_HEADER="<ivorbisfile.h>"
LOCAL_STATIC_LIBRARIES += ogg vorbisidec LOCAL_STATIC_LIBRARIES += vorbisidec
endif
ifeq ($(SUPPORT_VORBIS_LIBVORBIS),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(VORBIS_LIBRARY_PATH)/include
LOCAL_CFLAGS += -DDECODER_OGGVORBIS_VORBISFILE -DVORBIS_HEADER="<vorbis/vorbisfile.h>"
LOCAL_STATIC_LIBRARIES += vorbisdec
endif endif
ifeq ($(SUPPORT_MP3_DRMP3),true) ifeq ($(SUPPORT_MP3_DRMP3),true)
LOCAL_CFLAGS += -DMUSIC_MP3_DRMP3 LOCAL_CFLAGS += -DDECODER_MP3_DRMP3
endif endif
# This needs to be a shared library to comply with the LGPL license # This needs to be a shared library to comply with the LGPL license
ifeq ($(SUPPORT_MP3_MPG123),true) ifeq ($(SUPPORT_MP3_MPG123),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(MPG123_LIBRARY_PATH)/android LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(MPG123_LIBRARY_PATH)/src/include
LOCAL_CFLAGS += -DMUSIC_MP3_MPG123 LOCAL_CFLAGS += -DDECODER_MP3_MPG123
LOCAL_SHARED_LIBRARIES += mpg123 LOCAL_SHARED_LIBRARIES += mpg123
endif endif
ifeq ($(SUPPORT_WAVPACK),true) ifeq ($(SUPPORT_WAVPACK),true)
LOCAL_CFLAGS += -DMUSIC_WAVPACK -DMUSIC_WAVPACK_DSD -DWAVPACK_HEADER=\"../external/wavpack/include/wavpack.h\" LOCAL_CFLAGS += -DDECODER_WAVPACK -DDECODER_WAVPACK_DSD -DWAVPACK_HEADER=\"../external/wavpack/include/wavpack.h\"
LOCAL_STATIC_LIBRARIES += wavpack LOCAL_STATIC_LIBRARIES += wavpack
endif endif
ifeq ($(SUPPORT_GME),true) ifeq ($(SUPPORT_GME),true)
LOCAL_CFLAGS += -DMUSIC_GME LOCAL_CFLAGS += -DDECODER_GME
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(GME_LIBRARY_PATH) LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(GME_LIBRARY_PATH)
LOCAL_STATIC_LIBRARIES += libgme LOCAL_STATIC_LIBRARIES += libgme
endif endif
ifeq ($(SUPPORT_MOD_XMP),true) ifeq ($(SUPPORT_MOD_XMP),true)
LOCAL_CFLAGS += -DMUSIC_MOD_XMP -DLIBXMP_HEADER=\"../external/libxmp/include/xmp.h\" LOCAL_CFLAGS += -DDECODER_MOD_XMP -DLIBXMP_HEADER=\"../external/libxmp/include/xmp.h\"
LOCAL_STATIC_LIBRARIES += xmp LOCAL_STATIC_LIBRARIES += xmp
endif endif
ifeq ($(SUPPORT_MID_TIMIDITY),true) ifeq ($(SUPPORT_MID_TIMIDITY),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(TIMIDITY_LIBRARY_PATH) LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(TIMIDITY_LIBRARY_PATH)
LOCAL_CFLAGS += -DMUSIC_MID_TIMIDITY LOCAL_CFLAGS += -DDECODER_MIDI_TIMIDITY
LOCAL_STATIC_LIBRARIES += timidity LOCAL_STATIC_LIBRARIES += timidity
endif endif
ifeq ($(SUPPORT_OPUS),true)
LOCAL_CFLAGS += -DDECODER_OPUS
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(OPUS_LIBRARY_PATH)/include
LOCAL_STATIC_LIBRARIES += opus
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(OPUSFILE_LIBRARY_PATH)/include
LOCAL_STATIC_LIBRARIES += opusfile
endif
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
+3
View File
@@ -0,0 +1,3 @@
3.2.0:
* First release of SDL3_mixer!
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.16...3.28) cmake_minimum_required(VERSION 3.16...4.0)
if(NOT DEFINED CMAKE_BUILD_TYPE) if(NOT DEFINED CMAKE_BUILD_TYPE)
set(cmake_build_type_undefined 1) set(cmake_build_type_undefined 1)
@@ -8,9 +8,9 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
# See docs/release_checklist.md # See docs/release_checklist.md
set(MAJOR_VERSION 3) set(MAJOR_VERSION 3)
set(MINOR_VERSION 0) set(MINOR_VERSION 2)
set(MICRO_VERSION 0) set(MICRO_VERSION 0)
set(SDL_REQUIRED_VERSION 3.0.0) set(SDL_REQUIRED_VERSION 3.4.0)
project(SDL3_mixer project(SDL3_mixer
LANGUAGES C LANGUAGES C
@@ -49,11 +49,6 @@ if(SDLMIXER_ROOTPROJECT)
endif() endif()
endif() endif()
set(SDLMIXER_SAMPLES_DEFAULT ${SDLMIXER_ROOTPROJECT})
if(ANDROID)
set(SDLMIXER_SAMPLES_DEFAULT OFF)
endif()
# option() honors normal variables. # option() honors normal variables.
cmake_policy(SET CMP0077 NEW) cmake_policy(SET CMP0077 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
@@ -120,90 +115,63 @@ if(SDLMIXER_STRICT)
set(fatal_error "FATAL_ERROR") set(fatal_error "FATAL_ERROR")
endif() endif()
option(SDLMIXER_SAMPLES "Build the SDL3_mixer sample program(s)" ${SDLMIXER_SAMPLES_DEFAULT}) option(SDLMIXER_TESTS "Build unit tests?" ${SDLMIXER_ROOTPROJECT})
cmake_dependent_option(SDLMIXER_SAMPLES_INSTALL "Install the SDL3_mixer sample program(s)" OFF "SDLMIXER_SAMPLES;SDLMIXER_INSTALL" OFF) cmake_dependent_option(SDLMIXER_TESTS_INSTALL "Install unit tests?" ${SDLMIXER_ROOTPROJECT} "SDLMIXER_INSTALL;SDLMIXER_TESTS" OFF)
option(SDLMIXER_EXAMPLES "Build the examples directory" ${SDLMIXER_ROOTPROJECT})
cmake_dependent_option(SDLMIXER_EXAMPLES_INSTALL "Install SDL3_mixer examples" ${SDLMIXER_ROOTPROJECT} "SDLMIXER_INSTALL;SDLMIXER_EXAMPLES" OFF)
option(SDLMIXER_SNDFILE "Support loading sounds via libsndfile" OFF) # These are implemented in SDL_mixer itself, not using a third-party library.
option(SDLMIXER_SNDFILE_SHARED "Dynamically load libsndfile" "${SDLMIXER_DEPS_SHARED}") option(SDLMIXER_AIFF "Enable AIFF audio" ON)
option(SDLMIXER_WAVE "Enable WAVE audio" ON)
option(SDLMIXER_VOC "Enable VOC audio" ON)
option(SDLMIXER_AU "Enable AU audio" ON)
option(SDLMIXER_FLAC "Enable FLAC music" ON) option(SDLMIXER_FLAC "Enable FLAC audio" ON)
cmake_dependent_option(SDLMIXER_FLAC_LIBFLAC "Enable FLAC music using libFLAC" OFF SDLMIXER_FLAC OFF) # Decoders that use third-party dependencies, even if they are compiled in, vendored, etc.
cmake_dependent_option(SDLMIXER_FLAC_LIBFLAC "Enable FLAC audio using libFLAC" ON SDLMIXER_FLAC OFF)
cmake_dependent_option(SDLMIXER_FLAC_LIBFLAC_SHARED "Dynamically load LIBFLAC" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_FLAC_LIBFLAC OFF) cmake_dependent_option(SDLMIXER_FLAC_LIBFLAC_SHARED "Dynamically load LIBFLAC" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_FLAC_LIBFLAC OFF)
cmake_dependent_option(SDLMIXER_FLAC_DRFLAC "Enable FLAC music using drflac" ON SDLMIXER_FLAC OFF) cmake_dependent_option(SDLMIXER_FLAC_DRFLAC "Enable FLAC audio using drflac" ON SDLMIXER_FLAC OFF)
option(SDLMIXER_GME "Support loading GME music via game-music-emu" ON) option(SDLMIXER_GME "Support loading GME audio via game-music-emu" ON)
option(SDLMIXER_GME_SHARED "Dynamically load libgme" "${SDLMIXER_DEPS_SHARED}") option(SDLMIXER_GME_SHARED "Dynamically load libgme" "${SDLMIXER_DEPS_SHARED}")
option(SDLMIXER_MOD "Support loading MOD music" ON) option(SDLMIXER_MOD "Support MOD audio" ON)
cmake_dependent_option(SDLMIXER_MOD_XMP "Support loading MOD music via libxmp" ON SDLMIXER_MOD OFF) cmake_dependent_option(SDLMIXER_MOD_XMP "Support loading MOD audio via libxmp" ON SDLMIXER_MOD OFF)
cmake_dependent_option(SDLMIXER_MOD_XMP_LITE "Use libxmp-lite instead of libxmp" OFF "SDLMIXER_MOD_XMP;NOT SDLMIXER_VENDORED" OFF) cmake_dependent_option(SDLMIXER_MOD_XMP_LITE "Use libxmp-lite instead of libxmp" OFF "SDLMIXER_MOD_XMP;NOT SDLMIXER_VENDORED" OFF)
cmake_dependent_option(SDLMIXER_MOD_XMP_SHARED "Dynamically load libxmp(-lite)" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MOD_XMP OFF) cmake_dependent_option(SDLMIXER_MOD_XMP_SHARED "Dynamically load libxmp(-lite)" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MOD_XMP OFF)
if(SDLMIXER_MOD AND NOT SDLMIXER_MOD_XMP) option(SDLMIXER_MP3 "Enable MP3 audio" ON)
message(FATAL_ERROR "MOD support was enabled (SDLMIXER_MOD) but xmp (SDLMIXER_MOD_XMP) was disabled.")
endif()
option(SDLMIXER_MP3 "Enable MP3 music" ON) cmake_dependent_option(SDLMIXER_MP3_DRMP3 "Support loading MP3 audio via dr_mp3" ON SDLMIXER_MP3 OFF)
cmake_dependent_option(SDLMIXER_MP3_MPG123 "Support loading MP3 audio via libmpg123" ON SDLMIXER_MP3 OFF)
cmake_dependent_option(SDLMIXER_MP3_DRMP3 "Support loading MP3 music via dr_mp3" ON SDLMIXER_MP3 OFF)
cmake_dependent_option(SDLMIXER_MP3_MPG123 "Support loading MP3 music via MPG123" OFF SDLMIXER_MP3 OFF)
cmake_dependent_option(SDLMIXER_MP3_MPG123_SHARED "Dynamically load mpg123" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MP3_MPG123 OFF) cmake_dependent_option(SDLMIXER_MP3_MPG123_SHARED "Dynamically load mpg123" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MP3_MPG123 OFF)
if(SDLMIXER_MP3 AND NOT (SDLMIXER_MP3_DRMP3 OR SDLMIXER_MP3_MPG123)) option(SDLMIXER_MIDI "Enable MIDI audio" ON)
message(FATAL_ERROR "MP3 support was enabled (SDLMIXER_MP3) but neither drmp3 (SDLMIXER_MP3_DRMP3) or mpg123 (SDLMIXER_MP3_MPG123) were enabled.")
endif()
option(SDLMIXER_MIDI "Enable MIDI music" ON)
cmake_dependent_option(SDLMIXER_MIDI_FLUIDSYNTH "Support FluidSynth MIDI output" ON "SDLMIXER_MIDI;NOT SDLMIXER_VENDORED" OFF) cmake_dependent_option(SDLMIXER_MIDI_FLUIDSYNTH "Support FluidSynth MIDI output" ON "SDLMIXER_MIDI;NOT SDLMIXER_VENDORED" OFF)
cmake_dependent_option(SDLMIXER_MIDI_FLUIDSYNTH_SHARED "Dynamically load libfluidsynth" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MIDI_FLUIDSYNTH OFF) cmake_dependent_option(SDLMIXER_MIDI_FLUIDSYNTH_SHARED "Dynamically load libfluidsynth" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MIDI_FLUIDSYNTH OFF)
if(WIN32 OR APPLE OR HAIKU OR "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
cmake_dependent_option(SDLMIXER_MIDI_NATIVE "Support native MIDI output" ON SDLMIXER_MIDI OFF)
else()
set(SDLMIXER_MIDI_NATIVE OFF)
endif()
cmake_dependent_option(SDLMIXER_MIDI_TIMIDITY "Support timidity MIDI output" ON SDLMIXER_MIDI OFF) cmake_dependent_option(SDLMIXER_MIDI_TIMIDITY "Support timidity MIDI output" ON SDLMIXER_MIDI OFF)
if(SDLMIXER_MIDI AND NOT (SDLMIXER_MIDI_TIMIDITY OR SDLMIXER_MIDI_NATIVE OR SDLMIXER_MIDI_FLUIDSYNTH)) option(SDLMIXER_OPUS "Enable Opus audio via libopus" ON)
message(FATAL_ERROR "MIDI support was enabled (SDLMIXER_MIDI) but neither FluidSynth (SDLMIXER_MIDI_FLUIDSYNTH), native (SDLMIXER_MIDI_NATIVE) or timidity (SDLMIXER_MIDI_TIMIDITY) was enabled")
endif()
option(SDLMIXER_OPUS "Enable Opus music" ON)
cmake_dependent_option(SDLMIXER_OPUS_SHARED "Dynamically load libopus" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_OPUS OFF) cmake_dependent_option(SDLMIXER_OPUS_SHARED "Dynamically load libopus" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_OPUS OFF)
set(sdl3mixer_vorbis_strings STB TREMOR VORBISFILE) option(SDLMIXER_VORBIS_STB "Enable Ogg Vorbis audio via stb_vorbis" ON)
set(SDLMIXER_VORBIS "STB" CACHE STRING "Enable OGG Vorbis music") option(SDLMIXER_VORBIS_VORBISFILE "Enable Ogg Vorbis audio via libvorbisfile" ON)
set_property(CACHE SDLMIXER_VORBIS PROPERTY STRINGS "${sdl3mixer_vorbis_strings}") option(SDLMIXER_VORBIS_TREMOR "Enable Ogg Vorbis audio via libvorbisidec ('tremor')" OFF)
if(SDLMIXER_VORBIS)
if(NOT SDLMIXER_VORBIS IN_LIST sdl3mixer_vorbis_strings) if (SDLMIXER_VORBIS_VORBISFILE AND SDLMIXER_VORBIS_TREMOR)
message(FATAL_ERROR "SDLMIXER_VORBIS contains an invalid value (=${SDLMIXER_VORBIS}). It must be one of ${sdl3mixer_vorbis_strings}.") message(FATAL_ERROR "Both SDLMIXER_VORBIS_VORBISFILE and SDLMIXER_VORBIS_TREMOR are both enabled, but only one can be used")
endif()
endif() endif()
set(SDLMIXER_VORBIS_STB OFF)
set(SDLMIXER_VORBIS_TREMOR OFF)
set(SDLMIXER_VORBIS_VORBISFILE OFF)
if(SDLMIXER_VORBIS STREQUAL "STB")
set(SDLMIXER_VORBIS_STB ON)
endif()
if(SDLMIXER_VORBIS STREQUAL "TREMOR")
set(SDLMIXER_VORBIS_TREMOR ON)
endif()
if(SDLMIXER_VORBIS STREQUAL "VORBISFILE")
set(SDLMIXER_VORBIS_VORBISFILE ON)
endif()
cmake_dependent_option(SDLMIXER_VORBIS_TREMOR_SHARED "Dynamically load tremor library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_TREMOR OFF)
cmake_dependent_option(SDLMIXER_VORBIS_VORBISFILE_SHARED "Dynamically load vorbisfile library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_VORBISFILE OFF) cmake_dependent_option(SDLMIXER_VORBIS_VORBISFILE_SHARED "Dynamically load vorbisfile library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_VORBISFILE OFF)
cmake_dependent_option(SDLMIXER_VORBIS_TREMOR_SHARED "Dynamically load vorbisidec ('tremor') library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_TREMOR OFF)
option(SDLMIXER_WAVE "Enable streaming WAVE music" ON) option(SDLMIXER_WAVPACK "Enable WavPack audio" ON)
cmake_dependent_option(SDLMIXER_WAVPACK_DSD "Enable WavPack DSD audio support" OFF SDLMIXER_WAVPACK OFF)
option(SDLMIXER_WAVPACK "Enable WavPack music" ON)
cmake_dependent_option(SDLMIXER_WAVPACK_DSD "Enable WavPack DSD music support" OFF SDLMIXER_WAVPACK OFF)
cmake_dependent_option(SDLMIXER_WAVPACK_SHARED "Dynamically load WavPack library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_WAVPACK OFF) cmake_dependent_option(SDLMIXER_WAVPACK_SHARED "Dynamically load WavPack library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_WAVPACK OFF)
if(SDLMIXER_VORBIS_TREMOR OR SDLMIXER_VORBIS_VORBISFILE OR SDLMIXER_FLAC_LIBFLAC OR SDLMIXER_OPUS) if(SDLMIXER_VORBIS_TREMOR OR SDLMIXER_VORBIS_VORBISFILE OR SDLMIXER_FLAC_LIBFLAC OR SDLMIXER_OPUS)
@@ -241,40 +209,48 @@ if(NOT TARGET SDL3::Headers OR NOT TARGET ${sdl3_target_name})
find_package(SDL3 ${SDL_REQUIRED_VERSION} REQUIRED COMPONENTS ${sdl_required_components}) find_package(SDL3 ${SDL_REQUIRED_VERSION} REQUIRED COMPONENTS ${sdl_required_components})
endif() endif()
set(install_license_names)
macro(register_license NAME FILE)
list(APPEND install_license_names ${NAME})
set(install_license_${NAME} "${FILE}")
endmacro()
SDL_DetectTargetCPUArchitectures(SDL_CPU_NAMES) SDL_DetectTargetCPUArchitectures(SDL_CPU_NAMES)
SDL_DetectCMakePlatform() SDL_DetectCMakePlatform()
set(BUILD_SHARED_LIBS ${SDLMIXER_BUILD_SHARED_LIBS}) set(BUILD_SHARED_LIBS ${SDLMIXER_BUILD_SHARED_LIBS})
add_library(${sdl3_mixer_target_name} add_library(${sdl3_mixer_target_name}
src/codecs/load_aiff.c src/SDL_mixer.c
src/codecs/load_voc.c src/SDL_mixer_metadata_tags.c
src/codecs/load_sndfile.c src/SDL_mixer_spatialization.c
src/codecs/mp3utils.c src/decoder_aiff.c
src/codecs/music_drflac.c src/decoder_au.c
src/codecs/music_drmp3.c src/decoder_drflac.c
src/codecs/music_flac.c src/decoder_drmp3.c
src/codecs/music_fluidsynth.c src/decoder_flac.c
src/codecs/music_gme.c src/decoder_fluidsynth.c
src/codecs/music_mpg123.c src/decoder_gme.c
src/codecs/music_nativemidi.c src/decoder_mpg123.c
src/codecs/music_ogg.c src/decoder_opus.c
src/codecs/music_ogg_stb.c src/decoder_raw.c
src/codecs/music_opus.c src/decoder_sinewave.c
src/codecs/music_timidity.c src/decoder_stb_vorbis.c
src/codecs/music_wav.c src/decoder_timidity.c
src/codecs/music_wavpack.c src/decoder_voc.c
src/codecs/music_xmp.c src/decoder_vorbis.c
src/effect_position.c src/decoder_wav.c
src/effect_stereoreverse.c src/decoder_wavpack.c
src/effects_internal.c src/decoder_xmp.c
src/mixer.c
src/music.c
src/utils.c
) )
add_library(SDL3_mixer::${sdl3_mixer_target_name} ALIAS ${sdl3_mixer_target_name}) add_library(SDL3_mixer::${sdl3_mixer_target_name} ALIAS ${sdl3_mixer_target_name})
if(NOT TARGET SDL3_mixer::SDL3_mixer) if(NOT TARGET SDL3_mixer::SDL3_mixer)
add_library(SDL3_mixer::SDL3_mixer ALIAS ${sdl3_mixer_target_name}) add_library(SDL3_mixer::SDL3_mixer ALIAS ${sdl3_mixer_target_name})
endif() endif()
if("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES)
target_compile_features(${sdl3_mixer_target_name} PRIVATE c_std_99)
else()
message(WARNING "target_compile_features does not know c_std_99 for C compiler")
endif()
target_include_directories(${sdl3_mixer_target_name} target_include_directories(${sdl3_mixer_target_name}
PUBLIC PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
@@ -289,6 +265,8 @@ target_compile_definitions(${sdl3_mixer_target_name} PRIVATE
SDL_BUILD_MINOR_VERSION=${MINOR_VERSION} SDL_BUILD_MINOR_VERSION=${MINOR_VERSION}
SDL_BUILD_MICRO_VERSION=${MICRO_VERSION} SDL_BUILD_MICRO_VERSION=${MICRO_VERSION}
) )
# Make sure SDL3's include directory comes first
target_include_directories(${sdl3_mixer_target_name} PRIVATE $<TARGET_PROPERTY:SDL3::Headers,INTERFACE_INCLUDE_DIRECTORIES>)
target_link_libraries(${sdl3_mixer_target_name} PUBLIC SDL3::Headers) target_link_libraries(${sdl3_mixer_target_name} PUBLIC SDL3::Headers)
if(SDLMIXER_BUILD_SHARED_LIBS) if(SDLMIXER_BUILD_SHARED_LIBS)
target_link_libraries(${sdl3_mixer_target_name} PRIVATE SDL3::SDL3-shared) target_link_libraries(${sdl3_mixer_target_name} PRIVATE SDL3::SDL3-shared)
@@ -317,11 +295,14 @@ if(NOT ANDROID)
VERSION "${SO_VERSION}" VERSION "${SO_VERSION}"
) )
if(APPLE) if(APPLE)
cmake_minimum_required(VERSION 3.17...3.28)
set_target_properties(${sdl3_mixer_target_name} PROPERTIES set_target_properties(${sdl3_mixer_target_name} PROPERTIES
MACHO_COMPATIBILITY_VERSION "${DYLIB_COMPAT_VERSION}" MACHO_COMPATIBILITY_VERSION "${DYLIB_COMPAT_VERSION}"
MACHO_CURRENT_VERSION "${DYLIB_CURRENT_VERSION}" MACHO_CURRENT_VERSION "${DYLIB_CURRENT_VERSION}"
) )
set_property(TARGET ${sdl3_mixer_target_name} APPEND PROPERTY LINK_DEPENDS
"${PROJECT_SOURCE_DIR}/src/SDL_mixer.exports")
target_link_options(${sdl3_mixer_target_name} PRIVATE
"SHELL:-Wl,-exported_symbols_list,${PROJECT_SOURCE_DIR}/src/SDL_mixer.exports")
endif() endif()
endif() endif()
if(SDLMIXER_BUILD_SHARED_LIBS) if(SDLMIXER_BUILD_SHARED_LIBS)
@@ -359,46 +340,8 @@ set(PC_LIBS)
set(PC_REQUIRES) set(PC_REQUIRES)
set(SDLMIXER_BACKENDS) set(SDLMIXER_BACKENDS)
list(APPEND SDLMIXER_BACKENDS SNDFILE)
set(SDLMIXER_SNDFILE_ENABLED FALSE)
if(SDLMIXER_SNDFILE)
if(SDLMIXER_VENDORED)
message(STATUS "Using vendored libsndfile")
message(${fatal_error} "libsndfile is not vendored.")
else()
find_package(SndFile ${required})
if(SndFile_FOUND)
set(SDLMIXER_SNDFILE_ENABLED TRUE)
message(STATUS "Using system libsndfile")
if(NOT SDLMIXER_SNDFILE_SHARED)
list(APPEND PC_REQUIRES sndfile)
endif()
else()
message(${fatal_error} "libsndfile NOT found")
endif()
endif()
if(SDLMIXER_SNDFILE_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE LOAD_SNDFILE)
if(SDLMIXER_SNDFILE_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:SndFile::sndfile,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
)
target_get_dynamic_library(dynamic_sndfile SndFile::sndfile)
message(STATUS "Dynamic libsndfile: ${dynamic_sndfile}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "SNDFILE_DYNAMIC=\"${dynamic_sndfile}\"")
if(SDLMIXER_VENDORED)
add_dependencies(${sdl3_mixer_target_name} SndFile::sndfile)
endif()
else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE SndFile::sndfile)
endif()
endif()
endif()
if(SDLMIXER_OGG) if(SDLMIXER_OGG)
# libogg is a requirement of libflac, libtremor and libvorbisfile, so only need this library when vendoring # libogg is a requirement of libflac, libvorbisidec and libvorbisfile, so only need this library when vendoring
if(SDLMIXER_VENDORED) if(SDLMIXER_VENDORED)
message(STATUS "Using vendored libogg") message(STATUS "Using vendored libogg")
set(BUILD_SHARED_LIBS ${SDLMIXER_OGG_SHARED}) set(BUILD_SHARED_LIBS ${SDLMIXER_OGG_SHARED})
@@ -406,6 +349,7 @@ if(SDLMIXER_OGG)
set(BUILD_TESTING OFF) set(BUILD_TESTING OFF)
sdl_check_project_in_subfolder(external/ogg ogg SDLMIXER_VENDORED) sdl_check_project_in_subfolder(external/ogg ogg SDLMIXER_VENDORED)
add_subdirectory(external/ogg external/ogg-build EXCLUDE_FROM_ALL) add_subdirectory(external/ogg external/ogg-build EXCLUDE_FROM_ALL)
register_license(ogg-vorbis external/ogg/COPYING)
if(SDLMIXER_OGG_install) if(SDLMIXER_OGG_install)
list(APPEND INSTALL_EXTRA_TARGETS ogg) list(APPEND INSTALL_EXTRA_TARGETS ogg)
endif() endif()
@@ -426,6 +370,7 @@ if(SDLMIXER_OPUS)
set(BUILD_PROGRAMS OFF) set(BUILD_PROGRAMS OFF)
sdl_check_project_in_subfolder(external/opus opus SDLMIXER_VENDORED) sdl_check_project_in_subfolder(external/opus opus SDLMIXER_VENDORED)
add_subdirectory(external/opus external/opus-build EXCLUDE_FROM_ALL) add_subdirectory(external/opus external/opus-build EXCLUDE_FROM_ALL)
register_license(opus external/opus/COPYING)
set(OP_DISABLE_DOCS TRUE) set(OP_DISABLE_DOCS TRUE)
set(OP_DISABLE_EXAMPLES TRUE) set(OP_DISABLE_EXAMPLES TRUE)
@@ -434,6 +379,7 @@ if(SDLMIXER_OPUS)
set(BUILD_SHARED_LIBS ${SDLMIXER_OPUS_SHARED}) set(BUILD_SHARED_LIBS ${SDLMIXER_OPUS_SHARED})
sdl_check_project_in_subfolder(external/opusfile opusfile SDLMIXER_VENDORED) sdl_check_project_in_subfolder(external/opusfile opusfile SDLMIXER_VENDORED)
add_subdirectory(external/opusfile external/opusfile-build EXCLUDE_FROM_ALL) add_subdirectory(external/opusfile external/opusfile-build EXCLUDE_FROM_ALL)
register_license(opusfile external/opusfile/COPYING)
if(MSVC) if(MSVC)
set_property(TARGET opusfile PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS TRUE) set_property(TARGET opusfile PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
endif() endif()
@@ -454,6 +400,9 @@ if(SDLMIXER_OPUS)
if(NOT SDLMIXER_OPUS_SHARED) if(NOT SDLMIXER_OPUS_SHARED)
list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:opusfile> -l$<TARGET_FILE_BASE_NAME:opus> -l$<TARGET_FILE_BASE_NAME:ogg>) list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:opusfile> -l$<TARGET_FILE_BASE_NAME:opus> -l$<TARGET_FILE_BASE_NAME:ogg>)
endif() endif()
elseif(SDLMIXER_OPUS_SHARED AND DEFINED SDLMIXER_DYNAMIC_OPUSFILE AND EXISTS "${SDLMIXER_DYNAMIC_OPUSFILE}")
message(STATUS "${PROJECT_NAME}: Using opusfile from CMake variable")
set(SDLMIXER_OPUS_ENABLED TRUE)
else() else()
find_package(OpusFile ${required}) find_package(OpusFile ${required})
if(OpusFile_FOUND AND Ogg_FOUND) if(OpusFile_FOUND AND Ogg_FOUND)
@@ -467,19 +416,21 @@ if(SDLMIXER_OPUS)
endif() endif()
endif() endif()
if(SDLMIXER_OPUS_ENABLED) if(SDLMIXER_OPUS_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OPUS) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OPUS)
if(SDLMIXER_OPUS_SHARED) if(SDLMIXER_OPUS_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_OPUSFILE)
$<TARGET_PROPERTY:OpusFile::opusfile,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:OpusFile::opusfile,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_opusfile OpusFile::opusfile) )
message(STATUS "Dynamic opus (opusfile): ${dynamic_opusfile}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OPUS_DYNAMIC=\"${dynamic_opusfile}\"") add_dependencies(${sdl3_mixer_target_name} OpusFile::opusfile)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} OpusFile::opusfile)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_OPUSFILE OpusFile::opusfile)
message(STATUS "Dynamic opus (opusfile): ${SDLMIXER_DYNAMIC_OPUSFILE}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OPUS_DYNAMIC=\"${SDLMIXER_DYNAMIC_OPUSFILE}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE OpusFile::opusfile) target_link_libraries(${sdl3_mixer_target_name} PRIVATE OpusFile::opusfile)
endif() endif()
@@ -490,9 +441,7 @@ list(APPEND SDLMIXER_BACKENDS VORBIS_STB)
set(SDLMIXER_VORBIS_STB_ENABLED FALSE) set(SDLMIXER_VORBIS_STB_ENABLED FALSE)
if(SDLMIXER_VORBIS_STB) if(SDLMIXER_VORBIS_STB)
set(SDLMIXER_VORBIS_STB_ENABLED TRUE) set(SDLMIXER_VORBIS_STB_ENABLED TRUE)
message(STATUS "Enabled ogg music: using stb_vorbis") target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OGGVORBIS_STB)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE OGG_USE_STB)
endif() endif()
list(APPEND SDLMIXER_BACKENDS VORBIS_TREMOR) list(APPEND SDLMIXER_BACKENDS VORBIS_TREMOR)
@@ -508,6 +457,7 @@ if(SDLMIXER_VORBIS_TREMOR)
set(BUILD_SHARED_LIBS ${SDLMIXER_VORBIS_TREMOR_SHARED}) set(BUILD_SHARED_LIBS ${SDLMIXER_VORBIS_TREMOR_SHARED})
sdl_check_project_in_subfolder(external/tremor tremor SDLMIXER_VENDORED) sdl_check_project_in_subfolder(external/tremor tremor SDLMIXER_VENDORED)
add_subdirectory(external/tremor external/tremor-build EXCLUDE_FROM_ALL) add_subdirectory(external/tremor external/tremor-build EXCLUDE_FROM_ALL)
register_license(tremor external/tremor/COPYING)
if(NOT TARGET tremor::tremor) if(NOT TARGET tremor::tremor)
add_library(tremor::tremor ALIAS vorbisidec) add_library(tremor::tremor ALIAS vorbisidec)
endif() endif()
@@ -524,12 +474,15 @@ if(SDLMIXER_VORBIS_TREMOR)
if(NOT SDLMIXER_VORBIS_TREMOR_SHARED) if(NOT SDLMIXER_VORBIS_TREMOR_SHARED)
list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:vorbisidec> -l$<TARGET_FILE_BASE_NAME:ogg>) list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:vorbisidec> -l$<TARGET_FILE_BASE_NAME:ogg>)
endif() endif()
elseif(SDLMIXER_VORBIS_TREMOR_SHARED AND DEFINED SDLMIXER_DYNAMIC_VORBIS_TREMOR AND EXISTS "${SDLMIXER_DYNAMIC_VORBIS_TREMOR}")
message(STATUS "${PROJECT_NAME}: Using tremor from CMake variable")
set(SDLMIXER_VORBIS_TREMOR_ENABLED TRUE)
else() else()
message(STATUS "Using system tremor") message(STATUS "Using system tremor")
find_package(tremor ${required}) find_package(tremor ${required})
if(tremor_FOUND) if(tremor_FOUND)
if(NOT SDLMIXER_VORBIS_TREMOR_SHARED) if(NOT SDLMIXER_VORBIS_TREMOR_SHARED)
list(APPEND PC_REQUIRES tremor) list(APPEND PC_REQUIRES vorbisidec)
endif() endif()
set(SDLMIXER_VORBIS_TREMOR_ENABLED TRUE) set(SDLMIXER_VORBIS_TREMOR_ENABLED TRUE)
else() else()
@@ -537,19 +490,21 @@ if(SDLMIXER_VORBIS_TREMOR)
endif() endif()
endif() endif()
if(SDLMIXER_VORBIS_TREMOR_ENABLED) if(SDLMIXER_VORBIS_TREMOR_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG OGG_USE_TREMOR) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OGGVORBIS_VORBISFILE VORBIS_USE_TREMOR)
if(SDLMIXER_VORBIS_TREMOR_SHARED) if(SDLMIXER_VORBIS_TREMOR_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_VORBIS_TREMOR)
$<TARGET_PROPERTY:tremor::tremor,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:tremor::tremor,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:tremor::tremor,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:tremor::tremor,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:tremor::tremor,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:tremor::tremor,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_tremor tremor::tremor) )
message(STATUS "Dynamic vorbis (tremor): ${dynamic_tremor}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_tremor}\"") add_dependencies(${sdl3_mixer_target_name} tremor::tremor)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} tremor::tremor)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_VORBIS_TREMOR tremor::tremor)
message(STATUS "Dynamic vorbis (tremor): ${SDLMIXER_DYNAMIC_VORBIS_TREMOR}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "VORBIS_DYNAMIC=\"${SDLMIXER_DYNAMIC_VORBIS_TREMOR}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE tremor::tremor) target_link_libraries(${sdl3_mixer_target_name} PRIVATE tremor::tremor)
endif() endif()
@@ -569,6 +524,7 @@ if(SDLMIXER_VORBIS_VORBISFILE)
set(BUILD_SHARED_LIBS ${SDLMIXER_VORBIS_VORBISFILE_SHARED}) set(BUILD_SHARED_LIBS ${SDLMIXER_VORBIS_VORBISFILE_SHARED})
sdl_check_project_in_subfolder(external/vorbis vorbisfile SDLMIXER_VENDORED) sdl_check_project_in_subfolder(external/vorbis vorbisfile SDLMIXER_VENDORED)
add_subdirectory(external/vorbis external/vorbis-build EXCLUDE_FROM_ALL) add_subdirectory(external/vorbis external/vorbis-build EXCLUDE_FROM_ALL)
register_license(vorbis external/vorbis/COPYING)
if(NOT TARGET Vorbis::vorbisfile) if(NOT TARGET Vorbis::vorbisfile)
add_library(Vorbis::vorbisfile ALIAS vorbisfile) add_library(Vorbis::vorbisfile ALIAS vorbisfile)
endif() endif()
@@ -578,6 +534,9 @@ if(SDLMIXER_VORBIS_VORBISFILE)
if(NOT SDLMIXER_VORBIS_VORBISFILE_SHARED) if(NOT SDLMIXER_VORBIS_VORBISFILE_SHARED)
list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:vorbisfile>) list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:vorbisfile>)
endif() endif()
elseif(SDLMIXER_VORBIS_VORBISFILE_SHARED AND DEFINED SDLMIXER_DYNAMIC_VORBIS_VORBISFILE AND EXISTS "${SDLMIXER_DYNAMIC_VORBIS_VORBISFILE}")
message(STATUS "${PROJECT_NAME}: Using vorbisfile from CMake variable")
set(SDLMIXER_VORBIS_VORBISFILE_ENABLED TRUE)
else() else()
find_package(Vorbis ${required}) find_package(Vorbis ${required})
if(Vorbis_FOUND) if(Vorbis_FOUND)
@@ -591,19 +550,21 @@ if(SDLMIXER_VORBIS_VORBISFILE)
endif() endif()
endif() endif()
if(SDLMIXER_VORBIS_VORBISFILE_ENABLED) if(SDLMIXER_VORBIS_VORBISFILE_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OGGVORBIS_VORBISFILE)
if(SDLMIXER_VORBIS_VORBISFILE_SHARED) if(SDLMIXER_VORBIS_VORBISFILE_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_VORBIS_VORBISFILE)
$<TARGET_PROPERTY:Vorbis::vorbisfile,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:Vorbis::vorbisfile,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_vorbisfile Vorbis::vorbisfile) )
message(STATUS "Dynamic vorbisfile: ${dynamic_vorbisfile}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_vorbisfile}\"") add_dependencies(${sdl3_mixer_target_name} Vorbis::vorbisfile)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} Vorbis::vorbisfile)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_VORBIS_VORBISFILE Vorbis::vorbisfile)
message(STATUS "Dynamic vorbisfile: ${SDLMIXER_DYNAMIC_VORBIS_VORBISFILE}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "VORBIS_DYNAMIC=\"${SDLMIXER_DYNAMIC_VORBIS_VORBISFILE}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE Vorbis::vorbisfile) target_link_libraries(${sdl3_mixer_target_name} PRIVATE Vorbis::vorbisfile)
endif() endif()
@@ -635,12 +596,16 @@ if(SDLMIXER_FLAC_LIBFLAC)
message(STATUS "Using vendored libflac") message(STATUS "Using vendored libflac")
sdl_check_project_in_subfolder(external/flac libflac SDLMIXER_VENDORED) sdl_check_project_in_subfolder(external/flac libflac SDLMIXER_VENDORED)
add_subdirectory(external/flac external/flac-build EXCLUDE_FROM_ALL) add_subdirectory(external/flac external/flac-build EXCLUDE_FROM_ALL)
register_license(flac external/flac/COPYING.Xiph)
if(SDLMIXER_FLAC_LIBFLAC_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS) if(SDLMIXER_FLAC_LIBFLAC_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS)
list(APPEND INSTALL_EXTRA_TARGETS FLAC) list(APPEND INSTALL_EXTRA_TARGETS FLAC)
endif() endif()
if(NOT SDLMIXER_FLAC_LIBFLAC_SHARED) if(NOT SDLMIXER_FLAC_LIBFLAC_SHARED)
list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:FLAC::FLAC> -l$<TARGET_FILE_BASE_NAME:ogg>) list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:FLAC::FLAC> -l$<TARGET_FILE_BASE_NAME:ogg>)
endif() endif()
elseif(SDLMIXER_FLAC_LIBFLAC_SHARED AND DEFINED SDLMIXER_DYNAMIC_FLAC_LIBFLAC AND EXISTS "${SDLMIXER_DYNAMIC_FLAC_LIBFLAC}")
message(STATUS "${PROJECT_NAME}: Using libflac from CMake variable")
set(SDLMIXER_FLAC_LIBFLAC_ENABLED TRUE)
else() else()
find_package(FLAC ${required}) find_package(FLAC ${required})
if(FLAC_FOUND) if(FLAC_FOUND)
@@ -649,24 +614,32 @@ if(SDLMIXER_FLAC_LIBFLAC)
if(NOT SDLMIXER_FLAC_LIBFLAC_SHARED) if(NOT SDLMIXER_FLAC_LIBFLAC_SHARED)
list(APPEND PC_REQUIRES flac) list(APPEND PC_REQUIRES flac)
endif() endif()
# Xiph's CMake script does not handle Threads::Threads correctly:
# https://github.com/xiph/flac/issues/820
get_property(flac_interface_link_libraries TARGET FLAC::FLAC PROPERTY INTERFACE_LINK_LIBRARIES)
if(Threads::Threads IN_LIST flac_interface_link_libraries)
find_package(Threads)
endif()
else() else()
message(${fatal_error} "libflac NOT found") message(${fatal_error} "libflac NOT found")
endif() endif()
endif() endif()
if(SDLMIXER_FLAC_LIBFLAC_ENABLED) if(SDLMIXER_FLAC_LIBFLAC_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_FLAC_LIBFLAC) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_FLAC_LIBFLAC)
if(SDLMIXER_FLAC_LIBFLAC_SHARED) if(SDLMIXER_FLAC_LIBFLAC_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_FLAC_LIBFLAC)
$<TARGET_PROPERTY:FLAC::FLAC,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:FLAC::FLAC,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_flac FLAC::FLAC) )
message(STATUS "Dynamic libflac: ${dynamic_flac}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "FLAC_DYNAMIC=\"${dynamic_flac}\"") add_dependencies(${sdl3_mixer_target_name} FLAC)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} FLAC)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_FLAC_LIBFLAC FLAC::FLAC)
message(STATUS "Dynamic libflac: ${SDLMIXER_DYNAMIC_FLAC_LIBFLAC}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "FLAC_DYNAMIC=\"${SDLMIXER_DYNAMIC_FLAC_LIBFLAC}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE FLAC::FLAC) target_link_libraries(${sdl3_mixer_target_name} PRIVATE FLAC::FLAC)
endif() endif()
@@ -677,7 +650,7 @@ list(APPEND SDLMIXER_BACKENDS FLAC_DRFLAC)
set(SDLMIXER_FLAC_DRFLAC_ENABLED FALSE) set(SDLMIXER_FLAC_DRFLAC_ENABLED FALSE)
if(SDLMIXER_FLAC_DRFLAC) if(SDLMIXER_FLAC_DRFLAC)
set(SDLMIXER_FLAC_DRFLAC_ENABLED TRUE) set(SDLMIXER_FLAC_DRFLAC_ENABLED TRUE)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_FLAC_DRFLAC) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_FLAC_DRFLAC)
endif() endif()
set(SDLMIXER_FLAC_ENABLED FALSE) set(SDLMIXER_FLAC_ENABLED FALSE)
@@ -693,10 +666,10 @@ if(SDLMIXER_GME)
set(GME_BUILD_SHARED "${SDLMIXER_GME_SHARED}") set(GME_BUILD_SHARED "${SDLMIXER_GME_SHARED}")
if(SDLMIXER_GME_SHARED) if(SDLMIXER_GME_SHARED)
set(GME_BUILD_STATIC OFF) set(GME_BUILD_STATIC OFF)
set(tgt_gme gme_shared) set(targets_gme gme_shared)
else() else()
set(GME_BUILD_STATIC ON) set(GME_BUILD_STATIC ON)
set(tgt_gme gme_static) set(targets_gme gme_static gme_deps)
endif() endif()
set(GME_BUILD_FRAMEWORK OFF) set(GME_BUILD_FRAMEWORK OFF)
set(GME_BUILD_TESTING OFF) set(GME_BUILD_TESTING OFF)
@@ -707,12 +680,16 @@ if(SDLMIXER_GME)
sdl_check_project_in_subfolder(external/libgme libgme SDLMIXER_VENDORED) sdl_check_project_in_subfolder(external/libgme libgme SDLMIXER_VENDORED)
enable_language(CXX) enable_language(CXX)
add_subdirectory(external/libgme external/libgme-build EXCLUDE_FROM_ALL) add_subdirectory(external/libgme external/libgme-build EXCLUDE_FROM_ALL)
register_license(gme external/libgme/license.txt)
if(SDLMIXER_GME_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS) if(SDLMIXER_GME_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS)
list(APPEND INSTALL_EXTRA_TARGETS ${tgt_gme}) list(APPEND INSTALL_EXTRA_TARGETS ${targets_gme})
endif() endif()
if(NOT SDLMIXER_GME_SHARED) if(NOT SDLMIXER_GME_SHARED)
list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:gme>) list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:gme>)
endif() endif()
elseif(SDLMIXER_GME_SHARED AND DEFINED SDLMIXER_DYNAMIC_GME AND EXISTS "${SDLMIXER_DYNAMIC_GME}")
message(STATUS "${PROJECT_NAME}: Using libgme from CMake variable")
set(SDLMIXER_GME_ENABLED TRUE)
else() else()
find_package(gme ${required}) find_package(gme ${required})
if(gme_FOUND) if(gme_FOUND)
@@ -726,19 +703,21 @@ if(SDLMIXER_GME)
endif() endif()
endif() endif()
if(SDLMIXER_GME_ENABLED) if(SDLMIXER_GME_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_GME) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_GME)
if(SDLMIXER_GME_SHARED) if(SDLMIXER_GME_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_GME)
$<TARGET_PROPERTY:gme::gme,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:gme::gme,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:gme::gme,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:gme::gme,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:gme::gme,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:gme::gme,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_gme gme::gme) )
message(STATUS "Dynamic libgme: ${dynamic_gme}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "GME_DYNAMIC=\"${dynamic_gme}\"") add_dependencies(${sdl3_mixer_target_name} gme::gme)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} gme::gme)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_GME gme::gme)
message(STATUS "Dynamic libgme: ${SDLMIXER_DYNAMIC_GME}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "GME_DYNAMIC=\"${SDLMIXER_DYNAMIC_GME}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE gme::gme) target_link_libraries(${sdl3_mixer_target_name} PRIVATE gme::gme)
endif() endif()
@@ -765,6 +744,7 @@ if(SDLMIXER_MOD_XMP)
endif() endif()
set(xmp_name libxmp) set(xmp_name libxmp)
add_subdirectory(external/libxmp external/libxmp-build EXCLUDE_FROM_ALL) add_subdirectory(external/libxmp external/libxmp-build EXCLUDE_FROM_ALL)
register_license(xmp external/libxmp/docs/COPYING)
if(SDLMIXER_MOD_XMP_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS) if(SDLMIXER_MOD_XMP_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS)
list(APPEND INSTALL_EXTRA_TARGETS ${tgt_xmp}) list(APPEND INSTALL_EXTRA_TARGETS ${tgt_xmp})
endif() endif()
@@ -785,6 +765,9 @@ if(SDLMIXER_MOD_XMP)
else() else()
message(${fatal_error} "libxmp-lite NOT found") message(${fatal_error} "libxmp-lite NOT found")
endif() endif()
elseif(SDLMIXER_MOD_XMP_SHARED AND DEFINED SDLMIXER_DYNAMIC_MOD_XMP AND EXISTS "${SDLMIXER_DYNAMIC_MOD_XMP}")
message(STATUS "${PROJECT_NAME}: Using libxmp from CMake variable")
set(SDLMIXER_MOD_XMP_ENABLED TRUE)
else() else()
find_package(libxmp ${required}) find_package(libxmp ${required})
if(libxmp_FOUND) if(libxmp_FOUND)
@@ -807,19 +790,23 @@ if(SDLMIXER_MOD_XMP)
endif() endif()
endif() endif()
if(SDLMIXER_MOD_XMP_ENABLED) if(SDLMIXER_MOD_XMP_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MOD_XMP) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MOD_XMP)
if(SDLMIXER_MOD_XMP_SHARED) if(SDLMIXER_MOD_XMP_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_MOD_XMP)
$<TARGET_PROPERTY:${tgt_xmp},INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:${tgt_xmp},INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:${tgt_xmp},INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:${tgt_xmp},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_xmp ${tgt_xmp}) )
message(STATUS "Dynamic ${xmp_name}: ${dynamic_xmp}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "XMP_DYNAMIC=\"${dynamic_xmp}\"") add_dependencies(${sdl3_mixer_target_name} ${tgt_xmp})
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} ${tgt_xmp}) else()
set(tgt_xmp dont_care)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_MOD_XMP ${tgt_xmp})
message(STATUS "Dynamic ${xmp_name}: ${SDLMIXER_DYNAMIC_MOD_XMP}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "XMP_DYNAMIC=\"${SDLMIXER_DYNAMIC_MOD_XMP}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE ${tgt_xmp}) target_link_libraries(${sdl3_mixer_target_name} PRIVATE ${tgt_xmp})
endif() endif()
@@ -835,7 +822,7 @@ list(APPEND SDLMIXER_BACKENDS MP3_DRMP3)
set(SDLMIXER_MP3_DRMP3_ENABLED FALSE) set(SDLMIXER_MP3_DRMP3_ENABLED FALSE)
if(SDLMIXER_MP3_DRMP3) if(SDLMIXER_MP3_DRMP3)
set(SDLMIXER_MP3_DRMP3_ENABLED TRUE) set(SDLMIXER_MP3_DRMP3_ENABLED TRUE)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MP3_DRMP3) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MP3_DRMP3)
endif() endif()
list(APPEND SDLMIXER_BACKENDS MP3_MPG123) list(APPEND SDLMIXER_BACKENDS MP3_MPG123)
@@ -849,6 +836,7 @@ if(SDLMIXER_MP3_MPG123)
set(BUILD_PROGRAMS OFF) set(BUILD_PROGRAMS OFF)
set(BUILD_SHARED_LIBS "${SDLMIXER_MP3_MPG123_SHARED}") set(BUILD_SHARED_LIBS "${SDLMIXER_MP3_MPG123_SHARED}")
add_subdirectory(external/mpg123/ports/cmake external/libmpg123-build/ports/cmake EXCLUDE_FROM_ALL) add_subdirectory(external/mpg123/ports/cmake external/libmpg123-build/ports/cmake EXCLUDE_FROM_ALL)
register_license(mpg123 external/mpg123/README)
if(NOT TARGET MPG123::libmpg123) if(NOT TARGET MPG123::libmpg123)
add_library(MPG123::libmpg123 ALIAS libmpg123) add_library(MPG123::libmpg123 ALIAS libmpg123)
endif() endif()
@@ -858,6 +846,9 @@ if(SDLMIXER_MP3_MPG123)
if(NOT SDLMIXER_MP3_MPG123_SHARED) if(NOT SDLMIXER_MP3_MPG123_SHARED)
list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:MPG123::mpg123>) list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:MPG123::mpg123>)
endif() endif()
elseif(SDLMIXER_MP3_MPG123_SHARED AND DEFINED SDLMIXER_DYNAMIC_MP3_MPG123 AND EXISTS "${SDLMIXER_DYNAMIC_MP3_MPG123}")
message(STATUS "${PROJECT_NAME}: Using mpg123 from CMake variable")
set(SDLMIXER_MP3_MPG123_ENABLED TRUE)
else() else()
find_package(mpg123 ${required}) find_package(mpg123 ${required})
if(mpg123_FOUND) if(mpg123_FOUND)
@@ -871,19 +862,21 @@ if(SDLMIXER_MP3_MPG123)
endif() endif()
endif() endif()
if(SDLMIXER_MP3_MPG123_ENABLED) if(SDLMIXER_MP3_MPG123_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MP3_MPG123) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MP3_MPG123)
if(SDLMIXER_MP3_MPG123_SHARED) if(SDLMIXER_MP3_MPG123_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_MP3_MPG123)
$<TARGET_PROPERTY:MPG123::libmpg123,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:MPG123::libmpg123,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:MPG123::libmpg123,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:MPG123::libmpg123,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:MPG123::libmpg123,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:MPG123::libmpg123,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_mpg123 MPG123::libmpg123) )
message(STATUS "Dynamic mpg123}: ${dynamic_mpg123}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "MPG123_DYNAMIC=\"${dynamic_mpg123}\"") add_dependencies(${sdl3_mixer_target_name} MPG123::libmpg123)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} MPG123::libmpg123)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_MP3_MPG123 MPG123::libmpg123)
message(STATUS "Dynamic mpg123: ${SDLMIXER_DYNAMIC_MP3_MPG123}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "MPG123_DYNAMIC=\"${SDLMIXER_DYNAMIC_MP3_MPG123}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE MPG123::libmpg123) target_link_libraries(${sdl3_mixer_target_name} PRIVATE MPG123::libmpg123)
endif() endif()
@@ -902,8 +895,11 @@ if(SDLMIXER_MIDI_FLUIDSYNTH)
message(STATUS "Using vendored FluidSynth") message(STATUS "Using vendored FluidSynth")
message(${fatal_error} "FluidSynth is not vendored.") message(${fatal_error} "FluidSynth is not vendored.")
set(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED FALSE) set(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED FALSE)
elseif(SDLMIXER_MIDI_FLUIDSYNTH_SHARED AND DEFINED SDLMIXER_DYNAMIC_MIDI_FLUIDSYNTH AND EXISTS "${SDLMIXER_DYNAMIC_MIDI_FLUIDSYNTH}")
message(STATUS "${PROJECT_NAME}: Using FluidSynth from CMake variable")
set(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED TRUE)
else() else()
find_package(FluidSynth ${required}) find_package(FluidSynth "2.2.0" ${required})
if(FluidSynth_FOUND) if(FluidSynth_FOUND)
set(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED TRUE) set(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED TRUE)
message(STATUS "Using system FluidSynth") message(STATUS "Using system FluidSynth")
@@ -915,85 +911,75 @@ if(SDLMIXER_MIDI_FLUIDSYNTH)
endif() endif()
endif() endif()
if(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED) if(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MID_FLUIDSYNTH) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MIDI_FLUIDSYNTH)
if(SDLMIXER_MIDI_FLUIDSYNTH_SHARED) if(SDLMIXER_MIDI_FLUIDSYNTH_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_MIDI_FLUIDSYNTH)
$<TARGET_PROPERTY:FluidSynth::libfluidsynth,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:FluidSynth::libfluidsynth,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:FluidSynth::libfluidsynth,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:FluidSynth::libfluidsynth,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:FluidSynth::libfluidsynth,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:FluidSynth::libfluidsynth,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_fluidsynth FluidSynth::libfluidsynth) )
message(STATUS "Dynamic fluidsynth: ${dynamic_fluidsynth}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "FLUIDSYNTH_DYNAMIC=\"${dynamic_fluidsynth}\"") add_dependencies(${sdl3_mixer_target_name} FluidSynth::libfluidsynth)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} FluidSynth::libfluidsynth)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_MIDI_FLUIDSYNTH FluidSynth::libfluidsynth)
message(STATUS "Dynamic fluidsynth: ${SDLMIXER_DYNAMIC_MIDI_FLUIDSYNTH}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "FLUIDSYNTH_DYNAMIC=\"${SDLMIXER_DYNAMIC_MIDI_FLUIDSYNTH}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE FluidSynth::libfluidsynth) target_link_libraries(${sdl3_mixer_target_name} PRIVATE FluidSynth::libfluidsynth)
endif() endif()
endif() endif()
endif() endif()
list(APPEND SDLMIXER_BACKENDS MIDI_NATIVE)
list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED FALSE)
if(SDLMIXER_MIDI_NATIVE)
set(midi_common_sources
src/codecs/native_midi/native_midi_common.c
src/codecs/native_midi/native_midi_common.h
)
if(WIN32)
list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED TRUE)
target_sources(${sdl3_mixer_target_name} PRIVATE src/codecs/native_midi/native_midi_win32.c ${midi_common_sources})
target_link_libraries(${sdl3_mixer_target_name} PRIVATE winmm)
elseif(APPLE)
list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED TRUE)
target_sources(${sdl3_mixer_target_name} PRIVATE src/codecs/native_midi/native_midi_macosx.c ${midi_common_sources})
target_link_libraries(${sdl3_mixer_target_name} PRIVATE -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,CoreServices)
elseif(HAIKU)
list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED TRUE)
enable_language(CXX)
target_sources(${sdl3_mixer_target_name} PRIVATE src/codecs/native_midi/native_midi_haiku.cpp ${midi_common_sources})
target_link_libraries(${sdl3_mixer_target_name} PRIVATE midi)
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED TRUE)
target_sources(${sdl3_mixer_target_name} PRIVATE src/codecs/native_midi/native_midi_linux_alsa.c ${midi_common_sources})
target_link_libraries(${sdl3_mixer_target_name} PRIVATE asound)
endif()
if(SDLMIXER_MIDI_NATIVE_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MID_NATIVE)
else()
message(${fatal_error} "native midi NOT available for current platform")
endif()
endif()
list(APPEND SDLMIXER_BACKENDS MIDI_TIMIDITY) list(APPEND SDLMIXER_BACKENDS MIDI_TIMIDITY)
set(SDLMIXER_MIDI_TIMIDITY_ENABLED FALSE) set(SDLMIXER_MIDI_TIMIDITY_ENABLED FALSE)
if(SDLMIXER_MIDI_TIMIDITY) if(SDLMIXER_MIDI_TIMIDITY)
set(SDLMIXER_MIDI_TIMIDITY_ENABLED TRUE) set(SDLMIXER_MIDI_TIMIDITY_ENABLED TRUE)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MID_TIMIDITY) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MIDI_TIMIDITY)
target_sources(${sdl3_mixer_target_name} PRIVATE target_sources(${sdl3_mixer_target_name} PRIVATE
src/codecs/timidity/common.c src/timidity/common.c
src/codecs/timidity/instrum.c src/timidity/instrum.c
src/codecs/timidity/mix.c src/timidity/mix.c
src/codecs/timidity/output.c src/timidity/output.c
src/codecs/timidity/playmidi.c src/timidity/playmidi.c
src/codecs/timidity/readmidi.c src/timidity/readmidi.c
src/codecs/timidity/resample.c src/timidity/resample.c
src/codecs/timidity/tables.c src/timidity/tables.c
src/codecs/timidity/timidity.c src/timidity/timidity.c
) )
endif() endif()
set(SDLMIXER_MIDI_ENABLED FALSE) if(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED OR SDLMIXER_MIDI_TIMIDITY_ENABLED)
if(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED OR SDLMIXER_MIDI_NATIVE_ENABLED OR SDLMIXER_MIDI_TIMIDITY_ENABLED) set(SDLMIXER_MIDI_ENABLED TRUE)
set(SDLMIXER_MIDI_ENABLED TRUE)
endif() endif()
list(APPEND SDLMIXER_BACKENDS WAVE) list(APPEND SDLMIXER_BACKENDS WAVE)
set(SDLMIXER_WAVE_ENABLED FALSE) set(SDLMIXER_WAVE_ENABLED FALSE)
if(SDLMIXER_WAVE) if(SDLMIXER_WAVE)
set(SDLMIXER_WAVE_ENABLED TRUE) set(SDLMIXER_WAVE_ENABLED TRUE)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_WAV) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_WAV)
endif()
list(APPEND SDLMIXER_BACKENDS AIFF)
set(SDLMIXER_AIFF_ENABLED FALSE)
if(SDLMIXER_AIFF)
set(SDLMIXER_AIFF_ENABLED TRUE)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_AIFF)
endif()
list(APPEND SDLMIXER_BACKENDS VOC)
set(SDLMIXER_VOC_ENABLED FALSE)
if(SDLMIXER_VOC)
set(SDLMIXER_VOC_ENABLED TRUE)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_VOC)
endif()
list(APPEND SDLMIXER_BACKENDS AU)
set(SDLMIXER_AU_ENABLED FALSE)
if(SDLMIXER_AU)
set(SDLMIXER_AU_ENABLED TRUE)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_AU)
endif() endif()
list(APPEND SDLMIXER_BACKENDS WAVPACK) list(APPEND SDLMIXER_BACKENDS WAVPACK)
@@ -1010,6 +996,7 @@ if(SDLMIXER_WAVPACK)
set(WAVPACK_BUILD_DOCS OFF) set(WAVPACK_BUILD_DOCS OFF)
set(BUILD_SHARED_LIBS "${SDLMIXER_WAVPACK_SHARED}") set(BUILD_SHARED_LIBS "${SDLMIXER_WAVPACK_SHARED}")
add_subdirectory(external/wavpack external/wavpack-build EXCLUDE_FROM_ALL) add_subdirectory(external/wavpack external/wavpack-build EXCLUDE_FROM_ALL)
register_license(wavpack external/wavpack/COPYING)
if(SDLMIXER_WAVPACK_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS) if(SDLMIXER_WAVPACK_SHARED OR NOT SDLMIXER_BUILD_SHARED_LIBS)
list(APPEND INSTALL_EXTRA_TARGETS wavpack) list(APPEND INSTALL_EXTRA_TARGETS wavpack)
endif() endif()
@@ -1017,6 +1004,9 @@ if(SDLMIXER_WAVPACK)
list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:WavPack::WavPack>) list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:WavPack::WavPack>)
endif() endif()
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE HAVE_WAVPACK_H) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE HAVE_WAVPACK_H)
elseif(SDLMIXER_WAVPACK_SHARED AND DEFINED SDLMIXER_DYNAMIC_WAVPACK AND EXISTS "${SDLMIXER_DYNAMIC_WAVPACK}")
message(STATUS "${PROJECT_NAME}: Using wavpack from CMake variable")
set(SDLMIXER_WAVPACK_ENABLED TRUE)
else() else()
find_package(wavpack ${required}) find_package(wavpack ${required})
if(wavpack_FOUND) if(wavpack_FOUND)
@@ -1030,22 +1020,24 @@ if(SDLMIXER_WAVPACK)
endif() endif()
endif() endif()
if(SDLMIXER_WAVPACK_ENABLED) if(SDLMIXER_WAVPACK_ENABLED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_WAVPACK) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_WAVPACK)
if(SDLMIXER_WAVPACK_DSD) if(SDLMIXER_WAVPACK_DSD)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_WAVPACK_DSD) target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_WAVPACK_DSD)
endif() endif()
if(SDLMIXER_WAVPACK_SHARED) if(SDLMIXER_WAVPACK_SHARED)
target_include_directories(${sdl3_mixer_target_name} PRIVATE if(NOT DEFINED SDLMIXER_DYNAMIC_WAVPACK)
$<TARGET_PROPERTY:WavPack::WavPack,INCLUDE_DIRECTORIES> target_include_directories(${sdl3_mixer_target_name} PRIVATE
$<TARGET_PROPERTY:WavPack::WavPack,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:WavPack::WavPack,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:WavPack::WavPack,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:WavPack::WavPack,INTERFACE_INCLUDE_DIRECTORIES>
) $<TARGET_PROPERTY:WavPack::WavPack,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
target_get_dynamic_library(dynamic_wavpack WavPack::WavPack) )
message(STATUS "Dynamic WavPack: ${dynamic_wavpack}") if(SDLMIXER_VENDORED)
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "WAVPACK_DYNAMIC=\"${dynamic_wavpack}\"") add_dependencies(${sdl3_mixer_target_name} WavPack::WavPack)
if(SDLMIXER_VENDORED) endif()
add_dependencies(${sdl3_mixer_target_name} WavPack::WavPack)
endif() endif()
target_get_dynamic_library(SDLMIXER_DYNAMIC_WAVPACK WavPack::WavPack)
message(STATUS "Dynamic WavPack: ${SDLMIXER_DYNAMIC_WAVPACK}")
target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "WAVPACK_DYNAMIC=\"${SDLMIXER_DYNAMIC_WAVPACK}\"")
else() else()
target_link_libraries(${sdl3_mixer_target_name} PRIVATE WavPack::WavPack) target_link_libraries(${sdl3_mixer_target_name} PRIVATE WavPack::WavPack)
endif() endif()
@@ -1135,7 +1127,6 @@ if(SDLMIXER_INSTALL)
cmake/FindVorbis.cmake cmake/FindVorbis.cmake
cmake/Findtremor.cmake cmake/Findtremor.cmake
cmake/Findwavpack.cmake cmake/Findwavpack.cmake
cmake/FindSndFile.cmake
DESTINATION "${SDLMIXER_INSTALL_CMAKEDIR}" DESTINATION "${SDLMIXER_INSTALL_CMAKEDIR}"
COMPONENT devel COMPONENT devel
) )
@@ -1181,6 +1172,10 @@ if(SDLMIXER_INSTALL)
COMPONENT library COMPONENT library
) )
foreach(license_name IN LISTS install_license_names)
install(FILES "${install_license_${license_name}}" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}/optional" RENAME "LICENSE.${license_name}.txt")
endforeach()
if(SDLMIXER_INSTALL_CPACK) if(SDLMIXER_INSTALL_CPACK)
if(MSVC) if(MSVC)
set(CPACK_GENERATOR "ZIP") set(CPACK_GENERATOR "ZIP")
@@ -1206,33 +1201,15 @@ if(SDLMIXER_INSTALL)
endif() endif()
endif() endif()
if(SDLMIXER_SAMPLES) if(SDLMIXER_TESTS)
find_package(SDL3 REQUIRED COMPONENTS SDL3_test) add_subdirectory(test)
endif()
check_include_file("signal.h" HAVE_SIGNAL_H) ##### Examples subproject (must appear after the install/uninstall targets) #####
check_symbol_exists("setbuf" "stdio.h" HAVE_SETBUF)
add_executable(playmus examples/playmus.c) if(SDLMIXER_EXAMPLES)
add_executable(playwave examples/playwave.c) set(HAVE_EXAMPLES ON)
add_subdirectory(examples)
foreach(prog playmus playwave)
sdl_add_warning_options(${prog} WARNING_AS_ERROR ${SDLMIXER_WERROR})
target_link_libraries(${prog} PRIVATE SDL3::SDL3_test)
target_link_libraries(${prog} PRIVATE SDL3_mixer::${sdl3_mixer_target_name})
target_link_libraries(${prog} PRIVATE ${sdl3_target_name})
if(HAVE_SIGNAL_H)
target_compile_definitions(${prog} PRIVATE HAVE_SIGNAL_H)
endif()
if(HAVE_SETBUF)
target_compile_definitions(${prog} PRIVATE HAVE_SETBUF)
endif()
if(SDLMIXER_SAMPLES_INSTALL)
install(TARGETS ${prog}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
endforeach()
endif() endif()
set(available_deps) set(available_deps)
+49
View File
@@ -0,0 +1,49 @@
# To build and use SDL_mixer:
SDL_mixer supports a number of development environments:
- [CMake](docs/INTRO-cmake.md)
- [Visual Studio on Windows](docs/INTRO-visualstudio.md)
- [Xcode on Apple platforms](docs/INTRO-xcode.md)
- [Android Studio](docs/INTRO-androidstudio.md)
- [Emscripten for web](docs/INTRO-emscripten.md)
SDL_mixer is also usable in other environments. The basic steps are to use CMake to build the library and then use the headers and library that you built in your project. You can search online to see if anyone has specific steps for your setup.
# Documentation
An API reference and additional documentation is available at:
https://wiki.libsdl.org/SDL3_mixer
# Example code
There are simple example programs in the examples directory.
If you're using CMake, you can build them adding `-DSDLMIXER_SAMPLES=ON` to the CMake command line when building SDL_mixer.
If you're using Visual Studio there are separate projects in the VisualC directory.
If you're using Xcode there are separate projects in the Xcode directory.
# Discussions
## Discord
You can join the official Discord server at:
https://discord.com/invite/BwpFGBWsv8
## Forums/mailing lists
You can join SDL development discussions at:
https://discourse.libsdl.org/
Once you sign up, you can use the forum through the website or as a mailing list from your email client.
## Announcement list
You can sign up for the low traffic announcement list at:
https://www.libsdl.org/mailing-list.php
@@ -1,3 +1,5 @@
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
arising from the use of this software. arising from the use of this software.
@@ -13,4 +15,3 @@ freely, subject to the following restrictions:
2. Altered source versions must be plainly marked as such, and must not be 2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
+29
View File
@@ -0,0 +1,29 @@
# SDL_mixer 3.0
This is an audio management library. It provides decoding of many popular audio
file formats, mixing, various DSP processing effects and positional audio.
Audio data can be preloaded, or streamed on-the-fly into the mixer.
SDL3_mixer supports multiple audio devices, and can even mix to a memory buffer
instead of feeding audio hardware in real time.
SDL3_mixer is a complete redesign, rewritten almost from scratch to address
deficiencies in SDL2_mixer. The API is completely different and, in our
opinion, a significant improvement in power and ease of use. Please refer to
docs/README-migration.md for details on how to migrate your program to the new
API.
The latest version of this library is available from GitHub:
https://github.com/libsdl-org/SDL_mixer/releases
Installation instructions and a quick introduction is available in
[INSTALL.md](INSTALL.md)
This library is distributed under the terms of the zlib license,
available in [LICENSE.txt](LICENSE.txt).
Enjoy!
Sam Lantinga (slouken@libsdl.org)
+1
View File
@@ -0,0 +1 @@
release-3.2.0-0-gcedfeef3
+50
View File
@@ -0,0 +1,50 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL3_mixer", "SDL_mixer.vcxproj", "{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}"
ProjectSection(ProjectDependencies) = postProject
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timidity", "timidity\timidity.vcxproj", "{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Debug|Win32.ActiveCfg = Debug|Win32
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Debug|Win32.Build.0 = Debug|Win32
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Debug|x64.ActiveCfg = Debug|x64
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Debug|x64.Build.0 = Debug|x64
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Release|Win32.ActiveCfg = Release|Win32
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Release|Win32.Build.0 = Release|Win32
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Release|x64.ActiveCfg = Release|x64
{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}.Release|x64.Build.0 = Release|x64
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Debug|Win32.ActiveCfg = Debug|Win32
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Debug|Win32.Build.0 = Debug|Win32
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Debug|x64.ActiveCfg = Debug|x64
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Debug|x64.Build.0 = Debug|x64
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Release|Win32.ActiveCfg = Release|Win32
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Release|Win32.Build.0 = Release|Win32
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Release|x64.ActiveCfg = Release|x64
{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}.Release|x64.Build.0 = Release|x64
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.ActiveCfg = Debug|Win32
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.Build.0 = Debug|Win32
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.ActiveCfg = Release|Win32
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.Build.0 = Release|Win32
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E7EE1E80-97A0-406E-8613-1A5264E2A972}
EndGlobalSection
EndGlobal
+473
View File
@@ -0,0 +1,473 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir Condition="'$(SolutionDir)'==''">$(ProjectDir)</SolutionDir>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>SDL3_mixer</ProjectName>
<ProjectGuid>{F7E944B3-0815-40CD-B3E4-90B2A15B0E33}</ProjectGuid>
<RootNamespace>SDL_mixer</RootNamespace>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(ProjectDir)..\include;$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(ProjectDir)..\include;$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(ProjectDir)..\include;$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(ProjectDir)..\include;$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>./$(Configuration)/$(Platform)/SDL_mixer.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>winmm.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>X64</TargetEnvironment>
<TypeLibraryName>./$(Configuration)/$(Platform)/SDL_mixer.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>winmm.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>./$(Configuration)/$(Platform)/SDL_mixer.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>winmm.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>X64</TargetEnvironment>
<TypeLibraryName>./$(Configuration)/$(Platform)/SDL_mixer.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>winmm.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\include\SDL3_mixer\SDL_mixer.h" />
<ClInclude Include="..\src\SDL_mixer_internal.h" />
<ClInclude Include="..\src\SDL_mixer_loader.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\src\version.rc">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="timidity\timidity.vcxproj">
<Project>{b162b6f1-e876-4d5f-a1f6-e3a6dc2f4a2c}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="external\optional\x64\libxmp.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\libogg-0.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\libopus-0.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\libopusfile-0.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\libwavpack-1.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\LICENSE.xmp.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\LICENSE.ogg-vorbis.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\LICENSE.opus.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\LICENSE.opusfile.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x64\LICENSE.wavpack.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libxmp.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libogg-0.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libopus-0.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libopusfile-0.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libwavpack-1.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.xmp.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.ogg-vorbis.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.opus.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.opusfile.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.wavpack.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="external\optional\x64\libgme.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libgme.dll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="external\optional\x64\LICENSE.gme.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying %(Filename)%(Extension)</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.gme.txt">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename)%(Extension)</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename)%(Extension)</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\decoder_aiff.c" />
<ClCompile Include="..\src\decoder_au.c" />
<ClCompile Include="..\src\decoder_drflac.c" />
<ClCompile Include="..\src\decoder_drmp3.c" />
<ClCompile Include="..\src\decoder_flac.c" />
<ClCompile Include="..\src\decoder_fluidsynth.c" />
<ClCompile Include="..\src\decoder_gme.c" />
<ClCompile Include="..\src\decoder_mpg123.c" />
<ClCompile Include="..\src\decoder_opus.c" />
<ClCompile Include="..\src\decoder_raw.c" />
<ClCompile Include="..\src\decoder_sinewave.c" />
<ClCompile Include="..\src\decoder_stb_vorbis.c" />
<ClCompile Include="..\src\decoder_timidity.c" />
<ClCompile Include="..\src\decoder_voc.c" />
<ClCompile Include="..\src\decoder_vorbis.c" />
<ClCompile Include="..\src\decoder_wav.c" />
<ClCompile Include="..\src\decoder_wavpack.c" />
<ClCompile Include="..\src\decoder_xmp.c" />
<ClCompile Include="..\src\SDL_mixer.c" />
<ClCompile Include="..\src\SDL_mixer_metadata_tags.c" />
<ClCompile Include="..\src\SDL_mixer_spatialization.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="..\include\SDL3_mixer\SDL_mixer.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\src\SDL_mixer_internal.h">
<Filter>Sources</Filter>
</ClInclude>
<ClInclude Include="..\src\SDL_mixer_loader.h">
<Filter>Sources</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="x86">
<UniqueIdentifier>{54eeb851-ebbf-436f-a736-a0b710acb7a7}</UniqueIdentifier>
</Filter>
<Filter Include="x64">
<UniqueIdentifier>{2e68f20d-bb6c-410f-bfb7-f513088d4f57}</UniqueIdentifier>
</Filter>
<Filter Include="Sources">
<UniqueIdentifier>{8ec29020-3461-45b5-a964-2caa2257aa07}</UniqueIdentifier>
<Extensions>
</Extensions>
</Filter>
<Filter Include="Public Headers">
<UniqueIdentifier>{8bbeafe5-52e5-4259-8b07-2de45556c6b9}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\src\version.rc">
<Filter>Sources</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="external\optional\x64\libgme.dll">
<Filter>x64</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libgme.dll">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libogg-0.dll">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libopus-0.dll">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libopusfile-0.dll">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libwavpack-1.dll">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\libxmp.dll">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.gme.txt">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.ogg-vorbis.txt">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.opus.txt">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.opusfile.txt">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.wavpack.txt">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x86\LICENSE.xmp.txt">
<Filter>x86</Filter>
</CustomBuild>
<CustomBuild Include="external\optional\x64\libxmp.dll" />
<CustomBuild Include="external\optional\x64\libogg-0.dll" />
<CustomBuild Include="external\optional\x64\libopus-0.dll" />
<CustomBuild Include="external\optional\x64\libopusfile-0.dll" />
<CustomBuild Include="external\optional\x64\libwavpack-1.dll" />
<CustomBuild Include="external\optional\x64\LICENSE.xmp.txt" />
<CustomBuild Include="external\optional\x64\LICENSE.ogg-vorbis.txt" />
<CustomBuild Include="external\optional\x64\LICENSE.opus.txt" />
<CustomBuild Include="external\optional\x64\LICENSE.opusfile.txt" />
<CustomBuild Include="external\optional\x64\LICENSE.wavpack.txt" />
<CustomBuild Include="external\optional\x64\LICENSE.gme.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\decoder_aiff.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_au.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_drflac.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_drmp3.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_flac.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_fluidsynth.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_gme.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_mpg123.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_opus.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_raw.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_sinewave.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_stb_vorbis.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_timidity.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_voc.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_vorbis.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_wav.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_wavpack.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\decoder_xmp.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\SDL_mixer.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\SDL_mixer_metadata_tags.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\SDL_mixer_spatialization.c">
<Filter>Sources</Filter>
</ClCompile>
</ItemGroup>
</Project>
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
find . -type f \( -name '*.user' -o -name '*.sdf' -o -name '*.ncb' -o -name '*.suo' \) -print -delete
rm -rvf Win32 */Win32 x64 */x64
+326
View File
@@ -0,0 +1,326 @@
/* Game music emulator library C interface (also usable from C++) */
/* Game_Music_Emu 0.6.4 */
#ifndef GME_H
#define GME_H
#ifdef __cplusplus
extern "C" {
#endif
#define GME_VERSION 0x000604 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t;
/* First parameter of most gme_ functions is a pointer to the Music_Emu */
typedef struct Music_Emu Music_Emu;
/* Setup compiler defines useful for exporting required public API symbols in gme.cpp */
#ifndef BLARGG_EXPORT
#if defined (_WIN32)
#if defined(BLARGG_BUILD_DLL)
#define BLARGG_EXPORT __declspec(dllexport)
#else
#define BLARGG_EXPORT /* Leave blank: friendly with both static and shared linking. */
#endif
#elif defined (LIBGME_VISIBILITY)
#define BLARGG_EXPORT __attribute__((visibility ("default")))
#else
#define BLARGG_EXPORT
#endif
#endif
/******** Basic operations ********/
/* Create emulator and load game music file/data into it. Sets *out to new emulator. */
BLARGG_EXPORT gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate );
/* Number of tracks available */
BLARGG_EXPORT int gme_track_count( Music_Emu const* );
/* Start a track, where 0 is the first track */
BLARGG_EXPORT gme_err_t gme_start_track( Music_Emu*, int index );
/* Generate 'count' 16-bit signed samples info 'out'. Output is in stereo. */
BLARGG_EXPORT gme_err_t gme_play( Music_Emu*, int count, short out [] );
/* Finish using emulator and free memory */
BLARGG_EXPORT void gme_delete( Music_Emu* );
/******** Track position/length ********/
/* Set time to start fading track out. Once fade ends track_ended() returns true.
Fade time can be changed while track is playing. */
BLARGG_EXPORT void gme_set_fade( Music_Emu*, int start_msec );
/** See gme_set_fade.
* @since 0.6.4
*/
BLARGG_EXPORT void gme_set_fade_msecs( Music_Emu*, int start_msec, int length_msecs );
/**
* If do_autoload_limit is nonzero, then automatically load track length
* metadata (if present) and terminate playback once the track length has been
* reached. Otherwise playback will continue for an arbitrary period of time
* until a prolonged period of silence is detected.
*
* Not all individual emulators support this setting.
*
* By default, playback limits are loaded and applied.
*
* @since 0.6.3
*/
BLARGG_EXPORT void gme_set_autoload_playback_limit( Music_Emu *, int do_autoload_limit );
/** See gme_set_autoload_playback_limit.
* (This was actually added in 0.6.3, but wasn't exported because of a typo.)
* @since 0.6.4
*/
BLARGG_EXPORT int gme_autoload_playback_limit( Music_Emu const* );
/* True if a track has reached its end */
BLARGG_EXPORT int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */
BLARGG_EXPORT int gme_tell( Music_Emu const* );
/* Number of samples generated since beginning of track */
BLARGG_EXPORT int gme_tell_samples( Music_Emu const* );
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
BLARGG_EXPORT gme_err_t gme_seek( Music_Emu*, int msec );
/* Equivalent to restarting track then skipping n samples */
BLARGG_EXPORT gme_err_t gme_seek_samples( Music_Emu*, int n );
/******** Informational ********/
/* If you only need track information from a music file, pass gme_info_only for
sample_rate to open/load. */
enum { gme_info_only = -1 };
/* Most recent warning string, or NULL if none. Clears current warning after returning.
Warning is also cleared when loading a file and starting a track. */
BLARGG_EXPORT const char* gme_warning( Music_Emu* );
/* Load m3u playlist file (must be done after loading music) */
BLARGG_EXPORT gme_err_t gme_load_m3u( Music_Emu*, const char path [] );
/* Clear any loaded m3u playlist and any internal playlist that the music format
supports (NSFE for example). */
BLARGG_EXPORT void gme_clear_playlist( Music_Emu* );
/* Gets information for a particular track (length, name, author, etc.).
Must be freed after use. */
typedef struct gme_info_t gme_info_t;
BLARGG_EXPORT gme_err_t gme_track_info( Music_Emu const*, gme_info_t** out, int track );
/* Frees track information */
BLARGG_EXPORT void gme_free_info( gme_info_t* );
struct gme_info_t
{
/* times in milliseconds; -1 if unknown */
int length; /* total length, if file specifies it */
int intro_length; /* length of song up to looping section */
int loop_length; /* length of looping section */
/* Length if available, otherwise intro_length+loop_length*2 if available,
otherwise a default of 150000 (2.5 minutes). */
int play_length;
/* fade length in milliseconds; -1 if unknown */
int fade_length;
int i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15; /* reserved */
/* empty string ("") if not available */
const char* system;
const char* game;
const char* song;
const char* author;
const char* copyright;
const char* comment;
const char* dumper;
const char *s7,*s8,*s9,*s10,*s11,*s12,*s13,*s14,*s15; /* reserved */
};
/******** Advanced playback ********/
/* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for
GYM, SPC, and Sega Genesis VGM music */
BLARGG_EXPORT void gme_set_stereo_depth( Music_Emu*, double depth );
/* Disable automatic end-of-track detection and skipping of silence at beginning
if ignore is true */
BLARGG_EXPORT void gme_ignore_silence( Music_Emu*, int ignore );
/* Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
Track length as returned by track_info() assumes a tempo of 1.0. */
BLARGG_EXPORT void gme_set_tempo( Music_Emu*, double tempo );
/* Number of voices used by currently loaded file */
BLARGG_EXPORT int gme_voice_count( Music_Emu const* );
/* Name of voice i, from 0 to gme_voice_count() - 1 */
BLARGG_EXPORT const char* gme_voice_name( Music_Emu const*, int i );
/* Mute/unmute voice i, where voice 0 is first voice */
BLARGG_EXPORT void gme_mute_voice( Music_Emu*, int index, int mute );
/* Set muting state of all voices at once using a bit mask, where -1 mutes all
voices, 0 unmutes them all, 0x01 mutes just the first voice, etc. */
BLARGG_EXPORT void gme_mute_voices( Music_Emu*, int muting_mask );
/* Disable/Enable echo effect for SPC files */
/* Available since 0.6.4 */
BLARGG_EXPORT void gme_disable_echo( Music_Emu*, int disable );
/* Frequency equalizer parameters (see gme.txt) */
/* Implementers: If modified, also adjust Music_Emu::make_equalizer as needed */
typedef struct gme_equalizer_t
{
double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
double bass; /* 1 = full bass, 90 = average, 16000 = almost no bass */
double d2,d3,d4,d5,d6,d7,d8,d9; /* reserved */
} gme_equalizer_t;
/* Get current frequency equalizater parameters */
BLARGG_EXPORT void gme_equalizer( Music_Emu const*, gme_equalizer_t* out );
/* Change frequency equalizer parameters */
BLARGG_EXPORT void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
/* Enables/disables most accurate sound emulation options */
BLARGG_EXPORT void gme_enable_accuracy( Music_Emu*, int enabled );
/******** Game music types ********/
/* Music file type identifier. Can also hold NULL. */
typedef const struct gme_type_t_* gme_type_t;
/* Emulator type constants for each supported file type */
extern BLARGG_EXPORT const gme_type_t
gme_ay_type,
gme_gbs_type,
gme_gym_type,
gme_hes_type,
gme_kss_type,
gme_nsf_type,
gme_nsfe_type,
gme_sap_type,
gme_spc_type,
gme_vgm_type,
gme_vgz_type;
/* Type of this emulator */
BLARGG_EXPORT gme_type_t gme_type( Music_Emu const* );
/* Pointer to array of all music types, with NULL entry at end. Allows a player linked
to this library to support new music types without having to be updated. */
BLARGG_EXPORT gme_type_t const* gme_type_list();
/* Name of game system for this music file type */
BLARGG_EXPORT const char* gme_type_system( gme_type_t );
/* True if this music file type supports multiple tracks */
BLARGG_EXPORT int gme_type_multitrack( gme_type_t );
/* whether the pcm output retrieved by gme_play() will have all 8 voices rendered to their
* individual stereo channel or (if false) these voices get mixed into one single stereo channel
* @since 0.6.3 */
BLARGG_EXPORT int gme_multi_channel( Music_Emu const* );
/******** Advanced file loading ********/
/* Error returned if file type is not supported */
extern BLARGG_EXPORT const char* const gme_wrong_file_type;
/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data.
* The resulting Music_Emu object will be set to single channel mode. */
BLARGG_EXPORT gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate );
/* Determine likely game music type based on first four bytes of file. Returns
string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
file header is not recognized. */
BLARGG_EXPORT const char* gme_identify_header( void const* header );
/* Get corresponding music type for file path or extension passed in. */
BLARGG_EXPORT gme_type_t gme_identify_extension( const char path_or_extension [] );
/**
* Get typical file extension for a given music type. This is not a replacement
* for a file content identification library (but see gme_identify_header).
*
* @since 0.6.3
*/
BLARGG_EXPORT const char* gme_type_extension( gme_type_t music_type );
/* Determine file type based on file's extension or header (if extension isn't recognized).
Sets *type_out to type, or 0 if unrecognized or error. */
BLARGG_EXPORT gme_err_t gme_identify_file( const char path [], gme_type_t* type_out );
/* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need
track information, pass gme_info_only for sample_rate. */
BLARGG_EXPORT Music_Emu* gme_new_emu( gme_type_t, int sample_rate );
/* Create new multichannel emulator and set sample rate. Returns NULL if out of memory.
* If you only need track information, pass gme_info_only for sample_rate.
* (see gme_multi_channel for more information on multichannel support)
* @since 0.6.3
*/
BLARGG_EXPORT Music_Emu* gme_new_emu_multi_channel( gme_type_t, int sample_rate );
/* Load music file into emulator */
BLARGG_EXPORT gme_err_t gme_load_file( Music_Emu*, const char path [] );
/* Load music file from memory into emulator. Makes a copy of data passed. */
BLARGG_EXPORT gme_err_t gme_load_data( Music_Emu*, void const* data, long size );
/* Load multiple single-track music files from memory into emulator.
* @since 0.6.4
*/
BLARGG_EXPORT gme_err_t gme_load_tracks( Music_Emu* me,
void const* data, long* sizes, int count );
/* Return the fixed track count of an emu file type
* @since 0.6.4
*/
BLARGG_EXPORT int gme_fixed_track_count( gme_type_t );
/* Load music file using custom data reader function that will be called to
read file data. Most emulators load the entire file in one read call. */
typedef gme_err_t (*gme_reader_t)( void* your_data, void* out, int count );
BLARGG_EXPORT gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
/* Load m3u playlist file from memory (must be done after loading music) */
BLARGG_EXPORT gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size );
/******** User data ********/
/* Set/get pointer to data you want to associate with this emulator.
You can use this for whatever you want. */
BLARGG_EXPORT void gme_set_user_data( Music_Emu*, void* new_user_data );
BLARGG_EXPORT void* gme_user_data( Music_Emu const* );
/* Register cleanup function to be called when deleting emulator, or NULL to
clear it. Passes user_data to cleanup function. */
typedef void (*gme_user_cleanup_t)( void* user_data );
BLARGG_EXPORT void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,26 @@
#ifndef __CONFIG_TYPES_H__
#define __CONFIG_TYPES_H__
/* these are filled in by configure or cmake*/
#define INCLUDE_INTTYPES_H 1
#define INCLUDE_STDINT_H 1
#define INCLUDE_SYS_TYPES_H 1
#if INCLUDE_INTTYPES_H
# include <inttypes.h>
#endif
#if INCLUDE_STDINT_H
# include <stdint.h>
#endif
#if INCLUDE_SYS_TYPES_H
# include <sys/types.h>
#endif
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
typedef uint64_t ogg_uint64_t;
#endif
+981
View File
@@ -0,0 +1,981 @@
/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
Written by Jean-Marc Valin and Koen Vos */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file opus.h
* @brief Opus reference implementation API
*/
#ifndef OPUS_H
#define OPUS_H
#include <opus/opus_types.h>
#include <opus/opus_defines.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @mainpage Opus
*
* The Opus codec is designed for interactive speech and audio transmission over the Internet.
* It is designed by the IETF Codec Working Group and incorporates technology from
* Skype's SILK codec and Xiph.Org's CELT codec.
*
* The Opus codec is designed to handle a wide range of interactive audio applications,
* including Voice over IP, videoconferencing, in-game chat, and even remote live music
* performances. It can scale from low bit-rate narrowband speech to very high quality
* stereo music. Its main features are:
* @li Sampling rates from 8 to 48 kHz
* @li Bit-rates from 6 kb/s to 510 kb/s
* @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR)
* @li Audio bandwidth from narrowband to full-band
* @li Support for speech and music
* @li Support for mono and stereo
* @li Support for multichannel (up to 255 channels)
* @li Frame sizes from 2.5 ms to 60 ms
* @li Good loss robustness and packet loss concealment (PLC)
* @li Floating point and fixed-point implementation
*
* Documentation sections:
* @li @ref opus_encoder
* @li @ref opus_decoder
* @li @ref opus_repacketizer
* @li @ref opus_multistream
* @li @ref opus_libinfo
* @li @ref opus_custom
*/
/** @defgroup opus_encoder Opus Encoder
* @{
*
* @brief This page describes the process and functions used to encode Opus.
*
* Since Opus is a stateful codec, the encoding process starts with creating an encoder
* state. This can be done with:
*
* @code
* int error;
* OpusEncoder *enc;
* enc = opus_encoder_create(Fs, channels, application, &error);
* @endcode
*
* From this point, @c enc can be used for encoding an audio stream. An encoder state
* @b must @b not be used for more than one stream at the same time. Similarly, the encoder
* state @b must @b not be re-initialized for each frame.
*
* While opus_encoder_create() allocates memory for the state, it's also possible
* to initialize pre-allocated memory:
*
* @code
* int size;
* int error;
* OpusEncoder *enc;
* size = opus_encoder_get_size(channels);
* enc = malloc(size);
* error = opus_encoder_init(enc, Fs, channels, application);
* @endcode
*
* where opus_encoder_get_size() returns the required size for the encoder state. Note that
* future versions of this code may change the size, so no assuptions should be made about it.
*
* The encoder state is always continuous in memory and only a shallow copy is sufficient
* to copy it (e.g. memcpy())
*
* It is possible to change some of the encoder's settings using the opus_encoder_ctl()
* interface. All these settings already default to the recommended value, so they should
* only be changed when necessary. The most common settings one may want to change are:
*
* @code
* opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate));
* opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
* opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type));
* @endcode
*
* where
*
* @arg bitrate is in bits per second (b/s)
* @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest
* @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC
*
* See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream.
*
* To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data:
* @code
* len = opus_encode(enc, audio_frame, frame_size, packet, max_packet);
* @endcode
*
* where
* <ul>
* <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>
* <li>frame_size is the duration of the frame in samples (per channel)</li>
* <li>packet is the byte array to which the compressed data is written</li>
* <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended).
* Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.</li>
* </ul>
*
* opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.
* The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
* is 2 bytes or less, then the packet does not need to be transmitted (DTX).
*
* Once the encoder state if no longer needed, it can be destroyed with
*
* @code
* opus_encoder_destroy(enc);
* @endcode
*
* If the encoder was created with opus_encoder_init() rather than opus_encoder_create(),
* then no action is required aside from potentially freeing the memory that was manually
* allocated for it (calling free(enc) for the example above)
*
*/
/** Opus encoder state.
* This contains the complete state of an Opus encoder.
* It is position independent and can be freely copied.
* @see opus_encoder_create,opus_encoder_init
*/
typedef struct OpusEncoder OpusEncoder;
/** Gets the size of an <code>OpusEncoder</code> structure.
* @param[in] channels <tt>int</tt>: Number of channels.
* This must be 1 or 2.
* @returns The size in bytes.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels);
/**
*/
/** Allocates and initializes an encoder state.
* There are three coding modes:
*
* @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice
* signals. It enhances the input signal by high-pass filtering and
* emphasizing formants and harmonics. Optionally it includes in-band
* forward error correction to protect against packet loss. Use this
* mode for typical VoIP applications. Because of the enhancement,
* even at high bitrates the output may sound different from the input.
*
* @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most
* non-voice signals like music. Use this mode for music and mixed
* (music/voice) content, broadcast, and applications requiring less
* than 15 ms of coding delay.
*
* @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that
* disables the speech-optimized mode in exchange for slightly reduced delay.
* This mode can only be set on an newly initialized or freshly reset encoder
* because it changes the codec delay.
*
* This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution).
* @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
* @param [in] application <tt>int</tt>: Coding mode (one of @ref OPUS_APPLICATION_VOIP, @ref OPUS_APPLICATION_AUDIO, or @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY)
* @param [out] error <tt>int*</tt>: @ref opus_errorcodes
* @note Regardless of the sampling rate and number channels selected, the Opus encoder
* can switch to a lower audio bandwidth or number of channels if the bitrate
* selected is too low. This also means that it is safe to always use 48 kHz stereo input
* and let the encoder optimize the encoding.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create(
opus_int32 Fs,
int channels,
int application,
int *error
);
/** Initializes a previously allocated encoder state
* The memory pointed to by st must be at least the size returned by opus_encoder_get_size().
* This is intended for applications which use their own allocator instead of malloc.
* @see opus_encoder_create(),opus_encoder_get_size()
* To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
* @param [in] st <tt>OpusEncoder*</tt>: Encoder state
* @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
* @param [in] application <tt>int</tt>: Coding mode (one of OPUS_APPLICATION_VOIP, OPUS_APPLICATION_AUDIO, or OPUS_APPLICATION_RESTRICTED_LOWDELAY)
* @retval #OPUS_OK Success or @ref opus_errorcodes
*/
OPUS_EXPORT int opus_encoder_init(
OpusEncoder *st,
opus_int32 Fs,
int channels,
int application
) OPUS_ARG_NONNULL(1);
/** Encodes an Opus frame.
* @param [in] st <tt>OpusEncoder*</tt>: Encoder state
* @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)
* @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
* input signal.
* This must be an Opus frame size for
* the encoder's sampling rate.
* For example, at 48 kHz the permitted
* values are 120, 240, 480, 960, 1920,
* and 2880.
* Passing in a duration of less than
* 10 ms (480 samples at 48 kHz) will
* prevent the encoder from using the LPC
* or hybrid modes.
* @param [out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
OpusEncoder *st,
const opus_int16 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes an Opus frame from floating point input.
* @param [in] st <tt>OpusEncoder*</tt>: Encoder state
* @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.
* Samples with a range beyond +/-1.0 are supported but will
* be clipped by decoders using the integer API and should
* only be used if it is known that the far end supports
* extended dynamic range.
* length is frame_size*channels*sizeof(float)
* @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
* input signal.
* This must be an Opus frame size for
* the encoder's sampling rate.
* For example, at 48 kHz the permitted
* values are 120, 240, 480, 960, 1920,
* and 2880.
* Passing in a duration of less than
* 10 ms (480 samples at 48 kHz) will
* prevent the encoder from using the LPC
* or hybrid modes.
* @param [out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float(
OpusEncoder *st,
const float *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Frees an <code>OpusEncoder</code> allocated by opus_encoder_create().
* @param[in] st <tt>OpusEncoder*</tt>: State to be freed.
*/
OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);
/** Perform a CTL function on an Opus encoder.
*
* Generally the request and subsequent arguments are generated
* by a convenience macro.
* @param st <tt>OpusEncoder*</tt>: Encoder state.
* @param request This and all remaining parameters should be replaced by one
* of the convenience macros in @ref opus_genericctls or
* @ref opus_encoderctls.
* @see opus_genericctls
* @see opus_encoderctls
*/
OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
/**@}*/
/** @defgroup opus_decoder Opus Decoder
* @{
*
* @brief This page describes the process and functions used to decode Opus.
*
* The decoding process also starts with creating a decoder
* state. This can be done with:
* @code
* int error;
* OpusDecoder *dec;
* dec = opus_decoder_create(Fs, channels, &error);
* @endcode
* where
* @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000
* @li channels is the number of channels (1 or 2)
* @li error will hold the error code in case of failure (or #OPUS_OK on success)
* @li the return value is a newly created decoder state to be used for decoding
*
* While opus_decoder_create() allocates memory for the state, it's also possible
* to initialize pre-allocated memory:
* @code
* int size;
* int error;
* OpusDecoder *dec;
* size = opus_decoder_get_size(channels);
* dec = malloc(size);
* error = opus_decoder_init(dec, Fs, channels);
* @endcode
* where opus_decoder_get_size() returns the required size for the decoder state. Note that
* future versions of this code may change the size, so no assuptions should be made about it.
*
* The decoder state is always continuous in memory and only a shallow copy is sufficient
* to copy it (e.g. memcpy())
*
* To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data:
* @code
* frame_size = opus_decode(dec, packet, len, decoded, max_size, 0);
* @endcode
* where
*
* @li packet is the byte array containing the compressed data
* @li len is the exact number of bytes contained in the packet
* @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float())
* @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array
*
* opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet.
* If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio
* buffer is too small to hold the decoded audio.
*
* Opus is a stateful codec with overlapping blocks and as a result Opus
* packets are not coded independently of each other. Packets must be
* passed into the decoder serially and in the correct order for a correct
* decode. Lost packets can be replaced with loss concealment by calling
* the decoder with a null pointer and zero length for the missing packet.
*
* A single codec state may only be accessed from a single thread at
* a time and any required locking must be performed by the caller. Separate
* streams must be decoded with separate decoder states and can be decoded
* in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK
* defined.
*
*/
/** Opus decoder state.
* This contains the complete state of an Opus decoder.
* It is position independent and can be freely copied.
* @see opus_decoder_create,opus_decoder_init
*/
typedef struct OpusDecoder OpusDecoder;
/** Gets the size of an <code>OpusDecoder</code> structure.
* @param [in] channels <tt>int</tt>: Number of channels.
* This must be 1 or 2.
* @returns The size in bytes.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels);
/** Allocates and initializes a decoder state.
* @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
* @param [out] error <tt>int*</tt>: #OPUS_OK Success or @ref opus_errorcodes
*
* Internally Opus stores data at 48000 Hz, so that should be the default
* value for Fs. However, the decoder can efficiently decode to buffers
* at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use
* data at the full sample rate, or knows the compressed data doesn't
* use the full frequency range, it can request decoding at a reduced
* rate. Likewise, the decoder is capable of filling in either mono or
* interleaved stereo pcm buffers, at the caller's request.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create(
opus_int32 Fs,
int channels,
int *error
);
/** Initializes a previously allocated decoder state.
* The state must be at least the size returned by opus_decoder_get_size().
* This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size
* To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state.
* @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
* @retval #OPUS_OK Success or @ref opus_errorcodes
*/
OPUS_EXPORT int opus_decoder_init(
OpusDecoder *st,
opus_int32 Fs,
int channels
) OPUS_ARG_NONNULL(1);
/** Decode an Opus packet.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
* @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
* @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
* is frame_size*channels*sizeof(opus_int16)
* @param [in] frame_size Number of samples per channel of available space in \a pcm.
* If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
* not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
* then frame_size needs to be exactly the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
* FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
* @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
* decoded. If no such data is available, the frame is decoded as if it were lost.
* @returns Number of decoded samples or @ref opus_errorcodes
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
OpusDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_int16 *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode an Opus packet with floating point output.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
* @param [in] len <tt>opus_int32</tt>: Number of bytes in payload
* @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
* is frame_size*channels*sizeof(float)
* @param [in] frame_size Number of samples per channel of available space in \a pcm.
* If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
* not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
* then frame_size needs to be exactly the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
* FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
* @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
* decoded. If no such data is available the frame is decoded as if it were lost.
* @returns Number of decoded samples or @ref opus_errorcodes
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float(
OpusDecoder *st,
const unsigned char *data,
opus_int32 len,
float *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Perform a CTL function on an Opus decoder.
*
* Generally the request and subsequent arguments are generated
* by a convenience macro.
* @param st <tt>OpusDecoder*</tt>: Decoder state.
* @param request This and all remaining parameters should be replaced by one
* of the convenience macros in @ref opus_genericctls or
* @ref opus_decoderctls.
* @see opus_genericctls
* @see opus_decoderctls
*/
OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
/** Frees an <code>OpusDecoder</code> allocated by opus_decoder_create().
* @param[in] st <tt>OpusDecoder*</tt>: State to be freed.
*/
OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
/** Parse an opus packet into one or more frames.
* Opus_decode will perform this operation internally so most applications do
* not need to use this function.
* This function does not copy the frames, the returned pointers are pointers into
* the input packet.
* @param [in] data <tt>char*</tt>: Opus packet to be parsed
* @param [in] len <tt>opus_int32</tt>: size of data
* @param [out] out_toc <tt>char*</tt>: TOC pointer
* @param [out] frames <tt>char*[48]</tt> encapsulated frames
* @param [out] size <tt>opus_int16[48]</tt> sizes of the encapsulated frames
* @param [out] payload_offset <tt>int*</tt>: returns the position of the payload within the packet (in bytes)
* @returns number of frames
*/
OPUS_EXPORT int opus_packet_parse(
const unsigned char *data,
opus_int32 len,
unsigned char *out_toc,
const unsigned char *frames[48],
opus_int16 size[48],
int *payload_offset
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5);
/** Gets the bandwidth of an Opus packet.
* @param [in] data <tt>char*</tt>: Opus packet
* @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass)
* @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass)
* @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass)
* @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass)
* @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass)
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1);
/** Gets the number of samples per frame from an Opus packet.
* @param [in] data <tt>char*</tt>: Opus packet.
* This must contain at least one byte of
* data.
* @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
* This must be a multiple of 400, or
* inaccurate results will be returned.
* @returns Number of samples per frame.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1);
/** Gets the number of channels from an Opus packet.
* @param [in] data <tt>char*</tt>: Opus packet
* @returns Number of channels
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1);
/** Gets the number of frames in an Opus packet.
* @param [in] packet <tt>char*</tt>: Opus packet
* @param [in] len <tt>opus_int32</tt>: Length of packet
* @returns Number of frames
* @retval OPUS_BAD_ARG Insufficient data was passed to the function
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1);
/** Gets the number of samples of an Opus packet.
* @param [in] packet <tt>char*</tt>: Opus packet
* @param [in] len <tt>opus_int32</tt>: Length of packet
* @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
* This must be a multiple of 400, or
* inaccurate results will be returned.
* @returns Number of samples
* @retval OPUS_BAD_ARG Insufficient data was passed to the function
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);
/** Gets the number of samples of an Opus packet.
* @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
* @param [in] packet <tt>char*</tt>: Opus packet
* @param [in] len <tt>opus_int32</tt>: Length of packet
* @returns Number of samples
* @retval OPUS_BAD_ARG Insufficient data was passed to the function
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
/** Applies soft-clipping to bring a float signal within the [-1,1] range. If
* the signal is already in that range, nothing is done. If there are values
* outside of [-1,1], then the signal is clipped as smoothly as possible to
* both fit in the range and avoid creating excessive distortion in the
* process.
* @param [in,out] pcm <tt>float*</tt>: Input PCM and modified PCM
* @param [in] frame_size <tt>int</tt> Number of samples per channel to process
* @param [in] channels <tt>int</tt>: Number of channels
* @param [in,out] softclip_mem <tt>float*</tt>: State memory for the soft clipping process (one float per channel, initialized to zero)
*/
OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem);
/**@}*/
/** @defgroup opus_repacketizer Repacketizer
* @{
*
* The repacketizer can be used to merge multiple Opus packets into a single
* packet or alternatively to split Opus packets that have previously been
* merged. Splitting valid Opus packets is always guaranteed to succeed,
* whereas merging valid packets only succeeds if all frames have the same
* mode, bandwidth, and frame size, and when the total duration of the merged
* packet is no more than 120 ms. The 120 ms limit comes from the
* specification and limits decoder memory requirements at a point where
* framing overhead becomes negligible.
*
* The repacketizer currently only operates on elementary Opus
* streams. It will not manipualte multistream packets successfully, except in
* the degenerate case where they consist of data from a single stream.
*
* The repacketizing process starts with creating a repacketizer state, either
* by calling opus_repacketizer_create() or by allocating the memory yourself,
* e.g.,
* @code
* OpusRepacketizer *rp;
* rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size());
* if (rp != NULL)
* opus_repacketizer_init(rp);
* @endcode
*
* Then the application should submit packets with opus_repacketizer_cat(),
* extract new packets with opus_repacketizer_out() or
* opus_repacketizer_out_range(), and then reset the state for the next set of
* input packets via opus_repacketizer_init().
*
* For example, to split a sequence of packets into individual frames:
* @code
* unsigned char *data;
* int len;
* while (get_next_packet(&data, &len))
* {
* unsigned char out[1276];
* opus_int32 out_len;
* int nb_frames;
* int err;
* int i;
* err = opus_repacketizer_cat(rp, data, len);
* if (err != OPUS_OK)
* {
* release_packet(data);
* return err;
* }
* nb_frames = opus_repacketizer_get_nb_frames(rp);
* for (i = 0; i < nb_frames; i++)
* {
* out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out));
* if (out_len < 0)
* {
* release_packet(data);
* return (int)out_len;
* }
* output_next_packet(out, out_len);
* }
* opus_repacketizer_init(rp);
* release_packet(data);
* }
* @endcode
*
* Alternatively, to combine a sequence of frames into packets that each
* contain up to <code>TARGET_DURATION_MS</code> milliseconds of data:
* @code
* // The maximum number of packets with duration TARGET_DURATION_MS occurs
* // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5)
* // packets.
* unsigned char *data[(TARGET_DURATION_MS*2/5)+1];
* opus_int32 len[(TARGET_DURATION_MS*2/5)+1];
* int nb_packets;
* unsigned char out[1277*(TARGET_DURATION_MS*2/2)];
* opus_int32 out_len;
* int prev_toc;
* nb_packets = 0;
* while (get_next_packet(data+nb_packets, len+nb_packets))
* {
* int nb_frames;
* int err;
* nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]);
* if (nb_frames < 1)
* {
* release_packets(data, nb_packets+1);
* return nb_frames;
* }
* nb_frames += opus_repacketizer_get_nb_frames(rp);
* // If adding the next packet would exceed our target, or it has an
* // incompatible TOC sequence, output the packets we already have before
* // submitting it.
* // N.B., The nb_packets > 0 check ensures we've submitted at least one
* // packet since the last call to opus_repacketizer_init(). Otherwise a
* // single packet longer than TARGET_DURATION_MS would cause us to try to
* // output an (invalid) empty packet. It also ensures that prev_toc has
* // been set to a valid value. Additionally, len[nb_packets] > 0 is
* // guaranteed by the call to opus_packet_get_nb_frames() above, so the
* // reference to data[nb_packets][0] should be valid.
* if (nb_packets > 0 && (
* ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) ||
* opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames >
* TARGET_DURATION_MS*48))
* {
* out_len = opus_repacketizer_out(rp, out, sizeof(out));
* if (out_len < 0)
* {
* release_packets(data, nb_packets+1);
* return (int)out_len;
* }
* output_next_packet(out, out_len);
* opus_repacketizer_init(rp);
* release_packets(data, nb_packets);
* data[0] = data[nb_packets];
* len[0] = len[nb_packets];
* nb_packets = 0;
* }
* err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]);
* if (err != OPUS_OK)
* {
* release_packets(data, nb_packets+1);
* return err;
* }
* prev_toc = data[nb_packets][0];
* nb_packets++;
* }
* // Output the final, partial packet.
* if (nb_packets > 0)
* {
* out_len = opus_repacketizer_out(rp, out, sizeof(out));
* release_packets(data, nb_packets);
* if (out_len < 0)
* return (int)out_len;
* output_next_packet(out, out_len);
* }
* @endcode
*
* An alternate way of merging packets is to simply call opus_repacketizer_cat()
* unconditionally until it fails. At that point, the merged packet can be
* obtained with opus_repacketizer_out() and the input packet for which
* opus_repacketizer_cat() needs to be re-added to a newly reinitialized
* repacketizer state.
*/
typedef struct OpusRepacketizer OpusRepacketizer;
/** Gets the size of an <code>OpusRepacketizer</code> structure.
* @returns The size in bytes.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void);
/** (Re)initializes a previously allocated repacketizer state.
* The state must be at least the size returned by opus_repacketizer_get_size().
* This can be used for applications which use their own allocator instead of
* malloc().
* It must also be called to reset the queue of packets waiting to be
* repacketized, which is necessary if the maximum packet duration of 120 ms
* is reached or if you wish to submit packets with a different Opus
* configuration (coding mode, audio bandwidth, frame size, or channel count).
* Failure to do so will prevent a new packet from being added with
* opus_repacketizer_cat().
* @see opus_repacketizer_create
* @see opus_repacketizer_get_size
* @see opus_repacketizer_cat
* @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to
* (re)initialize.
* @returns A pointer to the same repacketizer state that was passed in.
*/
OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
/** Allocates memory and initializes the new repacketizer with
* opus_repacketizer_init().
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void);
/** Frees an <code>OpusRepacketizer</code> allocated by
* opus_repacketizer_create().
* @param[in] rp <tt>OpusRepacketizer*</tt>: State to be freed.
*/
OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);
/** Add a packet to the current repacketizer state.
* This packet must match the configuration of any packets already submitted
* for repacketization since the last call to opus_repacketizer_init().
* This means that it must have the same coding mode, audio bandwidth, frame
* size, and channel count.
* This can be checked in advance by examining the top 6 bits of the first
* byte of the packet, and ensuring they match the top 6 bits of the first
* byte of any previously submitted packet.
* The total duration of audio in the repacketizer state also must not exceed
* 120 ms, the maximum duration of a single packet, after adding this packet.
*
* The contents of the current repacketizer state can be extracted into new
* packets using opus_repacketizer_out() or opus_repacketizer_out_range().
*
* In order to add a packet with a different configuration or to add more
* audio beyond 120 ms, you must clear the repacketizer state by calling
* opus_repacketizer_init().
* If a packet is too large to add to the current repacketizer state, no part
* of it is added, even if it contains multiple frames, some of which might
* fit.
* If you wish to be able to add parts of such packets, you should first use
* another repacketizer to split the packet into pieces and add them
* individually.
* @see opus_repacketizer_out_range
* @see opus_repacketizer_out
* @see opus_repacketizer_init
* @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to which to
* add the packet.
* @param[in] data <tt>const unsigned char*</tt>: The packet data.
* The application must ensure
* this pointer remains valid
* until the next call to
* opus_repacketizer_init() or
* opus_repacketizer_destroy().
* @param len <tt>opus_int32</tt>: The number of bytes in the packet data.
* @returns An error code indicating whether or not the operation succeeded.
* @retval #OPUS_OK The packet's contents have been added to the repacketizer
* state.
* @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence,
* the packet's TOC sequence was not compatible
* with previously submitted packets (because
* the coding mode, audio bandwidth, frame size,
* or channel count did not match), or adding
* this packet would increase the total amount of
* audio stored in the repacketizer state to more
* than 120 ms.
*/
OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
/** Construct a new packet from data previously submitted to the repacketizer
* state via opus_repacketizer_cat().
* @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
* construct the new packet.
* @param begin <tt>int</tt>: The index of the first frame in the current
* repacketizer state to include in the output.
* @param end <tt>int</tt>: One past the index of the last frame in the
* current repacketizer state to include in the
* output.
* @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
* store the output packet.
* @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
* the output buffer. In order to guarantee
* success, this should be at least
* <code>1276</code> for a single frame,
* or for multiple frames,
* <code>1277*(end-begin)</code>.
* However, <code>1*(end-begin)</code> plus
* the size of all packet data submitted to
* the repacketizer since the last call to
* opus_repacketizer_init() or
* opus_repacketizer_create() is also
* sufficient, and possibly much smaller.
* @returns The total size of the output packet on success, or an error code
* on failure.
* @retval #OPUS_BAD_ARG <code>[begin,end)</code> was an invalid range of
* frames (begin < 0, begin >= end, or end >
* opus_repacketizer_get_nb_frames()).
* @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
* complete output packet.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Return the total number of frames contained in packet data submitted to
* the repacketizer state so far via opus_repacketizer_cat() since the last
* call to opus_repacketizer_init() or opus_repacketizer_create().
* This defines the valid range of packets that can be extracted with
* opus_repacketizer_out_range() or opus_repacketizer_out().
* @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state containing the
* frames.
* @returns The total number of frames contained in the packet data submitted
* to the repacketizer state.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
/** Construct a new packet from data previously submitted to the repacketizer
* state via opus_repacketizer_cat().
* This is a convenience routine that returns all the data submitted so far
* in a single packet.
* It is equivalent to calling
* @code
* opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp),
* data, maxlen)
* @endcode
* @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
* construct the new packet.
* @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
* store the output packet.
* @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
* the output buffer. In order to guarantee
* success, this should be at least
* <code>1277*opus_repacketizer_get_nb_frames(rp)</code>.
* However,
* <code>1*opus_repacketizer_get_nb_frames(rp)</code>
* plus the size of all packet data
* submitted to the repacketizer since the
* last call to opus_repacketizer_init() or
* opus_repacketizer_create() is also
* sufficient, and possibly much smaller.
* @returns The total size of the output packet on success, or an error code
* on failure.
* @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
* complete output packet.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);
/** Pads a given Opus packet to a larger size (possibly changing the TOC sequence).
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
* packet to pad.
* @param len <tt>opus_int32</tt>: The size of the packet.
* This must be at least 1.
* @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
* This must be at least as large as len.
* @returns an error code
* @retval #OPUS_OK \a on success.
* @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
*/
OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len);
/** Remove all padding from a given Opus packet and rewrite the TOC sequence to
* minimize space usage.
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
* packet to strip.
* @param len <tt>opus_int32</tt>: The size of the packet.
* This must be at least 1.
* @returns The new size of the output packet on success, or an error code
* on failure.
* @retval #OPUS_BAD_ARG \a len was less than 1.
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len);
/** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence).
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
* packet to pad.
* @param len <tt>opus_int32</tt>: The size of the packet.
* This must be at least 1.
* @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
* This must be at least 1.
* @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
* This must be at least as large as len.
* @returns an error code
* @retval #OPUS_OK \a on success.
* @retval #OPUS_BAD_ARG \a len was less than 1.
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
*/
OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams);
/** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to
* minimize space usage.
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
* packet to strip.
* @param len <tt>opus_int32</tt>: The size of the packet.
* This must be at least 1.
* @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
* This must be at least 1.
* @returns The new size of the output packet on success, or an error code
* on failure.
* @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* OPUS_H */
@@ -0,0 +1,801 @@
/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
Written by Jean-Marc Valin and Koen Vos */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file opus_defines.h
* @brief Opus reference implementation constants
*/
#ifndef OPUS_DEFINES_H
#define OPUS_DEFINES_H
#include <opus/opus_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup opus_errorcodes Error codes
* @{
*/
/** No error @hideinitializer*/
#define OPUS_OK 0
/** One or more invalid/out of range arguments @hideinitializer*/
#define OPUS_BAD_ARG -1
/** Not enough bytes allocated in the buffer @hideinitializer*/
#define OPUS_BUFFER_TOO_SMALL -2
/** An internal error was detected @hideinitializer*/
#define OPUS_INTERNAL_ERROR -3
/** The compressed data passed is corrupted @hideinitializer*/
#define OPUS_INVALID_PACKET -4
/** Invalid/unsupported request number @hideinitializer*/
#define OPUS_UNIMPLEMENTED -5
/** An encoder or decoder structure is invalid or already freed @hideinitializer*/
#define OPUS_INVALID_STATE -6
/** Memory allocation has failed @hideinitializer*/
#define OPUS_ALLOC_FAIL -7
/**@}*/
/** @cond OPUS_INTERNAL_DOC */
/**Export control for opus functions */
#ifndef OPUS_EXPORT
# if defined(_WIN32)
# if defined(OPUS_BUILD) && defined(DLL_EXPORT)
# define OPUS_EXPORT __declspec(dllexport)
# else
# define OPUS_EXPORT
# endif
# elif defined(__GNUC__) && defined(OPUS_BUILD)
# define OPUS_EXPORT __attribute__ ((visibility ("default")))
# else
# define OPUS_EXPORT
# endif
#endif
# if !defined(OPUS_GNUC_PREREQ)
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
# define OPUS_GNUC_PREREQ(_maj,_min) \
((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
# else
# define OPUS_GNUC_PREREQ(_maj,_min) 0
# endif
# endif
#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
# if OPUS_GNUC_PREREQ(3,0)
# define OPUS_RESTRICT __restrict__
# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
# define OPUS_RESTRICT __restrict
# else
# define OPUS_RESTRICT
# endif
#else
# define OPUS_RESTRICT restrict
#endif
#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
# if OPUS_GNUC_PREREQ(2,7)
# define OPUS_INLINE __inline__
# elif (defined(_MSC_VER))
# define OPUS_INLINE __inline
# else
# define OPUS_INLINE
# endif
#else
# define OPUS_INLINE inline
#endif
/**Warning attributes for opus functions
* NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out
* some paranoid null checks. */
#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
#else
# define OPUS_WARN_UNUSED_RESULT
#endif
#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x)))
#else
# define OPUS_ARG_NONNULL(_x)
#endif
/** These are the actual Encoder CTL ID numbers.
* They should not be used directly by applications.
* In general, SETs should be even and GETs should be odd.*/
#define OPUS_SET_APPLICATION_REQUEST 4000
#define OPUS_GET_APPLICATION_REQUEST 4001
#define OPUS_SET_BITRATE_REQUEST 4002
#define OPUS_GET_BITRATE_REQUEST 4003
#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004
#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005
#define OPUS_SET_VBR_REQUEST 4006
#define OPUS_GET_VBR_REQUEST 4007
#define OPUS_SET_BANDWIDTH_REQUEST 4008
#define OPUS_GET_BANDWIDTH_REQUEST 4009
#define OPUS_SET_COMPLEXITY_REQUEST 4010
#define OPUS_GET_COMPLEXITY_REQUEST 4011
#define OPUS_SET_INBAND_FEC_REQUEST 4012
#define OPUS_GET_INBAND_FEC_REQUEST 4013
#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014
#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015
#define OPUS_SET_DTX_REQUEST 4016
#define OPUS_GET_DTX_REQUEST 4017
#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021
#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022
#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023
#define OPUS_SET_SIGNAL_REQUEST 4024
#define OPUS_GET_SIGNAL_REQUEST 4025
#define OPUS_GET_LOOKAHEAD_REQUEST 4027
/* #define OPUS_RESET_STATE 4028 */
#define OPUS_GET_SAMPLE_RATE_REQUEST 4029
#define OPUS_GET_FINAL_RANGE_REQUEST 4031
#define OPUS_GET_PITCH_REQUEST 4033
#define OPUS_SET_GAIN_REQUEST 4034
#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */
#define OPUS_SET_LSB_DEPTH_REQUEST 4036
#define OPUS_GET_LSB_DEPTH_REQUEST 4037
#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040
#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
#define OPUS_GET_IN_DTX_REQUEST 4049
/** Defines for the presence of extended APIs. */
#define OPUS_HAVE_OPUS_PROJECTION_H
/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr)))
/** @endcond */
/** @defgroup opus_ctlvalues Pre-defined values for CTL interface
* @see opus_genericctls, opus_encoderctls
* @{
*/
/* Values for the various encoder CTLs */
#define OPUS_AUTO -1000 /**<Auto/default setting @hideinitializer*/
#define OPUS_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/
/** Best for most VoIP/videoconference applications where listening quality and intelligibility matter most
* @hideinitializer */
#define OPUS_APPLICATION_VOIP 2048
/** Best for broadcast/high-fidelity application where the decoded audio should be as close as possible to the input
* @hideinitializer */
#define OPUS_APPLICATION_AUDIO 2049
/** Only use when lowest-achievable latency is what matters most. Voice-optimized modes cannot be used.
* @hideinitializer */
#define OPUS_APPLICATION_RESTRICTED_LOWDELAY 2051
#define OPUS_SIGNAL_VOICE 3001 /**< Signal being encoded is voice */
#define OPUS_SIGNAL_MUSIC 3002 /**< Signal being encoded is music */
#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/
#define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */
#define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */
#define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */
#define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */
#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
#define OPUS_FRAMESIZE_80_MS 5007 /**< Use 80 ms frames */
#define OPUS_FRAMESIZE_100_MS 5008 /**< Use 100 ms frames */
#define OPUS_FRAMESIZE_120_MS 5009 /**< Use 120 ms frames */
/**@}*/
/** @defgroup opus_encoderctls Encoder related CTLs
*
* These are convenience macros for use with the \c opus_encode_ctl
* interface. They are used to generate the appropriate series of
* arguments for that call, passing the correct type, size and so
* on as expected for each particular request.
*
* Some usage examples:
*
* @code
* int ret;
* ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO));
* if (ret != OPUS_OK) return ret;
*
* opus_int32 rate;
* opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate));
*
* opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
* @endcode
*
* @see opus_genericctls, opus_encoder
* @{
*/
/** Configures the encoder's computational complexity.
* The supported range is 0-10 inclusive with 10 representing the highest complexity.
* @see OPUS_GET_COMPLEXITY
* @param[in] x <tt>opus_int32</tt>: Allowed values: 0-10, inclusive.
*
* @hideinitializer */
#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x)
/** Gets the encoder's complexity configuration.
* @see OPUS_SET_COMPLEXITY
* @param[out] x <tt>opus_int32 *</tt>: Returns a value in the range 0-10,
* inclusive.
* @hideinitializer */
#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x)
/** Configures the bitrate in the encoder.
* Rates from 500 to 512000 bits per second are meaningful, as well as the
* special values #OPUS_AUTO and #OPUS_BITRATE_MAX.
* The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much
* rate as it can, which is useful for controlling the rate by adjusting the
* output buffer size.
* @see OPUS_GET_BITRATE
* @param[in] x <tt>opus_int32</tt>: Bitrate in bits per second. The default
* is determined based on the number of
* channels and the input sampling rate.
* @hideinitializer */
#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x)
/** Gets the encoder's bitrate configuration.
* @see OPUS_SET_BITRATE
* @param[out] x <tt>opus_int32 *</tt>: Returns the bitrate in bits per second.
* The default is determined based on the
* number of channels and the input
* sampling rate.
* @hideinitializer */
#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x)
/** Enables or disables variable bitrate (VBR) in the encoder.
* The configured bitrate may not be met exactly because frames must
* be an integer number of bytes in length.
* @see OPUS_GET_VBR
* @see OPUS_SET_VBR_CONSTRAINT
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Hard CBR. For LPC/hybrid modes at very low bit-rate, this can
* cause noticeable quality degradation.</dd>
* <dt>1</dt><dd>VBR (default). The exact type of VBR is controlled by
* #OPUS_SET_VBR_CONSTRAINT.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x)
/** Determine if variable bitrate (VBR) is enabled in the encoder.
* @see OPUS_SET_VBR
* @see OPUS_GET_VBR_CONSTRAINT
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Hard CBR.</dd>
* <dt>1</dt><dd>VBR (default). The exact type of VBR may be retrieved via
* #OPUS_GET_VBR_CONSTRAINT.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x)
/** Enables or disables constrained VBR in the encoder.
* This setting is ignored when the encoder is in CBR mode.
* @warning Only the MDCT mode of Opus currently heeds the constraint.
* Speech mode ignores it completely, hybrid mode may fail to obey it
* if the LPC layer uses more bitrate than the constraint would have
* permitted.
* @see OPUS_GET_VBR_CONSTRAINT
* @see OPUS_SET_VBR
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Unconstrained VBR.</dd>
* <dt>1</dt><dd>Constrained VBR (default). This creates a maximum of one
* frame of buffering delay assuming a transport with a
* serialization speed of the nominal bitrate.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)
/** Determine if constrained VBR is enabled in the encoder.
* @see OPUS_SET_VBR_CONSTRAINT
* @see OPUS_GET_VBR
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Unconstrained VBR.</dd>
* <dt>1</dt><dd>Constrained VBR (default).</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)
/** Configures mono/stereo forcing in the encoder.
* This can force the encoder to produce packets encoded as either mono or
* stereo, regardless of the format of the input audio. This is useful when
* the caller knows that the input signal is currently a mono source embedded
* in a stereo stream.
* @see OPUS_GET_FORCE_CHANNELS
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
* <dt>1</dt> <dd>Forced mono</dd>
* <dt>2</dt> <dd>Forced stereo</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x)
/** Gets the encoder's forced channel configuration.
* @see OPUS_SET_FORCE_CHANNELS
* @param[out] x <tt>opus_int32 *</tt>:
* <dl>
* <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
* <dt>1</dt> <dd>Forced mono</dd>
* <dt>2</dt> <dd>Forced stereo</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
/** Configures the maximum bandpass that the encoder will select automatically.
* Applications should normally use this instead of #OPUS_SET_BANDWIDTH
* (leaving that set to the default, #OPUS_AUTO). This allows the
* application to set an upper bound based on the type of input it is
* providing, but still gives the encoder the freedom to reduce the bandpass
* when the bitrate becomes too low, for better overall quality.
* @see OPUS_GET_MAX_BANDWIDTH
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured maximum allowed bandpass.
* @see OPUS_SET_MAX_BANDWIDTH
* @param[out] x <tt>opus_int32 *</tt>: Allowed values:
* <dl>
* <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
/** Sets the encoder's bandpass to a specific value.
* This prevents the encoder from automatically selecting the bandpass based
* on the available bitrate. If an application knows the bandpass of the input
* audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH
* instead, which still gives the encoder the freedom to reduce the bandpass
* when the bitrate becomes too low, for better overall quality.
* @see OPUS_GET_BANDWIDTH
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x)
/** Configures the type of signal being encoded.
* This is a hint which helps the encoder's mode selection.
* @see OPUS_GET_SIGNAL
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
* <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured signal type.
* @see OPUS_SET_SIGNAL
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
* <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's intended application.
* The initial value is a mandatory argument to the encoder_create function.
* @see OPUS_GET_APPLICATION
* @param[in] x <tt>opus_int32</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured application.
* @see OPUS_SET_APPLICATION
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x)
/** Gets the total samples of delay added by the entire codec.
* This can be queried by the encoder and then the provided number of samples can be
* skipped on from the start of the decoder's output to provide time aligned input
* and output. From the perspective of a decoding application the real data begins this many
* samples late.
*
* The decoder contribution to this delay is identical for all decoders, but the
* encoder portion of the delay may vary from implementation to implementation,
* version to version, or even depend on the encoder's initial configuration.
* Applications needing delay compensation should call this CTL rather than
* hard-coding a value.
* @param[out] x <tt>opus_int32 *</tt>: Number of lookahead samples
* @hideinitializer */
#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's use of inband forward error correction (FEC).
* @note This is only applicable to the LPC layer
* @see OPUS_GET_INBAND_FEC
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Disable inband FEC (default).</dd>
* <dt>1</dt><dd>Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.</dd>
* <dt>2</dt><dd>Inband FEC enabled, but does not necessarily switch to SILK if we have music.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x)
/** Gets encoder's configured use of inband forward error correction.
* @see OPUS_SET_INBAND_FEC
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Inband FEC disabled (default).</dd>
* <dt>1</dt><dd>Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.</dd>
* <dt>2</dt><dd>Inband FEC enabled, but does not necessarily switch to SILK if we have music.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's expected packet loss percentage.
* Higher values trigger progressively more loss resistant behavior in the encoder
* at the expense of quality at a given bitrate in the absence of packet loss, but
* greater quality under loss.
* @see OPUS_GET_PACKET_LOSS_PERC
* @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0).
* @hideinitializer */
#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured packet loss percentage.
* @see OPUS_SET_PACKET_LOSS_PERC
* @param[out] x <tt>opus_int32 *</tt>: Returns the configured loss percentage
* in the range 0-100, inclusive (default: 0).
* @hideinitializer */
#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's use of discontinuous transmission (DTX).
* @note This is only applicable to the LPC layer
* @see OPUS_GET_DTX
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Disable DTX (default).</dd>
* <dt>1</dt><dd>Enabled DTX.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x)
/** Gets encoder's configured use of discontinuous transmission.
* @see OPUS_SET_DTX
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>DTX disabled (default).</dd>
* <dt>1</dt><dd>DTX enabled.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
/** Configures the depth of signal being encoded.
*
* This is a hint which helps the encoder identify silence and near-silence.
* It represents the number of significant bits of linear intensity below
* which the signal contains ignorable quantization or other noise.
*
* For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting
* for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate
* for 16-bit linear pcm input with opus_encode_float().
*
* When using opus_encode() instead of opus_encode_float(), or when libopus
* is compiled for fixed-point, the encoder uses the minimum of the value
* set here and the value 16.
*
* @see OPUS_GET_LSB_DEPTH
* @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
* (default: 24).
* @hideinitializer */
#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured signal depth.
* @see OPUS_SET_LSB_DEPTH
* @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
* 24 (default: 24).
* @hideinitializer */
#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's use of variable duration frames.
* When variable duration is enabled, the encoder is free to use a shorter frame
* size than the one requested in the opus_encode*() call.
* It is then the user's responsibility
* to verify how much audio was encoded by checking the ToC byte of the encoded
* packet. The part of the audio that was not encoded needs to be resent to the
* encoder for the next call. Do not use this option unless you <b>really</b>
* know what you are doing.
* @see OPUS_GET_EXPERT_FRAME_DURATION
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
* <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured use of variable duration frames.
* @see OPUS_SET_EXPERT_FRAME_DURATION
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
* <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
/** If set to 1, disables almost all use of prediction, making frames almost
* completely independent. This reduces quality.
* @see OPUS_GET_PREDICTION_DISABLED
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Enable prediction (default).</dd>
* <dt>1</dt><dd>Disable prediction.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured prediction status.
* @see OPUS_SET_PREDICTION_DISABLED
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Prediction enabled (default).</dd>
* <dt>1</dt><dd>Prediction disabled.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)
/**@}*/
/** @defgroup opus_genericctls Generic CTLs
*
* These macros are used with the \c opus_decoder_ctl and
* \c opus_encoder_ctl calls to generate a particular
* request.
*
* When called on an \c OpusDecoder they apply to that
* particular decoder instance. When called on an
* \c OpusEncoder they apply to the corresponding setting
* on that encoder instance, if present.
*
* Some usage examples:
*
* @code
* int ret;
* opus_int32 pitch;
* ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch));
* if (ret == OPUS_OK) return ret;
*
* opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
* opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE);
*
* opus_int32 enc_bw, dec_bw;
* opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw));
* opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw));
* if (enc_bw != dec_bw) {
* printf("packet bandwidth mismatch!\n");
* }
* @endcode
*
* @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls
* @{
*/
/** Resets the codec state to be equivalent to a freshly initialized state.
* This should be called when switching streams in order to prevent
* the back to back decoding from giving different results from
* one at a time decoding.
* @hideinitializer */
#define OPUS_RESET_STATE 4028
/** Gets the final state of the codec's entropy coder.
* This is used for testing purposes,
* The encoder and decoder state should be identical after coding a payload
* (assuming no data corruption or software bugs)
*
* @param[out] x <tt>opus_uint32 *</tt>: Entropy coder state
*
* @hideinitializer */
#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)
/** Gets the encoder's configured bandpass or the decoder's last bandpass.
* @see OPUS_SET_BANDWIDTH
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
/** Gets the sampling rate the encoder or decoder was initialized with.
* This simply returns the <code>Fs</code> value passed to opus_encoder_init()
* or opus_decoder_init().
* @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder.
* @hideinitializer
*/
#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
/** If set to 1, disables the use of phase inversion for intensity stereo,
* improving the quality of mono downmixes, but slightly reducing normal
* stereo quality. Disabling phase inversion in the decoder does not comply
* with RFC 6716, although it does not cause any interoperability issue and
* is expected to become part of the Opus standard once RFC 6716 is updated
* by draft-ietf-codec-opus-update.
* @see OPUS_GET_PHASE_INVERSION_DISABLED
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Enable phase inversion (default).</dd>
* <dt>1</dt><dd>Disable phase inversion.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured phase inversion status.
* @see OPUS_SET_PHASE_INVERSION_DISABLED
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Stereo phase inversion enabled (default).</dd>
* <dt>1</dt><dd>Stereo phase inversion disabled.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x)
/** Gets the DTX state of the encoder.
* Returns whether the last encoded frame was either a comfort noise update
* during DTX or not encoded because of DTX.
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>The encoder is not in DTX.</dd>
* <dt>1</dt><dd>The encoder is in DTX.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x)
/**@}*/
/** @defgroup opus_decoderctls Decoder related CTLs
* @see opus_genericctls, opus_encoderctls, opus_decoder
* @{
*/
/** Configures decoder gain adjustment.
* Scales the decoded output by a factor specified in Q8 dB units.
* This has a maximum range of -32768 to 32767 inclusive, and returns
* OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment.
* This setting survives decoder reset.
*
* gain = pow(10, x/(20.0*256))
*
* @param[in] x <tt>opus_int32</tt>: Amount to scale PCM signal by in Q8 dB units.
* @hideinitializer */
#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x)
/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN
*
* @param[out] x <tt>opus_int32 *</tt>: Amount to scale PCM signal by in Q8 dB units.
* @hideinitializer */
#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x)
/** Gets the duration (in samples) of the last packet successfully decoded or concealed.
* @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
* @hideinitializer */
#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
/** Gets the pitch of the last decoded frame, if available.
* This can be used for any post-processing algorithm requiring the use of pitch,
* e.g. time stretching/shortening. If the last frame was not voiced, or if the
* pitch was not coded in the frame, then zero is returned.
*
* This CTL is only implemented for decoder instances.
*
* @param[out] x <tt>opus_int32 *</tt>: pitch period at 48 kHz (or 0 if not available)
*
* @hideinitializer */
#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x)
/**@}*/
/** @defgroup opus_libinfo Opus library information functions
* @{
*/
/** Converts an opus error code into a human readable string.
*
* @param[in] error <tt>int</tt>: Error number
* @returns Error string
*/
OPUS_EXPORT const char *opus_strerror(int error);
/** Gets the libopus version string.
*
* Applications may look for the substring "-fixed" in the version string to
* determine whether they have a fixed-point or floating-point build at
* runtime.
*
* @returns Version string
*/
OPUS_EXPORT const char *opus_get_version_string(void);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* OPUS_DEFINES_H */
@@ -0,0 +1,660 @@
/* Copyright (c) 2011 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file opus_multistream.h
* @brief Opus reference implementation multistream API
*/
#ifndef OPUS_MULTISTREAM_H
#define OPUS_MULTISTREAM_H
#include <opus/opus.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @cond OPUS_INTERNAL_DOC */
/** Macros to trigger compilation errors when the wrong types are provided to a
* CTL. */
/**@{*/
#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))
#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))
/**@}*/
/** These are the actual encoder and decoder CTL ID numbers.
* They should not be used directly by applications.
* In general, SETs should be even and GETs should be odd.*/
/**@{*/
#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120
#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122
/**@}*/
/** @endcond */
/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs
*
* These are convenience macros that are specific to the
* opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()
* interface.
* The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and
* @ref opus_decoderctls may be applied to a multistream encoder or decoder as
* well.
* In addition, you may retrieve the encoder or decoder state for an specific
* stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or
* #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.
*/
/**@{*/
/** Gets the encoder state for an individual stream of a multistream encoder.
* @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you
* wish to retrieve.
* This must be non-negative and less than
* the <code>streams</code> parameter used
* to initialize the encoder.
* @param[out] y <tt>OpusEncoder**</tt>: Returns a pointer to the given
* encoder state.
* @retval OPUS_BAD_ARG The index of the requested stream was out of range.
* @hideinitializer
*/
#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)
/** Gets the decoder state for an individual stream of a multistream decoder.
* @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you
* wish to retrieve.
* This must be non-negative and less than
* the <code>streams</code> parameter used
* to initialize the decoder.
* @param[out] y <tt>OpusDecoder**</tt>: Returns a pointer to the given
* decoder state.
* @retval OPUS_BAD_ARG The index of the requested stream was out of range.
* @hideinitializer
*/
#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)
/**@}*/
/** @defgroup opus_multistream Opus Multistream API
* @{
*
* The multistream API allows individual Opus streams to be combined into a
* single packet, enabling support for up to 255 channels. Unlike an
* elementary Opus stream, the encoder and decoder must negotiate the channel
* configuration before the decoder can successfully interpret the data in the
* packets produced by the encoder. Some basic information, such as packet
* duration, can be computed without any special negotiation.
*
* The format for multistream Opus packets is defined in
* <a href="https://tools.ietf.org/html/rfc7845">RFC 7845</a>
* and is based on the self-delimited Opus framing described in Appendix B of
* <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
* Normal Opus packets are just a degenerate case of multistream Opus packets,
* and can be encoded or decoded with the multistream API by setting
* <code>streams</code> to <code>1</code> when initializing the encoder or
* decoder.
*
* Multistream Opus streams can contain up to 255 elementary Opus streams.
* These may be either "uncoupled" or "coupled", indicating that the decoder
* is configured to decode them to either 1 or 2 channels, respectively.
* The streams are ordered so that all coupled streams appear at the
* beginning.
*
* A <code>mapping</code> table defines which decoded channel <code>i</code>
* should be used for each input/output (I/O) channel <code>j</code>. This table is
* typically provided as an unsigned char array.
* Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.
* If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is
* encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>
* is even, or as the right channel of stream <code>(i/2)</code> if
* <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as
* mono in stream <code>(i - coupled_streams)</code>, unless it has the special
* value 255, in which case it is omitted from the encoding entirely (the
* decoder will reproduce it as silence). Each value <code>i</code> must either
* be the special value 255 or be less than <code>streams + coupled_streams</code>.
*
* The output channels specified by the encoder
* should use the
* <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
* channel ordering</a>. A decoder may wish to apply an additional permutation
* to the mapping the encoder used to achieve a different output channel
* order (e.g. for outputing in WAV order).
*
* Each multistream packet contains an Opus packet for each stream, and all of
* the Opus packets in a single multistream packet must have the same
* duration. Therefore the duration of a multistream packet can be extracted
* from the TOC sequence of the first stream, which is located at the
* beginning of the packet, just like an elementary Opus stream:
*
* @code
* int nb_samples;
* int nb_frames;
* nb_frames = opus_packet_get_nb_frames(data, len);
* if (nb_frames < 1)
* return nb_frames;
* nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;
* @endcode
*
* The general encoding and decoding process proceeds exactly the same as in
* the normal @ref opus_encoder and @ref opus_decoder APIs.
* See their documentation for an overview of how to use the corresponding
* multistream functions.
*/
/** Opus multistream encoder state.
* This contains the complete state of a multistream Opus encoder.
* It is position independent and can be freely copied.
* @see opus_multistream_encoder_create
* @see opus_multistream_encoder_init
*/
typedef struct OpusMSEncoder OpusMSEncoder;
/** Opus multistream decoder state.
* This contains the complete state of a multistream Opus decoder.
* It is position independent and can be freely copied.
* @see opus_multistream_decoder_create
* @see opus_multistream_decoder_init
*/
typedef struct OpusMSDecoder OpusMSDecoder;
/**\name Multistream encoder functions */
/**@{*/
/** Gets the size of an OpusMSEncoder structure.
* @param streams <tt>int</tt>: The total number of streams to encode from the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
* to encode.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* encoded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @returns The size in bytes on success, or a negative error code
* (see @ref opus_errorcodes) on error.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
int streams,
int coupled_streams
);
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size(
int channels,
int mapping_family
);
/** Allocates and initializes a multistream encoder state.
* Call opus_multistream_encoder_destroy() to release
* this object when finished.
* @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels in the input signal.
* This must be at most 255.
* It may be greater than the number of
* coded channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams to encode from the
* input.
* This must be no more than the number of channels.
* @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
* to encode.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* encoded channels (<code>streams +
* coupled_streams</code>) must be no
* more than the number of input channels.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* encoded channels to input channels, as described in
* @ref opus_multistream. As an extra constraint, the
* multistream encoder does not allow encoding coupled
* streams for which one channel is unused since this
* is never a good idea.
* @param application <tt>int</tt>: The target encoder application.
* This must be one of the following:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
* code (see @ref opus_errorcodes) on
* failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping,
int application,
int *error
) OPUS_ARG_NONNULL(5);
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create(
opus_int32 Fs,
int channels,
int mapping_family,
int *streams,
int *coupled_streams,
unsigned char *mapping,
int application,
int *error
) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
/** Initialize a previously allocated multistream encoder state.
* The memory pointed to by \a st must be at least the size returned by
* opus_multistream_encoder_get_size().
* This is intended for applications which use their own allocator instead of
* malloc.
* To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
* @see opus_multistream_encoder_create
* @see opus_multistream_encoder_get_size
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
* @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels in the input signal.
* This must be at most 255.
* It may be greater than the number of
* coded channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams to encode from the
* input.
* This must be no more than the number of channels.
* @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
* to encode.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* encoded channels (<code>streams +
* coupled_streams</code>) must be no
* more than the number of input channels.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* encoded channels to input channels, as described in
* @ref opus_multistream. As an extra constraint, the
* multistream encoder does not allow encoding coupled
* streams for which one channel is unused since this
* is never a good idea.
* @param application <tt>int</tt>: The target encoder application.
* This must be one of the following:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
* on failure.
*/
OPUS_EXPORT int opus_multistream_encoder_init(
OpusMSEncoder *st,
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping,
int application
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
OPUS_EXPORT int opus_multistream_surround_encoder_init(
OpusMSEncoder *st,
opus_int32 Fs,
int channels,
int mapping_family,
int *streams,
int *coupled_streams,
unsigned char *mapping,
int application
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7);
/** Encodes a multistream Opus frame.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
* samples.
* This must contain
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
* signal.
* This must be an Opus frame size for the
* encoder's sampling rate.
* For example, at 48 kHz the permitted values
* are 120, 240, 480, 960, 1920, and 2880.
* Passing in a duration of less than 10 ms
* (480 samples at 48 kHz) will prevent the
* encoder from using the LPC or hybrid modes.
* @param[out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
OpusMSEncoder *st,
const opus_int16 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes a multistream Opus frame from floating point input.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
* samples with a normal range of
* +/-1.0.
* Samples with a range beyond +/-1.0
* are supported but will be clipped by
* decoders using the integer API and
* should only be used if it is known
* that the far end supports extended
* dynamic range.
* This must contain
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
* signal.
* This must be an Opus frame size for the
* encoder's sampling rate.
* For example, at 48 kHz the permitted values
* are 120, 240, 480, 960, 1920, and 2880.
* Passing in a duration of less than 10 ms
* (480 samples at 48 kHz) will prevent the
* encoder from using the LPC or hybrid modes.
* @param[out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(
OpusMSEncoder *st,
const float *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Frees an <code>OpusMSEncoder</code> allocated by
* opus_multistream_encoder_create().
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.
*/
OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
/** Perform a CTL function on a multistream Opus encoder.
*
* Generally the request and subsequent arguments are generated by a
* convenience macro.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param request This and all remaining parameters should be replaced by one
* of the convenience macros in @ref opus_genericctls,
* @ref opus_encoderctls, or @ref opus_multistream_ctls.
* @see opus_genericctls
* @see opus_encoderctls
* @see opus_multistream_ctls
*/
OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
/**@}*/
/**\name Multistream decoder functions */
/**@{*/
/** Gets the size of an <code>OpusMSDecoder</code> structure.
* @param streams <tt>int</tt>: The total number of streams coded in the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
* (2 channel) streams.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* coded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @returns The size in bytes on success, or a negative error code
* (see @ref opus_errorcodes) on error.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
int streams,
int coupled_streams
);
/** Allocates and initializes a multistream decoder state.
* Call opus_multistream_decoder_destroy() to release
* this object when finished.
* @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels to output.
* This must be at most 255.
* It may be different from the number of coded
* channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams coded in the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
* (2 channel) streams.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* coded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* coded channels to output channels, as described in
* @ref opus_multistream.
* @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
* code (see @ref opus_errorcodes) on
* failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping,
int *error
) OPUS_ARG_NONNULL(5);
/** Intialize a previously allocated decoder state object.
* The memory pointed to by \a st must be at least the size returned by
* opus_multistream_encoder_get_size().
* This is intended for applications which use their own allocator instead of
* malloc.
* To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
* @see opus_multistream_decoder_create
* @see opus_multistream_deocder_get_size
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
* @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels to output.
* This must be at most 255.
* It may be different from the number of coded
* channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams coded in the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
* (2 channel) streams.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* coded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* coded channels to output channels, as described in
* @ref opus_multistream.
* @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
* on failure.
*/
OPUS_EXPORT int opus_multistream_decoder_init(
OpusMSDecoder *st,
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
/** Decode a multistream Opus packet.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
* Use a <code>NULL</code>
* pointer to indicate packet
* loss.
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
* @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
* samples.
* This must contain room for
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: The number of samples per channel of
* available space in \a pcm.
* If this is less than the maximum packet duration
* (120 ms; 5760 for 48kHz), this function will not be capable
* of decoding some packets. In the case of PLC (data==NULL)
* or FEC (decode_fec=1), then frame_size needs to be exactly
* the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the
* next incoming packet. For the PLC and FEC cases, frame_size
* <b>must</b> be a multiple of 2.5 ms.
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
* forward error correction data be decoded.
* If no such data is available, the frame is
* decoded as if it were lost.
* @returns Number of samples decoded on success or a negative error code
* (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_int16 *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode a multistream Opus packet with floating point output.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
* Use a <code>NULL</code>
* pointer to indicate packet
* loss.
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
* @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
* samples.
* This must contain room for
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: The number of samples per channel of
* available space in \a pcm.
* If this is less than the maximum packet duration
* (120 ms; 5760 for 48kHz), this function will not be capable
* of decoding some packets. In the case of PLC (data==NULL)
* or FEC (decode_fec=1), then frame_size needs to be exactly
* the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the
* next incoming packet. For the PLC and FEC cases, frame_size
* <b>must</b> be a multiple of 2.5 ms.
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
* forward error correction data be decoded.
* If no such data is available, the frame is
* decoded as if it were lost.
* @returns Number of samples decoded on success or a negative error code
* (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
float *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Perform a CTL function on a multistream Opus decoder.
*
* Generally the request and subsequent arguments are generated by a
* convenience macro.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param request This and all remaining parameters should be replaced by one
* of the convenience macros in @ref opus_genericctls,
* @ref opus_decoderctls, or @ref opus_multistream_ctls.
* @see opus_genericctls
* @see opus_decoderctls
* @see opus_multistream_ctls
*/
OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
/** Frees an <code>OpusMSDecoder</code> allocated by
* opus_multistream_decoder_create().
* @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.
*/
OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);
/**@}*/
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* OPUS_MULTISTREAM_H */
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
/* wrapper to avoid an additional -Iinclude/opus directive.
* headers under opus/ are edited accordingly for this */
#include <opus/opusfile.h>
@@ -0,0 +1,440 @@
////////////////////////////////////////////////////////////////////////////
// **** WAVPACK **** //
// Hybrid Lossless Wavefile Compressor //
// Copyright (c) 1998 - 2024 David Bryant. //
// All Rights Reserved. //
// Distributed under the BSD Software License (see license.txt) //
////////////////////////////////////////////////////////////////////////////
// wavpack.h
#ifndef WAVPACK_H
#define WAVPACK_H
// This header file contains all the definitions required to use the
// functions in "wputils.c" to read and write WavPack files and streams.
#include <sys/types.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
#else
#include <stdint.h>
#endif
// RIFF / wav header formats (these occur at the beginning of both wav files
// and pre-4.0 WavPack files that are not in the "raw" mode). Generally, an
// application using the library to read or write WavPack files will not be
// concerned with any of these.
typedef struct {
char ckID [4];
uint32_t ckSize;
char formType [4];
} RiffChunkHeader;
typedef struct {
char ckID [4];
uint32_t ckSize;
} ChunkHeader;
#define ChunkHeaderFormat "4L"
typedef struct {
uint16_t FormatTag, NumChannels;
uint32_t SampleRate, BytesPerSecond;
uint16_t BlockAlign, BitsPerSample;
uint16_t cbSize, ValidBitsPerSample;
int32_t ChannelMask;
uint16_t SubFormat;
char GUID [14];
} WaveHeader;
#define WaveHeaderFormat "SSLLSSSSLS"
// This is the ONLY structure that occurs in WavPack files (as of version
// 4.0), and is the preamble to every block in both the .wv and .wvc
// files (in little-endian format). Normally, this structure has no use
// to an application using the library to read or write WavPack files,
// but if an application needs to manually parse WavPack files then this
// would be used (with appropriate endian correction).
typedef struct {
char ckID [4];
uint32_t ckSize;
int16_t version;
unsigned char block_index_u8;
unsigned char total_samples_u8;
uint32_t total_samples, block_index, block_samples, flags, crc;
} WavpackHeader;
#define WavpackHeaderFormat "4LS2LLLLL"
// Macros to access the 40-bit block_index field
#define GET_BLOCK_INDEX(hdr) ( (int64_t) (hdr).block_index + ((int64_t) (hdr).block_index_u8 << 32) )
#define SET_BLOCK_INDEX(hdr,value) do { \
int64_t tmp = (value); \
(hdr).block_index = (uint32_t) tmp; \
(hdr).block_index_u8 = \
(unsigned char) (tmp >> 32); \
} while (0)
// Macros to access the 40-bit total_samples field, which is complicated by the fact that
// all 1's in the lower 32 bits indicates "unknown" (regardless of upper 8 bits)
#define GET_TOTAL_SAMPLES(hdr) ( ((hdr).total_samples == (uint32_t) -1) ? -1 : \
(int64_t) (hdr).total_samples + ((int64_t) (hdr).total_samples_u8 << 32) - (hdr).total_samples_u8 )
#define SET_TOTAL_SAMPLES(hdr,value) do { \
int64_t tmp = (value); \
if (tmp < 0) \
(hdr).total_samples = (uint32_t) -1; \
else { \
tmp += (tmp / 0xffffffffLL); \
(hdr).total_samples = (uint32_t) tmp; \
(hdr).total_samples_u8 = \
(unsigned char) (tmp >> 32); \
} \
} while (0)
// or-values for WavpackHeader.flags
#define BYTES_STORED 3 // 1-4 bytes/sample
#define MONO_FLAG 4 // not stereo
#define HYBRID_FLAG 8 // hybrid mode
#define JOINT_STEREO 0x10 // joint stereo
#define CROSS_DECORR 0x20 // no-delay cross decorrelation
#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
#define FLOAT_DATA 0x80 // ieee 32-bit floating point data
#define INT32_DATA 0x100 // special extended int handling
#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only)
#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only)
#define INITIAL_BLOCK 0x800 // initial block of multichannel segment
#define FINAL_BLOCK 0x1000 // final block of multichannel segment
#define SHIFT_LSB 13
#define SHIFT_MASK (0x1fL << SHIFT_LSB)
#define MAG_LSB 18
#define MAG_MASK (0x1fL << MAG_LSB)
#define SRATE_LSB 23
#define SRATE_MASK (0xfL << SRATE_LSB)
#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono
#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
#define MONO_DATA (MONO_FLAG | FALSE_STEREO)
// Introduced in WavPack 5.0:
#define HAS_CHECKSUM 0x10000000 // block contains a trailing checksum
#define DSD_FLAG 0x80000000 // block is encoded DSD (1-bit PCM)
#define IGNORED_FLAGS 0x08000000 // reserved, but ignore if encountered
#define UNKNOWN_FLAGS 0x00000000 // we no longer have any of these spares
#define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode
#define MAX_STREAM_VERS 0x410 // highest stream version we'll decode or encode
#define WAVPACK_MAX_CHANS 4096 // max channels handled by WavPack format & library
// This sets the maximum number of channels that the current WavPack CLI applications
// accept. It's somewhat arbitrary because the actual WavPack format and library can
// handle up to 4096 channels. However, anything beyond 256 channels is obviously
// a niche case and is not well tested, so this lower limit is defined for now.
#define WAVPACK_MAX_CLI_CHANS 256
// These are the mask bit definitions for the metadata chunk id byte (see format.txt)
#define ID_UNIQUE 0x3f
#define ID_OPTIONAL_DATA 0x20
#define ID_ODD_SIZE 0x40
#define ID_LARGE 0x80
#define ID_DUMMY 0x0
#define ID_ENCODER_INFO 0x1
#define ID_DECORR_TERMS 0x2
#define ID_DECORR_WEIGHTS 0x3
#define ID_DECORR_SAMPLES 0x4
#define ID_ENTROPY_VARS 0x5
#define ID_HYBRID_PROFILE 0x6
#define ID_SHAPING_WEIGHTS 0x7
#define ID_FLOAT_INFO 0x8
#define ID_INT32_INFO 0x9
#define ID_WV_BITSTREAM 0xa
#define ID_WVC_BITSTREAM 0xb
#define ID_WVX_BITSTREAM 0xc
#define ID_CHANNEL_INFO 0xd
#define ID_DSD_BLOCK 0xe
#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1)
#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2)
#define ID_ALT_HEADER (ID_OPTIONAL_DATA | 0x3)
#define ID_ALT_TRAILER (ID_OPTIONAL_DATA | 0x4)
#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5)
#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6)
#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7)
#define ID_ALT_EXTENSION (ID_OPTIONAL_DATA | 0x8)
#define ID_ALT_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x9)
#define ID_NEW_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0xa)
#define ID_CHANNEL_IDENTITIES (ID_OPTIONAL_DATA | 0xb)
#define ID_WVX_NEW_BITSTREAM (ID_OPTIONAL_DATA | ID_WVX_BITSTREAM)
#define ID_BLOCK_CHECKSUM (ID_OPTIONAL_DATA | 0xf)
///////////////////////// WavPack Configuration ///////////////////////////////
// This external structure is used during encode to provide configuration to
// the encoding engine and during decoding to provide fle information back to
// the higher level functions. Not all fields are used in both modes.
typedef struct {
float bitrate, shaping_weight;
int bits_per_sample, bytes_per_sample;
int qmode, flags, xmode, num_channels, float_norm_exp;
int32_t block_samples, worker_threads, sample_rate, channel_mask;
unsigned char md5_checksum [16], md5_read;
int num_tag_strings; // this field is not used
char **tag_strings; // this field is not used
} WavpackConfig;
#define CONFIG_HYBRID_FLAG 8 // hybrid mode
#define CONFIG_JOINT_STEREO 0x10 // joint stereo
#define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation
#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
#define CONFIG_FAST_FLAG 0x200 // fast mode
#define CONFIG_HIGH_FLAG 0x800 // high quality mode
#define CONFIG_VERY_HIGH_FLAG 0x1000 // very high
#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
#define CONFIG_DYNAMIC_SHAPING 0x20000 // dynamic noise shaping
#define CONFIG_CREATE_EXE 0x40000 // create executable
#define CONFIG_CREATE_WVC 0x80000 // create correction file
#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize hybrid compression
#define CONFIG_COMPATIBLE_WRITE 0x400000 // write files for decoders < 4.3
#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode
#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
#define CONFIG_MD5_CHECKSUM 0x8000000 // store MD5 signature
#define CONFIG_MERGE_BLOCKS 0x10000000 // merge blocks of equal redundancy (for lossyWAV)
#define CONFIG_PAIR_UNDEF_CHANS 0x20000000 // encode undefined channels in stereo pairs
#define CONFIG_OPTIMIZE_32BIT 0x40000000 // new optimizations for 32-bit integer files
#define CONFIG_OPTIMIZE_MONO 0x80000000 // optimize for mono streams posing as stereo
// The lower 8 bits of qmode indicate the use of new features in version 5 that (presently)
// only apply to Core Audio Files (CAF) and DSD files, but could apply to other things too.
// These flags are stored in the file and can be retrieved by a decoder that is aware of
// them, but the individual bits are meaningless to the library. If ANY of these bits are
// set then the MD5 sum is written with a new ID so that old decoders will not see it
// (because these features will cause the MD5 sum to be different and fail).
#define QMODE_BIG_ENDIAN 0x1 // big-endian data format (opposite of WAV format)
#define QMODE_SIGNED_BYTES 0x2 // 8-bit audio data is signed (opposite of WAV format)
#define QMODE_UNSIGNED_WORDS 0x4 // audio data (other than 8-bit) is unsigned (opposite of WAV format)
#define QMODE_REORDERED_CHANS 0x8 // source channels were not Microsoft order, so they were reordered
#define QMODE_DSD_LSB_FIRST 0x10 // DSD bytes, LSB first (most Sony .dsf files)
#define QMODE_DSD_MSB_FIRST 0x20 // DSD bytes, MSB first (Philips .dff files)
#define QMODE_DSD_IN_BLOCKS 0x40 // DSD data is blocked by channels (Sony .dsf only)
#define QMODE_DSD_AUDIO (QMODE_DSD_LSB_FIRST | QMODE_DSD_MSB_FIRST)
// The rest of the qmode word is reserved for the private use of the command-line programs
// and are ignored by the library (and not stored either). They really should not be defined
// here, but I thought it would be a good idea to have all the definitions together.
#define QMODE_ADOBE_MODE 0x100 // user specified Adobe mode
#define QMODE_NO_STORE_WRAPPER 0x200 // user specified to not store audio file wrapper (RIFF, CAFF, etc.)
#define QMODE_CHANS_UNASSIGNED 0x400 // user specified "..." in --channel-order option
#define QMODE_IGNORE_LENGTH 0x800 // user specified to ignore length in file header
#define QMODE_RAW_PCM 0x1000 // user specified raw PCM format (no header present)
#define QMODE_EVEN_BYTE_DEPTH 0x2000 // user specified to force even byte bit-depth
////////////// Callbacks used for reading & writing WavPack streams //////////
typedef struct {
int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
uint32_t (*get_pos)(void *id);
int (*set_pos_abs)(void *id, uint32_t pos);
int (*set_pos_rel)(void *id, int32_t delta, int mode);
int (*push_back_byte)(void *id, int c);
uint32_t (*get_length)(void *id);
int (*can_seek)(void *id);
// this callback is for writing edited tags only
int32_t (*write_bytes)(void *id, void *data, int32_t bcount);
} WavpackStreamReader;
// Extended version of structure for handling large files and added
// functionality for truncating and closing files
typedef struct {
int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
int32_t (*write_bytes)(void *id, void *data, int32_t bcount);
int64_t (*get_pos)(void *id); // new signature for large files
int (*set_pos_abs)(void *id, int64_t pos); // new signature for large files
int (*set_pos_rel)(void *id, int64_t delta, int mode); // new signature for large files
int (*push_back_byte)(void *id, int c);
int64_t (*get_length)(void *id); // new signature for large files
int (*can_seek)(void *id);
int (*truncate_here)(void *id); // new function to truncate file at current position
int (*close)(void *id); // new function to close file
} WavpackStreamReader64;
typedef int (*WavpackBlockOutput)(void *id, void *data, int32_t bcount);
//////////////////////////// function prototypes /////////////////////////////
typedef struct WavpackContext WavpackContext;
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_WAVPACK_SAMPLES ((1LL << 40) - 257)
WavpackContext *WavpackOpenRawDecoder (
void *main_data, int32_t main_size,
void *corr_data, int32_t corr_size,
int16_t version, char *error, int flags, int norm_offset);
WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
WavpackContext *WavpackOpenFileInputEx (WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset);
#define OPEN_WVC 0x1 // open/read "correction" file
#define OPEN_TAGS 0x2 // read ID3v1 / APEv2 tags (seekable file)
#define OPEN_WRAPPER 0x4 // make audio wrapper available (i.e. RIFF)
#define OPEN_2CH_MAX 0x8 // open multichannel as stereo (no downmix)
#define OPEN_NORMALIZE 0x10 // normalize floating point data to +/- 1.0
#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks
// w/o regard to header file position info
#define OPEN_EDIT_TAGS 0x40 // allow editing of tags
#define OPEN_FILE_UTF8 0x80 // assume filenames are UTF-8 encoded, not ANSI (Windows only)
// new for version 5
#define OPEN_DSD_NATIVE 0x100 // open DSD files as bitstreams
// (returned as 8-bit "samples" stored in 32-bit words)
#define OPEN_DSD_AS_PCM 0x200 // open DSD files as 24-bit PCM (decimated 8x)
#define OPEN_ALT_TYPES 0x400 // application is aware of alternate file types & qmode
// (just affects retrieving wrappers & MD5 checksums)
#define OPEN_NO_CHECKSUM 0x800 // don't verify block checksums before decoding
// new for multithreaded
#define OPEN_THREADS_SHFT 12 // specify number of additional worker threads here for
#define OPEN_THREADS_MASK 0xF000 // decode; 0 to disable, otherwise 1-15 added threads
int WavpackGetMode (WavpackContext *wpc);
#define MODE_WVC 0x1
#define MODE_LOSSLESS 0x2
#define MODE_HYBRID 0x4
#define MODE_FLOAT 0x8
#define MODE_VALID_TAG 0x10
#define MODE_HIGH 0x20
#define MODE_FAST 0x40
#define MODE_EXTRA 0x80 // extra mode used, see MODE_XMODE for possible level
#define MODE_APETAG 0x100
#define MODE_SFX 0x200
#define MODE_VERY_HIGH 0x400
#define MODE_MD5 0x800
#define MODE_XMODE 0x7000 // mask for extra level (1-6, 0=unknown)
#define MODE_DNS 0x8000
int WavpackVerifySingleBlock (unsigned char *buffer, int verify_checksum);
int WavpackGetQualifyMode (WavpackContext *wpc);
char *WavpackGetErrorMessage (WavpackContext *wpc);
int WavpackGetVersion (WavpackContext *wpc);
char *WavpackGetFileExtension (WavpackContext *wpc);
unsigned char WavpackGetFileFormat (WavpackContext *wpc);
uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
uint32_t WavpackGetNumSamples (WavpackContext *wpc);
int64_t WavpackGetNumSamples64 (WavpackContext *wpc);
uint32_t WavpackGetNumSamplesInFrame (WavpackContext *wpc);
uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
int64_t WavpackGetSampleIndex64 (WavpackContext *wpc);
int WavpackGetNumErrors (WavpackContext *wpc);
int WavpackLossyBlocks (WavpackContext *wpc);
int WavpackSeekSample (WavpackContext *wpc, uint32_t sample);
int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample);
WavpackContext *WavpackCloseFile (WavpackContext *wpc);
uint32_t WavpackGetSampleRate (WavpackContext *wpc);
uint32_t WavpackGetNativeSampleRate (WavpackContext *wpc);
int WavpackGetBitsPerSample (WavpackContext *wpc);
int WavpackGetBytesPerSample (WavpackContext *wpc);
int WavpackGetNumChannels (WavpackContext *wpc);
int WavpackGetChannelMask (WavpackContext *wpc);
int WavpackGetReducedChannels (WavpackContext *wpc);
int WavpackGetFloatNormExp (WavpackContext *wpc);
int WavpackGetMD5Sum (WavpackContext *wpc, unsigned char data [16]);
void WavpackGetChannelIdentities (WavpackContext *wpc, unsigned char *identities);
uint32_t WavpackGetChannelLayout (WavpackContext *wpc, unsigned char *reorder);
uint32_t WavpackGetWrapperBytes (WavpackContext *wpc);
unsigned char *WavpackGetWrapperData (WavpackContext *wpc);
void WavpackFreeWrapper (WavpackContext *wpc);
void WavpackSeekTrailingWrapper (WavpackContext *wpc);
double WavpackGetProgress (WavpackContext *wpc);
uint32_t WavpackGetFileSize (WavpackContext *wpc);
int64_t WavpackGetFileSize64 (WavpackContext *wpc);
double WavpackGetRatio (WavpackContext *wpc);
double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc);
double WavpackGetInstantBitrate (WavpackContext *wpc);
int WavpackGetNumTagItems (WavpackContext *wpc);
int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size);
int WavpackGetTagItemIndexed (WavpackContext *wpc, int index, char *item, int size);
int WavpackGetNumBinaryTagItems (WavpackContext *wpc);
int WavpackGetBinaryTagItem (WavpackContext *wpc, const char *item, char *value, int size);
int WavpackGetBinaryTagItemIndexed (WavpackContext *wpc, int index, char *item, int size);
int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize);
int WavpackAppendBinaryTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize);
int WavpackDeleteTagItem (WavpackContext *wpc, const char *item);
int WavpackWriteTag (WavpackContext *wpc);
WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id);
void WavpackSetFileInformation (WavpackContext *wpc, char *file_extension, unsigned char file_format);
#define WP_FORMAT_WAV 0 // Microsoft RIFF, including BWF and RF64 variants
#define WP_FORMAT_W64 1 // Sony Wave64
#define WP_FORMAT_CAF 2 // Apple CoreAudio
#define WP_FORMAT_DFF 3 // Philips DSDIFF
#define WP_FORMAT_DSF 4 // Sony DSD Format
#define WP_FORMAT_AIF 5 // Apple AIFF
int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids);
int WavpackSetChannelLayout (WavpackContext *wpc, uint32_t layout_tag, const unsigned char *reorder);
int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
int WavpackStoreMD5Sum (WavpackContext *wpc, unsigned char data [16]);
int WavpackPackInit (WavpackContext *wpc);
int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
int WavpackFlushSamples (WavpackContext *wpc);
void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
void *WavpackGetWrapperLocation (void *first_block, uint32_t *size);
double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak);
void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp);
void WavpackLittleEndianToNative (void *data, char *format);
void WavpackNativeToLittleEndian (void *data, char *format);
void WavpackBigEndianToNative (void *data, char *format);
void WavpackNativeToBigEndian (void *data, char *format);
uint32_t WavpackGetLibraryVersion (void);
const char *WavpackGetLibraryVersionString (void);
#ifdef __cplusplus
}
#endif
#endif
+416
View File
@@ -0,0 +1,416 @@
#ifndef XMP_H
#define XMP_H
#if defined(EMSCRIPTEN)
# include <emscripten.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define XMP_VERSION "4.7.0"
#define XMP_VERCODE 0x040700
#define XMP_VER_MAJOR 4
#define XMP_VER_MINOR 7
#define XMP_VER_RELEASE 0
#if defined(_WIN32) && !defined(__CYGWIN__)
# if defined(LIBXMP_STATIC)
# define LIBXMP_EXPORT
# elif defined(BUILDING_DLL)
# define LIBXMP_EXPORT __declspec(dllexport)
# else
# define LIBXMP_EXPORT __declspec(dllimport)
# endif
#elif defined(__OS2__) && defined(__WATCOMC__)
# if defined(LIBXMP_STATIC)
# define LIBXMP_EXPORT
# elif defined(BUILDING_DLL)
# define LIBXMP_EXPORT __declspec(dllexport)
# else
# define LIBXMP_EXPORT
# endif
#elif (defined(__GNUC__) || defined(__clang__) || defined(__HP_cc)) && defined(XMP_SYM_VISIBILITY)
# if defined(LIBXMP_STATIC)
# define LIBXMP_EXPORT
# else
# define LIBXMP_EXPORT __attribute__((visibility("default")))
# endif
#elif defined(__SUNPRO_C) && defined(XMP_LDSCOPE_GLOBAL)
# if defined(LIBXMP_STATIC)
# define LIBXMP_EXPORT
# else
# define LIBXMP_EXPORT __global
# endif
#elif defined(EMSCRIPTEN)
# define LIBXMP_EXPORT EMSCRIPTEN_KEEPALIVE
# define LIBXMP_EXPORT_VAR
#else
# define LIBXMP_EXPORT
#endif
#if !defined(LIBXMP_EXPORT_VAR)
# define LIBXMP_EXPORT_VAR LIBXMP_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 */
#define XMP_FORMAT_32BIT (1 << 3) /* Mix to 32-bit int instead of 16 */
/* 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 768000 /* 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_subinstrument {
int vol; /* Default volume */
int gvl; /* Global volume */
#define XMP_INST_NO_DEFAULT_PAN -1
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 */
};
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 *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_STEREO (1 << 7) /* Interlaced stereo sample */
#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 */
#define XMP_MARK_SKIP 0xfe /* S3M/IT-only: skip position */
#define XMP_MARK_END 0xff /* S3M/IT-only: end position */
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_channel_info {
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 */
};
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 channel_info[XMP_MAX_CHANNELS]; /* Current channel information */
};
struct xmp_callbacks {
unsigned long (*read_func)(void *dest, unsigned long len,
unsigned long nmemb, void *priv);
int (*seek_func)(void *priv, long offset, int whence);
long (*tell_func)(void *priv);
int (*close_func)(void *priv);
};
typedef char *xmp_context;
LIBXMP_EXPORT_VAR extern const char *xmp_version;
LIBXMP_EXPORT_VAR extern const unsigned int xmp_vercode;
LIBXMP_EXPORT int xmp_syserrno (void);
LIBXMP_EXPORT xmp_context xmp_create_context (void);
LIBXMP_EXPORT void xmp_free_context (xmp_context);
LIBXMP_EXPORT int xmp_load_module (xmp_context, const char *);
LIBXMP_EXPORT int xmp_load_module_from_memory (xmp_context, const void *, long);
LIBXMP_EXPORT int xmp_load_module_from_file (xmp_context, void *, long);
LIBXMP_EXPORT int xmp_load_module_from_callbacks (xmp_context, void *, struct xmp_callbacks);
LIBXMP_EXPORT int xmp_test_module (const char *, struct xmp_test_info *);
LIBXMP_EXPORT int xmp_test_module_from_memory (const void *, long, struct xmp_test_info *);
LIBXMP_EXPORT int xmp_test_module_from_file (void *, struct xmp_test_info *);
LIBXMP_EXPORT int xmp_test_module_from_callbacks (void *, struct xmp_callbacks, struct xmp_test_info *);
LIBXMP_EXPORT void xmp_scan_module (xmp_context);
LIBXMP_EXPORT void xmp_release_module (xmp_context);
LIBXMP_EXPORT int xmp_start_player (xmp_context, int, int);
LIBXMP_EXPORT int xmp_play_frame (xmp_context);
LIBXMP_EXPORT int xmp_play_buffer (xmp_context, void *, int, int);
LIBXMP_EXPORT void xmp_get_frame_info (xmp_context, struct xmp_frame_info *);
LIBXMP_EXPORT void xmp_end_player (xmp_context);
LIBXMP_EXPORT void xmp_inject_event (xmp_context, int, struct xmp_event *);
LIBXMP_EXPORT void xmp_get_module_info (xmp_context, struct xmp_module_info *);
LIBXMP_EXPORT const char *const *xmp_get_format_list (void);
LIBXMP_EXPORT int xmp_next_position (xmp_context);
LIBXMP_EXPORT int xmp_prev_position (xmp_context);
LIBXMP_EXPORT int xmp_set_position (xmp_context, int);
LIBXMP_EXPORT int xmp_set_row (xmp_context, int);
LIBXMP_EXPORT int xmp_set_tempo_factor(xmp_context, double);
LIBXMP_EXPORT int xmp_set_tempo_factor_relative(xmp_context, double);
LIBXMP_EXPORT double xmp_get_tempo_factor(xmp_context);
LIBXMP_EXPORT double xmp_get_tempo_factor_relative(xmp_context);
LIBXMP_EXPORT void xmp_stop_module (xmp_context);
LIBXMP_EXPORT void xmp_restart_module (xmp_context);
LIBXMP_EXPORT int xmp_seek_time (xmp_context, int);
LIBXMP_EXPORT int xmp_seek_time_frame (xmp_context, int);
LIBXMP_EXPORT int xmp_channel_mute (xmp_context, int, int);
LIBXMP_EXPORT int xmp_channel_vol (xmp_context, int, int);
LIBXMP_EXPORT int xmp_set_player (xmp_context, int, int);
LIBXMP_EXPORT int xmp_get_player (xmp_context, int);
LIBXMP_EXPORT int xmp_set_instrument_path (xmp_context, const char *);
/* External sample mixer API */
LIBXMP_EXPORT int xmp_start_smix (xmp_context, int, int);
LIBXMP_EXPORT void xmp_end_smix (xmp_context);
LIBXMP_EXPORT int xmp_smix_play_instrument(xmp_context, int, int, int, int);
LIBXMP_EXPORT int xmp_smix_play_sample (xmp_context, int, int, int, int);
LIBXMP_EXPORT int xmp_smix_channel_pan (xmp_context, int, int);
LIBXMP_EXPORT int xmp_smix_load_sample (xmp_context, int, const char *);
LIBXMP_EXPORT int xmp_smix_release_sample (xmp_context, int);
#ifdef __cplusplus
}
#endif
#endif /* XMP_H */
@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
@@ -0,0 +1,28 @@
Copyright (c) 2002-2020 Xiph.org Foundation
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,25 @@
Copyright (c) 1998 - 2025 David Bryant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -1,21 +1,20 @@
The MIT License (MIT) Extended Module Player
Copyright (C) 1996-2024 Claudio Matsuoka and Hipolito Carraro Jr
Copyright (c) 2014-2024 Omar Cornut 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:
Permission is hereby granted, free of charge, to any person obtaining a copy The above copyright notice and this permission notice shall be included in
of this software and associated documentation files (the "Software"), to deal all copies or substantial portions of the Software.
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 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
SOFTWARE. THE SOFTWARE.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
@@ -0,0 +1,28 @@
Copyright (c) 2002-2020 Xiph.org Foundation
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,44 @@
Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
Jean-Marc Valin, Timothy B. Terriberry,
CSIRO, Gregory Maxwell, Mark Borgerding,
Erik de Castro Lopo
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Internet Society, IETF or IETF Trust, nor the
names of specific contributors, may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Opus is subject to the royalty-free patent licenses which are
specified at:
Xiph.Org Foundation:
https://datatracker.ietf.org/ipr/1524/
Microsoft Corporation:
https://datatracker.ietf.org/ipr/1914/
Broadcom Corporation:
https://datatracker.ietf.org/ipr/1526/
@@ -0,0 +1,28 @@
Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.Org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,25 @@
Copyright (c) 1998 - 2025 David Bryant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,20 @@
Extended Module Player
Copyright (C) 1996-2024 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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir Condition="'$(SolutionDir)'==''">$(ProjectDir)..\</SolutionDir>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\timidity\common.c" />
<ClCompile Include="..\..\src\timidity\instrum.c" />
<ClCompile Include="..\..\src\timidity\mix.c" />
<ClCompile Include="..\..\src\timidity\output.c" />
<ClCompile Include="..\..\src\timidity\playmidi.c" />
<ClCompile Include="..\..\src\timidity\readmidi.c" />
<ClCompile Include="..\..\src\timidity\resample.c" />
<ClCompile Include="..\..\src\timidity\tables.c" />
<ClCompile Include="..\..\src\timidity\timidity.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\timidity\common.h" />
<ClInclude Include="..\..\src\timidity\instrum.h" />
<ClInclude Include="..\..\src\timidity\mix.h" />
<ClInclude Include="..\..\src\timidity\options.h" />
<ClInclude Include="..\..\src\timidity\output.h" />
<ClInclude Include="..\..\src\timidity\playmidi.h" />
<ClInclude Include="..\..\src\timidity\readmidi.h" />
<ClInclude Include="..\..\src\timidity\resample.h" />
<ClInclude Include="..\..\src\timidity\tables.h" />
<ClInclude Include="..\..\src\timidity\timidity.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>timidity</ProjectName>
<ProjectGuid>{B162B6F1-E876-4D5F-A1F6-E3A6DC2F4A2C}</ProjectGuid>
<RootNamespace>timidity</RootNamespace>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
</ResourceCompile>
<Bscmake />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
</ResourceCompile>
<Bscmake />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
</ResourceCompile>
<Bscmake />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
</ResourceCompile>
<Bscmake />
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,573 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 55;
objects = {
/* Begin PBXAggregateTarget section */
F3B38D7B296F9312005DA6D3 /* FLAC.xcframework */ = {
isa = PBXAggregateTarget;
buildConfigurationList = F3B38D7E296F9312005DA6D3 /* Build configuration list for PBXAggregateTarget "FLAC.xcframework" */;
buildPhases = (
F3B38D7F296F931D005DA6D3 /* ShellScript */,
);
dependencies = (
);
name = FLAC.xcframework;
productName = xcFramework;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
F3F70E8F281F4562005AA27D /* float.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E74281F4561005AA27D /* float.c */; };
F3F70E90281F4562005AA27D /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E75281F4561005AA27D /* lpc.c */; };
F3F70E91281F4562005AA27D /* stream_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E76281F4561005AA27D /* stream_decoder.c */; };
F3F70E92281F4562005AA27D /* fixed_intrin_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E77281F4561005AA27D /* fixed_intrin_sse2.c */; };
F3F70E93281F4562005AA27D /* stream_encoder_intrin_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E78281F4561005AA27D /* stream_encoder_intrin_sse2.c */; };
F3F70E94281F4562005AA27D /* bitmath.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E79281F4561005AA27D /* bitmath.c */; };
F3F70E95281F4562005AA27D /* lpc_intrin_sse2.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E7A281F4561005AA27D /* lpc_intrin_sse2.c */; };
F3F70E96281F4562005AA27D /* bitreader.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E7B281F4561005AA27D /* bitreader.c */; };
F3F70E97281F4562005AA27D /* fixed_intrin_ssse3.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E7C281F4561005AA27D /* fixed_intrin_ssse3.c */; };
F3F70E98281F4562005AA27D /* format.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E7D281F4561005AA27D /* format.c */; };
F3F70E99281F4562005AA27D /* stream_encoder_intrin_avx2.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E7E281F4561005AA27D /* stream_encoder_intrin_avx2.c */; };
F3F70E9A281F4562005AA27D /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E7F281F4561005AA27D /* memory.c */; };
F3F70E9B281F4562005AA27D /* stream_encoder_intrin_ssse3.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E80281F4561005AA27D /* stream_encoder_intrin_ssse3.c */; };
F3F70E9C281F4562005AA27D /* lpc_intrin_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E81281F4561005AA27D /* lpc_intrin_sse.c */; };
F3F70E9D281F4562005AA27D /* lpc_intrin_avx2.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E82281F4561005AA27D /* lpc_intrin_avx2.c */; };
F3F70E9E281F4562005AA27D /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E83281F4561005AA27D /* window.c */; };
F3F70E9F281F4562005AA27D /* fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E84281F4561005AA27D /* fixed.c */; };
F3F70EA0281F4562005AA27D /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E85281F4561005AA27D /* md5.c */; };
F3F70EA1281F4562005AA27D /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E86281F4561005AA27D /* cpu.c */; };
F3F70EA2281F4562005AA27D /* stream_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E87281F4561005AA27D /* stream_encoder.c */; };
F3F70EA3281F4562005AA27D /* crc.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E88281F4561005AA27D /* crc.c */; };
F3F70EA4281F4562005AA27D /* metadata_object.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E89281F4561005AA27D /* metadata_object.c */; };
F3F70EA5281F4562005AA27D /* bitwriter.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E8A281F4561005AA27D /* bitwriter.c */; };
F3F70EA6281F4562005AA27D /* lpc_intrin_sse41.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E8B281F4561005AA27D /* lpc_intrin_sse41.c */; };
F3F70EA7281F4562005AA27D /* stream_encoder_framing.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E8C281F4561005AA27D /* stream_encoder_framing.c */; };
F3F70EA8281F4562005AA27D /* metadata_iterators.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E8D281F4561005AA27D /* metadata_iterators.c */; };
F3F70EA9281F4562005AA27D /* lpc_intrin_vsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F70E8E281F4561005AA27D /* lpc_intrin_vsx.c */; };
F3F70EB3281F45A9005AA27D /* callback.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EAA281F45A9005AA27D /* callback.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EB4281F45A9005AA27D /* stream_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EAB281F45A9005AA27D /* stream_decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EB5281F45A9005AA27D /* format.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EAC281F45A9005AA27D /* format.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EB6281F45A9005AA27D /* assert.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EAD281F45A9005AA27D /* assert.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EB7281F45A9005AA27D /* metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EAE281F45A9005AA27D /* metadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EB8281F45A9005AA27D /* all.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EAF281F45A9005AA27D /* all.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EB9281F45A9005AA27D /* stream_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EB0281F45A9005AA27D /* stream_encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EBA281F45A9005AA27D /* export.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EB1281F45A9005AA27D /* export.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EBB281F45A9005AA27D /* ordinals.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F70EB2281F45A9005AA27D /* ordinals.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3F70EBE281F45D0005AA27D /* COPYING.Xiph in Resources */ = {isa = PBXBuildFile; fileRef = F3F70EBC281F45D0005AA27D /* COPYING.Xiph */; };
F3F70EBF281F45D0005AA27D /* README in Resources */ = {isa = PBXBuildFile; fileRef = F3F70EBD281F45D0005AA27D /* README */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F3F70E67281F442C005AA27D /* FLAC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FLAC.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F3F70E74281F4561005AA27D /* float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = float.c; path = ../../external/flac/src/libFLAC/float.c; sourceTree = "<group>"; };
F3F70E75281F4561005AA27D /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpc.c; path = ../../external/flac/src/libFLAC/lpc.c; sourceTree = "<group>"; };
F3F70E76281F4561005AA27D /* stream_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stream_decoder.c; path = ../../external/flac/src/libFLAC/stream_decoder.c; sourceTree = "<group>"; };
F3F70E77281F4561005AA27D /* fixed_intrin_sse2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fixed_intrin_sse2.c; path = ../../external/flac/src/libFLAC/fixed_intrin_sse2.c; sourceTree = "<group>"; };
F3F70E78281F4561005AA27D /* stream_encoder_intrin_sse2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stream_encoder_intrin_sse2.c; path = ../../external/flac/src/libFLAC/stream_encoder_intrin_sse2.c; sourceTree = "<group>"; };
F3F70E79281F4561005AA27D /* bitmath.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitmath.c; path = ../../external/flac/src/libFLAC/bitmath.c; sourceTree = "<group>"; };
F3F70E7A281F4561005AA27D /* lpc_intrin_sse2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpc_intrin_sse2.c; path = ../../external/flac/src/libFLAC/lpc_intrin_sse2.c; sourceTree = "<group>"; };
F3F70E7B281F4561005AA27D /* bitreader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitreader.c; path = ../../external/flac/src/libFLAC/bitreader.c; sourceTree = "<group>"; };
F3F70E7C281F4561005AA27D /* fixed_intrin_ssse3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fixed_intrin_ssse3.c; path = ../../external/flac/src/libFLAC/fixed_intrin_ssse3.c; sourceTree = "<group>"; };
F3F70E7D281F4561005AA27D /* format.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = format.c; path = ../../external/flac/src/libFLAC/format.c; sourceTree = "<group>"; };
F3F70E7E281F4561005AA27D /* stream_encoder_intrin_avx2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stream_encoder_intrin_avx2.c; path = ../../external/flac/src/libFLAC/stream_encoder_intrin_avx2.c; sourceTree = "<group>"; };
F3F70E7F281F4561005AA27D /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memory.c; path = ../../external/flac/src/libFLAC/memory.c; sourceTree = "<group>"; };
F3F70E80281F4561005AA27D /* stream_encoder_intrin_ssse3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stream_encoder_intrin_ssse3.c; path = ../../external/flac/src/libFLAC/stream_encoder_intrin_ssse3.c; sourceTree = "<group>"; };
F3F70E81281F4561005AA27D /* lpc_intrin_sse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpc_intrin_sse.c; path = ../../external/flac/src/libFLAC/lpc_intrin_sse.c; sourceTree = "<group>"; };
F3F70E82281F4561005AA27D /* lpc_intrin_avx2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpc_intrin_avx2.c; path = ../../external/flac/src/libFLAC/lpc_intrin_avx2.c; sourceTree = "<group>"; };
F3F70E83281F4561005AA27D /* window.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = window.c; path = ../../external/flac/src/libFLAC/window.c; sourceTree = "<group>"; };
F3F70E84281F4561005AA27D /* fixed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fixed.c; path = ../../external/flac/src/libFLAC/fixed.c; sourceTree = "<group>"; };
F3F70E85281F4561005AA27D /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../external/flac/src/libFLAC/md5.c; sourceTree = "<group>"; };
F3F70E86281F4561005AA27D /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = ../../external/flac/src/libFLAC/cpu.c; sourceTree = "<group>"; };
F3F70E87281F4561005AA27D /* stream_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stream_encoder.c; path = ../../external/flac/src/libFLAC/stream_encoder.c; sourceTree = "<group>"; };
F3F70E88281F4561005AA27D /* crc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crc.c; path = ../../external/flac/src/libFLAC/crc.c; sourceTree = "<group>"; };
F3F70E89281F4561005AA27D /* metadata_object.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = metadata_object.c; path = ../../external/flac/src/libFLAC/metadata_object.c; sourceTree = "<group>"; };
F3F70E8A281F4561005AA27D /* bitwriter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitwriter.c; path = ../../external/flac/src/libFLAC/bitwriter.c; sourceTree = "<group>"; };
F3F70E8B281F4561005AA27D /* lpc_intrin_sse41.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpc_intrin_sse41.c; path = ../../external/flac/src/libFLAC/lpc_intrin_sse41.c; sourceTree = "<group>"; };
F3F70E8C281F4561005AA27D /* stream_encoder_framing.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stream_encoder_framing.c; path = ../../external/flac/src/libFLAC/stream_encoder_framing.c; sourceTree = "<group>"; };
F3F70E8D281F4561005AA27D /* metadata_iterators.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = metadata_iterators.c; path = ../../external/flac/src/libFLAC/metadata_iterators.c; sourceTree = "<group>"; };
F3F70E8E281F4561005AA27D /* lpc_intrin_vsx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpc_intrin_vsx.c; path = ../../external/flac/src/libFLAC/lpc_intrin_vsx.c; sourceTree = "<group>"; };
F3F70EAA281F45A9005AA27D /* callback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = callback.h; path = ../../external/flac/include/FLAC/callback.h; sourceTree = "<group>"; };
F3F70EAB281F45A9005AA27D /* stream_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stream_decoder.h; path = ../../external/flac/include/FLAC/stream_decoder.h; sourceTree = "<group>"; };
F3F70EAC281F45A9005AA27D /* format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = format.h; path = ../../external/flac/include/FLAC/format.h; sourceTree = "<group>"; };
F3F70EAD281F45A9005AA27D /* assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = assert.h; path = ../../external/flac/include/FLAC/assert.h; sourceTree = "<group>"; };
F3F70EAE281F45A9005AA27D /* metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = metadata.h; path = ../../external/flac/include/FLAC/metadata.h; sourceTree = "<group>"; };
F3F70EAF281F45A9005AA27D /* all.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = all.h; path = ../../external/flac/include/FLAC/all.h; sourceTree = "<group>"; };
F3F70EB0281F45A9005AA27D /* stream_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stream_encoder.h; path = ../../external/flac/include/FLAC/stream_encoder.h; sourceTree = "<group>"; };
F3F70EB1281F45A9005AA27D /* export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = export.h; path = ../../external/flac/include/FLAC/export.h; sourceTree = "<group>"; };
F3F70EB2281F45A9005AA27D /* ordinals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ordinals.h; path = ../../external/flac/include/FLAC/ordinals.h; sourceTree = "<group>"; };
F3F70EBC281F45D0005AA27D /* COPYING.Xiph */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING.Xiph; path = ../../external/flac/COPYING.Xiph; sourceTree = "<group>"; };
F3F70EBD281F45D0005AA27D /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../../external/flac/README; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F3F70E64281F442C005AA27D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F3F70E5D281F442C005AA27D = {
isa = PBXGroup;
children = (
F3F70E68281F442C005AA27D /* Products */,
F3F70E73281F44E4005AA27D /* Resources */,
F3F70E72281F44DD005AA27D /* Headers */,
F3F70E71281F44C9005AA27D /* Source */,
);
sourceTree = "<group>";
};
F3F70E68281F442C005AA27D /* Products */ = {
isa = PBXGroup;
children = (
F3F70E67281F442C005AA27D /* FLAC.framework */,
);
name = Products;
sourceTree = "<group>";
};
F3F70E71281F44C9005AA27D /* Source */ = {
isa = PBXGroup;
children = (
F3F70E79281F4561005AA27D /* bitmath.c */,
F3F70E7B281F4561005AA27D /* bitreader.c */,
F3F70E8A281F4561005AA27D /* bitwriter.c */,
F3F70E86281F4561005AA27D /* cpu.c */,
F3F70E88281F4561005AA27D /* crc.c */,
F3F70E77281F4561005AA27D /* fixed_intrin_sse2.c */,
F3F70E7C281F4561005AA27D /* fixed_intrin_ssse3.c */,
F3F70E84281F4561005AA27D /* fixed.c */,
F3F70E74281F4561005AA27D /* float.c */,
F3F70E7D281F4561005AA27D /* format.c */,
F3F70E82281F4561005AA27D /* lpc_intrin_avx2.c */,
F3F70E81281F4561005AA27D /* lpc_intrin_sse.c */,
F3F70E7A281F4561005AA27D /* lpc_intrin_sse2.c */,
F3F70E8B281F4561005AA27D /* lpc_intrin_sse41.c */,
F3F70E8E281F4561005AA27D /* lpc_intrin_vsx.c */,
F3F70E75281F4561005AA27D /* lpc.c */,
F3F70E85281F4561005AA27D /* md5.c */,
F3F70E7F281F4561005AA27D /* memory.c */,
F3F70E8D281F4561005AA27D /* metadata_iterators.c */,
F3F70E89281F4561005AA27D /* metadata_object.c */,
F3F70E76281F4561005AA27D /* stream_decoder.c */,
F3F70E8C281F4561005AA27D /* stream_encoder_framing.c */,
F3F70E7E281F4561005AA27D /* stream_encoder_intrin_avx2.c */,
F3F70E78281F4561005AA27D /* stream_encoder_intrin_sse2.c */,
F3F70E80281F4561005AA27D /* stream_encoder_intrin_ssse3.c */,
F3F70E87281F4561005AA27D /* stream_encoder.c */,
F3F70E83281F4561005AA27D /* window.c */,
);
name = Source;
sourceTree = "<group>";
};
F3F70E72281F44DD005AA27D /* Headers */ = {
isa = PBXGroup;
children = (
F3F70EAF281F45A9005AA27D /* all.h */,
F3F70EAD281F45A9005AA27D /* assert.h */,
F3F70EAA281F45A9005AA27D /* callback.h */,
F3F70EB1281F45A9005AA27D /* export.h */,
F3F70EAC281F45A9005AA27D /* format.h */,
F3F70EAE281F45A9005AA27D /* metadata.h */,
F3F70EB2281F45A9005AA27D /* ordinals.h */,
F3F70EAB281F45A9005AA27D /* stream_decoder.h */,
F3F70EB0281F45A9005AA27D /* stream_encoder.h */,
);
name = Headers;
sourceTree = "<group>";
};
F3F70E73281F44E4005AA27D /* Resources */ = {
isa = PBXGroup;
children = (
F3F70EBC281F45D0005AA27D /* COPYING.Xiph */,
F3F70EBD281F45D0005AA27D /* README */,
);
name = Resources;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
F3F70E62281F442C005AA27D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
F3F70EB8281F45A9005AA27D /* all.h in Headers */,
F3F70EB6281F45A9005AA27D /* assert.h in Headers */,
F3F70EB3281F45A9005AA27D /* callback.h in Headers */,
F3F70EBA281F45A9005AA27D /* export.h in Headers */,
F3F70EB5281F45A9005AA27D /* format.h in Headers */,
F3F70EB7281F45A9005AA27D /* metadata.h in Headers */,
F3F70EBB281F45A9005AA27D /* ordinals.h in Headers */,
F3F70EB4281F45A9005AA27D /* stream_decoder.h in Headers */,
F3F70EB9281F45A9005AA27D /* stream_encoder.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
F3F70E66281F442C005AA27D /* FLAC */ = {
isa = PBXNativeTarget;
buildConfigurationList = F3F70E6E281F442C005AA27D /* Build configuration list for PBXNativeTarget "FLAC" */;
buildPhases = (
F3F70E62281F442C005AA27D /* Headers */,
F3F70E63281F442C005AA27D /* Sources */,
F3F70E64281F442C005AA27D /* Frameworks */,
F3F70E65281F442C005AA27D /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = FLAC;
productName = FLAC;
productReference = F3F70E67281F442C005AA27D /* FLAC.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F3F70E5E281F442C005AA27D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastUpgradeCheck = 1330;
TargetAttributes = {
F3B38D7B296F9312005DA6D3 = {
CreatedOnToolsVersion = 14.2;
};
F3F70E66281F442C005AA27D = {
CreatedOnToolsVersion = 13.3.1;
};
};
};
buildConfigurationList = F3F70E61281F442C005AA27D /* Build configuration list for PBXProject "FLAC" */;
compatibilityVersion = "Xcode 13.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F3F70E5D281F442C005AA27D;
productRefGroup = F3F70E68281F442C005AA27D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F3F70E66281F442C005AA27D /* FLAC */,
F3B38D7B296F9312005DA6D3 /* FLAC.xcframework */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F3F70E65281F442C005AA27D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F3F70EBF281F45D0005AA27D /* README in Resources */,
F3F70EBE281F45D0005AA27D /* COPYING.Xiph in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
F3B38D7F296F931D005DA6D3 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"FLAC\"\nPROJECT_NAME=\"FLAC\"\nSCHEME=\"FLAC\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"../build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -sdk macosx \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk iphonesimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -sdk iphoneos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk appletvsimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -sdk appletvos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F3F70E63281F442C005AA27D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F3F70EA8281F4562005AA27D /* metadata_iterators.c in Sources */,
F3F70E98281F4562005AA27D /* format.c in Sources */,
F3F70E9E281F4562005AA27D /* window.c in Sources */,
F3F70E99281F4562005AA27D /* stream_encoder_intrin_avx2.c in Sources */,
F3F70EA4281F4562005AA27D /* metadata_object.c in Sources */,
F3F70E8F281F4562005AA27D /* float.c in Sources */,
F3F70E95281F4562005AA27D /* lpc_intrin_sse2.c in Sources */,
F3F70E91281F4562005AA27D /* stream_decoder.c in Sources */,
F3F70EA0281F4562005AA27D /* md5.c in Sources */,
F3F70E9B281F4562005AA27D /* stream_encoder_intrin_ssse3.c in Sources */,
F3F70EA2281F4562005AA27D /* stream_encoder.c in Sources */,
F3F70E90281F4562005AA27D /* lpc.c in Sources */,
F3F70EA5281F4562005AA27D /* bitwriter.c in Sources */,
F3F70EA6281F4562005AA27D /* lpc_intrin_sse41.c in Sources */,
F3F70E92281F4562005AA27D /* fixed_intrin_sse2.c in Sources */,
F3F70E93281F4562005AA27D /* stream_encoder_intrin_sse2.c in Sources */,
F3F70E97281F4562005AA27D /* fixed_intrin_ssse3.c in Sources */,
F3F70E96281F4562005AA27D /* bitreader.c in Sources */,
F3F70E9A281F4562005AA27D /* memory.c in Sources */,
F3F70EA7281F4562005AA27D /* stream_encoder_framing.c in Sources */,
F3F70EA3281F4562005AA27D /* crc.c in Sources */,
F3F70E9D281F4562005AA27D /* lpc_intrin_avx2.c in Sources */,
F3F70E94281F4562005AA27D /* bitmath.c in Sources */,
F3F70E9C281F4562005AA27D /* lpc_intrin_sse.c in Sources */,
F3F70EA9281F4562005AA27D /* lpc_intrin_vsx.c in Sources */,
F3F70E9F281F4562005AA27D /* fixed.c in Sources */,
F3F70EA1281F4562005AA27D /* cpu.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
F3B38D7C296F9312005DA6D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
F3B38D7D296F9312005DA6D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
F3F70E6C281F442C005AA27D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)\"",
"\"$(SRCROOT)/../../external/flac/include\"",
"\"$(SRCROOT)/../../external/flac/src/libFLAC/include\"",
);
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
F3F70E6D281F442C005AA27D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)\"",
"\"$(SRCROOT)/../../external/flac/include\"",
"\"$(SRCROOT)/../../external/flac/src/libFLAC/include\"",
);
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
F3F70E6F281F442C005AA27D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.3.4;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.FLAC;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
};
name = Debug;
};
F3F70E70281F442C005AA27D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.3.4;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.FLAC;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F3B38D7E296F9312005DA6D3 /* Build configuration list for PBXAggregateTarget "FLAC.xcframework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3B38D7C296F9312005DA6D3 /* Debug */,
F3B38D7D296F9312005DA6D3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F3F70E61281F442C005AA27D /* Build configuration list for PBXProject "FLAC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3F70E6C281F442C005AA27D /* Debug */,
F3F70E6D281F442C005AA27D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F3F70E6E281F442C005AA27D /* Build configuration list for PBXNativeTarget "FLAC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3F70E6F281F442C005AA27D /* Debug */,
F3F70E70281F442C005AA27D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F3F70E5E281F442C005AA27D /* Project object */;
}
+262
View File
@@ -0,0 +1,262 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Target processor is big endian. */
#define CPU_IS_BIG_ENDIAN 0
/* Target processor is little endian. */
#define CPU_IS_LITTLE_ENDIAN 1
/* Set FLAC__BYTES_PER_WORD to 8 (4 is the default) */
#define ENABLE_64_BIT_WORDS 0
/* libtool defines DLL_EXPORT for windows dll builds,
but flac code relies on FLAC_API_EXPORTS instead. */
#ifdef DLL_EXPORT
#ifdef __cplusplus
# define FLACPP_API_EXPORTS
#else
# define FLAC_API_EXPORTS
#endif
#endif
/* define to align allocated memory on 32-byte boundaries */
/* #undef FLAC__ALIGN_MALLOC_DATA */
/* define if building for ia32/i386 */
/* #undef FLAC__CPU_IA32 */
/* define if building for PowerPC */
/* #undef FLAC__CPU_PPC */
/* define if building for PowerPC64 */
/* #undef FLAC__CPU_PPC64 */
/* define if building for SPARC */
/* #undef FLAC__CPU_SPARC */
/* define if building for x86_64 */
/* #undef FLAC__CPU_X86_64 */
/* define if you have docbook-to-man or docbook2man */
/* #undef FLAC__HAS_DOCBOOK_TO_MAN */
/* define if you are compiling for x86 and have the NASM assembler */
/* #undef FLAC__HAS_NASM */
/* define if you have the ogg library */
#define FLAC__HAS_OGG 0
/* define if compiler has __attribute__((target("cpu=power8"))) support */
/* #undef FLAC__HAS_TARGET_POWER8 */
/* define if compiler has __attribute__((target("cpu=power9"))) support */
/* #undef FLAC__HAS_TARGET_POWER9 */
/* Set to 1 if <x86intrin.h> is available. */
#define FLAC__HAS_X86INTRIN 0
/* define to disable use of assembly code */
/* #undef FLAC__NO_ASM */
/* define if building for Darwin / MacOS X */
#define FLAC__SYS_DARWIN 1
/* define if building for Linux */
/* #undef FLAC__SYS_LINUX */
/* define to enable use of Altivec instructions */
#define FLAC__USE_ALTIVEC 1
/* define to enable use of AVX instructions */
#define FLAC__USE_AVX 1
/* define to enable use of VSX instructions */
#define FLAC__USE_VSX 1
/* Compiler has the __builtin_bswap16 intrinsic */
#define HAVE_BSWAP16 1
/* Compiler has the __builtin_bswap32 intrinsic */
#define HAVE_BSWAP32 1
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_BYTESWAP_H */
/* define if you have clock_gettime */
/* #undef HAVE_CLOCK_GETTIME */
/* Define to 1 if you have the <cpuid.h> header file. */
/* #undef HAVE_CPUID_H */
/* Define to 1 if C++ supports variable-length arrays. */
#define HAVE_CXX_VARARRAYS 1
/* Define to 1 if C supports variable-length arrays. */
#define HAVE_C_VARARRAYS 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#define HAVE_FSEEKO 1
/* Define to 1 if you have the `getopt_long' function. */
#define HAVE_GETOPT_LONG 1
/* Define if you have the iconv() function and it works. */
#define HAVE_ICONV 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#define HAVE_LANGINFO_CODESET 1
/* lround support */
#define HAVE_LROUND 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if the system has the type `socklen_t'. */
/* #undef HAVE_SOCKLEN_T */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define to 1 if typeof works with your compiler. */
#define HAVE_TYPEOF 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <x86intrin.h> header file. */
/* #undef HAVE_X86INTRIN_H */
/* Define as const if the declaration of iconv() needs const. */
#define ICONV_CONST
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Define if debugging is disabled */
#define NDEBUG /**/
/* Name of package */
#define PACKAGE "flac"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "flac-dev@xiph.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "flac"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "flac 1.3.4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "flac"
/* Define to the home page for this package. */
#define PACKAGE_URL "https://www.xiph.org/flac/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.3.4"
/* The size of `off_t', as computed by sizeof. */
#define SIZEOF_OFF_T 8
/* The size of `void*', as computed by sizeof. */
#define SIZEOF_VOIDP 8
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Version number of package */
#define VERSION "1.3.4"
/* Target processor is big endian. */
#define WORDS_BIGENDIAN 0
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
/* #undef _LARGEFILE_SOURCE */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to __typeof__ if your compiler spells it that way. */
/* #undef typeof */
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>SDL3_mixer</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>SDL3_mixer</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.2.0</string>
<key>CFBundleVersion</key>
<string>3.2.0</string>
</dict>
</plist>
@@ -0,0 +1,808 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 55;
objects = {
/* Begin PBXAggregateTarget section */
F3B38D54296F8E79005DA6D3 /* SDL3_mixer.xcframework */ = {
isa = PBXAggregateTarget;
buildConfigurationList = F3B38D57296F8E79005DA6D3 /* Build configuration list for PBXAggregateTarget "SDL3_mixer.xcframework" */;
buildPhases = (
F3B38D5A296F8E82005DA6D3 /* ShellScript */,
);
dependencies = (
);
name = SDL3_mixer.xcframework;
productName = xcFramework;
};
F3E1F78F2A78A23C00AC76D3 /* SDL3_mixer.dmg */ = {
isa = PBXAggregateTarget;
buildConfigurationList = F3E1F7902A78A23C00AC76D3 /* Build configuration list for PBXAggregateTarget "SDL3_mixer.dmg" */;
buildPhases = (
F3E1F79B2A78A27700AC76D3 /* ShellScript */,
);
dependencies = (
F3F7BE3A2CB725E900C984AF /* PBXTargetDependency */,
F3F7BE382CB725E300C984AF /* PBXTargetDependency */,
F3F7BE362CB725DF00C984AF /* PBXTargetDependency */,
F3F7BE342CB725DA00C984AF /* PBXTargetDependency */,
F3F7BE322CB725CF00C984AF /* PBXTargetDependency */,
F3F7BE302CB725CB00C984AF /* PBXTargetDependency */,
);
name = SDL3_mixer.dmg;
productName = "Create DMG";
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
BE1FA8CD07AF96B2004B6283 /* SDL_mixer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1014BAEA010A4B677F000001 /* SDL_mixer.h */; settings = {ATTRIBUTES = (Public, ); }; };
F31BA93D2F2039F500646176 /* INSTALL.md in Resources */ = {isa = PBXBuildFile; fileRef = F31BA93B2F2039F500646176 /* INSTALL.md */; };
F31BA9422F203ACA00646176 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = F31BA9402F203ACA00646176 /* LICENSE.txt */; };
F31BA9432F203ACA00646176 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = F31BA9412F203ACA00646176 /* README.md */; };
F3249B39285C448100DB9B5C /* CMake in Resources */ = {isa = PBXBuildFile; fileRef = F3249B36285C448100DB9B5C /* CMake */; };
F3412A412D4C950E00D6C2B7 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3412A402D4C950E00D6C2B7 /* SDL3.framework */; };
F382FB962E340BDE004C6137 /* decoder_drmp3.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB822E340BDE004C6137 /* decoder_drmp3.c */; };
F382FB972E340BDE004C6137 /* decoder_opus.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB872E340BDE004C6137 /* decoder_opus.c */; };
F382FB982E340BDE004C6137 /* decoder_mpg123.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB862E340BDE004C6137 /* decoder_mpg123.c */; };
F382FB992E340BDE004C6137 /* decoder_sinewave.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB892E340BDE004C6137 /* decoder_sinewave.c */; };
F382FB9A2E340BDE004C6137 /* decoder_vorbis.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB8D2E340BDE004C6137 /* decoder_vorbis.c */; };
F382FB9B2E340BDE004C6137 /* decoder_wavpack.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB8F2E340BDE004C6137 /* decoder_wavpack.c */; };
F382FB9C2E340BDE004C6137 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB912E340BDE004C6137 /* SDL_mixer.c */; };
F382FB9D2E340BDE004C6137 /* decoder_au.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB802E340BDE004C6137 /* decoder_au.c */; };
F382FB9E2E340BDE004C6137 /* decoder_raw.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB882E340BDE004C6137 /* decoder_raw.c */; };
F382FB9F2E340BDE004C6137 /* decoder_wav.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB8E2E340BDE004C6137 /* decoder_wav.c */; };
F382FBA02E340BDE004C6137 /* decoder_drflac.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB812E340BDE004C6137 /* decoder_drflac.c */; };
F382FBA12E340BDE004C6137 /* decoder_gme.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB852E340BDE004C6137 /* decoder_gme.c */; };
F382FBA22E340BDE004C6137 /* decoder_timidity.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB8B2E340BDE004C6137 /* decoder_timidity.c */; };
F382FBA32E340BDE004C6137 /* decoder_aiff.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB7F2E340BDE004C6137 /* decoder_aiff.c */; };
F382FBA42E340BDE004C6137 /* decoder_stb_vorbis.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB8A2E340BDE004C6137 /* decoder_stb_vorbis.c */; };
F382FBA52E340BDE004C6137 /* decoder_fluidsynth.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB842E340BDE004C6137 /* decoder_fluidsynth.c */; };
F382FBA62E340BDE004C6137 /* decoder_voc.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB8C2E340BDE004C6137 /* decoder_voc.c */; };
F382FBA72E340BDE004C6137 /* decoder_xmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB902E340BDE004C6137 /* decoder_xmp.c */; };
F382FBA82E340BDE004C6137 /* SDL_mixer_metadata_tags.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB942E340BDE004C6137 /* SDL_mixer_metadata_tags.c */; };
F382FBA92E340BDE004C6137 /* decoder_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB832E340BDE004C6137 /* decoder_flac.c */; };
F382FBAA2E340BDE004C6137 /* SDL_mixer_spatialization.c in Sources */ = {isa = PBXBuildFile; fileRef = F382FB952E340BDE004C6137 /* SDL_mixer_spatialization.c */; };
F382FBAB2E340BDE004C6137 /* SDL_mixer_loader.h in Headers */ = {isa = PBXBuildFile; fileRef = F382FB932E340BDE004C6137 /* SDL_mixer_loader.h */; };
F382FBAC2E340BDE004C6137 /* SDL_mixer_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F382FB922E340BDE004C6137 /* SDL_mixer_internal.h */; };
F3D87C09281DFABD005DA540 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D87C08281DFABD005DA540 /* AudioToolbox.framework */; };
F3D87C0B281DFAD4005DA540 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D87C0A281DFAD4005DA540 /* AudioUnit.framework */; platformFilters = (macos, ); };
F3D87C0D281DFADB005DA540 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D87C0C281DFADB005DA540 /* CoreServices.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
F307A2622B542F110012534B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F307A25D2B542F110012534B /* wavpack.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F3F70EDA281F61B4005AA27D;
remoteInfo = wavpack;
};
F307A2782B5431700012534B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F307A2732B5431700012534B /* gme.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F3F70EDA281F61B4005AA27D;
remoteInfo = gme;
};
F3968B96281F817E00661875 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3968B90281F817E00661875 /* opus.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F3968A21281F704800661875;
remoteInfo = opus;
};
F3B38D9E296F97BB005DA6D3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3B38D97296F97BB005DA6D3 /* ogg.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F3F70EDA281F61B4005AA27D;
remoteInfo = ogg;
};
F3E29D062882107B0006D108 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3E29D022882107B0006D108 /* xmp.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F3968D85281FBB1900661875;
remoteInfo = xmp;
};
F3F7BE2F2CB725CB00C984AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3E29D022882107B0006D108 /* xmp.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F3B38D4F296F8E1F005DA6D3;
remoteInfo = xmp.xcframework;
};
F3F7BE312CB725CF00C984AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F307A25D2B542F110012534B /* wavpack.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F3B38D49296F8DDD005DA6D3;
remoteInfo = wavpack.xcframework;
};
F3F7BE332CB725DA00C984AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3968B90281F817E00661875 /* opus.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F3B38D49296F8DDD005DA6D3;
remoteInfo = opus.xcframework;
};
F3F7BE352CB725DF00C984AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3B38D97296F97BB005DA6D3 /* ogg.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F3B38D8F296F9773005DA6D3;
remoteInfo = ogg.xcframework;
};
F3F7BE372CB725E300C984AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F307A2732B5431700012534B /* gme.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F3B38D8F296F9773005DA6D3;
remoteInfo = gme.xcframework;
};
F3F7BE392CB725E900C984AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = F3B38D54296F8E79005DA6D3;
remoteInfo = SDL3_mixer.xcframework;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
1014BAEA010A4B677F000001 /* SDL_mixer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_mixer.h; path = SDL3_mixer/SDL_mixer.h; sourceTree = "<group>"; };
BE1FA90507AF96B2004B6283 /* Info-Framework.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-Framework.plist"; sourceTree = "<group>"; };
BE1FA90607AF96B2004B6283 /* SDL3_mixer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL3_mixer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F307A25D2B542F110012534B /* wavpack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = wavpack.xcodeproj; path = wavpack/wavpack.xcodeproj; sourceTree = "<group>"; };
F307A2732B5431700012534B /* gme.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gme.xcodeproj; path = gme/gme.xcodeproj; sourceTree = "<group>"; };
F31BA93B2F2039F500646176 /* INSTALL.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = INSTALL.md; sourceTree = "<group>"; };
F31BA93F2F203AAF00646176 /* INSTALL.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = INSTALL.md; sourceTree = "<group>"; };
F31BA9402F203ACA00646176 /* LICENSE.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE.txt; path = ../../../LICENSE.txt; sourceTree = "<group>"; };
F31BA9412F203ACA00646176 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../../../README.md; sourceTree = "<group>"; };
F3249B36285C448100DB9B5C /* CMake */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CMake; sourceTree = "<group>"; };
F3412A402D4C950E00D6C2B7 /* SDL3.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL3.framework; path = macOS/SDL3.framework; sourceTree = "<group>"; };
F382FB7F2E340BDE004C6137 /* decoder_aiff.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_aiff.c; path = ../src/decoder_aiff.c; sourceTree = SOURCE_ROOT; };
F382FB802E340BDE004C6137 /* decoder_au.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_au.c; path = ../src/decoder_au.c; sourceTree = SOURCE_ROOT; };
F382FB812E340BDE004C6137 /* decoder_drflac.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_drflac.c; path = ../src/decoder_drflac.c; sourceTree = SOURCE_ROOT; };
F382FB822E340BDE004C6137 /* decoder_drmp3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_drmp3.c; path = ../src/decoder_drmp3.c; sourceTree = SOURCE_ROOT; };
F382FB832E340BDE004C6137 /* decoder_flac.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_flac.c; path = ../src/decoder_flac.c; sourceTree = SOURCE_ROOT; };
F382FB842E340BDE004C6137 /* decoder_fluidsynth.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_fluidsynth.c; path = ../src/decoder_fluidsynth.c; sourceTree = SOURCE_ROOT; };
F382FB852E340BDE004C6137 /* decoder_gme.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_gme.c; path = ../src/decoder_gme.c; sourceTree = SOURCE_ROOT; };
F382FB862E340BDE004C6137 /* decoder_mpg123.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_mpg123.c; path = ../src/decoder_mpg123.c; sourceTree = SOURCE_ROOT; };
F382FB872E340BDE004C6137 /* decoder_opus.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_opus.c; path = ../src/decoder_opus.c; sourceTree = SOURCE_ROOT; };
F382FB882E340BDE004C6137 /* decoder_raw.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_raw.c; path = ../src/decoder_raw.c; sourceTree = SOURCE_ROOT; };
F382FB892E340BDE004C6137 /* decoder_sinewave.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_sinewave.c; path = ../src/decoder_sinewave.c; sourceTree = SOURCE_ROOT; };
F382FB8A2E340BDE004C6137 /* decoder_stb_vorbis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_stb_vorbis.c; path = ../src/decoder_stb_vorbis.c; sourceTree = SOURCE_ROOT; };
F382FB8B2E340BDE004C6137 /* decoder_timidity.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_timidity.c; path = ../src/decoder_timidity.c; sourceTree = SOURCE_ROOT; };
F382FB8C2E340BDE004C6137 /* decoder_voc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_voc.c; path = ../src/decoder_voc.c; sourceTree = SOURCE_ROOT; };
F382FB8D2E340BDE004C6137 /* decoder_vorbis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_vorbis.c; path = ../src/decoder_vorbis.c; sourceTree = SOURCE_ROOT; };
F382FB8E2E340BDE004C6137 /* decoder_wav.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_wav.c; path = ../src/decoder_wav.c; sourceTree = SOURCE_ROOT; };
F382FB8F2E340BDE004C6137 /* decoder_wavpack.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_wavpack.c; path = ../src/decoder_wavpack.c; sourceTree = SOURCE_ROOT; };
F382FB902E340BDE004C6137 /* decoder_xmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = decoder_xmp.c; path = ../src/decoder_xmp.c; sourceTree = SOURCE_ROOT; };
F382FB912E340BDE004C6137 /* SDL_mixer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SDL_mixer.c; path = ../src/SDL_mixer.c; sourceTree = SOURCE_ROOT; };
F382FB922E340BDE004C6137 /* SDL_mixer_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDL_mixer_internal.h; path = ../src/SDL_mixer_internal.h; sourceTree = SOURCE_ROOT; };
F382FB932E340BDE004C6137 /* SDL_mixer_loader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDL_mixer_loader.h; path = ../src/SDL_mixer_loader.h; sourceTree = SOURCE_ROOT; };
F382FB942E340BDE004C6137 /* SDL_mixer_metadata_tags.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SDL_mixer_metadata_tags.c; path = ../src/SDL_mixer_metadata_tags.c; sourceTree = SOURCE_ROOT; };
F382FB952E340BDE004C6137 /* SDL_mixer_spatialization.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SDL_mixer_spatialization.c; path = ../src/SDL_mixer_spatialization.c; sourceTree = SOURCE_ROOT; };
F3968B90281F817E00661875 /* opus.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = opus.xcodeproj; path = opus/opus.xcodeproj; sourceTree = "<group>"; };
F3968D71281FB5E100661875 /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = "<group>"; };
F3B38D97296F97BB005DA6D3 /* ogg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ogg.xcodeproj; path = ogg/ogg.xcodeproj; sourceTree = "<group>"; };
F3D87C08281DFABD005DA540 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
F3D87C0A281DFAD4005DA540 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
F3D87C0C281DFADB005DA540 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
F3E29D022882107B0006D108 /* xmp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = xmp.xcodeproj; path = xmp/xmp.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
BE1FA90107AF96B2004B6283 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F3412A412D4C950E00D6C2B7 /* SDL3.framework in Frameworks */,
F3D87C09281DFABD005DA540 /* AudioToolbox.framework in Frameworks */,
F3D87C0B281DFAD4005DA540 /* AudioUnit.framework in Frameworks */,
F3D87C0D281DFADB005DA540 /* CoreServices.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0153844A006D81B07F000001 /* Public Headers */ = {
isa = PBXGroup;
children = (
1014BAEA010A4B677F000001 /* SDL_mixer.h */,
);
name = "Public Headers";
path = ../include;
sourceTree = "<group>";
};
034768DDFF38A45A11DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
089C1665FE841158C02AAC07 /* Resources */,
BE1FA90607AF96B2004B6283 /* SDL3_mixer.framework */,
);
name = Products;
sourceTree = "<group>";
};
0867D691FE84028FC02AAC07 /* SDL_mixerFramework */ = {
isa = PBXGroup;
children = (
F3968D71281FB5E100661875 /* config.xcconfig */,
F307A2732B5431700012534B /* gme.xcodeproj */,
F3B38D97296F97BB005DA6D3 /* ogg.xcodeproj */,
F3968B90281F817E00661875 /* opus.xcodeproj */,
F307A25D2B542F110012534B /* wavpack.xcodeproj */,
F3E29D022882107B0006D108 /* xmp.xcodeproj */,
F59C70FC00D5CB5801000001 /* pkg-support */,
0153844A006D81B07F000001 /* Public Headers */,
08FB77ACFE841707C02AAC07 /* Library Source */,
BE1FA8AC07AF95D4004B6283 /* Frameworks */,
034768DDFF38A45A11DB9C8B /* Products */,
BE1FA90507AF96B2004B6283 /* Info-Framework.plist */,
);
name = SDL_mixerFramework;
sourceTree = "<group>";
};
089C1665FE841158C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
);
name = Resources;
sourceTree = "<group>";
};
08FB77ACFE841707C02AAC07 /* Library Source */ = {
isa = PBXGroup;
children = (
F382FB7F2E340BDE004C6137 /* decoder_aiff.c */,
F382FB802E340BDE004C6137 /* decoder_au.c */,
F382FB812E340BDE004C6137 /* decoder_drflac.c */,
F382FB822E340BDE004C6137 /* decoder_drmp3.c */,
F382FB832E340BDE004C6137 /* decoder_flac.c */,
F382FB842E340BDE004C6137 /* decoder_fluidsynth.c */,
F382FB852E340BDE004C6137 /* decoder_gme.c */,
F382FB862E340BDE004C6137 /* decoder_mpg123.c */,
F382FB872E340BDE004C6137 /* decoder_opus.c */,
F382FB882E340BDE004C6137 /* decoder_raw.c */,
F382FB892E340BDE004C6137 /* decoder_sinewave.c */,
F382FB8A2E340BDE004C6137 /* decoder_stb_vorbis.c */,
F382FB8B2E340BDE004C6137 /* decoder_timidity.c */,
F382FB8C2E340BDE004C6137 /* decoder_voc.c */,
F382FB8D2E340BDE004C6137 /* decoder_vorbis.c */,
F382FB8E2E340BDE004C6137 /* decoder_wav.c */,
F382FB8F2E340BDE004C6137 /* decoder_wavpack.c */,
F382FB902E340BDE004C6137 /* decoder_xmp.c */,
F382FB912E340BDE004C6137 /* SDL_mixer.c */,
F382FB922E340BDE004C6137 /* SDL_mixer_internal.h */,
F382FB932E340BDE004C6137 /* SDL_mixer_loader.h */,
F382FB942E340BDE004C6137 /* SDL_mixer_metadata_tags.c */,
F382FB952E340BDE004C6137 /* SDL_mixer_spatialization.c */,
);
name = "Library Source";
sourceTree = "<group>";
};
BE1FA8AC07AF95D4004B6283 /* Frameworks */ = {
isa = PBXGroup;
children = (
F3412A402D4C950E00D6C2B7 /* SDL3.framework */,
F3D87C0C281DFADB005DA540 /* CoreServices.framework */,
F3D87C0A281DFAD4005DA540 /* AudioUnit.framework */,
F3D87C08281DFABD005DA540 /* AudioToolbox.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
F307A25E2B542F110012534B /* Products */ = {
isa = PBXGroup;
children = (
F307A2632B542F110012534B /* wavpack.framework */,
);
name = Products;
sourceTree = "<group>";
};
F307A2742B5431700012534B /* Products */ = {
isa = PBXGroup;
children = (
F307A2792B5431700012534B /* gme.framework */,
);
name = Products;
sourceTree = "<group>";
};
F31BA93C2F2039F500646176 /* framework */ = {
isa = PBXGroup;
children = (
F31BA93B2F2039F500646176 /* INSTALL.md */,
);
path = framework;
sourceTree = "<group>";
};
F3968B91281F817E00661875 /* Products */ = {
isa = PBXGroup;
children = (
F3968B97281F817E00661875 /* opus.framework */,
);
name = Products;
sourceTree = "<group>";
};
F3B38D98296F97BB005DA6D3 /* Products */ = {
isa = PBXGroup;
children = (
F3B38D9F296F97BB005DA6D3 /* ogg.framework */,
);
name = Products;
sourceTree = "<group>";
};
F3E29D032882107B0006D108 /* Products */ = {
isa = PBXGroup;
children = (
F3E29D072882107B0006D108 /* xmp.framework */,
);
name = Products;
sourceTree = "<group>";
};
F59C70FC00D5CB5801000001 /* pkg-support */ = {
isa = PBXGroup;
children = (
F59C710100D5CB5801000001 /* resources */,
);
path = "pkg-support";
sourceTree = SOURCE_ROOT;
};
F59C710100D5CB5801000001 /* resources */ = {
isa = PBXGroup;
children = (
F31BA93C2F2039F500646176 /* framework */,
F3249B36285C448100DB9B5C /* CMake */,
F31BA9402F203ACA00646176 /* LICENSE.txt */,
F31BA9412F203ACA00646176 /* README.md */,
F31BA93F2F203AAF00646176 /* INSTALL.md */,
);
path = resources;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
BE1FA8B507AF96B2004B6283 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
F382FBAB2E340BDE004C6137 /* SDL_mixer_loader.h in Headers */,
F382FBAC2E340BDE004C6137 /* SDL_mixer_internal.h in Headers */,
BE1FA8CD07AF96B2004B6283 /* SDL_mixer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
BE1FA8B407AF96B2004B6283 /* SDL3_mixer */ = {
isa = PBXNativeTarget;
buildConfigurationList = 00B7E48B097EC6B300826121 /* Build configuration list for PBXNativeTarget "SDL3_mixer" */;
buildPhases = (
BE1FA8B507AF96B2004B6283 /* Headers */,
BE1FA8CF07AF96B2004B6283 /* Resources */,
BE1FA8D007AF96B2004B6283 /* Sources */,
BE1FA90107AF96B2004B6283 /* Frameworks */,
BE1FA90307AF96B2004B6283 /* Rez */,
);
buildRules = (
);
comments = "Installed into ~/Library/Frameworks/SDL_mixer.framework\n\nAdd -framework SDL_mixer to your linker flags\nAdd ~/Library/Frameworks/SDL_mixer.framework/Headers to your header search path\nAdd ~/Library/Frameworks to your library search path";
dependencies = (
);
name = SDL3_mixer;
productInstallPath = "@executable_path/../Frameworks";
productName = SDL_mixer;
productReference = BE1FA90607AF96B2004B6283 /* SDL3_mixer.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
TargetAttributes = {
F3B38D54296F8E79005DA6D3 = {
CreatedOnToolsVersion = 14.2;
};
F3E1F78F2A78A23C00AC76D3 = {
CreatedOnToolsVersion = 14.3.1;
};
};
};
buildConfigurationList = 00B7E497097EC6B300826121 /* Build configuration list for PBXProject "SDL_mixer" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
en,
);
mainGroup = 0867D691FE84028FC02AAC07 /* SDL_mixerFramework */;
productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = F307A2742B5431700012534B /* Products */;
ProjectRef = F307A2732B5431700012534B /* gme.xcodeproj */;
},
{
ProductGroup = F3B38D98296F97BB005DA6D3 /* Products */;
ProjectRef = F3B38D97296F97BB005DA6D3 /* ogg.xcodeproj */;
},
{
ProductGroup = F3968B91281F817E00661875 /* Products */;
ProjectRef = F3968B90281F817E00661875 /* opus.xcodeproj */;
},
{
ProductGroup = F307A25E2B542F110012534B /* Products */;
ProjectRef = F307A25D2B542F110012534B /* wavpack.xcodeproj */;
},
{
ProductGroup = F3E29D032882107B0006D108 /* Products */;
ProjectRef = F3E29D022882107B0006D108 /* xmp.xcodeproj */;
},
);
projectRoot = "";
targets = (
BE1FA8B407AF96B2004B6283 /* SDL3_mixer */,
F3B38D54296F8E79005DA6D3 /* SDL3_mixer.xcframework */,
F3E1F78F2A78A23C00AC76D3 /* SDL3_mixer.dmg */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
F307A2632B542F110012534B /* wavpack.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = wavpack.framework;
remoteRef = F307A2622B542F110012534B /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
F307A2792B5431700012534B /* gme.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = gme.framework;
remoteRef = F307A2782B5431700012534B /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
F3968B97281F817E00661875 /* opus.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = opus.framework;
remoteRef = F3968B96281F817E00661875 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
F3B38D9F296F97BB005DA6D3 /* ogg.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = ogg.framework;
remoteRef = F3B38D9E296F97BB005DA6D3 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
F3E29D072882107B0006D108 /* xmp.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = xmp.framework;
remoteRef = F3E29D062882107B0006D108 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
BE1FA8CF07AF96B2004B6283 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F31BA93D2F2039F500646176 /* INSTALL.md in Resources */,
F31BA9422F203ACA00646176 /* LICENSE.txt in Resources */,
F31BA9432F203ACA00646176 /* README.md in Resources */,
F3249B39285C448100DB9B5C /* CMake in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXRezBuildPhase section */
BE1FA90307AF96B2004B6283 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXRezBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
F3B38D5A296F8E82005DA6D3 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"SDL3_mixer\"\nPROJECT_NAME=\"SDL_mixer\"\nSCHEME=\"SDL3_mixer\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"./build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -destination 'generic/platform=macOS,name=Any Mac' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
};
F3E1F79B2A78A27700AC76D3 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -ex\n\nPRODUCT_NAME=SDL3_mixer\nOPTIONAL_FRAMEWORKS=\"gme ogg opus wavpack xmp\"\n\nmkdir -p build/dmg-tmp/share/cmake/$PRODUCT_NAME\ncp -a build/$PRODUCT_NAME.xcframework build/dmg-tmp/\n\ncp ../LICENSE.txt build/dmg-tmp\ncp ../README.md build/dmg-tmp\ncp pkg-support/resources/INSTALL.md build/dmg-tmp\ncp pkg-support/resources/share/cmake/${PRODUCT_NAME}/${PRODUCT_NAME}Config.cmake build/dmg-tmp/share/cmake/${PRODUCT_NAME}\ncp pkg-support/resources/share/cmake/${PRODUCT_NAME}/${PRODUCT_NAME}ConfigVersion.cmake build/dmg-tmp/share/cmake/${PRODUCT_NAME}\nfor i in $OPTIONAL_FRAMEWORKS; do\n if [ -d build/$i.xcframework ]; then\n mkdir -p build/dmg-tmp/optional\n cp -a build/$i.xcframework build/dmg-tmp/optional/\n fi\ndone\n\n# remove the .DS_Store files if any (we may want to provide one in the future for fancy .dmgs)\nrm -rf build/dmg-tmp/.DS_Store\n\n# for fancy .dmg\nmkdir -p build/dmg-tmp/.logo\ncp pkg-support/resources/SDL_DS_Store build/dmg-tmp/.DS_Store\ncp pkg-support/sdl_logo.pdf build/dmg-tmp/.logo\n\n# create the dmg\nhdiutil create -ov -fs HFS+ -volname $PRODUCT_NAME -srcfolder build/dmg-tmp build/$PRODUCT_NAME.dmg\n\n# clean up\nrm -rf build/dmg-tmp\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
BE1FA8D007AF96B2004B6283 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F382FB962E340BDE004C6137 /* decoder_drmp3.c in Sources */,
F382FB972E340BDE004C6137 /* decoder_opus.c in Sources */,
F382FB982E340BDE004C6137 /* decoder_mpg123.c in Sources */,
F382FB992E340BDE004C6137 /* decoder_sinewave.c in Sources */,
F382FB9A2E340BDE004C6137 /* decoder_vorbis.c in Sources */,
F382FB9B2E340BDE004C6137 /* decoder_wavpack.c in Sources */,
F382FB9C2E340BDE004C6137 /* SDL_mixer.c in Sources */,
F382FB9D2E340BDE004C6137 /* decoder_au.c in Sources */,
F382FB9E2E340BDE004C6137 /* decoder_raw.c in Sources */,
F382FB9F2E340BDE004C6137 /* decoder_wav.c in Sources */,
F382FBA02E340BDE004C6137 /* decoder_drflac.c in Sources */,
F382FBA12E340BDE004C6137 /* decoder_gme.c in Sources */,
F382FBA22E340BDE004C6137 /* decoder_timidity.c in Sources */,
F382FBA32E340BDE004C6137 /* decoder_aiff.c in Sources */,
F382FBA42E340BDE004C6137 /* decoder_stb_vorbis.c in Sources */,
F382FBA52E340BDE004C6137 /* decoder_fluidsynth.c in Sources */,
F382FBA62E340BDE004C6137 /* decoder_voc.c in Sources */,
F382FBA72E340BDE004C6137 /* decoder_xmp.c in Sources */,
F382FBA82E340BDE004C6137 /* SDL_mixer_metadata_tags.c in Sources */,
F382FBA92E340BDE004C6137 /* decoder_flac.c in Sources */,
F382FBAA2E340BDE004C6137 /* SDL_mixer_spatialization.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
F3F7BE302CB725CB00C984AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = xmp.xcframework;
targetProxy = F3F7BE2F2CB725CB00C984AF /* PBXContainerItemProxy */;
};
F3F7BE322CB725CF00C984AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = wavpack.xcframework;
targetProxy = F3F7BE312CB725CF00C984AF /* PBXContainerItemProxy */;
};
F3F7BE342CB725DA00C984AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = opus.xcframework;
targetProxy = F3F7BE332CB725DA00C984AF /* PBXContainerItemProxy */;
};
F3F7BE362CB725DF00C984AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = ogg.xcframework;
targetProxy = F3F7BE352CB725DF00C984AF /* PBXContainerItemProxy */;
};
F3F7BE382CB725E300C984AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = gme.xcframework;
targetProxy = F3F7BE372CB725E300C984AF /* PBXContainerItemProxy */;
};
F3F7BE3A2CB725E900C984AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F3B38D54296F8E79005DA6D3 /* SDL3_mixer.xcframework */;
targetProxy = F3F7BE392CB725E900C984AF /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
00B7E48C097EC6B300826121 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
00B7E48D097EC6B300826121 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/../src/SDL_mixer.exports";
};
name = Debug;
};
00B7E498097EC6B300826121 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F3968D71281FB5E100661875 /* config.xcconfig */;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DEPLOYMENT_POSTPROCESSING = YES;
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
"FRAMEWORK_SEARCH_PATHS[sdk=appletv*]" = "\"$(PROJECT_DIR)/iOS\"";
"FRAMEWORK_SEARCH_PATHS[sdk=iphone*]" = "\"$(PROJECT_DIR)/iOS\"";
"FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = "\"$(PROJECT_DIR)/macOS\"";
"FRAMEWORK_SEARCH_PATHS[sdk=xr*]" = "\"$(PROJECT_DIR)/iOS\"";
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
DECODER_FLAC_DRFLAC,
DECODER_MP3_DRMP3,
DECODER_OGGVORBIS_STB,
DECODER_WAV,
"$(CONFIG_PREPROCESSOR_DEFINITIONS)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../include\"";
INFOPLIST_FILE = "Info-Framework.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = (
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.1.3;
PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.SDL3-mixer";
PRODUCT_NAME = SDL3_mixer;
SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 11.0;
XROS_DEPLOYMENT_TARGET = 1.3;
};
name = Release;
};
00B7E499097EC6B300826121 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F3968D71281FB5E100661875 /* config.xcconfig */;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_TESTABILITY = YES;
"FRAMEWORK_SEARCH_PATHS[sdk=appletv*]" = "\"$(PROJECT_DIR)/iOS\"";
"FRAMEWORK_SEARCH_PATHS[sdk=iphone*]" = "\"$(PROJECT_DIR)/iOS\"";
"FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = "\"$(PROJECT_DIR)/macOS\"";
"FRAMEWORK_SEARCH_PATHS[sdk=xr*]" = "\"$(PROJECT_DIR)/iOS\"";
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
DECODER_FLAC_DRFLAC,
DECODER_MP3_DRMP3,
DECODER_OGGVORBIS_STB,
DECODER_WAV,
"$(CONFIG_PREPROCESSOR_DEFINITIONS)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../include\"";
INFOPLIST_FILE = "Info-Framework.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = (
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.1.3;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.SDL3-mixer";
PRODUCT_NAME = SDL3_mixer;
SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 11.0;
XROS_DEPLOYMENT_TARGET = 1.3;
};
name = Debug;
};
F3B38D58296F8E79005DA6D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/../src/SDL_mixer.exports";
};
name = Release;
};
F3B38D59296F8E79005DA6D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
F3E1F7912A78A23C00AC76D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
F3E1F7922A78A23C00AC76D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
00B7E48B097EC6B300826121 /* Build configuration list for PBXNativeTarget "SDL3_mixer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00B7E48C097EC6B300826121 /* Release */,
00B7E48D097EC6B300826121 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
00B7E497097EC6B300826121 /* Build configuration list for PBXProject "SDL_mixer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00B7E498097EC6B300826121 /* Release */,
00B7E499097EC6B300826121 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F3B38D57296F8E79005DA6D3 /* Build configuration list for PBXAggregateTarget "SDL3_mixer.xcframework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3B38D58296F8E79005DA6D3 /* Release */,
F3B38D59296F8E79005DA6D3 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F3E1F7902A78A23C00AC76D3 /* Build configuration list for PBXAggregateTarget "SDL3_mixer.dmg" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3E1F7912A78A23C00AC76D3 /* Release */,
F3E1F7922A78A23C00AC76D3 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
}
+32
View File
@@ -0,0 +1,32 @@
//
// config.xcconfig
//
// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974
// Include any optional config for this build
#include? "build.xcconfig"
// Uncomment these lines to enable Game_Music_Emu support
// If you do this, you should run external/download.sh to download the decode libraries and add gme.framework to your application bundle.
//GME_PREPROCESSOR_DEFINITIONS = MUSIC_GME
//GME_FRAMEWORK_LDFLAGS = -weak_framework gme
// Uncomment these lines to enable MOD support
// If you do this, you should run external/download.sh to download the decode libraries and add xmp.framework to your application bundle.
//MOD_PREPROCESSOR_DEFINITIONS = MUSIC_MOD_XMP LIBXMP_HEADER=\"../external/libxmp/include/xmp.h\"
//MOD_FRAMEWORK_LDFLAGS = -weak_framework xmp
// Uncomment these lines to enable Opus support
// If you do this, you should run external/download.sh to download the decode libraries and add opus.framework to your application bundle.
//OPUS_PREPROCESSOR_DEFINITIONS = MUSIC_OPUS
//OPUS_FRAMEWORK_LDFLAGS = -weak_framework opus
// Uncomment these lines to enable WavPack support
// If you do this, you should run external/download.sh to download the decode libraries and add wavpack.framework to your application bundle.
//WAVPACK_PREPROCESSOR_DEFINITIONS = MUSIC_WAVPACK MUSIC_WAVPACK_DSD
//WAVPACK_FRAMEWORK_LDFLAGS = -weak_framework wavpack
CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited) $(GME_PREPROCESSOR_DEFINITIONS) $(MOD_PREPROCESSOR_DEFINITIONS) $(OPUS_PREPROCESSOR_DEFINITIONS) $(WAVPACK_PREPROCESSOR_DEFINITIONS)
CONFIG_FRAMEWORK_LDFLAGS = $(inherited) $(GME_FRAMEWORK_LDFLAGS) $(MOD_FRAMEWORK_LDFLAGS) $(OPUS_FRAMEWORK_LDFLAGS) $(WAVPACK_FRAMEWORK_LDFLAGS)
@@ -0,0 +1,644 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 55;
objects = {
/* Begin PBXAggregateTarget section */
F3B38D8F296F9773005DA6D3 /* gme.xcframework */ = {
isa = PBXAggregateTarget;
buildConfigurationList = F3B38D92296F9773005DA6D3 /* Build configuration list for PBXAggregateTarget "gme.xcframework" */;
buildPhases = (
F3B38D93296F9779005DA6D3 /* ShellScript */,
);
dependencies = (
);
name = gme.xcframework;
productName = xcFramework;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
F307A27D2B5431C70012534B /* license.txt in Resources */ = {isa = PBXBuildFile; fileRef = F307A27A2B5431C70012534B /* license.txt */; };
F307A27E2B5431C70012534B /* gme.txt in Resources */ = {isa = PBXBuildFile; fileRef = F307A27B2B5431C70012534B /* gme.txt */; };
F307A27F2B5431C70012534B /* readme.txt in Resources */ = {isa = PBXBuildFile; fileRef = F307A27C2B5431C70012534B /* readme.txt */; };
F307A2AF2B54329C0012534B /* Ym2612_GENS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2802B54329C0012534B /* Ym2612_GENS.cpp */; };
F307A2B02B54329C0012534B /* Nes_Vrc6_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2812B54329C0012534B /* Nes_Vrc6_Apu.cpp */; };
F307A2B12B54329C0012534B /* Sap_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2822B54329C0012534B /* Sap_Cpu.cpp */; };
F307A2B22B54329C0012534B /* Dual_Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2832B54329C0012534B /* Dual_Resampler.cpp */; };
F307A2B32B54329C0012534B /* Ym2612_MAME.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2842B54329C0012534B /* Ym2612_MAME.cpp */; };
F307A2B42B54329C0012534B /* Nes_Namco_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2852B54329C0012534B /* Nes_Namco_Apu.cpp */; };
F307A2B52B54329C0012534B /* M3u_Playlist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2862B54329C0012534B /* M3u_Playlist.cpp */; };
F307A2B62B54329C0012534B /* Vgm_Emu_Impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2872B54329C0012534B /* Vgm_Emu_Impl.cpp */; };
F307A2B72B54329C0012534B /* Hes_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2882B54329C0012534B /* Hes_Emu.cpp */; };
F307A2B82B54329C0012534B /* Snes_Spc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2892B54329C0012534B /* Snes_Spc.cpp */; };
F307A2B92B54329C0012534B /* Kss_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28A2B54329C0012534B /* Kss_Cpu.cpp */; };
F307A2BA2B54329C0012534B /* Nes_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28B2B54329C0012534B /* Nes_Cpu.cpp */; };
F307A2BB2B54329C0012534B /* Effects_Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28C2B54329C0012534B /* Effects_Buffer.cpp */; };
F307A2BC2B54329C0012534B /* Fir_Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28D2B54329C0012534B /* Fir_Resampler.cpp */; };
F307A2BD2B54329C0012534B /* Music_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28E2B54329C0012534B /* Music_Emu.cpp */; };
F307A2BE2B54329C0012534B /* Blip_Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28F2B54329C0012534B /* Blip_Buffer.cpp */; };
F307A2BF2B54329C0012534B /* Sap_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2902B54329C0012534B /* Sap_Apu.cpp */; };
F307A2C02B54329C0012534B /* Sap_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2912B54329C0012534B /* Sap_Emu.cpp */; };
F307A2C12B54329C0012534B /* Classic_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2922B54329C0012534B /* Classic_Emu.cpp */; };
F307A2C22B54329C0012534B /* Gbs_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2932B54329C0012534B /* Gbs_Emu.cpp */; };
F307A2C32B54329C0012534B /* Nes_Fme7_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2942B54329C0012534B /* Nes_Fme7_Apu.cpp */; };
F307A2C42B54329C0012534B /* Sms_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2952B54329C0012534B /* Sms_Apu.cpp */; };
F307A2C52B54329C0012534B /* Ym2413_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2962B54329C0012534B /* Ym2413_Emu.cpp */; };
F307A2C62B54329C0012534B /* Ym2612_Nuked.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2972B54329C0012534B /* Ym2612_Nuked.cpp */; };
F307A2C72B54329C0012534B /* Gme_File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2982B54329C0012534B /* Gme_File.cpp */; };
F307A2C82B54329C0012534B /* Nsfe_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2992B54329C0012534B /* Nsfe_Emu.cpp */; };
F307A2C92B54329C0012534B /* Kss_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29A2B54329C0012534B /* Kss_Emu.cpp */; };
F307A2CA2B54329C0012534B /* Spc_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29B2B54329C0012534B /* Spc_Cpu.cpp */; };
F307A2CB2B54329C0012534B /* Hes_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29C2B54329C0012534B /* Hes_Cpu.cpp */; };
F307A2CC2B54329C0012534B /* Gb_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29D2B54329C0012534B /* Gb_Cpu.cpp */; };
F307A2CD2B54329C0012534B /* Nes_Oscs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29E2B54329C0012534B /* Nes_Oscs.cpp */; };
F307A2CE2B54329C0012534B /* Nsf_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29F2B54329C0012534B /* Nsf_Emu.cpp */; };
F307A2CF2B54329C0012534B /* Hes_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A02B54329C0012534B /* Hes_Apu.cpp */; };
F307A2D02B54329C0012534B /* Gb_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A12B54329C0012534B /* Gb_Apu.cpp */; };
F307A2D12B54329C0012534B /* Multi_Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A22B54329C0012534B /* Multi_Buffer.cpp */; };
F307A2D22B54329C0012534B /* Spc_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A32B54329C0012534B /* Spc_Emu.cpp */; };
F307A2D32B54329C0012534B /* Ay_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A42B54329C0012534B /* Ay_Cpu.cpp */; };
F307A2D42B54329C0012534B /* Ay_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A52B54329C0012534B /* Ay_Emu.cpp */; };
F307A2D52B54329C0012534B /* Kss_Scc_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A62B54329C0012534B /* Kss_Scc_Apu.cpp */; };
F307A2D62B54329C0012534B /* Ay_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A72B54329C0012534B /* Ay_Apu.cpp */; };
F307A2D72B54329C0012534B /* Gym_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A82B54329C0012534B /* Gym_Emu.cpp */; };
F307A2D82B54329C0012534B /* Data_Reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A92B54329C0012534B /* Data_Reader.cpp */; };
F307A2D92B54329C0012534B /* Nes_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AA2B54329C0012534B /* Nes_Apu.cpp */; };
F307A2DA2B54329C0012534B /* Gb_Oscs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AB2B54329C0012534B /* Gb_Oscs.cpp */; };
F307A2DB2B54329C0012534B /* Spc_Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AC2B54329C0012534B /* Spc_Filter.cpp */; };
F307A2DC2B54329C0012534B /* Spc_Dsp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AD2B54329C0012534B /* Spc_Dsp.cpp */; };
F307A2DD2B54329C0012534B /* gme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AE2B54329C0012534B /* gme.cpp */; };
F307A2DF2B5434FF0012534B /* Vgm_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2DE2B5434FF0012534B /* Vgm_Emu.cpp */; };
6314974C2D8D4A3600EEC879 /* Nes_Fds_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6314974B2D8D4A3600EEC879 /* Nes_Fds_Apu.cpp */; };
6314974E2D8D4A9200EEC879 /* Nes_Vrc7_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6314974D2D8D4A9200EEC879 /* Nes_Vrc7_Apu.cpp */; };
631497502D8D4AEA00EEC879 /* emu2413.c in Sources */ = {isa = PBXBuildFile; fileRef = 6314974F2D8D4AEA00EEC879 /* emu2413.c */; };
631497522D8D4B0500EEC879 /* panning.c in Sources */ = {isa = PBXBuildFile; fileRef = 631497512D8D4B0500EEC879 /* panning.c */; };
F307A2E12B54358D0012534B /* gme.h in Headers */ = {isa = PBXBuildFile; fileRef = F307A2E02B54358D0012534B /* gme.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F307A27A2B5431C70012534B /* license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = license.txt; path = ../../external/libgme/license.txt; sourceTree = "<group>"; };
F307A27B2B5431C70012534B /* gme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = gme.txt; path = ../../external/libgme/gme.txt; sourceTree = "<group>"; };
F307A27C2B5431C70012534B /* readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = readme.txt; path = ../../external/libgme/readme.txt; sourceTree = "<group>"; };
F307A2802B54329C0012534B /* Ym2612_GENS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2612_GENS.cpp; path = ../../external/libgme/gme/Ym2612_GENS.cpp; sourceTree = "<group>"; };
F307A2812B54329C0012534B /* Nes_Vrc6_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Vrc6_Apu.cpp; path = ../../external/libgme/gme/Nes_Vrc6_Apu.cpp; sourceTree = "<group>"; };
F307A2822B54329C0012534B /* Sap_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sap_Cpu.cpp; path = ../../external/libgme/gme/Sap_Cpu.cpp; sourceTree = "<group>"; };
F307A2832B54329C0012534B /* Dual_Resampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Dual_Resampler.cpp; path = ../../external/libgme/gme/Dual_Resampler.cpp; sourceTree = "<group>"; };
F307A2842B54329C0012534B /* Ym2612_MAME.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2612_MAME.cpp; path = ../../external/libgme/gme/Ym2612_MAME.cpp; sourceTree = "<group>"; };
F307A2852B54329C0012534B /* Nes_Namco_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Namco_Apu.cpp; path = ../../external/libgme/gme/Nes_Namco_Apu.cpp; sourceTree = "<group>"; };
F307A2862B54329C0012534B /* M3u_Playlist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = M3u_Playlist.cpp; path = ../../external/libgme/gme/M3u_Playlist.cpp; sourceTree = "<group>"; };
F307A2872B54329C0012534B /* Vgm_Emu_Impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vgm_Emu_Impl.cpp; path = ../../external/libgme/gme/Vgm_Emu_Impl.cpp; sourceTree = "<group>"; };
F307A2882B54329C0012534B /* Hes_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Hes_Emu.cpp; path = ../../external/libgme/gme/Hes_Emu.cpp; sourceTree = "<group>"; };
F307A2892B54329C0012534B /* Snes_Spc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Snes_Spc.cpp; path = ../../external/libgme/gme/Snes_Spc.cpp; sourceTree = "<group>"; };
F307A28A2B54329C0012534B /* Kss_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Kss_Cpu.cpp; path = ../../external/libgme/gme/Kss_Cpu.cpp; sourceTree = "<group>"; };
F307A28B2B54329C0012534B /* Nes_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Cpu.cpp; path = ../../external/libgme/gme/Nes_Cpu.cpp; sourceTree = "<group>"; };
F307A28C2B54329C0012534B /* Effects_Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Effects_Buffer.cpp; path = ../../external/libgme/gme/Effects_Buffer.cpp; sourceTree = "<group>"; };
F307A28D2B54329C0012534B /* Fir_Resampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fir_Resampler.cpp; path = ../../external/libgme/gme/Fir_Resampler.cpp; sourceTree = "<group>"; };
F307A28E2B54329C0012534B /* Music_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Music_Emu.cpp; path = ../../external/libgme/gme/Music_Emu.cpp; sourceTree = "<group>"; };
F307A28F2B54329C0012534B /* Blip_Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Blip_Buffer.cpp; path = ../../external/libgme/gme/Blip_Buffer.cpp; sourceTree = "<group>"; };
F307A2902B54329C0012534B /* Sap_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sap_Apu.cpp; path = ../../external/libgme/gme/Sap_Apu.cpp; sourceTree = "<group>"; };
F307A2912B54329C0012534B /* Sap_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sap_Emu.cpp; path = ../../external/libgme/gme/Sap_Emu.cpp; sourceTree = "<group>"; };
F307A2922B54329C0012534B /* Classic_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Classic_Emu.cpp; path = ../../external/libgme/gme/Classic_Emu.cpp; sourceTree = "<group>"; };
F307A2932B54329C0012534B /* Gbs_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gbs_Emu.cpp; path = ../../external/libgme/gme/Gbs_Emu.cpp; sourceTree = "<group>"; };
F307A2942B54329C0012534B /* Nes_Fme7_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Fme7_Apu.cpp; path = ../../external/libgme/gme/Nes_Fme7_Apu.cpp; sourceTree = "<group>"; };
F307A2952B54329C0012534B /* Sms_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sms_Apu.cpp; path = ../../external/libgme/gme/Sms_Apu.cpp; sourceTree = "<group>"; };
F307A2962B54329C0012534B /* Ym2413_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2413_Emu.cpp; path = ../../external/libgme/gme/Ym2413_Emu.cpp; sourceTree = "<group>"; };
F307A2972B54329C0012534B /* Ym2612_Nuked.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2612_Nuked.cpp; path = ../../external/libgme/gme/Ym2612_Nuked.cpp; sourceTree = "<group>"; };
F307A2982B54329C0012534B /* Gme_File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gme_File.cpp; path = ../../external/libgme/gme/Gme_File.cpp; sourceTree = "<group>"; };
F307A2992B54329C0012534B /* Nsfe_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nsfe_Emu.cpp; path = ../../external/libgme/gme/Nsfe_Emu.cpp; sourceTree = "<group>"; };
F307A29A2B54329C0012534B /* Kss_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Kss_Emu.cpp; path = ../../external/libgme/gme/Kss_Emu.cpp; sourceTree = "<group>"; };
F307A29B2B54329C0012534B /* Spc_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Cpu.cpp; path = ../../external/libgme/gme/Spc_Cpu.cpp; sourceTree = "<group>"; };
F307A29C2B54329C0012534B /* Hes_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Hes_Cpu.cpp; path = ../../external/libgme/gme/Hes_Cpu.cpp; sourceTree = "<group>"; };
F307A29D2B54329C0012534B /* Gb_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gb_Cpu.cpp; path = ../../external/libgme/gme/Gb_Cpu.cpp; sourceTree = "<group>"; };
F307A29E2B54329C0012534B /* Nes_Oscs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Oscs.cpp; path = ../../external/libgme/gme/Nes_Oscs.cpp; sourceTree = "<group>"; };
F307A29F2B54329C0012534B /* Nsf_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nsf_Emu.cpp; path = ../../external/libgme/gme/Nsf_Emu.cpp; sourceTree = "<group>"; };
F307A2A02B54329C0012534B /* Hes_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Hes_Apu.cpp; path = ../../external/libgme/gme/Hes_Apu.cpp; sourceTree = "<group>"; };
F307A2A12B54329C0012534B /* Gb_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gb_Apu.cpp; path = ../../external/libgme/gme/Gb_Apu.cpp; sourceTree = "<group>"; };
F307A2A22B54329C0012534B /* Multi_Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Multi_Buffer.cpp; path = ../../external/libgme/gme/Multi_Buffer.cpp; sourceTree = "<group>"; };
F307A2A32B54329C0012534B /* Spc_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Emu.cpp; path = ../../external/libgme/gme/Spc_Emu.cpp; sourceTree = "<group>"; };
F307A2A42B54329C0012534B /* Ay_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ay_Cpu.cpp; path = ../../external/libgme/gme/Ay_Cpu.cpp; sourceTree = "<group>"; };
F307A2A52B54329C0012534B /* Ay_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ay_Emu.cpp; path = ../../external/libgme/gme/Ay_Emu.cpp; sourceTree = "<group>"; };
F307A2A62B54329C0012534B /* Kss_Scc_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Kss_Scc_Apu.cpp; path = ../../external/libgme/gme/Kss_Scc_Apu.cpp; sourceTree = "<group>"; };
F307A2A72B54329C0012534B /* Ay_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ay_Apu.cpp; path = ../../external/libgme/gme/Ay_Apu.cpp; sourceTree = "<group>"; };
F307A2A82B54329C0012534B /* Gym_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gym_Emu.cpp; path = ../../external/libgme/gme/Gym_Emu.cpp; sourceTree = "<group>"; };
F307A2A92B54329C0012534B /* Data_Reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Data_Reader.cpp; path = ../../external/libgme/gme/Data_Reader.cpp; sourceTree = "<group>"; };
F307A2AA2B54329C0012534B /* Nes_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Apu.cpp; path = ../../external/libgme/gme/Nes_Apu.cpp; sourceTree = "<group>"; };
F307A2AB2B54329C0012534B /* Gb_Oscs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gb_Oscs.cpp; path = ../../external/libgme/gme/Gb_Oscs.cpp; sourceTree = "<group>"; };
F307A2AC2B54329C0012534B /* Spc_Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Filter.cpp; path = ../../external/libgme/gme/Spc_Filter.cpp; sourceTree = "<group>"; };
F307A2AD2B54329C0012534B /* Spc_Dsp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Dsp.cpp; path = ../../external/libgme/gme/Spc_Dsp.cpp; sourceTree = "<group>"; };
F307A2AE2B54329C0012534B /* gme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gme.cpp; path = ../../external/libgme/gme/gme.cpp; sourceTree = "<group>"; };
F307A2DE2B5434FF0012534B /* Vgm_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vgm_Emu.cpp; path = ../../external/libgme/gme/Vgm_Emu.cpp; sourceTree = "<group>"; };
6314974B2D8D4A3600EEC879 /* Nes_Fds_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Fds_Apu.cpp; path = ../../external/libgme/gme/Nes_Fds_Apu.cpp; sourceTree = "<group>"; };
6314974D2D8D4A9200EEC879 /* Nes_Vrc7_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Vrc7_Apu.cpp; path = ../../external/libgme/gme/Nes_Vrc7_Apu.cpp; sourceTree = "<group>"; };
6314974F2D8D4AEA00EEC879 /* emu2413.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = emu2413.c; path = ../../external/libgme/gme/ext/emu2413.c; sourceTree = "<group>"; };
631497512D8D4B0500EEC879 /* panning.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = panning.c; path = ../../external/libgme/gme/ext/panning.c; sourceTree = "<group>"; };
F307A2E02B54358D0012534B /* gme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gme.h; path = ../../external/libgme/gme/gme.h; sourceTree = "<group>"; };
F3F70EDA281F61B4005AA27D /* gme.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gme.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F3F70ED7281F61B4005AA27D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F3F70ED0281F61B4005AA27D = {
isa = PBXGroup;
children = (
F3F70EDB281F61B4005AA27D /* Products */,
F3F70EE6281F61D0005AA27D /* Resources */,
F3F70EE5281F61C9005AA27D /* Headers */,
F3F70EE4281F61C3005AA27D /* Source */,
);
sourceTree = "<group>";
};
F3F70EDB281F61B4005AA27D /* Products */ = {
isa = PBXGroup;
children = (
F3F70EDA281F61B4005AA27D /* gme.framework */,
);
name = Products;
sourceTree = "<group>";
};
F3F70EE4281F61C3005AA27D /* Source */ = {
isa = PBXGroup;
children = (
F307A2A72B54329C0012534B /* Ay_Apu.cpp */,
F307A2A42B54329C0012534B /* Ay_Cpu.cpp */,
F307A2A52B54329C0012534B /* Ay_Emu.cpp */,
F307A28F2B54329C0012534B /* Blip_Buffer.cpp */,
F307A2922B54329C0012534B /* Classic_Emu.cpp */,
F307A2A92B54329C0012534B /* Data_Reader.cpp */,
F307A2832B54329C0012534B /* Dual_Resampler.cpp */,
F307A28C2B54329C0012534B /* Effects_Buffer.cpp */,
F307A28D2B54329C0012534B /* Fir_Resampler.cpp */,
F307A2A12B54329C0012534B /* Gb_Apu.cpp */,
F307A29D2B54329C0012534B /* Gb_Cpu.cpp */,
F307A2AB2B54329C0012534B /* Gb_Oscs.cpp */,
F307A2932B54329C0012534B /* Gbs_Emu.cpp */,
F307A2982B54329C0012534B /* Gme_File.cpp */,
F307A2AE2B54329C0012534B /* gme.cpp */,
6314974F2D8D4AEA00EEC879 /* emu2413.c */,
631497512D8D4B0500EEC879 /* panning.c */,
F307A2A82B54329C0012534B /* Gym_Emu.cpp */,
F307A2A02B54329C0012534B /* Hes_Apu.cpp */,
F307A29C2B54329C0012534B /* Hes_Cpu.cpp */,
F307A2882B54329C0012534B /* Hes_Emu.cpp */,
F307A28A2B54329C0012534B /* Kss_Cpu.cpp */,
F307A29A2B54329C0012534B /* Kss_Emu.cpp */,
F307A2A62B54329C0012534B /* Kss_Scc_Apu.cpp */,
F307A2862B54329C0012534B /* M3u_Playlist.cpp */,
F307A2A22B54329C0012534B /* Multi_Buffer.cpp */,
F307A28E2B54329C0012534B /* Music_Emu.cpp */,
F307A2AA2B54329C0012534B /* Nes_Apu.cpp */,
F307A28B2B54329C0012534B /* Nes_Cpu.cpp */,
F307A2942B54329C0012534B /* Nes_Fme7_Apu.cpp */,
F307A2852B54329C0012534B /* Nes_Namco_Apu.cpp */,
F307A29E2B54329C0012534B /* Nes_Oscs.cpp */,
F307A2812B54329C0012534B /* Nes_Vrc6_Apu.cpp */,
6314974B2D8D4A3600EEC879 /* Nes_Fds_Apu.cpp */,
6314974D2D8D4A9200EEC879 /* Nes_Vrc7_Apu.cpp */,
F307A29F2B54329C0012534B /* Nsf_Emu.cpp */,
F307A2992B54329C0012534B /* Nsfe_Emu.cpp */,
F307A2902B54329C0012534B /* Sap_Apu.cpp */,
F307A2822B54329C0012534B /* Sap_Cpu.cpp */,
F307A2912B54329C0012534B /* Sap_Emu.cpp */,
F307A2952B54329C0012534B /* Sms_Apu.cpp */,
F307A2892B54329C0012534B /* Snes_Spc.cpp */,
F307A29B2B54329C0012534B /* Spc_Cpu.cpp */,
F307A2AD2B54329C0012534B /* Spc_Dsp.cpp */,
F307A2A32B54329C0012534B /* Spc_Emu.cpp */,
F307A2AC2B54329C0012534B /* Spc_Filter.cpp */,
F307A2872B54329C0012534B /* Vgm_Emu_Impl.cpp */,
F307A2DE2B5434FF0012534B /* Vgm_Emu.cpp */,
F307A2962B54329C0012534B /* Ym2413_Emu.cpp */,
F307A2802B54329C0012534B /* Ym2612_GENS.cpp */,
F307A2842B54329C0012534B /* Ym2612_MAME.cpp */,
F307A2972B54329C0012534B /* Ym2612_Nuked.cpp */,
);
name = Source;
sourceTree = "<group>";
};
F3F70EE5281F61C9005AA27D /* Headers */ = {
isa = PBXGroup;
children = (
F307A2E02B54358D0012534B /* gme.h */,
);
name = Headers;
sourceTree = "<group>";
};
F3F70EE6281F61D0005AA27D /* Resources */ = {
isa = PBXGroup;
children = (
F307A27B2B5431C70012534B /* gme.txt */,
F307A27A2B5431C70012534B /* license.txt */,
F307A27C2B5431C70012534B /* readme.txt */,
);
name = Resources;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
F3F70ED5281F61B4005AA27D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
F307A2E12B54358D0012534B /* gme.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
F3F70ED9281F61B4005AA27D /* gme */ = {
isa = PBXNativeTarget;
buildConfigurationList = F3F70EE1281F61B4005AA27D /* Build configuration list for PBXNativeTarget "gme" */;
buildPhases = (
F3F70ED5281F61B4005AA27D /* Headers */,
F3F70ED6281F61B4005AA27D /* Sources */,
F3F70ED7281F61B4005AA27D /* Frameworks */,
F3F70ED8281F61B4005AA27D /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = gme;
productName = gme;
productReference = F3F70EDA281F61B4005AA27D /* gme.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F3F70ED1281F61B4005AA27D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastUpgradeCheck = 1330;
TargetAttributes = {
F3B38D8F296F9773005DA6D3 = {
CreatedOnToolsVersion = 14.2;
};
F3F70ED9281F61B4005AA27D = {
CreatedOnToolsVersion = 13.3.1;
};
};
};
buildConfigurationList = F3F70ED4281F61B4005AA27D /* Build configuration list for PBXProject "gme" */;
compatibilityVersion = "Xcode 13.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F3F70ED0281F61B4005AA27D;
productRefGroup = F3F70EDB281F61B4005AA27D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F3F70ED9281F61B4005AA27D /* gme */,
F3B38D8F296F9773005DA6D3 /* gme.xcframework */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F3F70ED8281F61B4005AA27D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F307A27F2B5431C70012534B /* readme.txt in Resources */,
F307A27E2B5431C70012534B /* gme.txt in Resources */,
F307A27D2B5431C70012534B /* license.txt in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
F3B38D93296F9779005DA6D3 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"gme\"\nPROJECT_NAME=\"gme\"\nSCHEME=\"gme\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"../build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -sdk macosx \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk iphonesimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -sdk iphoneos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk appletvsimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -sdk appletvos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F3F70ED6281F61B4005AA27D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F307A2C62B54329C0012534B /* Ym2612_Nuked.cpp in Sources */,
F307A2D42B54329C0012534B /* Ay_Emu.cpp in Sources */,
F307A2D82B54329C0012534B /* Data_Reader.cpp in Sources */,
F307A2DB2B54329C0012534B /* Spc_Filter.cpp in Sources */,
F307A2D92B54329C0012534B /* Nes_Apu.cpp in Sources */,
F307A2BE2B54329C0012534B /* Blip_Buffer.cpp in Sources */,
F307A2D12B54329C0012534B /* Multi_Buffer.cpp in Sources */,
F307A2D52B54329C0012534B /* Kss_Scc_Apu.cpp in Sources */,
F307A2BD2B54329C0012534B /* Music_Emu.cpp in Sources */,
F307A2B92B54329C0012534B /* Kss_Cpu.cpp in Sources */,
F307A2C52B54329C0012534B /* Ym2413_Emu.cpp in Sources */,
F307A2CA2B54329C0012534B /* Spc_Cpu.cpp in Sources */,
F307A2B42B54329C0012534B /* Nes_Namco_Apu.cpp in Sources */,
F307A2DD2B54329C0012534B /* gme.cpp in Sources */,
F307A2B12B54329C0012534B /* Sap_Cpu.cpp in Sources */,
F307A2B62B54329C0012534B /* Vgm_Emu_Impl.cpp in Sources */,
F307A2D02B54329C0012534B /* Gb_Apu.cpp in Sources */,
F307A2CE2B54329C0012534B /* Nsf_Emu.cpp in Sources */,
F307A2D72B54329C0012534B /* Gym_Emu.cpp in Sources */,
F307A2B72B54329C0012534B /* Hes_Emu.cpp in Sources */,
F307A2BB2B54329C0012534B /* Effects_Buffer.cpp in Sources */,
F307A2B02B54329C0012534B /* Nes_Vrc6_Apu.cpp in Sources */,
F307A2CB2B54329C0012534B /* Hes_Cpu.cpp in Sources */,
F307A2C72B54329C0012534B /* Gme_File.cpp in Sources */,
F307A2BC2B54329C0012534B /* Fir_Resampler.cpp in Sources */,
F307A2C22B54329C0012534B /* Gbs_Emu.cpp in Sources */,
F307A2B82B54329C0012534B /* Snes_Spc.cpp in Sources */,
F307A2D22B54329C0012534B /* Spc_Emu.cpp in Sources */,
F307A2DF2B5434FF0012534B /* Vgm_Emu.cpp in Sources */,
F307A2C12B54329C0012534B /* Classic_Emu.cpp in Sources */,
F307A2AF2B54329C0012534B /* Ym2612_GENS.cpp in Sources */,
F307A2C02B54329C0012534B /* Sap_Emu.cpp in Sources */,
F307A2D62B54329C0012534B /* Ay_Apu.cpp in Sources */,
F307A2B22B54329C0012534B /* Dual_Resampler.cpp in Sources */,
F307A2CC2B54329C0012534B /* Gb_Cpu.cpp in Sources */,
F307A2BA2B54329C0012534B /* Nes_Cpu.cpp in Sources */,
F307A2CF2B54329C0012534B /* Hes_Apu.cpp in Sources */,
F307A2C32B54329C0012534B /* Nes_Fme7_Apu.cpp in Sources */,
F307A2D32B54329C0012534B /* Ay_Cpu.cpp in Sources */,
F307A2CD2B54329C0012534B /* Nes_Oscs.cpp in Sources */,
F307A2C42B54329C0012534B /* Sms_Apu.cpp in Sources */,
F307A2C92B54329C0012534B /* Kss_Emu.cpp in Sources */,
F307A2B52B54329C0012534B /* M3u_Playlist.cpp in Sources */,
F307A2DA2B54329C0012534B /* Gb_Oscs.cpp in Sources */,
F307A2B32B54329C0012534B /* Ym2612_MAME.cpp in Sources */,
F307A2BF2B54329C0012534B /* Sap_Apu.cpp in Sources */,
F307A2DC2B54329C0012534B /* Spc_Dsp.cpp in Sources */,
F307A2C82B54329C0012534B /* Nsfe_Emu.cpp in Sources */,
6314974C2D8D4A3600EEC879 /* Nes_Fds_Apu.cpp in Sources */,
6314974E2D8D4A9200EEC879 /* Nes_Vrc7_Apu.cpp in Sources */,
631497502D8D4AEA00EEC879 /* emu2413.c in Sources */,
631497522D8D4B0500EEC879 /* panning.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
F3B38D90296F9773005DA6D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
F3B38D91296F9773005DA6D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
F3F70EDF281F61B4005AA27D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"BLARGG_LITTLE_ENDIAN=1",
BLARGG_BUILD_DLL,
LIBGME_VISIBILITY,
VGM_YM2612_NUKED,
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../external/libgme\"";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 11.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
F3F70EE0281F61B4005AA27D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"BLARGG_LITTLE_ENDIAN=1",
BLARGG_BUILD_DLL,
LIBGME_VISIBILITY,
VGM_YM2612_NUKED,
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../external/libgme\"";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 11.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
F3F70EE2281F61B4005AA27D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.3.2;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.gme;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
};
name = Debug;
};
F3F70EE3281F61B4005AA27D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.3.2;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.gme;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F3B38D92296F9773005DA6D3 /* Build configuration list for PBXAggregateTarget "gme.xcframework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3B38D90296F9773005DA6D3 /* Debug */,
F3B38D91296F9773005DA6D3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F3F70ED4281F61B4005AA27D /* Build configuration list for PBXProject "gme" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3F70EDF281F61B4005AA27D /* Debug */,
F3F70EE0281F61B4005AA27D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F3F70EE1281F61B4005AA27D /* Build configuration list for PBXNativeTarget "gme" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3F70EE2281F61B4005AA27D /* Debug */,
F3F70EE3281F61B4005AA27D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F3F70ED1281F61B4005AA27D /* Project object */;
}
@@ -0,0 +1,91 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/**
* Main include header for the SDL library, version 3.4.0
*
* It is almost always best to include just this one header instead of
* picking out individual headers included here. There are exceptions to
* this rule--SDL_main.h is special and not included here--but usually
* letting SDL.h include the kitchen sink for you is the correct approach.
*/
#ifndef SDL_h_
#define SDL_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_assert.h>
#include <SDL3/SDL_asyncio.h>
#include <SDL3/SDL_atomic.h>
#include <SDL3/SDL_audio.h>
#include <SDL3/SDL_bits.h>
#include <SDL3/SDL_blendmode.h>
#include <SDL3/SDL_camera.h>
#include <SDL3/SDL_clipboard.h>
#include <SDL3/SDL_cpuinfo.h>
#include <SDL3/SDL_dialog.h>
#include <SDL3/SDL_dlopennote.h>
#include <SDL3/SDL_endian.h>
#include <SDL3/SDL_error.h>
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_gamepad.h>
#include <SDL3/SDL_gpu.h>
#include <SDL3/SDL_guid.h>
#include <SDL3/SDL_haptic.h>
#include <SDL3/SDL_hidapi.h>
#include <SDL3/SDL_hints.h>
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_iostream.h>
#include <SDL3/SDL_joystick.h>
#include <SDL3/SDL_keyboard.h>
#include <SDL3/SDL_keycode.h>
#include <SDL3/SDL_loadso.h>
#include <SDL3/SDL_locale.h>
#include <SDL3/SDL_log.h>
#include <SDL3/SDL_messagebox.h>
#include <SDL3/SDL_metal.h>
#include <SDL3/SDL_misc.h>
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_mutex.h>
#include <SDL3/SDL_pen.h>
#include <SDL3/SDL_pixels.h>
#include <SDL3/SDL_platform.h>
#include <SDL3/SDL_power.h>
#include <SDL3/SDL_process.h>
#include <SDL3/SDL_properties.h>
#include <SDL3/SDL_rect.h>
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_scancode.h>
#include <SDL3/SDL_sensor.h>
#include <SDL3/SDL_storage.h>
#include <SDL3/SDL_surface.h>
#include <SDL3/SDL_system.h>
#include <SDL3/SDL_thread.h>
#include <SDL3/SDL_time.h>
#include <SDL3/SDL_timer.h>
#include <SDL3/SDL_tray.h>
#include <SDL3/SDL_touch.h>
#include <SDL3/SDL_version.h>
#include <SDL3/SDL_video.h>
#include <SDL3/SDL_oldnames.h>
#endif /* SDL_h_ */
@@ -0,0 +1,695 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/**
* # CategoryAssert
*
* A helpful assertion macro!
*
* SDL assertions operate like your usual `assert` macro, but with some added
* features:
*
* - It uses a trick with the `sizeof` operator, so disabled assertions
* vaporize out of the compiled code, but variables only referenced in the
* assertion won't trigger compiler warnings about being unused.
* - It is safe to use with a dangling-else: `if (x) SDL_assert(y); else
* do_something();`
* - It works the same everywhere, instead of counting on various platforms'
* compiler and C runtime to behave.
* - It provides multiple levels of assertion (SDL_assert, SDL_assert_release,
* SDL_assert_paranoid) instead of a single all-or-nothing option.
* - It offers a variety of responses when an assertion fails (retry, trigger
* the debugger, abort the program, ignore the failure once, ignore it for
* the rest of the program's run).
* - It tries to show the user a dialog by default, if possible, but the app
* can provide a callback to handle assertion failures however they like.
* - It lets failed assertions be retried. Perhaps you had a network failure
* and just want to retry the test after plugging your network cable back
* in? You can.
* - It lets the user ignore an assertion failure, if there's a harmless
* problem that one can continue past.
* - It lets the user mark an assertion as ignored for the rest of the
* program's run; if there's a harmless problem that keeps popping up.
* - It provides statistics and data on all failed assertions to the app.
* - It allows the default assertion handler to be controlled with environment
* variables, in case an automated script needs to control it.
* - It can be used as an aid to Clang's static analysis; it will treat SDL
* assertions as universally true (under the assumption that you are serious
* about the asserted claims and that your debug builds will detect when
* these claims were wrong). This can help the analyzer avoid false
* positives.
*
* To use it: compile a debug build and just sprinkle around tests to check
* your code!
*/
#ifndef SDL_assert_h_
#define SDL_assert_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* The level of assertion aggressiveness.
*
* This value changes depending on compiler options and other preprocessor
* defines.
*
* It is currently one of the following values, but future SDL releases might
* add more:
*
* - 0: All SDL assertion macros are disabled.
* - 1: Release settings: SDL_assert disabled, SDL_assert_release enabled.
* - 2: Debug settings: SDL_assert and SDL_assert_release enabled.
* - 3: Paranoid settings: All SDL assertion macros enabled, including
* SDL_assert_paranoid.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_ASSERT_LEVEL SomeNumberBasedOnVariousFactors
#elif !defined(SDL_ASSERT_LEVEL)
#ifdef SDL_DEFAULT_ASSERT_LEVEL
#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL
#elif defined(_DEBUG) || defined(DEBUG) || \
(defined(__GNUC__) && !defined(__OPTIMIZE__))
#define SDL_ASSERT_LEVEL 2
#else
#define SDL_ASSERT_LEVEL 1
#endif
#endif
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* Attempt to tell an attached debugger to pause.
*
* This allows an app to programmatically halt ("break") the debugger as if it
* had hit a breakpoint, allowing the developer to examine program state, etc.
*
* This is a macro--not a function--so that the debugger breaks on the source
* code line that used SDL_TriggerBreakpoint and not in some random guts of
* SDL. SDL_assert uses this macro for the same reason.
*
* If the program is not running under a debugger, SDL_TriggerBreakpoint will
* likely terminate the app, possibly without warning. If the current platform
* isn't supported, this macro is left undefined.
*
* \threadsafety It is safe to call this macro from any thread.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner
#elif defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1310)
/* Don't include intrin.h here because it contains C++ code */
extern void __cdecl __debugbreak(void);
#define SDL_TriggerBreakpoint() __debugbreak()
#elif defined(_MSC_VER) && defined(_M_IX86)
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
#elif SDL_HAS_BUILTIN(__builtin_debugtrap)
#define SDL_TriggerBreakpoint() __builtin_debugtrap()
#elif SDL_HAS_BUILTIN(__builtin_trap)
#define SDL_TriggerBreakpoint() __builtin_trap()
#elif (defined(__GNUC__) || defined(__clang__) || defined(__TINYC__)) && (defined(__i386__) || defined(__x86_64__))
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv)
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" )
#elif ( defined(SDL_PLATFORM_APPLE) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" )
#elif defined(SDL_PLATFORM_APPLE) && defined(__arm__)
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" )
#elif defined(_WIN32) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__)) )
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #0xF000\n\t" )
#elif defined(__GNUC__) || defined(__clang__)
#define SDL_TriggerBreakpoint() __builtin_trap() /* older gcc may not support SDL_HAS_BUILTIN(__builtin_trap) above */
#elif defined(__386__) && defined(__WATCOMC__)
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__)
#include <signal.h>
#define SDL_TriggerBreakpoint() raise(SIGTRAP)
#else
/* SDL_TriggerBreakpoint is intentionally left undefined on unknown platforms. */
#endif
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* A macro that reports the current function being compiled.
*
* If SDL can't figure how the compiler reports this, it will use "???".
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_FUNCTION __FUNCTION__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */
# define SDL_FUNCTION __func__
#elif ((defined(__GNUC__) && (__GNUC__ >= 2)) || defined(_MSC_VER) || defined (__WATCOMC__))
# define SDL_FUNCTION __FUNCTION__
#else
# define SDL_FUNCTION "???"
#endif
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* A macro that reports the current file being compiled.
*
* This macro is only defined if it isn't already defined, so to override it
* (perhaps with something that doesn't provide path information at all, so
* build machine information doesn't leak into public binaries), apps can
* define this macro before including SDL.h or SDL_assert.h.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_FILE __FILE_NAME__
#elif !defined(SDL_FILE)
#ifdef __FILE_NAME__
#define SDL_FILE __FILE_NAME__
#else
#define SDL_FILE __FILE__
#endif
#endif
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* A macro that reports the current file being compiled, for use in
* assertions.
*
* This macro is only defined if it isn't already defined, so to override it
* (perhaps with something that doesn't provide path information at all, so
* build machine information doesn't leak into public binaries), apps can
* define this macro before including SDL_assert.h. For example, defining this
* to `""` will make sure no source path information is included in asserts.
*
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_ASSERT_FILE SDL_FILE
#elif !defined(SDL_ASSERT_FILE)
#define SDL_ASSERT_FILE SDL_FILE
#endif
/**
* A macro that reports the current line number of the file being compiled.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_LINE __LINE__
/*
sizeof (x) makes the compiler still parse the expression even without
assertions enabled, so the code is always checked at compile time, but
doesn't actually generate code for it, so there are no side effects or
expensive checks at run time, just the constant size of what x WOULD be,
which presumably gets optimized out as unused.
This also solves the problem of...
int somevalue = blah();
SDL_assert(somevalue == 1);
...which would cause compiles to complain that somevalue is unused if we
disable assertions.
*/
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* A macro for wrapping code in `do {} while (0);` without compiler warnings.
*
* Visual Studio with really aggressive warnings enabled needs this to avoid
* compiler complaints.
*
* the `do {} while (0);` trick is useful for wrapping code in a macro that
* may or may not be a single statement, to avoid various C language
* accidents.
*
* To use:
*
* ```c
* do { SomethingOnce(); } while (SDL_NULL_WHILE_LOOP_CONDITION (0));
* ```
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_NULL_WHILE_LOOP_CONDITION (0)
#elif defined(_MSC_VER) /* Avoid /W4 warnings. */
/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking
this condition isn't constant. And looks like an owl's face! */
#define SDL_NULL_WHILE_LOOP_CONDITION (0,0)
#else
#define SDL_NULL_WHILE_LOOP_CONDITION (0)
#endif
/**
* The macro used when an assertion is disabled.
*
* This isn't for direct use by apps, but this is the code that is inserted
* when an SDL_assert is disabled (perhaps in a release build).
*
* The code does nothing, but wraps `condition` in a sizeof operator, which
* generates no code and has no side effects, but avoid compiler warnings
* about unused variables.
*
* \param condition the condition to assert (but not actually run here).
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_disabled_assert(condition) \
do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION)
/**
* Possible outcomes from a triggered assertion.
*
* When an enabled assertion triggers, it may call the assertion handler
* (possibly one provided by the app via SDL_SetAssertionHandler), which will
* return one of these values, possibly after asking the user.
*
* Then SDL will respond based on this outcome (loop around to retry the
* condition, try to break in a debugger, kill the program, or ignore the
* problem).
*
* \since This enum is available since SDL 3.2.0.
*/
typedef enum SDL_AssertState
{
SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */
SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */
SDL_ASSERTION_ABORT, /**< Terminate the program. */
SDL_ASSERTION_IGNORE, /**< Ignore the assert. */
SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */
} SDL_AssertState;
/**
* Information about an assertion failure.
*
* This structure is filled in with information about a triggered assertion,
* used by the assertion handler, then added to the assertion report. This is
* returned as a linked list from SDL_GetAssertionReport().
*
* \since This struct is available since SDL 3.2.0.
*/
typedef struct SDL_AssertData
{
bool always_ignore; /**< true if app should always continue when assertion is triggered. */
unsigned int trigger_count; /**< Number of times this assertion has been triggered. */
const char *condition; /**< A string of this assert's test code. */
const char *filename; /**< The source file where this assert lives. */
int linenum; /**< The line in `filename` where this assert lives. */
const char *function; /**< The name of the function where this assert lives. */
const struct SDL_AssertData *next; /**< next item in the linked list. */
} SDL_AssertData;
/**
* Never call this directly.
*
* Use the SDL_assert macros instead.
*
* \param data assert data structure.
* \param func function name.
* \param file file name.
* \param line line number.
* \returns assert state.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *data,
const char *func,
const char *file, int line) SDL_ANALYZER_NORETURN;
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* The macro used when an assertion triggers a breakpoint.
*
* This isn't for direct use by apps; use SDL_assert or SDL_TriggerBreakpoint
* instead.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_AssertBreakpoint() SDL_TriggerBreakpoint()
#elif !defined(SDL_AssertBreakpoint)
# if defined(ANDROID) && defined(assert)
/* Define this as empty in case assert() is defined as SDL_assert */
# define SDL_AssertBreakpoint()
# else
# define SDL_AssertBreakpoint() SDL_TriggerBreakpoint()
# endif
#endif /* !SDL_AssertBreakpoint */
/**
* The macro used when an assertion is enabled.
*
* This isn't for direct use by apps, but this is the code that is inserted
* when an SDL_assert is enabled.
*
* The `do {} while(0)` avoids dangling else problems:
*
* ```c
* if (x) SDL_assert(y); else blah();
* ```
*
* ... without the do/while, the "else" could attach to this macro's "if". We
* try to handle just the minimum we need here in a macro...the loop, the
* static vars, and break points. The heavy lifting is handled in
* SDL_ReportAssertion().
*
* \param condition the condition to assert.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_enabled_assert(condition) \
do { \
while ( !(condition) ) { \
static struct SDL_AssertData sdl_assert_data = { false, 0, #condition, NULL, 0, NULL, NULL }; \
const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_ASSERT_FILE, SDL_LINE); \
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
continue; /* go again. */ \
} else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \
SDL_AssertBreakpoint(); \
} \
break; /* not retrying. */ \
} \
} while (SDL_NULL_WHILE_LOOP_CONDITION)
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* An assertion test that is normally performed only in debug builds.
*
* This macro is enabled when the SDL_ASSERT_LEVEL is >= 2, otherwise it is
* disabled. This is meant to only do these tests in debug builds, so they can
* tend to be more expensive, and they are meant to bring everything to a halt
* when they fail, with the programmer there to assess the problem.
*
* In short: you can sprinkle these around liberally and assume they will
* evaporate out of the build when building for end-users.
*
* When assertions are disabled, this wraps `condition` in a `sizeof`
* operator, which means any function calls and side effects will not run, but
* the compiler will not complain about any otherwise-unused variables that
* are only referenced in the assertion.
*
* One can set the environment variable "SDL_ASSERT" to one of several strings
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
* behavior, which may be desirable for automation purposes. If your platform
* requires GUI interfaces to happen on the main thread but you're debugging
* an assertion in a background thread, it might be desirable to set this to
* "break" so that your debugger takes control as soon as assert is triggered,
* instead of risking a bad UI interaction (deadlock, etc) in the application.
*
* \param condition boolean value to test.
*
* \threadsafety It is safe to call this macro from any thread.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_assert(condition) if (assertion_enabled && (condition)) { trigger_assertion; }
/**
* An assertion test that is performed even in release builds.
*
* This macro is enabled when the SDL_ASSERT_LEVEL is >= 1, otherwise it is
* disabled. This is meant to be for tests that are cheap to make and
* extremely unlikely to fail; generally it is frowned upon to have an
* assertion failure in a release build, so these assertions generally need to
* be of more than life-and-death importance if there's a chance they might
* trigger. You should almost always consider handling these cases more
* gracefully than an assert allows.
*
* When assertions are disabled, this wraps `condition` in a `sizeof`
* operator, which means any function calls and side effects will not run, but
* the compiler will not complain about any otherwise-unused variables that
* are only referenced in the assertion.
*
* One can set the environment variable "SDL_ASSERT" to one of several strings
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
* behavior, which may be desirable for automation purposes. If your platform
* requires GUI interfaces to happen on the main thread but you're debugging
* an assertion in a background thread, it might be desirable to set this to
* "break" so that your debugger takes control as soon as assert is triggered,
* instead of risking a bad UI interaction (deadlock, etc) in the application.
* *
*
* \param condition boolean value to test.
*
* \threadsafety It is safe to call this macro from any thread.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_assert_release(condition) SDL_disabled_assert(condition)
/**
* An assertion test that is performed only when built with paranoid settings.
*
* This macro is enabled when the SDL_ASSERT_LEVEL is >= 3, otherwise it is
* disabled. This is a higher level than both release and debug, so these
* tests are meant to be expensive and only run when specifically looking for
* extremely unexpected failure cases in a special build.
*
* When assertions are disabled, this wraps `condition` in a `sizeof`
* operator, which means any function calls and side effects will not run, but
* the compiler will not complain about any otherwise-unused variables that
* are only referenced in the assertion.
*
* One can set the environment variable "SDL_ASSERT" to one of several strings
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
* behavior, which may be desirable for automation purposes. If your platform
* requires GUI interfaces to happen on the main thread but you're debugging
* an assertion in a background thread, it might be desirable to set this to
* "break" so that your debugger takes control as soon as assert is triggered,
* instead of risking a bad UI interaction (deadlock, etc) in the application.
*
* \param condition boolean value to test.
*
* \threadsafety It is safe to call this macro from any thread.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
/* Enable various levels of assertions. */
#elif SDL_ASSERT_LEVEL == 0 /* assertions disabled */
# define SDL_assert(condition) SDL_disabled_assert(condition)
# define SDL_assert_release(condition) SDL_disabled_assert(condition)
# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
#elif SDL_ASSERT_LEVEL == 1 /* release settings. */
# define SDL_assert(condition) SDL_disabled_assert(condition)
# define SDL_assert_release(condition) SDL_enabled_assert(condition)
# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
#elif SDL_ASSERT_LEVEL == 2 /* debug settings. */
# define SDL_assert(condition) SDL_enabled_assert(condition)
# define SDL_assert_release(condition) SDL_enabled_assert(condition)
# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */
# define SDL_assert(condition) SDL_enabled_assert(condition)
# define SDL_assert_release(condition) SDL_enabled_assert(condition)
# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition)
#else
# error Unknown assertion level.
#endif
/**
* An assertion test that is always performed.
*
* This macro is always enabled no matter what SDL_ASSERT_LEVEL is set to. You
* almost never want to use this, as it could trigger on an end-user's system,
* crashing your program.
*
* One can set the environment variable "SDL_ASSERT" to one of several strings
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
* behavior, which may be desirable for automation purposes. If your platform
* requires GUI interfaces to happen on the main thread but you're debugging
* an assertion in a background thread, it might be desirable to set this to
* "break" so that your debugger takes control as soon as assert is triggered,
* instead of risking a bad UI interaction (deadlock, etc) in the application.
*
* \param condition boolean value to test.
*
* \threadsafety It is safe to call this macro from any thread.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_assert_always(condition) SDL_enabled_assert(condition)
/**
* A callback that fires when an SDL assertion fails.
*
* \param data a pointer to the SDL_AssertData structure corresponding to the
* current assertion.
* \param userdata what was passed as `userdata` to SDL_SetAssertionHandler().
* \returns an SDL_AssertState value indicating how to handle the failure.
*
* \threadsafety This callback may be called from any thread that triggers an
* assert at any time.
*
* \since This datatype is available since SDL 3.2.0.
*/
typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)(
const SDL_AssertData *data, void *userdata);
/**
* Set an application-defined assertion handler.
*
* This function allows an application to show its own assertion UI and/or
* force the response to an assertion failure. If the application doesn't
* provide this, SDL will try to do the right thing, popping up a
* system-specific GUI dialog, and probably minimizing any fullscreen windows.
*
* This callback may fire from any thread, but it runs wrapped in a mutex, so
* it will only fire from one thread at a time.
*
* This callback is NOT reset to SDL's internal handler upon SDL_Quit()!
*
* \param handler the SDL_AssertionHandler function to call when an assertion
* fails or NULL for the default handler.
* \param userdata a pointer that is passed to `handler`.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetAssertionHandler
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetAssertionHandler(
SDL_AssertionHandler handler,
void *userdata);
/**
* Get the default assertion handler.
*
* This returns the function pointer that is called by default when an
* assertion is triggered. This is an internal function provided by SDL, that
* is used for assertions when SDL_SetAssertionHandler() hasn't been used to
* provide a different function.
*
* \returns the default SDL_AssertionHandler that is called when an assert
* triggers.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetAssertionHandler
*/
extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void);
/**
* Get the current assertion handler.
*
* This returns the function pointer that is called when an assertion is
* triggered. This is either the value last passed to
* SDL_SetAssertionHandler(), or if no application-specified function is set,
* is equivalent to calling SDL_GetDefaultAssertionHandler().
*
* The parameter `puserdata` is a pointer to a void*, which will store the
* "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value
* will always be NULL for the default handler. If you don't care about this
* data, it is safe to pass a NULL pointer to this function to ignore it.
*
* \param puserdata pointer which is filled with the "userdata" pointer that
* was passed to SDL_SetAssertionHandler().
* \returns the SDL_AssertionHandler that is called when an assert triggers.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetAssertionHandler
*/
extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata);
/**
* Get a list of all assertion failures.
*
* This function gets all assertions triggered since the last call to
* SDL_ResetAssertionReport(), or the start of the program.
*
* The proper way to examine this data looks something like this:
*
* ```c
* const SDL_AssertData *item = SDL_GetAssertionReport();
* while (item) {
* printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n",
* item->condition, item->function, item->filename,
* item->linenum, item->trigger_count,
* item->always_ignore ? "yes" : "no");
* item = item->next;
* }
* ```
*
* \returns a list of all failed assertions or NULL if the list is empty. This
* memory should not be modified or freed by the application. This
* pointer remains valid until the next call to SDL_Quit() or
* SDL_ResetAssertionReport().
*
* \threadsafety This function is not thread safe. Other threads calling
* SDL_ResetAssertionReport() simultaneously, may render the
* returned pointer invalid.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_ResetAssertionReport
*/
extern SDL_DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void);
/**
* Clear the list of all assertion failures.
*
* This function will clear the list of all assertions triggered up to that
* point. Immediately following this call, SDL_GetAssertionReport will return
* no items. In addition, any previously-triggered assertions will be reset to
* a trigger_count of zero, and their always_ignore state will be false.
*
* \threadsafety This function is not thread safe. Other threads triggering an
* assertion, or simultaneously calling this function may cause
* memory leaks or crashes.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetAssertionReport
*/
extern SDL_DECLSPEC void SDLCALL SDL_ResetAssertionReport(void);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_assert_h_ */
@@ -0,0 +1,546 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/* WIKI CATEGORY: AsyncIO */
/**
* # CategoryAsyncIO
*
* SDL offers a way to perform I/O asynchronously. This allows an app to read
* or write files without waiting for data to actually transfer; the functions
* that request I/O never block while the request is fulfilled.
*
* Instead, the data moves in the background and the app can check for results
* at their leisure.
*
* This is more complicated than just reading and writing files in a
* synchronous way, but it can allow for more efficiency, and never having
* framerate drops as the hard drive catches up, etc.
*
* The general usage pattern for async I/O is:
*
* - Create one or more SDL_AsyncIOQueue objects.
* - Open files with SDL_AsyncIOFromFile.
* - Start I/O tasks to the files with SDL_ReadAsyncIO or SDL_WriteAsyncIO,
* putting those tasks into one of the queues.
* - Later on, use SDL_GetAsyncIOResult on a queue to see if any task is
* finished without blocking. Tasks might finish in any order with success
* or failure.
* - When all your tasks are done, close the file with SDL_CloseAsyncIO. This
* also generates a task, since it might flush data to disk!
*
* This all works, without blocking, in a single thread, but one can also wait
* on a queue in a background thread, sleeping until new results have arrived:
*
* - Call SDL_WaitAsyncIOResult from one or more threads to efficiently block
* until new tasks complete.
* - When shutting down, call SDL_SignalAsyncIOQueue to unblock any sleeping
* threads despite there being no new tasks completed.
*
* And, of course, to match the synchronous SDL_LoadFile, we offer
* SDL_LoadFileAsync as a convenience function. This will handle allocating a
* buffer, slurping in the file data, and null-terminating it; you still check
* for results later.
*
* Behind the scenes, SDL will use newer, efficient APIs on platforms that
* support them: Linux's io_uring and Windows 11's IoRing, for example. If
* those technologies aren't available, SDL will offload the work to a thread
* pool that will manage otherwise-synchronous loads without blocking the app.
*
* ## Best Practices
*
* Simple non-blocking I/O--for an app that just wants to pick up data
* whenever it's ready without losing framerate waiting on disks to spin--can
* use whatever pattern works well for the program. In this case, simply call
* SDL_ReadAsyncIO, or maybe SDL_LoadFileAsync, as needed. Once a frame, call
* SDL_GetAsyncIOResult to check for any completed tasks and deal with the
* data as it arrives.
*
* If two separate pieces of the same program need their own I/O, it is legal
* for each to create their own queue. This will prevent either piece from
* accidentally consuming the other's completed tasks. Each queue does require
* some amount of resources, but it is not an overwhelming cost. Do not make a
* queue for each task, however. It is better to put many tasks into a single
* queue. They will be reported in order of completion, not in the order they
* were submitted, so it doesn't generally matter what order tasks are
* started.
*
* One async I/O queue can be shared by multiple threads, or one thread can
* have more than one queue, but the most efficient way--if ruthless
* efficiency is the goal--is to have one queue per thread, with multiple
* threads working in parallel, and attempt to keep each queue loaded with
* tasks that are both started by and consumed by the same thread. On modern
* platforms that can use newer interfaces, this can keep data flowing as
* efficiently as possible all the way from storage hardware to the app, with
* no contention between threads for access to the same queue.
*
* Written data is not guaranteed to make it to physical media by the time a
* closing task is completed, unless SDL_CloseAsyncIO is called with its
* `flush` parameter set to true, which is to say that a successful result
* here can still result in lost data during an unfortunately-timed power
* outage if not flushed. However, flushing will take longer and may be
* unnecessary, depending on the app's needs.
*/
#ifndef SDL_asyncio_h_
#define SDL_asyncio_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* The asynchronous I/O operation structure.
*
* This operates as an opaque handle. One can then request read or write
* operations on it.
*
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_AsyncIOFromFile
*/
typedef struct SDL_AsyncIO SDL_AsyncIO;
/**
* Types of asynchronous I/O tasks.
*
* \since This enum is available since SDL 3.2.0.
*/
typedef enum SDL_AsyncIOTaskType
{
SDL_ASYNCIO_TASK_READ, /**< A read operation. */
SDL_ASYNCIO_TASK_WRITE, /**< A write operation. */
SDL_ASYNCIO_TASK_CLOSE /**< A close operation. */
} SDL_AsyncIOTaskType;
/**
* Possible outcomes of an asynchronous I/O task.
*
* \since This enum is available since SDL 3.2.0.
*/
typedef enum SDL_AsyncIOResult
{
SDL_ASYNCIO_COMPLETE, /**< request was completed without error */
SDL_ASYNCIO_FAILURE, /**< request failed for some reason; check SDL_GetError()! */
SDL_ASYNCIO_CANCELED /**< request was canceled before completing. */
} SDL_AsyncIOResult;
/**
* Information about a completed asynchronous I/O request.
*
* \since This struct is available since SDL 3.2.0.
*/
typedef struct SDL_AsyncIOOutcome
{
SDL_AsyncIO *asyncio; /**< what generated this task. This pointer will be invalid if it was closed! */
SDL_AsyncIOTaskType type; /**< What sort of task was this? Read, write, etc? */
SDL_AsyncIOResult result; /**< the result of the work (success, failure, cancellation). */
void *buffer; /**< buffer where data was read/written. */
Uint64 offset; /**< offset in the SDL_AsyncIO where data was read/written. */
Uint64 bytes_requested; /**< number of bytes the task was to read/write. */
Uint64 bytes_transferred; /**< actual number of bytes that were read/written. */
void *userdata; /**< pointer provided by the app when starting the task */
} SDL_AsyncIOOutcome;
/**
* A queue of completed asynchronous I/O tasks.
*
* When starting an asynchronous operation, you specify a queue for the new
* task. A queue can be asked later if any tasks in it have completed,
* allowing an app to manage multiple pending tasks in one place, in whatever
* order they complete.
*
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_CreateAsyncIOQueue
* \sa SDL_ReadAsyncIO
* \sa SDL_WriteAsyncIO
* \sa SDL_GetAsyncIOResult
* \sa SDL_WaitAsyncIOResult
*/
typedef struct SDL_AsyncIOQueue SDL_AsyncIOQueue;
/**
* Use this function to create a new SDL_AsyncIO object for reading from
* and/or writing to a named file.
*
* The `mode` string understands the following values:
*
* - "r": Open a file for reading only. It must exist.
* - "w": Open a file for writing only. It will create missing files or
* truncate existing ones.
* - "r+": Open a file for update both reading and writing. The file must
* exist.
* - "w+": Create an empty file for both reading and writing. If a file with
* the same name already exists its content is erased and the file is
* treated as a new empty file.
*
* There is no "b" mode, as there is only "binary" style I/O, and no "a" mode
* for appending, since you specify the position when starting a task.
*
* This function supports Unicode filenames, but they must be encoded in UTF-8
* format, regardless of the underlying operating system.
*
* This call is _not_ asynchronous; it will open the file before returning,
* under the assumption that doing so is generally a fast operation. Future
* reads and writes to the opened file will be async, however.
*
* \param file a UTF-8 string representing the filename to open.
* \param mode an ASCII string representing the mode to be used for opening
* the file.
* \returns a pointer to the SDL_AsyncIO structure that is created or NULL on
* failure; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CloseAsyncIO
* \sa SDL_ReadAsyncIO
* \sa SDL_WriteAsyncIO
*/
extern SDL_DECLSPEC SDL_AsyncIO * SDLCALL SDL_AsyncIOFromFile(const char *file, const char *mode);
/**
* Use this function to get the size of the data stream in an SDL_AsyncIO.
*
* This call is _not_ asynchronous; it assumes that obtaining this info is a
* non-blocking operation in most reasonable cases.
*
* \param asyncio the SDL_AsyncIO to get the size of the data stream from.
* \returns the size of the data stream in the SDL_IOStream on success or a
* negative error code on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC Sint64 SDLCALL SDL_GetAsyncIOSize(SDL_AsyncIO *asyncio);
/**
* Start an async read.
*
* This function reads up to `size` bytes from `offset` position in the data
* source to the area pointed at by `ptr`. This function may read less bytes
* than requested.
*
* This function returns as quickly as possible; it does not wait for the read
* to complete. On a successful return, this work will continue in the
* background. If the work begins, even failure is asynchronous: a failing
* return value from this function only means the work couldn't start at all.
*
* `ptr` must remain available until the work is done, and may be accessed by
* the system at any time until then. Do not allocate it on the stack, as this
* might take longer than the life of the calling function to complete!
*
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
* to it when it completes its work.
*
* \param asyncio a pointer to an SDL_AsyncIO structure.
* \param ptr a pointer to a buffer to read data into.
* \param offset the position to start reading in the data source.
* \param size the number of bytes to read from the data source.
* \param queue a queue to add the new SDL_AsyncIO to.
* \param userdata an app-defined pointer that will be provided with the task
* results.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_WriteAsyncIO
* \sa SDL_CreateAsyncIOQueue
*/
extern SDL_DECLSPEC bool SDLCALL SDL_ReadAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
/**
* Start an async write.
*
* This function writes `size` bytes from `offset` position in the data source
* to the area pointed at by `ptr`.
*
* This function returns as quickly as possible; it does not wait for the
* write to complete. On a successful return, this work will continue in the
* background. If the work begins, even failure is asynchronous: a failing
* return value from this function only means the work couldn't start at all.
*
* `ptr` must remain available until the work is done, and may be accessed by
* the system at any time until then. Do not allocate it on the stack, as this
* might take longer than the life of the calling function to complete!
*
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
* to it when it completes its work.
*
* \param asyncio a pointer to an SDL_AsyncIO structure.
* \param ptr a pointer to a buffer to write data from.
* \param offset the position to start writing to the data source.
* \param size the number of bytes to write to the data source.
* \param queue a queue to add the new SDL_AsyncIO to.
* \param userdata an app-defined pointer that will be provided with the task
* results.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_ReadAsyncIO
* \sa SDL_CreateAsyncIOQueue
*/
extern SDL_DECLSPEC bool SDLCALL SDL_WriteAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
/**
* Close and free any allocated resources for an async I/O object.
*
* Closing a file is _also_ an asynchronous task! If a write failure were to
* happen during the closing process, for example, the task results will
* report it as usual.
*
* Closing a file that has been written to does not guarantee the data has
* made it to physical media; it may remain in the operating system's file
* cache, for later writing to disk. This means that a successfully-closed
* file can be lost if the system crashes or loses power in this small window.
* To prevent this, call this function with the `flush` parameter set to true.
* This will make the operation take longer, and perhaps increase system load
* in general, but a successful result guarantees that the data has made it to
* physical storage. Don't use this for temporary files, caches, and
* unimportant data, and definitely use it for crucial irreplaceable files,
* like game saves.
*
* This function guarantees that the close will happen after any other pending
* tasks to `asyncio`, so it's safe to open a file, start several operations,
* close the file immediately, then check for all results later. This function
* will not block until the tasks have completed.
*
* Once this function returns true, `asyncio` is no longer valid, regardless
* of any future outcomes. Any completed tasks might still contain this
* pointer in their SDL_AsyncIOOutcome data, in case the app was using this
* value to track information, but it should not be used again.
*
* If this function returns false, the close wasn't started at all, and it's
* safe to attempt to close again later.
*
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
* to it when it completes its work.
*
* \param asyncio a pointer to an SDL_AsyncIO structure to close.
* \param flush true if data should sync to disk before the task completes.
* \param queue a queue to add the new SDL_AsyncIO to.
* \param userdata an app-defined pointer that will be provided with the task
* results.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread, but two
* threads should not attempt to close the same object.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_CloseAsyncIO(SDL_AsyncIO *asyncio, bool flush, SDL_AsyncIOQueue *queue, void *userdata);
/**
* Create a task queue for tracking multiple I/O operations.
*
* Async I/O operations are assigned to a queue when started. The queue can be
* checked for completed tasks thereafter.
*
* \returns a new task queue object or NULL if there was an error; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_DestroyAsyncIOQueue
* \sa SDL_GetAsyncIOResult
* \sa SDL_WaitAsyncIOResult
*/
extern SDL_DECLSPEC SDL_AsyncIOQueue * SDLCALL SDL_CreateAsyncIOQueue(void);
/**
* Destroy a previously-created async I/O task queue.
*
* If there are still tasks pending for this queue, this call will block until
* those tasks are finished. All those tasks will be deallocated. Their
* results will be lost to the app.
*
* Any pending reads from SDL_LoadFileAsync() that are still in this queue
* will have their buffers deallocated by this function, to prevent a memory
* leak.
*
* Once this function is called, the queue is no longer valid and should not
* be used, including by other threads that might access it while destruction
* is blocking on pending tasks.
*
* Do not destroy a queue that still has threads waiting on it through
* SDL_WaitAsyncIOResult(). You can call SDL_SignalAsyncIOQueue() first to
* unblock those threads, and take measures (such as SDL_WaitThread()) to make
* sure they have finished their wait and won't wait on the queue again.
*
* \param queue the task queue to destroy.
*
* \threadsafety It is safe to call this function from any thread, so long as
* no other thread is waiting on the queue with
* SDL_WaitAsyncIOResult.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC void SDLCALL SDL_DestroyAsyncIOQueue(SDL_AsyncIOQueue *queue);
/**
* Query an async I/O task queue for completed tasks.
*
* If a task assigned to this queue has finished, this will return true and
* fill in `outcome` with the details of the task. If no task in the queue has
* finished, this function will return false. This function does not block.
*
* If a task has completed, this function will free its resources and the task
* pointer will no longer be valid. The task will be removed from the queue.
*
* It is safe for multiple threads to call this function on the same queue at
* once; a completed task will only go to one of the threads.
*
* \param queue the async I/O task queue to query.
* \param outcome details of a finished task will be written here. May not be
* NULL.
* \returns true if a task has completed, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_WaitAsyncIOResult
*/
extern SDL_DECLSPEC bool SDLCALL SDL_GetAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome);
/**
* Block until an async I/O task queue has a completed task.
*
* This function puts the calling thread to sleep until there a task assigned
* to the queue that has finished.
*
* If a task assigned to the queue has finished, this will return true and
* fill in `outcome` with the details of the task. If no task in the queue has
* finished, this function will return false.
*
* If a task has completed, this function will free its resources and the task
* pointer will no longer be valid. The task will be removed from the queue.
*
* It is safe for multiple threads to call this function on the same queue at
* once; a completed task will only go to one of the threads.
*
* Note that by the nature of various platforms, more than one waiting thread
* may wake to handle a single task, but only one will obtain it, so
* `timeoutMS` is a _maximum_ wait time, and this function may return false
* sooner.
*
* This function may return false if there was a system error, the OS
* inadvertently awoke multiple threads, or if SDL_SignalAsyncIOQueue() was
* called to wake up all waiting threads without a finished task.
*
* A timeout can be used to specify a maximum wait time, but rather than
* polling, it is possible to have a timeout of -1 to wait forever, and use
* SDL_SignalAsyncIOQueue() to wake up the waiting threads later.
*
* \param queue the async I/O task queue to wait on.
* \param outcome details of a finished task will be written here. May not be
* NULL.
* \param timeoutMS the maximum time to wait, in milliseconds, or -1 to wait
* indefinitely.
* \returns true if task has completed, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SignalAsyncIOQueue
*/
extern SDL_DECLSPEC bool SDLCALL SDL_WaitAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome, Sint32 timeoutMS);
/**
* Wake up any threads that are blocking in SDL_WaitAsyncIOResult().
*
* This will unblock any threads that are sleeping in a call to
* SDL_WaitAsyncIOResult for the specified queue, and cause them to return
* from that function.
*
* This can be useful when destroying a queue to make sure nothing is touching
* it indefinitely. In this case, once this call completes, the caller should
* take measures to make sure any previously-blocked threads have returned
* from their wait and will not touch the queue again (perhaps by setting a
* flag to tell the threads to terminate and then using SDL_WaitThread() to
* make sure they've done so).
*
* \param queue the async I/O task queue to signal.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_WaitAsyncIOResult
*/
extern SDL_DECLSPEC void SDLCALL SDL_SignalAsyncIOQueue(SDL_AsyncIOQueue *queue);
/**
* Load all the data from a file path, asynchronously.
*
* This function returns as quickly as possible; it does not wait for the read
* to complete. On a successful return, this work will continue in the
* background. If the work begins, even failure is asynchronous: a failing
* return value from this function only means the work couldn't start at all.
*
* The data is allocated with a zero byte at the end (null terminated) for
* convenience. This extra byte is not included in SDL_AsyncIOOutcome's
* bytes_transferred value.
*
* This function will allocate the buffer to contain the file. It must be
* deallocated by calling SDL_free() on SDL_AsyncIOOutcome's buffer field
* after completion.
*
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
* to it when it completes its work.
*
* \param file the path to read all available data from.
* \param queue a queue to add the new SDL_AsyncIO to.
* \param userdata an app-defined pointer that will be provided with the task
* results.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_LoadFile_IO
*/
extern SDL_DECLSPEC bool SDLCALL SDL_LoadFileAsync(const char *file, SDL_AsyncIOQueue *queue, void *userdata);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_asyncio_h_ */
@@ -0,0 +1,682 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/**
* # CategoryAtomic
*
* Atomic operations.
*
* IMPORTANT: If you are not an expert in concurrent lockless programming, you
* should not be using any functions in this file. You should be protecting
* your data structures with full mutexes instead.
*
* ***Seriously, here be dragons!***
*
* You can find out a little more about lockless programming and the subtle
* issues that can arise here:
* https://learn.microsoft.com/en-us/windows/win32/dxtecharts/lockless-programming
*
* There's also lots of good information here:
*
* - https://www.1024cores.net/home/lock-free-algorithms
* - https://preshing.com/
*
* These operations may or may not actually be implemented using processor
* specific atomic operations. When possible they are implemented as true
* processor specific atomic operations. When that is not possible the are
* implemented using locks that *do* use the available atomic operations.
*
* All of the atomic operations that modify memory are full memory barriers.
*/
#ifndef SDL_atomic_h_
#define SDL_atomic_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_platform_defines.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* An atomic spinlock.
*
* The atomic locks are efficient spinlocks using CPU instructions, but are
* vulnerable to starvation and can spin forever if a thread holding a lock
* has been terminated. For this reason you should minimize the code executed
* inside an atomic lock and never do expensive things like API or system
* calls while holding them.
*
* They are also vulnerable to starvation if the thread holding the lock is
* lower priority than other threads and doesn't get scheduled. In general you
* should use mutexes instead, since they have better performance and
* contention behavior.
*
* The atomic locks are not safe to lock recursively.
*
* Porting Note: The spin lock functions and type are required and can not be
* emulated because they are used in the atomic emulation code.
*/
typedef int SDL_SpinLock;
/**
* Try to lock a spin lock by setting it to a non-zero value.
*
* ***Please note that spinlocks are dangerous if you don't know what you're
* doing. Please be careful using any sort of spinlock!***
*
* \param lock a pointer to a lock variable.
* \returns true if the lock succeeded, false if the lock is already held.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_LockSpinlock
* \sa SDL_UnlockSpinlock
*/
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockSpinlock(SDL_SpinLock *lock);
/**
* Lock a spin lock by setting it to a non-zero value.
*
* ***Please note that spinlocks are dangerous if you don't know what you're
* doing. Please be careful using any sort of spinlock!***
*
* \param lock a pointer to a lock variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_TryLockSpinlock
* \sa SDL_UnlockSpinlock
*/
extern SDL_DECLSPEC void SDLCALL SDL_LockSpinlock(SDL_SpinLock *lock);
/**
* Unlock a spin lock by setting it to 0.
*
* Always returns immediately.
*
* ***Please note that spinlocks are dangerous if you don't know what you're
* doing. Please be careful using any sort of spinlock!***
*
* \param lock a pointer to a lock variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_LockSpinlock
* \sa SDL_TryLockSpinlock
*/
extern SDL_DECLSPEC void SDLCALL SDL_UnlockSpinlock(SDL_SpinLock *lock);
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* Mark a compiler barrier.
*
* A compiler barrier prevents the compiler from reordering reads and writes
* to globally visible variables across the call.
*
* This macro only prevents the compiler from reordering reads and writes, it
* does not prevent the CPU from reordering reads and writes. However, all of
* the atomic operations that modify memory are full memory barriers.
*
* \threadsafety Obviously this macro is safe to use from any thread at any
* time, but if you find yourself needing this, you are probably
* dealing with some very sensitive code; be careful!
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_CompilerBarrier() DoCompilerSpecificReadWriteBarrier()
#elif defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__)
void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier)
#define SDL_CompilerBarrier() _ReadWriteBarrier()
#elif (defined(__GNUC__) && !defined(SDL_PLATFORM_EMSCRIPTEN)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory")
#elif defined(__WATCOMC__)
extern __inline void SDL_CompilerBarrier(void);
#pragma aux SDL_CompilerBarrier = "" parm [] modify exact [];
#else
#define SDL_CompilerBarrier() \
{ SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); }
#endif
/**
* Insert a memory release barrier (function version).
*
* Please refer to SDL_MemoryBarrierRelease for details. This is a function
* version, which might be useful if you need to use this functionality from a
* scripting language, etc. Also, some of the macro versions call this
* function behind the scenes, where more heavy lifting can happen inside of
* SDL. Generally, though, an app written in C/C++/etc should use the macro
* version, as it will be more efficient.
*
* \threadsafety Obviously this function is safe to use from any thread at any
* time, but if you find yourself needing this, you are probably
* dealing with some very sensitive code; be careful!
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_MemoryBarrierRelease
*/
extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void);
/**
* Insert a memory acquire barrier (function version).
*
* Please refer to SDL_MemoryBarrierRelease for details. This is a function
* version, which might be useful if you need to use this functionality from a
* scripting language, etc. Also, some of the macro versions call this
* function behind the scenes, where more heavy lifting can happen inside of
* SDL. Generally, though, an app written in C/C++/etc should use the macro
* version, as it will be more efficient.
*
* \threadsafety Obviously this function is safe to use from any thread at any
* time, but if you find yourself needing this, you are probably
* dealing with some very sensitive code; be careful!
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_MemoryBarrierAcquire
*/
extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void);
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* Insert a memory release barrier (macro version).
*
* Memory barriers are designed to prevent reads and writes from being
* reordered by the compiler and being seen out of order on multi-core CPUs.
*
* A typical pattern would be for thread A to write some data and a flag, and
* for thread B to read the flag and get the data. In this case you would
* insert a release barrier between writing the data and the flag,
* guaranteeing that the data write completes no later than the flag is
* written, and you would insert an acquire barrier between reading the flag
* and reading the data, to ensure that all the reads associated with the flag
* have completed.
*
* In this pattern you should always see a release barrier paired with an
* acquire barrier and you should gate the data reads/writes with a single
* flag variable.
*
* For more information on these semantics, take a look at the blog post:
* http://preshing.com/20120913/acquire-and-release-semantics
*
* This is the macro version of this functionality; if possible, SDL will use
* compiler intrinsics or inline assembly, but some platforms might need to
* call the function version of this, SDL_MemoryBarrierReleaseFunction to do
* the heavy lifting. Apps that can use the macro should favor it over the
* function.
*
* \threadsafety Obviously this macro is safe to use from any thread at any
* time, but if you find yourself needing this, you are probably
* dealing with some very sensitive code; be careful!
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_MemoryBarrierAcquire
* \sa SDL_MemoryBarrierReleaseFunction
*/
#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
/**
* Insert a memory acquire barrier (macro version).
*
* Please see SDL_MemoryBarrierRelease for the details on what memory barriers
* are and when to use them.
*
* This is the macro version of this functionality; if possible, SDL will use
* compiler intrinsics or inline assembly, but some platforms might need to
* call the function version of this, SDL_MemoryBarrierAcquireFunction, to do
* the heavy lifting. Apps that can use the macro should favor it over the
* function.
*
* \threadsafety Obviously this macro is safe to use from any thread at any
* time, but if you find yourself needing this, you are probably
* dealing with some very sensitive code; be careful!
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_MemoryBarrierRelease
* \sa SDL_MemoryBarrierAcquireFunction
*/
#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory")
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory")
#elif defined(__GNUC__) && defined(__aarch64__)
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
#elif defined(__GNUC__) && defined(__arm__)
#if 0 /* defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID) */
/* Information from:
https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19
The Linux kernel provides a helper function which provides the right code for a memory barrier,
hard-coded at address 0xffff0fa0
*/
typedef void (*SDL_KernelMemoryBarrierFunc)();
#define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
#define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
#else
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__)
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
#ifdef __thumb__
/* The mcr instruction isn't available in thumb mode, use real functions */
#define SDL_MEMORY_BARRIER_USES_FUNCTION
#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
#else
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
#endif /* __thumb__ */
#else
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory")
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory")
#endif /* SDL_PLATFORM_LINUX || SDL_PLATFORM_ANDROID */
#endif /* __GNUC__ && __arm__ */
#else
#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */
#include <mbarrier.h>
#define SDL_MemoryBarrierRelease() __machine_rel_barrier()
#define SDL_MemoryBarrierAcquire() __machine_acq_barrier()
#else
/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier()
#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier()
#endif
#endif
/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* A macro to insert a CPU-specific "pause" instruction into the program.
*
* This can be useful in busy-wait loops, as it serves as a hint to the CPU as
* to the program's intent; some CPUs can use this to do more efficient
* processing. On some platforms, this doesn't do anything, so using this
* macro might just be a harmless no-op.
*
* Note that if you are busy-waiting, there are often more-efficient
* approaches with other synchronization primitives: mutexes, semaphores,
* condition variables, etc.
*
* \threadsafety This macro is safe to use from any thread.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_CPUPauseInstruction() DoACPUPauseInACompilerAndArchitectureSpecificWay
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
#define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__)
#define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory")
#elif (defined(__powerpc__) || defined(__powerpc64__))
#define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27");
#elif (defined(__riscv) && __riscv_xlen == 64)
#define SDL_CPUPauseInstruction() __asm__ __volatile__(".insn i 0x0F, 0, x0, x0, 0x010");
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
#define SDL_CPUPauseInstruction() __yield()
#elif defined(__WATCOMC__) && defined(__386__)
extern __inline void SDL_CPUPauseInstruction(void);
#pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause"
#else
#define SDL_CPUPauseInstruction()
#endif
/**
* A type representing an atomic integer value.
*
* This can be used to manage a value that is synchronized across multiple
* CPUs without a race condition; when an app sets a value with
* SDL_SetAtomicInt all other threads, regardless of the CPU it is running on,
* will see that value when retrieved with SDL_GetAtomicInt, regardless of CPU
* caches, etc.
*
* This is also useful for atomic compare-and-swap operations: a thread can
* change the value as long as its current value matches expectations. When
* done in a loop, one can guarantee data consistency across threads without a
* lock (but the usual warnings apply: if you don't know what you're doing, or
* you don't do it carefully, you can confidently cause any number of
* disasters with this, so in most cases, you _should_ use a mutex instead of
* this!).
*
* This is a struct so people don't accidentally use numeric operations on it
* directly. You have to use SDL atomic functions.
*
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_CompareAndSwapAtomicInt
* \sa SDL_GetAtomicInt
* \sa SDL_SetAtomicInt
* \sa SDL_AddAtomicInt
*/
typedef struct SDL_AtomicInt { int value; } SDL_AtomicInt;
/**
* Set an atomic variable to a new value if it is currently an old value.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicInt variable to be modified.
* \param oldval the old value.
* \param newval the new value.
* \returns true if the atomic variable was set, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetAtomicInt
* \sa SDL_SetAtomicInt
*/
extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval);
/**
* Set an atomic variable to a value.
*
* This function also acts as a full memory barrier.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicInt variable to be modified.
* \param v the desired value.
* \returns the previous value of the atomic variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetAtomicInt
*/
extern SDL_DECLSPEC int SDLCALL SDL_SetAtomicInt(SDL_AtomicInt *a, int v);
/**
* Get the value of an atomic variable.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicInt variable.
* \returns the current value of an atomic variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetAtomicInt
*/
extern SDL_DECLSPEC int SDLCALL SDL_GetAtomicInt(SDL_AtomicInt *a);
/**
* Add to an atomic variable.
*
* This function also acts as a full memory barrier.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicInt variable to be modified.
* \param v the desired value to add.
* \returns the previous value of the atomic variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_AtomicDecRef
* \sa SDL_AtomicIncRef
*/
extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicInt(SDL_AtomicInt *a, int v);
#ifndef SDL_AtomicIncRef
/**
* Increment an atomic variable used as a reference count.
*
* ***Note: If you don't know what this macro is for, you shouldn't use it!***
*
* \param a a pointer to an SDL_AtomicInt to increment.
* \returns the previous value of the atomic variable.
*
* \threadsafety It is safe to call this macro from any thread.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_AtomicDecRef
*/
#define SDL_AtomicIncRef(a) SDL_AddAtomicInt(a, 1)
#endif
#ifndef SDL_AtomicDecRef
/**
* Decrement an atomic variable used as a reference count.
*
* ***Note: If you don't know what this macro is for, you shouldn't use it!***
*
* \param a a pointer to an SDL_AtomicInt to decrement.
* \returns true if the variable reached zero after decrementing, false
* otherwise.
*
* \threadsafety It is safe to call this macro from any thread.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_AtomicIncRef
*/
#define SDL_AtomicDecRef(a) (SDL_AddAtomicInt(a, -1) == 1)
#endif
/**
* A type representing an atomic unsigned 32-bit value.
*
* This can be used to manage a value that is synchronized across multiple
* CPUs without a race condition; when an app sets a value with
* SDL_SetAtomicU32 all other threads, regardless of the CPU it is running on,
* will see that value when retrieved with SDL_GetAtomicU32, regardless of CPU
* caches, etc.
*
* This is also useful for atomic compare-and-swap operations: a thread can
* change the value as long as its current value matches expectations. When
* done in a loop, one can guarantee data consistency across threads without a
* lock (but the usual warnings apply: if you don't know what you're doing, or
* you don't do it carefully, you can confidently cause any number of
* disasters with this, so in most cases, you _should_ use a mutex instead of
* this!).
*
* This is a struct so people don't accidentally use numeric operations on it
* directly. You have to use SDL atomic functions.
*
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_CompareAndSwapAtomicU32
* \sa SDL_GetAtomicU32
* \sa SDL_SetAtomicU32
*/
typedef struct SDL_AtomicU32 { Uint32 value; } SDL_AtomicU32;
/**
* Set an atomic variable to a new value if it is currently an old value.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicU32 variable to be modified.
* \param oldval the old value.
* \param newval the new value.
* \returns true if the atomic variable was set, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetAtomicU32
* \sa SDL_SetAtomicU32
*/
extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval);
/**
* Set an atomic variable to a value.
*
* This function also acts as a full memory barrier.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicU32 variable to be modified.
* \param v the desired value.
* \returns the previous value of the atomic variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetAtomicU32
*/
extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v);
/**
* Get the value of an atomic variable.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicU32 variable.
* \returns the current value of an atomic variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetAtomicU32
*/
extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32(SDL_AtomicU32 *a);
/**
* Add to an atomic variable.
*
* This function also acts as a full memory barrier.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to an SDL_AtomicU32 variable to be modified.
* \param v the desired value to add or subtract.
* \returns the previous value of the atomic variable.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*/
extern SDL_DECLSPEC Uint32 SDLCALL SDL_AddAtomicU32(SDL_AtomicU32 *a, int v);
/**
* Set a pointer to a new value if it is currently an old value.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to a pointer.
* \param oldval the old pointer value.
* \param newval the new pointer value.
* \returns true if the pointer was set, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CompareAndSwapAtomicInt
* \sa SDL_GetAtomicPointer
* \sa SDL_SetAtomicPointer
*/
extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval);
/**
* Set a pointer to a value atomically.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to a pointer.
* \param v the desired pointer value.
* \returns the previous value of the pointer.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CompareAndSwapAtomicPointer
* \sa SDL_GetAtomicPointer
*/
extern SDL_DECLSPEC void * SDLCALL SDL_SetAtomicPointer(void **a, void *v);
/**
* Get the value of a pointer atomically.
*
* ***Note: If you don't know what this function is for, you shouldn't use
* it!***
*
* \param a a pointer to a pointer.
* \returns the current value of a pointer.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CompareAndSwapAtomicPointer
* \sa SDL_SetAtomicPointer
*/
extern SDL_DECLSPEC void * SDLCALL SDL_GetAtomicPointer(void **a);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_atomic_h_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,553 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/* WIKI CATEGORY: BeginCode */
/**
* # CategoryBeginCode
*
* `SDL_begin_code.h` sets things up for C dynamic library function
* definitions, static inlined functions, and structures aligned at 4-byte
* alignment. If you don't like ugly C preprocessor code, don't look at this
* file. :)
*
* SDL's headers use this; applications generally should not include this
* header directly.
*/
/* This shouldn't be nested -- included it around code only. */
#ifdef SDL_begin_code_h
#error Nested inclusion of SDL_begin_code.h
#endif
#define SDL_begin_code_h
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* A macro to tag a symbol as deprecated.
*
* A function is marked deprecated by adding this macro to its declaration:
*
* ```c
* extern SDL_DEPRECATED int ThisFunctionWasABadIdea(void);
* ```
*
* Compilers with deprecation support can give a warning when a deprecated
* function is used. This symbol may be used in SDL's headers, but apps are
* welcome to use it for their own interfaces as well.
*
* SDL, on occasion, might deprecate a function for various reasons. However,
* SDL never removes symbols before major versions, so deprecated interfaces
* in SDL3 will remain available until SDL4, where it would be expected an app
* would have to take steps to migrate anyhow.
*
* On compilers without a deprecation mechanism, this is defined to nothing,
* and using a deprecated function will not generate a warning.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_DEPRECATED __attribute__((deprecated))
/**
* A macro to tag a symbol as a public API.
*
* SDL uses this macro for all its public functions. On some targets, it is
* used to signal to the compiler that this function needs to be exported from
* a shared library, but it might have other side effects.
*
* This symbol is used in SDL's headers, but apps and other libraries are
* welcome to use it for their own interfaces as well.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_DECLSPEC __attribute__ ((visibility("default")))
/**
* A macro to set a function's calling conventions.
*
* SDL uses this macro for all its public functions, and any callbacks it
* defines. This macro guarantees that calling conventions match between SDL
* and the app, even if the two were built with different compilers or
* optimization settings.
*
* When writing a callback function, it is very important for it to be
* correctly tagged with SDLCALL, as mismatched calling conventions can cause
* strange behaviors and can be difficult to diagnose. Plus, on many
* platforms, SDLCALL is defined to nothing, so compilers won't be able to
* warn that the tag is missing.
*
* This symbol is used in SDL's headers, but apps and other libraries are
* welcome to use it for their own interfaces as well.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDLCALL __cdecl
/**
* A macro to request a function be inlined.
*
* This is a hint to the compiler to inline a function. The compiler is free
* to ignore this request. On compilers without inline support, this is
* defined to nothing.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_INLINE __inline
/**
* A macro to demand a function be inlined.
*
* This is a command to the compiler to inline a function. SDL uses this macro
* in its public headers for a handful of simple functions. On compilers
* without forceinline support, this is defined to `static SDL_INLINE`, which
* is often good enough.
*
* This symbol is used in SDL's headers, but apps and other libraries are
* welcome to use it for their own interfaces as well.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_FORCE_INLINE __forceinline
/**
* A macro to tag a function as never-returning.
*
* This is a hint to the compiler that a function does not return. An example
* of a function like this is the C runtime's exit() function.
*
* This hint can lead to code optimizations, and help analyzers understand
* code flow better. On compilers without noreturn support, this is defined to
* nothing.
*
* This symbol is used in SDL's headers, but apps and other libraries are
* welcome to use it for their own interfaces as well.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_NORETURN __attribute__((noreturn))
/**
* A macro to tag a function as never-returning (for analysis purposes).
*
* This is almost identical to SDL_NORETURN, except functions marked with this
* _can_ actually return. The difference is that this isn't used for code
* generation, but rather static analyzers use this information to assume
* truths about program state and available code paths. Specifically, this tag
* is useful for writing an assertion mechanism. Indeed, SDL_assert uses this
* tag behind the scenes. Generally, apps that don't understand the specific
* use-case for this tag should avoid using it directly.
*
* On compilers without analyzer_noreturn support, this is defined to nothing.
*
* This symbol is used in SDL's headers, but apps and other libraries are
* welcome to use it for their own interfaces as well.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
/**
* A macro to signal that a case statement without a `break` is intentional.
*
* C compilers have gotten more aggressive about warning when a switch's
* `case` block does not end with a `break` or other flow control statement,
* flowing into the next case's code, as this is a common accident that leads
* to strange bugs. But sometimes falling through to the next case is the
* correct and desired behavior. This symbol lets an app communicate this
* intention to the compiler, so it doesn't generate a warning.
*
* It is used like this:
*
* ```c
* switch (x) {
* case 1:
* DoSomethingOnlyForOne();
* SDL_FALLTHROUGH; // tell the compiler this was intentional.
* case 2:
* DoSomethingForOneAndTwo();
* break;
* }
* ```
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_FALLTHROUGH [[fallthrough]]
/**
* A macro to tag a function's return value as critical.
*
* This is a hint to the compiler that a function's return value should not be
* ignored.
*
* If an NODISCARD function's return value is thrown away (the function is
* called as if it returns `void`), the compiler will issue a warning.
*
* While it's generally good practice to check return values for errors, often
* times legitimate programs do not for good reasons. Be careful about what
* functions are tagged as NODISCARD. It operates best when used on a function
* that's failure is surprising and catastrophic; a good example would be a
* program that checks the return values of all its file write function calls
* but not the call to close the file, which it assumes incorrectly never
* fails.
*
* Function callers that want to throw away a NODISCARD return value can call
* the function with a `(void)` cast, which informs the compiler the act is
* intentional.
*
* On compilers without nodiscard support, this is defined to nothing.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_NODISCARD [[nodiscard]]
/**
* A macro to tag a function as an allocator.
*
* This is a hint to the compiler that a function is an allocator, like
* malloc(), with certain rules. A description of how GCC treats this hint is
* here:
*
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
*
* On compilers without allocator tag support, this is defined to nothing.
*
* Most apps don't need to, and should not, use this directly.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
/**
* A macro to tag a function as returning a certain allocation.
*
* This is a hint to the compiler that a function allocates and returns a
* specific amount of memory based on one of its arguments. For example, the C
* runtime's malloc() function could use this macro with an argument of 1
* (first argument to malloc is the size of the allocation).
*
* On compilers without alloc_size support, this is defined to nothing.
*
* Most apps don't need to, and should not, use this directly.
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
/**
* A macro to tag a pointer variable, to help with pointer aliasing.
*
* A good explanation of the restrict keyword is here:
*
* https://en.wikipedia.org/wiki/Restrict
*
* On compilers without restrict support, this is defined to nothing.
*
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_RESTRICT __restrict
/**
* Check if the compiler supports a given builtin functionality.
*
* This allows preprocessor checks for things that otherwise might fail to
* compile.
*
* Supported by virtually all clang versions and more-recent GCCs. Use this
* instead of checking the clang version if possible.
*
* On compilers without has_builtin support, this is defined to 0 (always
* false).
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_HAS_BUILTIN(x) __has_builtin(x)
/**
* A macro to specify data alignment.
*
* This informs the compiler that a given datatype or variable must be aligned
* to a specific byte count.
*
* For example:
*
* ```c
* // make sure this is struct is aligned to 16 bytes for SIMD access.
* typedef struct {
* float x, y, z, w;
* } SDL_ALIGNED(16) MySIMDAlignedData;
*
* // make sure this one field in a struct is aligned to 16 bytes for SIMD access.
* typedef struct {
* SomeStuff stuff;
* float SDL_ALIGNED(16) position[4];
* SomeOtherStuff other_stuff;
* } MyStruct;
*
* // make sure this variable is aligned to 32 bytes.
* int SDL_ALIGNED(32) myval = 0;
* ```
*
* Alignment is only guaranteed for things the compiler places: local
* variables on the stack and global/static variables. To dynamically allocate
* something that respects this alignment, use SDL_aligned_alloc() or some
* other mechanism.
*
* On compilers without alignment support, this macro is defined to an invalid
* symbol, to make it clear that the current compiler is likely to generate
* incorrect code when it sees this macro.
*
* \param x the byte count to align to, so the data's address will be a
* multiple of this value.
*
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_ALIGNED(x) __attribute__((aligned(x)))
/* end of wiki documentation section. */
#endif
/* `restrict` is from C99, but __restrict works with both Visual Studio and GCC. */
#ifndef SDL_RESTRICT
# if defined(restrict) || ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)))
# define SDL_RESTRICT restrict
# elif defined(_MSC_VER) || defined(__GNUC__) || defined(__clang__)
# define SDL_RESTRICT __restrict
# else
# define SDL_RESTRICT
# endif
#endif
#ifndef SDL_HAS_BUILTIN
#ifdef __has_builtin
#define SDL_HAS_BUILTIN(x) __has_builtin(x)
#else
#define SDL_HAS_BUILTIN(x) 0
#endif
#endif
#ifndef SDL_DEPRECATED
# if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
# define SDL_DEPRECATED __attribute__((deprecated))
# elif defined(_MSC_VER)
# define SDL_DEPRECATED __declspec(deprecated)
# else
# define SDL_DEPRECATED
# endif
#endif
#ifndef SDL_UNUSED
# ifdef __GNUC__
# define SDL_UNUSED __attribute__((unused))
# else
# define SDL_UNUSED
# endif
#endif
/* Some compilers use a special export keyword */
#ifndef SDL_DECLSPEC
# if defined(SDL_PLATFORM_WINDOWS)
# ifdef DLL_EXPORT
# define SDL_DECLSPEC __declspec(dllexport)
# else
# define SDL_DECLSPEC
# endif
# else
# if defined(__GNUC__) && __GNUC__ >= 4
# define SDL_DECLSPEC __attribute__ ((visibility("default")))
# else
# define SDL_DECLSPEC
# endif
# endif
#endif
/* By default SDL uses the C calling convention */
#ifndef SDLCALL
#if defined(SDL_PLATFORM_WINDOWS) && !defined(__GNUC__)
#define SDLCALL __cdecl
#else
#define SDLCALL
#endif
#endif /* SDLCALL */
/* Force structure packing at 4 byte alignment.
This is necessary if the header is included in code which has structure
packing set to an alternate value, say for loading structures from disk.
The packing is reset to the previous value in SDL_close_code.h
*/
#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
#ifdef _MSC_VER
#pragma warning(disable: 4103)
#endif
#ifdef __clang__
#pragma clang diagnostic ignored "-Wpragma-pack"
#endif
#ifdef __BORLANDC__
#pragma nopackwarning
#endif
#ifdef _WIN64
/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
#pragma pack(push,8)
#else
#pragma pack(push,4)
#endif
#endif /* Compiler needs structure packing set */
#ifndef SDL_INLINE
#ifdef __GNUC__
#define SDL_INLINE __inline__
#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
defined(__DMC__) || defined(__SC__) || \
defined(__WATCOMC__) || defined(__LCC__) || \
defined(__DECC) || defined(__CC_ARM)
#define SDL_INLINE __inline
#ifndef __inline__
#define __inline__ __inline
#endif
#else
#define SDL_INLINE inline
#ifndef __inline__
#define __inline__ inline
#endif
#endif
#endif /* SDL_INLINE not defined */
#ifndef SDL_FORCE_INLINE
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
#define SDL_FORCE_INLINE __forceinline
#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
#else
#define SDL_FORCE_INLINE static SDL_INLINE
#endif
#endif /* SDL_FORCE_INLINE not defined */
#ifndef SDL_NORETURN
#if defined(__GNUC__)
#define SDL_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define SDL_NORETURN __declspec(noreturn)
#else
#define SDL_NORETURN
#endif
#endif /* SDL_NORETURN not defined */
#ifdef __clang__
#if __has_feature(attribute_analyzer_noreturn)
#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
#endif
#endif
#ifndef SDL_ANALYZER_NORETURN
#define SDL_ANALYZER_NORETURN
#endif
/* Apparently this is needed by several Windows compilers */
#ifndef __MACH__
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif /* NULL */
#endif /* ! macOS - breaks precompiled headers */
#ifndef SDL_FALLTHROUGH
#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L)
#define SDL_FALLTHROUGH [[fallthrough]]
#else
#if defined(__has_attribute) && !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__)
#else
#define SDL_HAS_FALLTHROUGH 0
#endif /* __has_attribute */
#if SDL_HAS_FALLTHROUGH && \
((defined(__GNUC__) && __GNUC__ >= 7) || \
(defined(__clang_major__) && __clang_major__ >= 10))
#define SDL_FALLTHROUGH __attribute__((__fallthrough__))
#else
#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */
#endif /* SDL_HAS_FALLTHROUGH */
#undef SDL_HAS_FALLTHROUGH
#endif /* C++17 or C2x */
#endif /* SDL_FALLTHROUGH not defined */
#ifndef SDL_NODISCARD
#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
#define SDL_NODISCARD [[nodiscard]]
#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
#define SDL_NODISCARD __attribute__((warn_unused_result))
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
#define SDL_NODISCARD _Check_return_
#else
#define SDL_NODISCARD
#endif /* C++17 or C23 */
#endif /* SDL_NODISCARD not defined */
#ifndef SDL_MALLOC
#if defined(__GNUC__) && (__GNUC__ >= 3)
#define SDL_MALLOC __attribute__((malloc))
/** FIXME
#elif defined(_MSC_VER)
#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
**/
#else
#define SDL_MALLOC
#endif
#endif /* SDL_MALLOC not defined */
#ifndef SDL_ALLOC_SIZE
#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
#elif defined(_MSC_VER)
#define SDL_ALLOC_SIZE(p)
#else
#define SDL_ALLOC_SIZE(p)
#endif
#endif /* SDL_ALLOC_SIZE not defined */
#ifndef SDL_ALLOC_SIZE2
#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
#define SDL_ALLOC_SIZE2(p1, p2) __attribute__((alloc_size(p1, p2)))
#elif defined(_MSC_VER)
#define SDL_ALLOC_SIZE2(p1, p2)
#else
#define SDL_ALLOC_SIZE2(p1, p2)
#endif
#endif /* SDL_ALLOC_SIZE2 not defined */
#ifndef SDL_ALIGNED
#if defined(__clang__) || defined(__GNUC__)
#define SDL_ALIGNED(x) __attribute__((aligned(x)))
#elif defined(_MSC_VER)
#define SDL_ALIGNED(x) __declspec(align(x))
#elif defined(__cplusplus) && (__cplusplus >= 201103L)
#define SDL_ALIGNED(x) alignas(x)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
#define SDL_ALIGNED(x) _Alignas(x)
#else
#define SDL_ALIGNED(x) PLEASE_DEFINE_SDL_ALIGNED
#endif
#endif /* SDL_ALIGNED not defined */
@@ -0,0 +1,147 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/**
* # CategoryBits
*
* Functions for fiddling with bits and bitmasks.
*/
#ifndef SDL_bits_h_
#define SDL_bits_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__WATCOMC__) && defined(__386__)
extern __inline int _SDL_bsr_watcom(Uint32);
#pragma aux _SDL_bsr_watcom = \
"bsr eax, eax" \
parm [eax] nomemory \
value [eax] \
modify exact [eax] nomemory;
#endif
/**
* Get the index of the most significant (set) bit in a 32-bit number.
*
* Result is undefined when called with 0. This operation can also be stated
* as "count leading zeroes" and "log base 2".
*
* Note that this is a forced-inline function in a header, and not a public
* API function available in the SDL library (which is to say, the code is
* embedded in the calling program and the linker and dynamic loader will not
* be able to find this function inside SDL itself).
*
* \param x the 32-bit value to examine.
* \returns the index of the most significant bit, or -1 if the value is 0.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*/
SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x)
{
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
/* Count Leading Zeroes builtin in GCC.
* http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html
*/
if (x == 0) {
return -1;
}
return 31 - __builtin_clz(x);
#elif defined(__WATCOMC__) && defined(__386__)
if (x == 0) {
return -1;
}
return _SDL_bsr_watcom(x);
#elif defined(_MSC_VER) && _MSC_VER >= 1400
unsigned long index;
if (_BitScanReverse(&index, x)) {
return (int)index;
}
return -1;
#else
/* Based off of Bit Twiddling Hacks by Sean Eron Anderson
* <seander@cs.stanford.edu>, released in the public domain.
* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
*/
const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
const int S[] = {1, 2, 4, 8, 16};
int msbIndex = 0;
int i;
if (x == 0) {
return -1;
}
for (i = 4; i >= 0; i--)
{
if (x & b[i])
{
x >>= S[i];
msbIndex |= S[i];
}
}
return msbIndex;
#endif
}
/**
* Determine if a unsigned 32-bit value has exactly one bit set.
*
* If there are no bits set (`x` is zero), or more than one bit set, this
* returns false. If any one bit is exclusively set, this returns true.
*
* Note that this is a forced-inline function in a header, and not a public
* API function available in the SDL library (which is to say, the code is
* embedded in the calling program and the linker and dynamic loader will not
* be able to find this function inside SDL itself).
*
* \param x the 32-bit value to examine.
* \returns true if exactly one bit is set in `x`, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*/
SDL_FORCE_INLINE bool SDL_HasExactlyOneBitSet32(Uint32 x)
{
if (x && !(x & (x - 1))) {
return true;
}
return false;
}
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_bits_h_ */
@@ -0,0 +1,202 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/**
* # CategoryBlendmode
*
* Blend modes decide how two colors will mix together. There are both
* standard modes for basic needs and a means to create custom modes,
* dictating what sort of math to do on what color components.
*/
#ifndef SDL_blendmode_h_
#define SDL_blendmode_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* A set of blend modes used in drawing operations.
*
* These predefined blend modes are supported everywhere.
*
* Additional values may be obtained from SDL_ComposeCustomBlendMode.
*
* \since This datatype is available since SDL 3.2.0.
*
* \sa SDL_ComposeCustomBlendMode
*/
typedef Uint32 SDL_BlendMode;
#define SDL_BLENDMODE_NONE 0x00000000u /**< no blending: dstRGBA = srcRGBA */
#define SDL_BLENDMODE_BLEND 0x00000001u /**< alpha blending: dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)), dstA = srcA + (dstA * (1-srcA)) */
#define SDL_BLENDMODE_BLEND_PREMULTIPLIED 0x00000010u /**< pre-multiplied alpha blending: dstRGBA = srcRGBA + (dstRGBA * (1-srcA)) */
#define SDL_BLENDMODE_ADD 0x00000002u /**< additive blending: dstRGB = (srcRGB * srcA) + dstRGB, dstA = dstA */
#define SDL_BLENDMODE_ADD_PREMULTIPLIED 0x00000020u /**< pre-multiplied additive blending: dstRGB = srcRGB + dstRGB, dstA = dstA */
#define SDL_BLENDMODE_MOD 0x00000004u /**< color modulate: dstRGB = srcRGB * dstRGB, dstA = dstA */
#define SDL_BLENDMODE_MUL 0x00000008u /**< color multiply: dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)), dstA = dstA */
#define SDL_BLENDMODE_INVALID 0x7FFFFFFFu
/**
* The blend operation used when combining source and destination pixel
* components.
*
* \since This enum is available since SDL 3.2.0.
*/
typedef enum SDL_BlendOperation
{
SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */
SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< src - dst : supported by D3D, OpenGL, OpenGLES, and Vulkan */
SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< dst - src : supported by D3D, OpenGL, OpenGLES, and Vulkan */
SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
} SDL_BlendOperation;
/**
* The normalized factor used to multiply pixel components.
*
* The blend factors are multiplied with the pixels from a drawing operation
* (src) and the pixels from the render target (dst) before the blend
* operation. The comma-separated factors listed above are always applied in
* the component order red, green, blue, and alpha.
*
* \since This enum is available since SDL 3.2.0.
*/
typedef enum SDL_BlendFactor
{
SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */
SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */
SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */
SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */
SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */
SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */
SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */
} SDL_BlendFactor;
/**
* Compose a custom blend mode for renderers.
*
* The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept
* the SDL_BlendMode returned by this function if the renderer supports it.
*
* A blend mode controls how the pixels from a drawing operation (source) get
* combined with the pixels from the render target (destination). First, the
* components of the source and destination pixels get multiplied with their
* blend factors. Then, the blend operation takes the two products and
* calculates the result that will get stored in the render target.
*
* Expressed in pseudocode, it would look like this:
*
* ```c
* dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor);
* dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor);
* ```
*
* Where the functions `colorOperation(src, dst)` and `alphaOperation(src,
* dst)` can return one of the following:
*
* - `src + dst`
* - `src - dst`
* - `dst - src`
* - `min(src, dst)`
* - `max(src, dst)`
*
* The red, green, and blue components are always multiplied with the first,
* second, and third components of the SDL_BlendFactor, respectively. The
* fourth component is not used.
*
* The alpha component is always multiplied with the fourth component of the
* SDL_BlendFactor. The other components are not used in the alpha
* calculation.
*
* Support for these blend modes varies for each renderer. To check if a
* specific SDL_BlendMode is supported, create a renderer and pass it to
* either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will
* return with an error if the blend mode is not supported.
*
* This list describes the support of custom blend modes for each renderer.
* All renderers support the four blend modes listed in the SDL_BlendMode
* enumeration.
*
* - **direct3d**: Supports all operations with all factors. However, some
* factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and
* `SDL_BLENDOPERATION_MAXIMUM`.
* - **direct3d11**: Same as Direct3D 9.
* - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all
* factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly here.
* - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`,
* `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT`
* operations with all factors.
* - **psp**: No custom blend mode support.
* - **software**: No custom blend mode support.
*
* Some renderers do not provide an alpha component for the default render
* target. The `SDL_BLENDFACTOR_DST_ALPHA` and
* `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this
* case.
*
* \param srcColorFactor the SDL_BlendFactor applied to the red, green, and
* blue components of the source pixels.
* \param dstColorFactor the SDL_BlendFactor applied to the red, green, and
* blue components of the destination pixels.
* \param colorOperation the SDL_BlendOperation used to combine the red,
* green, and blue components of the source and
* destination pixels.
* \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of
* the source pixels.
* \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of
* the destination pixels.
* \param alphaOperation the SDL_BlendOperation used to combine the alpha
* component of the source and destination pixels.
* \returns an SDL_BlendMode that represents the chosen factors and
* operations.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetRenderDrawBlendMode
* \sa SDL_GetRenderDrawBlendMode
* \sa SDL_SetTextureBlendMode
* \sa SDL_GetTextureBlendMode
*/
extern SDL_DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor,
SDL_BlendFactor dstColorFactor,
SDL_BlendOperation colorOperation,
SDL_BlendFactor srcAlphaFactor,
SDL_BlendFactor dstAlphaFactor,
SDL_BlendOperation alphaOperation);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_blendmode_h_ */
@@ -0,0 +1,535 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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.
*/
/**
* # CategoryCamera
*
* Video capture for the SDL library.
*
* This API lets apps read input from video sources, like webcams. Camera
* devices can be enumerated, queried, and opened. Once opened, it will
* provide SDL_Surface objects as new frames of video come in. These surfaces
* can be uploaded to an SDL_Texture or processed as pixels in memory.
*
* Several platforms will alert the user if an app tries to access a camera,
* and some will present a UI asking the user if your application should be
* allowed to obtain images at all, which they can deny. A successfully opened
* camera will not provide images until permission is granted. Applications,
* after opening a camera device, can see if they were granted access by
* either polling with the SDL_GetCameraPermissionState() function, or waiting
* for an SDL_EVENT_CAMERA_DEVICE_APPROVED or SDL_EVENT_CAMERA_DEVICE_DENIED
* event. Platforms that don't have any user approval process will report
* approval immediately.
*
* Note that SDL cameras only provide video as individual frames; they will
* not provide full-motion video encoded in a movie file format, although an
* app is free to encode the acquired frames into any format it likes. It also
* does not provide audio from the camera hardware through this API; not only
* do many webcams not have microphones at all, many people--from streamers to
* people on Zoom calls--will want to use a separate microphone regardless of
* the camera. In any case, recorded audio will be available through SDL's
* audio API no matter what hardware provides the microphone.
*
* ## Camera gotchas
*
* Consumer-level camera hardware tends to take a little while to warm up,
* once the device has been opened. Generally most camera apps have some sort
* of UI to take a picture (a button to snap a pic while a preview is showing,
* some sort of multi-second countdown for the user to pose, like a photo
* booth), which puts control in the users' hands, or they are intended to
* stay on for long times (Pokemon Go, etc).
*
* It's not uncommon that a newly-opened camera will provide a couple of
* completely black frames, maybe followed by some under-exposed images. If
* taking a single frame automatically, or recording video from a camera's
* input without the user initiating it from a preview, it could be wise to
* drop the first several frames (if not the first several _seconds_ worth of
* frames!) before using images from a camera.
*/
#ifndef SDL_camera_h_
#define SDL_camera_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_error.h>
#include <SDL3/SDL_pixels.h>
#include <SDL3/SDL_properties.h>
#include <SDL3/SDL_surface.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* This is a unique ID for a camera device for the time it is connected to the
* system, and is never reused for the lifetime of the application.
*
* If the device is disconnected and reconnected, it will get a new ID.
*
* The value 0 is an invalid ID.
*
* \since This datatype is available since SDL 3.2.0.
*
* \sa SDL_GetCameras
*/
typedef Uint32 SDL_CameraID;
/**
* The opaque structure used to identify an opened SDL camera.
*
* \since This struct is available since SDL 3.2.0.
*/
typedef struct SDL_Camera SDL_Camera;
/**
* The details of an output format for a camera device.
*
* Cameras often support multiple formats; each one will be encapsulated in
* this struct.
*
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_GetCameraSupportedFormats
* \sa SDL_GetCameraFormat
*/
typedef struct SDL_CameraSpec
{
SDL_PixelFormat format; /**< Frame format */
SDL_Colorspace colorspace; /**< Frame colorspace */
int width; /**< Frame width */
int height; /**< Frame height */
int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
int framerate_denominator; /**< Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds) */
} SDL_CameraSpec;
/**
* The position of camera in relation to system device.
*
* \since This enum is available since SDL 3.2.0.
*
* \sa SDL_GetCameraPosition
*/
typedef enum SDL_CameraPosition
{
SDL_CAMERA_POSITION_UNKNOWN,
SDL_CAMERA_POSITION_FRONT_FACING,
SDL_CAMERA_POSITION_BACK_FACING
} SDL_CameraPosition;
/**
* The current state of a request for camera access.
*
* \since This enum is available since SDL 3.4.0.
*
* \sa SDL_GetCameraPermissionState
*/
typedef enum SDL_CameraPermissionState
{
SDL_CAMERA_PERMISSION_STATE_DENIED = -1,
SDL_CAMERA_PERMISSION_STATE_PENDING,
SDL_CAMERA_PERMISSION_STATE_APPROVED,
} SDL_CameraPermissionState;
/**
* Use this function to get the number of built-in camera drivers.
*
* This function returns a hardcoded number. This never returns a negative
* value; if there are no drivers compiled into this build of SDL, this
* function returns zero. The presence of a driver in this list does not mean
* it will function, it just means SDL is capable of interacting with that
* interface. For example, a build of SDL might have v4l2 support, but if
* there's no kernel support available, SDL's v4l2 driver would fail if used.
*
* By default, SDL tries all drivers, in its preferred order, until one is
* found to be usable.
*
* \returns the number of built-in camera drivers.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetCameraDriver
*/
extern SDL_DECLSPEC int SDLCALL SDL_GetNumCameraDrivers(void);
/**
* Use this function to get the name of a built in camera driver.
*
* The list of camera drivers is given in the order that they are normally
* initialized by default; the drivers that seem more reasonable to choose
* first (as far as the SDL developers believe) are earlier in the list.
*
* The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
* "coremedia" or "android". These never have Unicode characters, and are not
* meant to be proper names.
*
* \param index the index of the camera driver; the value ranges from 0 to
* SDL_GetNumCameraDrivers() - 1.
* \returns the name of the camera driver at the requested index, or NULL if
* an invalid index was specified.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetNumCameraDrivers
*/
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraDriver(int index);
/**
* Get the name of the current camera driver.
*
* The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
* "coremedia" or "android". These never have Unicode characters, and are not
* meant to be proper names.
*
* \returns the name of the current camera driver or NULL if no driver has
* been initialized.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCurrentCameraDriver(void);
/**
* Get a list of currently connected camera devices.
*
* \param count a pointer filled in with the number of cameras returned, may
* be NULL.
* \returns a 0 terminated array of camera instance IDs or NULL on failure;
* call SDL_GetError() for more information. This should be freed
* with SDL_free() when it is no longer needed.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_OpenCamera
*/
extern SDL_DECLSPEC SDL_CameraID * SDLCALL SDL_GetCameras(int *count);
/**
* Get the list of native formats/sizes a camera supports.
*
* This returns a list of all formats and frame sizes that a specific camera
* can offer. This is useful if your app can accept a variety of image formats
* and sizes and so want to find the optimal spec that doesn't require
* conversion.
*
* This function isn't strictly required; if you call SDL_OpenCamera with a
* NULL spec, SDL will choose a native format for you, and if you instead
* specify a desired format, it will transparently convert to the requested
* format on your behalf.
*
* If `count` is not NULL, it will be filled with the number of elements in
* the returned array.
*
* Note that it's legal for a camera to supply an empty list. This is what
* will happen on Emscripten builds, since that platform won't tell _anything_
* about available cameras until you've opened one, and won't even tell if
* there _is_ a camera until the user has given you permission to check
* through a scary warning popup.
*
* \param instance_id the camera device instance ID.
* \param count a pointer filled in with the number of elements in the list,
* may be NULL.
* \returns a NULL terminated array of pointers to SDL_CameraSpec or NULL on
* failure; call SDL_GetError() for more information. This is a
* single allocation that should be freed with SDL_free() when it is
* no longer needed.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetCameras
* \sa SDL_OpenCamera
*/
extern SDL_DECLSPEC SDL_CameraSpec ** SDLCALL SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int *count);
/**
* Get the human-readable device name for a camera.
*
* \param instance_id the camera device instance ID.
* \returns a human-readable device name or NULL on failure; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetCameras
*/
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraName(SDL_CameraID instance_id);
/**
* Get the position of the camera in relation to the system.
*
* Most platforms will report UNKNOWN, but mobile devices, like phones, can
* often make a distinction between cameras on the front of the device (that
* points towards the user, for taking "selfies") and cameras on the back (for
* filming in the direction the user is facing).
*
* \param instance_id the camera device instance ID.
* \returns the position of the camera on the system hardware.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetCameras
*/
extern SDL_DECLSPEC SDL_CameraPosition SDLCALL SDL_GetCameraPosition(SDL_CameraID instance_id);
/**
* Open a video recording device (a "camera").
*
* You can open the device with any reasonable spec, and if the hardware can't
* directly support it, it will convert data seamlessly to the requested
* format. This might incur overhead, including scaling of image data.
*
* If you would rather accept whatever format the device offers, you can pass
* a NULL spec here and it will choose one for you (and you can use
* SDL_Surface's conversion/scaling functions directly if necessary).
*
* You can call SDL_GetCameraFormat() to get the actual data format if passing
* a NULL spec here. You can see the exact specs a device can support without
* conversion with SDL_GetCameraSupportedFormats().
*
* SDL will not attempt to emulate framerate; it will try to set the hardware
* to the rate closest to the requested speed, but it won't attempt to limit
* or duplicate frames artificially; call SDL_GetCameraFormat() to see the
* actual framerate of the opened the device, and check your timestamps if
* this is crucial to your app!
*
* Note that the camera is not usable until the user approves its use! On some
* platforms, the operating system will prompt the user to permit access to
* the camera, and they can choose Yes or No at that point. Until they do, the
* camera will not be usable. The app should either wait for an
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
* or poll SDL_GetCameraPermissionState() occasionally until it returns
* non-zero. On platforms that don't require explicit user approval (and
* perhaps in places where the user previously permitted access), the approval
* event might come immediately, but it might come seconds, minutes, or hours
* later!
*
* \param instance_id the camera device instance ID.
* \param spec the desired format for data the device will provide. Can be
* NULL.
* \returns an SDL_Camera object or NULL on failure; call SDL_GetError() for
* more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetCameras
* \sa SDL_GetCameraFormat
*/
extern SDL_DECLSPEC SDL_Camera * SDLCALL SDL_OpenCamera(SDL_CameraID instance_id, const SDL_CameraSpec *spec);
/**
* Query if camera access has been approved by the user.
*
* Cameras will not function between when the device is opened by the app and
* when the user permits access to the hardware. On some platforms, this
* presents as a popup dialog where the user has to explicitly approve access;
* on others the approval might be implicit and not alert the user at all.
*
* This function can be used to check the status of that approval. It will
* return SDL_CAMERA_PERMISSION_STATE_PENDING if waiting for user response,
* SDL_CAMERA_PERMISSION_STATE_APPROVED if the camera is approved for use, and
* SDL_CAMERA_PERMISSION_STATE_DENIED if the user denied access.
*
* Instead of polling with this function, you can wait for a
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event
* in the standard SDL event loop, which is guaranteed to be sent once when
* permission to use the camera is decided.
*
* If a camera is declined, there's nothing to be done but call
* SDL_CloseCamera() to dispose of it.
*
* \param camera the opened camera device to query.
* \returns an SDL_CameraPermissionState value indicating if access is
* granted, or `SDL_CAMERA_PERMISSION_STATE_PENDING` if the decision
* is still pending.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_OpenCamera
* \sa SDL_CloseCamera
*/
extern SDL_DECLSPEC SDL_CameraPermissionState SDLCALL SDL_GetCameraPermissionState(SDL_Camera *camera);
/**
* Get the instance ID of an opened camera.
*
* \param camera an SDL_Camera to query.
* \returns the instance ID of the specified camera on success or 0 on
* failure; call SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_OpenCamera
*/
extern SDL_DECLSPEC SDL_CameraID SDLCALL SDL_GetCameraID(SDL_Camera *camera);
/**
* Get the properties associated with an opened camera.
*
* \param camera the SDL_Camera obtained from SDL_OpenCamera().
* \returns a valid property ID on success or 0 on failure; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetCameraProperties(SDL_Camera *camera);
/**
* Get the spec that a camera is using when generating images.
*
* Note that this might not be the native format of the hardware, as SDL might
* be converting to this format behind the scenes.
*
* If the system is waiting for the user to approve access to the camera, as
* some platforms require, this will return false, but this isn't necessarily
* a fatal error; you should either wait for an
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
* or poll SDL_GetCameraPermissionState() occasionally until it returns
* non-zero.
*
* \param camera opened camera device.
* \param spec the SDL_CameraSpec to be initialized by this function.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_OpenCamera
*/
extern SDL_DECLSPEC bool SDLCALL SDL_GetCameraFormat(SDL_Camera *camera, SDL_CameraSpec *spec);
/**
* Acquire a frame.
*
* The frame is a memory pointer to the image data, whose size and format are
* given by the spec requested when opening the device.
*
* This is a non blocking API. If there is a frame available, a non-NULL
* surface is returned, and timestampNS will be filled with a non-zero value.
*
* Note that an error case can also return NULL, but a NULL by itself is
* normal and just signifies that a new frame is not yet available. Note that
* even if a camera device fails outright (a USB camera is unplugged while in
* use, etc), SDL will send an event separately to notify the app, but
* continue to provide blank frames at ongoing intervals until
* SDL_CloseCamera() is called, so real failure here is almost always an out
* of memory condition.
*
* After use, the frame should be released with SDL_ReleaseCameraFrame(). If
* you don't do this, the system may stop providing more video!
*
* Do not call SDL_DestroySurface() on the returned surface! It must be given
* back to the camera subsystem with SDL_ReleaseCameraFrame!
*
* If the system is waiting for the user to approve access to the camera, as
* some platforms require, this will return NULL (no frames available); you
* should either wait for an SDL_EVENT_CAMERA_DEVICE_APPROVED (or
* SDL_EVENT_CAMERA_DEVICE_DENIED) event, or poll
* SDL_GetCameraPermissionState() occasionally until it returns non-zero.
*
* \param camera opened camera device.
* \param timestampNS a pointer filled in with the frame's timestamp, or 0 on
* error. Can be NULL.
* \returns a new frame of video on success, NULL if none is currently
* available.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_ReleaseCameraFrame
*/
extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_AcquireCameraFrame(SDL_Camera *camera, Uint64 *timestampNS);
/**
* Release a frame of video acquired from a camera.
*
* Let the back-end re-use the internal buffer for camera.
*
* This function _must_ be called only on surface objects returned by
* SDL_AcquireCameraFrame(). This function should be called as quickly as
* possible after acquisition, as SDL keeps a small FIFO queue of surfaces for
* video frames; if surfaces aren't released in a timely manner, SDL may drop
* upcoming video frames from the camera.
*
* If the app needs to keep the surface for a significant time, they should
* make a copy of it and release the original.
*
* The app should not use the surface again after calling this function;
* assume the surface is freed and the pointer is invalid.
*
* \param camera opened camera device.
* \param frame the video frame surface to release.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_AcquireCameraFrame
*/
extern SDL_DECLSPEC void SDLCALL SDL_ReleaseCameraFrame(SDL_Camera *camera, SDL_Surface *frame);
/**
* Use this function to shut down camera processing and close the camera
* device.
*
* \param camera opened camera device.
*
* \threadsafety It is safe to call this function from any thread, but no
* thread may reference `device` once this function is called.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_OpenCamera
*/
extern SDL_DECLSPEC void SDLCALL SDL_CloseCamera(SDL_Camera *camera);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_camera_h_ */

Some files were not shown because too many files have changed in this diff Show More