New upstream version 2.5.2+dfsg
Simon McVittie
1 year, 10 months ago
0 | 2.0.5: | |
1 | * Added support for playing Ogg files using stb_vorbis | |
2 | * Added support for playing FLAC files using dr_flac | |
3 | * Added support for playing MP3 files using dr_mp3 | |
4 | * Implemented a master volume feature, Mix_MasterVolume added to public api. | |
5 | * Multiple fixes and updates to autotools build system. | |
0 | 2.6.0: | |
1 | * Added support for playing Ogg files using stb_vorbis, which is now the default Vorbis backend. | |
2 | To use libvorbis instead, configure using --disable-music-ogg-stb --enable-music-ogg-vorbis | |
3 | * Added support for playing FLAC files using dr_flac, which is now the default FLAC music backend. | |
4 | To use libflac instead, configure using --disable-music-flac-drflac --enable-music-flac-libflac | |
5 | * Added support for playing MP3 files using dr_mp3, which is now the default MP3 music backend. | |
6 | To use libmpg123 instead, configure using --disable-music-mp3-drmp3 --enable-music-mp3-mpg123 | |
7 | * Added libxmp support for mod music playback. Modplug is still the default backend for MOD music. | |
8 | To use libxmp instead, configure using --disable-music-mod-modplug --enable-music-mod-xmp | |
9 | * Removed support for libmad as a MP3 music backend. | |
10 | * Removed support for libmikmod as a MOD music backend. | |
11 | * Added Mix_MasterVolume() for additional volume control over all channels | |
6 | 12 | * Update Mix_Init() return value to match documentation, including MIXER_INIT_* flags for already-initialized modules |
7 | * Fixed leak in Mix_FreeChunk + race condition in Mix_HaltChannel | |
8 | * Fixed possible crash in Mix_LoadMusic_RW() | |
9 | * Do not report a non-playing channel as paused | |
10 | * Always check 'looping' field to tell if a channel is playing | |
11 | * Added support of quoted strings in timidity.cfg | |
12 | * Added missing Mix_HasMusicDecoder(). | |
13 | * Memory leak fixes and F32 format support to fluidsynth player. | |
14 | * Fixes to mp3 (libmad) and opus playback on big-endian systems. | |
15 | * Added support for Tell and Duration to MP3 libmad backend. | |
13 | * Added Mix_HasMusicDecoder() | |
14 | * Memory leak fixes and F32 format support to fluidsynth player | |
16 | 15 | * Fixed distorted MIDI playback with FluidSynth if sample rate is out of library's limits |
17 | * Added Mix_ModMusicJumpToOrder for mod music formats | |
18 | * Added libxmp support for mod music playback. | |
19 | * Fixed mikmod player reader issue with umx files | |
16 | * Added Mix_ModMusicJumpToOrder() for mod music formats | |
20 | 17 | * Enabled module internal loops in modplug player |
21 | 18 | * Respect original mp3 file offset |
22 | * Fixed a use-after-free issue in fluidsynth player | |
23 | 19 | * Support setting soundfont via SDL_SOUNDFONTS in OSX native midi |
24 | * Fixed mp3 file detection. | |
25 | * Fixed divide by zero crash in voc_get_block(). | |
26 | * Fixes to ogg playback on big-endian devices. | |
27 | * Added MetaTags api procedures: | |
20 | * Fixed mp3 file detection | |
21 | * Fixes to ogg playback on big-endian devices | |
22 | * Added functions to get metadata information: | |
28 | 23 | Mix_GetMusicTitle() |
29 | 24 | Mix_GetMusicTitleTag() |
30 | 25 | Mix_GetMusicArtistTag() |
34 | 29 | Mix_GetMusicLoopStartTime() |
35 | 30 | Mix_GetMusicLoopEndTime() |
36 | 31 | Mix_GetMusicLoopLengthTime() |
37 | * Add Mix_GetMusicVolume and Mix_GetMusicPosition to public api. | |
38 | * Avoid playing junk chunk after seek in MP3 with libmad backend. | |
39 | * Fixes to MP3 Frankenstein streams playback (thanks to Vitaly Novichkov.) | |
40 | * Add Mix_MusicDuration() to return music duration in seconds. | |
32 | * Added Mix_GetMusicVolume() and Mix_GetMusicPosition() | |
33 | * Added Mix_MusicDuration() to return music duration in seconds | |
41 | 34 | * Fixed music_mpg123 seek bug when sample rate of the file and the stream don't match |
42 | * Timidity improvements. New Mix_SetTimidityCfg() public api. | |
35 | * Timidity improvements, added Mix_SetTimidityCfg() | |
43 | 36 | * Improved mp3 tag detection/skipping |
44 | * Updated external libraries with multiple bug/security fixes | |
45 | 37 | * Extended support for WAV files |
46 | * Added looping support for Opus files | |
47 | 38 | * Allow rmid files be opened by native midi |
48 | 39 | * Fixed possible crash in win32 native midi |
49 | 40 | * Prevent clipping due to volume settings in modplug music |
50 | * Fixed FLAC initial stutter | |
51 | * Reorganized source tree layout | |
41 | * Added looping support for Opus files | |
52 | 42 | * Added looping support for FLAC files |
53 | 43 | * Improved OGG looping support |
54 | 44 | * Fixed loading Opus audio as audio chunks |
55 | * Fixed Mix_FadeOutChannel() never setting fade_volume_reset | |
56 | * Fixed memory leak in macOS native midi code | |
57 | 45 | |
58 | 46 | 2.0.4: |
59 | 47 | Ozkan Sezer - Wed, 10 Oct 2018 14:56:10 |
0 | cmake_minimum_required(VERSION 3.1.0) | |
1 | project(SDL2_mixer C) | |
2 | ||
3 | # FIXME: CMAKE SUPPORT IN SDL2_mixer IS VERY INCOMPLETE YET !!! | |
4 | # | |
5 | # FIXME: make it able build against system codec libraries, too. | |
6 | # FIXME: handle library versioning. | |
7 | # FIXME: test accross different target platforms. | |
0 | cmake_minimum_required(VERSION 3.16) | |
1 | ||
2 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") | |
8 | 3 | |
9 | 4 | # See docs/release_checklist.md |
10 | 5 | set(MAJOR_VERSION 2) |
11 | 6 | set(MINOR_VERSION 5) |
12 | set(MICRO_VERSION 1) | |
13 | set(FULL_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}") | |
14 | ||
15 | option(SUPPORT_WAV "Support loading WAVE music" ON) | |
16 | option(SUPPORT_FLAC "Support loading FLAC music with libFLAC" OFF) | |
17 | option(SUPPORT_OGG "Support loading OGG Vorbis music via libvorbis" OFF) | |
18 | option(SUPPORT_OPUS "Support loading OGG Opus music via libopusfile" OFF) | |
19 | option(SUPPORT_MP3_MPG123 "Support loading MP3 music via MPG123" OFF) | |
20 | option(SUPPORT_MOD_MODPLUG "Support loading MOD music via modplug" OFF) | |
21 | option(SUPPORT_MID_TIMIDITY "Support loading MIDI music via TiMidity" ON) | |
22 | ||
23 | option(BUILD_SHARED_LIBS "Enable shared library" ON) | |
24 | ||
25 | if (NOT (TARGET SDL2::SDL2 OR TARGET SDL2::SDL2-static)) | |
26 | find_package(SDL2 REQUIRED) | |
27 | if(NOT TARGET SDL2::SDL2) | |
28 | # SDL < 2.0.12 | |
29 | add_library(SDL2::SDL2 INTERFACE IMPORTED) | |
30 | set_target_properties(SDL2::SDL2 PROPERTIES | |
31 | INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR} | |
32 | INTERFACE_LINK_LIBRARIES ${SDL2_LIBRARIES} ${SDL2_LIBRARY} | |
33 | ) | |
34 | endif() | |
35 | endif() | |
36 | ||
37 | # Calculate a libtool-like version number | |
38 | math(EXPR BINARY_AGE "${MINOR_VERSION} * 100 + ${MICRO_VERSION}") | |
39 | if(MINOR_VERSION MATCHES "[02468]$") | |
40 | # Stable branch, 2.6.1 -> libSDL2_mixer-2.0.so.0.600.1 | |
41 | set(INTERFACE_AGE ${MICRO_VERSION}) | |
42 | else() | |
43 | # Development branch, 2.5.1 -> libSDL2_mixer-2.0.so.0.501.0 | |
44 | set(INTERFACE_AGE 0) | |
45 | endif() | |
46 | ||
47 | # Increment this if there is an incompatible change - but if that happens, | |
48 | # we should rename the library from SDL2 to SDL3, at which point this would | |
49 | # reset to 0 anyway. | |
50 | set(LT_MAJOR "0") | |
51 | ||
52 | math(EXPR LT_AGE "${BINARY_AGE} - ${INTERFACE_AGE}") | |
53 | math(EXPR LT_CURRENT "${LT_MAJOR} + ${LT_AGE}") | |
54 | set(LT_REVISION "${INTERFACE_AGE}") | |
55 | # For historical reasons, the library name redundantly includes the major | |
56 | # version twice: libSDL2_mixer-2.0.so.0. | |
57 | # TODO: in SDL 3, set the OUTPUT_NAME to plain SDL3_mixer, which will simplify | |
58 | # it to libSDL3_mixer.so.0 | |
59 | set(LT_RELEASE "2.0") | |
60 | set(LT_VERSION "${LT_MAJOR}.${LT_AGE}.${LT_REVISION}") | |
61 | ||
62 | # The following should match the versions in the Xcode project file. | |
63 | # Each version is 1 higher than you might expect, for compatibility | |
64 | # with libtool: macOS ABI versioning is 1-based, unlike other platforms | |
65 | # which are normally 0-based. | |
66 | math(EXPR DYLIB_CURRENT_VERSION_MAJOR "${LT_MAJOR} + ${LT_AGE} + 1") | |
67 | math(EXPR DYLIB_CURRENT_VERSION_MINOR "${LT_REVISION}") | |
68 | math(EXPR DYLIB_COMPAT_VERSION_MAJOR "${LT_MAJOR} + 1") | |
69 | set(DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.${DYLIB_CURRENT_VERSION_MINOR}.0") | |
7 | set(MICRO_VERSION 2) | |
8 | set(SDL_REQUIRED_VERSION 2.0.9) | |
9 | ||
70 | 10 | # For historical reasons this is 3.0.0 rather than the expected 1.0.0 |
71 | 11 | set(DYLIB_COMPATIBILITY_VERSION "3.0.0") |
72 | 12 | |
73 | # For the static assertions in mixer.c | |
74 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MAJOR_VERSION=${MAJOR_VERSION}") | |
75 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MINOR_VERSION=${MINOR_VERSION}") | |
76 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MICRO_VERSION=${MICRO_VERSION}") | |
77 | ||
78 | include_directories(include src src/codecs) | |
79 | ||
80 | add_library(SDL2_mixer) | |
81 | add_library(SDL2::mixer ALIAS SDL2_mixer) | |
82 | ||
83 | if(SUPPORT_MID_TIMIDITY) | |
84 | set(TIMIDITY_SRCS | |
13 | include(PrivateSdlFunctions) | |
14 | sdl_calculate_derived_version_variables() | |
15 | ||
16 | if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) | |
17 | message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL_mixer source code and call cmake from there") | |
18 | endif() | |
19 | ||
20 | project(SDL2_mixer | |
21 | LANGUAGES C | |
22 | VERSION "${FULL_VERSION}" | |
23 | ) | |
24 | ||
25 | message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION}") | |
26 | ||
27 | if(POLICY CMP0112) | |
28 | # Target file component generator expressions do not add target dependencies. | |
29 | cmake_policy(SET CMP0112 NEW) | |
30 | endif() | |
31 | ||
32 | # Set defaults preventing destination file conflicts | |
33 | set(SDL2MIXER_DEBUG_POSTFIX "d" | |
34 | CACHE STRING "Name suffix for debug builds") | |
35 | mark_as_advanced(SDL2MIXER_DEBUG_POSTFIX) | |
36 | ||
37 | # Assume MSVC projects don't have a package manager and need vendored dependencies (by default). | |
38 | # Most other platforms have some kind of package manager. | |
39 | # FIXME: consider a package manager such as conan/vcpkg instead of vendoring | |
40 | if(MSVC) | |
41 | set(vendored_default ON) | |
42 | else() | |
43 | set(vendored_default OFF) | |
44 | endif() | |
45 | ||
46 | include(CheckSymbolExists) | |
47 | include(CMakeDependentOption) | |
48 | include(CMakePackageConfigHelpers) | |
49 | include(GNUInstallDirs) | |
50 | ||
51 | option(CMAKE_POSITION_INDEPENDENT_CODE "Build static libraries with -fPIC" ON) | |
52 | option(BUILD_SHARED_LIBS "Build the library as a shared library" ON) | |
53 | ||
54 | # Save BUILD_SHARED_LIBS variable as soon as possible | |
55 | set(SDL2MIXER_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) | |
56 | ||
57 | option(SDL2MIXER_INSTALL "Enable SDL2mixer install target" ON) | |
58 | option(SDL2MIXER_DEPS_SHARED "Default value for loading dependencies dynamically" ON) | |
59 | option(SDL2MIXER_VENDORED "Use vendored third-party libraries" ${vendored_default}) | |
60 | ||
61 | option(SDL2MIXER_SAMPLES "Build the SDL2_mixer sample program(s)" ON) | |
62 | cmake_dependent_option(SDL2MIXER_SAMPLES_INSTALL "Install the SDL2_mixer sample program(s)" OFF "SDL2MIXER_SAMPLES;SDL2MIXER_INSTALL" OFF) | |
63 | ||
64 | if(UNIX AND NOT APPLE) | |
65 | set(sdl2mixer_cmd_default ON) | |
66 | else() | |
67 | set(sdl2mixer_cmd_default OFF) | |
68 | endif() | |
69 | option(SDL2MIXER_CMD "Support an external music player" ${sdl2mixer_cmd_default}) | |
70 | ||
71 | option(SDL2MIXER_FLAC "Enable FLAC music" ON) | |
72 | ||
73 | cmake_dependent_option(SDL2MIXER_FLAC_LIBFLAC "Enable FLAC music using libFLAC" ON SDL2MIXER_FLAC OFF) | |
74 | cmake_dependent_option(SDL2MIXER_FLAC_LIBFLAC_SHARED "Dynamically load LIBFLAC" "${SDL2MIXER_DEPS_SHARED}" SDL2MIXER_FLAC_LIBFLAC OFF) | |
75 | ||
76 | cmake_dependent_option(SDL2MIXER_FLAC_DRFLAC "Enable FLAC music using drflac" ON SDL2MIXER_FLAC OFF) | |
77 | ||
78 | option(SDL2MIXER_MOD "Support loading MOD music" ON) | |
79 | ||
80 | cmake_dependent_option(SDL2MIXER_MOD_MODPLUG "Support loading MOD music via modplug" ON SDL2MIXER_MOD OFF) | |
81 | cmake_dependent_option(SDL2MIXER_MOD_MODPLUG_SHARED "Dynamically load modplug" "${SDL2MIXER_DEPS_SHARED}" SDL2MIXER_MOD_MODPLUG OFF) | |
82 | ||
83 | cmake_dependent_option(SDL2MIXER_MOD_XMP "Support loading MOD music via libxmp" OFF SDL2MIXER_MOD OFF) | |
84 | cmake_dependent_option(SDL2MIXER_MOD_XMP_LITE "Use libxmp-lite instead of libxmp" OFF SDL2MIXER_MOD_XMP OFF) | |
85 | cmake_dependent_option(SDL2MIXER_MOD_XMP_SHARED "Dynamically load libxmp(-lite)" "${SDL2MIXER_DEPS_SHARED}" SDL2MIXER_MOD_XMP OFF) | |
86 | ||
87 | if(SDL2MIXER_MOD AND NOT (SDL2MIXER_MOD_MODPLUG OR SDL2MIXER_MOD_XMP)) | |
88 | message(FATAL_EROR "MOD support was enabled (SDL2MIXER_MOD) but neither mpdplug (SDL2MIXER_MOD_MODPLUG) or xmp (SDL2MIXER_MOD_XMP) was enabled.") | |
89 | endif() | |
90 | ||
91 | option(SDL2MIXER_MP3 "Enable MP3 music" ON) | |
92 | ||
93 | cmake_dependent_option(SDL2MIXER_MP3_DRMP3 "Support loading MP3 music via dr_mp3" ON SDL2MIXER_MP3 OFF) | |
94 | ||
95 | cmake_dependent_option(SDL2MIXER_MP3_MPG123 "Support loading MP3 music via MPG123" OFF SDL2MIXER_MP3 OFF) | |
96 | cmake_dependent_option(SDL2MIXER_MP3_MPG123_SHARED "Dynamically load mpg123" "${SDL2MIXER_DEPS_SHARED}" SDL2MIXER_MP3_MPG123 OFF) | |
97 | ||
98 | if(SDL2MIXER_MP3 AND NOT (SDL2MIXER_MP3_DRMP3 OR SDL2MIXER_MP3_MPG123)) | |
99 | message(FATAL_ERROR "MP3 support was enabled (SDL2MIXER_MP3) but neither drmp3 (SDL2MIXER_MP3_DRMP3) or mpg123 (SDL2MIXER_MP3_MPG123) were enabled.") | |
100 | endif() | |
101 | ||
102 | option(SDL2MIXER_MIDI "Enable MIDI music" ON) | |
103 | ||
104 | cmake_dependent_option(SDL2MIXER_MIDI_FLUIDSYNTH "Support FluidSynth MIDI output" ON "SDL2MIXER_MIDI;NOT SDL2MIXER_VENDORED" OFF) | |
105 | cmake_dependent_option(SDL2MIXER_MIDI_FLUIDSYNTH_SHARED "Dynamically load libfluidsynth" "${SDL2MIXER_DEPS_SHARED}" SDL2MIXER_MIDI_FLUIDSYNTH OFF) | |
106 | ||
107 | if(WIN32 OR APPLE OR HAIKU) | |
108 | cmake_dependent_option(SDL2MIXER_MIDI_NATIVE "Support native MIDI output" ON SDL2MIXER_MIDI OFF) | |
109 | else() | |
110 | set(SDL2MIXER_MIDI_NATIVE OFF) | |
111 | endif() | |
112 | ||
113 | cmake_dependent_option(SDL2MIXER_MIDI_TIMIDITY "Support timidity MIDI output" ON SDL2MIXER_MIDI OFF) | |
114 | ||
115 | if(SDL2MIXER_MIDI AND NOT (SDL2MIXER_MIDI_TIMIDITY OR SDL2MIXER_MIDI_NATIVE OR SDL2MIXER_MIDI_FLUIDSYNTH)) | |
116 | message(FATAL_ERROR "MIDI support was enabled (SDL2MIXER_MIDI) but neither FluidSynth (SDL2MIXER_MIDI_FLUIDSYNTH), native (SDL2MIXER_MIDI_NATIVE) or timidity (SDL2MIXER_MIDI_TIMIDITY) was enabled") | |
117 | endif() | |
118 | ||
119 | option(SDL2MIXER_OPUS "Enable Opus music" ON) | |
120 | cmake_dependent_option(SDL2MIXER_OPUS_SHARED "Dynamically load libopus" ON SDL2MIXER_OPUS OFF) | |
121 | ||
122 | set(sdl2mixer_vorbis_strings STB TREMOR VORBISFILE) | |
123 | set(SDL2MIXER_VORBIS "STB" CACHE STRING "Enable OGG Vorbis music") | |
124 | set_property(CACHE SDL2MIXER_VORBIS PROPERTY STRINGS "${sdl2mixer_vorbis_strings}") | |
125 | if(SDL2MIXER_VORBIS) | |
126 | if(NOT SDL2MIXER_VORBIS IN_LIST sdl2mixer_vorbis_strings) | |
127 | message(FATAL_ERROR "SDL2MIXER_VORBIS contains an invalid value (=${SDL2MIXER_VORBIS}). It must be one of ${sdl2mixer_vorbis_strings}.") | |
128 | endif() | |
129 | endif() | |
130 | set(SDL2MIXER_VORBIS_STB OFF) | |
131 | set(SDL2MIXER_VORBIS_TREMOR OFF) | |
132 | set(SDL2MIXER_VORBIS_VORBISFILE OFF) | |
133 | if(SDL2MIXER_VORBIS STREQUAL "STB") | |
134 | set(SDL2MIXER_VORBIS_STB ON) | |
135 | endif() | |
136 | if(SDL2MIXER_VORBIS STREQUAL "TREMOR") | |
137 | set(SDL2MIXER_VORBIS_TREMOR ON) | |
138 | endif() | |
139 | if(SDL2MIXER_VORBIS STREQUAL "VORBISFILE") | |
140 | set(SDL2MIXER_VORBIS_VORBISFILE ON) | |
141 | endif() | |
142 | cmake_dependent_option(SDL2MIXER_VORBIS_TREMOR_SHARED "Dynamically load tremor library" ON SDL2MIXER_VORBIS_TREMOR OFF) | |
143 | cmake_dependent_option(SDL2MIXER_VORBIS_VORBISFILE_SHARED "Dynamically load vorbisfile library" ON SDL2MIXER_VORBIS_VORBISFILE OFF) | |
144 | ||
145 | option(SDL2MIXER_WAVE "Enable streaming WAVE music" ON) | |
146 | ||
147 | if(SDL2MIXER_VORBIS_TREMOR OR SDL2MIXER_VORBIS_VORBISFILE OR SDL2MIXER_FLAC_LIBFLAC OR SDL2MIXER_OPUS) | |
148 | set(SDL2MIXER_OGG TRUE) | |
149 | set(SDL2MIXER_OGG_install FALSE) | |
150 | if(SDL2MIXER_VORBIS_VORBISFILE_SHARED OR SDL2MIXER_FLAC_SHARED OR SDL2MIXER_OPUS_SHARED) | |
151 | set(SDL2MIXER_OGG_SHARED TRUE) | |
152 | set(SDL2MIXER_OGG_install TRUE) | |
153 | else() | |
154 | set(SDL2MIXER_OGG_SHARED FALSE) | |
155 | if(NOT SDL2MIXER_BUILD_SHARED_LIBS) | |
156 | set(SDL2MIXER_OGG_install TRUE) | |
157 | endif() | |
158 | endif() | |
159 | else() | |
160 | set(SDL2MIXER_OGG FALSE) | |
161 | endif() | |
162 | ||
163 | if(SDL2MIXER_BUILD_SHARED_LIBS) | |
164 | set(sdl2_mixer_export_name SDL2_mixer) | |
165 | set(sdl2_mixer_install_name_infix shared) | |
166 | set(sdl2_target_name SDL2::SDL2) | |
167 | else() | |
168 | set(sdl2_mixer_export_name SDL2_mixer-static) | |
169 | set(sdl2_mixer_install_name_infix static) | |
170 | set(sdl2_target_name SDL2::SDL2-static) | |
171 | endif() | |
172 | ||
173 | sdl_find_sdl2(${sdl2_target_name} ${SDL_REQUIRED_VERSION}) | |
174 | ||
175 | set(BUILD_SHARED_LIBS ${SDL2MIXER_BUILD_SHARED_LIBS}) | |
176 | add_library(SDL2_mixer | |
177 | src/codecs/load_aiff.c | |
178 | src/codecs/load_voc.c | |
179 | src/codecs/mp3utils.c | |
180 | src/codecs/music_cmd.c | |
181 | src/codecs/music_drflac.c | |
182 | src/codecs/music_drmp3.c | |
183 | src/codecs/music_flac.c | |
184 | src/codecs/music_fluidsynth.c | |
185 | src/codecs/music_modplug.c | |
186 | src/codecs/music_mpg123.c | |
187 | src/codecs/music_nativemidi.c | |
188 | src/codecs/music_ogg.c | |
189 | src/codecs/music_ogg_stb.c | |
190 | src/codecs/music_opus.c | |
191 | src/codecs/music_timidity.c | |
192 | src/codecs/music_wav.c | |
193 | src/codecs/music_xmp.c | |
194 | src/effect_position.c | |
195 | src/effect_stereoreverse.c | |
196 | src/effects_internal.c | |
197 | src/mixer.c | |
198 | src/music.c | |
199 | src/utils.c | |
200 | ) | |
201 | add_library(SDL2_mixer::${sdl2_mixer_export_name} ALIAS SDL2_mixer) | |
202 | target_include_directories(SDL2_mixer | |
203 | PUBLIC | |
204 | "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" | |
205 | "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SDL2>" | |
206 | PRIVATE | |
207 | src | |
208 | src/codecs | |
209 | ) | |
210 | target_compile_definitions(SDL2_mixer PRIVATE | |
211 | BUILD_SDL | |
212 | SDL_BUILD_MAJOR_VERSION=${MAJOR_VERSION} | |
213 | SDL_BUILD_MINOR_VERSION=${MINOR_VERSION} | |
214 | SDL_BUILD_MICRO_VERSION=${MICRO_VERSION} | |
215 | ) | |
216 | target_link_libraries(SDL2_mixer PRIVATE $<BUILD_INTERFACE:${sdl2_target_name}>) | |
217 | if(WIN32 AND BUILD_SHARED_LIBS) | |
218 | target_sources(SDL2_mixer PRIVATE | |
219 | version.rc | |
220 | ) | |
221 | endif() | |
222 | set_target_properties(SDL2_mixer PROPERTIES | |
223 | DEFINE_SYMBOL DLL_EXPORT | |
224 | PUBLIC_HEADER "include/SDL_mixer.h" | |
225 | EXPORT_NAME ${sdl2_mixer_export_name} | |
226 | C_VISIBILITY_PRESET "hidden" | |
227 | ) | |
228 | if(NOT ANDROID) | |
229 | set_target_properties(SDL2_mixer PROPERTIES | |
230 | DEBUG_POSTFIX "${SDL2MIXER_DEBUG_POSTFIX}" | |
231 | ) | |
232 | if(APPLE) | |
233 | # the SOVERSION property corresponds to the compatibility version and VERSION corresponds to the current version | |
234 | # https://cmake.org/cmake/help/latest/prop_tgt/SOVERSION.html#mach-o-versions | |
235 | set_target_properties(SDL2_mixer PROPERTIES | |
236 | SOVERSION "${DYLIB_COMPATIBILITY_VERSION}" | |
237 | VERSION "${DYLIB_CURRENT_VERSION}" | |
238 | ) | |
239 | else() | |
240 | set_target_properties(SDL2_mixer PROPERTIES | |
241 | SOVERSION "${LT_MAJOR}" | |
242 | VERSION "${LT_VERSION}" | |
243 | ) | |
244 | endif() | |
245 | endif() | |
246 | if(SDL2MIXER_BUILD_SHARED_LIBS AND (APPLE OR (UNIX AND NOT ANDROID))) | |
247 | add_custom_command(TARGET SDL2_mixer POST_BUILD | |
248 | COMMAND "${CMAKE_COMMAND}" -E create_symlink "$<TARGET_SONAME_FILE_NAME:SDL2_mixer>" "libSDL2_mixer$<$<CONFIG:Debug>:${SDL2MIXER_DEBUG_POSTFIX}>$<TARGET_FILE_SUFFIX:SDL2_mixer>" | |
249 | # BYPRODUCTS "libSDL2_mixer$<$<CONFIG:Debug>:${SDL2MIXER_DEBUG_POSTFIX}>$<TARGET_FILE_SUFFIX:SDL2_mixer>" # Needs CMake 3.20 | |
250 | WORKING_DIRECTORY "${PROJECT_BINARY_DIR}" | |
251 | ) | |
252 | endif() | |
253 | if(SDL2MIXER_BUILD_SHARED_LIBS) | |
254 | if(WIN32 OR OS2) | |
255 | set_target_properties(SDL2_mixer PROPERTIES | |
256 | PREFIX "" | |
257 | ) | |
258 | endif() | |
259 | if(OS2) | |
260 | # OS/2 doesn't support a DLL name longer than 8 characters. | |
261 | set_target_properties(SDL2_mixer PROPERTIES | |
262 | OUTPUT_NAME "SDL2mix" | |
263 | ) | |
264 | elseif(UNIX AND NOT ANDROID) | |
265 | set_target_properties(SDL2_mixer PROPERTIES | |
266 | OUTPUT_NAME "SDL2_mixer-${LT_RELEASE}" | |
267 | ) | |
268 | endif() | |
269 | else() | |
270 | if(MSVC OR (WATCOM AND (WIN32 OR OS2))) | |
271 | set_target_properties(SDL2_mixer PROPERTIES | |
272 | OUTPUT_NAME "SDL2_mixer-static" | |
273 | ) | |
274 | endif() | |
275 | endif() | |
276 | ||
277 | if(SDL2MIXER_BUILD_SHARED_LIBS) | |
278 | # Use `Compatible Interface Properties` to ensure a shared SDL2_mixer is linked to a shared SDL2 library | |
279 | set_property(TARGET SDL2_mixer PROPERTY INTERFACE_SDL2_SHARED ${SDL2MIXER_BUILD_SHARED_LIBS}) | |
280 | set_property(TARGET SDL2_mixer APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SDL2_SHARED) | |
281 | endif() | |
282 | ||
283 | if(SDL2MIXER_BUILD_SHARED_LIBS) | |
284 | # Make sure static library dependencies are built with -fPIC when building a shared SDL2_mixer | |
285 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) | |
286 | endif() | |
287 | ||
288 | set(INSTALL_EXTRA_TARGETS) | |
289 | set(PC_LIBS) | |
290 | set(PC_REQUIRES) | |
291 | ||
292 | if(SDL2MIXER_CMD) | |
293 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_CMD) | |
294 | set(fork_found OFF) | |
295 | if(NOT fork_found) | |
296 | check_symbol_exists(fork sys/unistd.h HAVE_FORK) | |
297 | if(HAVE_FORK) | |
298 | set(fork_found ON) | |
299 | target_compile_definitions(SDL2_mixer PRIVATE HAVE_FORK) | |
300 | endif() | |
301 | endif() | |
302 | if(NOT fork_found) | |
303 | check_symbol_exists(fork sys/unistd.h HAVE_VFORK) | |
304 | if(HAVE_VFORK) | |
305 | set(fork_found ON) | |
306 | target_compile_definitions(SDL2_mixer PRIVATE HAVE_VFORK) | |
307 | endif() | |
308 | endif() | |
309 | if(NOT fork_found) | |
310 | message(FATAL_ERROR "Neither fork() or vfork() or available on this platform. Reconfigure with -DSDL2MIXER_CMD=OFF.") | |
311 | endif() | |
312 | endif() | |
313 | ||
314 | if(SDL2MIXER_OGG) | |
315 | # libogg is a requirement of libflac, libtremor and libvorbisfile, so only need this library when vendoring | |
316 | if(SDL2MIXER_VENDORED) | |
317 | message(STATUS "Using vendored libogg") | |
318 | set(BUILD_SHARED_LIBS ${SDL2MIXER_OGG_SHARED}) | |
319 | set(INSTALL_CMAKE_PACKAGE_MODULE FALSE CACHE BOOL "Don't install cmake module for libogg") | |
320 | sdl_check_project_in_subfolder(external/ogg ogg SDL2MIXER_VENDORED) | |
321 | add_subdirectory(external/ogg EXCLUDE_FROM_ALL) | |
322 | if(SDL2MIXER_OGG_install) | |
323 | list(APPEND INSTALL_EXTRA_TARGETS ogg) | |
324 | endif() | |
325 | endif() | |
326 | endif() | |
327 | ||
328 | if(SDL2MIXER_OPUS) | |
329 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_OPUS) | |
330 | if(SDL2MIXER_VENDORED) | |
331 | # vendored libogg alread handled | |
332 | if(NOT TARGET ogg) | |
333 | message(FATAL_ERROR "ogg target not present") | |
334 | endif() | |
335 | message(STATUS "Using vendored opus") | |
336 | set(BUILD_SHARED_LIBS ${SDL2MIXER_OPUS_SHARED}) | |
337 | sdl_check_project_in_subfolder(external/opus opus SDL2MIXER_VENDORED) | |
338 | add_subdirectory(external/opus EXCLUDE_FROM_ALL) | |
339 | ||
340 | set(OP_DISABLE_DOCS TRUE CACHE BOOL "Disable opusfile documentation") | |
341 | set(OP_DISABLE_HTTP TRUE CACHE BOOL "Disable opusfile HTTP SUPPORT") | |
342 | message(STATUS "Using vendored opusfile") | |
343 | set(BUILD_SHARED_LIBS ${SDL2MIXER_OPUS_SHARED}) | |
344 | sdl_check_project_in_subfolder(external/opusfile opusfile SDL2MIXER_VENDORED) | |
345 | add_subdirectory(external/opusfile EXCLUDE_FROM_ALL) | |
346 | if(MSVC) | |
347 | set_property(TARGET opusfile PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS TRUE) | |
348 | endif() | |
349 | ||
350 | file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/opusfile.h" "#include \"${CMAKE_CURRENT_SOURCE_DIR}/external/opusfile/include/opusfile.h\"\n") | |
351 | execute_process( | |
352 | COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/opus" | |
353 | COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/opusfile.h" "${CMAKE_CURRENT_BINARY_DIR}/opus/opusfile.h" | |
354 | ) | |
355 | target_include_directories(SDL2_mixer PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") | |
356 | ||
357 | if(NOT TARGET opusfile::opusfile) | |
358 | add_library(opusfile::opusfile ALIAS opusfile) | |
359 | endif() | |
360 | if(SDL2MIXER_OPUS_SHARED OR NOT SDL2MIXER_BUILD_SHARED_LIBS) | |
361 | list(APPEND INSTALL_EXTRA_TARGETS opus opusfile) | |
362 | endif() | |
363 | if(NOT SDL2MIXER_OPUS_SHARED) | |
364 | list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:opusfile> -l$<TARGET_FILE_BASE_NAME:opus> -l$<TARGET_FILE_BASE_NAME:ogg>) | |
365 | endif() | |
366 | else() | |
367 | message(STATUS "Using system opusfile") | |
368 | find_package(opusfile REQUIRED) | |
369 | if(NOT SDL2MIXER_OPUS_SHARED) | |
370 | list(APPEND PC_REQUIRES opusfile) | |
371 | endif() | |
372 | endif() | |
373 | if(SDL2MIXER_OPUS_SHARED) | |
374 | target_include_directories(SDL2_mixer PRIVATE | |
375 | $<TARGET_PROPERTY:opusfile::opusfile,INCLUDE_DIRECTORIES> | |
376 | $<TARGET_PROPERTY:opusfile::opusfile,INTERFACE_INCLUDE_DIRECTORIES> | |
377 | $<TARGET_PROPERTY:opusfile::opusfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
378 | ) | |
379 | target_get_dynamic_library(dynamic_opusfile opusfile::opusfile) | |
380 | message(STATUS "Dynamic opus (opusfile): ${dynamic_opusfile}") | |
381 | target_compile_definitions(SDL2_mixer PRIVATE "OPUS_DYNAMIC=\"${dynamic_opusfile}\"") | |
382 | if(SDL2MIXER_VENDORED) | |
383 | add_dependencies(SDL2_mixer opusfile::opusfile) | |
384 | endif() | |
385 | else() | |
386 | target_link_libraries(SDL2_mixer PRIVATE opusfile::opusfile) | |
387 | endif() | |
388 | endif() | |
389 | ||
390 | if(SDL2MIXER_VORBIS_STB) | |
391 | message(STATUS "Enabled ogg music: using stb_vorbis") | |
392 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_OGG) | |
393 | target_compile_definitions(SDL2_mixer PRIVATE OGG_USE_STB) | |
394 | endif() | |
395 | ||
396 | if(SDL2MIXER_VORBIS_TREMOR) | |
397 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_OGG OGG_USE_TREMOR) | |
398 | if(SDL2MIXER_VENDORED) | |
399 | # vendored libogg alread handled | |
400 | if(NOT TARGET ogg) | |
401 | message(FATAL_ERROR "ogg target not present") | |
402 | endif() | |
403 | message(STATUS "Using vendored tremor") | |
404 | set(BUILD_SHARED_LIBS ${SDL2MIXER_VORBIS_TREMOR_SHARED}) | |
405 | sdl_check_project_in_subfolder(external/tremor tremor SDL2MIXER_VENDORED) | |
406 | add_subdirectory(external/tremor EXCLUDE_FROM_ALL) | |
407 | if(NOT TARGET tremor::tremor) | |
408 | add_library(tremor::tremor ALIAS vorbisidec) | |
409 | endif() | |
410 | ||
411 | file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ivorbisfile.h" "#include \"${CMAKE_CURRENT_SOURCE_DIR}/external/tremor/ivorbisfile.h\"\n") | |
412 | execute_process( | |
413 | COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/tremor" | |
414 | COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/ivorbisfile.h" "${CMAKE_CURRENT_BINARY_DIR}/tremor/ivorbisfile.h" | |
415 | ) | |
416 | target_include_directories(SDL2_mixer PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") | |
417 | if(SDL2MIXER_VORBIS_TREMOR_SHARED OR NOT SDL2MIXER_BUILD_SHARED_LIBS) | |
418 | list(APPEND INSTALL_EXTRA_TARGETS vorbisidec) | |
419 | endif() | |
420 | if(NOT SDL2MIXER_VORBIS_TREMOR_SHARED) | |
421 | list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:vorbisidec> -l$<TARGET_FILE_BASE_NAME:ogg>) | |
422 | endif() | |
423 | else() | |
424 | message(STATUS "Using system tremor") | |
425 | find_package(tremor REQUIRED) | |
426 | if(NOT SDL2MIXER_VORBIS_TREMOR_SHARED) | |
427 | list(APPEND PC_REQUIRES tremor) | |
428 | endif() | |
429 | endif() | |
430 | if(SDL2MIXER_VORBIS_TREMOR_SHARED) | |
431 | target_include_directories(SDL2_mixer PRIVATE | |
432 | $<TARGET_PROPERTY:tremor::tremor,INCLUDE_DIRECTORIES> | |
433 | $<TARGET_PROPERTY:tremor::tremor,INTERFACE_INCLUDE_DIRECTORIES> | |
434 | $<TARGET_PROPERTY:tremor::tremor,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
435 | ) | |
436 | target_get_dynamic_library(dynamic_tremor tremor::tremor) | |
437 | message(STATUS "Dynamic vorbis (tremor): ${dynamic_tremor}") | |
438 | target_compile_definitions(SDL2_mixer PRIVATE "OGG_DYNAMIC=\"${dynamic_tremor}\"") | |
439 | if(SDL2MIXER_VENDORED) | |
440 | add_dependencies(SDL2_mixer tremor::tremor) | |
441 | endif() | |
442 | else() | |
443 | target_link_libraries(SDL2_mixer PRIVATE tremor::tremor) | |
444 | endif() | |
445 | endif() | |
446 | ||
447 | if(SDL2MIXER_VORBIS_VORBISFILE) | |
448 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_OGG) | |
449 | if(SDL2MIXER_VENDORED) | |
450 | # vendored libogg alread handled | |
451 | if(NOT TARGET ogg) | |
452 | message(FATAL_ERROR "ogg target not present") | |
453 | endif() | |
454 | message(STATUS "Using vendored vorbis + vorbisfile") | |
455 | set(BUILD_SHARED_LIBS ${SDL2MIXER_VORBIS_VORBISFILE_SHARED}) | |
456 | sdl_check_project_in_subfolder(external/vorbis vorbisfile SDL2MIXER_VENDORED) | |
457 | add_subdirectory(external/vorbis EXCLUDE_FROM_ALL) | |
458 | if(NOT TARGET vorbisfile::vorbisfile) | |
459 | add_library(vorbisfile::vorbisfile ALIAS vorbisfile) | |
460 | endif() | |
461 | if(SDL2MIXER_VORBIS_VORBISFILE_SHARED OR NOT SDL2MIXER_BUILD_SHARED_LIBS) | |
462 | list(APPEND INSTALL_EXTRA_TARGETS vorbis vorbisfile) | |
463 | endif() | |
464 | if(NOT SDL2MIXER_VORBIS_VORBISFILE_SHARED) | |
465 | list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:vorbisfile>) | |
466 | endif() | |
467 | else() | |
468 | message(STATUS "Using system vorbisfile") | |
469 | find_package(vorbisfile REQUIRED) | |
470 | if(NOT SDL2MIXER_VORBIS_VORBISFILE_SHARED) | |
471 | list(APPEND PC_REQUIRES vorbisfile) | |
472 | endif() | |
473 | endif() | |
474 | if(SDL2MIXER_VORBIS_VORBISFILE_SHARED) | |
475 | target_include_directories(SDL2_mixer PRIVATE | |
476 | $<TARGET_PROPERTY:vorbisfile::vorbisfile,INCLUDE_DIRECTORIES> | |
477 | $<TARGET_PROPERTY:vorbisfile::vorbisfile,INTERFACE_INCLUDE_DIRECTORIES> | |
478 | $<TARGET_PROPERTY:vorbisfile::vorbisfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
479 | ) | |
480 | target_get_dynamic_library(dynamic_vorbisfile vorbisfile::vorbisfile) | |
481 | message(STATUS "Dynamic vorbisfile: ${dynamic_vorbisfile}") | |
482 | target_compile_definitions(SDL2_mixer PRIVATE "OGG_DYNAMIC=\"${dynamic_vorbisfile}\"") | |
483 | if(SDL2MIXER_VENDORED) | |
484 | add_dependencies(SDL2_mixer vorbisfile::vorbisfile) | |
485 | endif() | |
486 | else() | |
487 | target_link_libraries(SDL2_mixer PRIVATE vorbisfile::vorbisfile) | |
488 | endif() | |
489 | endif() | |
490 | ||
491 | if(SDL2MIXER_FLAC_LIBFLAC) | |
492 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_FLAC_LIBFLAC) | |
493 | if(SDL2MIXER_VENDORED) | |
494 | # vendored libogg alread handled | |
495 | if(NOT TARGET ogg) | |
496 | message(FATAL_ERROR "ogg target not present") | |
497 | endif() | |
498 | set(BUILD_SHARED_LIBS "${SDL2MIXER_FLAC_LIBFLAC_SHARED}") | |
499 | set(INSTALL_CMAKE_CONFIG_MODULE OFF CACHE BOOL "Disable libflac installation") | |
500 | set(WITH_OGG OFF CACHE BOOL "Disable finding ogg using `find_package` (we have vendored it)") | |
501 | message(STATUS "Using vendored libflac") | |
502 | sdl_check_project_in_subfolder(external/flac libflac SDL2MIXER_VENDORED) | |
503 | add_subdirectory(external/flac EXCLUDE_FROM_ALL) | |
504 | if(SDL2MIXER_FLAC_LIBFLAC_SHARED) | |
505 | list(APPEND INSTALL_EXTRA_TARGETS FLAC) | |
506 | endif() | |
507 | if(NOT SDL2MIXER_FLAC_LIBFLAC_SHARED) | |
508 | list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:FLAC::FLAC> -l$<TARGET_FILE_BASE_NAME:ogg>) | |
509 | endif() | |
510 | else() | |
511 | message(STATUS "Using system libflac") | |
512 | find_package(FLAC REQUIRED) | |
513 | if(NOT SDL2MIXER_FLAC_LIBFLAC_SHARED) | |
514 | list(APPEND PC_REQUIRES flac) | |
515 | endif() | |
516 | endif() | |
517 | if(SDL2MIXER_FLAC_LIBFLAC_SHARED) | |
518 | target_include_directories(SDL2_mixer PRIVATE | |
519 | $<TARGET_PROPERTY:FLAC::FLAC,INCLUDE_DIRECTORIES> | |
520 | $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_INCLUDE_DIRECTORIES> | |
521 | $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
522 | ) | |
523 | target_get_dynamic_library(dynamic_flac FLAC::FLAC) | |
524 | message(STATUS "Dynamic libflac: ${dynamic_flac}") | |
525 | target_compile_definitions(SDL2_mixer PRIVATE "FLAC_DYNAMIC=\"${dynamic_flac}\"") | |
526 | if(SDL2MIXER_VENDORED) | |
527 | add_dependencies(SDL2_mixer FLAC) | |
528 | endif() | |
529 | else() | |
530 | target_link_libraries(SDL2_mixer PRIVATE FLAC) | |
531 | endif() | |
532 | endif() | |
533 | ||
534 | if(SDL2MIXER_FLAC_DRFLAC) | |
535 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_FLAC_DRFLAC) | |
536 | endif() | |
537 | ||
538 | if(SDL2MIXER_MOD_MODPLUG) | |
539 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MOD_MODPLUG) | |
540 | if(SDL2MIXER_VENDORED) | |
541 | message(STATUS "Using vendored libmodplug") | |
542 | sdl_check_project_in_subfolder(external/libmodplug libmodplug SDL2MIXER_VENDORED) | |
543 | set(BUILD_SHARED_LIBS "${SDL2MIXER_MOD_MODPLUG_SHARED}") | |
544 | enable_language(CXX) | |
545 | add_subdirectory(external/libmodplug EXCLUDE_FROM_ALL) | |
546 | target_include_directories(SDL2_mixer PRIVATE external/libmodplug/src) | |
547 | if(NOT TARGET modplug::modplug) | |
548 | add_library(modplug::modplug ALIAS modplug) | |
549 | # <modplug.h> is not escaped properly for windres when using MinGW + "Unix Makefiles" ==> limit it to C sources | |
550 | target_compile_definitions(SDL2_mixer PRIVATE $<$<COMPILE_LANGUAGE:C>:MODPLUG_HEADER=<modplug.h$<ANGLE-R>>) | |
551 | endif() | |
552 | if(SDL2MIXER_FLAC_LIBFLAC_SHARED OR NOT SDL2MIXER_BUILD_SHARED_LIBS) | |
553 | list(APPEND INSTALL_EXTRA_TARGETS modplug) | |
554 | endif() | |
555 | if(NOT SDL2MIXER_MOD_MODPLUG_SHARED) | |
556 | list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:modplug>) | |
557 | endif() | |
558 | else() | |
559 | message(STATUS "Using system libmodplug") | |
560 | find_package(modplug REQUIRED) | |
561 | if(NOT SDL2MIXER_MOD_MODPLUG_SHARED) | |
562 | list(APPEND PC_REQUIRES libmodplug) | |
563 | endif() | |
564 | endif() | |
565 | if(SDL2MIXER_MOD_MODPLUG_SHARED) | |
566 | target_include_directories(SDL2_mixer PRIVATE | |
567 | $<TARGET_PROPERTY:modplug::modplug,INCLUDE_DIRECTORIES> | |
568 | $<TARGET_PROPERTY:modplug::modplug,INTERFACE_INCLUDE_DIRECTORIES> | |
569 | $<TARGET_PROPERTY:modplug::modplug,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
570 | ) | |
571 | target_get_dynamic_library(dynamic_modplug modplug::modplug) | |
572 | message(STATUS "Dynamic modplug: ${dynamic_modplug}") | |
573 | target_compile_definitions(SDL2_mixer PRIVATE "MODPLUG_DYNAMIC=\"${dynamic_modplug}\"") | |
574 | if(SDL2MIXER_VENDORED) | |
575 | add_dependencies(SDL2_mixer modplug::modplug) | |
576 | endif() | |
577 | else() | |
578 | target_link_libraries(SDL2_mixer PRIVATE modplug::modplug) | |
579 | endif() | |
580 | endif() | |
581 | ||
582 | if(SDL2MIXER_MOD_XMP) | |
583 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MOD_XMP) | |
584 | if(SDL2MIXER_VENDORED) | |
585 | message(STATUS "Using vendored libxmp/libxmp-lite") | |
586 | message(WARNING "Neither libxmp or libxmp-lite are vendored. Using system libxmp instead.") | |
587 | endif() | |
588 | if(SDL2MIXER_MOD_XMP_LITE) | |
589 | message(STATUS "Using system libxmp-lite") | |
590 | find_package(libxmp-lite REQUIRED) | |
591 | set(tgt_xmp libxmp-lite::libxmp-lite) | |
592 | set(xmp_name libxmp-lite) | |
593 | if(NOT SDL2MIXER_MOD_XMP_SHARED) | |
594 | list(APPEND PC_REQUIRES libxmplite) | |
595 | endif() | |
596 | else() | |
597 | message(STATUS "Using system libxmp") | |
598 | find_package(libxmp REQUIRED) | |
599 | set(tgt_xmp libxmp::libxmp) | |
600 | set(xmp_name libxmp) | |
601 | if(NOT SDL2MIXER_MOD_XMP_SHARED) | |
602 | list(APPEND PC_REQUIRES libxmp) | |
603 | endif() | |
604 | endif() | |
605 | if(SDL2MIXER_MOD_XMP_SHARED) | |
606 | target_include_directories(SDL2_mixer PRIVATE | |
607 | $<TARGET_PROPERTY:${tgt_xmp},INCLUDE_DIRECTORIES> | |
608 | $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_INCLUDE_DIRECTORIES> | |
609 | $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
610 | ) | |
611 | target_get_dynamic_library(dynamic_xmp ${tgt_xmp}) | |
612 | message(STATUS "Dynamic ${xmp_name}: ${dynamic_xmp}") | |
613 | target_compile_definitions(SDL2_mixer PRIVATE "XMP_DYNAMIC=\"${dynamic_xmp}\"") | |
614 | if(SDL2MIXER_VENDORED) | |
615 | add_dependencies(SDL2_mixer ${tgt_xmp}) | |
616 | endif() | |
617 | else() | |
618 | target_link_libraries(SDL2_mixer PRIVATE ${tgt_xmp}) | |
619 | endif() | |
620 | endif() | |
621 | ||
622 | if(SDL2MIXER_MP3_DRMP3) | |
623 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MP3_DRMP3) | |
624 | endif() | |
625 | ||
626 | if(SDL2MIXER_MP3_MPG123) | |
627 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MP3_MPG123) | |
628 | if(SDL2MIXER_VENDORED) | |
629 | message(STATUS "Using vendored mpg123") | |
630 | sdl_check_project_in_subfolder(external/mpg123/ports/cmake mpg123 SDL2MIXER_VENDORED) | |
631 | set(BUILD_LIBOUT123 FALSE CACHE BOOL "Don't configure libout123") | |
632 | set(BUILD_SHARED_LIBS "${SDL2MIXER_MP3_MPG123_SHARED}") | |
633 | add_subdirectory(external/mpg123/ports/cmake EXCLUDE_FROM_ALL) | |
634 | if(NOT TARGET MPG123::mpg123) | |
635 | add_library(MPG123::mpg123 ALIAS libmpg123) | |
636 | endif() | |
637 | if(SDL2MIXER_MP3_MPG123_SHARED OR NOT SDL2MIXER_BUILD_SHARED_LIBS) | |
638 | list(APPEND INSTALL_EXTRA_TARGETS libmpg123) | |
639 | endif() | |
640 | if(NOT SDL2MIXER_MP3_MPG123_SHARED) | |
641 | list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:MPG123::mpg123>) | |
642 | endif() | |
643 | else() | |
644 | message(STATUS "Using system mpg123") | |
645 | find_package(MPG123 REQUIRED) | |
646 | if(NOT SDL2MIXER_MP3_MPG123_SHARED) | |
647 | list(APPEND PC_REQUIRES libmpg123) | |
648 | endif() | |
649 | endif() | |
650 | if(SDL2MIXER_MP3_MPG123_SHARED) | |
651 | target_include_directories(SDL2_mixer PRIVATE | |
652 | $<TARGET_PROPERTY:MPG123::mpg123,INCLUDE_DIRECTORIES> | |
653 | $<TARGET_PROPERTY:MPG123::mpg123,INTERFACE_INCLUDE_DIRECTORIES> | |
654 | $<TARGET_PROPERTY:MPG123::mpg123,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
655 | ) | |
656 | target_get_dynamic_library(dynamic_mpg123 MPG123::mpg123) | |
657 | message(STATUS "Dynamic mpg123}: ${dynamic_mpg123}") | |
658 | target_compile_definitions(SDL2_mixer PRIVATE "MPG123_DYNAMIC=\"${dynamic_mpg123}\"") | |
659 | if(SDL2MIXER_VENDORED) | |
660 | add_dependencies(SDL2_mixer MPG123::mpg123) | |
661 | endif() | |
662 | else() | |
663 | target_link_libraries(SDL2_mixer PRIVATE MPG123::mpg123) | |
664 | endif() | |
665 | endif() | |
666 | ||
667 | if(SDL2MIXER_MIDI_FLUIDSYNTH) | |
668 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MID_FLUIDSYNTH) | |
669 | if(SDL2MIXER_VENDORED) | |
670 | message(STATUS "Using vendored FluidSynth") | |
671 | message(FATAL_ERROR "FluidSynth is not vendored.") | |
672 | else() | |
673 | message(STATUS "Using system FluidSynth") | |
674 | find_package(FluidSynth REQUIRED) | |
675 | if(NOT SDL2MIXER_MIDI_FLUIDSYNTH_SHARED) | |
676 | list(APPEND PC_REQUIRES fluidsynth) | |
677 | endif() | |
678 | endif() | |
679 | if(SDL2MIXER_MIDI_FLUIDSYNTH_SHARED) | |
680 | target_include_directories(SDL2_mixer PRIVATE | |
681 | $<TARGET_PROPERTY:FluidSynth::FluidSynth,INCLUDE_DIRECTORIES> | |
682 | $<TARGET_PROPERTY:FluidSynth::FluidSynth,INTERFACE_INCLUDE_DIRECTORIES> | |
683 | $<TARGET_PROPERTY:FluidSynth::FluidSynth,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
684 | ) | |
685 | target_get_dynamic_library(dynamic_fluidsynth FluidSynth::FluidSynth) | |
686 | message(STATUS "Dynamic fluidsynth: ${dynamic_fluidsynth}") | |
687 | target_compile_definitions(SDL2_mixer PRIVATE "FLUIDSYNTH_DYNAMIC=\"${dynamic_fluidsynth}\"") | |
688 | if(SDL2MIXER_VENDORED) | |
689 | add_dependencies(SDL2_mixer FluidSynth::FluidSynth) | |
690 | endif() | |
691 | else() | |
692 | target_link_libraries(SDL2_mixer PRIVATE FluidSynth::FluidSynth) | |
693 | endif() | |
694 | endif() | |
695 | ||
696 | if(SDL2MIXER_MIDI_NATIVE) | |
697 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MID_NATIVE) | |
698 | target_sources(SDL2_mixer PRIVATE | |
699 | src/codecs/native_midi/native_midi_common.c | |
700 | src/codecs/native_midi/native_midi_common.h | |
701 | ) | |
702 | if(WIN32) | |
703 | target_sources(SDL2_mixer PRIVATE src/codecs/native_midi/native_midi_win32.c) | |
704 | target_link_libraries(SDL2_mixer PRIVATE winmm) | |
705 | elseif(APPLE) | |
706 | target_sources(SDL2_mixer PRIVATE src/codecs/native_midi/native_midi_macosx.c) | |
707 | target_link_options(SDL2_mixer PRIVATE -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,CoreServices) | |
708 | elseif(HAIKU) | |
709 | enable_language(CXX) | |
710 | target_sources(SDL2_mixer PRIVATE src/codecs/native_midi/native_midi_haiku.cpp) | |
711 | target_link_libraries(SDL2_mixer PRIVATE midi) | |
712 | endif() | |
713 | endif() | |
714 | ||
715 | if(SDL2MIXER_MIDI_TIMIDITY) | |
716 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MID_TIMIDITY) | |
717 | target_sources(SDL2_mixer PRIVATE | |
85 | 718 | src/codecs/timidity/common.c |
86 | 719 | src/codecs/timidity/instrum.c |
87 | 720 | src/codecs/timidity/mix.c |
94 | 727 | ) |
95 | 728 | endif() |
96 | 729 | |
97 | target_sources(SDL2_mixer PRIVATE | |
98 | src/effect_position.c | |
99 | src/effects_internal.c | |
100 | src/effect_stereoreverse.c | |
101 | src/mixer.c | |
102 | src/music.c | |
103 | src/utils.c | |
104 | src/codecs/load_aiff.c | |
105 | src/codecs/load_voc.c | |
106 | src/codecs/music_cmd.c | |
107 | src/codecs/music_wav.c | |
108 | src/codecs/music_drflac.c | |
109 | src/codecs/music_flac.c | |
110 | src/codecs/music_drmp3.c | |
111 | src/codecs/music_mad.c | |
112 | src/codecs/music_mpg123.c | |
113 | src/codecs/mp3utils.c | |
114 | src/codecs/music_ogg.c | |
115 | src/codecs/music_ogg_stb.c | |
116 | src/codecs/music_opus.c | |
117 | src/codecs/music_mikmod.c | |
118 | src/codecs/music_modplug.c | |
119 | src/codecs/music_xmp.c | |
120 | src/codecs/music_fluidsynth.c | |
121 | src/codecs/music_timidity.c | |
122 | src/codecs/music_nativemidi.c | |
123 | ${TIMIDITY_SRCS} | |
730 | if(SDL2MIXER_WAVE) | |
731 | target_compile_definitions(SDL2_mixer PRIVATE MUSIC_WAV) | |
732 | endif() | |
733 | ||
734 | if(SDL2MIXER_INSTALL) | |
735 | install( | |
736 | TARGETS SDL2_mixer | |
737 | EXPORT SDL2MixerTargets | |
738 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel | |
739 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT library | |
740 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT library | |
741 | PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/SDL2" COMPONENT devel | |
742 | ) | |
743 | ||
744 | if(INSTALL_EXTRA_TARGETS) | |
745 | install(TARGETS ${INSTALL_EXTRA_TARGETS} | |
746 | EXPORT SDL2MixerTargets | |
747 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel | |
748 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT library | |
749 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT library | |
750 | PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" COMPONENT devel | |
751 | ) | |
752 | endif() | |
753 | ||
754 | ##### export files ##### | |
755 | if(WIN32 AND NOT MINGW) | |
756 | set(PKG_PREFIX "cmake") | |
757 | else() | |
758 | set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2_mixer") | |
759 | endif() | |
760 | ||
761 | configure_package_config_file(SDL2_mixerConfig.cmake.in SDL2_mixerConfig.cmake | |
762 | INSTALL_DESTINATION "${PKG_PREFIX}" | |
763 | ) | |
764 | write_basic_package_version_file("${PROJECT_BINARY_DIR}/SDL2_mixerConfigVersion.cmake" | |
765 | VERSION ${FULL_VERSION} | |
766 | COMPATIBILITY AnyNewerVersion | |
767 | ) | |
768 | install( | |
769 | FILES | |
770 | "${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixerConfig.cmake" | |
771 | "${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixerConfigVersion.cmake" | |
772 | DESTINATION "${PKG_PREFIX}" | |
773 | COMPONENT devel | |
774 | ) | |
775 | if(NOT SDL2MIXER_BUILD_SHARED_LIBS) | |
776 | install( | |
777 | FILES | |
778 | cmake/FindFLAC.cmake | |
779 | cmake/FindFluidSynth.cmake | |
780 | cmake/Findlibxmp.cmake | |
781 | cmake/Findlibxmp-lite.cmake | |
782 | cmake/Findmodplug.cmake | |
783 | cmake/Findopusfile.cmake | |
784 | cmake/FindMPG123.cmake | |
785 | cmake/Findvorbisfile.cmake | |
786 | cmake/Findtremor.cmake | |
787 | DESTINATION "${PKG_PREFIX}" | |
788 | COMPONENT devel | |
789 | ) | |
790 | endif() | |
791 | install(EXPORT SDL2MixerTargets | |
792 | FILE SDL2_mixer-${sdl2_mixer_install_name_infix}-targets.cmake | |
793 | NAMESPACE SDL2_mixer:: | |
794 | DESTINATION "${PKG_PREFIX}" | |
795 | COMPONENT devel | |
796 | ) | |
797 | ||
798 | if(SDL2MIXER_BUILD_SHARED_LIBS) | |
799 | # Only create a .pc file for a shared SDL2_mixer | |
800 | set(VERSION ${FULL_VERSION}) | |
801 | set(SDL_VERSION ${SDL_REQUIRED_VERSION}) | |
802 | set(prefix "${CMAKE_INSTALL_PREFIX}") | |
803 | set(exec_prefix "\${prefix}") | |
804 | set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") | |
805 | set(bindir "\${exec_prefix}/bin") | |
806 | set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") | |
807 | string(JOIN " " PC_REQUIRES ${PC_REQUIRES}) | |
808 | string(JOIN " " PC_LIBS ${PC_LIBS}) | |
809 | configure_file(SDL2_mixer.pc.in ${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixer.pc.intermediate @ONLY) | |
810 | file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixer-$<CONFIG>.pc" INPUT "${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixer.pc.intermediate") | |
811 | ||
812 | set(PC_DESTDIR) | |
813 | if(CMAKE_SYSTEM_NAME MATCHES FreeBSD) | |
814 | # FreeBSD uses ${PREFIX}/libdata/pkgconfig | |
815 | set(PC_DESTDIR "libdata/pkgconfig") | |
816 | else() | |
817 | set(PC_DESTDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig") | |
818 | endif() | |
819 | # Only install a SDL2_mixer.pc file in Release mode | |
820 | install(CODE " | |
821 | # FIXME: use file(COPY_FILE) if minimum CMake version >= 3.21 | |
822 | execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E copy_if_different | |
823 | \"${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixer-$<CONFIG>.pc\" | |
824 | \"${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixer.pc\") | |
825 | file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${PC_DESTDIR}\" | |
826 | TYPE FILE | |
827 | FILES \"${CMAKE_CURRENT_BINARY_DIR}/SDL2_mixer.pc\")" CONFIG Release COMPONENT devel) | |
828 | endif() | |
829 | ||
830 | if(SDL2MIXER_BUILD_SHARED_LIBS AND (APPLE OR (UNIX AND NOT ANDROID))) | |
831 | install( | |
832 | FILES | |
833 | "${PROJECT_BINARY_DIR}/libSDL2_mixer$<$<CONFIG:Debug>:${SDL2MIXER_DEBUG_POSTFIX}>$<TARGET_FILE_SUFFIX:SDL2_mixer>" | |
834 | DESTINATION "${CMAKE_INSTALL_LIBDIR}" | |
835 | COMPONENT devel | |
836 | ) | |
837 | endif() | |
838 | ||
839 | install(FILES "LICENSE.txt" | |
840 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}" | |
841 | COMPONENT library | |
842 | ) | |
843 | endif() | |
844 | ||
845 | if(SDL2MIXER_SAMPLES) | |
846 | add_executable(playmus playmus.c) | |
847 | add_executable(playwave playwave.c) | |
848 | ||
849 | find_package(SDL2main) | |
850 | ||
851 | foreach(prog playmus playwave) | |
852 | # FIXME: mingw should be handled by SDL2::SDL2(-static) target | |
853 | if(MINGW) | |
854 | target_link_libraries(${prog} PRIVATE mingw32) | |
855 | target_link_options(${prog} PRIVATE -mwindows) | |
856 | endif() | |
857 | target_link_libraries(${prog} PRIVATE SDL2_mixer::${sdl2_mixer_export_name}) | |
858 | if(TARGET SDL2::SDL2main) | |
859 | target_link_libraries(${prog} PRIVATE SDL2::SDL2main) | |
860 | endif() | |
861 | target_link_libraries(${prog} PRIVATE ${sdl2_target_name}) | |
862 | ||
863 | if(SDL2MIXER_SAMPLES_INSTALL) | |
864 | install(TARGETS ${prog} | |
865 | RUNTIME DESTINATION "{CMAKE_INSTALL_BINDIR}" | |
866 | ) | |
867 | endif() | |
868 | endforeach() | |
869 | endif() | |
870 | ||
871 | add_library(SDL2::mixer INTERFACE IMPORTED GLOBAL) | |
872 | set_target_properties(SDL2::mixer PROPERTIES | |
873 | INTERFACE_LINK_LIBRARIES "SDL2_mixer" | |
124 | 874 | ) |
125 | ||
126 | if (SUPPORT_WAV) | |
127 | target_compile_definitions(SDL2_mixer PRIVATE -DMUSIC_WAV) | |
128 | endif() | |
129 | ||
130 | if (SUPPORT_OGG OR SUPPORT_FLAC OR SUPPORT_OPUS) | |
131 | add_subdirectory(external/ogg) | |
132 | endif() | |
133 | ||
134 | if (SUPPORT_FLAC) | |
135 | target_compile_definitions(SDL2_mixer PRIVATE -DMUSIC_FLAC_LIBFLAC) | |
136 | add_subdirectory(external/flac) | |
137 | target_include_directories(SDL2_mixer PRIVATE external/flac/include) | |
138 | target_link_libraries(SDL2_mixer PRIVATE FLAC) | |
139 | endif() | |
140 | ||
141 | if (SUPPORT_OGG) | |
142 | target_compile_definitions(SDL2_mixer PRIVATE -DMUSIC_OGG) | |
143 | add_subdirectory(external/vorbis) | |
144 | target_include_directories(SDL2_mixer PRIVATE external/vorbis/include) | |
145 | target_link_libraries(SDL2_mixer PRIVATE vorbisfile vorbis ogg) | |
146 | endif() | |
147 | ||
148 | if (SUPPORT_OPUS) | |
149 | target_compile_definitions(SDL2_mixer PRIVATE -DMUSIC_OPUS -DOPUSFILE_HEADER=<opusfile.h>) | |
150 | set(OP_DISABLE_HTTP ON CACHE BOOL "Disable HTTP support") | |
151 | set(OP_DISABLE_EXAMPLES ON CACHE BOOL "Do not build example applications") | |
152 | set(OP_DISABLE_DOCS ON CACHE BOOL "Do not build API documentation") | |
153 | add_subdirectory(external/opus) | |
154 | add_subdirectory(external/opusfile) | |
155 | target_link_libraries(SDL2_mixer PRIVATE opusfile) | |
156 | endif() | |
157 | ||
158 | if (SUPPORT_MP3_MPG123) | |
159 | target_compile_definitions(SDL2_mixer PRIVATE -DMUSIC_MP3_MPG123) | |
160 | add_subdirectory(external/mpg123/ports/cmake) | |
161 | target_include_directories(SDL2_mixer PRIVATE external/mpg123/ports/cmake/src/libmpg123) | |
162 | target_link_libraries(SDL2_mixer PRIVATE libmpg123) | |
163 | endif() | |
164 | ||
165 | if (SUPPORT_MOD_MODPLUG) | |
166 | target_compile_definitions(SDL2_mixer PRIVATE -DMUSIC_MOD_MODPLUG -DMODPLUG_HEADER=<modplug.h>) | |
167 | add_subdirectory(external/libmodplug) | |
168 | target_include_directories(SDL2_mixer PRIVATE external/libmodplug/src) | |
169 | target_link_libraries(SDL2_mixer PRIVATE modplug) | |
170 | endif() | |
171 | ||
172 | if (SUPPORT_MID_TIMIDITY) | |
173 | target_compile_definitions(SDL2_mixer PRIVATE -DMUSIC_MID_TIMIDITY) | |
174 | endif() | |
175 | ||
176 | if(BUILD_SHARED_LIBS) | |
177 | if(WIN32 OR OS2) | |
178 | set_target_properties(SDL2_mixer PROPERTIES PREFIX "") | |
179 | endif() | |
180 | if(APPLE) | |
181 | # TODO: Use DYLIB_COMPATIBILITY_VERSION, DYLIB_CURRENT_VERSION here | |
182 | endif() | |
183 | if(WIN32) | |
184 | target_compile_definitions(SDL2_mixer PRIVATE -DDLL_EXPORT) | |
185 | target_sources(SDL2_mixer PRIVATE version.rc) | |
186 | elseif(OS2) | |
187 | # OS/2 doesn't support a DLL name longer than 8 characters. | |
188 | set_target_properties(SDL2_mixer PROPERTIES | |
189 | OUTPUT_NAME "SDL2mix" | |
190 | ) | |
191 | elseif(UNIX AND NOT ANDROID) | |
192 | # This is compatible with the libtool build | |
193 | set_target_properties(SDL2_mixer PROPERTIES | |
194 | VERSION ${LT_VERSION} | |
195 | SOVERSION ${LT_MAJOR} | |
196 | OUTPUT_NAME "SDL2_mixer-${LT_RELEASE}" | |
197 | ) | |
198 | endif() | |
199 | endif() | |
200 | ||
201 | target_include_directories(SDL2_mixer PUBLIC include) | |
202 | ||
203 | if (BUILD_SHARED_LIBS) | |
204 | target_link_libraries(SDL2_mixer PRIVATE SDL2::SDL2) | |
205 | else() | |
206 | target_link_libraries(SDL2_mixer PRIVATE SDL2::SDL2-static) | |
207 | endif() | |
875 | if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.17") | |
876 | set_target_properties(SDL2::mixer PROPERTIES | |
877 | DEPRECATION "Use SDL2_mixer::SDL2_mixer or SDL2_mixer::SDL2_mixer-static instead" | |
878 | ) | |
879 | endif() |
12 | 12 | mandir = @mandir@ |
13 | 13 | auxdir = @ac_aux_dir@ |
14 | 14 | distpath = $(srcdir)/.. |
15 | distdir = SDL2_mixer-@VERSION@ | |
15 | distdir = @PACKAGE_NAME@-@PACKAGE_VERSION@ | |
16 | 16 | distfile = $(distdir).tar.gz |
17 | 17 | |
18 | 18 | @SET_MAKE@ |
39 | 39 | PLAYMUS_OBJECTS = @PLAYMUS_OBJECTS@ |
40 | 40 | |
41 | 41 | SRC_DIST = \ |
42 | LICENSE.txt \ | |
43 | README.txt \ | |
44 | CHANGES.txt \ | |
45 | 42 | .gitmodules \ |
46 | 43 | Android.mk \ |
44 | CHANGES.txt \ | |
47 | 45 | CMakeLists.txt \ |
46 | LICENSE.txt \ | |
48 | 47 | Makefile.in \ |
49 | 48 | Makefile.os2 \ |
49 | README.txt \ | |
50 | 50 | SDL2_mixer.pc.in \ |
51 | 51 | SDL2_mixer.spec.in \ |
52 | include/SDL_mixer.h \ | |
52 | SDL2_mixerConfig.cmake.in \ | |
53 | 53 | VisualC \ |
54 | 54 | VisualC-WinRT \ |
55 | 55 | Xcode \ |
56 | 56 | acinclude \ |
57 | 57 | autogen.sh \ |
58 | 58 | build-scripts \ |
59 | cmake \ | |
59 | 60 | configure \ |
60 | 61 | configure.ac \ |
61 | 62 | external/download.sh \ |
62 | src \ | |
63 | include/SDL_mixer.h \ | |
64 | mingw \ | |
63 | 65 | playmus.c \ |
64 | 66 | playwave.c \ |
67 | sdl2_mixer-config-version.cmake.in \ | |
68 | sdl2_mixer-config.cmake.in \ | |
69 | src \ | |
65 | 70 | version.rc |
66 | 71 | |
67 | 72 | GEN_DIST = SDL2_mixer.spec |
105 | 110 | done |
106 | 111 | $(SHELL) $(auxdir)/mkinstalldirs $(libdir)/pkgconfig |
107 | 112 | $(INSTALL) -m 644 SDL2_mixer.pc $(libdir)/pkgconfig/ |
113 | $(SHELL) $(auxdir)/mkinstalldirs $(libdir)/cmake/SDL2_mixer/ | |
114 | $(INSTALL) -m 644 sdl2_mixer-config.cmake $(libdir)/cmake/SDL2_mixer | |
115 | $(INSTALL) -m 644 sdl2_mixer-config-version.cmake $(libdir)/cmake/SDL2_mixer | |
108 | 116 | install-lib: $(objects)/$(TARGET) |
109 | 117 | $(SHELL) $(auxdir)/mkinstalldirs $(libdir) |
110 | 118 | $(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(TARGET) $(libdir)/$(TARGET) |
122 | 130 | -rmdir $(includedir)/SDL2 |
123 | 131 | rm -f $(libdir)/pkgconfig/SDL2_mixer.pc |
124 | 132 | -rmdir $(libdir)/pkgconfig |
133 | rm -f $(libdir)/cmake/SDL2_mixer/sdl2_mixer-config.cmake | |
134 | rm -f $(libdir)/cmake/SDL2_mixer/sdl2_mixer-config-version.cmake | |
135 | -rmdir $(libdir)/cmake/SDL2_mixer | |
136 | -rmdir $(libdir)/cmake | |
125 | 137 | uninstall-lib: |
126 | 138 | $(LIBTOOL) --mode=uninstall rm -f $(libdir)/$(TARGET) |
127 | 139 | uninstall-bin: |
6 | 6 | LIBNAME = SDL2mix |
7 | 7 | MAJOR_VERSION = 2 |
8 | 8 | MINOR_VERSION = 5 |
9 | MICRO_VERSION = 1 | |
9 | MICRO_VERSION = 2 | |
10 | 10 | VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION) |
11 | 11 | |
12 | 12 | TITLENAME = $(LIBNAME) $(VERSION) |
30 | 30 | USE_DRFLAC=no |
31 | 31 | # opus music support |
32 | 32 | USE_OPUS=yes |
33 | # mp3 music support (using libmad - Note: GPL license!) | |
34 | USE_LIBMAD=no | |
35 | 33 | # mp3 music support (using mpg123) |
36 | 34 | USE_MPG123=yes |
37 | 35 | # mp3 music support (using dr_mp3) |
40 | 38 | USE_TIMIDITY=yes |
41 | 39 | # midi music support (using fluidsynth) |
42 | 40 | USE_FLUIDSYNTH=no |
43 | # tracker music support (using libmikmod) | |
44 | USE_MIKMOD=no | |
45 | 41 | # tracker music support (using libxmp) |
46 | 42 | USE_XMP=yes |
47 | 43 | # tracker music support (using libmodplug) |
57 | 53 | SRCS+= load_aiff.c load_voc.c music_wav.c & |
58 | 54 | music_ogg.c music_ogg_stb.c music_opus.c & |
59 | 55 | music_flac.c music_drflac.c mp3utils.c & |
60 | music_mad.c music_mpg123.c music_drmp3.c & | |
61 | music_xmp.c music_mikmod.c music_modplug.c & | |
56 | music_mpg123.c music_drmp3.c & | |
57 | music_xmp.c music_modplug.c & | |
62 | 58 | music_fluidsynth.c music_timidity.c |
63 | 59 | # timidity sources: |
64 | 60 | TIMISRCS = common.c instrum.c mix.c output.c playmidi.c readmidi.c resample.c tables.c timidity.c |
127 | 123 | NEED_LIBOGG=yes |
128 | 124 | !endif |
129 | 125 | |
130 | !ifeq USE_LIBMAD yes | |
131 | CFLAGS+= -DMUSIC_MP3_MAD | |
132 | LIBS+= mad.lib | |
133 | !endif | |
134 | 126 | !ifeq USE_MPG123 yes |
135 | 127 | CFLAGS+= -DMUSIC_MP3_MPG123 |
136 | 128 | LIBS+= mpg123.lib |
142 | 134 | !ifeq USE_XMP yes |
143 | 135 | CFLAGS+= -DMUSIC_MOD_XMP |
144 | 136 | LIBS+= libxmp.lib |
145 | !endif | |
146 | !ifeq USE_MIKMOD yes | |
147 | CFLAGS+= -DMUSIC_MOD_MIKMOD | |
148 | LIBS+= mikmod.lib | |
149 | 137 | !endif |
150 | 138 | !ifeq USE_MODPLUG yes |
151 | 139 | CFLAGS+= -DMUSIC_MOD_MODPLUG |
28 | 28 | - When building with Xcode, you can edit the config at the top of the project to enable them, and you will need to include the appropriate framework in your application. |
29 | 29 | - For Android, you can edit the config at the top of Android.mk to enable them. |
30 | 30 | |
31 | The default MP3 support is provided using dr_mp3. SDL_mixer also supports using libmad, but does not use it by default because the libmad license is GPL, which requires your application to also be GPL. If your application has a compatible license, you can enable libmad by passing | |
32 | --enable-music-mp3-mad | |
33 | to configure, or by defining MUSIC_MP3_MAD | |
31 | The default MP3 support is provided using dr_mp3. SDL_mixer also supports using libmpg123: you can enable it by passing --enable-music-mp3-mpg123 to configure. |
0 | 0 | %define name SDL2_mixer |
1 | %define version 2.5.1 | |
1 | %define version | |
2 | 2 | %define release 1 |
3 | 3 | |
4 | 4 | Summary: Simple DirectMedia Layer - Sample Mixer Library |
14 | 14 | %description |
15 | 15 | Due to popular demand, here is a simple multi-channel audio mixer. |
16 | 16 | It supports 4 channels of 16 bit stereo audio, plus a single channel |
17 | of music, mixed by the popular MikMod MOD, Timidity MIDI, Ogg Vorbis, | |
18 | Tremor, libmpg123 and libmad MP3 libraries. | |
17 | of music, mixed by the popular ModPlug, Timidity MIDI, Ogg Vorbis, | |
18 | Tremor, and libmpg123 MP3 libraries. | |
19 | 19 | |
20 | 20 | %package devel |
21 | 21 | Summary: Libraries, includes and more to develop SDL applications. |
25 | 25 | %description devel |
26 | 26 | Due to popular demand, here is a simple multi-channel audio mixer. |
27 | 27 | It supports 4 channels of 16 bit stereo audio, plus a single channel |
28 | of music, mixed by the popular MikMod MOD, Timidity MIDI, Ogg Vorbis, | |
29 | Tremor, libmpg123 and libmad MP3 libraries. | |
28 | of music, mixed by the popular ModPlug, Timidity MIDI, Ogg Vorbis, | |
29 | Tremor, and libmpg123 MP3 libraries. | |
30 | 30 | |
31 | 31 | %prep |
32 | 32 | %setup |
14 | 14 | %description |
15 | 15 | Due to popular demand, here is a simple multi-channel audio mixer. |
16 | 16 | It supports 4 channels of 16 bit stereo audio, plus a single channel |
17 | of music, mixed by the popular MikMod MOD, Timidity MIDI, Ogg Vorbis, | |
18 | Tremor, libmpg123 and libmad MP3 libraries. | |
17 | of music, mixed by the popular ModPlug, Timidity MIDI, Ogg Vorbis, | |
18 | Tremor, and libmpg123 MP3 libraries. | |
19 | 19 | |
20 | 20 | %package devel |
21 | 21 | Summary: Libraries, includes and more to develop SDL applications. |
25 | 25 | %description devel |
26 | 26 | Due to popular demand, here is a simple multi-channel audio mixer. |
27 | 27 | It supports 4 channels of 16 bit stereo audio, plus a single channel |
28 | of music, mixed by the popular MikMod MOD, Timidity MIDI, Ogg Vorbis, | |
29 | Tremor, libmpg123 and libmad MP3 libraries. | |
28 | of music, mixed by the popular ModPlug, Timidity MIDI, Ogg Vorbis, | |
29 | Tremor, and libmpg123 MP3 libraries. | |
30 | 30 | |
31 | 31 | %prep |
32 | 32 | %setup |
0 | # sdl2_mixer cmake project-config input for CMakeLists.txt script | |
1 | ||
2 | include(FeatureSummary) | |
3 | set_package_properties(SDL2_mixer PROPERTIES | |
4 | URL "https://www.libsdl.org/projects/SDL_mixer/" | |
5 | DESCRIPTION "SDL_mixer is a sample multi-channel audio mixer library" | |
6 | ) | |
7 | ||
8 | set(SDL2_mixer_FOUND ON) | |
9 | ||
10 | set(SDL2MIXER_VENDORED @SDL2MIXER_VENDORED@) | |
11 | ||
12 | set(SDL2MIXER_CMD @SDL2MIXER_CMD@) | |
13 | ||
14 | set(SDL2MIXER_FLAC_LIBFLAC @SDL2MIXER_FLAC_LIBFLAC@) | |
15 | set(SDL2MIXER_FLAC_DRFLAC @SDL2MIXER_FLAC_DRFLAC@) | |
16 | ||
17 | set(SDL2MIXER_MOD @SDL2MIXER_MOD@) | |
18 | set(SDL2MIXER_MOD_MODPLUG @SDL2MIXER_MOD_MODPLUG@) | |
19 | set(SDL2MIXER_MOD_XMP @SDL2MIXER_MOD_XMP@) | |
20 | set(SDL2MIXER_MOD_XMP_LITE @SDL2MIXER_MOD_XMP_LITE@) | |
21 | ||
22 | set(SDL2MIXER_MP3 @SDL2MIXER_MP3@) | |
23 | set(SDL2MIXER_MP3_DRMP3 @SDL2MIXER_MP3_DRMP3@) | |
24 | set(SDL2MIXER_MP3_MPG123 @SDL2MIXER_MP3_MPG123@) | |
25 | ||
26 | set(SDL2MIXER_MIDI @SDL2MIXER_MIDI@) | |
27 | set(SDL2MIXER_MIDI_FLUIDSYNTH @SDL2MIXER_MIDI_FLUIDSYNTH@) | |
28 | set(SDL2MIXER_MIDI_NATIVE @SDL2MIXER_MIDI_NATIVE@) | |
29 | set(SDL2MIXER_MIDI_TIMIDITY @SDL2MIXER_MIDI_TIMIDITY@) | |
30 | ||
31 | set(SDL2MIXER_OPUS @SDL2MIXER_OPUS@) | |
32 | ||
33 | set(SDL2MIXER_VORBIS @SDL2MIXER_VORBIS@) | |
34 | set(SDL2MIXER_VORBIS_STB @SDL2MIXER_VORBIS_STB@) | |
35 | set(SDL2MIXER_VORBIS_TREMOR @SDL2MIXER_VORBIS_TREMOR@) | |
36 | set(SDL2MIXER_VORBIS_VORBISFILE @SDL2MIXER_VORBIS_VORBISFILE@) | |
37 | ||
38 | set(SDL2MIXER_WAVE @SDL2MIXER_WAVE@) | |
39 | ||
40 | set(SDL2MIXER_SDL2_REQUIRED_VERSION @SDL_REQUIRED_VERSION@) | |
41 | ||
42 | if(NOT SDL2MIXER_VENDORED) | |
43 | set(_sdl_cmake_module_path "${CMAKE_MODULE_PATH}") | |
44 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") | |
45 | endif() | |
46 | ||
47 | if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2_mixer-shared-targets.cmake") | |
48 | include("${CMAKE_CURRENT_LIST_DIR}/SDL2_mixer-shared-targets.cmake") | |
49 | endif() | |
50 | ||
51 | if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2_mixer-static-targets.cmake") | |
52 | ||
53 | ||
54 | include(CMakeFindDependencyMacro) | |
55 | if(SDL2MIXER_FLAC_LIBFLAC AND NOT SDL2MIXER_VENDORED AND NOT TARGET FLAC::FLAC) | |
56 | find_dependency(FLAC) | |
57 | endif() | |
58 | ||
59 | if(SDL2MIXER_MOD_MODPLUG AND NOT SDL2MIXER_VENDORED AND NOT TARGET modplug::modplug) | |
60 | find_dependency(modplug) | |
61 | endif() | |
62 | ||
63 | if(SDL2MIXER_MOD_XMP AND NOT SDL2MIXER_VENDORED AND NOT TARGET libxmp::libxmp) | |
64 | find_dependency(libxmp) | |
65 | endif() | |
66 | ||
67 | if(SDL2MIXER_MOD_XMP_LITE AND NOT SDL2MIXER_VENDORED AND NOT TARGET libxmp-lite::libxmp-lite) | |
68 | find_dependency(libxmp-lite) | |
69 | endif() | |
70 | ||
71 | if(SDL2MIXER_MP3_MPG123 AND NOT SDL2MIXER_VENDORED AND NOT TARGET MPG123::mpg123) | |
72 | find_dependency(MPG123) | |
73 | endif() | |
74 | ||
75 | if(SDL2MIXER_MIDI_FLUIDSYNTH AND NOT SDL2MIXER_VENDORED AND NOT TARGET FluidSynth::FluidSynth) | |
76 | find_dependency(FluidSynth) | |
77 | endif() | |
78 | ||
79 | if(SDL2MIXER_VORBIS_TREMOR AND NOT SDL2MIXER_VENDORED AND NOT TARGET tremor::tremor) | |
80 | find_dependency(tremor) | |
81 | endif() | |
82 | ||
83 | if(SDL2MIXER_VORBIS_VORBISFILE AND NOT SDL2MIXER_VENDORED AND NOT TARGET vorbisfile::vorbisfile) | |
84 | find_dependency(vorbisfile) | |
85 | endif() | |
86 | ||
87 | if((NOT SDL2MIXER_VENDORED AND SDL2MIXER_MOD_MODPLUG) OR (HAIKU AND SDL2MIXER_MIDI_NATIVE)) | |
88 | include(CheckLanguage) | |
89 | check_language(CXX) | |
90 | if(NOT CMAKE_CXX_COMPILER) | |
91 | message(WARNING "CXX language not enabled. Linking to SDL2_mixer::SDL2_mixer-static might fail.") | |
92 | endif() | |
93 | endif() | |
94 | include("${CMAKE_CURRENT_LIST_DIR}/SDL2_mixer-static-targets.cmake") | |
95 | endif() | |
96 | ||
97 | if(NOT SDL2MIXER_VENDORED) | |
98 | set(CMAKE_MODULE_PATH "${_sdl_cmake_module_path}") | |
99 | unset(_sdl_cmake_module_path) | |
100 | endif() |
0 | # Common variables for FindSDL2*.cmake modules | |
1 | ||
2 | set(_inc_suffixes include) | |
3 | set(_lib_suffixes) | |
4 | if(MSVC) | |
5 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) | |
6 | list(APPEND _lib_suffixes "lib/x86") | |
7 | endif() | |
8 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) | |
9 | list(APPEND _lib_suffixes "lib/x64") | |
10 | endif() | |
11 | endif() | |
12 | if(MINGW) | |
13 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) | |
14 | list(APPEND _lib_suffixes "i686-w64-mingw32/lib") | |
15 | list(APPEND _inc_suffixes "i686-w64-mingw32/include") | |
16 | endif() | |
17 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) | |
18 | list(APPEND _lib_suffixes "x86_46-w64-mingw32/lib") | |
19 | list(APPEND _inc_suffixes "x86_46-w64-mingw32/include") | |
20 | endif() | |
21 | endif()⏎ |
0 | include(FindPackageHandleStandardArgs) | |
1 | ||
2 | find_library(FLAC_LIBRARY | |
3 | NAMES FLAC | |
4 | ) | |
5 | ||
6 | find_path(FLAC_INCLUDE_PATH | |
7 | NAMES FLAC/all.h | |
8 | ) | |
9 | ||
10 | set(FLAC_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of FLAC") | |
11 | ||
12 | set(FLAC_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of FLAC") | |
13 | ||
14 | set(FLAC_LINK_FLAGS "" CACHE STRING "Extra link flags of FLAC") | |
15 | ||
16 | find_package_handle_standard_args(FLAC | |
17 | REQUIRED_VARS FLAC_LIBRARY FLAC_INCLUDE_PATH | |
18 | ) | |
19 | ||
20 | if(FLAC_FOUND) | |
21 | if(NOT TARGET FLAC::FLAC) | |
22 | add_library(FLAC::FLAC UNKNOWN IMPORTED) | |
23 | set_target_properties(FLAC::FLAC PROPERTIES | |
24 | IMPORTED_LOCATION "${FLAC_LIBRARY}" | |
25 | INTERFACE_INCLUDE_DIRECTORIES "${FLAC_INCLUDE_PATH}" | |
26 | INTERFACE_COMPILE_OPTIONS "${FLAC_COMPILE_OPTIONS}" | |
27 | INTERFACE_LINK_LIBRARIES "${FLAC_LINK_LIBRARIES}" | |
28 | INTERFACE_LINK_FLAGS "${FLAC_LINK_FLAGS}" | |
29 | ) | |
30 | endif() | |
31 | endif() |
0 | include(FindPackageHandleStandardArgs) | |
1 | ||
2 | find_library(FluidSynth_LIBRARY | |
3 | NAMES fluidsynth | |
4 | ) | |
5 | ||
6 | find_path(FluidSynth_INCLUDE_PATH | |
7 | NAMES fluidsynth.h | |
8 | ) | |
9 | ||
10 | set(FluidSynth_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of FluidSynth") | |
11 | ||
12 | set(FluidSynth_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of FluidSynth") | |
13 | ||
14 | set(FluidSynth_LINK_FLAGS "" CACHE STRING "Extra link flags of FluidSynth") | |
15 | ||
16 | find_package_handle_standard_args(FluidSynth | |
17 | REQUIRED_VARS FluidSynth_LIBRARY FluidSynth_INCLUDE_PATH | |
18 | ) | |
19 | ||
20 | if(FluidSynth_FOUND) | |
21 | if(NOT TARGET FluidSynth::FluidSynth) | |
22 | add_library(FluidSynth::FluidSynth UNKNOWN IMPORTED) | |
23 | set_target_properties(FluidSynth::FluidSynth PROPERTIES | |
24 | IMPORTED_LOCATION "${FluidSynth_LIBRARY}" | |
25 | INTERFACE_INCLUDE_DIRECTORIES "${FluidSynth_INCLUDE_PATH}" | |
26 | INTERFACE_COMPILE_OPTIONS "${FluidSynth_COMPILE_OPTIONS}" | |
27 | INTERFACE_LINK_LIBRARIES "${FluidSynth_LINK_LIBRARIES}" | |
28 | INTERFACE_LINK_FLAGS "${FluidSynth_LINK_FLAGS}" | |
29 | ) | |
30 | endif() | |
31 | endif() |
0 | include(FindPackageHandleStandardArgs) | |
1 | ||
2 | find_library(MPG123_LIBRARY | |
3 | NAMES mpg123 | |
4 | ) | |
5 | ||
6 | find_path(MPG123_INCLUDE_PATH | |
7 | NAMES mpg123.h | |
8 | ) | |
9 | ||
10 | set(MPG123_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of mpg123") | |
11 | ||
12 | set(MPG123_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of mpg123") | |
13 | ||
14 | set(MPG123_LINK_FLAGS "" CACHE STRING "Extra link flags of mpg123") | |
15 | ||
16 | find_package_handle_standard_args(MPG123 | |
17 | REQUIRED_VARS MPG123_LIBRARY MPG123_INCLUDE_PATH | |
18 | ) | |
19 | ||
20 | if (MPG123_FOUND) | |
21 | if (NOT TARGET MPG123::mpg123) | |
22 | add_library(MPG123::mpg123 UNKNOWN IMPORTED) | |
23 | set_target_properties(MPG123::mpg123 PROPERTIES | |
24 | IMPORTED_LOCATION "${MPG123_LIBRARY}" | |
25 | INTERFACE_INCLUDE_DIRECTORIES "${MPG123_INCLUDE_PATH}" | |
26 | INTERFACE_COMPILE_OPTIONS "${MPG123_COMPILE_OPTIONS}" | |
27 | INTERFACE_LINK_LIBRARIES "${MPG123_LINK_LIBRARIES}" | |
28 | INTERFACE_LINK_FLAGS "${MPG123_LINK_FLAGS}" | |
29 | ) | |
30 | endif() | |
31 | endif() |
0 | # FIXME: this should be provided by SDL2 | |
1 | ||
2 | include(FindPackageHandleStandardArgs) | |
3 | include("${CMAKE_CURRENT_LIST_DIR}/CommonFindSDL2.cmake") | |
4 | ||
5 | find_library(SDL2_LIBRARY | |
6 | NAMES SDL2 | |
7 | HINTS ${SDL2_DIR} ENV SDL2_DIR | |
8 | PATH_SUFFIXES ${_lib_suffixes} | |
9 | ) | |
10 | ||
11 | find_path(SDL2_INCLUDE_DIR | |
12 | NAMES SDL_haptic.h | |
13 | PATH_SUFFIXES SDL2 | |
14 | HINTS ${SDL2_DIR} ENV SDL2_DIR | |
15 | PATH_SUFFIXES ${_inc_suffixes} | |
16 | ) | |
17 | ||
18 | set(SDL2_VERSION) | |
19 | if(SDL2_INCLUDE_DIR) | |
20 | file(READ "${SDL2_INCLUDE_DIR}/SDL_version.h" _sdl_version_h) | |
21 | string(REGEX MATCH "#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)" _sdl2_major_re "${_sdl_version_h}") | |
22 | set(_sdl2_major "${CMAKE_MATCH_1}") | |
23 | string(REGEX MATCH "#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)" _sdl2_minor_re "${_sdl_version_h}") | |
24 | set(_sdl2_minor "${CMAKE_MATCH_1}") | |
25 | string(REGEX MATCH "#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)" _sdl2_patch_re "${_sdl_version_h}") | |
26 | set(_sdl2_patch "${CMAKE_MATCH_1}") | |
27 | if(_sdl2_major_re AND _sdl2_minor_re AND _sdl2_patch_re) | |
28 | set(SDL2_VERSION "${_sdl2_major}.${_sdl2_minor}.${_sdl2_patch}") | |
29 | endif() | |
30 | endif() | |
31 | ||
32 | find_package_handle_standard_args(PrivateSDL2 | |
33 | REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR | |
34 | VERSION_VAR SDL2_VERSION | |
35 | ) | |
36 | ||
37 | if(PrivateSDL2_FOUND) | |
38 | if(NOT TARGET PrivateSDL2::PrivateSDL2) | |
39 | add_library(PrivateSDL2::PrivateSDL2 UNKNOWN IMPORTED) | |
40 | set_target_properties(PrivateSDL2::PrivateSDL2 PROPERTIES | |
41 | INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}" | |
42 | IMPORTED_LINK_INTERFACE_LANGUAGES "C" | |
43 | IMPORTED_LOCATION "${SDL2_LIBRARY}" | |
44 | ) | |
45 | endif() | |
46 | endif() |
0 | # FIXME: this should be provided by SDL2 | |
1 | ||
2 | include(FindPackageHandleStandardArgs) | |
3 | include("${CMAKE_CURRENT_LIST_DIR}/CommonFindSDL2.cmake") | |
4 | ||
5 | find_library(SDL2_MAIN_LIBRARY | |
6 | NAMES SDL2main | |
7 | HINTS ${SDL2_DIR} ENV SDL2_DIR | |
8 | PATH_SUFFIXES ${_lib_suffixes} | |
9 | ) | |
10 | ||
11 | find_package_handle_standard_args(SDL2main | |
12 | REQUIRED_VARS SDL2_MAIN_LIBRARY | |
13 | ) | |
14 | ||
15 | if(SDL2main_FOUND) | |
16 | if(NOT TARGET SDL2::SDL2main) | |
17 | add_library(SDL2::SDL2main UNKNOWN IMPORTED) | |
18 | set_target_properties(SDL2::SDL2main PROPERTIES | |
19 | IMPORTED_LINK_INTERFACE_LANGUAGES "C" | |
20 | IMPORTED_LOCATION "${SDL2_MAIN_LIBRARY}" | |
21 | ) | |
22 | endif() | |
23 | endif() |
0 | find_library(libxmp_lite_LIBRARY | |
1 | NAMES xmp | |
2 | ) | |
3 | ||
4 | find_path(libxmp_lite_INCLUDE_PATH | |
5 | NAMES xmp.h | |
6 | ) | |
7 | ||
8 | set(libxmp_lite_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of libxmp_lite") | |
9 | ||
10 | set(libxmp_lite_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of libxmp_lite") | |
11 | ||
12 | set(libxmp_lite_LINK_FLAGS "" CACHE STRING "Extra link flags of libxmp_lite") | |
13 | ||
14 | find_package_handle_standard_args(libxmp_lite | |
15 | REQUIRED_VARS libxmp_lite_LIBRARY libxmp_lite_INCLUDE_PATH | |
16 | ) | |
17 | ||
18 | if(libxmp_lite_FOUND) | |
19 | if(NOT TARGET libxmp-lite::libxmp-lite) | |
20 | add_library(libxmp-lite::libxmp-lite UNKNOWN IMPORTED) | |
21 | set_target_properties(libxmp_lite::libxmp_lite-shared PROPERTIES | |
22 | IMPORTED_LOCATION "${libxmp_lite_LIBRARY}" | |
23 | INTERFACE_INCLUDE_DIRECTORIES "${libxmp_lite_INCLUDE_PATH}" | |
24 | INTERFACE_COMPILE_OPTIONS "${libxmp_lite_COMPILE_OPTIONS}" | |
25 | INTERFACE_LINK_LIBRARIES "${libxmp_lite_LINK_LIBRARIES}" | |
26 | INTERFACE_LINK_FLAGS "${libxmp_lite_LINK_FLAGS}" | |
27 | ) | |
28 | endif() | |
29 | endif() | |
30 | endif() |
0 | find_library(libxmp_LIBRARY | |
1 | NAMES xmp | |
2 | ) | |
3 | ||
4 | find_path(libxmp_INCLUDE_PATH | |
5 | NAMES xmp.h | |
6 | ) | |
7 | ||
8 | set(libxmp_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of libxmp") | |
9 | ||
10 | set(libxmp_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of libxmp") | |
11 | ||
12 | set(libxmp_LINK_FLAGS "" CACHE STRING "Extra link flags of libxmp") | |
13 | ||
14 | find_package_handle_standard_args(libxmp | |
15 | REQUIRED_VARS libxmp_LIBRARY libxmp_INCLUDE_PATH | |
16 | ) | |
17 | ||
18 | if(libxmp_FOUND) | |
19 | if(NOT TARGET libxmp::libxmp) | |
20 | add_library(libxmp::libxmp UNKNOWN IMPORTED) | |
21 | set_target_properties(libxmp::libxmp PROPERTIES | |
22 | IMPORTED_LOCATION "${libxmp_LIBRARY}" | |
23 | INTERFACE_INCLUDE_DIRECTORIES "${libxmp_INCLUDE_PATH}" | |
24 | INTERFACE_COMPILE_OPTIONS "${libxmp_COMPILE_OPTIONS}" | |
25 | INTERFACE_LINK_LIBRARIES "${libxmp_LINK_LIBRARIES}" | |
26 | INTERFACE_LINK_FLAGS "${libxmp_LINK_FLAGS}" | |
27 | ) | |
28 | endif() | |
29 | endif() |
0 | include(FindPackageHandleStandardArgs) | |
1 | ||
2 | find_library(modplug_LIBRARY | |
3 | NAMES modplug | |
4 | ) | |
5 | ||
6 | find_path(modplug_INCLUDE_PATH | |
7 | NAMES libmodplug/modplug.h | |
8 | ) | |
9 | ||
10 | set(modplug_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of modplug") | |
11 | ||
12 | set(modplug_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of modplug") | |
13 | ||
14 | set(modplug_LINK_FLAGS "" CACHE STRING "Extra link flags of modplug") | |
15 | ||
16 | find_package_handle_standard_args(modplug | |
17 | REQUIRED_VARS modplug_LIBRARY modplug_INCLUDE_PATH | |
18 | ) | |
19 | ||
20 | if (modplug_FOUND) | |
21 | if (NOT TARGET modplug::modplug) | |
22 | add_library(modplug::modplug UNKNOWN IMPORTED) | |
23 | set_target_properties(modplug::modplug PROPERTIES | |
24 | IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" | |
25 | IMPORTED_LOCATION "${modplug_LIBRARY}" | |
26 | INTERFACE_INCLUDE_DIRECTORIES "${modplug_INCLUDE_PATH}" | |
27 | INTERFACE_COMPILE_OPTIONS "${modplug_COMPILE_OPTIONS}" | |
28 | INTERFACE_LINK_LIBRARIES "${modplug_LINK_LIBRARIES}" | |
29 | INTERFACE_LINK_FLAGS "${modplug_LINK_FLAGS}" | |
30 | ) | |
31 | endif() | |
32 | endif() |
0 | include(FindPackageHandleStandardArgs) | |
1 | ||
2 | find_library(opusfile_LIBRARY | |
3 | NAMES opusfile | |
4 | ) | |
5 | ||
6 | set(opusfile_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of opusfile") | |
7 | ||
8 | set(opusfile_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of opusfile") | |
9 | ||
10 | set(opusfile_LINK_FLAGS "" CACHE STRING "Extra link flags of opusfile") | |
11 | ||
12 | find_path(opusfile_INCLUDE_PATH | |
13 | NAMES opusfile.h | |
14 | PATH_SUFFIXES opus | |
15 | ) | |
16 | ||
17 | find_package_handle_standard_args(opusfile | |
18 | REQUIRED_VARS opusfile_LIBRARY opusfile_INCLUDE_PATH | |
19 | ) | |
20 | ||
21 | if (opusfile_FOUND) | |
22 | set(opusfile_dirs ${opusfile_INCLUDE_PATH}) | |
23 | if(EXISTS "${opusfile_INCLUDE_PATH}/opus") | |
24 | list(APPEND opusfile_dirs "${opusfile_INCLUDE_PATH}/opus") | |
25 | endif() | |
26 | if (NOT TARGET opusfile::opusfile) | |
27 | add_library(opusfile::opusfile UNKNOWN IMPORTED) | |
28 | set_target_properties(opusfile::opusfile PROPERTIES | |
29 | IMPORTED_LOCATION "${opusfile_LIBRARY}" | |
30 | INTERFACE_INCLUDE_DIRECTORIES "${opusfile_dirs}" | |
31 | INTERFACE_COMPILE_OPTIONS "${opusfile_COMPILE_OPTIONS}" | |
32 | INTERFACE_LINK_LIBRARIES "${opusfile_LINK_LIBRARIES}" | |
33 | INTERFACE_LINK_FLAGS "${opusfile_LINK_FLAGS}" | |
34 | ) | |
35 | endif() | |
36 | endif() |
0 | include(FindPackageHandleStandardArgs) | |
1 | ||
2 | find_library(tremor_LIBRARY | |
3 | NAMES vorbisidec libvorbisidec | |
4 | ) | |
5 | ||
6 | find_path(tremor_INCLUDE_PATH | |
7 | NAMES tremor/ivorbisfile.h | |
8 | ) | |
9 | ||
10 | set(tremor_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of vorbis") | |
11 | ||
12 | set(tremor_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of vorbis") | |
13 | ||
14 | set(tremor_LINK_FLAGS "" CACHE STRING "Extra link flags of vorbis") | |
15 | ||
16 | find_package_handle_standard_args(tremor | |
17 | REQUIRED_VARS tremor_LIBRARY tremor_INCLUDE_PATH | |
18 | ) | |
19 | ||
20 | if (tremor_FOUND) | |
21 | if (NOT TARGET tremor::tremor) | |
22 | add_library(tremor::tremor UNKNOWN IMPORTED) | |
23 | set_target_properties(tremor::tremor PROPERTIES | |
24 | IMPORTED_LOCATION "${tremor_LIBRARY}" | |
25 | INTERFACE_INCLUDE_DIRECTORIES "${tremor_INCLUDE_PATH}" | |
26 | INTERFACE_COMPILE_OPTIONS "${tremor_COMPILE_OPTIONS}" | |
27 | INTERFACE_LINK_LIBRARIES "${tremor_LINK_LIBRARIES}" | |
28 | INTERFACE_LINK_FLAGS "${tremor_LINK_FLAGS}" | |
29 | ) | |
30 | endif() | |
31 | endif() |
0 | include(FindPackageHandleStandardArgs) | |
1 | ||
2 | find_library(vorbisfile_LIBRARY | |
3 | NAMES vorbisfile | |
4 | ) | |
5 | ||
6 | set(vorbisfile_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of vorbisfile") | |
7 | ||
8 | set(vorbisfile_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of vorbisfile") | |
9 | ||
10 | set(vorbisfile_LINK_FLAGS "" CACHE STRING "Extra link flags of vorbisfile") | |
11 | ||
12 | find_path(vorbisfile_INCLUDE_PATH | |
13 | NAMES vorbis/vorbisfile.h | |
14 | ) | |
15 | ||
16 | find_package_handle_standard_args(vorbisfile | |
17 | REQUIRED_VARS vorbisfile_LIBRARY vorbisfile_INCLUDE_PATH | |
18 | ) | |
19 | ||
20 | if (vorbisfile_FOUND) | |
21 | if (NOT TARGET vorbisfile::vorbisfile) | |
22 | add_library(vorbisfile::vorbisfile UNKNOWN IMPORTED) | |
23 | set_target_properties(vorbisfile::vorbisfile PROPERTIES | |
24 | IMPORTED_LOCATION "${vorbisfile_LIBRARY}" | |
25 | INTERFACE_INCLUDE_DIRECTORIES "${vorbisfile_INCLUDE_PATH}" | |
26 | INTERFACE_COMPILE_OPTIONS "${vorbisfile_COMPILE_OPTIONS}" | |
27 | INTERFACE_LINK_LIBRARIES "${vorbisfile_LINK_LIBRARIES}" | |
28 | INTERFACE_LINK_FLAGS "${vorbisfile_LINK_FLAGS}" | |
29 | ) | |
30 | endif() | |
31 | endif() |
0 | # This file is shared amongst SDL_image/SDL_mixer/SDL_net/SDL_ttf | |
1 | ||
2 | macro(sdl_calculate_derived_version_variables) | |
3 | if (NOT DEFINED MAJOR_VERSION OR NOT DEFINED MINOR_VERSION OR NOT DEFINED MICRO_VERSION) | |
4 | message(FATAL_ERROR "MAJOR_VERSION, MINOR_VERSION and MICRO_VERSION need to be defined") | |
5 | endif() | |
6 | ||
7 | set(FULL_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}") | |
8 | ||
9 | # Calculate a libtool-like version number | |
10 | math(EXPR BINARY_AGE "${MINOR_VERSION} * 100 + ${MICRO_VERSION}") | |
11 | math(EXPR IS_DEVELOPMENT "${MINOR_VERSION} % 2") | |
12 | if (IS_DEVELOPMENT) | |
13 | # Development branch, 2.5.1 -> libSDL2_XXXXX-2.0.so.0.501.0 | |
14 | set(INTERFACE_AGE 0) | |
15 | else() | |
16 | # Stable branch, 2.6.1 -> libSDL2_XXXXX-2.0.so.0.600.1 | |
17 | set(INTERFACE_AGE ${MICRO_VERSION}) | |
18 | endif() | |
19 | ||
20 | # Increment this if there is an incompatible change - but if that happens, | |
21 | # we should rename the library from SDL2 to SDL3, at which point this would | |
22 | # reset to 0 anyway. | |
23 | set(LT_MAJOR "0") | |
24 | ||
25 | math(EXPR LT_AGE "${BINARY_AGE} - ${INTERFACE_AGE}") | |
26 | math(EXPR LT_CURRENT "${LT_MAJOR} + ${LT_AGE}") | |
27 | set(LT_REVISION "${INTERFACE_AGE}") | |
28 | # For historical reasons, the library name redundantly includes the major | |
29 | # version twice: libSDL2_XXXXX-2.0.so.0. | |
30 | # TODO: in SDL 3, set the OUTPUT_NAME to plain SDL3_XXXXX, which will simplify | |
31 | # it to libSDL2_XXXXX.so.0 | |
32 | set(LT_RELEASE "2.0") | |
33 | set(LT_VERSION "${LT_MAJOR}.${LT_AGE}.${LT_REVISION}") | |
34 | ||
35 | # The following should match the versions in the Xcode project file. | |
36 | # Each version is 1 higher than you might expect, for compatibility | |
37 | # with libtool: macOS ABI versioning is 1-based, unlike other platforms | |
38 | # which are normally 0-based. | |
39 | math(EXPR DYLIB_CURRENT_VERSION_MAJOR "${LT_MAJOR} + ${LT_AGE} + 1") | |
40 | math(EXPR DYLIB_CURRENT_VERSION_MINOR "${LT_REVISION}") | |
41 | math(EXPR DYLIB_COMPAT_VERSION_MAJOR "${LT_MAJOR} + 1") | |
42 | set(DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.${DYLIB_CURRENT_VERSION_MINOR}.0") | |
43 | endmacro() | |
44 | ||
45 | macro(sdl_find_sdl2 TARGET VERSION) | |
46 | if(NOT TARGET ${TARGET}) | |
47 | # FIXME: can't add REQUIRED since not all SDL2 installs ship SDL2ConfigVersion.cmake (or sdl2-config-version.cmake) | |
48 | find_package(SDL2 ${VERSION} QUIET) | |
49 | endif() | |
50 | if(NOT TARGET ${TARGET}) | |
51 | # FIXME: can't add REQUIRED since not all SDL2 installs ship SDL2Config.cmake (or sdl2-config.cmake) | |
52 | find_package(SDL2 QUIET) | |
53 | if(SDL2_FOUND) | |
54 | message(WARNING "Could not verify SDL2 version. Assuming SDL2 has version of at least ${VERSION}.") | |
55 | endif() | |
56 | endif() | |
57 | ||
58 | # Use Private FindSDL2.cmake module to find SDL2 for installations where no SDL2Config.cmake is available, | |
59 | # or for those installations where no target is generated. | |
60 | if (NOT TARGET ${TARGET}) | |
61 | message(STATUS "Using private SDL2 find module") | |
62 | find_package(PrivateSDL2 ${VERSION} REQUIRED) | |
63 | add_library(${TARGET} INTERFACE IMPORTED) | |
64 | set_target_properties(${TARGET} PROPERTIES | |
65 | INTERFACE_LINK_LIBRARIES "PrivateSDL2::PrivateSDL2" | |
66 | ) | |
67 | endif() | |
68 | endmacro() | |
69 | ||
70 | function(read_absolute_symlink DEST PATH) | |
71 | file(READ_SYMLINK "${PATH}" p) | |
72 | if (NOT IS_ABSOLUTE p) | |
73 | get_filename_component(pdir "${PATH}" DIRECTORY) | |
74 | set(p "${pdir}/${p}") | |
75 | endif() | |
76 | set("${DEST}" "${p}" PARENT_SCOPE) | |
77 | endfunction() | |
78 | ||
79 | function(win32_implib_identify_dll DEST IMPLIB) | |
80 | cmake_parse_arguments(ARGS "NOTFATAL" "" "" ${ARGN}) | |
81 | if (CMAKE_DLLTOOL) | |
82 | execute_process( | |
83 | COMMAND "${CMAKE_DLLTOOL}" --identify "${IMPLIB}" | |
84 | RESULT_VARIABLE retcode | |
85 | OUTPUT_VARIABLE stdout | |
86 | ERROR_VARIABLE stderr) | |
87 | if (NOT retcode EQUAL 0) | |
88 | if (NOT ARGS_NOTFATAL) | |
89 | message(FATAL_ERROR "${CMAKE_DLLTOOL} failed.") | |
90 | else() | |
91 | set("${DEST}" "${DEST}-NOTFOUND" PARENT_SCOPE) | |
92 | return() | |
93 | endif() | |
94 | endif() | |
95 | string(STRIP "${stdout}" result) | |
96 | set(${DEST} "${result}" PARENT_SCOPE) | |
97 | elseif (MSVC) | |
98 | get_filename_component(CMAKE_C_COMPILER_DIRECTORY "${CMAKE_C_COMPILER}" DIRECTORY CACHE) | |
99 | find_program(CMAKE_DUMPBIN NAMES dumpbin PATHS "${CMAKE_C_COMPILER_DIRECTORY}") | |
100 | if (CMAKE_DUMPBIN) | |
101 | execute_process( | |
102 | COMMAND "${CMAKE_DUMPBIN}" "-headers" "${IMPLIB}" | |
103 | RESULT_VARIABLE retcode | |
104 | OUTPUT_VARIABLE stdout | |
105 | ERROR_VARIABLE stderr) | |
106 | if (NOT retcode EQUAL 0) | |
107 | if (NOT ARGS_NOTFATAL) | |
108 | message(FATAL_ERROR "dumpbin failed.") | |
109 | else() | |
110 | set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE) | |
111 | return() | |
112 | endif() | |
113 | endif() | |
114 | string(REGEX MATCH "DLL name[ ]+:[ ]+([^\n]+)\n" match "${stdout}") | |
115 | if (NOT match) | |
116 | if (NOT ARGS_NOTFATAL) | |
117 | message(FATAL_ERROR "dumpbin did not find any associated dll for ${IMPLIB}.") | |
118 | else() | |
119 | set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE) | |
120 | return() | |
121 | endif() | |
122 | endif() | |
123 | set(result "${CMAKE_MATCH_1}") | |
124 | set(${DEST} "${result}" PARENT_SCOPE) | |
125 | else() | |
126 | message(FATAL_ERROR "Cannot find dumpbin, please set CMAKE_DUMPBIN cmake variable") | |
127 | endif() | |
128 | else() | |
129 | if (NOT ARGS_NOTFATAL) | |
130 | message(FATAL_ERROR "Don't know how to identify dll from import library. Set CMAKE_DLLTOOL (for mingw) or CMAKE_DUMPBIN (for MSVC)") | |
131 | else() | |
132 | set(${DEST} "${DEST}-NOTFOUND") | |
133 | endif() | |
134 | endif() | |
135 | endfunction() | |
136 | ||
137 | function(target_get_dynamic_library DEST TARGET) | |
138 | set(result) | |
139 | get_target_property(alias "${TARGET}" ALIASED_TARGET) | |
140 | while (alias) | |
141 | set(TARGET "${alias}") | |
142 | get_target_property(alias "${TARGET}" ALIASED_TARGET) | |
143 | endwhile() | |
144 | if (WIN32) | |
145 | # Use the target dll of the import library | |
146 | set(props_to_check IMPORTED_IMPLIB) | |
147 | if (CMAKE_BUILD_TYPE) | |
148 | list(APPEND props_to_check IMPORTED_IMPLIB_${CMAKE_BUILD_TYPE}) | |
149 | endif() | |
150 | list(APPEND props_to_check IMPORTED_LOCATION) | |
151 | if (CMAKE_BUILD_TYPE) | |
152 | list(APPEND props_to_check IMPORTED_LOCATION_${CMAKE_BUILD_TYPE}) | |
153 | endif() | |
154 | foreach (config_type ${CMAKE_CONFIGURATION_TYPES} RELEASE DEBUG RELWITHDEBINFO MINSIZEREL) | |
155 | list(APPEND props_to_check IMPORTED_IMPLIB_${config_type}) | |
156 | list(APPEND props_to_check IMPORTED_LOCATION_${config_type}) | |
157 | endforeach() | |
158 | ||
159 | foreach(prop_to_check ${props_to_check}) | |
160 | if (NOT result) | |
161 | get_target_property(propvalue "${TARGET}" ${prop_to_check}) | |
162 | if (propvalue AND EXISTS "${propvalue}") | |
163 | win32_implib_identify_dll(result "${propvalue}" NOTFATAL) | |
164 | endif() | |
165 | endif() | |
166 | endforeach() | |
167 | else() | |
168 | # 1. find the target library a file might be symbolic linking to | |
169 | # 2. find all other files in the same folder that symolic link to it | |
170 | # 3. sort all these files, and select the 2nd item | |
171 | set(props_to_check IMPORTED_LOCATION) | |
172 | if (CMAKE_BUILD_TYPE) | |
173 | list(APPEND props_to_check IMPORTED_LOCATION_${CMAKE_BUILD_TYPE}) | |
174 | endif() | |
175 | foreach (config_type ${CMAKE_CONFIGURATION_TYPES} RELEASE DEBUG RELWITHDEBINFO MINSIZEREL) | |
176 | list(APPEND props_to_check IMPORTED_LOCATION_${config_type}) | |
177 | endforeach() | |
178 | foreach(prop_to_check ${props_to_check}) | |
179 | if (NOT result) | |
180 | get_target_property(propvalue "${TARGET}" ${prop_to_check}) | |
181 | if (EXISTS "${propvalue}") | |
182 | while (IS_SYMLINK "${propvalue}") | |
183 | read_absolute_symlink(propvalue "${propvalue}") | |
184 | endwhile() | |
185 | get_filename_component(libdir "${propvalue}" DIRECTORY) | |
186 | file(GLOB subfiles "${libdir}/*") | |
187 | set(similar_files "${propvalue}") | |
188 | foreach(subfile ${subfiles}) | |
189 | if (IS_SYMLINK "${subfile}") | |
190 | read_absolute_symlink(subfile_target "${subfile}") | |
191 | if (subfile_target STREQUAL propvalue) | |
192 | list(APPEND similar_files "${subfile}") | |
193 | endif() | |
194 | endif() | |
195 | endforeach() | |
196 | list(SORT similar_files) | |
197 | list(LENGTH similar_files eq_length) | |
198 | if (eq_length GREATER 1) | |
199 | list(GET similar_files 1 item) | |
200 | else() | |
201 | list(GET similar_files 0 item) | |
202 | endif() | |
203 | get_filename_component(result "${item}" NAME) | |
204 | endif() | |
205 | endif() | |
206 | endforeach() | |
207 | endif() | |
208 | if (NOT result) | |
209 | set (result "$<TARGET_FILE_NAME:${TARGET}>") | |
210 | endif() | |
211 | set(${DEST} ${result} PARENT_SCOPE) | |
212 | endfunction() | |
213 | ||
214 | macro(sdl_check_project_in_subfolder relative_subfolder name vendored_option) | |
215 | if(NOT EXISTS "${PROJECT_SOURCE_DIR}/${relative_subfolder}/CMakeLists.txt") | |
216 | message(FATAL_ERROR "No cmake project for ${name} found in ${relative_subfolder}.\n" | |
217 | "Run the download script in the external folder, or re-configure with -D${vendored_option}=OFF to use system packages.") | |
218 | endif() | |
219 | endmacro() | |
220 | ||
221 | macro(sdl_check_linker_flag flag var) | |
222 | # FIXME: Use CheckLinkerFlag module once cmake minimum version >= 3.18 | |
223 | include(CMakePushCheckState) | |
224 | include(CheckCSourceCompiles) | |
225 | cmake_push_check_state(RESET) | |
226 | set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--no-undefined") | |
227 | check_c_source_compiles("int main() { return 0; }" ${var}) | |
228 | cmake_pop_check_state() | |
229 | endmacro() | |
230 | ||
231 | function(sdl_target_link_options_no_undefined TARGET) | |
232 | if(NOT MSVC) | |
233 | if(CMAKE_C_COMPILER_ID MATCHES "AppleClang") | |
234 | target_link_options(${TARGET} PRIVATE "-Wl,-undefined,error") | |
235 | else() | |
236 | sdl_check_linker_flag("-Wl,--no-undefined" HAVE_WL_NO_UNDEFINED) | |
237 | if(HAVE_WL_NO_UNDEFINED) | |
238 | target_link_options(${TARGET} PRIVATE "-Wl,--no-undefined") | |
239 | endif() | |
240 | endif() | |
241 | endif() | |
242 | endfunction() |
0 | # This cmake build script is meant for verifying the various CMake configuration script. | |
1 | ||
2 | cmake_minimum_required(VERSION 3.12) | |
3 | project(sdl_test LANGUAGES C) | |
4 | ||
5 | cmake_policy(SET CMP0074 NEW) | |
6 | ||
7 | # Override CMAKE_FIND_ROOT_PATH_MODE to allow search for SDL2_mixer outside of sysroot | |
8 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) | |
9 | ||
10 | include(FeatureSummary) | |
11 | ||
12 | option(TEST_SHARED "Test linking to shared SDL2_mixer library" ON) | |
13 | add_feature_info("TEST_SHARED" TEST_SHARED "Test linking with shared library") | |
14 | ||
15 | option(TEST_STATIC "Test linking to static SDL2_mixer libary" ON) | |
16 | add_feature_info("TEST_STATIC" TEST_STATIC "Test linking with static library") | |
17 | ||
18 | if(TEST_SHARED) | |
19 | # FIXME: in the distant future, must become REQUIRED | |
20 | find_package(SDL2 CONFIG COMPONENTS SDL2) | |
21 | # FIXME: and the following should be removed | |
22 | if(NOT TARGET SDL2::SDL2) | |
23 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/..") | |
24 | include(PrivateSdlFunctions) | |
25 | sdl_find_sdl2(SDL2::SDL2 2.0) | |
26 | endif() | |
27 | find_package(SDL2_mixer REQUIRED CONFIG) | |
28 | add_executable(main_shared main.c) | |
29 | target_link_libraries(main_shared PRIVATE SDL2::SDL2 SDL2_mixer::SDL2_mixer) | |
30 | endif() | |
31 | ||
32 | if(TEST_STATIC) | |
33 | # FIXME: in the distant future, must become REQUIRED | |
34 | find_package(SDL2 CONFIG COMPONENTS SDL2-static) | |
35 | # FIXME: and the following should be removed | |
36 | if(NOT TARGET SDL2::SDL2-static) | |
37 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/..") | |
38 | include(PrivateSdlFunctions) | |
39 | sdl_find_sdl2(SDL2::SDL2-static 2.0) | |
40 | endif() | |
41 | # some static vendored libraries use c++ (enable CXX after `find_package` might show a warning) | |
42 | enable_language(CXX) | |
43 | find_package(SDL2_mixer REQUIRED CONFIG) | |
44 | add_executable(main_static main.c) | |
45 | target_link_libraries(main_static PRIVATE SDL2::SDL2-static SDL2_mixer::SDL2_mixer-static) | |
46 | endif() | |
47 | ||
48 | feature_summary(WHAT ALL) |
0 | #define SDL_MAIN_HANDLED | |
1 | #include "SDL.h" | |
2 | #include "SDL_mixer.h" | |
3 | #include <stdio.h> | |
4 | ||
5 | int main(int argc, char *argv[]) { | |
6 | SDL_SetMainReady(); | |
7 | if (SDL_Init(0) < 0) { | |
8 | fprintf(stderr, "SDL_Init: could not initialize SDL: %s\n", SDL_GetError()); | |
9 | return 1; | |
10 | } | |
11 | if (Mix_Init(0) == 0) { | |
12 | fprintf(stderr, "Mix_Init: no sound/music loaders supported (%s)\n", Mix_GetError()); | |
13 | } | |
14 | Mix_Quit(); | |
15 | SDL_Quit(); | |
16 | return 0; | |
17 | } |
0 | 0 | dnl Process this file with autoconf to produce a configure script. |
1 | AC_INIT | |
1 | ||
2 | dnl Set various version strings - taken gratefully from the GTk sources | |
3 | # See release_checklist.md | |
4 | m4_define([MAJOR_VERSION_MACRO], [2]) | |
5 | m4_define([MINOR_VERSION_MACRO], [5]) | |
6 | m4_define([MICRO_VERSION_MACRO], [2]) | |
7 | ||
8 | AC_INIT([SDL2_mixer], | |
9 | [MAJOR_VERSION_MACRO.MINOR_VERSION_MACRO.MICRO_VERSION_MACRO], | |
10 | [https://github.com/libsdl-org/SDL_mixer/issues], | |
11 | [SDL2_mixer]) | |
2 | 12 | AC_CONFIG_SRCDIR([src/mixer.c]) |
3 | 13 | AC_CONFIG_AUX_DIR(build-scripts) |
4 | 14 | |
5 | dnl Set various version strings - taken gratefully from the GTk sources | |
6 | ||
7 | # See release_checklist.md | |
8 | MAJOR_VERSION=2 | |
9 | MINOR_VERSION=5 | |
10 | MICRO_VERSION=1 | |
11 | VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION | |
15 | AC_SUBST([MAJOR_VERSION], MAJOR_VERSION_MACRO) | |
16 | AC_SUBST([MINOR_VERSION], MINOR_VERSION_MACRO) | |
17 | AC_SUBST([MICRO_VERSION], MICRO_VERSION_MACRO) | |
12 | 18 | |
13 | 19 | BINARY_AGE=`expr $MINOR_VERSION \* 100 + $MICRO_VERSION` |
14 | 20 | AS_CASE(["$MINOR_VERSION"], |
42 | 48 | LT_REVISION=$INTERFACE_AGE |
43 | 49 | LT_AGE=`expr $BINARY_AGE - $INTERFACE_AGE` |
44 | 50 | LT_CURRENT=`expr $LT_MAJOR + $LT_AGE` |
45 | ||
46 | LT_EXTRA="" dnl for OS2 dll name | |
51 | LT_EXTRA="" | |
52 | ||
47 | 53 | m4_pattern_allow([^LT_]) |
48 | 54 | |
49 | 55 | AC_SUBST(LT_RELEASE) |
117 | 123 | CFLAGS="$CFLAGS $EXTRA_CFLAGS" |
118 | 124 | LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" |
119 | 125 | |
120 | dnl Check for compiler characteristics | |
121 | AC_C_CONST | |
122 | ||
123 | 126 | dnl See whether we can use gcc style dependency tracking |
124 | 127 | AC_ARG_ENABLE(dependency-tracking, |
125 | 128 | [AS_HELP_STRING([--enable-dependency-tracking], |
291 | 294 | |
292 | 295 | dnl Check command-line options |
293 | 296 | |
297 | SDL2MIXER_CMD=0 | |
294 | 298 | AC_ARG_ENABLE([music-cmd], |
295 | 299 | [AS_HELP_STRING([--enable-music-cmd], [support an external music player [default=yes]])], |
296 | 300 | [], [enable_music_cmd=detect]) |
307 | 311 | fi |
308 | 312 | if test "x$enable_music_cmd" != xno; then |
309 | 313 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_CMD" |
310 | fi | |
311 | fi | |
312 | ||
314 | SDL2MIXER_CMD=1 | |
315 | fi | |
316 | fi | |
317 | ||
318 | SDL2MIXER_WAVE=0 | |
313 | 319 | AC_ARG_ENABLE([music-wave], |
314 | 320 | [AS_HELP_STRING([--enable-music-wave], [enable streaming WAVE music [default=yes]])], |
315 | 321 | [], [enable_music_wave=yes]) |
316 | 322 | if test x$enable_music_wave = xyes; then |
317 | 323 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_WAV" |
324 | SDL2MIXER_WAVE=1 | |
318 | 325 | fi |
319 | 326 | |
320 | 327 | AC_ARG_ENABLE([music-mod], |
321 | 328 | [AS_HELP_STRING([--enable-music-mod], [enable MOD music [default=yes]])], |
322 | 329 | [], [enable_music_mod=yes]) |
323 | 330 | |
331 | SDL2MIXER_MOD_MODPLUG=0 | |
324 | 332 | AC_ARG_ENABLE([music-mod-modplug], |
325 | 333 | [AS_HELP_STRING([--enable-music-mod-modplug], [enable MOD music via modplug [default=yes]])], |
326 | 334 | [], [enable_music_mod_modplug=yes]) |
365 | 373 | PC_LIBS="$PC_LIBS $MODPLUG_LIBS" |
366 | 374 | fi |
367 | 375 | fi |
376 | SDL2MIXER_MOD_MODPLUG=1 | |
368 | 377 | else |
369 | 378 | AC_MSG_WARN([*** Unable to find ModPlug library (http://modplug-xmms.sourceforge.net/)]) |
370 | 379 | fi |
371 | 380 | fi |
372 | 381 | |
373 | AC_ARG_ENABLE([music-mod-mikmod], | |
374 | [AS_HELP_STRING([--enable-music-mod-mikmod], [enable MOD music via mikmod [default=no]])], | |
375 | [], [enable_music_mod_mikmod=no]) | |
376 | AC_ARG_ENABLE([music-mod-mikmod-shared], | |
377 | [AS_HELP_STRING([--enable-music-mod-mikmod-shared], [dynamically load mikmod library [default=yes]])], | |
378 | [], [enable_music_mod_mikmod_shared=yes]) | |
379 | if test x$enable_music_mod = xyes -a x$enable_music_mod_mikmod = xyes; then | |
380 | AC_PATH_PROG(LIBMIKMOD_CONFIG, libmikmod-config, no, [$PATH]) | |
381 | AC_SUBST(LIBMIKMOD_CFLAGS) | |
382 | AC_SUBST(LIBMIKMOD_LIBS) | |
383 | if test "$LIBMIKMOD_CONFIG" != "no" ; then | |
384 | test -z "$LIBMIKMOD_CFLAGS" && LIBMIKMOD_CFLAGS=`$LIBMIKMOD_CONFIG --cflags` | |
385 | test -z "$LIBMIKMOD_LIBS" && LIBMIKMOD_LIBS=`$LIBMIKMOD_CONFIG --libs` | |
386 | fi | |
387 | CFLAGS_SAVED="$CFLAGS" | |
388 | LIBS_SAVED="$LIBS" | |
389 | CFLAGS="$CFLAGS $LIBMIKMOD_CFLAGS" | |
390 | LIBS="$LIBS $LIBMIKMOD_LIBS" | |
391 | AC_MSG_CHECKING([for libmikmod >= 3.1.10]) | |
392 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <mikmod.h>]],[[ | |
393 | #if (LIBMIKMOD_VERSION < 0x03010a) | |
394 | choke me | |
395 | #endif | |
396 | Player_LoadGeneric(NULL,0,0); | |
397 | ]])], [have_libmikmod=yes],[have_libmikmod=no]) | |
398 | ||
399 | CFLAGS="$CFLAGS_SAVED" | |
400 | LIBS="$LIBS_SAVED" | |
401 | AC_MSG_RESULT($have_libmikmod) | |
402 | ||
403 | if test x$have_libmikmod = xyes; then | |
404 | case "$host" in | |
405 | *-*-darwin*) | |
406 | mikmod_lib=[`find_lib libmikmod.dylib`] | |
407 | ;; | |
408 | *-*-cygwin* | *-*-mingw*) | |
409 | mikmod_lib=[`find_lib "libmikmod*.dll"`] | |
410 | ;; | |
411 | *) | |
412 | mikmod_lib=[`find_lib "libmikmod[0-9]*.so.*"`] | |
413 | if test x$mikmod_lib = x; then | |
414 | mikmod_lib=[`find_lib "libmikmod.so.*"`] | |
415 | fi | |
416 | ;; | |
417 | esac | |
418 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MOD_MIKMOD $LIBMIKMOD_CFLAGS" | |
419 | if test x$enable_music_mod_mikmod_shared = xyes && test x$mikmod_lib != x; then | |
420 | echo "-- dynamic libmikmod -> $mikmod_lib" | |
421 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMIKMOD_DYNAMIC=\\\"$mikmod_lib\\\"" | |
422 | else | |
423 | EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBMIKMOD_LIBS" | |
424 | PC_LIBS="$PC_LIBS $LIBMIKMOD_LIBS" | |
425 | fi | |
426 | else | |
427 | AC_MSG_WARN([*** Unable to find MikMod library (http://mikmod.sourceforge.net/)]) | |
428 | fi | |
429 | fi | |
430 | ||
382 | SDL2MIXER_MOD_XMP=0 | |
383 | SDL2MIXER_MOD_XMP_LITE=0 | |
431 | 384 | AC_ARG_ENABLE([music-mod-xmp], |
432 | 385 | [AS_HELP_STRING([--enable-music-mod-xmp], [enable MOD music via libxmp [default=no]])], |
433 | 386 | [], [enable_music_mod_xmp=no]) |
479 | 432 | PC_LIBS="$PC_LIBS $XMP_LIBS" |
480 | 433 | fi |
481 | 434 | fi |
435 | SDL2MIXER_MOD_XMP=1 | |
436 | if test x$enable_music_mod_xmp_lite = xyes; then | |
437 | SDL2MIXER_MOD_XMP_LITE=1 | |
438 | fi | |
482 | 439 | else |
483 | 440 | AC_MSG_WARN([*** Unable to find xmp library (http://xmp.sourceforge.net/)]) |
484 | 441 | fi |
485 | 442 | fi |
486 | 443 | |
487 | if test x$have_libmodplug != xyes -a x$have_libmikmod != xyes -a x$have_libxmp != xyes; then | |
444 | if test x$have_libmodplug != xyes -a x$have_libxmp != xyes; then | |
488 | 445 | AC_MSG_WARN([MOD support disabled]) |
489 | 446 | fi |
490 | 447 | |
448 | SDL2MIXER_MIDI_FLUIDSYNTH=0 | |
449 | SDL2MIXER_MIDI_NATIVE=0 | |
450 | SDL2MIXER_MIDI_TIMIDITY=0 | |
491 | 451 | AC_ARG_ENABLE([music-midi], |
492 | 452 | [AS_HELP_STRING([--enable-music-midi], [enable MIDI music [default=yes]])], |
493 | 453 | [], [enable_music_midi=yes]) |
505 | 465 | if test x$timidity_cfg != xyes -a x$timidity_cfg != xno; then |
506 | 466 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DTIMIDITY_CFG=\\\"$timidity_cfg\\\"" |
507 | 467 | fi |
468 | SDL2MIXER_MIDI_TIMIDITY=1 | |
508 | 469 | fi |
509 | 470 | AC_ARG_ENABLE([music-midi-native], |
510 | 471 | [AS_HELP_STRING([--enable-music-midi-native], [enable native MIDI music output [default=yes]])], |
531 | 492 | if test x$use_music_midi_native = xyes; then |
532 | 493 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MID_NATIVE -I\$(srcdir)/src/codecs/native_midi" |
533 | 494 | SOURCES="$SOURCES $srcdir/src/codecs/native_midi/*.c" |
495 | SDL2MIXER_MIDI_NATIVE=1 | |
534 | 496 | elif test x$use_music_midi_native = xyes_cpp; then |
535 | 497 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MID_NATIVE -I\$(srcdir)/src/codecs/native_midi" |
536 | 498 | SOURCES="$SOURCES $srcdir/src/codecs/native_midi/*.c" |
537 | 499 | SOURCES_CXX="$SOURCES_CXX $srcdir/src/codecs/native_midi/*.cpp" |
500 | SDL2MIXER_MIDI_NATIVE=1 | |
538 | 501 | fi |
539 | 502 | fi |
540 | 503 | AC_ARG_ENABLE([music-midi-fluidsynth], |
583 | 546 | PC_LIBS="$PC_LIBS $FLUIDSYNTH_LIBS" |
584 | 547 | fi |
585 | 548 | fi |
549 | SDL2MIXER_MIDI_FLUIDSYNTH=1 | |
586 | 550 | else |
587 | 551 | AC_MSG_WARN([*** Unable to find FluidSynth library (http://www.fluidsynth.org/)]) |
588 | 552 | AC_MSG_WARN([FluidSynth support disabled]) |
600 | 564 | [AS_HELP_STRING([--enable-music-ogg], [enable Ogg Vorbis music [default=yes]])], |
601 | 565 | [], [enable_music_ogg=yes]) |
602 | 566 | |
567 | SDL2MIXER_VORBIS_STB=0 | |
603 | 568 | AC_ARG_ENABLE(music-ogg-stb, |
604 | 569 | [AS_HELP_STRING([--enable-music-ogg-stb], [enable OGG Vorbis music via stb_vorbis [default=yes]])], |
605 | 570 | [], enable_music_ogg_stb=yes) |
606 | 571 | if test x$enable_music_ogg = xyes -a x$enable_music_ogg_stb = xyes; then |
607 | 572 | have_stb_vorbis=yes |
608 | 573 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OGG -DOGG_USE_STB" |
609 | fi | |
610 | ||
574 | SDL2MIXER_VORBIS_STB=1 | |
575 | fi | |
576 | ||
577 | SDL2MIXER_VORBIS_VORBISFILE=0 | |
611 | 578 | AC_ARG_ENABLE(music-ogg-vorbis, |
612 | 579 | [AS_HELP_STRING([--enable-music-ogg-vorbis], [enable OGG Vorbis music via libvorbis [default=no]])], |
613 | 580 | [], enable_music_ogg_vorbis=no) |
654 | 621 | PC_LIBS="$PC_LIBS $VORBIS_LIBS" |
655 | 622 | fi |
656 | 623 | fi |
624 | SDL2MIXER_VORBIS_VORBISFILE=1 | |
657 | 625 | else |
658 | 626 | AC_MSG_WARN([*** Unable to find Ogg Vorbis library (http://www.xiph.org/)]) |
659 | 627 | fi |
660 | 628 | fi |
661 | 629 | |
630 | SDL2MIXER_VORBIS_TREMOR=0 | |
662 | 631 | AC_ARG_ENABLE(music-ogg-tremor, |
663 | 632 | [AS_HELP_STRING([--enable-music-ogg-tremor], [enable OGG Vorbis music via Tremor [default=no]])], |
664 | 633 | [], enable_music_ogg_tremor=no) |
708 | 677 | PC_LIBS="$PC_LIBS $TREMOR_LIBS" |
709 | 678 | fi |
710 | 679 | fi |
680 | SDL2MIXER_VORBIS_TREMOR=1 | |
711 | 681 | else |
712 | 682 | AC_MSG_WARN([*** Unable to find Ogg Vorbis Tremor library (http://www.xiph.org/)]) |
713 | 683 | fi |
718 | 688 | AC_MSG_WARN([Ogg Vorbis support disabled]) |
719 | 689 | fi |
720 | 690 | |
691 | SDL2MIXER_FLAC_DRFLAC=0 | |
721 | 692 | AC_ARG_ENABLE([music-flac], |
722 | 693 | [AS_HELP_STRING([--enable-music-flac], [enable FLAC music [default=yes]])], |
723 | 694 | [], [enable_music_flac=yes]) |
728 | 699 | if test x$enable_music_flac = xyes -a x$enable_music_flac_drflac = xyes; then |
729 | 700 | have_drflac=yes |
730 | 701 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_FLAC_DRFLAC" |
731 | fi | |
732 | ||
702 | SDL2MIXER_FLAC_DRFLAC=1 | |
703 | fi | |
704 | ||
705 | SDL2MIXER_FLAC_LIBFLAC=0 | |
733 | 706 | AC_ARG_ENABLE(music-flac-libflac, |
734 | 707 | [AS_HELP_STRING([--enable-music-flac-libflac], [enable FLAC music via libFLAC [default=no]])], |
735 | 708 | [], [enable_music_flac_libflac=no]) |
791 | 764 | PC_LIBS="$PC_LIBS $FLAC_LIBS" |
792 | 765 | fi |
793 | 766 | fi |
767 | SDL2MIXER_FLAC_LIBFLAC=1 | |
794 | 768 | else |
795 | 769 | AC_MSG_WARN([*** Unable to find FLAC library (https://xiph.org/flac/)]) |
796 | 770 | fi |
805 | 779 | [AS_HELP_STRING([--enable-music-mp3], [enable MP3 music [default=yes]])], |
806 | 780 | [], enable_music_mp3=yes) |
807 | 781 | |
782 | SDL2MIXER_MP3_DRMP3=0 | |
808 | 783 | AC_ARG_ENABLE(music-mp3-drmp3, |
809 | 784 | [AS_HELP_STRING([--enable-music-mp3-drmp3], [enable MP3 music via dr_mp3 [default=yes]])], |
810 | 785 | [], [enable_music_mp3_drmp3=yes]) |
811 | 786 | if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_drmp3 = xyes; then |
812 | 787 | have_drmp3=yes |
813 | 788 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_DRMP3" |
814 | fi | |
815 | ||
789 | SDL2MIXER_MP3_DRMP3=1 | |
790 | fi | |
791 | ||
792 | SDL2MIXER_MP3_MPG123=0 | |
816 | 793 | AC_ARG_ENABLE(music-mp3-mpg123, |
817 | 794 | [AS_HELP_STRING([--enable-music-mp3-mpg123], [enable MP3 music via mpg123 [default=no]])], |
818 | 795 | [], [enable_music_mp3_mpg123=no]) |
853 | 830 | PC_LIBS="$PC_LIBS $MPG123_LIBS" |
854 | 831 | fi |
855 | 832 | fi |
833 | SDL2MIXER_MP3_MPG123=1 | |
856 | 834 | else |
857 | 835 | AC_MSG_WARN([*** Unable to find mpg123 library (https://www.mpg123.de)]) |
858 | 836 | fi |
859 | 837 | fi |
860 | 838 | |
861 | AC_ARG_ENABLE(music-mp3-mad-gpl, | |
862 | [AS_HELP_STRING([--enable-music-mp3-mad-gpl], [enable MP3 music via libmad GPL code [default=no]])], | |
863 | [], [enable_music_mp3_mad_gpl=no]) | |
864 | AC_ARG_ENABLE(music-mp3-mad-gpl-dithering, | |
865 | [AS_HELP_STRING([--enable-music-mp3-mad-gpl-dithering], [enable MP3 music via libmad GPL code [default=yes]])], | |
866 | [], [enable_music_mp3_mad_gpl_dithering=yes]) | |
867 | if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_mad_gpl = xyes; then | |
868 | AC_MSG_CHECKING(for libmad headers) | |
869 | have_libmad=no | |
870 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | |
871 | #include "mad.h" | |
872 | ]],[])], [have_libmad=yes],[]) | |
873 | AC_MSG_RESULT($have_libmad) | |
874 | if test x$have_libmad = xyes; then | |
875 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_MAD" | |
876 | if test x$enable_music_mp3_mad_gpl_dithering = xyes; then | |
877 | AC_MSG_WARN([*** Using GPL libmad and MP3 dithering routines, this build of SDL_mixer is now under the GPL]) | |
878 | EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_MAD_GPL_DITHERING" | |
879 | fi | |
880 | EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmad" | |
881 | PC_LIBS="$PC_LIBS -lmad" | |
882 | else | |
883 | AC_MSG_WARN([*** Unable to find MAD library (http://www.underbit.com/products/mad/)]) | |
884 | fi | |
885 | fi | |
886 | ||
887 | if test x$enable_music_mp3 = xyes -a \ | |
888 | x$have_drmp3 != xyes -a x$have_libmpg123 != xyes -a x$have_libmad != xyes; then | |
839 | if test x$enable_music_mp3 = xyes -a x$have_drmp3 != xyes -a x$have_libmpg123 != xyes; then | |
889 | 840 | AC_MSG_WARN([MP3 support disabled]) |
890 | 841 | fi |
891 | 842 | |
843 | SDL2MIXER_OPUS=0 | |
892 | 844 | AC_ARG_ENABLE([music-opus], |
893 | 845 | [AS_HELP_STRING([--enable-music-opus], [enable Opus music [default=yes]])], |
894 | 846 | [], [enable_music_opus=yes]) |
935 | 887 | PC_LIBS="$PC_LIBS $OPUSFILE_LIBS" |
936 | 888 | fi |
937 | 889 | fi |
890 | SDL2MIXER_OPUS=1 | |
938 | 891 | else |
939 | 892 | AC_MSG_WARN([*** Unable to find opusfile library (http://opus-codec.org/)]) |
940 | 893 | AC_MSG_WARN([Opus support disabled]) |
988 | 941 | $(objects)/\2.lo: \1/\2.c \$(objects)/.created\\ |
989 | 942 | \$(LIBTOOL) --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) '"$DEPENDENCY_TRACKING_OPTIONS"' -c \$< -o \$@,g'` |
990 | 943 | PLAYMUS_DEPENDS=`echo "$PLAYMUS_DEPENDS" | sed 's,\\$,\\\\$,g'` |
944 | ||
945 | dnl Calculate the location of the prefix, relative to the cmake folder | |
946 | eval pkg_prefix=$prefix | |
947 | eval pkg_cmakedir=$libdir/cmake/SDL2_mixer | |
948 | cmake_prefix_relpath="$(echo -n "$pkg_cmakedir" | sed -E "s#^$pkg_prefix##" | sed -E "s#[A-Za-z0-9_ .-]+#..#g")" | |
949 | AC_SUBST([cmake_prefix_relpath]) | |
991 | 950 | |
992 | 951 | dnl Expand the sources and objects needed to build the library |
993 | 952 | AC_SUBST(ac_aux_dir) |
1006 | 965 | AC_SUBST(PC_REQUIRES) |
1007 | 966 | AC_SUBST(PC_LIBS) |
1008 | 967 | |
968 | AC_SUBST(SDL2MIXER_CMD) | |
969 | AC_SUBST(SDL2MIXER_FLAC_DRFLAC) | |
970 | AC_SUBST(SDL2MIXER_FLAC_LIBFLAC) | |
971 | AC_SUBST(SDL2MIXER_MOD_MODPLUG) | |
972 | AC_SUBST(SDL2MIXER_MOD_XMP) | |
973 | AC_SUBST(SDL2MIXER_MOD_XMP_LITE) | |
974 | AC_SUBST(SDL2MIXER_MP3_DRMP3) | |
975 | AC_SUBST(SDL2MIXER_MP3_MPG123) | |
976 | AC_SUBST(SDL2MIXER_MIDI_FLUIDSYNTH) | |
977 | AC_SUBST(SDL2MIXER_MIDI_NATIVE) | |
978 | AC_SUBST(SDL2MIXER_MIDI_TIMIDITY) | |
979 | AC_SUBST(SDL2MIXER_OPUS) | |
980 | AC_SUBST(SDL2MIXER_VORBIS_STB) | |
981 | AC_SUBST(SDL2MIXER_VORBIS_TREMOR) | |
982 | AC_SUBST(SDL2MIXER_VORBIS_VORBISFILE) | |
983 | AC_SUBST(SDL2MIXER_WAVE) | |
984 | ||
1009 | 985 | AC_CONFIG_FILES([ |
1010 | Makefile SDL2_mixer.spec SDL2_mixer.pc | |
986 | Makefile | |
987 | SDL2_mixer.spec | |
988 | SDL2_mixer.pc | |
989 | sdl2_mixer-config.cmake | |
990 | sdl2_mixer-config-version.cmake | |
1011 | 991 | ]) |
1012 | 992 | AC_CONFIG_COMMANDS([default], |
1013 | 993 | [cat >>Makefile <<__EOF__ |
37 | 37 | */ |
38 | 38 | #define SDL_MIXER_MAJOR_VERSION 2 |
39 | 39 | #define SDL_MIXER_MINOR_VERSION 5 |
40 | #define SDL_MIXER_PATCHLEVEL 1 | |
40 | #define SDL_MIXER_PATCHLEVEL 2 | |
41 | 41 | |
42 | 42 | /* This macro can be used to fill a version structure with the compile-time |
43 | 43 | * version of the SDL_mixer library. |
148 | 148 | MUS_OPUS |
149 | 149 | } Mix_MusicType; |
150 | 150 | |
151 | /* The internal format for a music chunk interpreted via mikmod */ | |
151 | /* The internal format for a music chunk interpreted via codecs */ | |
152 | 152 | typedef struct _Mix_Music Mix_Music; |
153 | 153 | |
154 | 154 | /* Open the mixer with a certain audio format */ |
384 | 384 | */ |
385 | 385 | |
386 | 386 | |
387 | /* Set the panning of a channel. The left and right channels are specified | |
388 | * as integers between 0 and 255, quietest to loudest, respectively. | |
387 | /** | |
388 | * Set the panning of a channel. | |
389 | * | |
390 | * The left and right channels are specified as integers between 0 and 255, | |
391 | * quietest to loudest, respectively. | |
389 | 392 | * |
390 | 393 | * Technically, this is just individual volume control for a sample with |
391 | 394 | * two (stereo) channels, so it can be used for more than just panning. |
392 | 395 | * If you want real panning, call it like this: |
393 | 396 | * |
394 | * Mix_SetPanning(channel, left, 255 - left); | |
397 | * ```c | |
398 | * Mix_SetPanning(channel, left, 255 - left); | |
399 | * ``` | |
395 | 400 | * |
396 | 401 | * ...which isn't so hard. |
397 | 402 | * |
398 | * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and | |
403 | * Setting `channel` to MIX_CHANNEL_POST registers this as a posteffect, and | |
399 | 404 | * the panning will be done to the final mixed stream before passing it on |
400 | 405 | * to the audio device. |
401 | 406 | * |
402 | 407 | * This uses the Mix_RegisterEffect() API internally, and returns without |
403 | 408 | * registering the effect function if the audio device is not configured |
404 | * for stereo output. Setting both (left) and (right) to 255 causes this | |
409 | * for stereo output. Setting both `left` and `right` to 255 causes this | |
405 | 410 | * effect to be unregistered, since that is the data's normal state. |
406 | 411 | * |
407 | * returns zero if error (no such channel or Mix_RegisterEffect() fails), | |
408 | * nonzero if panning effect enabled. Note that an audio device in mono | |
409 | * mode is a no-op, but this call will return successful in that case. | |
410 | * Error messages can be retrieved from Mix_GetError(). | |
412 | * Note that an audio device in mono mode is a no-op, but this call will | |
413 | * return successful in that case. Error messages can be retrieved from | |
414 | * Mix_GetError(). | |
415 | * | |
416 | * \param channel The mixer channel to pan or MIX_CHANNEL_POST. | |
417 | * \param left Volume of stereo left channel, 0 is silence, 255 is full volume. | |
418 | * \param right Volume of stereo right channel, 0 is silence, 255 is full volume. | |
419 | * \returns zero if error (no such channel or Mix_RegisterEffect() fails), | |
420 | * nonzero if panning effect enabled. | |
421 | * | |
422 | * \since This function is available since SDL_mixer 2.0.0. | |
423 | * | |
424 | * \sa Mix_SetPosition | |
425 | * \sa Mix_SetDistance | |
411 | 426 | */ |
412 | 427 | extern DECLSPEC int SDLCALL Mix_SetPanning(int channel, Uint8 left, Uint8 right); |
413 | 428 | |
589 | 604 | /* Get the current volume value in the range of 0-128 of a music stream */ |
590 | 605 | extern DECLSPEC int SDLCALL Mix_GetMusicVolume(Mix_Music *music); |
591 | 606 | |
592 | /* Set the master volume. | |
593 | This did not affect the member variables of music, channel or chunck volume. | |
607 | /* Set the master volume for all channels. | |
608 | This did not affect the member variables of channel or chunk volume. | |
594 | 609 | If the specified volume is -1, just return the current master volume. |
595 | 610 | */ |
596 | 611 | extern DECLSPEC int SDLCALL Mix_MasterVolume(int volume); |
635 | 650 | */ |
636 | 651 | extern DECLSPEC int SDLCALL Mix_ModMusicJumpToOrder(int order); |
637 | 652 | |
638 | /* Set the current position in the music stream. | |
639 | This returns 0 if successful, or -1 if it failed or isn't implemented. | |
653 | /* Set the current position in the music stream (in seconds). | |
654 | This returns 0 if successful, or -1 if it failed or not implemented. | |
640 | 655 | This function is only implemented for MOD music formats (set pattern |
641 | order number) and for WAV, OGG, FLAC, MP3_MAD, MP3_MPG, and MODPLUG music | |
642 | (set position in seconds), at the moment. | |
656 | order number) and for WAV, OGG, FLAC, MP3, and MODPLUG music at the | |
657 | moment. | |
643 | 658 | */ |
644 | 659 | extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position); |
645 | 660 | |
680 | 695 | /* Stop music and set external music playback command */ |
681 | 696 | extern DECLSPEC int SDLCALL Mix_SetMusicCMD(const char *command); |
682 | 697 | |
683 | /* Synchro value is set by MikMod from modules while playing */ | |
698 | /* Synchro value is set from modules while playing */ | |
684 | 699 | extern DECLSPEC int SDLCALL Mix_SetSynchroValue(int value); |
685 | 700 | extern DECLSPEC int SDLCALL Mix_GetSynchroValue(void); |
686 | 701 |
0 | # SDL2_mixer CMake version configuration file: | |
1 | # This file is meant to be placed in a cmake subfolder of SDL2_mixer-devel-2.x.y-mingw | |
2 | ||
3 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) | |
4 | set(sdl2_mixer_config_path "${CMAKE_CURRENT_LIST_DIR}/../i686-w64-mingw32/lib/cmake/SDL2_mixer/sdl2_mixer-config-version.cmake") | |
5 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) | |
6 | set(sdl2_mixer_config_path "${CMAKE_CURRENT_LIST_DIR}/../x86_64-w64-mingw32/lib/cmake/SDL2_mixer/sdl2_mixer-config-version.cmake") | |
7 | else("${CMAKE_SIZEOF_VOID_P}" STREQUAL "") | |
8 | set(PACKAGE_VERSION_UNSUITABLE TRUE) | |
9 | return() | |
10 | endif() | |
11 | ||
12 | if(NOT EXISTS "${sdl2_mixer_config_path}") | |
13 | message(WARNING "${sdl2_mixer_config_path} does not exist: MinGW development package is corrupted") | |
14 | set(PACKAGE_VERSION_UNSUITABLE TRUE) | |
15 | return() | |
16 | endif() | |
17 | ||
18 | include("${sdl2_mixer_config_path}") |
0 | # SDL2_mixer CMake configuration file: | |
1 | # This file is meant to be placed in a cmake subfolder of SDL2_mixer-devel-2.x.y-mingw | |
2 | ||
3 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) | |
4 | set(sdl2_mixer_config_path "${CMAKE_CURRENT_LIST_DIR}/../i686-w64-mingw32/lib/cmake/SDL2_mixer/sdl2_mixer-config.cmake") | |
5 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) | |
6 | set(sdl2_mixer_config_path "${CMAKE_CURRENT_LIST_DIR}/../x86_64-w64-mingw32/lib/cmake/SDL2_mixer/sdl2_mixer-config.cmake") | |
7 | else("${CMAKE_SIZEOF_VOID_P}" STREQUAL "") | |
8 | set(SDL2_mixer_FOUND FALSE) | |
9 | return() | |
10 | endif() | |
11 | ||
12 | if(NOT EXISTS "${sdl2_mixer_config_path}") | |
13 | message(WARNING "${sdl2_mixer_config_path} does not exist: MinGW development package is corrupted") | |
14 | set(SDL2_mixer_FOUND FALSE) | |
15 | return() | |
16 | endif() | |
17 | ||
18 | include("${sdl2_mixer_config_path}") | |
19 | ||
20 | # The SDL_mixer MinGW development package ships with vendored libraries | |
21 | set(SDL2MIXER_VENDORED 1) |
0 | # sdl2_mixer cmake project-config-version input for ./configure scripts | |
1 | ||
2 | set(PACKAGE_VERSION "@MAJOR_VERSION@.@MINOR_VERSION@.@MICRO_VERSION@") | |
3 | ||
4 | if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) | |
5 | set(PACKAGE_VERSION_COMPATIBLE FALSE) | |
6 | else() | |
7 | set(PACKAGE_VERSION_COMPATIBLE TRUE) | |
8 | if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) | |
9 | set(PACKAGE_VERSION_EXACT TRUE) | |
10 | endif() | |
11 | endif() |
0 | # sdl2_mixer cmake project-config input for ./configure scripts | |
1 | ||
2 | include(FeatureSummary) | |
3 | set_package_properties(SDL2_mixer PROPERTIES | |
4 | URL "https://www.libsdl.org/projects/SDL_mixer/" | |
5 | DESCRIPTION "SDL_mixer is a sample multi-channel audio mixer library" | |
6 | ) | |
7 | ||
8 | set(SDL2_mixer_FOUND TRUE) | |
9 | ||
10 | set(SDL2MIXER_VENDORED 0) | |
11 | ||
12 | set(SDL2MIXER_CMD @SDL2MIXER_CMD@) | |
13 | ||
14 | set(SDL2MIXER_FLAC_LIBFLAC @SDL2MIXER_FLAC_LIBFLAC@) | |
15 | set(SDL2MIXER_FLAC_DRFLAC @SDL2MIXER_FLAC_DRFLAC@) | |
16 | if(SDL2MIXER_FLAC_LIBFLAC OR SDL2MIXER_FLAC_DRFLAC) | |
17 | set(SDL2MIXER_FLAC 1) | |
18 | else() | |
19 | set(SDL2MIXER_FLAC 0) | |
20 | endif() | |
21 | ||
22 | set(SDL2MIXER_MOD_MODPLUG @SDL2MIXER_MOD_MODPLUG@) | |
23 | set(SDL2MIXER_MOD_XMP @SDL2MIXER_MOD_XMP@) | |
24 | set(SDL2MIXER_MOD_XMP_LITE @SDL2MIXER_MOD_XMP_LITE@) | |
25 | if(SDL2MIXER_MOD_MODPLUG OR SDL2MIXER_MOD_XMP OR SDL2MIXER_MOD_XMP_LITE) | |
26 | set(SDL2MIXER_MOD 1) | |
27 | else() | |
28 | set(SDL2MIXER_MOD 0) | |
29 | endif() | |
30 | ||
31 | set(SDL2MIXER_MP3_DRMP3 @SDL2MIXER_MP3_DRMP3@) | |
32 | set(SDL2MIXER_MP3_MPG123 @SDL2MIXER_MP3_MPG123@) | |
33 | if(SDL2MIXER_MP3_DRMP3 OR SDL2MIXER_MP3_MPG123) | |
34 | set(SDL2MIXER_MP3 1) | |
35 | else() | |
36 | set(SDL2MIXER_MP3 0) | |
37 | endif() | |
38 | ||
39 | set(SDL2MIXER_MIDI_FLUIDSYNTH @SDL2MIXER_MIDI_FLUIDSYNTH@) | |
40 | set(SDL2MIXER_MIDI_NATIVE @SDL2MIXER_MIDI_NATIVE@) | |
41 | set(SDL2MIXER_MIDI_TIMIDITY @SDL2MIXER_MIDI_TIMIDITY@) | |
42 | if(SDL2MIXER_MIDI_FLUIDSYNTH OR SDL2MIXER_MIDI_NATIVE OR SDL2MIXER_MIDI_TIMIDITY) | |
43 | set(SDL2MIXER_MIDI 1) | |
44 | else() | |
45 | set(SDL2MIXER_MIDI 0) | |
46 | endif() | |
47 | ||
48 | set(SDL2MIXER_OPUS @SDL2MIXER_OPUS@) | |
49 | ||
50 | set(SDL2MIXER_VORBIS) | |
51 | set(SDL2MIXER_VORBIS_STB @SDL2MIXER_VORBIS_STB@) | |
52 | set(SDL2MIXER_VORBIS_VORBISFILE @SDL2MIXER_VORBIS_VORBISFILE@) | |
53 | set(SDL2MIXER_VORBIS_TREMOR @SDL2MIXER_VORBIS_TREMOR@) | |
54 | if(SDL2MIXER_VORBIS_STB) | |
55 | set(SDL2MIXER_VORBIS STB) | |
56 | endif() | |
57 | if(SDL2MIXER_VORBIS_VORBISFILE) | |
58 | set(SDL2MIXER_VORBIS VORBISFILE) | |
59 | endif() | |
60 | if(SDL2MIXER_VORBIS_TREMOR) | |
61 | set(SDL2MIXER_VORBIS TREMOR) | |
62 | endif() | |
63 | ||
64 | set(SDL2MIXER_WAVE @SDL2MIXER_WAVE@) | |
65 | ||
66 | set(SDL2MIXER_SDL2_REQUIRED_VERSION @SDL_VERSION@) | |
67 | ||
68 | get_filename_component(prefix "${CMAKE_CURRENT_LIST_DIR}@cmake_prefix_relpath@" ABSOLUTE) | |
69 | set(exec_prefix "@exec_prefix@") | |
70 | set(bindir "@bindir@") | |
71 | set(includedir "@includedir@") | |
72 | set(libdir "@libdir@") | |
73 | set(_sdl2mixer_extra_static_libraries "@PC_LIBS@") | |
74 | string(STRIP "${_sdl2mixer_extra_static_libraries}" _sdl2mixer_extra_static_libraries) | |
75 | ||
76 | set(_sdl2mixer_bindir "${bindir}") | |
77 | set(_sdl2mixer_libdir "${libdir}") | |
78 | set(_sdl2mixer_incdir "${includedir}/SDL2") | |
79 | ||
80 | # Convert _sdl2mixer_extra_static_libraries to list and keep only libraries | |
81 | string(REGEX MATCHALL "(-[lm]([-a-zA-Z0-9._]+))|(-Wl,[^ ]*framework[^ ]*)" _sdl2mixer_extra_static_libraries "${_sdl2mixer_extra_static_libraries}") | |
82 | string(REGEX REPLACE "^-l" "" _sdl2mixer_extra_static_libraries "${_sdl2mixer_extra_static_libraries}") | |
83 | string(REGEX REPLACE ";-l" ";" _sdl2mixer_extra_static_libraries "${_sdl2mixer_extra_static_libraries}") | |
84 | ||
85 | unset(prefix) | |
86 | unset(exec_prefix) | |
87 | unset(bindir) | |
88 | unset(includedir) | |
89 | unset(libdir) | |
90 | ||
91 | include(CMakeFindDependencyMacro) | |
92 | ||
93 | if(NOT TARGET SDL2_mixer::SDL2_mixer) | |
94 | if(WIN32) | |
95 | set(_sdl2mixer_dll "${_sdl2mixer_bindir}/SDL2_mixer.dll") | |
96 | set(_sdl2mixer_imp "${_sdl2mixer_libdir}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2_mixer.dll${CMAKE_STATIC_LIBRARY_SUFFIX}") | |
97 | if(EXISTS "${_sdl2mixer_dll}" AND EXISTS "${_sdl2mixer_imp}") | |
98 | add_library(SDL2_mixer::SDL2_mixer SHARED IMPORTED) | |
99 | set_target_properties(SDL2_mixer::SDL2_mixer | |
100 | PROPERTIES | |
101 | IMPORTED_LOCATION "${_sdl2mixer_dll}" | |
102 | IMPORTED_IMPLIB "${_sdl2mixer_imp}" | |
103 | ) | |
104 | endif() | |
105 | unset(_sdl2mixer_dll) | |
106 | unset(_sdl2mixer_imp) | |
107 | else() | |
108 | set(_sdl2mixer_shl "${_sdl2mixer_libdir}/${CMAKE_SHARED_LIBRARY_PREFIX}SDL2_mixer${CMAKE_SHARED_LIBRARY_SUFFIX}") | |
109 | if(EXISTS "${_sdl2mixer_shl}") | |
110 | add_library(SDL2_mixer::SDL2_mixer SHARED IMPORTED) | |
111 | set_target_properties(SDL2_mixer::SDL2_mixer | |
112 | PROPERTIES | |
113 | IMPORTED_LOCATION "${_sdl2mixer_shl}" | |
114 | ) | |
115 | endif() | |
116 | endif() | |
117 | if(TARGET SDL2_mixer::SDL2_mixer) | |
118 | set_target_properties(SDL2_mixer::SDL2_mixer | |
119 | PROPERTIES | |
120 | INTERFACE_INCLUDE_DIRECTORIES "${_sdl2mixer_incdir}" | |
121 | COMPATIBLE_INTERFACE_BOOL "SDL2_SHARED" | |
122 | INTERFACE_SDL2_SHARED "ON" | |
123 | ) | |
124 | endif() | |
125 | endif() | |
126 | ||
127 | if(NOT TARGET SDL2_mixer::SDL2_mixer-static) | |
128 | set(_sdl2mixer_stl "${_sdl2mixer_libdir}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2_mixer${CMAKE_STATIC_LIBRARY_SUFFIX}") | |
129 | if(EXISTS "${_sdl2mixer_stl}") | |
130 | add_library(SDL2_mixer::SDL2_mixer-static STATIC IMPORTED) | |
131 | set_target_properties(SDL2_mixer::SDL2_mixer-static | |
132 | PROPERTIES | |
133 | INTERFACE_INCLUDE_DIRECTORIES "${_sdl2mixer_incdir}" | |
134 | IMPORTED_LOCATION "${_sdl2mixer_stl}" | |
135 | INTERFACE_LINK_LIBRARIES "${_sdl2mixer_extra_static_libraries}" | |
136 | ) | |
137 | endif() | |
138 | unset(_sdl2mixer_stl) | |
139 | endif() | |
140 | ||
141 | unset(_sdl2mixer_extra_static_libraries) | |
142 | unset(_sdl2mixer_bindir) | |
143 | unset(_sdl2mixer_libdir) | |
144 | unset(_sdl2mixer_incdir) |
383 | 383 | if (!voc_check_header(src)) |
384 | 384 | goto done; |
385 | 385 | |
386 | SDL_memset(&v, 0, sizeof (vs_t)); | |
386 | 387 | v.rate = VOC_BAD_RATE; |
387 | 388 | v.rest = 0; |
388 | 389 | v.has_extended = 0; |
398 | 399 | goto done; |
399 | 400 | } |
400 | 401 | |
402 | if (v.size == 0) { | |
403 | SDL_SetError("VOC data had invalid word size!"); | |
404 | goto done; | |
405 | } | |
406 | ||
401 | 407 | spec->format = ((v.size == ST_SIZE_WORD) ? AUDIO_S16 : AUDIO_U8); |
402 | 408 | if (spec->channels == 0) |
403 | 409 | spec->channels = v.channels; |
404 | 410 | |
405 | 411 | *audio_len = v.rest; |
406 | *audio_buf = SDL_malloc(v.rest); | |
412 | *audio_buf = (v.rest == 0) ? NULL : SDL_malloc(v.rest); | |
407 | 413 | if (*audio_buf == NULL) |
408 | 414 | goto done; |
409 | 415 |
159 | 159 | music->play_count = play_count; |
160 | 160 | #ifdef HAVE_FORK |
161 | 161 | music->pid = fork(); |
162 | #elif defined(HAVE_VFORK) | |
163 | music->pid = vfork(); | |
162 | 164 | #else |
163 | music->pid = vfork(); | |
165 | music->pid = -1; | |
164 | 166 | #endif |
165 | 167 | switch(music->pid) { |
166 | 168 | /* Failed fork() system call */ |
0 | /* | |
1 | SDL_mixer: An audio mixer library based on the SDL library | |
2 | Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org> | |
3 | ||
4 | This software is provided 'as-is', without any express or implied | |
5 | warranty. In no event will the authors be held liable for any damages | |
6 | arising from the use of this software. | |
7 | ||
8 | Permission is granted to anyone to use this software for any purpose, | |
9 | including commercial applications, and to alter it and redistribute it | |
10 | freely, subject to the following restrictions: | |
11 | ||
12 | 1. The origin of this software must not be misrepresented; you must not | |
13 | claim that you wrote the original software. If you use this software | |
14 | in a product, an acknowledgment in the product documentation would be | |
15 | appreciated but is not required. | |
16 | 2. Altered source versions must be plainly marked as such, and must not be | |
17 | misrepresented as being the original software. | |
18 | 3. This notice may not be removed or altered from any source distribution. | |
19 | */ | |
20 | ||
21 | #ifdef MUSIC_MP3_MAD | |
22 | ||
23 | #include "music_mad.h" | |
24 | #include "mp3utils.h" | |
25 | ||
26 | #include "mad.h" | |
27 | ||
28 | ||
29 | /* NOTE: The dithering functions are GPL, which should be fine if your | |
30 | application is GPL (which would need to be true if you enabled | |
31 | libmad support in SDL_mixer). If you're using libmad under the | |
32 | commercial license, you need to disable this code. | |
33 | */ | |
34 | /************************ dithering functions ***************************/ | |
35 | ||
36 | #ifdef MUSIC_MP3_MAD_GPL_DITHERING | |
37 | ||
38 | /* All dithering done here is taken from the GPL'ed xmms-mad plugin. */ | |
39 | ||
40 | /* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */ | |
41 | /* Any feedback is very welcome. For any question, comments, */ | |
42 | /* see http://www.math.keio.ac.jp/matumoto/emt.html or email */ | |
43 | /* matumoto@math.keio.ac.jp */ | |
44 | ||
45 | /* Period parameters */ | |
46 | #define MP3_DITH_N 624 | |
47 | #define MP3_DITH_M 397 | |
48 | #define MATRIX_A 0x9908b0df /* constant vector a */ | |
49 | #define UPPER_MASK 0x80000000 /* most significant w-r bits */ | |
50 | #define LOWER_MASK 0x7fffffff /* least significant r bits */ | |
51 | ||
52 | /* Tempering parameters */ | |
53 | #define TEMPERING_MASK_B 0x9d2c5680 | |
54 | #define TEMPERING_MASK_C 0xefc60000 | |
55 | #define TEMPERING_SHIFT_U(y) (y >> 11) | |
56 | #define TEMPERING_SHIFT_S(y) (y << 7) | |
57 | #define TEMPERING_SHIFT_T(y) (y << 15) | |
58 | #define TEMPERING_SHIFT_L(y) (y >> 18) | |
59 | ||
60 | static unsigned long mt[MP3_DITH_N]; /* the array for the state vector */ | |
61 | static int mti=MP3_DITH_N+1; /* mti==MP3_DITH_N+1 means mt[MP3_DITH_N] is not initialized */ | |
62 | ||
63 | /* initializing the array with a NONZERO seed */ | |
64 | static void sgenrand(unsigned long seed) | |
65 | { | |
66 | /* setting initial seeds to mt[MP3_DITH_N] using */ | |
67 | /* the generator Line 25 of Table 1 in */ | |
68 | /* [KNUTH 1981, The Art of Computer Programming */ | |
69 | /* Vol. 2 (2nd Ed.), pp102] */ | |
70 | mt[0]= seed & 0xffffffff; | |
71 | for (mti=1; mti<MP3_DITH_N; mti++) | |
72 | mt[mti] = (69069 * mt[mti-1]) & 0xffffffff; | |
73 | } | |
74 | ||
75 | static unsigned long genrand(void) | |
76 | { | |
77 | unsigned long y; | |
78 | static unsigned long mag01[2]={0x0, MATRIX_A}; | |
79 | /* mag01[x] = x * MATRIX_A for x=0,1 */ | |
80 | ||
81 | if (mti >= MP3_DITH_N) { /* generate MP3_DITH_N words at one time */ | |
82 | int kk; | |
83 | ||
84 | if (mti == MP3_DITH_N+1) /* if sgenrand() has not been called, */ | |
85 | sgenrand(4357); /* a default initial seed is used */ | |
86 | ||
87 | for (kk=0;kk<MP3_DITH_N-MP3_DITH_M;kk++) { | |
88 | y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); | |
89 | mt[kk] = mt[kk+MP3_DITH_M] ^ (y >> 1) ^ mag01[y & 0x1]; | |
90 | } | |
91 | for (;kk<MP3_DITH_N-1;kk++) { | |
92 | y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); | |
93 | mt[kk] = mt[kk+(MP3_DITH_M-MP3_DITH_N)] ^ (y >> 1) ^ mag01[y & 0x1]; | |
94 | } | |
95 | y = (mt[MP3_DITH_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); | |
96 | mt[MP3_DITH_N-1] = mt[MP3_DITH_M-1] ^ (y >> 1) ^ mag01[y & 0x1]; | |
97 | ||
98 | mti = 0; | |
99 | } | |
100 | ||
101 | y = mt[mti++]; | |
102 | y ^= TEMPERING_SHIFT_U(y); | |
103 | y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; | |
104 | y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; | |
105 | y ^= TEMPERING_SHIFT_L(y); | |
106 | ||
107 | return y; | |
108 | } | |
109 | ||
110 | static long triangular_dither_noise(int nbits) { | |
111 | /* parameter nbits : the peak-to-peak amplitude desired (in bits) | |
112 | * use with nbits set to 2 + nber of bits to be trimmed. | |
113 | * (because triangular is made from two uniformly distributed processes, | |
114 | * it starts at 2 bits peak-to-peak amplitude) | |
115 | * see The Theory of Dithered Quantization by Robert Alexander Wannamaker | |
116 | * for complete proof of why that's optimal | |
117 | */ | |
118 | long v = (genrand()/2 - genrand()/2); /* in ]-2^31, 2^31[ */ | |
119 | long P = 1 << (32 - nbits); /* the power of 2 */ | |
120 | v /= P; | |
121 | /* now v in ]-2^(nbits-1), 2^(nbits-1) [ */ | |
122 | ||
123 | return v; | |
124 | } | |
125 | ||
126 | #endif /* MUSIC_MP3_MAD_GPL_DITHERING */ | |
127 | ||
128 | ||
129 | #define MAD_INPUT_BUFFER_SIZE (5*8192) | |
130 | ||
131 | enum { | |
132 | MS_input_eof = 0x0001, | |
133 | MS_input_error = 0x0001, | |
134 | MS_decode_error = 0x0002, | |
135 | MS_error_flags = 0x000f | |
136 | }; | |
137 | ||
138 | typedef struct { | |
139 | struct mp3file_t mp3file; | |
140 | int play_count; | |
141 | int freesrc; | |
142 | struct mad_stream stream; | |
143 | struct mad_frame frame; | |
144 | struct mad_synth synth; | |
145 | mad_timer_t next_frame_start; | |
146 | int volume; | |
147 | int status; | |
148 | SDL_AudioStream *audiostream; | |
149 | unsigned short last_nchannels; | |
150 | unsigned int last_samplerate; | |
151 | ||
152 | double total_length; | |
153 | int sample_rate; | |
154 | int sample_position; | |
155 | Mix_MusicMetaTags tags; | |
156 | ||
157 | unsigned char input_buffer[MAD_INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD]; | |
158 | } MAD_Music; | |
159 | ||
160 | ||
161 | static void read_update_buffer(struct mad_stream *stream, MAD_Music *music); | |
162 | ||
163 | static double extract_length(struct mad_header *header, struct mad_stream *stream, Sint64 file_size) | |
164 | { | |
165 | int mpeg_version = 0; | |
166 | int xing_offset = 0; | |
167 | Uint32 samples_per_frame = 0; | |
168 | Uint32 frames_count = 0; | |
169 | unsigned char const *frames_count_raw; | |
170 | ||
171 | /* There are two methods to compute duration: | |
172 | * - Using Xing/Info/VBRI headers | |
173 | * - Rely on filesize and first size of frame in condition of CRB | |
174 | * https://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header#VBRHeaders | |
175 | */ | |
176 | ||
177 | if (!stream->this_frame || !stream->next_frame || | |
178 | stream->next_frame <= stream->this_frame || | |
179 | (stream->next_frame - stream->this_frame) < 48) { | |
180 | return -1.0; /* Too small buffer to get any necessary headers */ | |
181 | } | |
182 | ||
183 | mpeg_version = (stream->this_frame[1] >> 3) & 0x03; | |
184 | ||
185 | switch(mpeg_version) { | |
186 | case 0x03: /* MPEG1 */ | |
187 | if (header->mode == MAD_MODE_SINGLE_CHANNEL) { | |
188 | xing_offset = 4 + 17; | |
189 | } else { | |
190 | xing_offset = 4 + 32; | |
191 | } | |
192 | break; | |
193 | default: /* MPEG2 and MPEG2.5 */ | |
194 | if (header->mode == MAD_MODE_SINGLE_CHANNEL) { | |
195 | xing_offset = 4 + 17; | |
196 | } else { | |
197 | xing_offset = 4 + 9; | |
198 | } | |
199 | break; | |
200 | } | |
201 | ||
202 | switch(header->layer) | |
203 | { | |
204 | case MAD_LAYER_I: | |
205 | samples_per_frame = 384; | |
206 | break; | |
207 | case MAD_LAYER_II: | |
208 | samples_per_frame = 1152; | |
209 | break; | |
210 | case MAD_LAYER_III: | |
211 | if (mpeg_version == 0x03) { | |
212 | samples_per_frame = 1152; | |
213 | } else { | |
214 | samples_per_frame = 576; | |
215 | } | |
216 | break; | |
217 | default: | |
218 | return -1.0; | |
219 | } | |
220 | ||
221 | if (SDL_memcmp(stream->this_frame + xing_offset, "Xing", 4) == 0 || | |
222 | SDL_memcmp(stream->this_frame + xing_offset, "Info", 4) == 0) { | |
223 | /* Xing header to get the count of frames for VBR */ | |
224 | frames_count_raw = stream->this_frame + xing_offset + 8; | |
225 | frames_count = ((Uint32)frames_count_raw[0] << 24) + | |
226 | ((Uint32)frames_count_raw[1] << 16) + | |
227 | ((Uint32)frames_count_raw[2] << 8) + | |
228 | ((Uint32)frames_count_raw[3]); | |
229 | } | |
230 | else if (SDL_memcmp(stream->this_frame + xing_offset, "VBRI", 4) == 0) { | |
231 | /* VBRI header to get the count of frames for VBR */ | |
232 | frames_count_raw = stream->this_frame + xing_offset + 14; | |
233 | frames_count = ((Uint32)frames_count_raw[0] << 24) + | |
234 | ((Uint32)frames_count_raw[1] << 16) + | |
235 | ((Uint32)frames_count_raw[2] << 8) + | |
236 | ((Uint32)frames_count_raw[3]); | |
237 | } else { | |
238 | /* To get a count of frames for CBR, divide the file size with a size of one frame */ | |
239 | frames_count = (Uint32)(file_size / (stream->next_frame - stream->this_frame)); | |
240 | } | |
241 | ||
242 | return (double)(frames_count * samples_per_frame) / header->samplerate; | |
243 | } | |
244 | ||
245 | static int calculate_total_time(MAD_Music *music) | |
246 | { | |
247 | mad_timer_t time = mad_timer_zero; | |
248 | struct mad_header header; | |
249 | struct mad_stream stream; | |
250 | SDL_bool is_first_frame = SDL_TRUE; | |
251 | int ret = 0; | |
252 | ||
253 | mad_header_init(&header); | |
254 | mad_stream_init(&stream); | |
255 | ||
256 | while (1) | |
257 | { | |
258 | read_update_buffer(&stream, music); | |
259 | ||
260 | if (mad_header_decode(&header, &stream) == -1) { | |
261 | if (MAD_RECOVERABLE(stream.error)) { | |
262 | if ((music->status & MS_input_error) == 0) { | |
263 | continue; | |
264 | } | |
265 | if (is_first_frame) { | |
266 | ret = -1; | |
267 | } | |
268 | break; | |
269 | } else if (stream.error == MAD_ERROR_BUFLEN) { | |
270 | if ((music->status & MS_input_error) == 0) { | |
271 | continue; | |
272 | } | |
273 | if (is_first_frame) { | |
274 | ret = -1; | |
275 | } | |
276 | break; | |
277 | } else { | |
278 | Mix_SetError("mad_frame_decode() failed, corrupt stream?"); | |
279 | music->status |= MS_decode_error; | |
280 | if (is_first_frame) { | |
281 | ret = -1; | |
282 | } | |
283 | break; | |
284 | } | |
285 | } | |
286 | ||
287 | music->sample_rate = (int)header.samplerate; | |
288 | mad_timer_add(&time, header.duration); | |
289 | ||
290 | if (is_first_frame) { | |
291 | music->total_length = extract_length(&header, &stream, music->mp3file.length); | |
292 | if (music->total_length > 0.0) { | |
293 | break; /* Duration has been recognized */ | |
294 | } | |
295 | is_first_frame = SDL_FALSE; | |
296 | /* Otherwise, do the full scan of MP3 file to retrieve a duration */ | |
297 | } | |
298 | } | |
299 | ||
300 | if (!is_first_frame) { | |
301 | music->total_length = (double)(mad_timer_count(time, (enum mad_units)music->sample_rate)) / (double)music->sample_rate; | |
302 | } | |
303 | mad_stream_finish(&stream); | |
304 | mad_header_finish(&header); | |
305 | SDL_memset(music->input_buffer, 0, sizeof(music->input_buffer)); | |
306 | ||
307 | music->status = 0; | |
308 | ||
309 | MP3_RWseek(&music->mp3file, 0, RW_SEEK_SET); | |
310 | return ret; | |
311 | } | |
312 | ||
313 | static int MAD_Seek(void *context, double position); | |
314 | ||
315 | static void *MAD_CreateFromRW(SDL_RWops *src, int freesrc) | |
316 | { | |
317 | MAD_Music *music; | |
318 | ||
319 | music = (MAD_Music *)SDL_calloc(1, sizeof(MAD_Music)); | |
320 | if (!music) { | |
321 | SDL_OutOfMemory(); | |
322 | return NULL; | |
323 | } | |
324 | music->volume = MIX_MAX_VOLUME; | |
325 | ||
326 | if (MP3_RWinit(&music->mp3file, src) < 0) { | |
327 | SDL_free(music); | |
328 | return NULL; | |
329 | } | |
330 | meta_tags_init(&music->tags); | |
331 | if (mp3_read_tags(&music->tags, &music->mp3file, SDL_FALSE) < 0) { | |
332 | SDL_free(music); | |
333 | Mix_SetError("music_mad: corrupt mp3 file (bad tags.)"); | |
334 | return NULL; | |
335 | } | |
336 | ||
337 | if (calculate_total_time(music) < 0) { | |
338 | SDL_free(music); | |
339 | Mix_SetError("music_mad: corrupt mp3 file (bad stream.)"); | |
340 | return NULL; | |
341 | } | |
342 | ||
343 | mad_stream_init(&music->stream); | |
344 | mad_frame_init(&music->frame); | |
345 | mad_synth_init(&music->synth); | |
346 | mad_timer_reset(&music->next_frame_start); | |
347 | ||
348 | music->freesrc = freesrc; | |
349 | return music; | |
350 | } | |
351 | ||
352 | static void MAD_SetVolume(void *context, int volume) | |
353 | { | |
354 | MAD_Music *music = (MAD_Music *)context; | |
355 | music->volume = volume; | |
356 | } | |
357 | ||
358 | static int MAD_GetVolume(void *context) | |
359 | { | |
360 | MAD_Music *music = (MAD_Music *)context; | |
361 | return music->volume; | |
362 | } | |
363 | ||
364 | /* Starts the playback. */ | |
365 | static int MAD_Play(void *context, int play_count) | |
366 | { | |
367 | MAD_Music *music = (MAD_Music *)context; | |
368 | music->play_count = play_count; | |
369 | return MAD_Seek(music, 0.0); | |
370 | } | |
371 | ||
372 | static void MAD_Stop(void *context) | |
373 | { | |
374 | MAD_Music *music = (MAD_Music *)context; | |
375 | SDL_AudioStreamClear(music->audiostream); | |
376 | } | |
377 | ||
378 | ||
379 | /* Reads the next frame from the file. | |
380 | Returns true on success or false on failure. | |
381 | */ | |
382 | static void read_update_buffer(struct mad_stream *stream, MAD_Music *music) | |
383 | { | |
384 | if (stream->buffer == NULL || | |
385 | stream->error == MAD_ERROR_BUFLEN) { | |
386 | size_t read_size; | |
387 | size_t remaining; | |
388 | unsigned char *read_start; | |
389 | ||
390 | /* There might be some bytes in the buffer left over from last | |
391 | time. If so, move them down and read more bytes following | |
392 | them. */ | |
393 | if (stream->next_frame != NULL) { | |
394 | remaining = (size_t)(stream->bufend - stream->next_frame); | |
395 | SDL_memmove(music->input_buffer, stream->next_frame, remaining); | |
396 | read_start = music->input_buffer + remaining; | |
397 | read_size = MAD_INPUT_BUFFER_SIZE - remaining; | |
398 | ||
399 | } else { | |
400 | read_size = MAD_INPUT_BUFFER_SIZE; | |
401 | read_start = music->input_buffer; | |
402 | remaining = 0; | |
403 | } | |
404 | ||
405 | /* Now read additional bytes from the input file. */ | |
406 | read_size = MP3_RWread(&music->mp3file, read_start, 1, read_size); | |
407 | ||
408 | if (read_size == 0) { | |
409 | if ((music->status & (MS_input_eof | MS_input_error)) == 0) { | |
410 | /* FIXME: how to detect error? */ | |
411 | music->status |= MS_input_eof; | |
412 | ||
413 | /* At the end of the file, we must stuff MAD_BUFFER_GUARD | |
414 | number of 0 bytes. */ | |
415 | SDL_memset(read_start + read_size, 0, MAD_BUFFER_GUARD); | |
416 | read_size += MAD_BUFFER_GUARD; | |
417 | } | |
418 | } | |
419 | ||
420 | /* Now feed those bytes into the libmad stream. */ | |
421 | mad_stream_buffer(stream, music->input_buffer, | |
422 | read_size + remaining); | |
423 | stream->error = MAD_ERROR_NONE; | |
424 | } | |
425 | } | |
426 | ||
427 | /* Reads the next frame from the file. | |
428 | Returns true on success or false on failure. | |
429 | */ | |
430 | static SDL_bool read_next_frame(MAD_Music *music) | |
431 | { | |
432 | read_update_buffer(&music->stream, music); | |
433 | ||
434 | /* Now ask libmad to extract a frame from the data we just put in | |
435 | its buffer. */ | |
436 | if (mad_frame_decode(&music->frame, &music->stream)) { | |
437 | if (MAD_RECOVERABLE(music->stream.error)) { | |
438 | mad_stream_sync(&music->stream); /* to frame seek mode */ | |
439 | return SDL_FALSE; | |
440 | ||
441 | } else if (music->stream.error == MAD_ERROR_BUFLEN) { | |
442 | return SDL_FALSE; | |
443 | ||
444 | } else { | |
445 | Mix_SetError("mad_frame_decode() failed, corrupt stream?"); | |
446 | music->status |= MS_decode_error; | |
447 | return SDL_FALSE; | |
448 | } | |
449 | } | |
450 | ||
451 | mad_timer_add(&music->next_frame_start, music->frame.header.duration); | |
452 | ||
453 | return SDL_TRUE; | |
454 | } | |
455 | ||
456 | /* Scale a MAD sample to 16 bits for output. */ | |
457 | static Sint16 scale(mad_fixed_t sample) | |
458 | { | |
459 | const int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16; | |
460 | ||
461 | /* round */ | |
462 | sample += (1L << (n_bits_to_loose - 1)); | |
463 | ||
464 | #ifdef MUSIC_MP3_MAD_GPL_DITHERING | |
465 | sample += triangular_dither_noise(n_bits_to_loose + 1); | |
466 | #endif | |
467 | ||
468 | /* clip */ | |
469 | if (sample >= MAD_F_ONE) | |
470 | sample = MAD_F_ONE - 1; | |
471 | else if (sample < -MAD_F_ONE) | |
472 | sample = -MAD_F_ONE; | |
473 | ||
474 | /* quantize */ | |
475 | return (Sint16)(sample >> n_bits_to_loose); | |
476 | } | |
477 | ||
478 | /* Once the frame has been read, copies its samples into the output buffer. */ | |
479 | static SDL_bool decode_frame(MAD_Music *music) | |
480 | { | |
481 | struct mad_pcm *pcm; | |
482 | unsigned int i, nchannels, nsamples; | |
483 | mad_fixed_t const *left_ch, *right_ch; | |
484 | Sint16 *buffer, *dst; | |
485 | int result; | |
486 | ||
487 | mad_synth_frame(&music->synth, &music->frame); | |
488 | pcm = &music->synth.pcm; | |
489 | ||
490 | if (!music->audiostream || music->last_nchannels != pcm->channels || music->last_samplerate != pcm->samplerate) { | |
491 | if (music->audiostream) { | |
492 | SDL_FreeAudioStream(music->audiostream); | |
493 | } | |
494 | music->audiostream = SDL_NewAudioStream(AUDIO_S16SYS, (Uint8)pcm->channels, (int)pcm->samplerate, | |
495 | music_spec.format, music_spec.channels, music_spec.freq); | |
496 | if (!music->audiostream) { | |
497 | return SDL_FALSE; | |
498 | } | |
499 | music->last_nchannels = pcm->channels; | |
500 | music->last_samplerate = pcm->samplerate; | |
501 | } | |
502 | ||
503 | nchannels = pcm->channels; | |
504 | nsamples = pcm->length; | |
505 | left_ch = pcm->samples[0]; | |
506 | right_ch = pcm->samples[1]; | |
507 | buffer = SDL_stack_alloc(Sint16, nsamples*nchannels); | |
508 | if (!buffer) { | |
509 | SDL_OutOfMemory(); | |
510 | return SDL_FALSE; | |
511 | } | |
512 | ||
513 | dst = buffer; | |
514 | if (nchannels == 1) { | |
515 | for (i = nsamples; i--;) { | |
516 | *dst++ = scale(*left_ch++); | |
517 | } | |
518 | } else { | |
519 | for (i = nsamples; i--;) { | |
520 | *dst++ = scale(*left_ch++); | |
521 | *dst++ = scale(*right_ch++); | |
522 | } | |
523 | } | |
524 | ||
525 | music->sample_position += nsamples; | |
526 | result = SDL_AudioStreamPut(music->audiostream, buffer, (int)(nsamples * nchannels * sizeof(Sint16))); | |
527 | SDL_stack_free(buffer); | |
528 | ||
529 | if (result < 0) { | |
530 | return SDL_FALSE; | |
531 | } | |
532 | return SDL_TRUE; | |
533 | } | |
534 | ||
535 | static int MAD_GetSome(void *context, void *data, int bytes, SDL_bool *done) | |
536 | { | |
537 | MAD_Music *music = (MAD_Music *)context; | |
538 | int filled; | |
539 | ||
540 | if (music->audiostream) { | |
541 | filled = SDL_AudioStreamGet(music->audiostream, data, bytes); | |
542 | if (filled != 0) { | |
543 | return filled; | |
544 | } | |
545 | } | |
546 | ||
547 | if (!music->play_count) { | |
548 | /* All done */ | |
549 | *done = SDL_TRUE; | |
550 | return 0; | |
551 | } | |
552 | ||
553 | if (read_next_frame(music)) { | |
554 | if (!decode_frame(music)) { | |
555 | return -1; | |
556 | } | |
557 | } else if (music->status & MS_input_eof) { | |
558 | int play_count = -1; | |
559 | if (music->play_count > 0) { | |
560 | play_count = (music->play_count - 1); | |
561 | } | |
562 | if (MAD_Play(music, play_count) < 0) { | |
563 | return -1; | |
564 | } | |
565 | } else if (music->status & MS_decode_error) { | |
566 | return -1; | |
567 | } | |
568 | return 0; | |
569 | } | |
570 | ||
571 | static int MAD_GetAudio(void *context, void *data, int bytes) | |
572 | { | |
573 | MAD_Music *music = (MAD_Music *)context; | |
574 | return music_pcm_getaudio(context, data, bytes, music->volume, MAD_GetSome); | |
575 | } | |
576 | ||
577 | static int MAD_Seek(void *context, double position) | |
578 | { | |
579 | MAD_Music *music = (MAD_Music *)context; | |
580 | mad_timer_t target; | |
581 | int int_part; | |
582 | ||
583 | int_part = (int)position; | |
584 | mad_timer_set(&target, (unsigned long)int_part, (unsigned long)((position - int_part) * 1000000), 1000000); | |
585 | ||
586 | music->sample_position = (int)(position * music->sample_rate); | |
587 | ||
588 | if (mad_timer_compare(music->next_frame_start, target) > 0) { | |
589 | /* In order to seek backwards in a VBR file, we have to rewind and | |
590 | start again from the beginning. This isn't necessary if the | |
591 | file happens to be CBR, of course; in that case we could seek | |
592 | directly to the frame we want. But I leave that little | |
593 | optimization for the future developer who discovers she really | |
594 | needs it. */ | |
595 | mad_timer_reset(&music->next_frame_start); | |
596 | music->status &= ~MS_error_flags; | |
597 | ||
598 | MP3_RWseek(&music->mp3file, 0, RW_SEEK_SET); | |
599 | /* Avoid junk chunk be played after seek -- Vitaly Novichkov */ | |
600 | SDL_memset(music->input_buffer, 0, sizeof(music->input_buffer)); | |
601 | } | |
602 | ||
603 | /* Now we have to skip frames until we come to the right one. | |
604 | Again, only truly necessary if the file is VBR. */ | |
605 | while (mad_timer_compare(music->next_frame_start, target) < 0) { | |
606 | if (!read_next_frame(music)) { | |
607 | if ((music->status & MS_error_flags) != 0) { | |
608 | /* Couldn't read a frame; either an error condition or | |
609 | end-of-file. Stop. */ | |
610 | return Mix_SetError("Seek position out of range"); | |
611 | } | |
612 | } | |
613 | } | |
614 | ||
615 | /* Here we are, at the beginning of the frame that contains the | |
616 | target time. Ehh, I say that's close enough. If we wanted to, | |
617 | we could get more precise by decoding the frame now and counting | |
618 | the appropriate number of samples out of it. */ | |
619 | return 0; | |
620 | } | |
621 | ||
622 | static double MAD_Tell(void *context) | |
623 | { | |
624 | MAD_Music *music = (MAD_Music *)context; | |
625 | return (double)music->sample_position / (double)music->sample_rate; | |
626 | } | |
627 | ||
628 | static double MAD_Duration(void *context) | |
629 | { | |
630 | MAD_Music *music = (MAD_Music *)context; | |
631 | return music->total_length; | |
632 | } | |
633 | ||
634 | static const char* MAD_GetMetaTag(void *context, Mix_MusicMetaTag tag_type) | |
635 | { | |
636 | MAD_Music *music = (MAD_Music *)context; | |
637 | return meta_tags_get(&music->tags, tag_type); | |
638 | } | |
639 | ||
640 | static void MAD_Delete(void *context) | |
641 | { | |
642 | MAD_Music *music = (MAD_Music *)context; | |
643 | ||
644 | mad_stream_finish(&music->stream); | |
645 | mad_frame_finish(&music->frame); | |
646 | mad_synth_finish(&music->synth); | |
647 | meta_tags_clear(&music->tags); | |
648 | ||
649 | if (music->audiostream) { | |
650 | SDL_FreeAudioStream(music->audiostream); | |
651 | } | |
652 | if (music->freesrc) { | |
653 | SDL_RWclose(music->mp3file.src); | |
654 | } | |
655 | SDL_free(music); | |
656 | } | |
657 | ||
658 | Mix_MusicInterface Mix_MusicInterface_MAD = | |
659 | { | |
660 | "MAD", | |
661 | MIX_MUSIC_MAD, | |
662 | MUS_MP3, | |
663 | SDL_FALSE, | |
664 | SDL_FALSE, | |
665 | ||
666 | NULL, /* Load */ | |
667 | NULL, /* Open */ | |
668 | MAD_CreateFromRW, | |
669 | NULL, /* CreateFromFile */ | |
670 | MAD_SetVolume, | |
671 | MAD_GetVolume, | |
672 | MAD_Play, | |
673 | NULL, /* IsPlaying */ | |
674 | MAD_GetAudio, | |
675 | NULL, /* Jump */ | |
676 | MAD_Seek, | |
677 | MAD_Tell, | |
678 | MAD_Duration, | |
679 | NULL, /* LoopStart */ | |
680 | NULL, /* LoopEnd */ | |
681 | NULL, /* LoopLength */ | |
682 | MAD_GetMetaTag, | |
683 | NULL, /* Pause */ | |
684 | NULL, /* Resume */ | |
685 | MAD_Stop, | |
686 | MAD_Delete, | |
687 | NULL, /* Close */ | |
688 | NULL /* Unload */ | |
689 | }; | |
690 | ||
691 | #endif /* MUSIC_MP3_MAD */ | |
692 | ||
693 | /* vi: set ts=4 sw=4 expandtab: */ |
0 | /* | |
1 | SDL_mixer: An audio mixer library based on the SDL library | |
2 | Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org> | |
3 | ||
4 | This software is provided 'as-is', without any express or implied | |
5 | warranty. In no event will the authors be held liable for any damages | |
6 | arising from the use of this software. | |
7 | ||
8 | Permission is granted to anyone to use this software for any purpose, | |
9 | including commercial applications, and to alter it and redistribute it | |
10 | freely, subject to the following restrictions: | |
11 | ||
12 | 1. The origin of this software must not be misrepresented; you must not | |
13 | claim that you wrote the original software. If you use this software | |
14 | in a product, an acknowledgment in the product documentation would be | |
15 | appreciated but is not required. | |
16 | 2. Altered source versions must be plainly marked as such, and must not be | |
17 | misrepresented as being the original software. | |
18 | 3. This notice may not be removed or altered from any source distribution. | |
19 | */ | |
20 | ||
21 | /* This file supports playing MP3 files with libmad */ | |
22 | ||
23 | #include "music.h" | |
24 | ||
25 | extern Mix_MusicInterface Mix_MusicInterface_MAD; | |
26 | ||
27 | /* vi: set ts=4 sw=4 expandtab: */ |
0 | /* | |
1 | SDL_mixer: An audio mixer library based on the SDL library | |
2 | Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org> | |
3 | ||
4 | This software is provided 'as-is', without any express or implied | |
5 | warranty. In no event will the authors be held liable for any damages | |
6 | arising from the use of this software. | |
7 | ||
8 | Permission is granted to anyone to use this software for any purpose, | |
9 | including commercial applications, and to alter it and redistribute it | |
10 | freely, subject to the following restrictions: | |
11 | ||
12 | 1. The origin of this software must not be misrepresented; you must not | |
13 | claim that you wrote the original software. If you use this software | |
14 | in a product, an acknowledgment in the product documentation would be | |
15 | appreciated but is not required. | |
16 | 2. Altered source versions must be plainly marked as such, and must not be | |
17 | misrepresented as being the original software. | |
18 | 3. This notice may not be removed or altered from any source distribution. | |
19 | */ | |
20 | ||
21 | #ifdef MUSIC_MOD_MIKMOD | |
22 | ||
23 | /* This file supports MOD tracker music streams */ | |
24 | ||
25 | #include "SDL_loadso.h" | |
26 | ||
27 | #include "music_mikmod.h" | |
28 | ||
29 | #include "mikmod.h" | |
30 | ||
31 | ||
32 | /* libmikmod >= 3.3.2 constified several funcs */ | |
33 | #if (LIBMIKMOD_VERSION < 0x030302) | |
34 | #define MIKMOD3_CONST | |
35 | #else | |
36 | #define MIKMOD3_CONST const | |
37 | #endif | |
38 | ||
39 | typedef struct { | |
40 | int loaded; | |
41 | void *handle; | |
42 | ||
43 | void (*MikMod_Exit)(void); | |
44 | CHAR* (*MikMod_InfoDriver)(void); | |
45 | CHAR* (*MikMod_InfoLoader)(void); | |
46 | int (*MikMod_Init)(MIKMOD3_CONST CHAR*); | |
47 | void (*MikMod_RegisterAllLoaders)(void); | |
48 | void (*MikMod_RegisterDriver)(struct MDRIVER*); | |
49 | int* MikMod_errno; | |
50 | MIKMOD3_CONST char* (*MikMod_strerror)(int); | |
51 | void (*MikMod_free)(void*); | |
52 | BOOL (*Player_Active)(void); | |
53 | void (*Player_Free)(MODULE*); | |
54 | MODULE* (*Player_LoadGeneric)(MREADER*,int,BOOL); | |
55 | void (*Player_SetPosition)(UWORD); | |
56 | void (*Player_SetVolume)(SWORD); | |
57 | void (*Player_Start)(MODULE*); | |
58 | void (*Player_Stop)(void); | |
59 | ULONG (*VC_WriteBytes)(SBYTE*,ULONG); | |
60 | struct MDRIVER* drv_nos; | |
61 | UWORD* md_device; | |
62 | UWORD* md_mixfreq; | |
63 | UWORD* md_mode; | |
64 | UBYTE* md_musicvolume; | |
65 | UBYTE* md_pansep; | |
66 | UBYTE* md_reverb; | |
67 | UBYTE* md_sndfxvolume; | |
68 | UBYTE* md_volume; | |
69 | } mikmod_loader; | |
70 | ||
71 | static mikmod_loader mikmod; | |
72 | ||
73 | #ifdef MIKMOD_DYNAMIC | |
74 | #define FUNCTION_LOADER(FUNC, SIG) \ | |
75 | mikmod.FUNC = (SIG) SDL_LoadFunction(mikmod.handle, #FUNC); \ | |
76 | if (mikmod.FUNC == NULL) { SDL_UnloadObject(mikmod.handle); return -1; } | |
77 | #define VARIABLE_LOADER(NAME, SIG) \ | |
78 | mikmod.NAME = (SIG) SDL_LoadFunction(mikmod.handle, #NAME); \ | |
79 | if (mikmod.NAME == NULL) { SDL_UnloadObject(mikmod.handle); return -1; } | |
80 | #else | |
81 | #define FUNCTION_LOADER(FUNC, SIG) \ | |
82 | mikmod.FUNC = FUNC; \ | |
83 | if (mikmod.FUNC == NULL) { Mix_SetError("Missing mikmod.framework"); return -1; } | |
84 | #define VARIABLE_LOADER(NAME, SIG) \ | |
85 | mikmod.NAME = &NAME; | |
86 | #endif | |
87 | ||
88 | static int MIKMOD_Load(void) | |
89 | { | |
90 | if (mikmod.loaded == 0) { | |
91 | #ifdef MIKMOD_DYNAMIC | |
92 | mikmod.handle = SDL_LoadObject(MIKMOD_DYNAMIC); | |
93 | if (mikmod.handle == NULL) { | |
94 | return -1; | |
95 | } | |
96 | #endif | |
97 | FUNCTION_LOADER(MikMod_Exit, void (*)(void)) | |
98 | FUNCTION_LOADER(MikMod_InfoDriver, CHAR* (*)(void)) | |
99 | FUNCTION_LOADER(MikMod_InfoLoader, CHAR* (*)(void)) | |
100 | FUNCTION_LOADER(MikMod_Init, int (*)(MIKMOD3_CONST CHAR*)) | |
101 | FUNCTION_LOADER(MikMod_RegisterAllLoaders, void (*)(void)) | |
102 | FUNCTION_LOADER(MikMod_RegisterDriver, void (*)(struct MDRIVER*)) | |
103 | VARIABLE_LOADER(MikMod_errno, int*) | |
104 | FUNCTION_LOADER(MikMod_strerror, MIKMOD3_CONST char* (*)(int)) | |
105 | #ifdef MIKMOD_DYNAMIC | |
106 | mikmod.MikMod_free = (void (*)(void*)) SDL_LoadFunction(mikmod.handle, "MikMod_free"); | |
107 | if (!mikmod.MikMod_free) { | |
108 | /* libmikmod-3.2.0-beta2 and earlier doesn't have it. */ | |
109 | mikmod.MikMod_free = free; | |
110 | } | |
111 | #else | |
112 | #if (LIBMIKMOD_VERSION < 0x030200) || (LIBMIKMOD_VERSION == 0x030200 && !defined(DMODE_NOISEREDUCTION)) | |
113 | /* libmikmod 3.2.0-beta2 or earlier */ | |
114 | mikmod.MikMod_free = free; | |
115 | #else | |
116 | mikmod.MikMod_free = MikMod_free; | |
117 | #endif | |
118 | #endif /* MIKMOD_DYNAMIC */ | |
119 | FUNCTION_LOADER(Player_Active, BOOL (*)(void)) | |
120 | FUNCTION_LOADER(Player_Free, void (*)(MODULE*)) | |
121 | FUNCTION_LOADER(Player_LoadGeneric, MODULE* (*)(MREADER*,int,BOOL)) | |
122 | FUNCTION_LOADER(Player_SetPosition, void (*)(UWORD)) | |
123 | FUNCTION_LOADER(Player_SetVolume, void (*)(SWORD)) | |
124 | FUNCTION_LOADER(Player_Start, void (*)(MODULE*)) | |
125 | FUNCTION_LOADER(Player_Stop, void (*)(void)) | |
126 | FUNCTION_LOADER(VC_WriteBytes, ULONG (*)(SBYTE*,ULONG)) | |
127 | VARIABLE_LOADER(drv_nos, MDRIVER*) | |
128 | VARIABLE_LOADER(md_device, UWORD*) | |
129 | VARIABLE_LOADER(md_mixfreq, UWORD*) | |
130 | VARIABLE_LOADER(md_mode, UWORD*) | |
131 | VARIABLE_LOADER(md_musicvolume, UBYTE*) | |
132 | VARIABLE_LOADER(md_pansep, UBYTE*) | |
133 | VARIABLE_LOADER(md_reverb, UBYTE*) | |
134 | VARIABLE_LOADER(md_sndfxvolume, UBYTE*) | |
135 | VARIABLE_LOADER(md_volume, UBYTE*) | |
136 | } | |
137 | ++mikmod.loaded; | |
138 | ||
139 | return 0; | |
140 | } | |
141 | ||
142 | static void MIKMOD_Unload(void) | |
143 | { | |
144 | if (mikmod.loaded == 0) { | |
145 | return; | |
146 | } | |
147 | if (mikmod.loaded == 1) { | |
148 | #ifdef MIKMOD_DYNAMIC | |
149 | SDL_UnloadObject(mikmod.handle); | |
150 | #endif | |
151 | } | |
152 | --mikmod.loaded; | |
153 | } | |
154 | ||
155 | ||
156 | typedef struct | |
157 | { | |
158 | int play_count; | |
159 | int volume; | |
160 | MODULE *module; | |
161 | SDL_AudioStream *stream; | |
162 | SBYTE *buffer; | |
163 | ULONG buffer_size; | |
164 | Mix_MusicMetaTags tags; | |
165 | } MIKMOD_Music; | |
166 | ||
167 | ||
168 | static int MIKMOD_Seek(void *context, double position); | |
169 | static void MIKMOD_Delete(void *context); | |
170 | ||
171 | /* Initialize the MOD player, with the given mixer settings | |
172 | This function returns 0, or -1 if there was an error. | |
173 | */ | |
174 | static int MIKMOD_Open(const SDL_AudioSpec *spec) | |
175 | { | |
176 | CHAR *list; | |
177 | ||
178 | /* Set the MikMod music format */ | |
179 | if (spec->format == AUDIO_S8 || spec->format == AUDIO_U8) { | |
180 | /* MIKMOD audio format is AUDIO_U8 */ | |
181 | *mikmod.md_mode = 0; | |
182 | } else { | |
183 | /* MIKMOD audio format is AUDIO_S16SYS */ | |
184 | *mikmod.md_mode = DMODE_16BITS; | |
185 | } | |
186 | if (spec->channels > 1) { | |
187 | *mikmod.md_mode |= DMODE_STEREO; | |
188 | } | |
189 | *mikmod.md_mixfreq = (spec->freq <= 65535) ? (UWORD)spec->freq : 44100; | |
190 | *mikmod.md_device = 0; | |
191 | *mikmod.md_volume = 96; | |
192 | *mikmod.md_musicvolume = 128; | |
193 | *mikmod.md_sndfxvolume = 128; | |
194 | *mikmod.md_pansep = 128; | |
195 | *mikmod.md_reverb = 0; | |
196 | *mikmod.md_mode |= DMODE_HQMIXER|DMODE_SOFT_MUSIC|DMODE_SURROUND; | |
197 | ||
198 | list = mikmod.MikMod_InfoDriver(); | |
199 | if (list) { | |
200 | mikmod.MikMod_free(list); | |
201 | } else { | |
202 | mikmod.MikMod_RegisterDriver(mikmod.drv_nos); | |
203 | } | |
204 | ||
205 | list = mikmod.MikMod_InfoLoader(); | |
206 | if (list) { | |
207 | mikmod.MikMod_free(list); | |
208 | } else { | |
209 | mikmod.MikMod_RegisterAllLoaders(); | |
210 | } | |
211 | ||
212 | if (mikmod.MikMod_Init(NULL)) { | |
213 | Mix_SetError("%s", mikmod.MikMod_strerror(*mikmod.MikMod_errno)); | |
214 | return -1; | |
215 | } | |
216 | return 0; | |
217 | } | |
218 | ||
219 | /* Uninitialize the music players */ | |
220 | static void MIKMOD_Close(void) | |
221 | { | |
222 | if (mikmod.MikMod_Exit) { | |
223 | mikmod.MikMod_Exit(); | |
224 | } | |
225 | } | |
226 | ||
227 | typedef struct | |
228 | { | |
229 | /* MREADER basic members in libmikmod2/3: */ | |
230 | int (*Seek)(struct MREADER*, long, int); | |
231 | long (*Tell)(struct MREADER*); | |
232 | BOOL (*Read)(struct MREADER*, void*, size_t); | |
233 | int (*Get)(struct MREADER*); | |
234 | BOOL (*Eof)(struct MREADER*); | |
235 | /* no iobase members in libmikmod <= 3.2.0-beta2 */ | |
236 | long iobase, prev_iobase; | |
237 | ||
238 | Sint64 eof; | |
239 | SDL_RWops *src; | |
240 | } LMM_MREADER; | |
241 | ||
242 | int LMM_Seek(struct MREADER *mr,long to,int dir) | |
243 | { | |
244 | Sint64 offset = to; | |
245 | LMM_MREADER* lmmmr = (LMM_MREADER*)mr; | |
246 | if (dir == SEEK_SET) { | |
247 | offset += lmmmr->iobase; | |
248 | if (offset < lmmmr->iobase) | |
249 | return -1; | |
250 | } | |
251 | return (SDL_RWseek(lmmmr->src, offset, dir) < lmmmr->iobase)? -1 : 0; | |
252 | } | |
253 | long LMM_Tell(struct MREADER *mr) | |
254 | { | |
255 | LMM_MREADER* lmmmr = (LMM_MREADER*)mr; | |
256 | return (long)(SDL_RWtell(lmmmr->src) - lmmmr->iobase); | |
257 | } | |
258 | BOOL LMM_Read(struct MREADER *mr,void *buf,size_t sz) | |
259 | { | |
260 | LMM_MREADER* lmmmr = (LMM_MREADER*)mr; | |
261 | return (BOOL)SDL_RWread(lmmmr->src, buf, sz, 1); | |
262 | } | |
263 | int LMM_Get(struct MREADER *mr) | |
264 | { | |
265 | unsigned char c; | |
266 | LMM_MREADER* lmmmr = (LMM_MREADER*)mr; | |
267 | if (SDL_RWread(lmmmr->src, &c, 1, 1)) { | |
268 | return c; | |
269 | } | |
270 | return EOF; | |
271 | } | |
272 | BOOL LMM_Eof(struct MREADER *mr) | |
273 | { | |
274 | Sint64 offset; | |
275 | LMM_MREADER* lmmmr = (LMM_MREADER*)mr; | |
276 | offset = LMM_Tell(mr); | |
277 | return offset >= lmmmr->eof; | |
278 | } | |
279 | MODULE *MikMod_LoadSongRW(SDL_RWops *src, int maxchan) | |
280 | { | |
281 | LMM_MREADER lmmmr; | |
282 | SDL_memset(&lmmmr, 0, sizeof(LMM_MREADER)); | |
283 | lmmmr.Seek = LMM_Seek; | |
284 | lmmmr.Tell = LMM_Tell; | |
285 | lmmmr.Read = LMM_Read; | |
286 | lmmmr.Get = LMM_Get; | |
287 | lmmmr.Eof = LMM_Eof; | |
288 | ||
289 | lmmmr.prev_iobase = lmmmr.iobase = SDL_RWtell(src); | |
290 | SDL_RWseek(src, 0, RW_SEEK_END); | |
291 | lmmmr.eof = SDL_RWtell(src); | |
292 | SDL_RWseek(src, lmmmr.iobase, RW_SEEK_SET); | |
293 | lmmmr.src = src; | |
294 | return mikmod.Player_LoadGeneric((MREADER*)&lmmmr, maxchan, 0); | |
295 | } | |
296 | ||
297 | /* Load a MOD stream from an SDL_RWops object */ | |
298 | void *MIKMOD_CreateFromRW(SDL_RWops *src, int freesrc) | |
299 | { | |
300 | MIKMOD_Music *music; | |
301 | SDL_AudioFormat format; | |
302 | Uint8 channels; | |
303 | ||
304 | music = (MIKMOD_Music *)SDL_calloc(1, sizeof(*music)); | |
305 | if (!music) { | |
306 | SDL_OutOfMemory(); | |
307 | return NULL; | |
308 | } | |
309 | music->volume = MIX_MAX_VOLUME; | |
310 | ||
311 | music->module = MikMod_LoadSongRW(src, 64); | |
312 | if (!music->module) { | |
313 | Mix_SetError("%s", mikmod.MikMod_strerror(*mikmod.MikMod_errno)); | |
314 | MIKMOD_Delete(music); | |
315 | return NULL; | |
316 | } | |
317 | ||
318 | /* Allow implicit looping, disable fade out and other flags. */ | |
319 | music->module->extspd = 1; | |
320 | music->module->panflag = 1; | |
321 | music->module->wrap = 0; | |
322 | music->module->loop = 1; | |
323 | music->module->fadeout = 0; | |
324 | ||
325 | meta_tags_init(&music->tags); | |
326 | meta_tags_set(&music->tags, MIX_META_TITLE, music->module->songname); | |
327 | ||
328 | if ((*mikmod.md_mode & DMODE_16BITS) == DMODE_16BITS) { | |
329 | format = AUDIO_S16SYS; | |
330 | } else { | |
331 | format = AUDIO_U8; | |
332 | } | |
333 | if ((*mikmod.md_mode & DMODE_STEREO) == DMODE_STEREO) { | |
334 | channels = 2; | |
335 | } else { | |
336 | channels = 1; | |
337 | } | |
338 | music->stream = SDL_NewAudioStream(format, channels, *mikmod.md_mixfreq, | |
339 | music_spec.format, music_spec.channels, music_spec.freq); | |
340 | if (!music->stream) { | |
341 | MIKMOD_Delete(music); | |
342 | return NULL; | |
343 | } | |
344 | ||
345 | music->buffer_size = music_spec.samples * (SDL_AUDIO_BITSIZE(format) / 8) * channels; | |
346 | music->buffer = (SBYTE *)SDL_malloc(music->buffer_size); | |
347 | if (!music->buffer) { | |
348 | SDL_OutOfMemory(); | |
349 | MIKMOD_Delete(music); | |
350 | return NULL; | |
351 | } | |
352 | ||
353 | if (freesrc) { | |
354 | SDL_RWclose(src); | |
355 | } | |
356 | ||
357 | return music; | |
358 | } | |
359 | ||
360 | /* Set the volume for a MOD stream */ | |
361 | static void MIKMOD_SetVolume(void *context, int volume) | |
362 | { | |
363 | MIKMOD_Music *music = (MIKMOD_Music *)context; | |
364 | music->volume = volume; | |
365 | mikmod.Player_SetVolume((SWORD)volume); | |
366 | } | |
367 | ||
368 | /* Set the volume for a MOD stream */ | |
369 | static int MIKMOD_GetVolume(void *context) | |
370 | { | |
371 | MIKMOD_Music *music = (MIKMOD_Music *)context; | |
372 | return music->volume; | |
373 | } | |
374 | ||
375 | /* Start playback of a given MOD stream */ | |
376 | static int MIKMOD_Play(void *context, int play_count) | |
377 | { | |
378 | MIKMOD_Music *music = (MIKMOD_Music *)context; | |
379 | music->play_count = play_count; | |
380 | music->module->initvolume = (UBYTE)music->volume; | |
381 | mikmod.Player_Start(music->module); | |
382 | return MIKMOD_Seek(music, 0.0); | |
383 | } | |
384 | ||
385 | /* Return non-zero if a stream is currently playing */ | |
386 | static SDL_bool MIKMOD_IsPlaying(void *context) | |
387 | { | |
388 | (void)context; | |
389 | return mikmod.Player_Active() ? SDL_TRUE : SDL_FALSE; | |
390 | } | |
391 | ||
392 | /* Play some of a stream previously started with MOD_play() */ | |
393 | static int MIKMOD_GetSome(void *context, void *data, int bytes, SDL_bool *done) | |
394 | { | |
395 | MIKMOD_Music *music = (MIKMOD_Music *)context; | |
396 | int filled; | |
397 | ||
398 | filled = SDL_AudioStreamGet(music->stream, data, bytes); | |
399 | if (filled != 0) { | |
400 | return filled; | |
401 | } | |
402 | ||
403 | if (!music->play_count) { | |
404 | /* All done */ | |
405 | *done = SDL_TRUE; | |
406 | return 0; | |
407 | } | |
408 | ||
409 | /* This never fails, and always writes a full buffer */ | |
410 | mikmod.VC_WriteBytes(music->buffer, music->buffer_size); | |
411 | ||
412 | if (SDL_AudioStreamPut(music->stream, music->buffer, (int)music->buffer_size) < 0) { | |
413 | return -1; | |
414 | } | |
415 | ||
416 | /* Check to see if we're done now */ | |
417 | if (!mikmod.Player_Active()) { | |
418 | if (music->play_count == 1) { | |
419 | music->play_count = 0; | |
420 | SDL_AudioStreamFlush(music->stream); | |
421 | } else { | |
422 | int play_count = -1; | |
423 | if (music->play_count > 0) { | |
424 | play_count = (music->play_count - 1); | |
425 | } | |
426 | if (MIKMOD_Play(music, play_count) < 0) { | |
427 | return -1; | |
428 | } | |
429 | } | |
430 | } | |
431 | return 0; | |
432 | } | |
433 | static int MIKMOD_GetAudio(void *context, void *data, int bytes) | |
434 | { | |
435 | return music_pcm_getaudio(context, data, bytes, MIX_MAX_VOLUME, MIKMOD_GetSome); | |
436 | } | |
437 | ||
438 | /* Jump to a given order */ | |
439 | static int MIKMOD_Jump(void *context, int order) | |
440 | { | |
441 | (void)context; | |
442 | mikmod.Player_SetPosition((UWORD)order); | |
443 | return 0; | |
444 | } | |
445 | ||
446 | /* Jump (seek) to a given position (time is in seconds) */ | |
447 | static int MIKMOD_Seek(void *context, double position) | |
448 | { | |
449 | (void)context; | |
450 | /* FIXME: WRONG: THIS IS NOT A TIME SEEK */ | |
451 | mikmod.Player_SetPosition((UWORD)position); | |
452 | return 0; | |
453 | } | |
454 | ||
455 | /* Stop playback of a stream previously started with MOD_play() */ | |
456 | static void MIKMOD_Stop(void *context) | |
457 | { | |
458 | (void)context; | |
459 | mikmod.Player_Stop(); | |
460 | } | |
461 | ||
462 | static const char* MIKMOD_GetMetaTag(void *context, Mix_MusicMetaTag tag_type) | |
463 | { | |
464 | MIKMOD_Music *music = (MIKMOD_Music *)context; | |
465 | return meta_tags_get(&music->tags, tag_type); | |
466 | } | |
467 | ||
468 | /* Close the given MOD stream */ | |
469 | static void MIKMOD_Delete(void *context) | |
470 | { | |
471 | MIKMOD_Music *music = (MIKMOD_Music *)context; | |
472 | ||
473 | meta_tags_clear(&music->tags); | |
474 | if (music->module) { | |
475 | mikmod.Player_Free(music->module); | |
476 | } | |
477 | if (music->stream) { | |
478 | SDL_FreeAudioStream(music->stream); | |
479 | } | |
480 | if (music->buffer) { | |
481 | SDL_free(music->buffer); | |
482 | } | |
483 | SDL_free(music); | |
484 | } | |
485 | ||
486 | Mix_MusicInterface Mix_MusicInterface_MIKMOD = | |
487 | { | |
488 | "MIKMOD", | |
489 | MIX_MUSIC_MIKMOD, | |
490 | MUS_MOD, | |
491 | SDL_FALSE, | |
492 | SDL_FALSE, | |
493 | ||
494 | MIKMOD_Load, | |
495 | MIKMOD_Open, | |
496 | MIKMOD_CreateFromRW, | |
497 | NULL, /* CreateFromFile */ | |
498 | MIKMOD_SetVolume, | |
499 | MIKMOD_GetVolume, | |
500 | MIKMOD_Play, | |
501 | MIKMOD_IsPlaying, | |
502 | MIKMOD_GetAudio, | |
503 | MIKMOD_Jump, | |
504 | MIKMOD_Seek, | |
505 | NULL, /* Tell */ | |
506 | NULL, /* Duration */ | |
507 | NULL, /* LoopStart */ | |
508 | NULL, /* LoopEnd */ | |
509 | NULL, /* LoopLength */ | |
510 | MIKMOD_GetMetaTag, | |
511 | NULL, /* Pause */ | |
512 | NULL, /* Resume */ | |
513 | MIKMOD_Stop, | |
514 | MIKMOD_Delete, | |
515 | MIKMOD_Close, | |
516 | MIKMOD_Unload | |
517 | }; | |
518 | ||
519 | #endif /* MUSIC_MOD_MIKMOD */ | |
520 | ||
521 | /* vi: set ts=4 sw=4 expandtab: */ |
0 | /* | |
1 | SDL_mixer: An audio mixer library based on the SDL library | |
2 | Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org> | |
3 | ||
4 | This software is provided 'as-is', without any express or implied | |
5 | warranty. In no event will the authors be held liable for any damages | |
6 | arising from the use of this software. | |
7 | ||
8 | Permission is granted to anyone to use this software for any purpose, | |
9 | including commercial applications, and to alter it and redistribute it | |
10 | freely, subject to the following restrictions: | |
11 | ||
12 | 1. The origin of this software must not be misrepresented; you must not | |
13 | claim that you wrote the original software. If you use this software | |
14 | in a product, an acknowledgment in the product documentation would be | |
15 | appreciated but is not required. | |
16 | 2. Altered source versions must be plainly marked as such, and must not be | |
17 | misrepresented as being the original software. | |
18 | 3. This notice may not be removed or altered from any source distribution. | |
19 | */ | |
20 | ||
21 | /* This file supports playing MOD files with libmikmod */ | |
22 | ||
23 | #include "music.h" | |
24 | ||
25 | extern Mix_MusicInterface Mix_MusicInterface_MIKMOD; | |
26 | ||
27 | /* vi: set ts=4 sw=4 expandtab: */ |
359 | 359 | { |
360 | 360 | MPG123_Music *music = (MPG123_Music *)context; |
361 | 361 | int filled, result; |
362 | size_t amount; | |
362 | size_t amount = 0; | |
363 | 363 | long rate; |
364 | 364 | int channels, encoding, format; |
365 | 365 | |
411 | 411 | break; |
412 | 412 | |
413 | 413 | case MPG123_DONE: |
414 | if (amount > 0) { | |
415 | if (SDL_AudioStreamPut(music->stream, music->buffer, (int)amount) < 0) { | |
416 | return -1; | |
417 | } | |
418 | break; | |
419 | } | |
414 | 420 | if (music->play_count == 1) { |
415 | 421 | music->play_count = 0; |
416 | 422 | SDL_AudioStreamFlush(music->stream); |
40 | 40 | Uint16 ppqn; |
41 | 41 | int Size; |
42 | 42 | int NewPos; |
43 | SDL_mutex *mutex; | |
43 | 44 | }; |
44 | 45 | |
45 | 46 | static UINT MidiDevice=MIDI_MAPPER; |
163 | 164 | void CALLBACK MidiProc( HMIDIIN hMidi, UINT uMsg, DWORD_PTR dwInstance, |
164 | 165 | DWORD_PTR dwParam1, DWORD_PTR dwParam2 ) |
165 | 166 | { |
167 | NativeMidiSong *song = (NativeMidiSong *)dwInstance; | |
166 | 168 | (void)hMidi; |
167 | (void)dwInstance; | |
168 | 169 | (void)dwParam2; |
169 | 170 | |
171 | if (!song) { | |
172 | return; | |
173 | } | |
174 | ||
175 | SDL_LockMutex(song->mutex); | |
170 | 176 | switch( uMsg ) |
171 | 177 | { |
172 | 178 | case MOM_DONE: |
173 | if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)¤tsong->MidiStreamHdr[currentsong->CurrentHdr])) | |
174 | BlockOut(currentsong); | |
179 | if (song->MusicPlaying && song->MusicLoaded && (dwParam1 == (DWORD_PTR)&song->MidiStreamHdr[song->CurrentHdr])) | |
180 | BlockOut(song); | |
175 | 181 | break; |
176 | 182 | case MOM_POSITIONCB: |
177 | if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)¤tsong->MidiStreamHdr[currentsong->CurrentHdr])) { | |
178 | if (currentsong->Loops) { | |
179 | if (currentsong->Loops > 0) | |
180 | --currentsong->Loops; | |
181 | currentsong->NewPos=0; | |
182 | BlockOut(currentsong); | |
183 | if (song->MusicPlaying && song->MusicLoaded && (dwParam1 == (DWORD_PTR)&song->MidiStreamHdr[song->CurrentHdr])) { | |
184 | if (song->Loops) { | |
185 | if (song->Loops > 0) | |
186 | --song->Loops; | |
187 | song->NewPos=0; | |
188 | BlockOut(song); | |
183 | 189 | } else { |
184 | currentsong->MusicPlaying=0; | |
190 | song->MusicPlaying=0; | |
185 | 191 | } |
186 | 192 | } |
187 | 193 | break; |
194 | case MOM_CLOSE: | |
195 | song->MusicPlaying=0; | |
196 | break; | |
188 | 197 | default: |
189 | 198 | break; |
190 | 199 | } |
200 | SDL_UnlockMutex(song->mutex); | |
191 | 201 | } |
192 | 202 | |
193 | 203 | int native_midi_detect(void) |
225 | 235 | |
226 | 236 | FreeMIDIEventList(evntlist); |
227 | 237 | |
238 | newsong->mutex = SDL_CreateMutex(); | |
239 | ||
228 | 240 | if (freesrc) { |
229 | 241 | SDL_RWclose(src); |
230 | 242 | } |
233 | 245 | |
234 | 246 | void native_midi_freesong(NativeMidiSong *song) |
235 | 247 | { |
236 | if (hMidiStream) | |
237 | { | |
238 | midiStreamStop(hMidiStream); | |
239 | midiStreamClose(hMidiStream); | |
240 | } | |
241 | 248 | if (song) |
242 | 249 | { |
243 | 250 | if (song->NewEvents) |
244 | 251 | SDL_free(song->NewEvents); |
252 | SDL_DestroyMutex(song->mutex); | |
245 | 253 | SDL_free(song); |
246 | 254 | } |
247 | 255 | } |
254 | 262 | native_midi_stop(); |
255 | 263 | if (!hMidiStream) |
256 | 264 | { |
257 | merr=midiStreamOpen(&hMidiStream,&MidiDevice,(DWORD)1,(DWORD_PTR)MidiProc,(DWORD_PTR)0,CALLBACK_FUNCTION); | |
265 | merr=midiStreamOpen(&hMidiStream,&MidiDevice,(DWORD)1,(DWORD_PTR)MidiProc,(DWORD_PTR)song,CALLBACK_FUNCTION); | |
258 | 266 | if (merr!=MMSYSERR_NOERROR) |
259 | 267 | { |
260 | 268 | hMidiStream = NULL; /* should I do midiStreamClose(hMidiStream) before? */ |
289 | 297 | |
290 | 298 | void native_midi_stop(void) |
291 | 299 | { |
300 | NativeMidiSong *song = currentsong; | |
301 | ||
292 | 302 | if (!hMidiStream) |
293 | 303 | return; |
304 | ||
305 | SDL_LockMutex(song->mutex); | |
294 | 306 | midiStreamStop(hMidiStream); |
295 | 307 | midiStreamClose(hMidiStream); |
296 | 308 | currentsong=NULL; |
297 | 309 | hMidiStream = NULL; |
310 | SDL_UnlockMutex(song->mutex); | |
298 | 311 | } |
299 | 312 | |
300 | 313 | int native_midi_active(void) |
325 | 325 | mix_channels(void *udata, Uint8 *stream, int len) |
326 | 326 | { |
327 | 327 | Uint8 *mix_input; |
328 | int i, mixable, volume, master_vol; | |
328 | int i, mixable, master_vol; | |
329 | 329 | Uint32 sdl_ticks; |
330 | 330 | |
331 | 331 | (void)udata; |
336 | 336 | /* Mix the music (must be done before the channels are added) */ |
337 | 337 | mix_music(music_data, stream, len); |
338 | 338 | |
339 | volume = Mix_MasterVolume(-1); | |
340 | master_vol = volume; | |
339 | master_vol = SDL_AtomicGet(&master_volume); | |
341 | 340 | |
342 | 341 | /* Mix any playing channels... */ |
343 | 342 | sdl_ticks = SDL_GetTicks(); |
371 | 370 | } |
372 | 371 | } |
373 | 372 | if (mix_channel[i].playing > 0) { |
373 | int volume = (master_vol * (mix_channel[i].volume * mix_channel[i].chunk->volume)) / (MIX_MAX_VOLUME * MIX_MAX_VOLUME); | |
374 | 374 | int index = 0; |
375 | 375 | int remaining = len; |
376 | 376 | while (mix_channel[i].playing > 0 && index < len) { |
377 | 377 | remaining = len - index; |
378 | volume = (master_vol * (mix_channel[i].volume * mix_channel[i].chunk->volume)) / (MIX_MAX_VOLUME * MIX_MAX_VOLUME); | |
379 | 378 | mixable = mix_channel[i].playing; |
380 | 379 | if (mixable > remaining) { |
381 | 380 | mixable = remaining; |
382 | 381 | } |
383 | 382 | |
384 | 383 | mix_input = Mix_DoEffects(i, mix_channel[i].samples, mixable); |
385 | SDL_MixAudioFormat(stream+index,mix_input,mixer.format,mixable,volume); | |
384 | SDL_MixAudioFormat(stream+index, mix_input, mixer.format, mixable, volume); | |
386 | 385 | if (mix_input != mix_channel[i].samples) |
387 | 386 | SDL_free(mix_input); |
388 | 387 | |
393 | 392 | /* rcg06072001 Alert app if channel is done playing. */ |
394 | 393 | if (!mix_channel[i].playing && !mix_channel[i].looping) { |
395 | 394 | _Mix_channel_done_playing(i); |
395 | ||
396 | /* Update the volume after the application callback */ | |
397 | volume = (master_vol * (mix_channel[i].volume * mix_channel[i].chunk->volume)) / (MIX_MAX_VOLUME * MIX_MAX_VOLUME); | |
396 | 398 | } |
397 | 399 | } |
398 | 400 | |
632 | 634 | |
633 | 635 | /* These music interfaces are not safe to use while music is playing */ |
634 | 636 | if (interface->api == MIX_MUSIC_CMD || |
635 | interface->api == MIX_MUSIC_MIKMOD || | |
636 | 637 | interface->api == MIX_MUSIC_NATIVEMIDI) { |
637 | 638 | continue; |
638 | 639 | } |
27 | 27 | |
28 | 28 | #include "music_cmd.h" |
29 | 29 | #include "music_wav.h" |
30 | #include "music_mikmod.h" | |
31 | 30 | #include "music_modplug.h" |
32 | 31 | #include "music_xmp.h" |
33 | 32 | #include "music_nativemidi.h" |
37 | 36 | #include "music_opus.h" |
38 | 37 | #include "music_drmp3.h" |
39 | 38 | #include "music_mpg123.h" |
40 | #include "music_mad.h" | |
41 | 39 | #include "music_drflac.h" |
42 | 40 | #include "music_flac.h" |
43 | 41 | #include "native_midi/native_midi.h" |
92 | 90 | |
93 | 91 | void meta_tags_clear(Mix_MusicMetaTags *tags) |
94 | 92 | { |
95 | size_t i = 0; | |
93 | size_t i; | |
94 | ||
96 | 95 | for (i = 0; i < MIX_META_LAST; i++) { |
97 | 96 | if (tags->tags[i]) { |
98 | 97 | SDL_free(tags->tags[i]); |
182 | 181 | #ifdef MUSIC_MP3_MPG123 |
183 | 182 | &Mix_MusicInterface_MPG123, |
184 | 183 | #endif |
185 | #ifdef MUSIC_MP3_MAD | |
186 | &Mix_MusicInterface_MAD, | |
187 | #endif | |
188 | 184 | #ifdef MUSIC_MOD_XMP |
189 | 185 | &Mix_MusicInterface_XMP, |
190 | 186 | #endif |
191 | 187 | #ifdef MUSIC_MOD_MODPLUG |
192 | 188 | &Mix_MusicInterface_MODPLUG, |
193 | #endif | |
194 | #ifdef MUSIC_MOD_MIKMOD | |
195 | &Mix_MusicInterface_MIKMOD, | |
196 | 189 | #endif |
197 | 190 | #ifdef MUSIC_MID_FLUIDSYNTH |
198 | 191 | &Mix_MusicInterface_FLUIDSYNTH, |
287 | 280 | Uint8 *snd = (Uint8 *)data; |
288 | 281 | Uint8 *dst; |
289 | 282 | int len = bytes; |
283 | int zero_cycles = 0; | |
284 | const int MAX_ZERO_CYCLES = 10; /* just try to catch infinite loops */ | |
290 | 285 | SDL_bool done = SDL_FALSE; |
291 | 286 | |
292 | 287 | if (volume == MIX_MAX_VOLUME) { |
299 | 294 | if (consumed < 0) { |
300 | 295 | break; |
301 | 296 | } |
297 | if (consumed == 0) { | |
298 | ++zero_cycles; | |
299 | if (zero_cycles > MAX_ZERO_CYCLES) { | |
300 | /* We went too many cycles with no data, we're done */ | |
301 | done = SDL_TRUE; | |
302 | } | |
303 | continue; | |
304 | } | |
305 | zero_cycles = 0; | |
302 | 306 | |
303 | 307 | if (volume == MIX_MAX_VOLUME) { |
304 | 308 | dst += consumed; |
317 | 321 | /* Mixing function */ |
318 | 322 | void SDLCALL music_mixer(void *udata, Uint8 *stream, int len) |
319 | 323 | { |
324 | SDL_bool done = SDL_FALSE; | |
325 | ||
320 | 326 | (void)udata; |
321 | 327 | |
322 | while (music_playing && music_active && len > 0) { | |
328 | while (music_playing && music_active && len > 0 && !done) { | |
323 | 329 | /* Handle fading */ |
324 | 330 | if (music_playing->fading != MIX_NO_FADING) { |
325 | 331 | if (music_playing->fade_step++ < music_playing->fade_steps) { |
326 | int volume = Mix_MasterVolume(-1); | |
332 | int volume; | |
327 | 333 | int fade_step = music_playing->fade_step; |
328 | 334 | int fade_steps = music_playing->fade_steps; |
329 | 335 | |
330 | 336 | if (music_playing->fading == MIX_FADING_OUT) { |
331 | volume = (volume * (music_volume * (fade_steps-fade_step))) / (fade_steps * MIX_MAX_VOLUME); | |
337 | volume = (music_volume * (fade_steps-fade_step)) / fade_steps; | |
332 | 338 | } else { /* Fading in */ |
333 | volume = (volume * (music_volume * fade_step)) / (fade_steps * MIX_MAX_VOLUME); | |
339 | volume = (music_volume * fade_step) / fade_steps; | |
334 | 340 | } |
335 | 341 | music_internal_volume(volume); |
336 | 342 | } else { |
350 | 356 | if (left != 0) { |
351 | 357 | /* Either an error or finished playing with data left */ |
352 | 358 | music_playing->playing = SDL_FALSE; |
359 | done = SDL_TRUE; | |
353 | 360 | } |
354 | 361 | if (left > 0) { |
355 | 362 | stream += (len - left); |
558 | 565 | /* Assume MOD format. |
559 | 566 | * |
560 | 567 | * Apparently there is no way to check if the file is really a MOD, |
561 | * or there are too many formats supported by MikMod/ModPlug, or | |
562 | * MikMod/ModPlug does this check by itself. */ | |
568 | * or there are too many formats supported by libmodplug or libxmp. | |
569 | * The mod library does this check by itself. */ | |
563 | 570 | return MUS_MOD; |
564 | 571 | } |
565 | 572 | |
731 | 738 | Mix_LockAudio(); |
732 | 739 | if (music == music_playing) { |
733 | 740 | /* Wait for any fade out to finish */ |
734 | while (music->fading == MIX_FADING_OUT) { | |
741 | while (music_active && music->fading == MIX_FADING_OUT) { | |
735 | 742 | Mix_UnlockAudio(); |
736 | 743 | SDL_Delay(100); |
737 | 744 | Mix_LockAudio(); |
29 | 29 | MIX_MUSIC_CMD, |
30 | 30 | MIX_MUSIC_WAVE, |
31 | 31 | MIX_MUSIC_MODPLUG, |
32 | MIX_MUSIC_MIKMOD, | |
33 | 32 | MIX_MUSIC_FLUIDSYNTH, |
34 | 33 | MIX_MUSIC_TIMIDITY, |
35 | 34 | MIX_MUSIC_NATIVEMIDI, |
36 | 35 | MIX_MUSIC_OGG, |
37 | 36 | MIX_MUSIC_DRMP3, |
38 | 37 | MIX_MUSIC_MPG123, |
39 | MIX_MUSIC_MAD, | |
40 | 38 | MIX_MUSIC_DRFLAC, |
41 | 39 | MIX_MUSIC_FLAC, |
42 | 40 | MIX_MUSIC_OPUS, |
8 | 8 | // |
9 | 9 | |
10 | 10 | VS_VERSION_INFO VERSIONINFO |
11 | FILEVERSION 2,5,1,0 | |
12 | PRODUCTVERSION 2,5,1,0 | |
11 | FILEVERSION 2,5,2,0 | |
12 | PRODUCTVERSION 2,5,2,0 | |
13 | 13 | FILEFLAGSMASK 0x3fL |
14 | 14 | FILEFLAGS 0x0L |
15 | 15 | FILEOS 0x40004L |
22 | 22 | BEGIN |
23 | 23 | VALUE "CompanyName", "\0" |
24 | 24 | VALUE "FileDescription", "SDL_mixer\0" |
25 | VALUE "FileVersion", "2, 5, 1, 0\0" | |
25 | VALUE "FileVersion", "2, 5, 2, 0\0" | |
26 | 26 | VALUE "InternalName", "SDL_mixer\0" |
27 | 27 | VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" |
28 | 28 | VALUE "OriginalFilename", "SDL_mixer.dll\0" |
29 | 29 | VALUE "ProductName", "Simple DirectMedia Layer\0" |
30 | VALUE "ProductVersion", "2, 5, 1, 0\0" | |
30 | VALUE "ProductVersion", "2, 5, 2, 0\0" | |
31 | 31 | END |
32 | 32 | END |
33 | 33 | BLOCK "VarFileInfo" |