Codebase list libsdl2-mixer / upstream/2.5.2+dfsg
New upstream version 2.5.2+dfsg Simon McVittie 1 year, 10 months ago
41 changed file(s) with 2109 addition(s) and 1702 deletion(s). Raw diff Collapse all Expand all
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
612 * 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
1615 * 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
2017 * Enabled module internal loops in modplug player
2118 * Respect original mp3 file offset
22 * Fixed a use-after-free issue in fluidsynth player
2319 * 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:
2823 Mix_GetMusicTitle()
2924 Mix_GetMusicTitleTag()
3025 Mix_GetMusicArtistTag()
3429 Mix_GetMusicLoopStartTime()
3530 Mix_GetMusicLoopEndTime()
3631 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
4134 * 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()
4336 * Improved mp3 tag detection/skipping
44 * Updated external libraries with multiple bug/security fixes
4537 * Extended support for WAV files
46 * Added looping support for Opus files
4738 * Allow rmid files be opened by native midi
4839 * Fixed possible crash in win32 native midi
4940 * 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
5242 * Added looping support for FLAC files
5343 * Improved OGG looping support
5444 * 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
5745
5846 2.0.4:
5947 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")
83
94 # See docs/release_checklist.md
105 set(MAJOR_VERSION 2)
116 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
7010 # For historical reasons this is 3.0.0 rather than the expected 1.0.0
7111 set(DYLIB_COMPATIBILITY_VERSION "3.0.0")
7212
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
85718 src/codecs/timidity/common.c
86719 src/codecs/timidity/instrum.c
87720 src/codecs/timidity/mix.c
94727 )
95728 endif()
96729
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"
124874 )
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()
1212 mandir = @mandir@
1313 auxdir = @ac_aux_dir@
1414 distpath = $(srcdir)/..
15 distdir = SDL2_mixer-@VERSION@
15 distdir = @PACKAGE_NAME@-@PACKAGE_VERSION@
1616 distfile = $(distdir).tar.gz
1717
1818 @SET_MAKE@
3939 PLAYMUS_OBJECTS = @PLAYMUS_OBJECTS@
4040
4141 SRC_DIST = \
42 LICENSE.txt \
43 README.txt \
44 CHANGES.txt \
4542 .gitmodules \
4643 Android.mk \
44 CHANGES.txt \
4745 CMakeLists.txt \
46 LICENSE.txt \
4847 Makefile.in \
4948 Makefile.os2 \
49 README.txt \
5050 SDL2_mixer.pc.in \
5151 SDL2_mixer.spec.in \
52 include/SDL_mixer.h \
52 SDL2_mixerConfig.cmake.in \
5353 VisualC \
5454 VisualC-WinRT \
5555 Xcode \
5656 acinclude \
5757 autogen.sh \
5858 build-scripts \
59 cmake \
5960 configure \
6061 configure.ac \
6162 external/download.sh \
62 src \
63 include/SDL_mixer.h \
64 mingw \
6365 playmus.c \
6466 playwave.c \
67 sdl2_mixer-config-version.cmake.in \
68 sdl2_mixer-config.cmake.in \
69 src \
6570 version.rc
6671
6772 GEN_DIST = SDL2_mixer.spec
105110 done
106111 $(SHELL) $(auxdir)/mkinstalldirs $(libdir)/pkgconfig
107112 $(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
108116 install-lib: $(objects)/$(TARGET)
109117 $(SHELL) $(auxdir)/mkinstalldirs $(libdir)
110118 $(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(TARGET) $(libdir)/$(TARGET)
122130 -rmdir $(includedir)/SDL2
123131 rm -f $(libdir)/pkgconfig/SDL2_mixer.pc
124132 -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
125137 uninstall-lib:
126138 $(LIBTOOL) --mode=uninstall rm -f $(libdir)/$(TARGET)
127139 uninstall-bin:
66 LIBNAME = SDL2mix
77 MAJOR_VERSION = 2
88 MINOR_VERSION = 5
9 MICRO_VERSION = 1
9 MICRO_VERSION = 2
1010 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
1111
1212 TITLENAME = $(LIBNAME) $(VERSION)
3030 USE_DRFLAC=no
3131 # opus music support
3232 USE_OPUS=yes
33 # mp3 music support (using libmad - Note: GPL license!)
34 USE_LIBMAD=no
3533 # mp3 music support (using mpg123)
3634 USE_MPG123=yes
3735 # mp3 music support (using dr_mp3)
4038 USE_TIMIDITY=yes
4139 # midi music support (using fluidsynth)
4240 USE_FLUIDSYNTH=no
43 # tracker music support (using libmikmod)
44 USE_MIKMOD=no
4541 # tracker music support (using libxmp)
4642 USE_XMP=yes
4743 # tracker music support (using libmodplug)
5753 SRCS+= load_aiff.c load_voc.c music_wav.c &
5854 music_ogg.c music_ogg_stb.c music_opus.c &
5955 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 &
6258 music_fluidsynth.c music_timidity.c
6359 # timidity sources:
6460 TIMISRCS = common.c instrum.c mix.c output.c playmidi.c readmidi.c resample.c tables.c timidity.c
127123 NEED_LIBOGG=yes
128124 !endif
129125
130 !ifeq USE_LIBMAD yes
131 CFLAGS+= -DMUSIC_MP3_MAD
132 LIBS+= mad.lib
133 !endif
134126 !ifeq USE_MPG123 yes
135127 CFLAGS+= -DMUSIC_MP3_MPG123
136128 LIBS+= mpg123.lib
142134 !ifeq USE_XMP yes
143135 CFLAGS+= -DMUSIC_MOD_XMP
144136 LIBS+= libxmp.lib
145 !endif
146 !ifeq USE_MIKMOD yes
147 CFLAGS+= -DMUSIC_MOD_MIKMOD
148 LIBS+= mikmod.lib
149137 !endif
150138 !ifeq USE_MODPLUG yes
151139 CFLAGS+= -DMUSIC_MOD_MODPLUG
2828 - 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.
2929 - For Android, you can edit the config at the top of Android.mk to enable them.
3030
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.
00 %define name SDL2_mixer
1 %define version 2.5.1
1 %define version
22 %define release 1
33
44 Summary: Simple DirectMedia Layer - Sample Mixer Library
1414 %description
1515 Due to popular demand, here is a simple multi-channel audio mixer.
1616 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.
1919
2020 %package devel
2121 Summary: Libraries, includes and more to develop SDL applications.
2525 %description devel
2626 Due to popular demand, here is a simple multi-channel audio mixer.
2727 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.
3030
3131 %prep
3232 %setup
1414 %description
1515 Due to popular demand, here is a simple multi-channel audio mixer.
1616 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.
1919
2020 %package devel
2121 Summary: Libraries, includes and more to develop SDL applications.
2525 %description devel
2626 Due to popular demand, here is a simple multi-channel audio mixer.
2727 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.
3030
3131 %prep
3232 %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 }
00 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])
212 AC_CONFIG_SRCDIR([src/mixer.c])
313 AC_CONFIG_AUX_DIR(build-scripts)
414
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)
1218
1319 BINARY_AGE=`expr $MINOR_VERSION \* 100 + $MICRO_VERSION`
1420 AS_CASE(["$MINOR_VERSION"],
4248 LT_REVISION=$INTERFACE_AGE
4349 LT_AGE=`expr $BINARY_AGE - $INTERFACE_AGE`
4450 LT_CURRENT=`expr $LT_MAJOR + $LT_AGE`
45
46 LT_EXTRA="" dnl for OS2 dll name
51 LT_EXTRA=""
52
4753 m4_pattern_allow([^LT_])
4854
4955 AC_SUBST(LT_RELEASE)
117123 CFLAGS="$CFLAGS $EXTRA_CFLAGS"
118124 LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS"
119125
120 dnl Check for compiler characteristics
121 AC_C_CONST
122
123126 dnl See whether we can use gcc style dependency tracking
124127 AC_ARG_ENABLE(dependency-tracking,
125128 [AS_HELP_STRING([--enable-dependency-tracking],
291294
292295 dnl Check command-line options
293296
297 SDL2MIXER_CMD=0
294298 AC_ARG_ENABLE([music-cmd],
295299 [AS_HELP_STRING([--enable-music-cmd], [support an external music player [default=yes]])],
296300 [], [enable_music_cmd=detect])
307311 fi
308312 if test "x$enable_music_cmd" != xno; then
309313 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_CMD"
310 fi
311 fi
312
314 SDL2MIXER_CMD=1
315 fi
316 fi
317
318 SDL2MIXER_WAVE=0
313319 AC_ARG_ENABLE([music-wave],
314320 [AS_HELP_STRING([--enable-music-wave], [enable streaming WAVE music [default=yes]])],
315321 [], [enable_music_wave=yes])
316322 if test x$enable_music_wave = xyes; then
317323 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_WAV"
324 SDL2MIXER_WAVE=1
318325 fi
319326
320327 AC_ARG_ENABLE([music-mod],
321328 [AS_HELP_STRING([--enable-music-mod], [enable MOD music [default=yes]])],
322329 [], [enable_music_mod=yes])
323330
331 SDL2MIXER_MOD_MODPLUG=0
324332 AC_ARG_ENABLE([music-mod-modplug],
325333 [AS_HELP_STRING([--enable-music-mod-modplug], [enable MOD music via modplug [default=yes]])],
326334 [], [enable_music_mod_modplug=yes])
365373 PC_LIBS="$PC_LIBS $MODPLUG_LIBS"
366374 fi
367375 fi
376 SDL2MIXER_MOD_MODPLUG=1
368377 else
369378 AC_MSG_WARN([*** Unable to find ModPlug library (http://modplug-xmms.sourceforge.net/)])
370379 fi
371380 fi
372381
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
431384 AC_ARG_ENABLE([music-mod-xmp],
432385 [AS_HELP_STRING([--enable-music-mod-xmp], [enable MOD music via libxmp [default=no]])],
433386 [], [enable_music_mod_xmp=no])
479432 PC_LIBS="$PC_LIBS $XMP_LIBS"
480433 fi
481434 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
482439 else
483440 AC_MSG_WARN([*** Unable to find xmp library (http://xmp.sourceforge.net/)])
484441 fi
485442 fi
486443
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
488445 AC_MSG_WARN([MOD support disabled])
489446 fi
490447
448 SDL2MIXER_MIDI_FLUIDSYNTH=0
449 SDL2MIXER_MIDI_NATIVE=0
450 SDL2MIXER_MIDI_TIMIDITY=0
491451 AC_ARG_ENABLE([music-midi],
492452 [AS_HELP_STRING([--enable-music-midi], [enable MIDI music [default=yes]])],
493453 [], [enable_music_midi=yes])
505465 if test x$timidity_cfg != xyes -a x$timidity_cfg != xno; then
506466 EXTRA_CFLAGS="$EXTRA_CFLAGS -DTIMIDITY_CFG=\\\"$timidity_cfg\\\""
507467 fi
468 SDL2MIXER_MIDI_TIMIDITY=1
508469 fi
509470 AC_ARG_ENABLE([music-midi-native],
510471 [AS_HELP_STRING([--enable-music-midi-native], [enable native MIDI music output [default=yes]])],
531492 if test x$use_music_midi_native = xyes; then
532493 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MID_NATIVE -I\$(srcdir)/src/codecs/native_midi"
533494 SOURCES="$SOURCES $srcdir/src/codecs/native_midi/*.c"
495 SDL2MIXER_MIDI_NATIVE=1
534496 elif test x$use_music_midi_native = xyes_cpp; then
535497 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MID_NATIVE -I\$(srcdir)/src/codecs/native_midi"
536498 SOURCES="$SOURCES $srcdir/src/codecs/native_midi/*.c"
537499 SOURCES_CXX="$SOURCES_CXX $srcdir/src/codecs/native_midi/*.cpp"
500 SDL2MIXER_MIDI_NATIVE=1
538501 fi
539502 fi
540503 AC_ARG_ENABLE([music-midi-fluidsynth],
583546 PC_LIBS="$PC_LIBS $FLUIDSYNTH_LIBS"
584547 fi
585548 fi
549 SDL2MIXER_MIDI_FLUIDSYNTH=1
586550 else
587551 AC_MSG_WARN([*** Unable to find FluidSynth library (http://www.fluidsynth.org/)])
588552 AC_MSG_WARN([FluidSynth support disabled])
600564 [AS_HELP_STRING([--enable-music-ogg], [enable Ogg Vorbis music [default=yes]])],
601565 [], [enable_music_ogg=yes])
602566
567 SDL2MIXER_VORBIS_STB=0
603568 AC_ARG_ENABLE(music-ogg-stb,
604569 [AS_HELP_STRING([--enable-music-ogg-stb], [enable OGG Vorbis music via stb_vorbis [default=yes]])],
605570 [], enable_music_ogg_stb=yes)
606571 if test x$enable_music_ogg = xyes -a x$enable_music_ogg_stb = xyes; then
607572 have_stb_vorbis=yes
608573 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
611578 AC_ARG_ENABLE(music-ogg-vorbis,
612579 [AS_HELP_STRING([--enable-music-ogg-vorbis], [enable OGG Vorbis music via libvorbis [default=no]])],
613580 [], enable_music_ogg_vorbis=no)
654621 PC_LIBS="$PC_LIBS $VORBIS_LIBS"
655622 fi
656623 fi
624 SDL2MIXER_VORBIS_VORBISFILE=1
657625 else
658626 AC_MSG_WARN([*** Unable to find Ogg Vorbis library (http://www.xiph.org/)])
659627 fi
660628 fi
661629
630 SDL2MIXER_VORBIS_TREMOR=0
662631 AC_ARG_ENABLE(music-ogg-tremor,
663632 [AS_HELP_STRING([--enable-music-ogg-tremor], [enable OGG Vorbis music via Tremor [default=no]])],
664633 [], enable_music_ogg_tremor=no)
708677 PC_LIBS="$PC_LIBS $TREMOR_LIBS"
709678 fi
710679 fi
680 SDL2MIXER_VORBIS_TREMOR=1
711681 else
712682 AC_MSG_WARN([*** Unable to find Ogg Vorbis Tremor library (http://www.xiph.org/)])
713683 fi
718688 AC_MSG_WARN([Ogg Vorbis support disabled])
719689 fi
720690
691 SDL2MIXER_FLAC_DRFLAC=0
721692 AC_ARG_ENABLE([music-flac],
722693 [AS_HELP_STRING([--enable-music-flac], [enable FLAC music [default=yes]])],
723694 [], [enable_music_flac=yes])
728699 if test x$enable_music_flac = xyes -a x$enable_music_flac_drflac = xyes; then
729700 have_drflac=yes
730701 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_FLAC_DRFLAC"
731 fi
732
702 SDL2MIXER_FLAC_DRFLAC=1
703 fi
704
705 SDL2MIXER_FLAC_LIBFLAC=0
733706 AC_ARG_ENABLE(music-flac-libflac,
734707 [AS_HELP_STRING([--enable-music-flac-libflac], [enable FLAC music via libFLAC [default=no]])],
735708 [], [enable_music_flac_libflac=no])
791764 PC_LIBS="$PC_LIBS $FLAC_LIBS"
792765 fi
793766 fi
767 SDL2MIXER_FLAC_LIBFLAC=1
794768 else
795769 AC_MSG_WARN([*** Unable to find FLAC library (https://xiph.org/flac/)])
796770 fi
805779 [AS_HELP_STRING([--enable-music-mp3], [enable MP3 music [default=yes]])],
806780 [], enable_music_mp3=yes)
807781
782 SDL2MIXER_MP3_DRMP3=0
808783 AC_ARG_ENABLE(music-mp3-drmp3,
809784 [AS_HELP_STRING([--enable-music-mp3-drmp3], [enable MP3 music via dr_mp3 [default=yes]])],
810785 [], [enable_music_mp3_drmp3=yes])
811786 if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_drmp3 = xyes; then
812787 have_drmp3=yes
813788 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_DRMP3"
814 fi
815
789 SDL2MIXER_MP3_DRMP3=1
790 fi
791
792 SDL2MIXER_MP3_MPG123=0
816793 AC_ARG_ENABLE(music-mp3-mpg123,
817794 [AS_HELP_STRING([--enable-music-mp3-mpg123], [enable MP3 music via mpg123 [default=no]])],
818795 [], [enable_music_mp3_mpg123=no])
853830 PC_LIBS="$PC_LIBS $MPG123_LIBS"
854831 fi
855832 fi
833 SDL2MIXER_MP3_MPG123=1
856834 else
857835 AC_MSG_WARN([*** Unable to find mpg123 library (https://www.mpg123.de)])
858836 fi
859837 fi
860838
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
889840 AC_MSG_WARN([MP3 support disabled])
890841 fi
891842
843 SDL2MIXER_OPUS=0
892844 AC_ARG_ENABLE([music-opus],
893845 [AS_HELP_STRING([--enable-music-opus], [enable Opus music [default=yes]])],
894846 [], [enable_music_opus=yes])
935887 PC_LIBS="$PC_LIBS $OPUSFILE_LIBS"
936888 fi
937889 fi
890 SDL2MIXER_OPUS=1
938891 else
939892 AC_MSG_WARN([*** Unable to find opusfile library (http://opus-codec.org/)])
940893 AC_MSG_WARN([Opus support disabled])
988941 $(objects)/\2.lo: \1/\2.c \$(objects)/.created\\
989942 \$(LIBTOOL) --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) '"$DEPENDENCY_TRACKING_OPTIONS"' -c \$< -o \$@,g'`
990943 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])
991950
992951 dnl Expand the sources and objects needed to build the library
993952 AC_SUBST(ac_aux_dir)
1006965 AC_SUBST(PC_REQUIRES)
1007966 AC_SUBST(PC_LIBS)
1008967
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
1009985 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
1011991 ])
1012992 AC_CONFIG_COMMANDS([default],
1013993 [cat >>Makefile <<__EOF__
3737 */
3838 #define SDL_MIXER_MAJOR_VERSION 2
3939 #define SDL_MIXER_MINOR_VERSION 5
40 #define SDL_MIXER_PATCHLEVEL 1
40 #define SDL_MIXER_PATCHLEVEL 2
4141
4242 /* This macro can be used to fill a version structure with the compile-time
4343 * version of the SDL_mixer library.
148148 MUS_OPUS
149149 } Mix_MusicType;
150150
151 /* The internal format for a music chunk interpreted via mikmod */
151 /* The internal format for a music chunk interpreted via codecs */
152152 typedef struct _Mix_Music Mix_Music;
153153
154154 /* Open the mixer with a certain audio format */
384384 */
385385
386386
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.
389392 *
390393 * Technically, this is just individual volume control for a sample with
391394 * two (stereo) channels, so it can be used for more than just panning.
392395 * If you want real panning, call it like this:
393396 *
394 * Mix_SetPanning(channel, left, 255 - left);
397 * ```c
398 * Mix_SetPanning(channel, left, 255 - left);
399 * ```
395400 *
396401 * ...which isn't so hard.
397402 *
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
399404 * the panning will be done to the final mixed stream before passing it on
400405 * to the audio device.
401406 *
402407 * This uses the Mix_RegisterEffect() API internally, and returns without
403408 * 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
405410 * effect to be unregistered, since that is the data's normal state.
406411 *
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
411426 */
412427 extern DECLSPEC int SDLCALL Mix_SetPanning(int channel, Uint8 left, Uint8 right);
413428
589604 /* Get the current volume value in the range of 0-128 of a music stream */
590605 extern DECLSPEC int SDLCALL Mix_GetMusicVolume(Mix_Music *music);
591606
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.
594609 If the specified volume is -1, just return the current master volume.
595610 */
596611 extern DECLSPEC int SDLCALL Mix_MasterVolume(int volume);
635650 */
636651 extern DECLSPEC int SDLCALL Mix_ModMusicJumpToOrder(int order);
637652
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.
640655 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.
643658 */
644659 extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position);
645660
680695 /* Stop music and set external music playback command */
681696 extern DECLSPEC int SDLCALL Mix_SetMusicCMD(const char *command);
682697
683 /* Synchro value is set by MikMod from modules while playing */
698 /* Synchro value is set from modules while playing */
684699 extern DECLSPEC int SDLCALL Mix_SetSynchroValue(int value);
685700 extern DECLSPEC int SDLCALL Mix_GetSynchroValue(void);
686701
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)
383383 if (!voc_check_header(src))
384384 goto done;
385385
386 SDL_memset(&v, 0, sizeof (vs_t));
386387 v.rate = VOC_BAD_RATE;
387388 v.rest = 0;
388389 v.has_extended = 0;
398399 goto done;
399400 }
400401
402 if (v.size == 0) {
403 SDL_SetError("VOC data had invalid word size!");
404 goto done;
405 }
406
401407 spec->format = ((v.size == ST_SIZE_WORD) ? AUDIO_S16 : AUDIO_U8);
402408 if (spec->channels == 0)
403409 spec->channels = v.channels;
404410
405411 *audio_len = v.rest;
406 *audio_buf = SDL_malloc(v.rest);
412 *audio_buf = (v.rest == 0) ? NULL : SDL_malloc(v.rest);
407413 if (*audio_buf == NULL)
408414 goto done;
409415
159159 music->play_count = play_count;
160160 #ifdef HAVE_FORK
161161 music->pid = fork();
162 #elif defined(HAVE_VFORK)
163 music->pid = vfork();
162164 #else
163 music->pid = vfork();
165 music->pid = -1;
164166 #endif
165167 switch(music->pid) {
166168 /* Failed fork() system call */
+0
-694
src/codecs/music_mad.c less more
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
-28
src/codecs/music_mad.h less more
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
-522
src/codecs/music_mikmod.c less more
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
-28
src/codecs/music_mikmod.h less more
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: */
359359 {
360360 MPG123_Music *music = (MPG123_Music *)context;
361361 int filled, result;
362 size_t amount;
362 size_t amount = 0;
363363 long rate;
364364 int channels, encoding, format;
365365
411411 break;
412412
413413 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 }
414420 if (music->play_count == 1) {
415421 music->play_count = 0;
416422 SDL_AudioStreamFlush(music->stream);
4040 Uint16 ppqn;
4141 int Size;
4242 int NewPos;
43 SDL_mutex *mutex;
4344 };
4445
4546 static UINT MidiDevice=MIDI_MAPPER;
163164 void CALLBACK MidiProc( HMIDIIN hMidi, UINT uMsg, DWORD_PTR dwInstance,
164165 DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
165166 {
167 NativeMidiSong *song = (NativeMidiSong *)dwInstance;
166168 (void)hMidi;
167 (void)dwInstance;
168169 (void)dwParam2;
169170
171 if (!song) {
172 return;
173 }
174
175 SDL_LockMutex(song->mutex);
170176 switch( uMsg )
171177 {
172178 case MOM_DONE:
173 if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)&currentsong->MidiStreamHdr[currentsong->CurrentHdr]))
174 BlockOut(currentsong);
179 if (song->MusicPlaying && song->MusicLoaded && (dwParam1 == (DWORD_PTR)&song->MidiStreamHdr[song->CurrentHdr]))
180 BlockOut(song);
175181 break;
176182 case MOM_POSITIONCB:
177 if ((currentsong->MusicLoaded) && (dwParam1 == (DWORD_PTR)&currentsong->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);
183189 } else {
184 currentsong->MusicPlaying=0;
190 song->MusicPlaying=0;
185191 }
186192 }
187193 break;
194 case MOM_CLOSE:
195 song->MusicPlaying=0;
196 break;
188197 default:
189198 break;
190199 }
200 SDL_UnlockMutex(song->mutex);
191201 }
192202
193203 int native_midi_detect(void)
225235
226236 FreeMIDIEventList(evntlist);
227237
238 newsong->mutex = SDL_CreateMutex();
239
228240 if (freesrc) {
229241 SDL_RWclose(src);
230242 }
233245
234246 void native_midi_freesong(NativeMidiSong *song)
235247 {
236 if (hMidiStream)
237 {
238 midiStreamStop(hMidiStream);
239 midiStreamClose(hMidiStream);
240 }
241248 if (song)
242249 {
243250 if (song->NewEvents)
244251 SDL_free(song->NewEvents);
252 SDL_DestroyMutex(song->mutex);
245253 SDL_free(song);
246254 }
247255 }
254262 native_midi_stop();
255263 if (!hMidiStream)
256264 {
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);
258266 if (merr!=MMSYSERR_NOERROR)
259267 {
260268 hMidiStream = NULL; /* should I do midiStreamClose(hMidiStream) before? */
289297
290298 void native_midi_stop(void)
291299 {
300 NativeMidiSong *song = currentsong;
301
292302 if (!hMidiStream)
293303 return;
304
305 SDL_LockMutex(song->mutex);
294306 midiStreamStop(hMidiStream);
295307 midiStreamClose(hMidiStream);
296308 currentsong=NULL;
297309 hMidiStream = NULL;
310 SDL_UnlockMutex(song->mutex);
298311 }
299312
300313 int native_midi_active(void)
325325 mix_channels(void *udata, Uint8 *stream, int len)
326326 {
327327 Uint8 *mix_input;
328 int i, mixable, volume, master_vol;
328 int i, mixable, master_vol;
329329 Uint32 sdl_ticks;
330330
331331 (void)udata;
336336 /* Mix the music (must be done before the channels are added) */
337337 mix_music(music_data, stream, len);
338338
339 volume = Mix_MasterVolume(-1);
340 master_vol = volume;
339 master_vol = SDL_AtomicGet(&master_volume);
341340
342341 /* Mix any playing channels... */
343342 sdl_ticks = SDL_GetTicks();
371370 }
372371 }
373372 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);
374374 int index = 0;
375375 int remaining = len;
376376 while (mix_channel[i].playing > 0 && index < len) {
377377 remaining = len - index;
378 volume = (master_vol * (mix_channel[i].volume * mix_channel[i].chunk->volume)) / (MIX_MAX_VOLUME * MIX_MAX_VOLUME);
379378 mixable = mix_channel[i].playing;
380379 if (mixable > remaining) {
381380 mixable = remaining;
382381 }
383382
384383 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);
386385 if (mix_input != mix_channel[i].samples)
387386 SDL_free(mix_input);
388387
393392 /* rcg06072001 Alert app if channel is done playing. */
394393 if (!mix_channel[i].playing && !mix_channel[i].looping) {
395394 _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);
396398 }
397399 }
398400
632634
633635 /* These music interfaces are not safe to use while music is playing */
634636 if (interface->api == MIX_MUSIC_CMD ||
635 interface->api == MIX_MUSIC_MIKMOD ||
636637 interface->api == MIX_MUSIC_NATIVEMIDI) {
637638 continue;
638639 }
2727
2828 #include "music_cmd.h"
2929 #include "music_wav.h"
30 #include "music_mikmod.h"
3130 #include "music_modplug.h"
3231 #include "music_xmp.h"
3332 #include "music_nativemidi.h"
3736 #include "music_opus.h"
3837 #include "music_drmp3.h"
3938 #include "music_mpg123.h"
40 #include "music_mad.h"
4139 #include "music_drflac.h"
4240 #include "music_flac.h"
4341 #include "native_midi/native_midi.h"
9290
9391 void meta_tags_clear(Mix_MusicMetaTags *tags)
9492 {
95 size_t i = 0;
93 size_t i;
94
9695 for (i = 0; i < MIX_META_LAST; i++) {
9796 if (tags->tags[i]) {
9897 SDL_free(tags->tags[i]);
182181 #ifdef MUSIC_MP3_MPG123
183182 &Mix_MusicInterface_MPG123,
184183 #endif
185 #ifdef MUSIC_MP3_MAD
186 &Mix_MusicInterface_MAD,
187 #endif
188184 #ifdef MUSIC_MOD_XMP
189185 &Mix_MusicInterface_XMP,
190186 #endif
191187 #ifdef MUSIC_MOD_MODPLUG
192188 &Mix_MusicInterface_MODPLUG,
193 #endif
194 #ifdef MUSIC_MOD_MIKMOD
195 &Mix_MusicInterface_MIKMOD,
196189 #endif
197190 #ifdef MUSIC_MID_FLUIDSYNTH
198191 &Mix_MusicInterface_FLUIDSYNTH,
287280 Uint8 *snd = (Uint8 *)data;
288281 Uint8 *dst;
289282 int len = bytes;
283 int zero_cycles = 0;
284 const int MAX_ZERO_CYCLES = 10; /* just try to catch infinite loops */
290285 SDL_bool done = SDL_FALSE;
291286
292287 if (volume == MIX_MAX_VOLUME) {
299294 if (consumed < 0) {
300295 break;
301296 }
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;
302306
303307 if (volume == MIX_MAX_VOLUME) {
304308 dst += consumed;
317321 /* Mixing function */
318322 void SDLCALL music_mixer(void *udata, Uint8 *stream, int len)
319323 {
324 SDL_bool done = SDL_FALSE;
325
320326 (void)udata;
321327
322 while (music_playing && music_active && len > 0) {
328 while (music_playing && music_active && len > 0 && !done) {
323329 /* Handle fading */
324330 if (music_playing->fading != MIX_NO_FADING) {
325331 if (music_playing->fade_step++ < music_playing->fade_steps) {
326 int volume = Mix_MasterVolume(-1);
332 int volume;
327333 int fade_step = music_playing->fade_step;
328334 int fade_steps = music_playing->fade_steps;
329335
330336 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;
332338 } else { /* Fading in */
333 volume = (volume * (music_volume * fade_step)) / (fade_steps * MIX_MAX_VOLUME);
339 volume = (music_volume * fade_step) / fade_steps;
334340 }
335341 music_internal_volume(volume);
336342 } else {
350356 if (left != 0) {
351357 /* Either an error or finished playing with data left */
352358 music_playing->playing = SDL_FALSE;
359 done = SDL_TRUE;
353360 }
354361 if (left > 0) {
355362 stream += (len - left);
558565 /* Assume MOD format.
559566 *
560567 * 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. */
563570 return MUS_MOD;
564571 }
565572
731738 Mix_LockAudio();
732739 if (music == music_playing) {
733740 /* Wait for any fade out to finish */
734 while (music->fading == MIX_FADING_OUT) {
741 while (music_active && music->fading == MIX_FADING_OUT) {
735742 Mix_UnlockAudio();
736743 SDL_Delay(100);
737744 Mix_LockAudio();
2929 MIX_MUSIC_CMD,
3030 MIX_MUSIC_WAVE,
3131 MIX_MUSIC_MODPLUG,
32 MIX_MUSIC_MIKMOD,
3332 MIX_MUSIC_FLUIDSYNTH,
3433 MIX_MUSIC_TIMIDITY,
3534 MIX_MUSIC_NATIVEMIDI,
3635 MIX_MUSIC_OGG,
3736 MIX_MUSIC_DRMP3,
3837 MIX_MUSIC_MPG123,
39 MIX_MUSIC_MAD,
4038 MIX_MUSIC_DRFLAC,
4139 MIX_MUSIC_FLAC,
4240 MIX_MUSIC_OPUS,
88 //
99
1010 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
1313 FILEFLAGSMASK 0x3fL
1414 FILEFLAGS 0x0L
1515 FILEOS 0x40004L
2222 BEGIN
2323 VALUE "CompanyName", "\0"
2424 VALUE "FileDescription", "SDL_mixer\0"
25 VALUE "FileVersion", "2, 5, 1, 0\0"
25 VALUE "FileVersion", "2, 5, 2, 0\0"
2626 VALUE "InternalName", "SDL_mixer\0"
2727 VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0"
2828 VALUE "OriginalFilename", "SDL_mixer.dll\0"
2929 VALUE "ProductName", "Simple DirectMedia Layer\0"
30 VALUE "ProductVersion", "2, 5, 1, 0\0"
30 VALUE "ProductVersion", "2, 5, 2, 0\0"
3131 END
3232 END
3333 BLOCK "VarFileInfo"