Codebase list libsdl2-mixer / upstream/2.5.0_git20220523+g8805ff3+dfsg
New upstream version 2.5.0~git20220523+g8805ff3+dfsg Simon McVittie 1 year, 11 months ago
36 changed file(s) with 25979 addition(s) and 559 deletion(s). Raw diff Collapse all Expand all
0 [submodule "external/flac"]
1 path = external/flac
2 url = https://github.com/libsdl-org/flac.git
3 branch = 1.3.4-SDL
4 [submodule "external/ogg"]
5 path = external/ogg
6 url = https://github.com/libsdl-org/ogg.git
7 branch = v1.3.5-SDL
8 [submodule "external/vorbis"]
9 path = external/vorbis
10 url = https://github.com/libsdl-org/vorbis.git
11 branch = v1.3.7-SDL
12 [submodule "external/opus"]
13 path = external/opus
14 url = https://github.com/libsdl-org/opus.git
15 branch = v1.3.1-SDL
16 [submodule "external/opusfile"]
17 path = external/opusfile
18 url = https://github.com/libsdl-org/opusfile.git
19 branch = v0.12-SDL
20 [submodule "external/tremor"]
21 path = external/tremor
22 url = https://github.com/libsdl-org/tremor.git
23 branch = v1.2.1-SDL
24 [submodule "external/libmodplug"]
25 path = external/libmodplug
26 url = https://github.com/libsdl-org/libmodplug.git
27 branch = v0.8.9.0-SDL
28 [submodule "external/mpg123"]
29 path = external/mpg123
30 url = https://github.com/libsdl-org/mpg123.git
31 branch = v1.29.3-SDL
33 # Enable this if you want to support loading WAV music
44 SUPPORT_WAV ?= true
55
6 # Enable this if you want to support loading FLAC music via dr_flac
7 SUPPORT_FLAC_DRFLAC ?= true
8
69 # Enable this if you want to support loading FLAC music with libFLAC
7 SUPPORT_FLAC ?= true
10 SUPPORT_FLAC_LIBFLAC ?= false
811 FLAC_LIBRARY_PATH := external/flac
912
13 # Enable this if you want to support loading OGG Vorbis music via stb_vorbis
14 SUPPORT_OGG_STB ?= true
15
1016 # Enable this if you want to support loading OGG Vorbis music via Tremor
11 SUPPORT_OGG ?= true
17 SUPPORT_OGG ?= false
1218 OGG_LIBRARY_PATH := external/ogg
1319 VORBIS_LIBRARY_PATH := external/tremor
1420
21 # Enable this if you want to support loading MP3 music via dr_mp3
22 SUPPORT_MP3_DRMP3 ?= true
23
1524 # Enable this if you want to support loading MP3 music via MPG123
16 SUPPORT_MP3_MPG123 ?= true
25 SUPPORT_MP3_MPG123 ?= false
1726 MPG123_LIBRARY_PATH := external/mpg123
1827
1928 # Enable this if you want to support loading MOD music via modplug
20 SUPPORT_MOD_MODPLUG ?= true
29 SUPPORT_MOD_MODPLUG ?= false
2130 MODPLUG_LIBRARY_PATH := external/libmodplug
2231
2332 # Enable this if you want to support TiMidity
24 SUPPORT_MID_TIMIDITY ?= true
33 SUPPORT_MID_TIMIDITY ?= false
2534 TIMIDITY_LIBRARY_PATH := src/codecs/timidity
2635
2736
2837 # Build the library
29 ifeq ($(SUPPORT_FLAC),true)
38 ifeq ($(SUPPORT_FLAC_LIBFLAC),true)
3039 include $(SDL_MIXER_LOCAL_PATH)/$(FLAC_LIBRARY_PATH)/Android.mk
3140 endif
3241
8089 LOCAL_CFLAGS += -DMUSIC_WAV
8190 endif
8291
83 ifeq ($(SUPPORT_FLAC),true)
92 ifeq ($(SUPPORT_FLAC_DRFLAC),true)
93 LOCAL_CFLAGS += -DMUSIC_FLAC_DRFLAC
94 endif
95
96 ifeq ($(SUPPORT_FLAC_LIBFLAC),true)
8497 LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(FLAC_LIBRARY_PATH)/include
85 LOCAL_CFLAGS += -DMUSIC_FLAC
98 LOCAL_CFLAGS += -DMUSIC_FLAC_LIBFLAC
8699 LOCAL_STATIC_LIBRARIES += libFLAC
100 endif
101
102 ifeq ($(SUPPORT_OGG_STB),true)
103 LOCAL_CFLAGS += -DMUSIC_OGG -DOGG_USE_STB
87104 endif
88105
89106 ifeq ($(SUPPORT_OGG),true)
91108 LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(VORBIS_LIBRARY_PATH)
92109 LOCAL_CFLAGS += -DMUSIC_OGG -DOGG_USE_TREMOR -DOGG_HEADER="<ivorbisfile.h>"
93110 LOCAL_STATIC_LIBRARIES += ogg vorbisidec
111 endif
112
113 ifeq ($(SUPPORT_MP3_DRMP3),true)
114 LOCAL_CFLAGS += -DMUSIC_MP3_DRMP3
94115 endif
95116
96117 # This needs to be a shared library to comply with the LGPL license
00 2.0.5:
1 Vitaly Novichkov - Fri May 20 22:19:38 PDT 2022
2 * Added support for playing Ogg files using stb_vorbis
3 Sam Lantinga - Fri May 20 21:59:13 PDT 2022
4 * Added support for playing FLAC files using dr_flac
5 Sam Lantinga - Fri May 20 20:50:29 PDT 2022
6 * Added support for playing MP3 files using dr_mp3
7 Mykola Rubets - Tue May 17 12:59:35 2022
8 * Implemented a master volume feature, Mix_MasterVolume added to
9 public api.
10 Ozkan Sezer, Simon McVittie, Cameron Cawley - Wed May 11 17:03:56 2022
11 * Multiple fixes and updates to autotools build system.
12 Nate Houghton - Fri Dec 31 22:33:21 2021
13 * Update Mix_Init() return value to match documentation, including
14 MIXER_INIT_* flags for already-initialized modules
15 pionere - Thu Dec 23 12:01:03 2021
16 * Fixed leak in Mix_FreeChunk + race condition in Mix_HaltChannel
17 Vitaly Novichkov - Wed Dec 15 23:22:36 2021
18 * Fixed possible crash in Mix_LoadMusic_RW()
19 pionere - Tue Dec 14 10:01:02 2021
20 * Do not report a non-playing channel as paused
21 pionere - Sun Dec 12 11:47:39 2021
22 * Always check 'looping' field to tell if a channel is playing
23 Dasperal - Mon Nov 22 23:22:30 2021
24 * Added support of quoted strings in timidity.cfg
25 Austin Hurst - Sun Jul 4 20:20:00 2021
26 * Added missing Mix_HasMusicDecoder().
27 Ozkan Sezer - Sat Apr 3 21:56:50 2021
28 * Memory leak fixes and F32 format support to fluidsynth player.
29 Ozkan Sezer - Fri Mar 26 21:56:50 2021
30 * Fixes to mp3 (libmad) and opus playback on big-endian systems.
31 Vitaly Novichkov - Thu Feb 18 10:00:37 2021
32 * Added support for Tell and Duration to MP3 libmad backend.
133 Ozkan Sezer - Sun Feb 07 03:10:10 2021
2 * fixed distorted MIDI playback with FluidSynth if the sample rate
3 is out of library's limits
34 * Fixed distorted MIDI playback with FluidSynth if sample rate is
35 out of library's limits
436 Ozkan Sezer - Fri Feb 05 14:33:50 2021
537 * Added Mix_ModMusicJumpToOrder for mod music formats
638 Ozkan Sezer - Sun Jan 31 10:03:10 2021
7 * Added libxmp support for mod music playback, partially based on
8 work by Vitaly Novichkov
39 * Added libxmp support for mod music playback.
940 Ozkan Sezer - Sun Jan 31 00:33:00 2021
1041 * Fixed mikmod player reader issue with umx files
1142 * Enabled module internal loops in modplug player
1243 Ozkan Sezer - Thu Jan 28 17:02:25 2021
1344 * Respect original mp3 file offset
1445 Sam Lantinga - Wed Jan 20 10:17:10 2021
15 * Fixed a used-after-free issue in fluidsynth player
46 * Fixed a use-after-free issue in fluidsynth player
1647 michaeljosephmaltese - Tue Nov 24 22:07:14 2020
1748 * Support setting soundfont via SDL_SOUNDFONTS in OSX native midi
1849 David Gow - Fri Oct 23 23:01:00 2020
1950 * Fixed mp3 file detection.
2051 Ozkan Sezer - Sat Jun 27 00:50:04 2020
2152 * Fixed divide by zero crash in voc_get_block().
53 Sergio Padrino - Mon Jun 15 10:08:14 2020
54 * Fixes to ogg playback on big-endian devices.
55 Vitaly Novichkov - Mon Dec 23 14:01:02 2019
56 * Added MetaTags api procedures Mix_GetMusicTitle,Mix_GetMusicTitleTag,
57 Mix_GetMusicArtistTag,Mix_GetMusicAlbumTag, Mix_GetMusicCopyrightTag.
58 Vitaly Novichkov - Mon Dec 23 14:01:02 2019
59 * Add loop points information calls Mix_GetMusicLoopStartTime,
60 Mix_GetMusicLoopEndTime and Mix_GetMusicLoopLengthTime.
61 Vitaly Novichkov - Mon Dec 23 14:01:02 2019
62 * Add Mix_GetMusicVolume and Mix_GetMusicPosition to public api.
63 Vitaly Novichkov - Sun Dec 22 17:20:50 2019
64 * Avoid playing junk chunk after seek in MP3 with libmad backend.
65 Ozkan Sezer - Sun Dec 22 15:55:50 2019
66 * Fixes to MP3 Frankenstein streams playback (thanks to Vitaly
67 Novichkov.)
2268 Matthias Gatto - Tue Dec 17 21:55:00 2019
2369 * Add Mix_MusicDuration() to return music duration in seconds.
2470 Vitaly Novichkov - Tue Dec 17 15:50:02 2019
4288 * Prevent clipping due to volume settings in modplug music
4389 Michael Day - Mon Nov 18 07:43:52 2019
4490 * Fixed FLAC initial stutter
91 Vitaly Novichkov - Tue Nov 19 12:36:40 2019
92 * Reorganized source tree layout
4593 Michael Day - Sat Nov 16 22:11:29 PST 2019
4694 * Added looping support for FLAC files
4795 Michael Day - Fri Nov 01 10:38:35 2019
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.
8
9 # See docs/release_checklist.md
10 set(MAJOR_VERSION 2)
11 set(MINOR_VERSION 5)
12 set(MICRO_VERSION 0)
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")
70 # For historical reasons this is 3.0.0 rather than the expected 1.0.0
71 set(DYLIB_COMPATIBILITY_VERSION "3.0.0")
72
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
85 src/codecs/timidity/common.c
86 src/codecs/timidity/instrum.c
87 src/codecs/timidity/mix.c
88 src/codecs/timidity/output.c
89 src/codecs/timidity/playmidi.c
90 src/codecs/timidity/readmidi.c
91 src/codecs/timidity/resample.c
92 src/codecs/timidity/tables.c
93 src/codecs/timidity/timidity.c
94 )
95 endif()
96
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}
124 )
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()
3838 PLAYWAVE_OBJECTS = @PLAYWAVE_OBJECTS@
3939 PLAYMUS_OBJECTS = @PLAYMUS_OBJECTS@
4040
41 SRC_DIST = LICENSE.txt README.txt CHANGES.txt Android.mk Makefile.in Makefile.os2 SDL2_mixer.pc.in SDL2_mixer.spec.in include/SDL_mixer.h VisualC VisualC-WinRT Xcode acinclude autogen.sh build-scripts configure configure.ac external gcc-fat.sh src/utils.c src/utils.h src/effect_position.c src/effect_stereoreverse.c src/effects_internal.c src/effects_internal.h src/codecs/load_aiff.c src/codecs/load_aiff.h src/codecs/load_voc.c src/codecs/load_voc.h src/codecs/mp3utils.c src/codecs/mp3utils.h src/mixer.c src/mixer.h src/music.c src/music.h src/codecs/music_cmd.c src/codecs/music_cmd.h src/codecs/music_flac.c src/codecs/music_flac.h src/codecs/music_fluidsynth.c src/codecs/music_fluidsynth.h src/codecs/music_mad.c src/codecs/music_mad.h src/codecs/music_mikmod.c src/codecs/music_mikmod.h src/codecs/music_modplug.c src/codecs/music_modplug.h src/codecs/music_xmp.c src/codecs/music_xmp.h src/codecs/music_mpg123.c src/codecs/music_mpg123.h src/codecs/music_nativemidi.c src/codecs/music_nativemidi.h src/codecs/music_ogg.c src/codecs/music_ogg.h src/codecs/music_opus.c src/codecs/music_opus.h src/codecs/music_timidity.c src/codecs/music_timidity.h src/codecs/music_wav.c src/codecs/music_wav.h src/codecs/native_midi playmus.c playwave.c src/codecs/timidity version.rc
41 SRC_DIST = \
42 LICENSE.txt \
43 README.txt \
44 CHANGES.txt \
45 .gitmodules \
46 Android.mk \
47 CMakeLists.txt \
48 Makefile.in \
49 Makefile.os2 \
50 SDL2_mixer.pc.in \
51 SDL2_mixer.spec.in \
52 include/SDL_mixer.h \
53 VisualC \
54 VisualC-WinRT \
55 Xcode \
56 acinclude \
57 autogen.sh \
58 build-scripts \
59 configure \
60 configure.ac \
61 external/download.sh \
62 src \
63 playmus.c \
64 playwave.c \
65 version.rc
66
4267 GEN_DIST = SDL2_mixer.spec
4368
4469 LT_AGE = @LT_AGE@
2222 USE_OGG=yes
2323 # use integer-only Tremor (libvorbisidec) instead of libvorbis?
2424 USE_TREMOR=no
25 # flac music support
25 # use stb_vorbis instead of libvorbis?
26 USE_STBVORBIS=no
27 # flac music support (using libflac)
2628 USE_FLAC=yes
29 # flac music support (using dr_flac)
30 USE_DRFLAC=no
2731 # opus music support
2832 USE_OPUS=yes
2933 # mp3 music support (using libmad - Note: GPL license!)
3034 USE_LIBMAD=no
3135 # mp3 music support (using mpg123)
3236 USE_MPG123=yes
37 # mp3 music support (using dr_mp3)
38 USE_DRMP3=no
3339 # midi music support (using timidity)
3440 USE_TIMIDITY=yes
3541 # midi music support (using fluidsynth)
4955 SRCS = utils.c effect_position.c effects_internal.c effect_stereoreverse.c mixer.c music.c
5056 # codec sources:
5157 SRCS+= load_aiff.c load_voc.c music_wav.c &
52 mp3utils.c music_mad.c music_mpg123.c &
53 music_ogg.c music_opus.c music_flac.c &
58 music_ogg.c music_ogg_stb.c music_opus.c &
59 music_flac.c music_drflac.c mp3utils.c &
60 music_mad.c music_mpg123.c music_drmp3.c &
5461 music_xmp.c music_mikmod.c music_modplug.c &
5562 music_fluidsynth.c music_timidity.c
5663 # timidity sources:
95102 !endif
96103 !ifeq USE_OGG yes
97104 CFLAGS+= -DMUSIC_OGG
105 !ifeq USE_STBVORBIS yes
106 CFLAGS+= -DOGG_USE_STB
107 !else
98108 !ifeq USE_TREMOR yes
99109 CFLAGS+= -DOGG_USE_TREMOR
100110 !endif
101111 LIBS+= $(VORBIS_LIBS)
102 LIBS+= ogg.lib
112 NEED_LIBOGG=yes
113 !endif
103114 !endif
104115
105116 !ifeq USE_FLAC yes
106 CFLAGS+= -DMUSIC_FLAC
117 CFLAGS+= -DMUSIC_FLAC_LIBFLAC
107118 LIBS+= FLAC.lib
119 !endif
120 !ifeq USE_DRFLAC yes
121 CFLAGS+= -DMUSIC_FLAC_DRFLAC
108122 !endif
109123
110124 !ifeq USE_OPUS yes
111125 CFLAGS+= -DMUSIC_OPUS
112126 LIBS+= opusfile.lib opus.lib
113 !ifneq USE_OGG yes
114 LIBS+= ogg.lib
115 !endif
127 NEED_LIBOGG=yes
116128 !endif
117129
118130 !ifeq USE_LIBMAD yes
123135 CFLAGS+= -DMUSIC_MP3_MPG123
124136 LIBS+= mpg123.lib
125137 !endif
138 !ifeq USE_DRMP3 yes
139 CFLAGS+= -DMUSIC_MP3_DRMP3
140 !endif
126141
127142 !ifeq USE_XMP yes
128143 CFLAGS+= -DMUSIC_MOD_XMP
135150 !ifeq USE_MODPLUG yes
136151 CFLAGS+= -DMUSIC_MOD_MODPLUG
137152 LIBS+= modplug.lib
153 !endif
154
155 !ifeq NEED_LIBOGG yes
156 LIBS+= ogg.lib
138157 !endif
139158
140159 # For the static assertions in mixer.c
44 http://www.libsdl.org/projects/SDL_mixer/
55
66 Due to popular demand, here is a simple multi-channel audio mixer.
7 It supports 8 channels of 16 bit stereo audio, plus a single channel
8 of music.
7 It supports 8 channels of 16 bit stereo audio, plus a single channel of music. It can load FLAC, MP3, Ogg, VOC, and WAV format audio. It can also load MIDI, MOD, and Opus audio, depending on build options (see the note below for details.)
98
109 See the header file SDL_mixer.h and the examples playwave.c and playmus.c
1110 for documentation on this mixer library.
1211
13 The mixer can currently load Microsoft WAVE files and Creative Labs VOC
14 files as audio samples, it can load FLAC files with libFLAC, it can load
15 Ogg Vorbis files with Ogg Vorbis or Tremor libraries, it can load MP3 files
16 using mpg123 or libmad, and it can load MIDI files with Timidity,
17 FluidSynth, and natively on Windows, Mac OSX, and Linux, and finally it can
18 load the following file formats via ModPlug or MikMod: .MOD .S3M .IT .XM.
12 The process of mixing MIDI files to wave output is very CPU intensive, so if playing regular WAVE files sound great, but playing MIDI files sound choppy, try using 8-bit audio, mono audio, or lower frequencies.
1913
20 Tremor decoding is disabled by default; you can enable it by passing
21 --enable-music-ogg-tremor
22 to configure, or by defining MUSIC_OGG and OGG_USE_TREMOR.
23
24 libmad decoding is disabled by default; you can enable it by passing
25 --enable-music-mp3-mad
26 to configure, or by defining MUSIC_MP3_MAD
27 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
28 WARNING: The license for libmad is GPL, which means that in order to
29 use it your application must also be GPL!
30 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31
32 The process of mixing MIDI files to wave output is very CPU intensive,
33 so if playing regular WAVE files sound great, but playing MIDI files
34 sound choppy, try using 8-bit audio, mono audio, or lower frequencies.
35
36 To play MIDI files using FluidSynth, you'll need to set the SDL_SOUNDFONTS
37 environment variable to a Sound Font 2 (.sf2) file containing the musical
38 instruments you want to use for MIDI playback.
14 To play MIDI files using FluidSynth, you'll need to set the SDL_SOUNDFONTS environment variable to a Sound Font 2 (.sf2) file containing the musical instruments you want to use for MIDI playback.
3915 (On some Linux distributions you can install the fluid-soundfont-gm package)
4016
41 To play MIDI files using Timidity, you'll need to get a complete set of
42 GUS patches from:
17 To play MIDI files using Timidity, you'll need to get a complete set of GUS patches from:
4318 http://www.libsdl.org/projects/mixer/timidity/timidity.tar.gz
4419 and unpack them in /usr/local/lib under UNIX, and C:\ under Win32.
4520
46 iOS:
47 In order to use this library on iOS, you should include the SDL.xcodeproj
48 and Xcode-iOS/SDL_mixer.xcodeproj in your application, add the SDL/include
49 and SDL_mixer directories to your "Header Search Paths" setting, then add the
50 libSDL2.a and libSDL2_mixer.a to your "Link Binary with Libraries" setting.
51
5221 This library is under the zlib license, see the file "LICENSE.txt" for details.
5322
23 Note:
24 Support for software MIDI, MOD, and Opus are not included by default because of the size of the decode libraries, but you can get them by running external/download.sh
25 - When building with CMake, you can enable the appropriate SUPPORT_* options defined in CMakeLists.txt.
26 - When building with configure/make, you can build and install them normally and the configure script will detect and use them.
27 - When building with Visual Studio, you will need to build the libraries and then add the appropriate LOAD_* preprocessor define to the Visual Studio project.
28 - When building with Xcode, you can edit the config at the top of the project to enable them, and you will need to include the appropriate framework in your application.
29 - For Android, you can edit the config at the top of Android.mk to enable them.
30
31 The default MP3 support is provided using dr_mp3. SDL_mixer also supports using libmad, but does not use it by default because the libmad license is GPL, which requires your application to also be GPL. If your application has a compatible license, you can enable libmad by passing
32 --enable-music-mp3-mad
33 to configure, or by defining MUSIC_MP3_MAD
250250 }
251251
252252 dnl Check for SDL
253 SDL_VERSION=2.0.7
253 SDL_VERSION=2.0.9
254254 AM_PATH_SDL2($SDL_VERSION,
255255 :,
256256 AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
351351 fi
352352 fi
353353
354 AC_ARG_ENABLE([music-mod-mikmod],
355 [AS_HELP_STRING([--enable-music-mod-mikmod], [enable MOD music via mikmod [default=no]])],
356 [], [enable_music_mod_mikmod=no])
357 AC_ARG_ENABLE([music-mod-mikmod-shared],
358 [AS_HELP_STRING([--enable-music-mod-mikmod-shared], [dynamically load mikmod library [default=yes]])],
359 [], [enable_music_mod_mikmod_shared=yes])
360 if test x$enable_music_mod = xyes -a x$enable_music_mod_mikmod = xyes; then
361 AC_PATH_PROG(LIBMIKMOD_CONFIG, libmikmod-config, no, [$PATH])
362 AC_SUBST(LIBMIKMOD_CFLAGS)
363 AC_SUBST(LIBMIKMOD_LIBS)
364 if test "$LIBMIKMOD_CONFIG" != "no" ; then
365 test -z "$LIBMIKMOD_CFLAGS" && LIBMIKMOD_CFLAGS=`$LIBMIKMOD_CONFIG --cflags`
366 test -z "$LIBMIKMOD_LIBS" && LIBMIKMOD_LIBS=`$LIBMIKMOD_CONFIG --libs`
367 fi
368 CFLAGS_SAVED="$CFLAGS"
369 LIBS_SAVED="$LIBS"
370 CFLAGS="$CFLAGS $LIBMIKMOD_CFLAGS"
371 LIBS="$LIBS $LIBMIKMOD_LIBS"
372 AC_MSG_CHECKING([for libmikmod >= 3.1.10])
373 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <mikmod.h>]],[[
374 #if (LIBMIKMOD_VERSION < 0x03010a)
375 choke me
376 #endif
377 Player_LoadGeneric(NULL,0,0);
378 ]])], [have_libmikmod=yes],[have_libmikmod=no])
379
380 CFLAGS="$CFLAGS_SAVED"
381 LIBS="$LIBS_SAVED"
382 AC_MSG_RESULT($have_libmikmod)
383
384 if test x$have_libmikmod = xyes; then
385 case "$host" in
386 *-*-darwin*)
387 mikmod_lib=[`find_lib libmikmod.dylib`]
388 ;;
389 *-*-cygwin* | *-*-mingw*)
390 mikmod_lib=[`find_lib "libmikmod*.dll"`]
391 ;;
392 *)
393 mikmod_lib=[`find_lib "libmikmod[0-9]*.so.*"`]
394 if test x$mikmod_lib = x; then
395 mikmod_lib=[`find_lib "libmikmod.so.*"`]
396 fi
397 ;;
398 esac
399 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MOD_MIKMOD $LIBMIKMOD_CFLAGS"
400 if test x$enable_music_mod_mikmod_shared = xyes && test x$mikmod_lib != x; then
401 echo "-- dynamic libmikmod -> $mikmod_lib"
402 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMIKMOD_DYNAMIC=\\\"$mikmod_lib\\\""
403 else
404 EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBMIKMOD_LIBS"
405 PC_LIBS="$PC_LIBS $LIBMIKMOD_LIBS"
406 fi
407 else
408 AC_MSG_WARN([*** Unable to find MikMod library (http://mikmod.sourceforge.net/)])
409 fi
410 fi
411
354412 AC_ARG_ENABLE([music-mod-xmp],
355413 [AS_HELP_STRING([--enable-music-mod-xmp], [enable MOD music via libxmp [default=no]])],
356414 [], [enable_music_mod_xmp=no])
405463 else
406464 AC_MSG_WARN([*** Unable to find xmp library (http://xmp.sourceforge.net/)])
407465 fi
408 fi
409
410 AC_ARG_ENABLE([music-mod-mikmod],
411 [AS_HELP_STRING([--enable-music-mod-mikmod], [enable MOD music via mikmod [default=no]])],
412 [], [enable_music_mod_mikmod=no])
413 AC_ARG_ENABLE([music-mod-mikmod-shared],
414 [AS_HELP_STRING([--enable-music-mod-mikmod-shared], [dynamically load mikmod library [default=yes]])],
415 [], [enable_music_mod_mikmod_shared=yes])
416 if test x$enable_music_mod = xyes -a x$enable_music_mod_mikmod = xyes; then
417 have_libmikmod=no
418 libmikmod_maj=3
419 libmikmod_min=1
420 libmikmod_rev=10
421 libmikmod_ver="$libmikmod_maj.$libmikmod_min.$libmikmod_rev"
422 CFLAGS_SAVED="$CFLAGS"
423 LIBS_SAVED="$LIBS"
424 AC_PATH_PROG(LIBMIKMOD_CONFIG, libmikmod-config, no, [$PATH])
425 if test "$LIBMIKMOD_CONFIG" != "no" ; then
426 CFLAGS="$CFLAGS `$LIBMIKMOD_CONFIG --cflags`"
427 LIBS="$LIBS `$LIBMIKMOD_CONFIG --libs`"
428 have_libmikmod=yes
429 AC_MSG_CHECKING([for libmikmod - version >= $libmikmod_ver])
430 AC_RUN_IFELSE([AC_LANG_SOURCE([[
431 #include "mikmod.h"
432 #include "stdio.h"
433
434 int main(int argc, char **argv)
435 {
436 long maj=$libmikmod_maj,min=$libmikmod_min,rev=$libmikmod_rev,ver=MikMod_GetVersion();
437 if (ver>=((maj<<16)|(min<<8)|(rev))) {
438 printf("yes\n");
439 return 0;
440 }
441 printf("no\n*** libmikmod is older than %d.%d.%d, not using.\n",maj,min,rev);
442 return 1;
443 }
444 ]])], [],[have_libmikmod=no],[echo $ac_n "cross compiling; assumed OK... $ac_c"])
445 fi
446
447 if test x$have_libmikmod = xyes; then
448 case "$host" in
449 *-*-darwin*)
450 mikmod_lib=[`find_lib libmikmod.dylib`]
451 ;;
452 *-*-cygwin* | *-*-mingw*)
453 mikmod_lib=[`find_lib "libmikmod*.dll"`]
454 ;;
455 *)
456 mikmod_lib=[`find_lib "libmikmod[0-9]*.so.*"`]
457 if test x$mikmod_lib = x; then
458 mikmod_lib=[`find_lib "libmikmod.so.*"`]
459 fi
460 ;;
461 esac
462 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MOD_MIKMOD `$LIBMIKMOD_CONFIG --cflags`"
463 if test x$enable_music_mod_mikmod_shared = xyes && test x$mikmod_lib != x; then
464 echo "-- dynamic libmikmod -> $mikmod_lib"
465 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMIKMOD_DYNAMIC=\\\"$mikmod_lib\\\""
466 else
467 EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$LIBMIKMOD_CONFIG --libs`"
468 PC_LIBS="$PC_LIBS `$LIBMIKMOD_CONFIG --libs`"
469 fi
470 else
471 AC_MSG_WARN([*** Unable to find MikMod library (http://mikmod.sourceforge.net/)])
472 fi
473 LIBS="$LIBS_SAVED"
474 CFLAGS="$CFLAGS_SAVED"
475466 fi
476467
477468 if test x$have_libmodplug != xyes -a x$have_libmikmod != xyes -a x$have_libxmp != xyes; then
589580 AC_ARG_ENABLE([music-ogg],
590581 [AS_HELP_STRING([--enable-music-ogg], [enable Ogg Vorbis music [default=yes]])],
591582 [], [enable_music_ogg=yes])
583
584 AC_ARG_ENABLE(music-ogg-stb,
585 [AS_HELP_STRING([--enable-music-ogg-stb], [enable OGG Vorbis music via stb_vorbis [default=yes]])],
586 [], enable_music_ogg_stb=yes)
587 if test x$enable_music_ogg = xyes -a x$enable_music_ogg_stb = xyes; then
588 have_stb_vorbis=yes
589 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OGG -DOGG_USE_STB"
590 fi
591
592 AC_ARG_ENABLE(music-ogg-vorbis,
593 [AS_HELP_STRING([--enable-music-ogg-vorbis], [enable OGG Vorbis music via libvorbis [default=no]])],
594 [], enable_music_ogg_vorbis=no)
595 AC_ARG_ENABLE([music-ogg-vorbis-shared],
596 [AS_HELP_STRING([--enable-music-ogg-vorbis-shared], [dynamically load libvorbis library [default=yes]])],
597 [], [enable_music_ogg_vorbis_shared=yes])
598 if test x$enable_music_ogg = xyes -a x$enable_music_ogg_vorbis = xyes; then
599 LIBS_SAVED="$LIBS"
600 PKG_CHECK_MODULES([VORBIS], [vorbisfile], [dnl
601 have_ogg_hdr=yes
602 have_ogg_lib=yes
603 have_ogg_pc=yes
604 ], [dnl
605 AC_CHECK_HEADER([vorbis/vorbisfile.h], [have_ogg_hdr=yes])
606 AC_CHECK_LIB([vorbisfile], [ov_open_callbacks], [have_ogg_lib=yes;VORBIS_LIBS="-lvorbisfile -lvorbis -logg -lm"], [], [-lvorbis -logg -lm])
607 ])
608 LIBS="$LIBS_SAVED"
609
610 if test x$have_ogg_hdr = xyes -a x$have_ogg_lib = xyes; then
611 have_vorbis=yes
612 case "$host" in
613 *-*-darwin*)
614 ogg_lib=[`find_lib libvorbisfile.dylib`]
615 ;;
616 *-*-cygwin* | *-*-mingw*)
617 ogg_lib=[`find_lib "libvorbisfile*.dll"`]
618 ;;
619 *)
620 ogg_lib=[`find_lib "libvorbisfile[0-9]*.so.*"`]
621 if test x$ogg_lib = x; then
622 ogg_lib=[`find_lib "libvorbisfile.so.*"`]
623 fi
624 ;;
625 esac
626 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OGG $VORBIS_CFLAGS"
627 if test x$enable_music_ogg_vorbis_shared = xyes && test x$ogg_lib != x; then
628 echo "-- dynamic libvorbisfile -> $ogg_lib"
629 EXTRA_CFLAGS="$EXTRA_CFLAGS -DOGG_DYNAMIC=\\\"$ogg_lib\\\""
630 else
631 EXTRA_LDFLAGS="$EXTRA_LDFLAGS $VORBIS_LIBS"
632 if test x$have_ogg_pc = xyes; then
633 PC_REQUIRES="$PC_REQUIRES vorbisfile"
634 else
635 PC_LIBS="$PC_LIBS $VORBIS_LIBS"
636 fi
637 fi
638 else
639 AC_MSG_WARN([*** Unable to find Ogg Vorbis library (http://www.xiph.org/)])
640 fi
641 fi
642
592643 AC_ARG_ENABLE(music-ogg-tremor,
593 [AS_HELP_STRING([--enable-music-ogg-tremor], [enable OGG Vorbis music via libtremor [default=no]])],
644 [AS_HELP_STRING([--enable-music-ogg-tremor], [enable OGG Vorbis music via Tremor [default=no]])],
594645 [], enable_music_ogg_tremor=no)
595 AC_ARG_ENABLE([music-ogg-shared],
596 [AS_HELP_STRING([--enable-music-ogg-shared], [dynamically load Ogg Vorbis library [default=yes]])],
597 [], [enable_music_ogg_shared=yes])
598 if test x$enable_music_ogg = xyes; then
646 AC_ARG_ENABLE([music-ogg-tremor-shared],
647 [AS_HELP_STRING([--enable-music-ogg-tremor-shared], [dynamically load Tremor library [default=yes]])],
648 [], [enable_music_ogg_tremor_shared=yes])
649 if test x$enable_music_ogg = xyes -a x$enable_music_ogg_tremor = xyes; then
599650 LIBS_SAVED="$LIBS"
600 if test x$enable_music_ogg_tremor = xyes; then
601 PKG_CHECK_MODULES([TREMOR], [vorbisidec], [dnl
602 have_tremor_hdr=yes
603 have_tremor_lib=yes
604 have_tremor_pc=yes
605 ], [dnl
606 AC_CHECK_HEADER([tremor/ivorbisfile.h], [have_tremor_hdr=yes])
607 AC_CHECK_LIB([vorbisidec], [ov_open_callbacks], [have_tremor_lib=yes;TREMOR_LIBS="-lvorbisidec -logg"], [], [-logg])
608 ])
609 if test x$have_tremor_hdr = xyes -a x$have_tremor_lib = xyes; then
610 case "$host" in
611 *-*-darwin*)
612 ogg_lib=[`find_lib libvorbisidec.dylib`]
613 ;;
614 *-*-cygwin* | *-*-mingw*)
615 ogg_lib=[`find_lib "vorbisidec*.dll"`]
616 if test x$ogg_lib = x; then
617 ogg_lib=[`find_lib "libvorbisidec*.dll"`]
618 fi
619 ;;
620 *)
621 ogg_lib=[`find_lib "libvorbisidec[0-9]*.so.*"`]
622 if test x$ogg_lib = x; then
623 ogg_lib=[`find_lib "libvorbisidec.so.*"`]
624 fi
625 ;;
626 esac
627 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OGG -DOGG_USE_TREMOR $TREMOR_CFLAGS"
628 if test x$enable_music_ogg_shared = xyes && test x$ogg_lib != x; then
629 echo "-- dynamic libvorbisidec -> $ogg_lib"
630 EXTRA_CFLAGS="$EXTRA_CFLAGS -DOGG_DYNAMIC=\\\"$ogg_lib\\\""
651 PKG_CHECK_MODULES([TREMOR], [vorbisidec], [dnl
652 have_tremor_hdr=yes
653 have_tremor_lib=yes
654 have_tremor_pc=yes
655 ], [dnl
656 AC_CHECK_HEADER([tremor/ivorbisfile.h], [have_tremor_hdr=yes])
657 AC_CHECK_LIB([vorbisidec], [ov_open_callbacks], [have_tremor_lib=yes;TREMOR_LIBS="-lvorbisidec -logg"], [], [-logg])
658 ])
659 LIBS="$LIBS_SAVED"
660
661 if test x$have_tremor_hdr = xyes -a x$have_tremor_lib = xyes; then
662 have_tremor=yes
663 case "$host" in
664 *-*-darwin*)
665 ogg_lib=[`find_lib libvorbisidec.dylib`]
666 ;;
667 *-*-cygwin* | *-*-mingw*)
668 ogg_lib=[`find_lib "vorbisidec*.dll"`]
669 if test x$ogg_lib = x; then
670 ogg_lib=[`find_lib "libvorbisidec*.dll"`]
671 fi
672 ;;
673 *)
674 ogg_lib=[`find_lib "libvorbisidec[0-9]*.so.*"`]
675 if test x$ogg_lib = x; then
676 ogg_lib=[`find_lib "libvorbisidec.so.*"`]
677 fi
678 ;;
679 esac
680 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OGG -DOGG_USE_TREMOR $TREMOR_CFLAGS"
681 if test x$enable_music_ogg_tremor_shared = xyes && test x$ogg_lib != x; then
682 echo "-- dynamic libvorbisidec -> $ogg_lib"
683 EXTRA_CFLAGS="$EXTRA_CFLAGS -DOGG_DYNAMIC=\\\"$ogg_lib\\\""
684 else
685 EXTRA_LDFLAGS="$EXTRA_LDFLAGS $TREMOR_LIBS"
686 if test x$have_tremor_pc = xyes; then
687 PC_REQUIRES="$PC_REQUIRES vorbisidec"
631688 else
632 EXTRA_LDFLAGS="$EXTRA_LDFLAGS $TREMOR_LIBS"
633 if test x$have_tremor_pc = xyes; then
634 PC_REQUIRES="$PC_REQUIRES vorbisidec"
635 else
636 PC_LIBS="$PC_LIBS $TREMOR_LIBS"
637 fi
689 PC_LIBS="$PC_LIBS $TREMOR_LIBS"
638690 fi
639 else
640 AC_MSG_WARN([*** Unable to find Ogg Vorbis Tremor library (http://www.xiph.org/)])
641 AC_MSG_WARN([Ogg Vorbis support disabled])
642691 fi
643692 else
644 PKG_CHECK_MODULES([VORBIS], [vorbisfile], [dnl
645 have_ogg_hdr=yes
646 have_ogg_lib=yes
647 have_ogg_pc=yes
648 ], [dnl
649 AC_CHECK_HEADER([vorbis/vorbisfile.h], [have_ogg_hdr=yes])
650 AC_CHECK_LIB([vorbisfile], [ov_open_callbacks], [have_ogg_lib=yes;VORBIS_LIBS="-lvorbisfile -lvorbis -logg -lm"], [], [-lvorbis -logg -lm])
651 ])
652 if test x$have_ogg_hdr = xyes -a x$have_ogg_lib = xyes; then
653 case "$host" in
654 *-*-darwin*)
655 ogg_lib=[`find_lib libvorbisfile.dylib`]
656 ;;
657 *-*-cygwin* | *-*-mingw*)
658 ogg_lib=[`find_lib "libvorbisfile*.dll"`]
659 ;;
660 *)
661 ogg_lib=[`find_lib "libvorbisfile[0-9]*.so.*"`]
662 if test x$ogg_lib = x; then
663 ogg_lib=[`find_lib "libvorbisfile.so.*"`]
664 fi
665 ;;
666 esac
667 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OGG $VORBIS_CFLAGS"
668 if test x$enable_music_ogg_shared = xyes && test x$ogg_lib != x; then
669 echo "-- dynamic libvorbisfile -> $ogg_lib"
670 EXTRA_CFLAGS="$EXTRA_CFLAGS -DOGG_DYNAMIC=\\\"$ogg_lib\\\""
671 else
672 EXTRA_LDFLAGS="$EXTRA_LDFLAGS $VORBIS_LIBS"
673 if test x$have_ogg_pc = xyes; then
674 PC_REQUIRES="$PC_REQUIRES vorbisfile"
675 else
676 PC_LIBS="$PC_LIBS $VORBIS_LIBS"
677 fi
678 fi
679 else
680 AC_MSG_WARN([*** Unable to find Ogg Vorbis library (http://www.xiph.org/)])
681 AC_MSG_WARN([Ogg Vorbis support disabled])
682 fi
683 fi
684 LIBS="$LIBS_SAVED"
685 fi
686
687 libflac_ver=8
693 AC_MSG_WARN([*** Unable to find Ogg Vorbis Tremor library (http://www.xiph.org/)])
694 fi
695 fi
696
697 if test x$enable_music_ogg = xyes -a \
698 x$have_stb_vorbis != xyes -a x$have_vorbis != xyes -a x$have_tremor != xyes; then
699 AC_MSG_WARN([Ogg Vorbis support disabled])
700 fi
701
688702 AC_ARG_ENABLE([music-flac],
689703 [AS_HELP_STRING([--enable-music-flac], [enable FLAC music [default=yes]])],
690704 [], [enable_music_flac=yes])
691 AC_ARG_ENABLE([music-flac-shared],
692 [AS_HELP_STRING([--enable-music-flac-shared],
693 [dynamically load FLAC library [default=yes]])],
694 [], [enable_music_flac_shared=yes])
695 if test x$enable_music_flac = xyes; then
705
706 AC_ARG_ENABLE(music-flac-drflac,
707 [AS_HELP_STRING([--enable-music-flac-drflac], [enable FLAC music via dr_flac [default=yes]])],
708 [], [enable_music_flac_drflac=yes])
709 if test x$enable_music_flac = xyes -a x$enable_music_flac_drflac = xyes; then
710 have_drflac=yes
711 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_FLAC_DRFLAC"
712 fi
713
714 AC_ARG_ENABLE(music-flac-libflac,
715 [AS_HELP_STRING([--enable-music-flac-libflac], [enable FLAC music via libFLAC [default=no]])],
716 [], [enable_music_flac_libflac=no])
717 AC_ARG_ENABLE([music-flac-libflac-shared],
718 [AS_HELP_STRING([--enable-music-flac-libflac-shared], [dynamically load FLAC library [default=yes]])],
719 [], [enable_music_flac_libflac_shared=yes])
720 if test x$enable_music_flac = xyes -a x$enable_music_flac_libflac = xyes; then
721 libflac_ver=8
696722 PKG_CHECK_MODULES([FLAC], [flac], [dnl
697723 have_flac_hdr=yes
698724 have_flac_lib=yes
719745 AC_MSG_RESULT($have_flac_ver)
720746 fi
721747 if test x$have_flac_ver = xyes; then
748 have_libflac=yes
722749 case "$host" in
723750 *-*-darwin*)
724751 flac_lib=[`find_lib libFLAC.dylib`]
733760 fi
734761 ;;
735762 esac
736 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_FLAC $FLAC_CFLAGS"
737 if test x$enable_music_flac_shared = xyes && test x$flac_lib != x; then
763 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_FLAC_LIBFLAC $FLAC_CFLAGS"
764 if test x$enable_music_flac_libflac_shared = xyes && test x$flac_lib != x; then
738765 echo "-- dynamic libFLAC -> $flac_lib"
739766 EXTRA_CFLAGS="$EXTRA_CFLAGS -DFLAC_DYNAMIC=\\\"$flac_lib\\\""
740767 else
746773 fi
747774 fi
748775 else
749 AC_MSG_WARN([*** Unable to find FLAC library (http://flac.sourceforge.net/)])
750 AC_MSG_WARN([FLAC support disabled])
751 fi
776 AC_MSG_WARN([*** Unable to find FLAC library (https://xiph.org/flac/)])
777 fi
778 fi
779
780 if test x$enable_music_flac = xyes -a \
781 x$have_drflac != xyes -a x$have_libflac != xyes; then
782 AC_MSG_WARN([FLAC support disabled])
752783 fi
753784
754785 AC_ARG_ENABLE(music-mp3,
755786 [AS_HELP_STRING([--enable-music-mp3], [enable MP3 music [default=yes]])],
756787 [], enable_music_mp3=yes)
788
789 AC_ARG_ENABLE(music-mp3-drmp3,
790 [AS_HELP_STRING([--enable-music-mp3-drmp3], [enable MP3 music via dr_mp3 [default=yes]])],
791 [], [enable_music_mp3_drmp3=yes])
792 if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_drmp3 = xyes; then
793 have_drmp3=yes
794 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_DRMP3"
795 fi
796
797 AC_ARG_ENABLE(music-mp3-mpg123,
798 [AS_HELP_STRING([--enable-music-mp3-mpg123], [enable MP3 music via mpg123 [default=no]])],
799 [], [enable_music_mp3_mpg123=no])
800 AC_ARG_ENABLE([music-mp3-mpg123-shared],
801 [AS_HELP_STRING([--enable-music-mp3-mpg123-shared], [dynamically load mpg123 library [default=yes]])],
802 [], [enable_music_mp3_mpg123_shared=yes])
803 if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_mpg123 = xyes; then
804 PKG_CHECK_MODULES([MPG123], [libmpg123], [dnl
805 have_mpg123_hdr=yes
806 have_mpg123_lib=yes
807 have_mpg123_pc=yes
808 ], [dnl
809 AC_CHECK_HEADER([mpg123.h], [have_mpg123_hdr=yes])
810 AC_CHECK_LIB([mpg123], [mpg123_replace_reader_handle], [have_mpg123_lib=yes;MPG123_LIBS="-lmpg123"])
811 ])
812 if test x$have_mpg123_hdr = xyes -a x$have_mpg123_lib = xyes; then
813 have_libmpg123=yes
814 case "$host" in
815 *-*-darwin*)
816 mpg123_lib=[`find_lib libmpg123.dylib`]
817 ;;
818 *-*-cygwin* | *-*-mingw*)
819 mpg123_lib=[`find_lib "libmpg123*.dll"`]
820 ;;
821 *)
822 mpg123_lib=[`find_lib "libmpg123.so.*"`]
823 ;;
824 esac
825 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_MPG123 $MPG123_CFLAGS"
826 if test x$enable_music_mp3_mpg123_shared = xyes && test x$mpg123_lib != x; then
827 echo "-- dynamic libmpg123 -> $mpg123_lib"
828 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMPG123_DYNAMIC=\\\"$mpg123_lib\\\""
829 else
830 EXTRA_LDFLAGS="$EXTRA_LDFLAGS $MPG123_LIBS"
831 if test x$have_mpg123_pc = xyes; then
832 PC_REQUIRES="$PC_REQUIRES libmpg123"
833 else
834 PC_LIBS="$PC_LIBS $MPG123_LIBS"
835 fi
836 fi
837 else
838 AC_MSG_WARN([*** Unable to find mpg123 library (https://www.mpg123.de)])
839 fi
840 fi
757841
758842 AC_ARG_ENABLE(music-mp3-mad-gpl,
759843 [AS_HELP_STRING([--enable-music-mp3-mad-gpl], [enable MP3 music via libmad GPL code [default=no]])],
781865 fi
782866 fi
783867
784 AC_ARG_ENABLE(music-mp3-mpg123,
785 [AS_HELP_STRING([--enable-music-mp3-mpg123], [enable MP3 music via libmpg123 [default=yes]])],
786 [], [enable_music_mp3_mpg123=yes])
787 AC_ARG_ENABLE([music-mp3-mpg123-shared],
788 [AS_HELP_STRING([--enable-music-mp3-mpg123-shared], [dynamically load libmpg123 library [default=yes]])],
789 [], [enable_music_mp3_mpg123_shared=yes])
790 if test x$enable_music_mp3_mpg123 = xyes; then
791 PKG_CHECK_MODULES([MPG123], [libmpg123], [dnl
792 have_mpg123_hdr=yes
793 have_mpg123_lib=yes
794 have_mpg123_pc=yes
795 ], [dnl
796 AC_CHECK_HEADER([mpg123.h], [have_mpg123_hdr=yes])
797 AC_CHECK_LIB([mpg123], [mpg123_replace_reader_handle], [have_mpg123_lib=yes;MPG123_LIBS="-lmpg123"])
798 ])
799 if test x$have_mpg123_hdr = xyes -a x$have_mpg123_lib = xyes; then
800 have_libmpg123=yes
801 case "$host" in
802 *-*-darwin*)
803 mpg123_lib=[`find_lib libmpg123.dylib`]
804 ;;
805 *-*-cygwin* | *-*-mingw*)
806 mpg123_lib=[`find_lib "libmpg123*.dll"`]
807 ;;
808 *)
809 mpg123_lib=[`find_lib "libmpg123.so.*"`]
810 ;;
811 esac
812 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_MPG123 $MPG123_CFLAGS"
813 if test x$enable_music_mp3_mpg123_shared = xyes && test x$mpg123_lib != x; then
814 echo "-- dynamic libmpg123 -> $mpg123_lib"
815 EXTRA_CFLAGS="$EXTRA_CFLAGS -DMPG123_DYNAMIC=\\\"$mpg123_lib\\\""
816 else
817 EXTRA_LDFLAGS="$EXTRA_LDFLAGS $MPG123_LIBS"
818 if test x$have_mpg123_pc = xyes; then
819 PC_REQUIRES="$PC_REQUIRES libmpg123"
820 else
821 PC_LIBS="$PC_LIBS $MPG123_LIBS"
822 fi
823 fi
824 else
825 AC_MSG_WARN([*** Unable to find mpg123 library (https://www.mpg123.de)])
826 AC_MSG_WARN([mpg123 support disabled])
827 fi
828 fi
829
830 if test x$have_libmad = xyes -o x$have_libmpg123 = xyes; then
831 :
832 else
868 if test x$enable_music_mp3 = xyes -a \
869 x$have_drmp3 != xyes -a x$have_libmpg123 != xyes -a x$have_libmad != xyes; then
833870 AC_MSG_WARN([MP3 support disabled])
834871 fi
835872
836873 AC_ARG_ENABLE([music-opus],
837874 [AS_HELP_STRING([--enable-music-opus], [enable Opus music [default=yes]])],
838875 [], [enable_music_opus=yes])
839
840876 AC_ARG_ENABLE([music-opus-shared],
841877 [AS_HELP_STRING([--enable-music-opus-shared], [dynamically load opusfile library [default=yes]])],
842878 [], [enable_music_opus_shared=yes])
882918 fi
883919 else
884920 AC_MSG_WARN([*** Unable to find opusfile library (http://opus-codec.org/)])
921 AC_MSG_WARN([Opus support disabled])
885922 fi
886923 fi
887924
+0
-103
gcc-fat.sh less more
0 #!/bin/sh
1 #
2 # Build Universal binaries on Mac OS X, thanks Ryan!
3 #
4 # Usage: ./configure CC="sh gcc-fat.sh" && make && rm -rf x86 x64
5
6 DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer"
7
8 # Intel 32-bit compiler flags (10.6 runtime compatibility)
9 GCC_COMPILE_X86="gcc -arch i386 -mmacosx-version-min=10.6 \
10 -DMAC_OS_X_VERSION_MIN_REQUIRED=1040 \
11 -I/usr/local/include"
12
13 GCC_LINK_X86="-mmacosx-version-min=10.6"
14
15 # Intel 64-bit compiler flags (10.6 runtime compatibility)
16 GCC_COMPILE_X64="gcc -arch x86_64 -mmacosx-version-min=10.6 \
17 -DMAC_OS_X_VERSION_MIN_REQUIRED=1050 \
18 -I/usr/local/include"
19
20 GCC_LINK_X64="-mmacosx-version-min=10.6"
21
22 # Output both PowerPC and Intel object files
23 args="$*"
24 compile=yes
25 link=yes
26 while test x$1 != x; do
27 case $1 in
28 --version) exec gcc $1;;
29 -v) exec gcc $1;;
30 -V) exec gcc $1;;
31 -print-prog-name=*) exec gcc $1;;
32 -print-search-dirs) exec gcc $1;;
33 -E) GCC_COMPILE_X86="$GCC_COMPILE_X86 -E"
34 GCC_COMPILE_X64="$GCC_COMPILE_X64 -E"
35 compile=no; link=no;;
36 -c) link=no;;
37 -o) output=$2;;
38 *.c|*.cc|*.cpp|*.S) source=$1;;
39 esac
40 shift
41 done
42 if test x$link = xyes; then
43 GCC_COMPILE_X86="$GCC_COMPILE_X86 $GCC_LINK_X86"
44 GCC_COMPILE_X64="$GCC_COMPILE_X64 $GCC_LINK_X64"
45 fi
46 if test x"$output" = x; then
47 if test x$link = xyes; then
48 output=a.out
49 elif test x$compile = xyes; then
50 output=`echo $source | sed -e 's|.*/||' -e 's|\(.*\)\.[^\.]*|\1|'`.o
51 fi
52 fi
53
54 # Compile X86 32-bit
55 if test x"$output" != x; then
56 dir=x86/`dirname $output`
57 if test -d $dir; then
58 :
59 else
60 mkdir -p $dir
61 fi
62 fi
63 set -- $args
64 while test x$1 != x; do
65 if test -f "x86/$1" && test "$1" != "$output"; then
66 x86_args="$x86_args x86/$1"
67 else
68 x86_args="$x86_args $1"
69 fi
70 shift
71 done
72 $GCC_COMPILE_X86 $x86_args || exit $?
73 if test x"$output" != x; then
74 cp $output x86/$output
75 fi
76
77 # Compile X86 32-bit
78 if test x"$output" != x; then
79 dir=x64/`dirname $output`
80 if test -d $dir; then
81 :
82 else
83 mkdir -p $dir
84 fi
85 fi
86 set -- $args
87 while test x$1 != x; do
88 if test -f "x64/$1" && test "$1" != "$output"; then
89 x64_args="$x64_args x64/$1"
90 else
91 x64_args="$x64_args $1"
92 fi
93 shift
94 done
95 $GCC_COMPILE_X64 $x64_args || exit $?
96 if test x"$output" != x; then
97 cp $output x64/$output
98 fi
99
100 if test x"$output" != x; then
101 lipo -create -o $output x86/$output x64/$output
102 fi
589589 /* Get the current volume value in the range of 0-128 of a music stream */
590590 extern DECLSPEC int SDLCALL Mix_GetMusicVolume(Mix_Music *music);
591591
592 /* Set the master volume.
593 This did not affect the member variables of music, channel or chunck volume.
594 If the specified volume is -1, just return the current master volume.
595 */
596 extern DECLSPEC int SDLCALL Mix_MasterVolume(int volume);
597
592598 /* Halt playing of a particular channel */
593599 extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel);
594600 extern DECLSPEC int SDLCALL Mix_HaltGroup(int tag);
0 This software is available as a choice of the following licenses. Choose
1 whichever you prefer.
2
3 ===============================================================================
4 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
5 ===============================================================================
6 This is free and unencumbered software released into the public domain.
7
8 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
9 software, either in source code form or as a compiled binary, for any purpose,
10 commercial or non-commercial, and by any means.
11
12 In jurisdictions that recognize copyright laws, the author or authors of this
13 software dedicate any and all copyright interest in the software to the public
14 domain. We make this dedication for the benefit of the public at large and to
15 the detriment of our heirs and successors. We intend this dedication to be an
16 overt act of relinquishment in perpetuity of all present and future rights to
17 this software under copyright law.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 For more information, please refer to <http://unlicense.org/>
27
28 ===============================================================================
29 ALTERNATIVE 2 - MIT No Attribution
30 ===============================================================================
31 Copyright 2020 David Reid
32
33 Permission is hereby granted, free of charge, to any person obtaining a copy of
34 this software and associated documentation files (the "Software"), to deal in
35 the Software without restriction, including without limitation the rights to
36 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
37 of the Software, and to permit persons to whom the Software is furnished to do
38 so.
39
40 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
46 SOFTWARE.
0 <h4 align="center">Public domain, single file audio decoding libraries for C and C++.</h4>
1
2 <p align="center">
3 <a href="https://discord.gg/9vpqbjU"><img src="https://img.shields.io/discord/712952679415939085?label=discord&logo=discord" alt="discord"></a>
4 <a href="https://twitter.com/mackron"><img src="https://img.shields.io/twitter/follow/mackron?style=flat&label=twitter&color=1da1f2&logo=twitter" alt="twitter"></a>
5 </p>
6
7
8 Library | Description
9 ----------------------------------------------- | -----------
10 [dr_flac](dr_flac.h) | FLAC audio decoder.
11 [dr_mp3](dr_mp3.h) | MP3 audio decoder. Based off [minimp3](https://github.com/lieff/minimp3).
12 [dr_wav](dr_wav.h) | WAV audio loader and writer.
13
14
15 # Other Libraries
16 Below are some of my other libraries you may be interested in.
17
18 Library | Description
19 ------------------------------------------------- | -----------
20 [miniaudio](https://github.com/mackron/miniaudio) | A public domain, single file library for audio playback and recording.
0 /*
1 FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
2 dr_flac - v0.12.38 - 2022-04-10
3
4 David Reid - mackron@gmail.com
5
6 GitHub: https://github.com/mackron/dr_libs
7 */
8
9 /*
10 RELEASE NOTES - v0.12.0
11 =======================
12 Version 0.12.0 has breaking API changes including changes to the existing API and the removal of deprecated APIs.
13
14
15 Improved Client-Defined Memory Allocation
16 -----------------------------------------
17 The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
18 existing system of DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE are still in place and will be used by default when no custom
19 allocation callbacks are specified.
20
21 To use the new system, you pass in a pointer to a drflac_allocation_callbacks object to drflac_open() and family, like this:
22
23 void* my_malloc(size_t sz, void* pUserData)
24 {
25 return malloc(sz);
26 }
27 void* my_realloc(void* p, size_t sz, void* pUserData)
28 {
29 return realloc(p, sz);
30 }
31 void my_free(void* p, void* pUserData)
32 {
33 free(p);
34 }
35
36 ...
37
38 drflac_allocation_callbacks allocationCallbacks;
39 allocationCallbacks.pUserData = &myData;
40 allocationCallbacks.onMalloc = my_malloc;
41 allocationCallbacks.onRealloc = my_realloc;
42 allocationCallbacks.onFree = my_free;
43 drflac* pFlac = drflac_open_file("my_file.flac", &allocationCallbacks);
44
45 The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
46
47 Passing in null for the allocation callbacks object will cause dr_flac to use defaults which is the same as DRFLAC_MALLOC,
48 DRFLAC_REALLOC and DRFLAC_FREE and the equivalent of how it worked in previous versions.
49
50 Every API that opens a drflac object now takes this extra parameter. These include the following:
51
52 drflac_open()
53 drflac_open_relaxed()
54 drflac_open_with_metadata()
55 drflac_open_with_metadata_relaxed()
56 drflac_open_file()
57 drflac_open_file_with_metadata()
58 drflac_open_memory()
59 drflac_open_memory_with_metadata()
60 drflac_open_and_read_pcm_frames_s32()
61 drflac_open_and_read_pcm_frames_s16()
62 drflac_open_and_read_pcm_frames_f32()
63 drflac_open_file_and_read_pcm_frames_s32()
64 drflac_open_file_and_read_pcm_frames_s16()
65 drflac_open_file_and_read_pcm_frames_f32()
66 drflac_open_memory_and_read_pcm_frames_s32()
67 drflac_open_memory_and_read_pcm_frames_s16()
68 drflac_open_memory_and_read_pcm_frames_f32()
69
70
71
72 Optimizations
73 -------------
74 Seeking performance has been greatly improved. A new binary search based seeking algorithm has been introduced which significantly
75 improves performance over the brute force method which was used when no seek table was present. Seek table based seeking also takes
76 advantage of the new binary search seeking system to further improve performance there as well. Note that this depends on CRC which
77 means it will be disabled when DR_FLAC_NO_CRC is used.
78
79 The SSE4.1 pipeline has been cleaned up and optimized. You should see some improvements with decoding speed of 24-bit files in
80 particular. 16-bit streams should also see some improvement.
81
82 drflac_read_pcm_frames_s16() has been optimized. Previously this sat on top of drflac_read_pcm_frames_s32() and performed it's s32
83 to s16 conversion in a second pass. This is now all done in a single pass. This includes SSE2 and ARM NEON optimized paths.
84
85 A minor optimization has been implemented for drflac_read_pcm_frames_s32(). This will now use an SSE2 optimized pipeline for stereo
86 channel reconstruction which is the last part of the decoding process.
87
88 The ARM build has seen a few improvements. The CLZ (count leading zeroes) and REV (byte swap) instructions are now used when
89 compiling with GCC and Clang which is achieved using inline assembly. The CLZ instruction requires ARM architecture version 5 at
90 compile time and the REV instruction requires ARM architecture version 6.
91
92 An ARM NEON optimized pipeline has been implemented. To enable this you'll need to add -mfpu=neon to the command line when compiling.
93
94
95 Removed APIs
96 ------------
97 The following APIs were deprecated in version 0.11.0 and have been completely removed in version 0.12.0:
98
99 drflac_read_s32() -> drflac_read_pcm_frames_s32()
100 drflac_read_s16() -> drflac_read_pcm_frames_s16()
101 drflac_read_f32() -> drflac_read_pcm_frames_f32()
102 drflac_seek_to_sample() -> drflac_seek_to_pcm_frame()
103 drflac_open_and_decode_s32() -> drflac_open_and_read_pcm_frames_s32()
104 drflac_open_and_decode_s16() -> drflac_open_and_read_pcm_frames_s16()
105 drflac_open_and_decode_f32() -> drflac_open_and_read_pcm_frames_f32()
106 drflac_open_and_decode_file_s32() -> drflac_open_file_and_read_pcm_frames_s32()
107 drflac_open_and_decode_file_s16() -> drflac_open_file_and_read_pcm_frames_s16()
108 drflac_open_and_decode_file_f32() -> drflac_open_file_and_read_pcm_frames_f32()
109 drflac_open_and_decode_memory_s32() -> drflac_open_memory_and_read_pcm_frames_s32()
110 drflac_open_and_decode_memory_s16() -> drflac_open_memory_and_read_pcm_frames_s16()
111 drflac_open_and_decode_memory_f32() -> drflac_open_memroy_and_read_pcm_frames_f32()
112
113 Prior versions of dr_flac operated on a per-sample basis whereas now it operates on PCM frames. The removed APIs all relate
114 to the old per-sample APIs. You now need to use the "pcm_frame" versions.
115 */
116
117
118 /*
119 Introduction
120 ============
121 dr_flac is a single file library. To use it, do something like the following in one .c file.
122
123 ```c
124 #define DR_FLAC_IMPLEMENTATION
125 #include "dr_flac.h"
126 ```
127
128 You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following:
129
130 ```c
131 drflac* pFlac = drflac_open_file("MySong.flac", NULL);
132 if (pFlac == NULL) {
133 // Failed to open FLAC file
134 }
135
136 drflac_int32* pSamples = malloc(pFlac->totalPCMFrameCount * pFlac->channels * sizeof(drflac_int32));
137 drflac_uint64 numberOfInterleavedSamplesActuallyRead = drflac_read_pcm_frames_s32(pFlac, pFlac->totalPCMFrameCount, pSamples);
138 ```
139
140 The drflac object represents the decoder. It is a transparent type so all the information you need, such as the number of channels and the bits per sample,
141 should be directly accessible - just make sure you don't change their values. Samples are always output as interleaved signed 32-bit PCM. In the example above
142 a native FLAC stream was opened, however dr_flac has seamless support for Ogg encapsulated FLAC streams as well.
143
144 You do not need to decode the entire stream in one go - you just specify how many samples you'd like at any given time and the decoder will give you as many
145 samples as it can, up to the amount requested. Later on when you need the next batch of samples, just call it again. Example:
146
147 ```c
148 while (drflac_read_pcm_frames_s32(pFlac, chunkSizeInPCMFrames, pChunkSamples) > 0) {
149 do_something();
150 }
151 ```
152
153 You can seek to a specific PCM frame with `drflac_seek_to_pcm_frame()`.
154
155 If you just want to quickly decode an entire FLAC file in one go you can do something like this:
156
157 ```c
158 unsigned int channels;
159 unsigned int sampleRate;
160 drflac_uint64 totalPCMFrameCount;
161 drflac_int32* pSampleData = drflac_open_file_and_read_pcm_frames_s32("MySong.flac", &channels, &sampleRate, &totalPCMFrameCount, NULL);
162 if (pSampleData == NULL) {
163 // Failed to open and decode FLAC file.
164 }
165
166 ...
167
168 drflac_free(pSampleData, NULL);
169 ```
170
171 You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs respectively, but note that these
172 should be considered lossy.
173
174
175 If you need access to metadata (album art, etc.), use `drflac_open_with_metadata()`, `drflac_open_file_with_metdata()` or `drflac_open_memory_with_metadata()`.
176 The rationale for keeping these APIs separate is that they're slightly slower than the normal versions and also just a little bit harder to use. dr_flac
177 reports metadata to the application through the use of a callback, and every metadata block is reported before `drflac_open_with_metdata()` returns.
178
179 The main opening APIs (`drflac_open()`, etc.) will fail if the header is not present. The presents a problem in certain scenarios such as broadcast style
180 streams or internet radio where the header may not be present because the user has started playback mid-stream. To handle this, use the relaxed APIs:
181
182 `drflac_open_relaxed()`
183 `drflac_open_with_metadata_relaxed()`
184
185 It is not recommended to use these APIs for file based streams because a missing header would usually indicate a corrupt or perverse file. In addition, these
186 APIs can take a long time to initialize because they may need to spend a lot of time finding the first frame.
187
188
189
190 Build Options
191 =============
192 #define these options before including this file.
193
194 #define DR_FLAC_NO_STDIO
195 Disable `drflac_open_file()` and family.
196
197 #define DR_FLAC_NO_OGG
198 Disables support for Ogg/FLAC streams.
199
200 #define DR_FLAC_BUFFER_SIZE <number>
201 Defines the size of the internal buffer to store data from onRead(). This buffer is used to reduce the number of calls back to the client for more data.
202 Larger values means more memory, but better performance. My tests show diminishing returns after about 4KB (which is the default). Consider reducing this if
203 you have a very efficient implementation of onRead(), or increase it if it's very inefficient. Must be a multiple of 8.
204
205 #define DR_FLAC_NO_CRC
206 Disables CRC checks. This will offer a performance boost when CRC is unnecessary. This will disable binary search seeking. When seeking, the seek table will
207 be used if available. Otherwise the seek will be performed using brute force.
208
209 #define DR_FLAC_NO_SIMD
210 Disables SIMD optimizations (SSE on x86/x64 architectures, NEON on ARM architectures). Use this if you are having compatibility issues with your compiler.
211
212
213
214 Notes
215 =====
216 - dr_flac does not support changing the sample rate nor channel count mid stream.
217 - dr_flac is not thread-safe, but its APIs can be called from any thread so long as you do your own synchronization.
218 - When using Ogg encapsulation, a corrupted metadata block will result in `drflac_open_with_metadata()` and `drflac_open()` returning inconsistent samples due
219 to differences in corrupted stream recorvery logic between the two APIs.
220 */
221
222 #ifndef dr_flac_h
223 #define dr_flac_h
224
225 #ifdef __cplusplus
226 extern "C" {
227 #endif
228
229 #define DRFLAC_STRINGIFY(x) #x
230 #define DRFLAC_XSTRINGIFY(x) DRFLAC_STRINGIFY(x)
231
232 #define DRFLAC_VERSION_MAJOR 0
233 #define DRFLAC_VERSION_MINOR 12
234 #define DRFLAC_VERSION_REVISION 38
235 #define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
236
237 #include <stddef.h> /* For size_t. */
238
239 /* Sized types. */
240 typedef signed char drflac_int8;
241 typedef unsigned char drflac_uint8;
242 typedef signed short drflac_int16;
243 typedef unsigned short drflac_uint16;
244 typedef signed int drflac_int32;
245 typedef unsigned int drflac_uint32;
246 #if defined(_MSC_VER) && !defined(__clang__)
247 typedef signed __int64 drflac_int64;
248 typedef unsigned __int64 drflac_uint64;
249 #else
250 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
251 #pragma GCC diagnostic push
252 #pragma GCC diagnostic ignored "-Wlong-long"
253 #if defined(__clang__)
254 #pragma GCC diagnostic ignored "-Wc++11-long-long"
255 #endif
256 #endif
257 typedef signed long long drflac_int64;
258 typedef unsigned long long drflac_uint64;
259 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
260 #pragma GCC diagnostic pop
261 #endif
262 #endif
263 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
264 typedef drflac_uint64 drflac_uintptr;
265 #else
266 typedef drflac_uint32 drflac_uintptr;
267 #endif
268 typedef drflac_uint8 drflac_bool8;
269 typedef drflac_uint32 drflac_bool32;
270 #define DRFLAC_TRUE 1
271 #define DRFLAC_FALSE 0
272
273 #if !defined(DRFLAC_API)
274 #if defined(DRFLAC_DLL)
275 #if defined(_WIN32)
276 #define DRFLAC_DLL_IMPORT __declspec(dllimport)
277 #define DRFLAC_DLL_EXPORT __declspec(dllexport)
278 #define DRFLAC_DLL_PRIVATE static
279 #else
280 #if defined(__GNUC__) && __GNUC__ >= 4
281 #define DRFLAC_DLL_IMPORT __attribute__((visibility("default")))
282 #define DRFLAC_DLL_EXPORT __attribute__((visibility("default")))
283 #define DRFLAC_DLL_PRIVATE __attribute__((visibility("hidden")))
284 #else
285 #define DRFLAC_DLL_IMPORT
286 #define DRFLAC_DLL_EXPORT
287 #define DRFLAC_DLL_PRIVATE static
288 #endif
289 #endif
290
291 #if defined(DR_FLAC_IMPLEMENTATION) || defined(DRFLAC_IMPLEMENTATION)
292 #define DRFLAC_API DRFLAC_DLL_EXPORT
293 #else
294 #define DRFLAC_API DRFLAC_DLL_IMPORT
295 #endif
296 #define DRFLAC_PRIVATE DRFLAC_DLL_PRIVATE
297 #else
298 #define DRFLAC_API extern
299 #define DRFLAC_PRIVATE static
300 #endif
301 #endif
302
303 #if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */
304 #define DRFLAC_DEPRECATED __declspec(deprecated)
305 #elif (defined(__GNUC__) && __GNUC__ >= 4) /* GCC 4 */
306 #define DRFLAC_DEPRECATED __attribute__((deprecated))
307 #elif defined(__has_feature) /* Clang */
308 #if __has_feature(attribute_deprecated)
309 #define DRFLAC_DEPRECATED __attribute__((deprecated))
310 #else
311 #define DRFLAC_DEPRECATED
312 #endif
313 #else
314 #define DRFLAC_DEPRECATED
315 #endif
316
317 DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision);
318 DRFLAC_API const char* drflac_version_string(void);
319
320 /*
321 As data is read from the client it is placed into an internal buffer for fast access. This controls the size of that buffer. Larger values means more speed,
322 but also more memory. In my testing there is diminishing returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8.
323 */
324 #ifndef DR_FLAC_BUFFER_SIZE
325 #define DR_FLAC_BUFFER_SIZE 4096
326 #endif
327
328 /* Check if we can enable 64-bit optimizations. */
329 #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
330 #define DRFLAC_64BIT
331 #endif
332
333 #ifdef DRFLAC_64BIT
334 typedef drflac_uint64 drflac_cache_t;
335 #else
336 typedef drflac_uint32 drflac_cache_t;
337 #endif
338
339 /* The various metadata block types. */
340 #define DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO 0
341 #define DRFLAC_METADATA_BLOCK_TYPE_PADDING 1
342 #define DRFLAC_METADATA_BLOCK_TYPE_APPLICATION 2
343 #define DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE 3
344 #define DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT 4
345 #define DRFLAC_METADATA_BLOCK_TYPE_CUESHEET 5
346 #define DRFLAC_METADATA_BLOCK_TYPE_PICTURE 6
347 #define DRFLAC_METADATA_BLOCK_TYPE_INVALID 127
348
349 /* The various picture types specified in the PICTURE block. */
350 #define DRFLAC_PICTURE_TYPE_OTHER 0
351 #define DRFLAC_PICTURE_TYPE_FILE_ICON 1
352 #define DRFLAC_PICTURE_TYPE_OTHER_FILE_ICON 2
353 #define DRFLAC_PICTURE_TYPE_COVER_FRONT 3
354 #define DRFLAC_PICTURE_TYPE_COVER_BACK 4
355 #define DRFLAC_PICTURE_TYPE_LEAFLET_PAGE 5
356 #define DRFLAC_PICTURE_TYPE_MEDIA 6
357 #define DRFLAC_PICTURE_TYPE_LEAD_ARTIST 7
358 #define DRFLAC_PICTURE_TYPE_ARTIST 8
359 #define DRFLAC_PICTURE_TYPE_CONDUCTOR 9
360 #define DRFLAC_PICTURE_TYPE_BAND 10
361 #define DRFLAC_PICTURE_TYPE_COMPOSER 11
362 #define DRFLAC_PICTURE_TYPE_LYRICIST 12
363 #define DRFLAC_PICTURE_TYPE_RECORDING_LOCATION 13
364 #define DRFLAC_PICTURE_TYPE_DURING_RECORDING 14
365 #define DRFLAC_PICTURE_TYPE_DURING_PERFORMANCE 15
366 #define DRFLAC_PICTURE_TYPE_SCREEN_CAPTURE 16
367 #define DRFLAC_PICTURE_TYPE_BRIGHT_COLORED_FISH 17
368 #define DRFLAC_PICTURE_TYPE_ILLUSTRATION 18
369 #define DRFLAC_PICTURE_TYPE_BAND_LOGOTYPE 19
370 #define DRFLAC_PICTURE_TYPE_PUBLISHER_LOGOTYPE 20
371
372 typedef enum
373 {
374 drflac_container_native,
375 drflac_container_ogg,
376 drflac_container_unknown
377 } drflac_container;
378
379 typedef enum
380 {
381 drflac_seek_origin_start,
382 drflac_seek_origin_current
383 } drflac_seek_origin;
384
385 /* Packing is important on this structure because we map this directly to the raw data within the SEEKTABLE metadata block. */
386 #pragma pack(2)
387 typedef struct
388 {
389 drflac_uint64 firstPCMFrame;
390 drflac_uint64 flacFrameOffset; /* The offset from the first byte of the header of the first frame. */
391 drflac_uint16 pcmFrameCount;
392 } drflac_seekpoint;
393 #pragma pack()
394
395 typedef struct
396 {
397 drflac_uint16 minBlockSizeInPCMFrames;
398 drflac_uint16 maxBlockSizeInPCMFrames;
399 drflac_uint32 minFrameSizeInPCMFrames;
400 drflac_uint32 maxFrameSizeInPCMFrames;
401 drflac_uint32 sampleRate;
402 drflac_uint8 channels;
403 drflac_uint8 bitsPerSample;
404 drflac_uint64 totalPCMFrameCount;
405 drflac_uint8 md5[16];
406 } drflac_streaminfo;
407
408 typedef struct
409 {
410 /*
411 The metadata type. Use this to know how to interpret the data below. Will be set to one of the
412 DRFLAC_METADATA_BLOCK_TYPE_* tokens.
413 */
414 drflac_uint32 type;
415
416 /*
417 A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to
418 not modify the contents of this buffer. Use the structures below for more meaningful and structured
419 information about the metadata. It's possible for this to be null.
420 */
421 const void* pRawData;
422
423 /* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */
424 drflac_uint32 rawDataSize;
425
426 union
427 {
428 drflac_streaminfo streaminfo;
429
430 struct
431 {
432 int unused;
433 } padding;
434
435 struct
436 {
437 drflac_uint32 id;
438 const void* pData;
439 drflac_uint32 dataSize;
440 } application;
441
442 struct
443 {
444 drflac_uint32 seekpointCount;
445 const drflac_seekpoint* pSeekpoints;
446 } seektable;
447
448 struct
449 {
450 drflac_uint32 vendorLength;
451 const char* vendor;
452 drflac_uint32 commentCount;
453 const void* pComments;
454 } vorbis_comment;
455
456 struct
457 {
458 char catalog[128];
459 drflac_uint64 leadInSampleCount;
460 drflac_bool32 isCD;
461 drflac_uint8 trackCount;
462 const void* pTrackData;
463 } cuesheet;
464
465 struct
466 {
467 drflac_uint32 type;
468 drflac_uint32 mimeLength;
469 const char* mime;
470 drflac_uint32 descriptionLength;
471 const char* description;
472 drflac_uint32 width;
473 drflac_uint32 height;
474 drflac_uint32 colorDepth;
475 drflac_uint32 indexColorCount;
476 drflac_uint32 pictureDataSize;
477 const drflac_uint8* pPictureData;
478 } picture;
479 } data;
480 } drflac_metadata;
481
482
483 /*
484 Callback for when data needs to be read from the client.
485
486
487 Parameters
488 ----------
489 pUserData (in)
490 The user data that was passed to drflac_open() and family.
491
492 pBufferOut (out)
493 The output buffer.
494
495 bytesToRead (in)
496 The number of bytes to read.
497
498
499 Return Value
500 ------------
501 The number of bytes actually read.
502
503
504 Remarks
505 -------
506 A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until either the entire bytesToRead is filled or
507 you have reached the end of the stream.
508 */
509 typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
510
511 /*
512 Callback for when data needs to be seeked.
513
514
515 Parameters
516 ----------
517 pUserData (in)
518 The user data that was passed to drflac_open() and family.
519
520 offset (in)
521 The number of bytes to move, relative to the origin. Will never be negative.
522
523 origin (in)
524 The origin of the seek - the current position or the start of the stream.
525
526
527 Return Value
528 ------------
529 Whether or not the seek was successful.
530
531
532 Remarks
533 -------
534 The offset will never be negative. Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which will be
535 either drflac_seek_origin_start or drflac_seek_origin_current.
536
537 When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of the FLAC stream. This needs to be detected
538 and handled by returning DRFLAC_FALSE.
539 */
540 typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
541
542 /*
543 Callback for when a metadata block is read.
544
545
546 Parameters
547 ----------
548 pUserData (in)
549 The user data that was passed to drflac_open() and family.
550
551 pMetadata (in)
552 A pointer to a structure containing the data of the metadata block.
553
554
555 Remarks
556 -------
557 Use pMetadata->type to determine which metadata block is being handled and how to read the data. This
558 will be set to one of the DRFLAC_METADATA_BLOCK_TYPE_* tokens.
559 */
560 typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
561
562
563 typedef struct
564 {
565 void* pUserData;
566 void* (* onMalloc)(size_t sz, void* pUserData);
567 void* (* onRealloc)(void* p, size_t sz, void* pUserData);
568 void (* onFree)(void* p, void* pUserData);
569 } drflac_allocation_callbacks;
570
571 /* Structure for internal use. Only used for decoders opened with drflac_open_memory. */
572 typedef struct
573 {
574 const drflac_uint8* data;
575 size_t dataSize;
576 size_t currentReadPos;
577 } drflac__memory_stream;
578
579 /* Structure for internal use. Used for bit streaming. */
580 typedef struct
581 {
582 /* The function to call when more data needs to be read. */
583 drflac_read_proc onRead;
584
585 /* The function to call when the current read position needs to be moved. */
586 drflac_seek_proc onSeek;
587
588 /* The user data to pass around to onRead and onSeek. */
589 void* pUserData;
590
591
592 /*
593 The number of unaligned bytes in the L2 cache. This will always be 0 until the end of the stream is hit. At the end of the
594 stream there will be a number of bytes that don't cleanly fit in an L1 cache line, so we use this variable to know whether
595 or not the bistreamer needs to run on a slower path to read those last bytes. This will never be more than sizeof(drflac_cache_t).
596 */
597 size_t unalignedByteCount;
598
599 /* The content of the unaligned bytes. */
600 drflac_cache_t unalignedCache;
601
602 /* The index of the next valid cache line in the "L2" cache. */
603 drflac_uint32 nextL2Line;
604
605 /* The number of bits that have been consumed by the cache. This is used to determine how many valid bits are remaining. */
606 drflac_uint32 consumedBits;
607
608 /*
609 The cached data which was most recently read from the client. There are two levels of cache. Data flows as such:
610 Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions.
611 */
612 drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
613 drflac_cache_t cache;
614
615 /*
616 CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this
617 is reset to 0 at the beginning of each frame.
618 */
619 drflac_uint16 crc16;
620 drflac_cache_t crc16Cache; /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */
621 drflac_uint32 crc16CacheIgnoredBytes; /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */
622 } drflac_bs;
623
624 typedef struct
625 {
626 /* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */
627 drflac_uint8 subframeType;
628
629 /* The number of wasted bits per sample as specified by the sub-frame header. */
630 drflac_uint8 wastedBitsPerSample;
631
632 /* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */
633 drflac_uint8 lpcOrder;
634
635 /* A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. */
636 drflac_int32* pSamplesS32;
637 } drflac_subframe;
638
639 typedef struct
640 {
641 /*
642 If the stream uses variable block sizes, this will be set to the index of the first PCM frame. If fixed block sizes are used, this will
643 always be set to 0. This is 64-bit because the decoded PCM frame number will be 36 bits.
644 */
645 drflac_uint64 pcmFrameNumber;
646
647 /*
648 If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0. This
649 is 32-bit because in fixed block sizes, the maximum frame number will be 31 bits.
650 */
651 drflac_uint32 flacFrameNumber;
652
653 /* The sample rate of this frame. */
654 drflac_uint32 sampleRate;
655
656 /* The number of PCM frames in each sub-frame within this frame. */
657 drflac_uint16 blockSizeInPCMFrames;
658
659 /*
660 The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this
661 will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE.
662 */
663 drflac_uint8 channelAssignment;
664
665 /* The number of bits per sample within this frame. */
666 drflac_uint8 bitsPerSample;
667
668 /* The frame's CRC. */
669 drflac_uint8 crc8;
670 } drflac_frame_header;
671
672 typedef struct
673 {
674 /* The header. */
675 drflac_frame_header header;
676
677 /*
678 The number of PCM frames left to be read in this FLAC frame. This is initially set to the block size. As PCM frames are read,
679 this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame.
680 */
681 drflac_uint32 pcmFramesRemaining;
682
683 /* The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels. */
684 drflac_subframe subframes[8];
685 } drflac_frame;
686
687 typedef struct
688 {
689 /* The function to call when a metadata block is read. */
690 drflac_meta_proc onMeta;
691
692 /* The user data posted to the metadata callback function. */
693 void* pUserDataMD;
694
695 /* Memory allocation callbacks. */
696 drflac_allocation_callbacks allocationCallbacks;
697
698
699 /* The sample rate. Will be set to something like 44100. */
700 drflac_uint32 sampleRate;
701
702 /*
703 The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. Maximum 8. This is set based on the
704 value specified in the STREAMINFO block.
705 */
706 drflac_uint8 channels;
707
708 /* The bits per sample. Will be set to something like 16, 24, etc. */
709 drflac_uint8 bitsPerSample;
710
711 /* The maximum block size, in samples. This number represents the number of samples in each channel (not combined). */
712 drflac_uint16 maxBlockSizeInPCMFrames;
713
714 /*
715 The total number of PCM Frames making up the stream. Can be 0 in which case it's still a valid stream, but just means
716 the total PCM frame count is unknown. Likely the case with streams like internet radio.
717 */
718 drflac_uint64 totalPCMFrameCount;
719
720
721 /* The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream. */
722 drflac_container container;
723
724 /* The number of seekpoints in the seektable. */
725 drflac_uint32 seekpointCount;
726
727
728 /* Information about the frame the decoder is currently sitting on. */
729 drflac_frame currentFLACFrame;
730
731
732 /* The index of the PCM frame the decoder is currently sitting on. This is only used for seeking. */
733 drflac_uint64 currentPCMFrame;
734
735 /* The position of the first FLAC frame in the stream. This is only ever used for seeking. */
736 drflac_uint64 firstFLACFramePosInBytes;
737
738
739 /* A hack to avoid a malloc() when opening a decoder with drflac_open_memory(). */
740 drflac__memory_stream memoryStream;
741
742
743 /* A pointer to the decoded sample data. This is an offset of pExtraData. */
744 drflac_int32* pDecodedSamples;
745
746 /* A pointer to the seek table. This is an offset of pExtraData, or NULL if there is no seek table. */
747 drflac_seekpoint* pSeekpoints;
748
749 /* Internal use only. Only used with Ogg containers. Points to a drflac_oggbs object. This is an offset of pExtraData. */
750 void* _oggbs;
751
752 /* Internal use only. Used for profiling and testing different seeking modes. */
753 drflac_bool32 _noSeekTableSeek : 1;
754 drflac_bool32 _noBinarySearchSeek : 1;
755 drflac_bool32 _noBruteForceSeek : 1;
756
757 /* The bit streamer. The raw FLAC data is fed through this object. */
758 drflac_bs bs;
759
760 /* Variable length extra data. We attach this to the end of the object so we can avoid unnecessary mallocs. */
761 drflac_uint8 pExtraData[1];
762 } drflac;
763
764
765 /*
766 Opens a FLAC decoder.
767
768
769 Parameters
770 ----------
771 onRead (in)
772 The function to call when data needs to be read from the client.
773
774 onSeek (in)
775 The function to call when the read position of the client data needs to move.
776
777 pUserData (in, optional)
778 A pointer to application defined data that will be passed to onRead and onSeek.
779
780 pAllocationCallbacks (in, optional)
781 A pointer to application defined callbacks for managing memory allocations.
782
783
784 Return Value
785 ------------
786 Returns a pointer to an object representing the decoder.
787
788
789 Remarks
790 -------
791 Close the decoder with `drflac_close()`.
792
793 `pAllocationCallbacks` can be NULL in which case it will use `DRFLAC_MALLOC`, `DRFLAC_REALLOC` and `DRFLAC_FREE`.
794
795 This function will automatically detect whether or not you are attempting to open a native or Ogg encapsulated FLAC, both of which should work seamlessly
796 without any manual intervention. Ogg encapsulation also works with multiplexed streams which basically means it can play FLAC encoded audio tracks in videos.
797
798 This is the lowest level function for opening a FLAC stream. You can also use `drflac_open_file()` and `drflac_open_memory()` to open the stream from a file or
799 from a block of memory respectively.
800
801 The STREAMINFO block must be present for this to succeed. Use `drflac_open_relaxed()` to open a FLAC stream where the header may not be present.
802
803 Use `drflac_open_with_metadata()` if you need access to metadata.
804
805
806 Seek Also
807 ---------
808 drflac_open_file()
809 drflac_open_memory()
810 drflac_open_with_metadata()
811 drflac_close()
812 */
813 DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
814
815 /*
816 Opens a FLAC stream with relaxed validation of the header block.
817
818
819 Parameters
820 ----------
821 onRead (in)
822 The function to call when data needs to be read from the client.
823
824 onSeek (in)
825 The function to call when the read position of the client data needs to move.
826
827 container (in)
828 Whether or not the FLAC stream is encapsulated using standard FLAC encapsulation or Ogg encapsulation.
829
830 pUserData (in, optional)
831 A pointer to application defined data that will be passed to onRead and onSeek.
832
833 pAllocationCallbacks (in, optional)
834 A pointer to application defined callbacks for managing memory allocations.
835
836
837 Return Value
838 ------------
839 A pointer to an object representing the decoder.
840
841
842 Remarks
843 -------
844 The same as drflac_open(), except attempts to open the stream even when a header block is not present.
845
846 Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do not set this to `drflac_container_unknown`
847 as that is for internal use only.
848
849 Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never found it will continue forever. To abort,
850 force your `onRead` callback to return 0, which dr_flac will use as an indicator that the end of the stream was found.
851
852 Use `drflac_open_with_metadata_relaxed()` if you need access to metadata.
853 */
854 DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
855
856 /*
857 Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).
858
859
860 Parameters
861 ----------
862 onRead (in)
863 The function to call when data needs to be read from the client.
864
865 onSeek (in)
866 The function to call when the read position of the client data needs to move.
867
868 onMeta (in)
869 The function to call for every metadata block.
870
871 pUserData (in, optional)
872 A pointer to application defined data that will be passed to onRead, onSeek and onMeta.
873
874 pAllocationCallbacks (in, optional)
875 A pointer to application defined callbacks for managing memory allocations.
876
877
878 Return Value
879 ------------
880 A pointer to an object representing the decoder.
881
882
883 Remarks
884 -------
885 Close the decoder with `drflac_close()`.
886
887 `pAllocationCallbacks` can be NULL in which case it will use `DRFLAC_MALLOC`, `DRFLAC_REALLOC` and `DRFLAC_FREE`.
888
889 This is slower than `drflac_open()`, so avoid this one if you don't need metadata. Internally, this will allocate and free memory on the heap for every
890 metadata block except for STREAMINFO and PADDING blocks.
891
892 The caller is notified of the metadata via the `onMeta` callback. All metadata blocks will be handled before the function returns. This callback takes a
893 pointer to a `drflac_metadata` object which is a union containing the data of all relevant metadata blocks. Use the `type` member to discriminate against
894 the different metadata types.
895
896 The STREAMINFO block must be present for this to succeed. Use `drflac_open_with_metadata_relaxed()` to open a FLAC stream where the header may not be present.
897
898 Note that this will behave inconsistently with `drflac_open()` if the stream is an Ogg encapsulated stream and a metadata block is corrupted. This is due to
899 the way the Ogg stream recovers from corrupted pages. When `drflac_open_with_metadata()` is being used, the open routine will try to read the contents of the
900 metadata block, whereas `drflac_open()` will simply seek past it (for the sake of efficiency). This inconsistency can result in different samples being
901 returned depending on whether or not the stream is being opened with metadata.
902
903
904 Seek Also
905 ---------
906 drflac_open_file_with_metadata()
907 drflac_open_memory_with_metadata()
908 drflac_open()
909 drflac_close()
910 */
911 DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
912
913 /*
914 The same as drflac_open_with_metadata(), except attempts to open the stream even when a header block is not present.
915
916 See Also
917 --------
918 drflac_open_with_metadata()
919 drflac_open_relaxed()
920 */
921 DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
922
923 /*
924 Closes the given FLAC decoder.
925
926
927 Parameters
928 ----------
929 pFlac (in)
930 The decoder to close.
931
932
933 Remarks
934 -------
935 This will destroy the decoder object.
936
937
938 See Also
939 --------
940 drflac_open()
941 drflac_open_with_metadata()
942 drflac_open_file()
943 drflac_open_file_w()
944 drflac_open_file_with_metadata()
945 drflac_open_file_with_metadata_w()
946 drflac_open_memory()
947 drflac_open_memory_with_metadata()
948 */
949 DRFLAC_API void drflac_close(drflac* pFlac);
950
951
952 /*
953 Reads sample data from the given FLAC decoder, output as interleaved signed 32-bit PCM.
954
955
956 Parameters
957 ----------
958 pFlac (in)
959 The decoder.
960
961 framesToRead (in)
962 The number of PCM frames to read.
963
964 pBufferOut (out, optional)
965 A pointer to the buffer that will receive the decoded samples.
966
967
968 Return Value
969 ------------
970 Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.
971
972
973 Remarks
974 -------
975 pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
976 */
977 DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut);
978
979
980 /*
981 Reads sample data from the given FLAC decoder, output as interleaved signed 16-bit PCM.
982
983
984 Parameters
985 ----------
986 pFlac (in)
987 The decoder.
988
989 framesToRead (in)
990 The number of PCM frames to read.
991
992 pBufferOut (out, optional)
993 A pointer to the buffer that will receive the decoded samples.
994
995
996 Return Value
997 ------------
998 Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.
999
1000
1001 Remarks
1002 -------
1003 pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
1004
1005 Note that this is lossy for streams where the bits per sample is larger than 16.
1006 */
1007 DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut);
1008
1009 /*
1010 Reads sample data from the given FLAC decoder, output as interleaved 32-bit floating point PCM.
1011
1012
1013 Parameters
1014 ----------
1015 pFlac (in)
1016 The decoder.
1017
1018 framesToRead (in)
1019 The number of PCM frames to read.
1020
1021 pBufferOut (out, optional)
1022 A pointer to the buffer that will receive the decoded samples.
1023
1024
1025 Return Value
1026 ------------
1027 Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.
1028
1029
1030 Remarks
1031 -------
1032 pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
1033
1034 Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly represent every possible number.
1035 */
1036 DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);
1037
1038 /*
1039 Seeks to the PCM frame at the given index.
1040
1041
1042 Parameters
1043 ----------
1044 pFlac (in)
1045 The decoder.
1046
1047 pcmFrameIndex (in)
1048 The index of the PCM frame to seek to. See notes below.
1049
1050
1051 Return Value
1052 -------------
1053 `DRFLAC_TRUE` if successful; `DRFLAC_FALSE` otherwise.
1054 */
1055 DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);
1056
1057
1058
1059 #ifndef DR_FLAC_NO_STDIO
1060 /*
1061 Opens a FLAC decoder from the file at the given path.
1062
1063
1064 Parameters
1065 ----------
1066 pFileName (in)
1067 The path of the file to open, either absolute or relative to the current directory.
1068
1069 pAllocationCallbacks (in, optional)
1070 A pointer to application defined callbacks for managing memory allocations.
1071
1072
1073 Return Value
1074 ------------
1075 A pointer to an object representing the decoder.
1076
1077
1078 Remarks
1079 -------
1080 Close the decoder with drflac_close().
1081
1082
1083 Remarks
1084 -------
1085 This will hold a handle to the file until the decoder is closed with drflac_close(). Some platforms will restrict the number of files a process can have open
1086 at any given time, so keep this mind if you have many decoders open at the same time.
1087
1088
1089 See Also
1090 --------
1091 drflac_open_file_with_metadata()
1092 drflac_open()
1093 drflac_close()
1094 */
1095 DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
1096 DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
1097
1098 /*
1099 Opens a FLAC decoder from the file at the given path and notifies the caller of the metadata chunks (album art, etc.)
1100
1101
1102 Parameters
1103 ----------
1104 pFileName (in)
1105 The path of the file to open, either absolute or relative to the current directory.
1106
1107 pAllocationCallbacks (in, optional)
1108 A pointer to application defined callbacks for managing memory allocations.
1109
1110 onMeta (in)
1111 The callback to fire for each metadata block.
1112
1113 pUserData (in)
1114 A pointer to the user data to pass to the metadata callback.
1115
1116 pAllocationCallbacks (in)
1117 A pointer to application defined callbacks for managing memory allocations.
1118
1119
1120 Remarks
1121 -------
1122 Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled.
1123
1124
1125 See Also
1126 --------
1127 drflac_open_with_metadata()
1128 drflac_open()
1129 drflac_close()
1130 */
1131 DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
1132 DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
1133 #endif
1134
1135 /*
1136 Opens a FLAC decoder from a pre-allocated block of memory
1137
1138
1139 Parameters
1140 ----------
1141 pData (in)
1142 A pointer to the raw encoded FLAC data.
1143
1144 dataSize (in)
1145 The size in bytes of `data`.
1146
1147 pAllocationCallbacks (in)
1148 A pointer to application defined callbacks for managing memory allocations.
1149
1150
1151 Return Value
1152 ------------
1153 A pointer to an object representing the decoder.
1154
1155
1156 Remarks
1157 -------
1158 This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for the lifetime of the decoder.
1159
1160
1161 See Also
1162 --------
1163 drflac_open()
1164 drflac_close()
1165 */
1166 DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks);
1167
1168 /*
1169 Opens a FLAC decoder from a pre-allocated block of memory and notifies the caller of the metadata chunks (album art, etc.)
1170
1171
1172 Parameters
1173 ----------
1174 pData (in)
1175 A pointer to the raw encoded FLAC data.
1176
1177 dataSize (in)
1178 The size in bytes of `data`.
1179
1180 onMeta (in)
1181 The callback to fire for each metadata block.
1182
1183 pUserData (in)
1184 A pointer to the user data to pass to the metadata callback.
1185
1186 pAllocationCallbacks (in)
1187 A pointer to application defined callbacks for managing memory allocations.
1188
1189
1190 Remarks
1191 -------
1192 Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled.
1193
1194
1195 See Also
1196 -------
1197 drflac_open_with_metadata()
1198 drflac_open()
1199 drflac_close()
1200 */
1201 DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
1202
1203
1204
1205 /* High Level APIs */
1206
1207 /*
1208 Opens a FLAC stream from the given callbacks and fully decodes it in a single operation. The return value is a
1209 pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with drflac_free().
1210
1211 You can pass in custom memory allocation callbacks via the pAllocationCallbacks parameter. This can be NULL in which
1212 case it will use DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
1213
1214 Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously
1215 read samples into a dynamically sized buffer on the heap until no samples are left.
1216
1217 Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
1218 */
1219 DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1220
1221 /* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
1222 DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1223
1224 /* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
1225 DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1226
1227 #ifndef DR_FLAC_NO_STDIO
1228 /* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
1229 DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1230
1231 /* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
1232 DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1233
1234 /* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
1235 DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1236 #endif
1237
1238 /* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a block of memory. */
1239 DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1240
1241 /* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
1242 DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1243
1244 /* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
1245 DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1246
1247 /*
1248 Frees memory that was allocated internally by dr_flac.
1249
1250 Set pAllocationCallbacks to the same object that was passed to drflac_open_*_and_read_pcm_frames_*(). If you originally passed in NULL, pass in NULL for this.
1251 */
1252 DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);
1253
1254
1255 /* Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block. */
1256 typedef struct
1257 {
1258 drflac_uint32 countRemaining;
1259 const char* pRunningData;
1260 } drflac_vorbis_comment_iterator;
1261
1262 /*
1263 Initializes a vorbis comment iterator. This can be used for iterating over the vorbis comments in a VORBIS_COMMENT
1264 metadata block.
1265 */
1266 DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments);
1267
1268 /*
1269 Goes to the next vorbis comment in the given iterator. If null is returned it means there are no more comments. The
1270 returned string is NOT null terminated.
1271 */
1272 DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
1273
1274
1275 /* Structure representing an iterator for cuesheet tracks in a CUESHEET metadata block. */
1276 typedef struct
1277 {
1278 drflac_uint32 countRemaining;
1279 const char* pRunningData;
1280 } drflac_cuesheet_track_iterator;
1281
1282 /* Packing is important on this structure because we map this directly to the raw data within the CUESHEET metadata block. */
1283 #pragma pack(4)
1284 typedef struct
1285 {
1286 drflac_uint64 offset;
1287 drflac_uint8 index;
1288 drflac_uint8 reserved[3];
1289 } drflac_cuesheet_track_index;
1290 #pragma pack()
1291
1292 typedef struct
1293 {
1294 drflac_uint64 offset;
1295 drflac_uint8 trackNumber;
1296 char ISRC[12];
1297 drflac_bool8 isAudio;
1298 drflac_bool8 preEmphasis;
1299 drflac_uint8 indexCount;
1300 const drflac_cuesheet_track_index* pIndexPoints;
1301 } drflac_cuesheet_track;
1302
1303 /*
1304 Initializes a cuesheet track iterator. This can be used for iterating over the cuesheet tracks in a CUESHEET metadata
1305 block.
1306 */
1307 DRFLAC_API void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData);
1308
1309 /* Goes to the next cuesheet track in the given iterator. If DRFLAC_FALSE is returned it means there are no more comments. */
1310 DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack);
1311
1312
1313 #ifdef __cplusplus
1314 }
1315 #endif
1316 #endif /* dr_flac_h */
1317
1318
1319 /************************************************************************************************************************************************************
1320 ************************************************************************************************************************************************************
1321
1322 IMPLEMENTATION
1323
1324 ************************************************************************************************************************************************************
1325 ************************************************************************************************************************************************************/
1326 #if defined(DR_FLAC_IMPLEMENTATION) || defined(DRFLAC_IMPLEMENTATION)
1327 #ifndef dr_flac_c
1328 #define dr_flac_c
1329
1330 /* Disable some annoying warnings. */
1331 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
1332 #pragma GCC diagnostic push
1333 #if __GNUC__ >= 7
1334 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
1335 #endif
1336 #endif
1337
1338 #ifdef __linux__
1339 #ifndef _BSD_SOURCE
1340 #define _BSD_SOURCE
1341 #endif
1342 #ifndef _DEFAULT_SOURCE
1343 #define _DEFAULT_SOURCE
1344 #endif
1345 #ifndef __USE_BSD
1346 #define __USE_BSD
1347 #endif
1348 #include <endian.h>
1349 #endif
1350
1351 #include <stdlib.h>
1352 #include <string.h>
1353
1354 #ifdef _MSC_VER
1355 #define DRFLAC_INLINE __forceinline
1356 #elif defined(__GNUC__)
1357 /*
1358 I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
1359 the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
1360 case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
1361 command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
1362 I am using "__inline__" only when we're compiling in strict ANSI mode.
1363 */
1364 #if defined(__STRICT_ANSI__)
1365 #define DRFLAC_GNUC_INLINE_HINT __inline__
1366 #else
1367 #define DRFLAC_GNUC_INLINE_HINT inline
1368 #endif
1369
1370 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
1371 #define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT __attribute__((always_inline))
1372 #else
1373 #define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT
1374 #endif
1375 #elif defined(__WATCOMC__)
1376 #define DRFLAC_INLINE __inline
1377 #else
1378 #define DRFLAC_INLINE
1379 #endif
1380
1381 /* CPU architecture. */
1382 #if defined(__x86_64__) || defined(_M_X64)
1383 #define DRFLAC_X64
1384 #elif defined(__i386) || defined(_M_IX86)
1385 #define DRFLAC_X86
1386 #elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
1387 #define DRFLAC_ARM
1388 #endif
1389
1390 /*
1391 Intrinsics Support
1392
1393 There's a bug in GCC 4.2.x which results in an incorrect compilation error when using _mm_slli_epi32() where it complains with
1394
1395 "error: shift must be an immediate"
1396
1397 Unfortuantely dr_flac depends on this for a few things so we're just going to disable SSE on GCC 4.2 and below.
1398 */
1399 #if !defined(DR_FLAC_NO_SIMD)
1400 #if defined(DRFLAC_X64) || defined(DRFLAC_X86)
1401 #if defined(_MSC_VER) && !defined(__clang__)
1402 /* MSVC. */
1403 #if _MSC_VER >= 1400 && !defined(DRFLAC_NO_SSE2) /* 2005 */
1404 #define DRFLAC_SUPPORT_SSE2
1405 #endif
1406 #if _MSC_VER >= 1600 && !defined(DRFLAC_NO_SSE41) /* 2010 */
1407 #define DRFLAC_SUPPORT_SSE41
1408 #endif
1409 #elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
1410 /* Assume GNUC-style. */
1411 #if defined(__SSE2__) && !defined(DRFLAC_NO_SSE2)
1412 #define DRFLAC_SUPPORT_SSE2
1413 #endif
1414 #if defined(__SSE4_1__) && !defined(DRFLAC_NO_SSE41)
1415 #define DRFLAC_SUPPORT_SSE41
1416 #endif
1417 #endif
1418
1419 /* If at this point we still haven't determined compiler support for the intrinsics just fall back to __has_include. */
1420 #if !defined(__GNUC__) && !defined(__clang__) && defined(__has_include)
1421 #if !defined(DRFLAC_SUPPORT_SSE2) && !defined(DRFLAC_NO_SSE2) && __has_include(<emmintrin.h>)
1422 #define DRFLAC_SUPPORT_SSE2
1423 #endif
1424 #if !defined(DRFLAC_SUPPORT_SSE41) && !defined(DRFLAC_NO_SSE41) && __has_include(<smmintrin.h>)
1425 #define DRFLAC_SUPPORT_SSE41
1426 #endif
1427 #endif
1428
1429 #if defined(DRFLAC_SUPPORT_SSE41)
1430 #include <smmintrin.h>
1431 #elif defined(DRFLAC_SUPPORT_SSE2)
1432 #include <emmintrin.h>
1433 #endif
1434 #endif
1435
1436 #if defined(DRFLAC_ARM)
1437 #if !defined(DRFLAC_NO_NEON) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
1438 #define DRFLAC_SUPPORT_NEON
1439 #include <arm_neon.h>
1440 #endif
1441 #endif
1442 #endif
1443
1444 /* Compile-time CPU feature support. */
1445 #if !defined(DR_FLAC_NO_SIMD) && (defined(DRFLAC_X86) || defined(DRFLAC_X64))
1446 #if defined(_MSC_VER) && !defined(__clang__)
1447 #if _MSC_VER >= 1400
1448 #include <intrin.h>
1449 static void drflac__cpuid(int info[4], int fid)
1450 {
1451 __cpuid(info, fid);
1452 }
1453 #else
1454 #define DRFLAC_NO_CPUID
1455 #endif
1456 #else
1457 #if defined(__GNUC__) || defined(__clang__)
1458 static void drflac__cpuid(int info[4], int fid)
1459 {
1460 /*
1461 It looks like the -fPIC option uses the ebx register which GCC complains about. We can work around this by just using a different register, the
1462 specific register of which I'm letting the compiler decide on. The "k" prefix is used to specify a 32-bit register. The {...} syntax is for
1463 supporting different assembly dialects.
1464
1465 What's basically happening is that we're saving and restoring the ebx register manually.
1466 */
1467 #if defined(DRFLAC_X86) && defined(__PIC__)
1468 __asm__ __volatile__ (
1469 "xchg{l} {%%}ebx, %k1;"
1470 "cpuid;"
1471 "xchg{l} {%%}ebx, %k1;"
1472 : "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
1473 );
1474 #else
1475 __asm__ __volatile__ (
1476 "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
1477 );
1478 #endif
1479 }
1480 #else
1481 #define DRFLAC_NO_CPUID
1482 #endif
1483 #endif
1484 #else
1485 #define DRFLAC_NO_CPUID
1486 #endif
1487
1488 static DRFLAC_INLINE drflac_bool32 drflac_has_sse2(void)
1489 {
1490 #if defined(DRFLAC_SUPPORT_SSE2)
1491 #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE2)
1492 #if defined(DRFLAC_X64)
1493 return DRFLAC_TRUE; /* 64-bit targets always support SSE2. */
1494 #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__)
1495 return DRFLAC_TRUE; /* If the compiler is allowed to freely generate SSE2 code we can assume support. */
1496 #else
1497 #if defined(DRFLAC_NO_CPUID)
1498 return DRFLAC_FALSE;
1499 #else
1500 int info[4];
1501 drflac__cpuid(info, 1);
1502 return (info[3] & (1 << 26)) != 0;
1503 #endif
1504 #endif
1505 #else
1506 return DRFLAC_FALSE; /* SSE2 is only supported on x86 and x64 architectures. */
1507 #endif
1508 #else
1509 return DRFLAC_FALSE; /* No compiler support. */
1510 #endif
1511 }
1512
1513 static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
1514 {
1515 #if defined(DRFLAC_SUPPORT_SSE41)
1516 #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE41)
1517 #if defined(DRFLAC_X64)
1518 return DRFLAC_TRUE; /* 64-bit targets always support SSE4.1. */
1519 #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE4_1__)
1520 return DRFLAC_TRUE; /* If the compiler is allowed to freely generate SSE41 code we can assume support. */
1521 #else
1522 #if defined(DRFLAC_NO_CPUID)
1523 return DRFLAC_FALSE;
1524 #else
1525 int info[4];
1526 drflac__cpuid(info, 1);
1527 return (info[2] & (1 << 19)) != 0;
1528 #endif
1529 #endif
1530 #else
1531 return DRFLAC_FALSE; /* SSE41 is only supported on x86 and x64 architectures. */
1532 #endif
1533 #else
1534 return DRFLAC_FALSE; /* No compiler support. */
1535 #endif
1536 }
1537
1538
1539 #if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(DRFLAC_X86) || defined(DRFLAC_X64)) && !defined(__clang__)
1540 #define DRFLAC_HAS_LZCNT_INTRINSIC
1541 #elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
1542 #define DRFLAC_HAS_LZCNT_INTRINSIC
1543 #elif defined(__clang__)
1544 #if defined(__has_builtin)
1545 #if __has_builtin(__builtin_clzll) || __has_builtin(__builtin_clzl)
1546 #define DRFLAC_HAS_LZCNT_INTRINSIC
1547 #endif
1548 #endif
1549 #endif
1550
1551 #if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(__clang__)
1552 #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1553 #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1554 #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1555 #elif defined(__clang__)
1556 #if defined(__has_builtin)
1557 #if __has_builtin(__builtin_bswap16)
1558 #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1559 #endif
1560 #if __has_builtin(__builtin_bswap32)
1561 #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1562 #endif
1563 #if __has_builtin(__builtin_bswap64)
1564 #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1565 #endif
1566 #endif
1567 #elif defined(__GNUC__)
1568 #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
1569 #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1570 #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1571 #endif
1572 #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
1573 #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1574 #endif
1575 #elif defined(__WATCOMC__) && defined(__386__)
1576 #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1577 #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1578 #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1579 extern __inline drflac_uint16 _watcom_bswap16(drflac_uint16);
1580 extern __inline drflac_uint32 _watcom_bswap32(drflac_uint32);
1581 extern __inline drflac_uint64 _watcom_bswap64(drflac_uint64);
1582 #pragma aux _watcom_bswap16 = \
1583 "xchg al, ah" \
1584 parm [ax] \
1585 modify [ax];
1586 #pragma aux _watcom_bswap32 = \
1587 "bswap eax" \
1588 parm [eax] \
1589 modify [eax];
1590 #pragma aux _watcom_bswap64 = \
1591 "bswap eax" \
1592 "bswap edx" \
1593 "xchg eax,edx" \
1594 parm [eax edx] \
1595 modify [eax edx];
1596 #endif
1597
1598
1599 /* Standard library stuff. */
1600 #ifndef DRFLAC_ASSERT
1601 #include <assert.h>
1602 #define DRFLAC_ASSERT(expression) assert(expression)
1603 #endif
1604 #ifndef DRFLAC_MALLOC
1605 #define DRFLAC_MALLOC(sz) malloc((sz))
1606 #endif
1607 #ifndef DRFLAC_REALLOC
1608 #define DRFLAC_REALLOC(p, sz) realloc((p), (sz))
1609 #endif
1610 #ifndef DRFLAC_FREE
1611 #define DRFLAC_FREE(p) free((p))
1612 #endif
1613 #ifndef DRFLAC_COPY_MEMORY
1614 #define DRFLAC_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
1615 #endif
1616 #ifndef DRFLAC_ZERO_MEMORY
1617 #define DRFLAC_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
1618 #endif
1619 #ifndef DRFLAC_ZERO_OBJECT
1620 #define DRFLAC_ZERO_OBJECT(p) DRFLAC_ZERO_MEMORY((p), sizeof(*(p)))
1621 #endif
1622
1623 #define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
1624
1625 typedef drflac_int32 drflac_result;
1626 #define DRFLAC_SUCCESS 0
1627 #define DRFLAC_ERROR -1 /* A generic error. */
1628 #define DRFLAC_INVALID_ARGS -2
1629 #define DRFLAC_INVALID_OPERATION -3
1630 #define DRFLAC_OUT_OF_MEMORY -4
1631 #define DRFLAC_OUT_OF_RANGE -5
1632 #define DRFLAC_ACCESS_DENIED -6
1633 #define DRFLAC_DOES_NOT_EXIST -7
1634 #define DRFLAC_ALREADY_EXISTS -8
1635 #define DRFLAC_TOO_MANY_OPEN_FILES -9
1636 #define DRFLAC_INVALID_FILE -10
1637 #define DRFLAC_TOO_BIG -11
1638 #define DRFLAC_PATH_TOO_LONG -12
1639 #define DRFLAC_NAME_TOO_LONG -13
1640 #define DRFLAC_NOT_DIRECTORY -14
1641 #define DRFLAC_IS_DIRECTORY -15
1642 #define DRFLAC_DIRECTORY_NOT_EMPTY -16
1643 #define DRFLAC_END_OF_FILE -17
1644 #define DRFLAC_NO_SPACE -18
1645 #define DRFLAC_BUSY -19
1646 #define DRFLAC_IO_ERROR -20
1647 #define DRFLAC_INTERRUPT -21
1648 #define DRFLAC_UNAVAILABLE -22
1649 #define DRFLAC_ALREADY_IN_USE -23
1650 #define DRFLAC_BAD_ADDRESS -24
1651 #define DRFLAC_BAD_SEEK -25
1652 #define DRFLAC_BAD_PIPE -26
1653 #define DRFLAC_DEADLOCK -27
1654 #define DRFLAC_TOO_MANY_LINKS -28
1655 #define DRFLAC_NOT_IMPLEMENTED -29
1656 #define DRFLAC_NO_MESSAGE -30
1657 #define DRFLAC_BAD_MESSAGE -31
1658 #define DRFLAC_NO_DATA_AVAILABLE -32
1659 #define DRFLAC_INVALID_DATA -33
1660 #define DRFLAC_TIMEOUT -34
1661 #define DRFLAC_NO_NETWORK -35
1662 #define DRFLAC_NOT_UNIQUE -36
1663 #define DRFLAC_NOT_SOCKET -37
1664 #define DRFLAC_NO_ADDRESS -38
1665 #define DRFLAC_BAD_PROTOCOL -39
1666 #define DRFLAC_PROTOCOL_UNAVAILABLE -40
1667 #define DRFLAC_PROTOCOL_NOT_SUPPORTED -41
1668 #define DRFLAC_PROTOCOL_FAMILY_NOT_SUPPORTED -42
1669 #define DRFLAC_ADDRESS_FAMILY_NOT_SUPPORTED -43
1670 #define DRFLAC_SOCKET_NOT_SUPPORTED -44
1671 #define DRFLAC_CONNECTION_RESET -45
1672 #define DRFLAC_ALREADY_CONNECTED -46
1673 #define DRFLAC_NOT_CONNECTED -47
1674 #define DRFLAC_CONNECTION_REFUSED -48
1675 #define DRFLAC_NO_HOST -49
1676 #define DRFLAC_IN_PROGRESS -50
1677 #define DRFLAC_CANCELLED -51
1678 #define DRFLAC_MEMORY_ALREADY_MAPPED -52
1679 #define DRFLAC_AT_END -53
1680 #define DRFLAC_CRC_MISMATCH -128
1681
1682 #define DRFLAC_SUBFRAME_CONSTANT 0
1683 #define DRFLAC_SUBFRAME_VERBATIM 1
1684 #define DRFLAC_SUBFRAME_FIXED 8
1685 #define DRFLAC_SUBFRAME_LPC 32
1686 #define DRFLAC_SUBFRAME_RESERVED 255
1687
1688 #define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE 0
1689 #define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 1
1690
1691 #define DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT 0
1692 #define DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE 8
1693 #define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE 9
1694 #define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10
1695
1696 #define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
1697
1698
1699 DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision)
1700 {
1701 if (pMajor) {
1702 *pMajor = DRFLAC_VERSION_MAJOR;
1703 }
1704
1705 if (pMinor) {
1706 *pMinor = DRFLAC_VERSION_MINOR;
1707 }
1708
1709 if (pRevision) {
1710 *pRevision = DRFLAC_VERSION_REVISION;
1711 }
1712 }
1713
1714 DRFLAC_API const char* drflac_version_string(void)
1715 {
1716 return DRFLAC_VERSION_STRING;
1717 }
1718
1719
1720 /* CPU caps. */
1721 #if defined(__has_feature)
1722 #if __has_feature(thread_sanitizer)
1723 #define DRFLAC_NO_THREAD_SANITIZE __attribute__((no_sanitize("thread")))
1724 #else
1725 #define DRFLAC_NO_THREAD_SANITIZE
1726 #endif
1727 #else
1728 #define DRFLAC_NO_THREAD_SANITIZE
1729 #endif
1730
1731 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
1732 static drflac_bool32 drflac__gIsLZCNTSupported = DRFLAC_FALSE;
1733 #endif
1734
1735 #ifndef DRFLAC_NO_CPUID
1736 static drflac_bool32 drflac__gIsSSE2Supported = DRFLAC_FALSE;
1737 static drflac_bool32 drflac__gIsSSE41Supported = DRFLAC_FALSE;
1738
1739 /*
1740 I've had a bug report that Clang's ThreadSanitizer presents a warning in this function. Having reviewed this, this does
1741 actually make sense. However, since CPU caps should never differ for a running process, I don't think the trade off of
1742 complicating internal API's by passing around CPU caps versus just disabling the warnings is worthwhile. I'm therefore
1743 just going to disable these warnings. This is disabled via the DRFLAC_NO_THREAD_SANITIZE attribute.
1744 */
1745 DRFLAC_NO_THREAD_SANITIZE static void drflac__init_cpu_caps(void)
1746 {
1747 static drflac_bool32 isCPUCapsInitialized = DRFLAC_FALSE;
1748
1749 if (!isCPUCapsInitialized) {
1750 /* LZCNT */
1751 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
1752 int info[4] = {0};
1753 drflac__cpuid(info, 0x80000001);
1754 drflac__gIsLZCNTSupported = (info[2] & (1 << 5)) != 0;
1755 #endif
1756
1757 /* SSE2 */
1758 drflac__gIsSSE2Supported = drflac_has_sse2();
1759
1760 /* SSE4.1 */
1761 drflac__gIsSSE41Supported = drflac_has_sse41();
1762
1763 /* Initialized. */
1764 isCPUCapsInitialized = DRFLAC_TRUE;
1765 }
1766 }
1767 #else
1768 static drflac_bool32 drflac__gIsNEONSupported = DRFLAC_FALSE;
1769
1770 static DRFLAC_INLINE drflac_bool32 drflac__has_neon(void)
1771 {
1772 #if defined(DRFLAC_SUPPORT_NEON)
1773 #if defined(DRFLAC_ARM) && !defined(DRFLAC_NO_NEON)
1774 #if (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
1775 return DRFLAC_TRUE; /* If the compiler is allowed to freely generate NEON code we can assume support. */
1776 #else
1777 /* TODO: Runtime check. */
1778 return DRFLAC_FALSE;
1779 #endif
1780 #else
1781 return DRFLAC_FALSE; /* NEON is only supported on ARM architectures. */
1782 #endif
1783 #else
1784 return DRFLAC_FALSE; /* No compiler support. */
1785 #endif
1786 }
1787
1788 DRFLAC_NO_THREAD_SANITIZE static void drflac__init_cpu_caps(void)
1789 {
1790 drflac__gIsNEONSupported = drflac__has_neon();
1791
1792 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
1793 drflac__gIsLZCNTSupported = DRFLAC_TRUE;
1794 #endif
1795 }
1796 #endif
1797
1798
1799 /* Endian Management */
1800 static DRFLAC_INLINE drflac_bool32 drflac__is_little_endian(void)
1801 {
1802 #if defined(DRFLAC_X86) || defined(DRFLAC_X64)
1803 return DRFLAC_TRUE;
1804 #elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
1805 return DRFLAC_TRUE;
1806 #else
1807 int n = 1;
1808 return (*(char*)&n) == 1;
1809 #endif
1810 }
1811
1812 static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n)
1813 {
1814 #ifdef DRFLAC_HAS_BYTESWAP16_INTRINSIC
1815 #if defined(_MSC_VER) && !defined(__clang__)
1816 return _byteswap_ushort(n);
1817 #elif defined(__GNUC__) || defined(__clang__)
1818 return __builtin_bswap16(n);
1819 #elif defined(__WATCOMC__) && defined(__386__)
1820 return _watcom_bswap16(n);
1821 #else
1822 #error "This compiler does not support the byte swap intrinsic."
1823 #endif
1824 #else
1825 return ((n & 0xFF00) >> 8) |
1826 ((n & 0x00FF) << 8);
1827 #endif
1828 }
1829
1830 static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
1831 {
1832 #ifdef DRFLAC_HAS_BYTESWAP32_INTRINSIC
1833 #if defined(_MSC_VER) && !defined(__clang__)
1834 return _byteswap_ulong(n);
1835 #elif defined(__GNUC__) || defined(__clang__)
1836 #if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
1837 /* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */
1838 drflac_uint32 r;
1839 __asm__ __volatile__ (
1840 #if defined(DRFLAC_64BIT)
1841 "rev %w[out], %w[in]" : [out]"=r"(r) : [in]"r"(n) /* <-- This is untested. If someone in the community could test this, that would be appreciated! */
1842 #else
1843 "rev %[out], %[in]" : [out]"=r"(r) : [in]"r"(n)
1844 #endif
1845 );
1846 return r;
1847 #else
1848 return __builtin_bswap32(n);
1849 #endif
1850 #elif defined(__WATCOMC__) && defined(__386__)
1851 return _watcom_bswap32(n);
1852 #else
1853 #error "This compiler does not support the byte swap intrinsic."
1854 #endif
1855 #else
1856 return ((n & 0xFF000000) >> 24) |
1857 ((n & 0x00FF0000) >> 8) |
1858 ((n & 0x0000FF00) << 8) |
1859 ((n & 0x000000FF) << 24);
1860 #endif
1861 }
1862
1863 static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n)
1864 {
1865 #ifdef DRFLAC_HAS_BYTESWAP64_INTRINSIC
1866 #if defined(_MSC_VER) && !defined(__clang__)
1867 return _byteswap_uint64(n);
1868 #elif defined(__GNUC__) || defined(__clang__)
1869 return __builtin_bswap64(n);
1870 #elif defined(__WATCOMC__) && defined(__386__)
1871 return _watcom_bswap64(n);
1872 #else
1873 #error "This compiler does not support the byte swap intrinsic."
1874 #endif
1875 #else
1876 /* Weird "<< 32" bitshift is required for C89 because it doesn't support 64-bit constants. Should be optimized out by a good compiler. */
1877 return ((n & ((drflac_uint64)0xFF000000 << 32)) >> 56) |
1878 ((n & ((drflac_uint64)0x00FF0000 << 32)) >> 40) |
1879 ((n & ((drflac_uint64)0x0000FF00 << 32)) >> 24) |
1880 ((n & ((drflac_uint64)0x000000FF << 32)) >> 8) |
1881 ((n & ((drflac_uint64)0xFF000000 )) << 8) |
1882 ((n & ((drflac_uint64)0x00FF0000 )) << 24) |
1883 ((n & ((drflac_uint64)0x0000FF00 )) << 40) |
1884 ((n & ((drflac_uint64)0x000000FF )) << 56);
1885 #endif
1886 }
1887
1888
1889 static DRFLAC_INLINE drflac_uint16 drflac__be2host_16(drflac_uint16 n)
1890 {
1891 if (drflac__is_little_endian()) {
1892 return drflac__swap_endian_uint16(n);
1893 }
1894
1895 return n;
1896 }
1897
1898 static DRFLAC_INLINE drflac_uint32 drflac__be2host_32(drflac_uint32 n)
1899 {
1900 if (drflac__is_little_endian()) {
1901 return drflac__swap_endian_uint32(n);
1902 }
1903
1904 return n;
1905 }
1906
1907 static DRFLAC_INLINE drflac_uint32 drflac__be2host_32_ptr_unaligned(const void* pData)
1908 {
1909 const drflac_uint8* pNum = (drflac_uint8*)pData;
1910 return *(pNum) << 24 | *(pNum+1) << 16 | *(pNum+2) << 8 | *(pNum+3);
1911 }
1912
1913 static DRFLAC_INLINE drflac_uint64 drflac__be2host_64(drflac_uint64 n)
1914 {
1915 if (drflac__is_little_endian()) {
1916 return drflac__swap_endian_uint64(n);
1917 }
1918
1919 return n;
1920 }
1921
1922
1923 static DRFLAC_INLINE drflac_uint32 drflac__le2host_32(drflac_uint32 n)
1924 {
1925 if (!drflac__is_little_endian()) {
1926 return drflac__swap_endian_uint32(n);
1927 }
1928
1929 return n;
1930 }
1931
1932 static DRFLAC_INLINE drflac_uint32 drflac__le2host_32_ptr_unaligned(const void* pData)
1933 {
1934 const drflac_uint8* pNum = (drflac_uint8*)pData;
1935 return *pNum | *(pNum+1) << 8 | *(pNum+2) << 16 | *(pNum+3) << 24;
1936 }
1937
1938
1939 static DRFLAC_INLINE drflac_uint32 drflac__unsynchsafe_32(drflac_uint32 n)
1940 {
1941 drflac_uint32 result = 0;
1942 result |= (n & 0x7F000000) >> 3;
1943 result |= (n & 0x007F0000) >> 2;
1944 result |= (n & 0x00007F00) >> 1;
1945 result |= (n & 0x0000007F) >> 0;
1946
1947 return result;
1948 }
1949
1950
1951
1952 /* The CRC code below is based on this document: http://zlib.net/crc_v3.txt */
1953 static drflac_uint8 drflac__crc8_table[] = {
1954 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
1955 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
1956 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
1957 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
1958 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
1959 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
1960 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
1961 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
1962 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
1963 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
1964 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
1965 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
1966 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
1967 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
1968 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
1969 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
1970 };
1971
1972 static drflac_uint16 drflac__crc16_table[] = {
1973 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
1974 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
1975 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
1976 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
1977 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
1978 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
1979 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
1980 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
1981 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
1982 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
1983 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
1984 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
1985 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
1986 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
1987 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
1988 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
1989 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
1990 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
1991 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
1992 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
1993 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
1994 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
1995 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
1996 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
1997 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
1998 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
1999 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
2000 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
2001 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
2002 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
2003 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
2004 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
2005 };
2006
2007 static DRFLAC_INLINE drflac_uint8 drflac_crc8_byte(drflac_uint8 crc, drflac_uint8 data)
2008 {
2009 return drflac__crc8_table[crc ^ data];
2010 }
2011
2012 static DRFLAC_INLINE drflac_uint8 drflac_crc8(drflac_uint8 crc, drflac_uint32 data, drflac_uint32 count)
2013 {
2014 #ifdef DR_FLAC_NO_CRC
2015 (void)crc;
2016 (void)data;
2017 (void)count;
2018 return 0;
2019 #else
2020 #if 0
2021 /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc8(crc, 0, 8);") */
2022 drflac_uint8 p = 0x07;
2023 for (int i = count-1; i >= 0; --i) {
2024 drflac_uint8 bit = (data & (1 << i)) >> i;
2025 if (crc & 0x80) {
2026 crc = ((crc << 1) | bit) ^ p;
2027 } else {
2028 crc = ((crc << 1) | bit);
2029 }
2030 }
2031 return crc;
2032 #else
2033 drflac_uint32 wholeBytes;
2034 drflac_uint32 leftoverBits;
2035 drflac_uint64 leftoverDataMask;
2036
2037 static drflac_uint64 leftoverDataMaskTable[8] = {
2038 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
2039 };
2040
2041 DRFLAC_ASSERT(count <= 32);
2042
2043 wholeBytes = count >> 3;
2044 leftoverBits = count - (wholeBytes*8);
2045 leftoverDataMask = leftoverDataMaskTable[leftoverBits];
2046
2047 switch (wholeBytes) {
2048 case 4: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
2049 case 3: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
2050 case 2: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
2051 case 1: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
2052 case 0: if (leftoverBits > 0) crc = (drflac_uint8)((crc << leftoverBits) ^ drflac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)]);
2053 }
2054 return crc;
2055 #endif
2056 #endif
2057 }
2058
2059 static DRFLAC_INLINE drflac_uint16 drflac_crc16_byte(drflac_uint16 crc, drflac_uint8 data)
2060 {
2061 return (crc << 8) ^ drflac__crc16_table[(drflac_uint8)(crc >> 8) ^ data];
2062 }
2063
2064 static DRFLAC_INLINE drflac_uint16 drflac_crc16_cache(drflac_uint16 crc, drflac_cache_t data)
2065 {
2066 #ifdef DRFLAC_64BIT
2067 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
2068 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
2069 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
2070 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
2071 #endif
2072 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
2073 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
2074 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF));
2075 crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF));
2076
2077 return crc;
2078 }
2079
2080 static DRFLAC_INLINE drflac_uint16 drflac_crc16_bytes(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 byteCount)
2081 {
2082 switch (byteCount)
2083 {
2084 #ifdef DRFLAC_64BIT
2085 case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
2086 case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
2087 case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
2088 case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
2089 #endif
2090 case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
2091 case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
2092 case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF));
2093 case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF));
2094 }
2095
2096 return crc;
2097 }
2098
2099 #if 0
2100 static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac_uint32 data, drflac_uint32 count)
2101 {
2102 #ifdef DR_FLAC_NO_CRC
2103 (void)crc;
2104 (void)data;
2105 (void)count;
2106 return 0;
2107 #else
2108 #if 0
2109 /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc16(crc, 0, 16);") */
2110 drflac_uint16 p = 0x8005;
2111 for (int i = count-1; i >= 0; --i) {
2112 drflac_uint16 bit = (data & (1ULL << i)) >> i;
2113 if (r & 0x8000) {
2114 r = ((r << 1) | bit) ^ p;
2115 } else {
2116 r = ((r << 1) | bit);
2117 }
2118 }
2119
2120 return crc;
2121 #else
2122 drflac_uint32 wholeBytes;
2123 drflac_uint32 leftoverBits;
2124 drflac_uint64 leftoverDataMask;
2125
2126 static drflac_uint64 leftoverDataMaskTable[8] = {
2127 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
2128 };
2129
2130 DRFLAC_ASSERT(count <= 64);
2131
2132 wholeBytes = count >> 3;
2133 leftoverBits = count & 7;
2134 leftoverDataMask = leftoverDataMaskTable[leftoverBits];
2135
2136 switch (wholeBytes) {
2137 default:
2138 case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
2139 case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
2140 case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
2141 case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
2142 case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
2143 }
2144 return crc;
2145 #endif
2146 #endif
2147 }
2148
2149 static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac_uint64 data, drflac_uint32 count)
2150 {
2151 #ifdef DR_FLAC_NO_CRC
2152 (void)crc;
2153 (void)data;
2154 (void)count;
2155 return 0;
2156 #else
2157 drflac_uint32 wholeBytes;
2158 drflac_uint32 leftoverBits;
2159 drflac_uint64 leftoverDataMask;
2160
2161 static drflac_uint64 leftoverDataMaskTable[8] = {
2162 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
2163 };
2164
2165 DRFLAC_ASSERT(count <= 64);
2166
2167 wholeBytes = count >> 3;
2168 leftoverBits = count & 7;
2169 leftoverDataMask = leftoverDataMaskTable[leftoverBits];
2170
2171 switch (wholeBytes) {
2172 default:
2173 case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 << 32) << leftoverBits)) >> (56 + leftoverBits))); /* Weird "<< 32" bitshift is required for C89 because it doesn't support 64-bit constants. Should be optimized out by a good compiler. */
2174 case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 << 32) << leftoverBits)) >> (48 + leftoverBits)));
2175 case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 << 32) << leftoverBits)) >> (40 + leftoverBits)));
2176 case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF << 32) << leftoverBits)) >> (32 + leftoverBits)));
2177 case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 ) << leftoverBits)) >> (24 + leftoverBits)));
2178 case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 ) << leftoverBits)) >> (16 + leftoverBits)));
2179 case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 ) << leftoverBits)) >> ( 8 + leftoverBits)));
2180 case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF ) << leftoverBits)) >> ( 0 + leftoverBits)));
2181 case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
2182 }
2183 return crc;
2184 #endif
2185 }
2186
2187
2188 static DRFLAC_INLINE drflac_uint16 drflac_crc16(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 count)
2189 {
2190 #ifdef DRFLAC_64BIT
2191 return drflac_crc16__64bit(crc, data, count);
2192 #else
2193 return drflac_crc16__32bit(crc, data, count);
2194 #endif
2195 }
2196 #endif
2197
2198
2199 #ifdef DRFLAC_64BIT
2200 #define drflac__be2host__cache_line drflac__be2host_64
2201 #else
2202 #define drflac__be2host__cache_line drflac__be2host_32
2203 #endif
2204
2205 /*
2206 BIT READING ATTEMPT #2
2207
2208 This uses a 32- or 64-bit bit-shifted cache - as bits are read, the cache is shifted such that the first valid bit is sitting
2209 on the most significant bit. It uses the notion of an L1 and L2 cache (borrowed from CPU architecture), where the L1 cache
2210 is a 32- or 64-bit unsigned integer (depending on whether or not a 32- or 64-bit build is being compiled) and the L2 is an
2211 array of "cache lines", with each cache line being the same size as the L1. The L2 is a buffer of about 4KB and is where data
2212 from onRead() is read into.
2213 */
2214 #define DRFLAC_CACHE_L1_SIZE_BYTES(bs) (sizeof((bs)->cache))
2215 #define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8)
2216 #define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (bs)->consumedBits)
2217 #define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~((~(drflac_cache_t)0) >> (_bitCount)))
2218 #define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
2219 #define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount))
2220 #define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)))
2221 #define DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, _bitCount)(DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> (DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)) & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1)))
2222 #define DRFLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2))
2223 #define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
2224 #define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
2225
2226
2227 #ifndef DR_FLAC_NO_CRC
2228 static DRFLAC_INLINE void drflac__reset_crc16(drflac_bs* bs)
2229 {
2230 bs->crc16 = 0;
2231 bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
2232 }
2233
2234 static DRFLAC_INLINE void drflac__update_crc16(drflac_bs* bs)
2235 {
2236 if (bs->crc16CacheIgnoredBytes == 0) {
2237 bs->crc16 = drflac_crc16_cache(bs->crc16, bs->crc16Cache);
2238 } else {
2239 bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache, DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bs->crc16CacheIgnoredBytes);
2240 bs->crc16CacheIgnoredBytes = 0;
2241 }
2242 }
2243
2244 static DRFLAC_INLINE drflac_uint16 drflac__flush_crc16(drflac_bs* bs)
2245 {
2246 /* We should never be flushing in a situation where we are not aligned on a byte boundary. */
2247 DRFLAC_ASSERT((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0);
2248
2249 /*
2250 The bits that were read from the L1 cache need to be accumulated. The number of bytes needing to be accumulated is determined
2251 by the number of bits that have been consumed.
2252 */
2253 if (DRFLAC_CACHE_L1_BITS_REMAINING(bs) == 0) {
2254 drflac__update_crc16(bs);
2255 } else {
2256 /* We only accumulate the consumed bits. */
2257 bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache >> DRFLAC_CACHE_L1_BITS_REMAINING(bs), (bs->consumedBits >> 3) - bs->crc16CacheIgnoredBytes);
2258
2259 /*
2260 The bits that we just accumulated should never be accumulated again. We need to keep track of how many bytes were accumulated
2261 so we can handle that later.
2262 */
2263 bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
2264 }
2265
2266 return bs->crc16;
2267 }
2268 #endif
2269
2270 static DRFLAC_INLINE drflac_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs)
2271 {
2272 size_t bytesRead;
2273 size_t alignedL1LineCount;
2274
2275 /* Fast path. Try loading straight from L2. */
2276 if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
2277 bs->cache = bs->cacheL2[bs->nextL2Line++];
2278 return DRFLAC_TRUE;
2279 }
2280
2281 /*
2282 If we get here it means we've run out of data in the L2 cache. We'll need to fetch more from the client, if there's
2283 any left.
2284 */
2285 if (bs->unalignedByteCount > 0) {
2286 return DRFLAC_FALSE; /* If we have any unaligned bytes it means there's no more aligned bytes left in the client. */
2287 }
2288
2289 bytesRead = bs->onRead(bs->pUserData, bs->cacheL2, DRFLAC_CACHE_L2_SIZE_BYTES(bs));
2290
2291 bs->nextL2Line = 0;
2292 if (bytesRead == DRFLAC_CACHE_L2_SIZE_BYTES(bs)) {
2293 bs->cache = bs->cacheL2[bs->nextL2Line++];
2294 return DRFLAC_TRUE;
2295 }
2296
2297
2298 /*
2299 If we get here it means we were unable to retrieve enough data to fill the entire L2 cache. It probably
2300 means we've just reached the end of the file. We need to move the valid data down to the end of the buffer
2301 and adjust the index of the next line accordingly. Also keep in mind that the L2 cache must be aligned to
2302 the size of the L1 so we'll need to seek backwards by any misaligned bytes.
2303 */
2304 alignedL1LineCount = bytesRead / DRFLAC_CACHE_L1_SIZE_BYTES(bs);
2305
2306 /* We need to keep track of any unaligned bytes for later use. */
2307 bs->unalignedByteCount = bytesRead - (alignedL1LineCount * DRFLAC_CACHE_L1_SIZE_BYTES(bs));
2308 if (bs->unalignedByteCount > 0) {
2309 bs->unalignedCache = bs->cacheL2[alignedL1LineCount];
2310 }
2311
2312 if (alignedL1LineCount > 0) {
2313 size_t offset = DRFLAC_CACHE_L2_LINE_COUNT(bs) - alignedL1LineCount;
2314 size_t i;
2315 for (i = alignedL1LineCount; i > 0; --i) {
2316 bs->cacheL2[i-1 + offset] = bs->cacheL2[i-1];
2317 }
2318
2319 bs->nextL2Line = (drflac_uint32)offset;
2320 bs->cache = bs->cacheL2[bs->nextL2Line++];
2321 return DRFLAC_TRUE;
2322 } else {
2323 /* If we get into this branch it means we weren't able to load any L1-aligned data. */
2324 bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs);
2325 return DRFLAC_FALSE;
2326 }
2327 }
2328
2329 static drflac_bool32 drflac__reload_cache(drflac_bs* bs)
2330 {
2331 size_t bytesRead;
2332
2333 #ifndef DR_FLAC_NO_CRC
2334 drflac__update_crc16(bs);
2335 #endif
2336
2337 /* Fast path. Try just moving the next value in the L2 cache to the L1 cache. */
2338 if (drflac__reload_l1_cache_from_l2(bs)) {
2339 bs->cache = drflac__be2host__cache_line(bs->cache);
2340 bs->consumedBits = 0;
2341 #ifndef DR_FLAC_NO_CRC
2342 bs->crc16Cache = bs->cache;
2343 #endif
2344 return DRFLAC_TRUE;
2345 }
2346
2347 /* Slow path. */
2348
2349 /*
2350 If we get here it means we have failed to load the L1 cache from the L2. Likely we've just reached the end of the stream and the last
2351 few bytes did not meet the alignment requirements for the L2 cache. In this case we need to fall back to a slower path and read the
2352 data from the unaligned cache.
2353 */
2354 bytesRead = bs->unalignedByteCount;
2355 if (bytesRead == 0) {
2356 bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); /* <-- The stream has been exhausted, so marked the bits as consumed. */
2357 return DRFLAC_FALSE;
2358 }
2359
2360 DRFLAC_ASSERT(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
2361 bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
2362
2363 bs->cache = drflac__be2host__cache_line(bs->unalignedCache);
2364 bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(DRFLAC_CACHE_L1_BITS_REMAINING(bs)); /* <-- Make sure the consumed bits are always set to zero. Other parts of the library depend on this property. */
2365 bs->unalignedByteCount = 0; /* <-- At this point the unaligned bytes have been moved into the cache and we thus have no more unaligned bytes. */
2366
2367 #ifndef DR_FLAC_NO_CRC
2368 bs->crc16Cache = bs->cache >> bs->consumedBits;
2369 bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
2370 #endif
2371 return DRFLAC_TRUE;
2372 }
2373
2374 static void drflac__reset_cache(drflac_bs* bs)
2375 {
2376 bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs); /* <-- This clears the L2 cache. */
2377 bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); /* <-- This clears the L1 cache. */
2378 bs->cache = 0;
2379 bs->unalignedByteCount = 0; /* <-- This clears the trailing unaligned bytes. */
2380 bs->unalignedCache = 0;
2381
2382 #ifndef DR_FLAC_NO_CRC
2383 bs->crc16Cache = 0;
2384 bs->crc16CacheIgnoredBytes = 0;
2385 #endif
2386 }
2387
2388
2389 static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, drflac_uint32* pResultOut)
2390 {
2391 DRFLAC_ASSERT(bs != NULL);
2392 DRFLAC_ASSERT(pResultOut != NULL);
2393 DRFLAC_ASSERT(bitCount > 0);
2394 DRFLAC_ASSERT(bitCount <= 32);
2395
2396 if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2397 if (!drflac__reload_cache(bs)) {
2398 return DRFLAC_FALSE;
2399 }
2400 }
2401
2402 if (bitCount <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2403 /*
2404 If we want to load all 32-bits from a 32-bit cache we need to do it slightly differently because we can't do
2405 a 32-bit shift on a 32-bit integer. This will never be the case on 64-bit caches, so we can have a slightly
2406 more optimal solution for this.
2407 */
2408 #ifdef DRFLAC_64BIT
2409 *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
2410 bs->consumedBits += bitCount;
2411 bs->cache <<= bitCount;
2412 #else
2413 if (bitCount < DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2414 *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
2415 bs->consumedBits += bitCount;
2416 bs->cache <<= bitCount;
2417 } else {
2418 /* Cannot shift by 32-bits, so need to do it differently. */
2419 *pResultOut = (drflac_uint32)bs->cache;
2420 bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs);
2421 bs->cache = 0;
2422 }
2423 #endif
2424
2425 return DRFLAC_TRUE;
2426 } else {
2427 /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */
2428 drflac_uint32 bitCountHi = DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2429 drflac_uint32 bitCountLo = bitCount - bitCountHi;
2430 drflac_uint32 resultHi;
2431
2432 DRFLAC_ASSERT(bitCountHi > 0);
2433 DRFLAC_ASSERT(bitCountHi < 32);
2434 resultHi = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi);
2435
2436 if (!drflac__reload_cache(bs)) {
2437 return DRFLAC_FALSE;
2438 }
2439 if (bitCountLo > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2440 /* This happens when we get to end of stream */
2441 return DRFLAC_FALSE;
2442 }
2443
2444 *pResultOut = (resultHi << bitCountLo) | (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo);
2445 bs->consumedBits += bitCountLo;
2446 bs->cache <<= bitCountLo;
2447 return DRFLAC_TRUE;
2448 }
2449 }
2450
2451 static drflac_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, drflac_int32* pResult)
2452 {
2453 drflac_uint32 result;
2454
2455 DRFLAC_ASSERT(bs != NULL);
2456 DRFLAC_ASSERT(pResult != NULL);
2457 DRFLAC_ASSERT(bitCount > 0);
2458 DRFLAC_ASSERT(bitCount <= 32);
2459
2460 if (!drflac__read_uint32(bs, bitCount, &result)) {
2461 return DRFLAC_FALSE;
2462 }
2463
2464 /* Do not attempt to shift by 32 as it's undefined. */
2465 if (bitCount < 32) {
2466 drflac_uint32 signbit;
2467 signbit = ((result >> (bitCount-1)) & 0x01);
2468 result |= (~signbit + 1) << bitCount;
2469 }
2470
2471 *pResult = (drflac_int32)result;
2472 return DRFLAC_TRUE;
2473 }
2474
2475 #ifdef DRFLAC_64BIT
2476 static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, drflac_uint64* pResultOut)
2477 {
2478 drflac_uint32 resultHi;
2479 drflac_uint32 resultLo;
2480
2481 DRFLAC_ASSERT(bitCount <= 64);
2482 DRFLAC_ASSERT(bitCount > 32);
2483
2484 if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) {
2485 return DRFLAC_FALSE;
2486 }
2487
2488 if (!drflac__read_uint32(bs, 32, &resultLo)) {
2489 return DRFLAC_FALSE;
2490 }
2491
2492 *pResultOut = (((drflac_uint64)resultHi) << 32) | ((drflac_uint64)resultLo);
2493 return DRFLAC_TRUE;
2494 }
2495 #endif
2496
2497 /* Function below is unused, but leaving it here in case I need to quickly add it again. */
2498 #if 0
2499 static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, drflac_int64* pResultOut)
2500 {
2501 drflac_uint64 result;
2502 drflac_uint64 signbit;
2503
2504 DRFLAC_ASSERT(bitCount <= 64);
2505
2506 if (!drflac__read_uint64(bs, bitCount, &result)) {
2507 return DRFLAC_FALSE;
2508 }
2509
2510 signbit = ((result >> (bitCount-1)) & 0x01);
2511 result |= (~signbit + 1) << bitCount;
2512
2513 *pResultOut = (drflac_int64)result;
2514 return DRFLAC_TRUE;
2515 }
2516 #endif
2517
2518 static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, drflac_uint16* pResult)
2519 {
2520 drflac_uint32 result;
2521
2522 DRFLAC_ASSERT(bs != NULL);
2523 DRFLAC_ASSERT(pResult != NULL);
2524 DRFLAC_ASSERT(bitCount > 0);
2525 DRFLAC_ASSERT(bitCount <= 16);
2526
2527 if (!drflac__read_uint32(bs, bitCount, &result)) {
2528 return DRFLAC_FALSE;
2529 }
2530
2531 *pResult = (drflac_uint16)result;
2532 return DRFLAC_TRUE;
2533 }
2534
2535 #if 0
2536 static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, drflac_int16* pResult)
2537 {
2538 drflac_int32 result;
2539
2540 DRFLAC_ASSERT(bs != NULL);
2541 DRFLAC_ASSERT(pResult != NULL);
2542 DRFLAC_ASSERT(bitCount > 0);
2543 DRFLAC_ASSERT(bitCount <= 16);
2544
2545 if (!drflac__read_int32(bs, bitCount, &result)) {
2546 return DRFLAC_FALSE;
2547 }
2548
2549 *pResult = (drflac_int16)result;
2550 return DRFLAC_TRUE;
2551 }
2552 #endif
2553
2554 static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, drflac_uint8* pResult)
2555 {
2556 drflac_uint32 result;
2557
2558 DRFLAC_ASSERT(bs != NULL);
2559 DRFLAC_ASSERT(pResult != NULL);
2560 DRFLAC_ASSERT(bitCount > 0);
2561 DRFLAC_ASSERT(bitCount <= 8);
2562
2563 if (!drflac__read_uint32(bs, bitCount, &result)) {
2564 return DRFLAC_FALSE;
2565 }
2566
2567 *pResult = (drflac_uint8)result;
2568 return DRFLAC_TRUE;
2569 }
2570
2571 static drflac_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, drflac_int8* pResult)
2572 {
2573 drflac_int32 result;
2574
2575 DRFLAC_ASSERT(bs != NULL);
2576 DRFLAC_ASSERT(pResult != NULL);
2577 DRFLAC_ASSERT(bitCount > 0);
2578 DRFLAC_ASSERT(bitCount <= 8);
2579
2580 if (!drflac__read_int32(bs, bitCount, &result)) {
2581 return DRFLAC_FALSE;
2582 }
2583
2584 *pResult = (drflac_int8)result;
2585 return DRFLAC_TRUE;
2586 }
2587
2588
2589 static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek)
2590 {
2591 if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2592 bs->consumedBits += (drflac_uint32)bitsToSeek;
2593 bs->cache <<= bitsToSeek;
2594 return DRFLAC_TRUE;
2595 } else {
2596 /* It straddles the cached data. This function isn't called too frequently so I'm favouring simplicity here. */
2597 bitsToSeek -= DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2598 bs->consumedBits += DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2599 bs->cache = 0;
2600
2601 /* Simple case. Seek in groups of the same number as bits that fit within a cache line. */
2602 #ifdef DRFLAC_64BIT
2603 while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2604 drflac_uint64 bin;
2605 if (!drflac__read_uint64(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
2606 return DRFLAC_FALSE;
2607 }
2608 bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
2609 }
2610 #else
2611 while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2612 drflac_uint32 bin;
2613 if (!drflac__read_uint32(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
2614 return DRFLAC_FALSE;
2615 }
2616 bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
2617 }
2618 #endif
2619
2620 /* Whole leftover bytes. */
2621 while (bitsToSeek >= 8) {
2622 drflac_uint8 bin;
2623 if (!drflac__read_uint8(bs, 8, &bin)) {
2624 return DRFLAC_FALSE;
2625 }
2626 bitsToSeek -= 8;
2627 }
2628
2629 /* Leftover bits. */
2630 if (bitsToSeek > 0) {
2631 drflac_uint8 bin;
2632 if (!drflac__read_uint8(bs, (drflac_uint32)bitsToSeek, &bin)) {
2633 return DRFLAC_FALSE;
2634 }
2635 bitsToSeek = 0; /* <-- Necessary for the assert below. */
2636 }
2637
2638 DRFLAC_ASSERT(bitsToSeek == 0);
2639 return DRFLAC_TRUE;
2640 }
2641 }
2642
2643
2644 /* This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16. */
2645 static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
2646 {
2647 DRFLAC_ASSERT(bs != NULL);
2648
2649 /*
2650 The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first
2651 thing to do is align to the next byte.
2652 */
2653 if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
2654 return DRFLAC_FALSE;
2655 }
2656
2657 for (;;) {
2658 drflac_uint8 hi;
2659
2660 #ifndef DR_FLAC_NO_CRC
2661 drflac__reset_crc16(bs);
2662 #endif
2663
2664 if (!drflac__read_uint8(bs, 8, &hi)) {
2665 return DRFLAC_FALSE;
2666 }
2667
2668 if (hi == 0xFF) {
2669 drflac_uint8 lo;
2670 if (!drflac__read_uint8(bs, 6, &lo)) {
2671 return DRFLAC_FALSE;
2672 }
2673
2674 if (lo == 0x3E) {
2675 return DRFLAC_TRUE;
2676 } else {
2677 if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
2678 return DRFLAC_FALSE;
2679 }
2680 }
2681 }
2682 }
2683
2684 /* Should never get here. */
2685 /*return DRFLAC_FALSE;*/
2686 }
2687
2688
2689 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
2690 #define DRFLAC_IMPLEMENT_CLZ_LZCNT
2691 #endif
2692 #if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(__clang__)
2693 #define DRFLAC_IMPLEMENT_CLZ_MSVC
2694 #endif
2695 #if defined(__WATCOMC__) && defined(__386__)
2696 #define DRFLAC_IMPLEMENT_CLZ_WATCOM
2697 #endif
2698
2699 static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x)
2700 {
2701 drflac_uint32 n;
2702 static drflac_uint32 clz_table_4[] = {
2703 0,
2704 4,
2705 3, 3,
2706 2, 2, 2, 2,
2707 1, 1, 1, 1, 1, 1, 1, 1
2708 };
2709
2710 if (x == 0) {
2711 return sizeof(x)*8;
2712 }
2713
2714 n = clz_table_4[x >> (sizeof(x)*8 - 4)];
2715 if (n == 0) {
2716 #ifdef DRFLAC_64BIT
2717 if ((x & ((drflac_uint64)0xFFFFFFFF << 32)) == 0) { n = 32; x <<= 32; }
2718 if ((x & ((drflac_uint64)0xFFFF0000 << 32)) == 0) { n += 16; x <<= 16; }
2719 if ((x & ((drflac_uint64)0xFF000000 << 32)) == 0) { n += 8; x <<= 8; }
2720 if ((x & ((drflac_uint64)0xF0000000 << 32)) == 0) { n += 4; x <<= 4; }
2721 #else
2722 if ((x & 0xFFFF0000) == 0) { n = 16; x <<= 16; }
2723 if ((x & 0xFF000000) == 0) { n += 8; x <<= 8; }
2724 if ((x & 0xF0000000) == 0) { n += 4; x <<= 4; }
2725 #endif
2726 n += clz_table_4[x >> (sizeof(x)*8 - 4)];
2727 }
2728
2729 return n - 1;
2730 }
2731
2732 #ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
2733 static DRFLAC_INLINE drflac_bool32 drflac__is_lzcnt_supported(void)
2734 {
2735 /* Fast compile time check for ARM. */
2736 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
2737 return DRFLAC_TRUE;
2738 #else
2739 /* If the compiler itself does not support the intrinsic then we'll need to return false. */
2740 #ifdef DRFLAC_HAS_LZCNT_INTRINSIC
2741 return drflac__gIsLZCNTSupported;
2742 #else
2743 return DRFLAC_FALSE;
2744 #endif
2745 #endif
2746 }
2747
2748 static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
2749 {
2750 /*
2751 It's critical for competitive decoding performance that this function be highly optimal. With MSVC we can use the __lzcnt64() and __lzcnt() intrinsics
2752 to achieve good performance, however on GCC and Clang it's a little bit more annoying. The __builtin_clzl() and __builtin_clzll() intrinsics leave
2753 it undefined as to the return value when `x` is 0. We need this to be well defined as returning 32 or 64, depending on whether or not it's a 32- or
2754 64-bit build. To work around this we would need to add a conditional to check for the x = 0 case, but this creates unnecessary inefficiency. To work
2755 around this problem I have written some inline assembly to emit the LZCNT (x86) or CLZ (ARM) instruction directly which removes the need to include
2756 the conditional. This has worked well in the past, but for some reason Clang's MSVC compatible driver, clang-cl, does not seem to be handling this
2757 in the same way as the normal Clang driver. It seems that `clang-cl` is just outputting the wrong results sometimes, maybe due to some register
2758 getting clobbered?
2759
2760 I'm not sure if this is a bug with dr_flac's inlined assembly (most likely), a bug in `clang-cl` or just a misunderstanding on my part with inline
2761 assembly rules for `clang-cl`. If somebody can identify an error in dr_flac's inlined assembly I'm happy to get that fixed.
2762
2763 Fortunately there is an easy workaround for this. Clang implements MSVC-specific intrinsics for compatibility. It also defines _MSC_VER for extra
2764 compatibility. We can therefore just check for _MSC_VER and use the MSVC intrinsic which, fortunately for us, Clang supports. It would still be nice
2765 to know how to fix the inlined assembly for correctness sake, however.
2766 */
2767
2768 #if defined(_MSC_VER) /*&& !defined(__clang__)*/ /* <-- Intentionally wanting Clang to use the MSVC __lzcnt64/__lzcnt intrinsics due to above ^. */
2769 #ifdef DRFLAC_64BIT
2770 return (drflac_uint32)__lzcnt64(x);
2771 #else
2772 return (drflac_uint32)__lzcnt(x);
2773 #endif
2774 #else
2775 #if defined(__GNUC__) || defined(__clang__)
2776 #if defined(DRFLAC_X64)
2777 {
2778 drflac_uint64 r;
2779 __asm__ __volatile__ (
2780 "lzcnt{ %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
2781 );
2782
2783 return (drflac_uint32)r;
2784 }
2785 #elif defined(DRFLAC_X86)
2786 {
2787 drflac_uint32 r;
2788 __asm__ __volatile__ (
2789 "lzcnt{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
2790 );
2791
2792 return r;
2793 }
2794 #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
2795 {
2796 unsigned int r;
2797 __asm__ __volatile__ (
2798 #if defined(DRFLAC_64BIT)
2799 "clz %w[out], %w[in]" : [out]"=r"(r) : [in]"r"(x) /* <-- This is untested. If someone in the community could test this, that would be appreciated! */
2800 #else
2801 "clz %[out], %[in]" : [out]"=r"(r) : [in]"r"(x)
2802 #endif
2803 );
2804
2805 return r;
2806 }
2807 #else
2808 if (x == 0) {
2809 return sizeof(x)*8;
2810 }
2811 #ifdef DRFLAC_64BIT
2812 return (drflac_uint32)__builtin_clzll((drflac_uint64)x);
2813 #else
2814 return (drflac_uint32)__builtin_clzl((drflac_uint32)x);
2815 #endif
2816 #endif
2817 #else
2818 /* Unsupported compiler. */
2819 #error "This compiler does not support the lzcnt intrinsic."
2820 #endif
2821 #endif
2822 }
2823 #endif
2824
2825 #ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
2826 #include <intrin.h> /* For BitScanReverse(). */
2827
2828 static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
2829 {
2830 drflac_uint32 n;
2831
2832 if (x == 0) {
2833 return sizeof(x)*8;
2834 }
2835
2836 #ifdef DRFLAC_64BIT
2837 _BitScanReverse64((unsigned long*)&n, x);
2838 #else
2839 _BitScanReverse((unsigned long*)&n, x);
2840 #endif
2841 return sizeof(x)*8 - n - 1;
2842 }
2843 #endif
2844
2845 #ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM
2846 static __inline drflac_uint32 drflac__clz_watcom (drflac_uint32);
2847 #pragma aux drflac__clz_watcom = \
2848 "bsr eax, eax" \
2849 "xor eax, 31" \
2850 parm [eax] nomemory \
2851 value [eax] \
2852 modify exact [eax] nomemory;
2853 #endif
2854
2855 static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
2856 {
2857 #ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
2858 if (drflac__is_lzcnt_supported()) {
2859 return drflac__clz_lzcnt(x);
2860 } else
2861 #endif
2862 {
2863 #ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
2864 return drflac__clz_msvc(x);
2865 #elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM)
2866 return (x == 0) ? sizeof(x)*8 : drflac__clz_watcom(x);
2867 #else
2868 return drflac__clz_software(x);
2869 #endif
2870 }
2871 }
2872
2873
2874 static DRFLAC_INLINE drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut)
2875 {
2876 drflac_uint32 zeroCounter = 0;
2877 drflac_uint32 setBitOffsetPlus1;
2878
2879 while (bs->cache == 0) {
2880 zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2881 if (!drflac__reload_cache(bs)) {
2882 return DRFLAC_FALSE;
2883 }
2884 }
2885
2886 if (bs->cache == 1) {
2887 /* Not catching this would lead to undefined behaviour: a shift of a 32-bit number by 32 or more is undefined */
2888 *pOffsetOut = zeroCounter + (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs) - 1;
2889 if (!drflac__reload_cache(bs)) {
2890 return DRFLAC_FALSE;
2891 }
2892
2893 return DRFLAC_TRUE;
2894 }
2895
2896 setBitOffsetPlus1 = drflac__clz(bs->cache);
2897 setBitOffsetPlus1 += 1;
2898
2899 if (setBitOffsetPlus1 > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2900 /* This happens when we get to end of stream */
2901 return DRFLAC_FALSE;
2902 }
2903
2904 bs->consumedBits += setBitOffsetPlus1;
2905 bs->cache <<= setBitOffsetPlus1;
2906
2907 *pOffsetOut = zeroCounter + setBitOffsetPlus1 - 1;
2908 return DRFLAC_TRUE;
2909 }
2910
2911
2912
2913 static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFromStart)
2914 {
2915 DRFLAC_ASSERT(bs != NULL);
2916 DRFLAC_ASSERT(offsetFromStart > 0);
2917
2918 /*
2919 Seeking from the start is not quite as trivial as it sounds because the onSeek callback takes a signed 32-bit integer (which
2920 is intentional because it simplifies the implementation of the onSeek callbacks), however offsetFromStart is unsigned 64-bit.
2921 To resolve we just need to do an initial seek from the start, and then a series of offset seeks to make up the remainder.
2922 */
2923 if (offsetFromStart > 0x7FFFFFFF) {
2924 drflac_uint64 bytesRemaining = offsetFromStart;
2925 if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
2926 return DRFLAC_FALSE;
2927 }
2928 bytesRemaining -= 0x7FFFFFFF;
2929
2930 while (bytesRemaining > 0x7FFFFFFF) {
2931 if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
2932 return DRFLAC_FALSE;
2933 }
2934 bytesRemaining -= 0x7FFFFFFF;
2935 }
2936
2937 if (bytesRemaining > 0) {
2938 if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, drflac_seek_origin_current)) {
2939 return DRFLAC_FALSE;
2940 }
2941 }
2942 } else {
2943 if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, drflac_seek_origin_start)) {
2944 return DRFLAC_FALSE;
2945 }
2946 }
2947
2948 /* The cache should be reset to force a reload of fresh data from the client. */
2949 drflac__reset_cache(bs);
2950 return DRFLAC_TRUE;
2951 }
2952
2953
2954 static drflac_result drflac__read_utf8_coded_number(drflac_bs* bs, drflac_uint64* pNumberOut, drflac_uint8* pCRCOut)
2955 {
2956 drflac_uint8 crc;
2957 drflac_uint64 result;
2958 drflac_uint8 utf8[7] = {0};
2959 int byteCount;
2960 int i;
2961
2962 DRFLAC_ASSERT(bs != NULL);
2963 DRFLAC_ASSERT(pNumberOut != NULL);
2964 DRFLAC_ASSERT(pCRCOut != NULL);
2965
2966 crc = *pCRCOut;
2967
2968 if (!drflac__read_uint8(bs, 8, utf8)) {
2969 *pNumberOut = 0;
2970 return DRFLAC_AT_END;
2971 }
2972 crc = drflac_crc8(crc, utf8[0], 8);
2973
2974 if ((utf8[0] & 0x80) == 0) {
2975 *pNumberOut = utf8[0];
2976 *pCRCOut = crc;
2977 return DRFLAC_SUCCESS;
2978 }
2979
2980 /*byteCount = 1;*/
2981 if ((utf8[0] & 0xE0) == 0xC0) {
2982 byteCount = 2;
2983 } else if ((utf8[0] & 0xF0) == 0xE0) {
2984 byteCount = 3;
2985 } else if ((utf8[0] & 0xF8) == 0xF0) {
2986 byteCount = 4;
2987 } else if ((utf8[0] & 0xFC) == 0xF8) {
2988 byteCount = 5;
2989 } else if ((utf8[0] & 0xFE) == 0xFC) {
2990 byteCount = 6;
2991 } else if ((utf8[0] & 0xFF) == 0xFE) {
2992 byteCount = 7;
2993 } else {
2994 *pNumberOut = 0;
2995 return DRFLAC_CRC_MISMATCH; /* Bad UTF-8 encoding. */
2996 }
2997
2998 /* Read extra bytes. */
2999 DRFLAC_ASSERT(byteCount > 1);
3000
3001 result = (drflac_uint64)(utf8[0] & (0xFF >> (byteCount + 1)));
3002 for (i = 1; i < byteCount; ++i) {
3003 if (!drflac__read_uint8(bs, 8, utf8 + i)) {
3004 *pNumberOut = 0;
3005 return DRFLAC_AT_END;
3006 }
3007 crc = drflac_crc8(crc, utf8[i], 8);
3008
3009 result = (result << 6) | (utf8[i] & 0x3F);
3010 }
3011
3012 *pNumberOut = result;
3013 *pCRCOut = crc;
3014 return DRFLAC_SUCCESS;
3015 }
3016
3017
3018 static DRFLAC_INLINE drflac_uint32 drflac__ilog2_u32(drflac_uint32 x)
3019 {
3020 #if 1 /* Needs optimizing. */
3021 drflac_uint32 result = 0;
3022 while (x > 0) {
3023 result += 1;
3024 x >>= 1;
3025 }
3026
3027 return result;
3028 #endif
3029 }
3030
3031 static DRFLAC_INLINE drflac_bool32 drflac__use_64_bit_prediction(drflac_uint32 bitsPerSample, drflac_uint32 order, drflac_uint32 precision)
3032 {
3033 /* https://web.archive.org/web/20220205005724/https://github.com/ietf-wg-cellar/flac-specification/blob/37a49aa48ba4ba12e8757badfc59c0df35435fec/rfc_backmatter.md */
3034 return bitsPerSample + precision + drflac__ilog2_u32(order) > 32;
3035 }
3036
3037
3038 /*
3039 The next two functions are responsible for calculating the prediction.
3040
3041 When the bits per sample is >16 we need to use 64-bit integer arithmetic because otherwise we'll run out of precision. It's
3042 safe to assume this will be slower on 32-bit platforms so we use a more optimal solution when the bits per sample is <=16.
3043 */
3044 #if defined(__clang__)
3045 __attribute__((no_sanitize("signed-integer-overflow")))
3046 #endif
3047 static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
3048 {
3049 drflac_int32 prediction = 0;
3050
3051 DRFLAC_ASSERT(order <= 32);
3052
3053 /* 32-bit version. */
3054
3055 /* VC++ optimizes this to a single jmp. I've not yet verified this for other compilers. */
3056 switch (order)
3057 {
3058 case 32: prediction += coefficients[31] * pDecodedSamples[-32];
3059 case 31: prediction += coefficients[30] * pDecodedSamples[-31];
3060 case 30: prediction += coefficients[29] * pDecodedSamples[-30];
3061 case 29: prediction += coefficients[28] * pDecodedSamples[-29];
3062 case 28: prediction += coefficients[27] * pDecodedSamples[-28];
3063 case 27: prediction += coefficients[26] * pDecodedSamples[-27];
3064 case 26: prediction += coefficients[25] * pDecodedSamples[-26];
3065 case 25: prediction += coefficients[24] * pDecodedSamples[-25];
3066 case 24: prediction += coefficients[23] * pDecodedSamples[-24];
3067 case 23: prediction += coefficients[22] * pDecodedSamples[-23];
3068 case 22: prediction += coefficients[21] * pDecodedSamples[-22];
3069 case 21: prediction += coefficients[20] * pDecodedSamples[-21];
3070 case 20: prediction += coefficients[19] * pDecodedSamples[-20];
3071 case 19: prediction += coefficients[18] * pDecodedSamples[-19];
3072 case 18: prediction += coefficients[17] * pDecodedSamples[-18];
3073 case 17: prediction += coefficients[16] * pDecodedSamples[-17];
3074 case 16: prediction += coefficients[15] * pDecodedSamples[-16];
3075 case 15: prediction += coefficients[14] * pDecodedSamples[-15];
3076 case 14: prediction += coefficients[13] * pDecodedSamples[-14];
3077 case 13: prediction += coefficients[12] * pDecodedSamples[-13];
3078 case 12: prediction += coefficients[11] * pDecodedSamples[-12];
3079 case 11: prediction += coefficients[10] * pDecodedSamples[-11];
3080 case 10: prediction += coefficients[ 9] * pDecodedSamples[-10];
3081 case 9: prediction += coefficients[ 8] * pDecodedSamples[- 9];
3082 case 8: prediction += coefficients[ 7] * pDecodedSamples[- 8];
3083 case 7: prediction += coefficients[ 6] * pDecodedSamples[- 7];
3084 case 6: prediction += coefficients[ 5] * pDecodedSamples[- 6];
3085 case 5: prediction += coefficients[ 4] * pDecodedSamples[- 5];
3086 case 4: prediction += coefficients[ 3] * pDecodedSamples[- 4];
3087 case 3: prediction += coefficients[ 2] * pDecodedSamples[- 3];
3088 case 2: prediction += coefficients[ 1] * pDecodedSamples[- 2];
3089 case 1: prediction += coefficients[ 0] * pDecodedSamples[- 1];
3090 }
3091
3092 return (drflac_int32)(prediction >> shift);
3093 }
3094
3095 static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
3096 {
3097 drflac_int64 prediction;
3098
3099 DRFLAC_ASSERT(order <= 32);
3100
3101 /* 64-bit version. */
3102
3103 /* This method is faster on the 32-bit build when compiling with VC++. See note below. */
3104 #ifndef DRFLAC_64BIT
3105 if (order == 8)
3106 {
3107 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3108 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3109 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3110 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3111 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3112 prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3113 prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3114 prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
3115 }
3116 else if (order == 7)
3117 {
3118 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3119 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3120 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3121 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3122 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3123 prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3124 prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3125 }
3126 else if (order == 3)
3127 {
3128 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3129 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3130 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3131 }
3132 else if (order == 6)
3133 {
3134 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3135 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3136 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3137 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3138 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3139 prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3140 }
3141 else if (order == 5)
3142 {
3143 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3144 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3145 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3146 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3147 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3148 }
3149 else if (order == 4)
3150 {
3151 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3152 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3153 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3154 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3155 }
3156 else if (order == 12)
3157 {
3158 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3159 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3160 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3161 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3162 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3163 prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3164 prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3165 prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
3166 prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
3167 prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
3168 prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
3169 prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
3170 }
3171 else if (order == 2)
3172 {
3173 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3174 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3175 }
3176 else if (order == 1)
3177 {
3178 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3179 }
3180 else if (order == 10)
3181 {
3182 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3183 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3184 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3185 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3186 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3187 prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3188 prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3189 prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
3190 prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
3191 prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
3192 }
3193 else if (order == 9)
3194 {
3195 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3196 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3197 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3198 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3199 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3200 prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3201 prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3202 prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
3203 prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
3204 }
3205 else if (order == 11)
3206 {
3207 prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3208 prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3209 prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3210 prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3211 prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3212 prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3213 prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3214 prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
3215 prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
3216 prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
3217 prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
3218 }
3219 else
3220 {
3221 int j;
3222
3223 prediction = 0;
3224 for (j = 0; j < (int)order; ++j) {
3225 prediction += coefficients[j] * (drflac_int64)pDecodedSamples[-j-1];
3226 }
3227 }
3228 #endif
3229
3230 /*
3231 VC++ optimizes this to a single jmp instruction, but only the 64-bit build. The 32-bit build generates less efficient code for some
3232 reason. The ugly version above is faster so we'll just switch between the two depending on the target platform.
3233 */
3234 #ifdef DRFLAC_64BIT
3235 prediction = 0;
3236 switch (order)
3237 {
3238 case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32];
3239 case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31];
3240 case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30];
3241 case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29];
3242 case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28];
3243 case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27];
3244 case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26];
3245 case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25];
3246 case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24];
3247 case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23];
3248 case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22];
3249 case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21];
3250 case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20];
3251 case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19];
3252 case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18];
3253 case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17];
3254 case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16];
3255 case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15];
3256 case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14];
3257 case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13];
3258 case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
3259 case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
3260 case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10];
3261 case 9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9];
3262 case 8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8];
3263 case 7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7];
3264 case 6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6];
3265 case 5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5];
3266 case 4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4];
3267 case 3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3];
3268 case 2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2];
3269 case 1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1];
3270 }
3271 #endif
3272
3273 return (drflac_int32)(prediction >> shift);
3274 }
3275
3276
3277 #if 0
3278 /*
3279 Reference implementation for reading and decoding samples with residual. This is intentionally left unoptimized for the
3280 sake of readability and should only be used as a reference.
3281 */
3282 static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3283 {
3284 drflac_uint32 i;
3285
3286 DRFLAC_ASSERT(bs != NULL);
3287 DRFLAC_ASSERT(pSamplesOut != NULL);
3288
3289 for (i = 0; i < count; ++i) {
3290 drflac_uint32 zeroCounter = 0;
3291 for (;;) {
3292 drflac_uint8 bit;
3293 if (!drflac__read_uint8(bs, 1, &bit)) {
3294 return DRFLAC_FALSE;
3295 }
3296
3297 if (bit == 0) {
3298 zeroCounter += 1;
3299 } else {
3300 break;
3301 }
3302 }
3303
3304 drflac_uint32 decodedRice;
3305 if (riceParam > 0) {
3306 if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
3307 return DRFLAC_FALSE;
3308 }
3309 } else {
3310 decodedRice = 0;
3311 }
3312
3313 decodedRice |= (zeroCounter << riceParam);
3314 if ((decodedRice & 0x01)) {
3315 decodedRice = ~(decodedRice >> 1);
3316 } else {
3317 decodedRice = (decodedRice >> 1);
3318 }
3319
3320
3321 if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
3322 pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
3323 } else {
3324 pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
3325 }
3326 }
3327
3328 return DRFLAC_TRUE;
3329 }
3330 #endif
3331
3332 #if 0
3333 static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
3334 {
3335 drflac_uint32 zeroCounter = 0;
3336 drflac_uint32 decodedRice;
3337
3338 for (;;) {
3339 drflac_uint8 bit;
3340 if (!drflac__read_uint8(bs, 1, &bit)) {
3341 return DRFLAC_FALSE;
3342 }
3343
3344 if (bit == 0) {
3345 zeroCounter += 1;
3346 } else {
3347 break;
3348 }
3349 }
3350
3351 if (riceParam > 0) {
3352 if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
3353 return DRFLAC_FALSE;
3354 }
3355 } else {
3356 decodedRice = 0;
3357 }
3358
3359 *pZeroCounterOut = zeroCounter;
3360 *pRiceParamPartOut = decodedRice;
3361 return DRFLAC_TRUE;
3362 }
3363 #endif
3364
3365 #if 0
3366 static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
3367 {
3368 drflac_cache_t riceParamMask;
3369 drflac_uint32 zeroCounter;
3370 drflac_uint32 setBitOffsetPlus1;
3371 drflac_uint32 riceParamPart;
3372 drflac_uint32 riceLength;
3373
3374 DRFLAC_ASSERT(riceParam > 0); /* <-- riceParam should never be 0. drflac__read_rice_parts__param_equals_zero() should be used instead for this case. */
3375
3376 riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
3377
3378 zeroCounter = 0;
3379 while (bs->cache == 0) {
3380 zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
3381 if (!drflac__reload_cache(bs)) {
3382 return DRFLAC_FALSE;
3383 }
3384 }
3385
3386 setBitOffsetPlus1 = drflac__clz(bs->cache);
3387 zeroCounter += setBitOffsetPlus1;
3388 setBitOffsetPlus1 += 1;
3389
3390 riceLength = setBitOffsetPlus1 + riceParam;
3391 if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3392 riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
3393
3394 bs->consumedBits += riceLength;
3395 bs->cache <<= riceLength;
3396 } else {
3397 drflac_uint32 bitCountLo;
3398 drflac_cache_t resultHi;
3399
3400 bs->consumedBits += riceLength;
3401 bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1); /* <-- Equivalent to "if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) { bs->cache <<= setBitOffsetPlus1; }" */
3402
3403 /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */
3404 bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
3405 resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam); /* <-- Use DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE() if ever this function allows riceParam=0. */
3406
3407 if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3408 #ifndef DR_FLAC_NO_CRC
3409 drflac__update_crc16(bs);
3410 #endif
3411 bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3412 bs->consumedBits = 0;
3413 #ifndef DR_FLAC_NO_CRC
3414 bs->crc16Cache = bs->cache;
3415 #endif
3416 } else {
3417 /* Slow path. We need to fetch more data from the client. */
3418 if (!drflac__reload_cache(bs)) {
3419 return DRFLAC_FALSE;
3420 }
3421 if (bitCountLo > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3422 /* This happens when we get to end of stream */
3423 return DRFLAC_FALSE;
3424 }
3425 }
3426
3427 riceParamPart = (drflac_uint32)(resultHi | DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo));
3428
3429 bs->consumedBits += bitCountLo;
3430 bs->cache <<= bitCountLo;
3431 }
3432
3433 pZeroCounterOut[0] = zeroCounter;
3434 pRiceParamPartOut[0] = riceParamPart;
3435
3436 return DRFLAC_TRUE;
3437 }
3438 #endif
3439
3440 static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
3441 {
3442 drflac_uint32 riceParamPlus1 = riceParam + 1;
3443 /*drflac_cache_t riceParamPlus1Mask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParamPlus1);*/
3444 drflac_uint32 riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1);
3445 drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
3446
3447 /*
3448 The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have
3449 no idea how this will work in practice...
3450 */
3451 drflac_cache_t bs_cache = bs->cache;
3452 drflac_uint32 bs_consumedBits = bs->consumedBits;
3453
3454 /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
3455 drflac_uint32 lzcount = drflac__clz(bs_cache);
3456 if (lzcount < sizeof(bs_cache)*8) {
3457 pZeroCounterOut[0] = lzcount;
3458
3459 /*
3460 It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
3461 this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
3462 outside of this function at a higher level.
3463 */
3464 extract_rice_param_part:
3465 bs_cache <<= lzcount;
3466 bs_consumedBits += lzcount;
3467
3468 if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
3469 /* Getting here means the rice parameter part is wholly contained within the current cache line. */
3470 pRiceParamPartOut[0] = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
3471 bs_cache <<= riceParamPlus1;
3472 bs_consumedBits += riceParamPlus1;
3473 } else {
3474 drflac_uint32 riceParamPartHi;
3475 drflac_uint32 riceParamPartLo;
3476 drflac_uint32 riceParamPartLoBitCount;
3477
3478 /*
3479 Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
3480 line, reload the cache, and then combine it with the head of the next cache line.
3481 */
3482
3483 /* Grab the high part of the rice parameter part. */
3484 riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
3485
3486 /* Before reloading the cache we need to grab the size in bits of the low part. */
3487 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
3488 DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
3489
3490 /* Now reload the cache. */
3491 if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3492 #ifndef DR_FLAC_NO_CRC
3493 drflac__update_crc16(bs);
3494 #endif
3495 bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3496 bs_consumedBits = riceParamPartLoBitCount;
3497 #ifndef DR_FLAC_NO_CRC
3498 bs->crc16Cache = bs_cache;
3499 #endif
3500 } else {
3501 /* Slow path. We need to fetch more data from the client. */
3502 if (!drflac__reload_cache(bs)) {
3503 return DRFLAC_FALSE;
3504 }
3505 if (riceParamPartLoBitCount > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3506 /* This happens when we get to end of stream */
3507 return DRFLAC_FALSE;
3508 }
3509
3510 bs_cache = bs->cache;
3511 bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
3512 }
3513
3514 /* We should now have enough information to construct the rice parameter part. */
3515 riceParamPartLo = (drflac_uint32)(bs_cache >> (DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPartLoBitCount)));
3516 pRiceParamPartOut[0] = riceParamPartHi | riceParamPartLo;
3517
3518 bs_cache <<= riceParamPartLoBitCount;
3519 }
3520 } else {
3521 /*
3522 Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call
3523 to drflac__clz() and we need to reload the cache.
3524 */
3525 drflac_uint32 zeroCounter = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs_consumedBits);
3526 for (;;) {
3527 if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3528 #ifndef DR_FLAC_NO_CRC
3529 drflac__update_crc16(bs);
3530 #endif
3531 bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3532 bs_consumedBits = 0;
3533 #ifndef DR_FLAC_NO_CRC
3534 bs->crc16Cache = bs_cache;
3535 #endif
3536 } else {
3537 /* Slow path. We need to fetch more data from the client. */
3538 if (!drflac__reload_cache(bs)) {
3539 return DRFLAC_FALSE;
3540 }
3541
3542 bs_cache = bs->cache;
3543 bs_consumedBits = bs->consumedBits;
3544 }
3545
3546 lzcount = drflac__clz(bs_cache);
3547 zeroCounter += lzcount;
3548
3549 if (lzcount < sizeof(bs_cache)*8) {
3550 break;
3551 }
3552 }
3553
3554 pZeroCounterOut[0] = zeroCounter;
3555 goto extract_rice_param_part;
3556 }
3557
3558 /* Make sure the cache is restored at the end of it all. */
3559 bs->cache = bs_cache;
3560 bs->consumedBits = bs_consumedBits;
3561
3562 return DRFLAC_TRUE;
3563 }
3564
3565 static DRFLAC_INLINE drflac_bool32 drflac__seek_rice_parts(drflac_bs* bs, drflac_uint8 riceParam)
3566 {
3567 drflac_uint32 riceParamPlus1 = riceParam + 1;
3568 drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
3569
3570 /*
3571 The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have
3572 no idea how this will work in practice...
3573 */
3574 drflac_cache_t bs_cache = bs->cache;
3575 drflac_uint32 bs_consumedBits = bs->consumedBits;
3576
3577 /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
3578 drflac_uint32 lzcount = drflac__clz(bs_cache);
3579 if (lzcount < sizeof(bs_cache)*8) {
3580 /*
3581 It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
3582 this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
3583 outside of this function at a higher level.
3584 */
3585 extract_rice_param_part:
3586 bs_cache <<= lzcount;
3587 bs_consumedBits += lzcount;
3588
3589 if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
3590 /* Getting here means the rice parameter part is wholly contained within the current cache line. */
3591 bs_cache <<= riceParamPlus1;
3592 bs_consumedBits += riceParamPlus1;
3593 } else {
3594 /*
3595 Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
3596 line, reload the cache, and then combine it with the head of the next cache line.
3597 */
3598
3599 /* Before reloading the cache we need to grab the size in bits of the low part. */
3600 drflac_uint32 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
3601 DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
3602
3603 /* Now reload the cache. */
3604 if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3605 #ifndef DR_FLAC_NO_CRC
3606 drflac__update_crc16(bs);
3607 #endif
3608 bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3609 bs_consumedBits = riceParamPartLoBitCount;
3610 #ifndef DR_FLAC_NO_CRC
3611 bs->crc16Cache = bs_cache;
3612 #endif
3613 } else {
3614 /* Slow path. We need to fetch more data from the client. */
3615 if (!drflac__reload_cache(bs)) {
3616 return DRFLAC_FALSE;
3617 }
3618
3619 if (riceParamPartLoBitCount > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3620 /* This happens when we get to end of stream */
3621 return DRFLAC_FALSE;
3622 }
3623
3624 bs_cache = bs->cache;
3625 bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
3626 }
3627
3628 bs_cache <<= riceParamPartLoBitCount;
3629 }
3630 } else {
3631 /*
3632 Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call
3633 to drflac__clz() and we need to reload the cache.
3634 */
3635 for (;;) {
3636 if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3637 #ifndef DR_FLAC_NO_CRC
3638 drflac__update_crc16(bs);
3639 #endif
3640 bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3641 bs_consumedBits = 0;
3642 #ifndef DR_FLAC_NO_CRC
3643 bs->crc16Cache = bs_cache;
3644 #endif
3645 } else {
3646 /* Slow path. We need to fetch more data from the client. */
3647 if (!drflac__reload_cache(bs)) {
3648 return DRFLAC_FALSE;
3649 }
3650
3651 bs_cache = bs->cache;
3652 bs_consumedBits = bs->consumedBits;
3653 }
3654
3655 lzcount = drflac__clz(bs_cache);
3656 if (lzcount < sizeof(bs_cache)*8) {
3657 break;
3658 }
3659 }
3660
3661 goto extract_rice_param_part;
3662 }
3663
3664 /* Make sure the cache is restored at the end of it all. */
3665 bs->cache = bs_cache;
3666 bs->consumedBits = bs_consumedBits;
3667
3668 return DRFLAC_TRUE;
3669 }
3670
3671
3672 static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar_zeroorder(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3673 {
3674 drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3675 drflac_uint32 zeroCountPart0;
3676 drflac_uint32 riceParamPart0;
3677 drflac_uint32 riceParamMask;
3678 drflac_uint32 i;
3679
3680 DRFLAC_ASSERT(bs != NULL);
3681 DRFLAC_ASSERT(pSamplesOut != NULL);
3682
3683 (void)bitsPerSample;
3684 (void)order;
3685 (void)shift;
3686 (void)coefficients;
3687
3688 riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
3689
3690 i = 0;
3691 while (i < count) {
3692 /* Rice extraction. */
3693 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) {
3694 return DRFLAC_FALSE;
3695 }
3696
3697 /* Rice reconstruction. */
3698 riceParamPart0 &= riceParamMask;
3699 riceParamPart0 |= (zeroCountPart0 << riceParam);
3700 riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3701
3702 pSamplesOut[i] = riceParamPart0;
3703
3704 i += 1;
3705 }
3706
3707 return DRFLAC_TRUE;
3708 }
3709
3710 static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3711 {
3712 drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3713 drflac_uint32 zeroCountPart0 = 0;
3714 drflac_uint32 zeroCountPart1 = 0;
3715 drflac_uint32 zeroCountPart2 = 0;
3716 drflac_uint32 zeroCountPart3 = 0;
3717 drflac_uint32 riceParamPart0 = 0;
3718 drflac_uint32 riceParamPart1 = 0;
3719 drflac_uint32 riceParamPart2 = 0;
3720 drflac_uint32 riceParamPart3 = 0;
3721 drflac_uint32 riceParamMask;
3722 const drflac_int32* pSamplesOutEnd;
3723 drflac_uint32 i;
3724
3725 DRFLAC_ASSERT(bs != NULL);
3726 DRFLAC_ASSERT(pSamplesOut != NULL);
3727
3728 if (lpcOrder == 0) {
3729 return drflac__decode_samples_with_residual__rice__scalar_zeroorder(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
3730 }
3731
3732 riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
3733 pSamplesOutEnd = pSamplesOut + (count & ~3);
3734
3735 if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
3736 while (pSamplesOut < pSamplesOutEnd) {
3737 /*
3738 Rice extraction. It's faster to do this one at a time against local variables than it is to use the x4 version
3739 against an array. Not sure why, but perhaps it's making more efficient use of registers?
3740 */
3741 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
3742 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
3743 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
3744 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
3745 return DRFLAC_FALSE;
3746 }
3747
3748 riceParamPart0 &= riceParamMask;
3749 riceParamPart1 &= riceParamMask;
3750 riceParamPart2 &= riceParamMask;
3751 riceParamPart3 &= riceParamMask;
3752
3753 riceParamPart0 |= (zeroCountPart0 << riceParam);
3754 riceParamPart1 |= (zeroCountPart1 << riceParam);
3755 riceParamPart2 |= (zeroCountPart2 << riceParam);
3756 riceParamPart3 |= (zeroCountPart3 << riceParam);
3757
3758 riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3759 riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
3760 riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
3761 riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
3762
3763 pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3764 pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
3765 pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
3766 pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
3767
3768 pSamplesOut += 4;
3769 }
3770 } else {
3771 while (pSamplesOut < pSamplesOutEnd) {
3772 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
3773 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
3774 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
3775 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
3776 return DRFLAC_FALSE;
3777 }
3778
3779 riceParamPart0 &= riceParamMask;
3780 riceParamPart1 &= riceParamMask;
3781 riceParamPart2 &= riceParamMask;
3782 riceParamPart3 &= riceParamMask;
3783
3784 riceParamPart0 |= (zeroCountPart0 << riceParam);
3785 riceParamPart1 |= (zeroCountPart1 << riceParam);
3786 riceParamPart2 |= (zeroCountPart2 << riceParam);
3787 riceParamPart3 |= (zeroCountPart3 << riceParam);
3788
3789 riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3790 riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
3791 riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
3792 riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
3793
3794 pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3795 pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
3796 pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
3797 pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
3798
3799 pSamplesOut += 4;
3800 }
3801 }
3802
3803 i = (count & ~3);
3804 while (i < count) {
3805 /* Rice extraction. */
3806 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) {
3807 return DRFLAC_FALSE;
3808 }
3809
3810 /* Rice reconstruction. */
3811 riceParamPart0 &= riceParamMask;
3812 riceParamPart0 |= (zeroCountPart0 << riceParam);
3813 riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3814 /*riceParamPart0 = (riceParamPart0 >> 1) ^ (~(riceParamPart0 & 0x01) + 1);*/
3815
3816 /* Sample reconstruction. */
3817 if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
3818 pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3819 } else {
3820 pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3821 }
3822
3823 i += 1;
3824 pSamplesOut += 1;
3825 }
3826
3827 return DRFLAC_TRUE;
3828 }
3829
3830 #if defined(DRFLAC_SUPPORT_SSE2)
3831 static DRFLAC_INLINE __m128i drflac__mm_packs_interleaved_epi32(__m128i a, __m128i b)
3832 {
3833 __m128i r;
3834
3835 /* Pack. */
3836 r = _mm_packs_epi32(a, b);
3837
3838 /* a3a2 a1a0 b3b2 b1b0 -> a3a2 b3b2 a1a0 b1b0 */
3839 r = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 1, 2, 0));
3840
3841 /* a3a2 b3b2 a1a0 b1b0 -> a3b3 a2b2 a1b1 a0b0 */
3842 r = _mm_shufflehi_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
3843 r = _mm_shufflelo_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
3844
3845 return r;
3846 }
3847 #endif
3848
3849 #if defined(DRFLAC_SUPPORT_SSE41)
3850 static DRFLAC_INLINE __m128i drflac__mm_not_si128(__m128i a)
3851 {
3852 return _mm_xor_si128(a, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()));
3853 }
3854
3855 static DRFLAC_INLINE __m128i drflac__mm_hadd_epi32(__m128i x)
3856 {
3857 __m128i x64 = _mm_add_epi32(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
3858 __m128i x32 = _mm_shufflelo_epi16(x64, _MM_SHUFFLE(1, 0, 3, 2));
3859 return _mm_add_epi32(x64, x32);
3860 }
3861
3862 static DRFLAC_INLINE __m128i drflac__mm_hadd_epi64(__m128i x)
3863 {
3864 return _mm_add_epi64(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
3865 }
3866
3867 static DRFLAC_INLINE __m128i drflac__mm_srai_epi64(__m128i x, int count)
3868 {
3869 /*
3870 To simplify this we are assuming count < 32. This restriction allows us to work on a low side and a high side. The low side
3871 is shifted with zero bits, whereas the right side is shifted with sign bits.
3872 */
3873 __m128i lo = _mm_srli_epi64(x, count);
3874 __m128i hi = _mm_srai_epi32(x, count);
3875
3876 hi = _mm_and_si128(hi, _mm_set_epi32(0xFFFFFFFF, 0, 0xFFFFFFFF, 0)); /* The high part needs to have the low part cleared. */
3877
3878 return _mm_or_si128(lo, hi);
3879 }
3880
3881 static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_32(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3882 {
3883 int i;
3884 drflac_uint32 riceParamMask;
3885 drflac_int32* pDecodedSamples = pSamplesOut;
3886 drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
3887 drflac_uint32 zeroCountParts0 = 0;
3888 drflac_uint32 zeroCountParts1 = 0;
3889 drflac_uint32 zeroCountParts2 = 0;
3890 drflac_uint32 zeroCountParts3 = 0;
3891 drflac_uint32 riceParamParts0 = 0;
3892 drflac_uint32 riceParamParts1 = 0;
3893 drflac_uint32 riceParamParts2 = 0;
3894 drflac_uint32 riceParamParts3 = 0;
3895 __m128i coefficients128_0;
3896 __m128i coefficients128_4;
3897 __m128i coefficients128_8;
3898 __m128i samples128_0;
3899 __m128i samples128_4;
3900 __m128i samples128_8;
3901 __m128i riceParamMask128;
3902
3903 const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3904
3905 riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
3906 riceParamMask128 = _mm_set1_epi32(riceParamMask);
3907
3908 /* Pre-load. */
3909 coefficients128_0 = _mm_setzero_si128();
3910 coefficients128_4 = _mm_setzero_si128();
3911 coefficients128_8 = _mm_setzero_si128();
3912
3913 samples128_0 = _mm_setzero_si128();
3914 samples128_4 = _mm_setzero_si128();
3915 samples128_8 = _mm_setzero_si128();
3916
3917 /*
3918 Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
3919 what's available in the input buffers. It would be convenient to use a fall-through switch to do this, but this results
3920 in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
3921 so I think there's opportunity for this to be simplified.
3922 */
3923 #if 1
3924 {
3925 int runningOrder = order;
3926
3927 /* 0 - 3. */
3928 if (runningOrder >= 4) {
3929 coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
3930 samples128_0 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 4));
3931 runningOrder -= 4;
3932 } else {
3933 switch (runningOrder) {
3934 case 3: coefficients128_0 = _mm_set_epi32(0, coefficients[2], coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], pSamplesOut[-3], 0); break;
3935 case 2: coefficients128_0 = _mm_set_epi32(0, 0, coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], 0, 0); break;
3936 case 1: coefficients128_0 = _mm_set_epi32(0, 0, 0, coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0, 0, 0); break;
3937 }
3938 runningOrder = 0;
3939 }
3940
3941 /* 4 - 7 */
3942 if (runningOrder >= 4) {
3943 coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
3944 samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
3945 runningOrder -= 4;
3946 } else {
3947 switch (runningOrder) {
3948 case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
3949 case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
3950 case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
3951 }
3952 runningOrder = 0;
3953 }
3954
3955 /* 8 - 11 */
3956 if (runningOrder == 4) {
3957 coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
3958 samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
3959 runningOrder -= 4;
3960 } else {
3961 switch (runningOrder) {
3962 case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
3963 case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
3964 case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
3965 }
3966 runningOrder = 0;
3967 }
3968
3969 /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
3970 coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
3971 coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
3972 coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
3973 }
3974 #else
3975 /* This causes strict-aliasing warnings with GCC. */
3976 switch (order)
3977 {
3978 case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
3979 case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
3980 case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
3981 case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
3982 case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
3983 case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
3984 case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
3985 case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
3986 case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
3987 case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
3988 case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
3989 case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
3990 }
3991 #endif
3992
3993 /* For this version we are doing one sample at a time. */
3994 while (pDecodedSamples < pDecodedSamplesEnd) {
3995 __m128i prediction128;
3996 __m128i zeroCountPart128;
3997 __m128i riceParamPart128;
3998
3999 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
4000 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
4001 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
4002 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
4003 return DRFLAC_FALSE;
4004 }
4005
4006 zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
4007 riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
4008
4009 riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
4010 riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
4011 riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01))), _mm_set1_epi32(0x01))); /* <-- SSE2 compatible */
4012 /*riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_mullo_epi32(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01)), _mm_set1_epi32(0xFFFFFFFF)));*/ /* <-- Only supported from SSE4.1 and is slower in my testing... */
4013
4014 if (order <= 4) {
4015 for (i = 0; i < 4; i += 1) {
4016 prediction128 = _mm_mullo_epi32(coefficients128_0, samples128_0);
4017
4018 /* Horizontal add and shift. */
4019 prediction128 = drflac__mm_hadd_epi32(prediction128);
4020 prediction128 = _mm_srai_epi32(prediction128, shift);
4021 prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
4022
4023 samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
4024 riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4025 }
4026 } else if (order <= 8) {
4027 for (i = 0; i < 4; i += 1) {
4028 prediction128 = _mm_mullo_epi32(coefficients128_4, samples128_4);
4029 prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
4030
4031 /* Horizontal add and shift. */
4032 prediction128 = drflac__mm_hadd_epi32(prediction128);
4033 prediction128 = _mm_srai_epi32(prediction128, shift);
4034 prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
4035
4036 samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
4037 samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
4038 riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4039 }
4040 } else {
4041 for (i = 0; i < 4; i += 1) {
4042 prediction128 = _mm_mullo_epi32(coefficients128_8, samples128_8);
4043 prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_4, samples128_4));
4044 prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
4045
4046 /* Horizontal add and shift. */
4047 prediction128 = drflac__mm_hadd_epi32(prediction128);
4048 prediction128 = _mm_srai_epi32(prediction128, shift);
4049 prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
4050
4051 samples128_8 = _mm_alignr_epi8(samples128_4, samples128_8, 4);
4052 samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
4053 samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
4054 riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4055 }
4056 }
4057
4058 /* We store samples in groups of 4. */
4059 _mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
4060 pDecodedSamples += 4;
4061 }
4062
4063 /* Make sure we process the last few samples. */
4064 i = (count & ~3);
4065 while (i < (int)count) {
4066 /* Rice extraction. */
4067 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
4068 return DRFLAC_FALSE;
4069 }
4070
4071 /* Rice reconstruction. */
4072 riceParamParts0 &= riceParamMask;
4073 riceParamParts0 |= (zeroCountParts0 << riceParam);
4074 riceParamParts0 = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
4075
4076 /* Sample reconstruction. */
4077 pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
4078
4079 i += 1;
4080 pDecodedSamples += 1;
4081 }
4082
4083 return DRFLAC_TRUE;
4084 }
4085
4086 static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_64(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4087 {
4088 int i;
4089 drflac_uint32 riceParamMask;
4090 drflac_int32* pDecodedSamples = pSamplesOut;
4091 drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
4092 drflac_uint32 zeroCountParts0 = 0;
4093 drflac_uint32 zeroCountParts1 = 0;
4094 drflac_uint32 zeroCountParts2 = 0;
4095 drflac_uint32 zeroCountParts3 = 0;
4096 drflac_uint32 riceParamParts0 = 0;
4097 drflac_uint32 riceParamParts1 = 0;
4098 drflac_uint32 riceParamParts2 = 0;
4099 drflac_uint32 riceParamParts3 = 0;
4100 __m128i coefficients128_0;
4101 __m128i coefficients128_4;
4102 __m128i coefficients128_8;
4103 __m128i samples128_0;
4104 __m128i samples128_4;
4105 __m128i samples128_8;
4106 __m128i prediction128;
4107 __m128i riceParamMask128;
4108
4109 const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
4110
4111 DRFLAC_ASSERT(order <= 12);
4112
4113 riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
4114 riceParamMask128 = _mm_set1_epi32(riceParamMask);
4115
4116 prediction128 = _mm_setzero_si128();
4117
4118 /* Pre-load. */
4119 coefficients128_0 = _mm_setzero_si128();
4120 coefficients128_4 = _mm_setzero_si128();
4121 coefficients128_8 = _mm_setzero_si128();
4122
4123 samples128_0 = _mm_setzero_si128();
4124 samples128_4 = _mm_setzero_si128();
4125 samples128_8 = _mm_setzero_si128();
4126
4127 #if 1
4128 {
4129 int runningOrder = order;
4130
4131 /* 0 - 3. */
4132 if (runningOrder >= 4) {
4133 coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
4134 samples128_0 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 4));
4135 runningOrder -= 4;
4136 } else {
4137 switch (runningOrder) {
4138 case 3: coefficients128_0 = _mm_set_epi32(0, coefficients[2], coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], pSamplesOut[-3], 0); break;
4139 case 2: coefficients128_0 = _mm_set_epi32(0, 0, coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], 0, 0); break;
4140 case 1: coefficients128_0 = _mm_set_epi32(0, 0, 0, coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0, 0, 0); break;
4141 }
4142 runningOrder = 0;
4143 }
4144
4145 /* 4 - 7 */
4146 if (runningOrder >= 4) {
4147 coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
4148 samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
4149 runningOrder -= 4;
4150 } else {
4151 switch (runningOrder) {
4152 case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
4153 case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
4154 case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
4155 }
4156 runningOrder = 0;
4157 }
4158
4159 /* 8 - 11 */
4160 if (runningOrder == 4) {
4161 coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
4162 samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
4163 runningOrder -= 4;
4164 } else {
4165 switch (runningOrder) {
4166 case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
4167 case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
4168 case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
4169 }
4170 runningOrder = 0;
4171 }
4172
4173 /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
4174 coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
4175 coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
4176 coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
4177 }
4178 #else
4179 switch (order)
4180 {
4181 case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
4182 case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
4183 case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
4184 case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
4185 case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
4186 case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
4187 case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
4188 case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
4189 case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
4190 case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
4191 case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
4192 case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
4193 }
4194 #endif
4195
4196 /* For this version we are doing one sample at a time. */
4197 while (pDecodedSamples < pDecodedSamplesEnd) {
4198 __m128i zeroCountPart128;
4199 __m128i riceParamPart128;
4200
4201 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
4202 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
4203 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
4204 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
4205 return DRFLAC_FALSE;
4206 }
4207
4208 zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
4209 riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
4210
4211 riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
4212 riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
4213 riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(1))), _mm_set1_epi32(1)));
4214
4215 for (i = 0; i < 4; i += 1) {
4216 prediction128 = _mm_xor_si128(prediction128, prediction128); /* Reset to 0. */
4217
4218 switch (order)
4219 {
4220 case 12:
4221 case 11: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(1, 1, 0, 0))));
4222 case 10:
4223 case 9: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(3, 3, 2, 2))));
4224 case 8:
4225 case 7: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(1, 1, 0, 0))));
4226 case 6:
4227 case 5: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(3, 3, 2, 2))));
4228 case 4:
4229 case 3: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(1, 1, 0, 0))));
4230 case 2:
4231 case 1: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(3, 3, 2, 2))));
4232 }
4233
4234 /* Horizontal add and shift. */
4235 prediction128 = drflac__mm_hadd_epi64(prediction128);
4236 prediction128 = drflac__mm_srai_epi64(prediction128, shift);
4237 prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
4238
4239 /* Our value should be sitting in prediction128[0]. We need to combine this with our SSE samples. */
4240 samples128_8 = _mm_alignr_epi8(samples128_4, samples128_8, 4);
4241 samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
4242 samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
4243
4244 /* Slide our rice parameter down so that the value in position 0 contains the next one to process. */
4245 riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4246 }
4247
4248 /* We store samples in groups of 4. */
4249 _mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
4250 pDecodedSamples += 4;
4251 }
4252
4253 /* Make sure we process the last few samples. */
4254 i = (count & ~3);
4255 while (i < (int)count) {
4256 /* Rice extraction. */
4257 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
4258 return DRFLAC_FALSE;
4259 }
4260
4261 /* Rice reconstruction. */
4262 riceParamParts0 &= riceParamMask;
4263 riceParamParts0 |= (zeroCountParts0 << riceParam);
4264 riceParamParts0 = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
4265
4266 /* Sample reconstruction. */
4267 pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
4268
4269 i += 1;
4270 pDecodedSamples += 1;
4271 }
4272
4273 return DRFLAC_TRUE;
4274 }
4275
4276 static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4277 {
4278 DRFLAC_ASSERT(bs != NULL);
4279 DRFLAC_ASSERT(pSamplesOut != NULL);
4280
4281 /* In my testing the order is rarely > 12, so in this case I'm going to simplify the SSE implementation by only handling order <= 12. */
4282 if (lpcOrder > 0 && lpcOrder <= 12) {
4283 if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
4284 return drflac__decode_samples_with_residual__rice__sse41_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4285 } else {
4286 return drflac__decode_samples_with_residual__rice__sse41_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4287 }
4288 } else {
4289 return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4290 }
4291 }
4292 #endif
4293
4294 #if defined(DRFLAC_SUPPORT_NEON)
4295 static DRFLAC_INLINE void drflac__vst2q_s32(drflac_int32* p, int32x4x2_t x)
4296 {
4297 vst1q_s32(p+0, x.val[0]);
4298 vst1q_s32(p+4, x.val[1]);
4299 }
4300
4301 static DRFLAC_INLINE void drflac__vst2q_u32(drflac_uint32* p, uint32x4x2_t x)
4302 {
4303 vst1q_u32(p+0, x.val[0]);
4304 vst1q_u32(p+4, x.val[1]);
4305 }
4306
4307 static DRFLAC_INLINE void drflac__vst2q_f32(float* p, float32x4x2_t x)
4308 {
4309 vst1q_f32(p+0, x.val[0]);
4310 vst1q_f32(p+4, x.val[1]);
4311 }
4312
4313 static DRFLAC_INLINE void drflac__vst2q_s16(drflac_int16* p, int16x4x2_t x)
4314 {
4315 vst1q_s16(p, vcombine_s16(x.val[0], x.val[1]));
4316 }
4317
4318 static DRFLAC_INLINE void drflac__vst2q_u16(drflac_uint16* p, uint16x4x2_t x)
4319 {
4320 vst1q_u16(p, vcombine_u16(x.val[0], x.val[1]));
4321 }
4322
4323 static DRFLAC_INLINE int32x4_t drflac__vdupq_n_s32x4(drflac_int32 x3, drflac_int32 x2, drflac_int32 x1, drflac_int32 x0)
4324 {
4325 drflac_int32 x[4];
4326 x[3] = x3;
4327 x[2] = x2;
4328 x[1] = x1;
4329 x[0] = x0;
4330 return vld1q_s32(x);
4331 }
4332
4333 static DRFLAC_INLINE int32x4_t drflac__valignrq_s32_1(int32x4_t a, int32x4_t b)
4334 {
4335 /* Equivalent to SSE's _mm_alignr_epi8(a, b, 4) */
4336
4337 /* Reference */
4338 /*return drflac__vdupq_n_s32x4(
4339 vgetq_lane_s32(a, 0),
4340 vgetq_lane_s32(b, 3),
4341 vgetq_lane_s32(b, 2),
4342 vgetq_lane_s32(b, 1)
4343 );*/
4344
4345 return vextq_s32(b, a, 1);
4346 }
4347
4348 static DRFLAC_INLINE uint32x4_t drflac__valignrq_u32_1(uint32x4_t a, uint32x4_t b)
4349 {
4350 /* Equivalent to SSE's _mm_alignr_epi8(a, b, 4) */
4351
4352 /* Reference */
4353 /*return drflac__vdupq_n_s32x4(
4354 vgetq_lane_s32(a, 0),
4355 vgetq_lane_s32(b, 3),
4356 vgetq_lane_s32(b, 2),
4357 vgetq_lane_s32(b, 1)
4358 );*/
4359
4360 return vextq_u32(b, a, 1);
4361 }
4362
4363 static DRFLAC_INLINE int32x2_t drflac__vhaddq_s32(int32x4_t x)
4364 {
4365 /* The sum must end up in position 0. */
4366
4367 /* Reference */
4368 /*return vdupq_n_s32(
4369 vgetq_lane_s32(x, 3) +
4370 vgetq_lane_s32(x, 2) +
4371 vgetq_lane_s32(x, 1) +
4372 vgetq_lane_s32(x, 0)
4373 );*/
4374
4375 int32x2_t r = vadd_s32(vget_high_s32(x), vget_low_s32(x));
4376 return vpadd_s32(r, r);
4377 }
4378
4379 static DRFLAC_INLINE int64x1_t drflac__vhaddq_s64(int64x2_t x)
4380 {
4381 return vadd_s64(vget_high_s64(x), vget_low_s64(x));
4382 }
4383
4384 static DRFLAC_INLINE int32x4_t drflac__vrevq_s32(int32x4_t x)
4385 {
4386 /* Reference */
4387 /*return drflac__vdupq_n_s32x4(
4388 vgetq_lane_s32(x, 0),
4389 vgetq_lane_s32(x, 1),
4390 vgetq_lane_s32(x, 2),
4391 vgetq_lane_s32(x, 3)
4392 );*/
4393
4394 return vrev64q_s32(vcombine_s32(vget_high_s32(x), vget_low_s32(x)));
4395 }
4396
4397 static DRFLAC_INLINE int32x4_t drflac__vnotq_s32(int32x4_t x)
4398 {
4399 return veorq_s32(x, vdupq_n_s32(0xFFFFFFFF));
4400 }
4401
4402 static DRFLAC_INLINE uint32x4_t drflac__vnotq_u32(uint32x4_t x)
4403 {
4404 return veorq_u32(x, vdupq_n_u32(0xFFFFFFFF));
4405 }
4406
4407 static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_32(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4408 {
4409 int i;
4410 drflac_uint32 riceParamMask;
4411 drflac_int32* pDecodedSamples = pSamplesOut;
4412 drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
4413 drflac_uint32 zeroCountParts[4];
4414 drflac_uint32 riceParamParts[4];
4415 int32x4_t coefficients128_0;
4416 int32x4_t coefficients128_4;
4417 int32x4_t coefficients128_8;
4418 int32x4_t samples128_0;
4419 int32x4_t samples128_4;
4420 int32x4_t samples128_8;
4421 uint32x4_t riceParamMask128;
4422 int32x4_t riceParam128;
4423 int32x2_t shift64;
4424 uint32x4_t one128;
4425
4426 const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
4427
4428 riceParamMask = ~((~0UL) << riceParam);
4429 riceParamMask128 = vdupq_n_u32(riceParamMask);
4430
4431 riceParam128 = vdupq_n_s32(riceParam);
4432 shift64 = vdup_n_s32(-shift); /* Negate the shift because we'll be doing a variable shift using vshlq_s32(). */
4433 one128 = vdupq_n_u32(1);
4434
4435 /*
4436 Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
4437 what's available in the input buffers. It would be conenient to use a fall-through switch to do this, but this results
4438 in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
4439 so I think there's opportunity for this to be simplified.
4440 */
4441 {
4442 int runningOrder = order;
4443 drflac_int32 tempC[4] = {0, 0, 0, 0};
4444 drflac_int32 tempS[4] = {0, 0, 0, 0};
4445
4446 /* 0 - 3. */
4447 if (runningOrder >= 4) {
4448 coefficients128_0 = vld1q_s32(coefficients + 0);
4449 samples128_0 = vld1q_s32(pSamplesOut - 4);
4450 runningOrder -= 4;
4451 } else {
4452 switch (runningOrder) {
4453 case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
4454 case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
4455 case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
4456 }
4457
4458 coefficients128_0 = vld1q_s32(tempC);
4459 samples128_0 = vld1q_s32(tempS);
4460 runningOrder = 0;
4461 }
4462
4463 /* 4 - 7 */
4464 if (runningOrder >= 4) {
4465 coefficients128_4 = vld1q_s32(coefficients + 4);
4466 samples128_4 = vld1q_s32(pSamplesOut - 8);
4467 runningOrder -= 4;
4468 } else {
4469 switch (runningOrder) {
4470 case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
4471 case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
4472 case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
4473 }
4474
4475 coefficients128_4 = vld1q_s32(tempC);
4476 samples128_4 = vld1q_s32(tempS);
4477 runningOrder = 0;
4478 }
4479
4480 /* 8 - 11 */
4481 if (runningOrder == 4) {
4482 coefficients128_8 = vld1q_s32(coefficients + 8);
4483 samples128_8 = vld1q_s32(pSamplesOut - 12);
4484 runningOrder -= 4;
4485 } else {
4486 switch (runningOrder) {
4487 case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
4488 case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
4489 case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
4490 }
4491
4492 coefficients128_8 = vld1q_s32(tempC);
4493 samples128_8 = vld1q_s32(tempS);
4494 runningOrder = 0;
4495 }
4496
4497 /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
4498 coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
4499 coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
4500 coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
4501 }
4502
4503 /* For this version we are doing one sample at a time. */
4504 while (pDecodedSamples < pDecodedSamplesEnd) {
4505 int32x4_t prediction128;
4506 int32x2_t prediction64;
4507 uint32x4_t zeroCountPart128;
4508 uint32x4_t riceParamPart128;
4509
4510 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
4511 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
4512 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
4513 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
4514 return DRFLAC_FALSE;
4515 }
4516
4517 zeroCountPart128 = vld1q_u32(zeroCountParts);
4518 riceParamPart128 = vld1q_u32(riceParamParts);
4519
4520 riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
4521 riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
4522 riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
4523
4524 if (order <= 4) {
4525 for (i = 0; i < 4; i += 1) {
4526 prediction128 = vmulq_s32(coefficients128_0, samples128_0);
4527
4528 /* Horizontal add and shift. */
4529 prediction64 = drflac__vhaddq_s32(prediction128);
4530 prediction64 = vshl_s32(prediction64, shift64);
4531 prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
4532
4533 samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
4534 riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4535 }
4536 } else if (order <= 8) {
4537 for (i = 0; i < 4; i += 1) {
4538 prediction128 = vmulq_s32(coefficients128_4, samples128_4);
4539 prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
4540
4541 /* Horizontal add and shift. */
4542 prediction64 = drflac__vhaddq_s32(prediction128);
4543 prediction64 = vshl_s32(prediction64, shift64);
4544 prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
4545
4546 samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
4547 samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
4548 riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4549 }
4550 } else {
4551 for (i = 0; i < 4; i += 1) {
4552 prediction128 = vmulq_s32(coefficients128_8, samples128_8);
4553 prediction128 = vmlaq_s32(prediction128, coefficients128_4, samples128_4);
4554 prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
4555
4556 /* Horizontal add and shift. */
4557 prediction64 = drflac__vhaddq_s32(prediction128);
4558 prediction64 = vshl_s32(prediction64, shift64);
4559 prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
4560
4561 samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
4562 samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
4563 samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
4564 riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4565 }
4566 }
4567
4568 /* We store samples in groups of 4. */
4569 vst1q_s32(pDecodedSamples, samples128_0);
4570 pDecodedSamples += 4;
4571 }
4572
4573 /* Make sure we process the last few samples. */
4574 i = (count & ~3);
4575 while (i < (int)count) {
4576 /* Rice extraction. */
4577 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0])) {
4578 return DRFLAC_FALSE;
4579 }
4580
4581 /* Rice reconstruction. */
4582 riceParamParts[0] &= riceParamMask;
4583 riceParamParts[0] |= (zeroCountParts[0] << riceParam);
4584 riceParamParts[0] = (riceParamParts[0] >> 1) ^ t[riceParamParts[0] & 0x01];
4585
4586 /* Sample reconstruction. */
4587 pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
4588
4589 i += 1;
4590 pDecodedSamples += 1;
4591 }
4592
4593 return DRFLAC_TRUE;
4594 }
4595
4596 static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_64(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4597 {
4598 int i;
4599 drflac_uint32 riceParamMask;
4600 drflac_int32* pDecodedSamples = pSamplesOut;
4601 drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
4602 drflac_uint32 zeroCountParts[4];
4603 drflac_uint32 riceParamParts[4];
4604 int32x4_t coefficients128_0;
4605 int32x4_t coefficients128_4;
4606 int32x4_t coefficients128_8;
4607 int32x4_t samples128_0;
4608 int32x4_t samples128_4;
4609 int32x4_t samples128_8;
4610 uint32x4_t riceParamMask128;
4611 int32x4_t riceParam128;
4612 int64x1_t shift64;
4613 uint32x4_t one128;
4614 int64x2_t prediction128 = { 0 };
4615 uint32x4_t zeroCountPart128;
4616 uint32x4_t riceParamPart128;
4617
4618 const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
4619
4620 riceParamMask = ~((~0UL) << riceParam);
4621 riceParamMask128 = vdupq_n_u32(riceParamMask);
4622
4623 riceParam128 = vdupq_n_s32(riceParam);
4624 shift64 = vdup_n_s64(-shift); /* Negate the shift because we'll be doing a variable shift using vshlq_s32(). */
4625 one128 = vdupq_n_u32(1);
4626
4627 /*
4628 Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
4629 what's available in the input buffers. It would be convenient to use a fall-through switch to do this, but this results
4630 in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
4631 so I think there's opportunity for this to be simplified.
4632 */
4633 {
4634 int runningOrder = order;
4635 drflac_int32 tempC[4] = {0, 0, 0, 0};
4636 drflac_int32 tempS[4] = {0, 0, 0, 0};
4637
4638 /* 0 - 3. */
4639 if (runningOrder >= 4) {
4640 coefficients128_0 = vld1q_s32(coefficients + 0);
4641 samples128_0 = vld1q_s32(pSamplesOut - 4);
4642 runningOrder -= 4;
4643 } else {
4644 switch (runningOrder) {
4645 case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
4646 case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
4647 case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
4648 }
4649
4650 coefficients128_0 = vld1q_s32(tempC);
4651 samples128_0 = vld1q_s32(tempS);
4652 runningOrder = 0;
4653 }
4654
4655 /* 4 - 7 */
4656 if (runningOrder >= 4) {
4657 coefficients128_4 = vld1q_s32(coefficients + 4);
4658 samples128_4 = vld1q_s32(pSamplesOut - 8);
4659 runningOrder -= 4;
4660 } else {
4661 switch (runningOrder) {
4662 case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
4663 case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
4664 case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
4665 }
4666
4667 coefficients128_4 = vld1q_s32(tempC);
4668 samples128_4 = vld1q_s32(tempS);
4669 runningOrder = 0;
4670 }
4671
4672 /* 8 - 11 */
4673 if (runningOrder == 4) {
4674 coefficients128_8 = vld1q_s32(coefficients + 8);
4675 samples128_8 = vld1q_s32(pSamplesOut - 12);
4676 runningOrder -= 4;
4677 } else {
4678 switch (runningOrder) {
4679 case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
4680 case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
4681 case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
4682 }
4683
4684 coefficients128_8 = vld1q_s32(tempC);
4685 samples128_8 = vld1q_s32(tempS);
4686 runningOrder = 0;
4687 }
4688
4689 /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
4690 coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
4691 coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
4692 coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
4693 }
4694
4695 /* For this version we are doing one sample at a time. */
4696 while (pDecodedSamples < pDecodedSamplesEnd) {
4697 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
4698 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
4699 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
4700 !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
4701 return DRFLAC_FALSE;
4702 }
4703
4704 zeroCountPart128 = vld1q_u32(zeroCountParts);
4705 riceParamPart128 = vld1q_u32(riceParamParts);
4706
4707 riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
4708 riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
4709 riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
4710
4711 for (i = 0; i < 4; i += 1) {
4712 int64x1_t prediction64;
4713
4714 prediction128 = veorq_s64(prediction128, prediction128); /* Reset to 0. */
4715 switch (order)
4716 {
4717 case 12:
4718 case 11: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_8), vget_low_s32(samples128_8)));
4719 case 10:
4720 case 9: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_8), vget_high_s32(samples128_8)));
4721 case 8:
4722 case 7: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_4), vget_low_s32(samples128_4)));
4723 case 6:
4724 case 5: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_4), vget_high_s32(samples128_4)));
4725 case 4:
4726 case 3: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_0), vget_low_s32(samples128_0)));
4727 case 2:
4728 case 1: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_0), vget_high_s32(samples128_0)));
4729 }
4730
4731 /* Horizontal add and shift. */
4732 prediction64 = drflac__vhaddq_s64(prediction128);
4733 prediction64 = vshl_s64(prediction64, shift64);
4734 prediction64 = vadd_s64(prediction64, vdup_n_s64(vgetq_lane_u32(riceParamPart128, 0)));
4735
4736 /* Our value should be sitting in prediction64[0]. We need to combine this with our SSE samples. */
4737 samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
4738 samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
4739 samples128_0 = drflac__valignrq_s32_1(vcombine_s32(vreinterpret_s32_s64(prediction64), vdup_n_s32(0)), samples128_0);
4740
4741 /* Slide our rice parameter down so that the value in position 0 contains the next one to process. */
4742 riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4743 }
4744
4745 /* We store samples in groups of 4. */
4746 vst1q_s32(pDecodedSamples, samples128_0);
4747 pDecodedSamples += 4;
4748 }
4749
4750 /* Make sure we process the last few samples. */
4751 i = (count & ~3);
4752 while (i < (int)count) {
4753 /* Rice extraction. */
4754 if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0])) {
4755 return DRFLAC_FALSE;
4756 }
4757
4758 /* Rice reconstruction. */
4759 riceParamParts[0] &= riceParamMask;
4760 riceParamParts[0] |= (zeroCountParts[0] << riceParam);
4761 riceParamParts[0] = (riceParamParts[0] >> 1) ^ t[riceParamParts[0] & 0x01];
4762
4763 /* Sample reconstruction. */
4764 pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
4765
4766 i += 1;
4767 pDecodedSamples += 1;
4768 }
4769
4770 return DRFLAC_TRUE;
4771 }
4772
4773 static drflac_bool32 drflac__decode_samples_with_residual__rice__neon(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4774 {
4775 DRFLAC_ASSERT(bs != NULL);
4776 DRFLAC_ASSERT(pSamplesOut != NULL);
4777
4778 /* In my testing the order is rarely > 12, so in this case I'm going to simplify the NEON implementation by only handling order <= 12. */
4779 if (lpcOrder > 0 && lpcOrder <= 12) {
4780 if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
4781 return drflac__decode_samples_with_residual__rice__neon_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4782 } else {
4783 return drflac__decode_samples_with_residual__rice__neon_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4784 }
4785 } else {
4786 return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4787 }
4788 }
4789 #endif
4790
4791 static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4792 {
4793 #if defined(DRFLAC_SUPPORT_SSE41)
4794 if (drflac__gIsSSE41Supported) {
4795 return drflac__decode_samples_with_residual__rice__sse41(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4796 } else
4797 #elif defined(DRFLAC_SUPPORT_NEON)
4798 if (drflac__gIsNEONSupported) {
4799 return drflac__decode_samples_with_residual__rice__neon(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4800 } else
4801 #endif
4802 {
4803 /* Scalar fallback. */
4804 #if 0
4805 return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4806 #else
4807 return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4808 #endif
4809 }
4810 }
4811
4812 /* Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes. */
4813 static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam)
4814 {
4815 drflac_uint32 i;
4816
4817 DRFLAC_ASSERT(bs != NULL);
4818
4819 for (i = 0; i < count; ++i) {
4820 if (!drflac__seek_rice_parts(bs, riceParam)) {
4821 return DRFLAC_FALSE;
4822 }
4823 }
4824
4825 return DRFLAC_TRUE;
4826 }
4827
4828 #if defined(__clang__)
4829 __attribute__((no_sanitize("signed-integer-overflow")))
4830 #endif
4831 static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4832 {
4833 drflac_uint32 i;
4834
4835 DRFLAC_ASSERT(bs != NULL);
4836 DRFLAC_ASSERT(unencodedBitsPerSample <= 31); /* <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31. */
4837 DRFLAC_ASSERT(pSamplesOut != NULL);
4838
4839 for (i = 0; i < count; ++i) {
4840 if (unencodedBitsPerSample > 0) {
4841 if (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) {
4842 return DRFLAC_FALSE;
4843 }
4844 } else {
4845 pSamplesOut[i] = 0;
4846 }
4847
4848 if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
4849 pSamplesOut[i] += drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
4850 } else {
4851 pSamplesOut[i] += drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
4852 }
4853 }
4854
4855 return DRFLAC_TRUE;
4856 }
4857
4858
4859 /*
4860 Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called
4861 when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be ignored. The
4862 <blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
4863 */
4864 static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
4865 {
4866 drflac_uint8 residualMethod;
4867 drflac_uint8 partitionOrder;
4868 drflac_uint32 samplesInPartition;
4869 drflac_uint32 partitionsRemaining;
4870
4871 DRFLAC_ASSERT(bs != NULL);
4872 DRFLAC_ASSERT(blockSize != 0);
4873 DRFLAC_ASSERT(pDecodedSamples != NULL); /* <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode? */
4874
4875 if (!drflac__read_uint8(bs, 2, &residualMethod)) {
4876 return DRFLAC_FALSE;
4877 }
4878
4879 if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4880 return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */
4881 }
4882
4883 /* Ignore the first <order> values. */
4884 pDecodedSamples += lpcOrder;
4885
4886 if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
4887 return DRFLAC_FALSE;
4888 }
4889
4890 /*
4891 From the FLAC spec:
4892 The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
4893 */
4894 if (partitionOrder > 8) {
4895 return DRFLAC_FALSE;
4896 }
4897
4898 /* Validation check. */
4899 if ((blockSize / (1 << partitionOrder)) < lpcOrder) {
4900 return DRFLAC_FALSE;
4901 }
4902
4903 samplesInPartition = (blockSize / (1 << partitionOrder)) - lpcOrder;
4904 partitionsRemaining = (1 << partitionOrder);
4905 for (;;) {
4906 drflac_uint8 riceParam = 0;
4907 if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
4908 if (!drflac__read_uint8(bs, 4, &riceParam)) {
4909 return DRFLAC_FALSE;
4910 }
4911 if (riceParam == 15) {
4912 riceParam = 0xFF;
4913 }
4914 } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4915 if (!drflac__read_uint8(bs, 5, &riceParam)) {
4916 return DRFLAC_FALSE;
4917 }
4918 if (riceParam == 31) {
4919 riceParam = 0xFF;
4920 }
4921 }
4922
4923 if (riceParam != 0xFF) {
4924 if (!drflac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
4925 return DRFLAC_FALSE;
4926 }
4927 } else {
4928 drflac_uint8 unencodedBitsPerSample = 0;
4929 if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
4930 return DRFLAC_FALSE;
4931 }
4932
4933 if (!drflac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
4934 return DRFLAC_FALSE;
4935 }
4936 }
4937
4938 pDecodedSamples += samplesInPartition;
4939
4940 if (partitionsRemaining == 1) {
4941 break;
4942 }
4943
4944 partitionsRemaining -= 1;
4945
4946 if (partitionOrder != 0) {
4947 samplesInPartition = blockSize / (1 << partitionOrder);
4948 }
4949 }
4950
4951 return DRFLAC_TRUE;
4952 }
4953
4954 /*
4955 Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called
4956 when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be set to 0. The
4957 <blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
4958 */
4959 static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 order)
4960 {
4961 drflac_uint8 residualMethod;
4962 drflac_uint8 partitionOrder;
4963 drflac_uint32 samplesInPartition;
4964 drflac_uint32 partitionsRemaining;
4965
4966 DRFLAC_ASSERT(bs != NULL);
4967 DRFLAC_ASSERT(blockSize != 0);
4968
4969 if (!drflac__read_uint8(bs, 2, &residualMethod)) {
4970 return DRFLAC_FALSE;
4971 }
4972
4973 if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4974 return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */
4975 }
4976
4977 if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
4978 return DRFLAC_FALSE;
4979 }
4980
4981 /*
4982 From the FLAC spec:
4983 The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
4984 */
4985 if (partitionOrder > 8) {
4986 return DRFLAC_FALSE;
4987 }
4988
4989 /* Validation check. */
4990 if ((blockSize / (1 << partitionOrder)) <= order) {
4991 return DRFLAC_FALSE;
4992 }
4993
4994 samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
4995 partitionsRemaining = (1 << partitionOrder);
4996 for (;;)
4997 {
4998 drflac_uint8 riceParam = 0;
4999 if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
5000 if (!drflac__read_uint8(bs, 4, &riceParam)) {
5001 return DRFLAC_FALSE;
5002 }
5003 if (riceParam == 15) {
5004 riceParam = 0xFF;
5005 }
5006 } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
5007 if (!drflac__read_uint8(bs, 5, &riceParam)) {
5008 return DRFLAC_FALSE;
5009 }
5010 if (riceParam == 31) {
5011 riceParam = 0xFF;
5012 }
5013 }
5014
5015 if (riceParam != 0xFF) {
5016 if (!drflac__read_and_seek_residual__rice(bs, samplesInPartition, riceParam)) {
5017 return DRFLAC_FALSE;
5018 }
5019 } else {
5020 drflac_uint8 unencodedBitsPerSample = 0;
5021 if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
5022 return DRFLAC_FALSE;
5023 }
5024
5025 if (!drflac__seek_bits(bs, unencodedBitsPerSample * samplesInPartition)) {
5026 return DRFLAC_FALSE;
5027 }
5028 }
5029
5030
5031 if (partitionsRemaining == 1) {
5032 break;
5033 }
5034
5035 partitionsRemaining -= 1;
5036 samplesInPartition = blockSize / (1 << partitionOrder);
5037 }
5038
5039 return DRFLAC_TRUE;
5040 }
5041
5042
5043 static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
5044 {
5045 drflac_uint32 i;
5046
5047 /* Only a single sample needs to be decoded here. */
5048 drflac_int32 sample;
5049 if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
5050 return DRFLAC_FALSE;
5051 }
5052
5053 /*
5054 We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely)
5055 we'll want to look at a more efficient way.
5056 */
5057 for (i = 0; i < blockSize; ++i) {
5058 pDecodedSamples[i] = sample;
5059 }
5060
5061 return DRFLAC_TRUE;
5062 }
5063
5064 static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
5065 {
5066 drflac_uint32 i;
5067
5068 for (i = 0; i < blockSize; ++i) {
5069 drflac_int32 sample;
5070 if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
5071 return DRFLAC_FALSE;
5072 }
5073
5074 pDecodedSamples[i] = sample;
5075 }
5076
5077 return DRFLAC_TRUE;
5078 }
5079
5080 static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
5081 {
5082 drflac_uint32 i;
5083
5084 static drflac_int32 lpcCoefficientsTable[5][4] = {
5085 {0, 0, 0, 0},
5086 {1, 0, 0, 0},
5087 {2, -1, 0, 0},
5088 {3, -3, 1, 0},
5089 {4, -6, 4, -1}
5090 };
5091
5092 /* Warm up samples and coefficients. */
5093 for (i = 0; i < lpcOrder; ++i) {
5094 drflac_int32 sample;
5095 if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
5096 return DRFLAC_FALSE;
5097 }
5098
5099 pDecodedSamples[i] = sample;
5100 }
5101
5102 if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, 4, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
5103 return DRFLAC_FALSE;
5104 }
5105
5106 return DRFLAC_TRUE;
5107 }
5108
5109 static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
5110 {
5111 drflac_uint8 i;
5112 drflac_uint8 lpcPrecision;
5113 drflac_int8 lpcShift;
5114 drflac_int32 coefficients[32];
5115
5116 /* Warm up samples. */
5117 for (i = 0; i < lpcOrder; ++i) {
5118 drflac_int32 sample;
5119 if (!drflac__read_int32(bs, bitsPerSample, &sample)) {
5120 return DRFLAC_FALSE;
5121 }
5122
5123 pDecodedSamples[i] = sample;
5124 }
5125
5126 if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
5127 return DRFLAC_FALSE;
5128 }
5129 if (lpcPrecision == 15) {
5130 return DRFLAC_FALSE; /* Invalid. */
5131 }
5132 lpcPrecision += 1;
5133
5134 if (!drflac__read_int8(bs, 5, &lpcShift)) {
5135 return DRFLAC_FALSE;
5136 }
5137
5138 /*
5139 From the FLAC specification:
5140
5141 Quantized linear predictor coefficient shift needed in bits (NOTE: this number is signed two's-complement)
5142
5143 Emphasis on the "signed two's-complement". In practice there does not seem to be any encoders nor decoders supporting negative shifts. For now dr_flac is
5144 not going to support negative shifts as I don't have any reference files. However, when a reference file comes through I will consider adding support.
5145 */
5146 if (lpcShift < 0) {
5147 return DRFLAC_FALSE;
5148 }
5149
5150 DRFLAC_ZERO_MEMORY(coefficients, sizeof(coefficients));
5151 for (i = 0; i < lpcOrder; ++i) {
5152 if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) {
5153 return DRFLAC_FALSE;
5154 }
5155 }
5156
5157 if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
5158 return DRFLAC_FALSE;
5159 }
5160
5161 return DRFLAC_TRUE;
5162 }
5163
5164
5165 static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
5166 {
5167 const drflac_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
5168 const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1}; /* -1 = reserved. */
5169
5170 DRFLAC_ASSERT(bs != NULL);
5171 DRFLAC_ASSERT(header != NULL);
5172
5173 /* Keep looping until we find a valid sync code. */
5174 for (;;) {
5175 drflac_uint8 crc8 = 0xCE; /* 0xCE = drflac_crc8(0, 0x3FFE, 14); */
5176 drflac_uint8 reserved = 0;
5177 drflac_uint8 blockingStrategy = 0;
5178 drflac_uint8 blockSize = 0;
5179 drflac_uint8 sampleRate = 0;
5180 drflac_uint8 channelAssignment = 0;
5181 drflac_uint8 bitsPerSample = 0;
5182 drflac_bool32 isVariableBlockSize;
5183
5184 if (!drflac__find_and_seek_to_next_sync_code(bs)) {
5185 return DRFLAC_FALSE;
5186 }
5187
5188 if (!drflac__read_uint8(bs, 1, &reserved)) {
5189 return DRFLAC_FALSE;
5190 }
5191 if (reserved == 1) {
5192 continue;
5193 }
5194 crc8 = drflac_crc8(crc8, reserved, 1);
5195
5196 if (!drflac__read_uint8(bs, 1, &blockingStrategy)) {
5197 return DRFLAC_FALSE;
5198 }
5199 crc8 = drflac_crc8(crc8, blockingStrategy, 1);
5200
5201 if (!drflac__read_uint8(bs, 4, &blockSize)) {
5202 return DRFLAC_FALSE;
5203 }
5204 if (blockSize == 0) {
5205 continue;
5206 }
5207 crc8 = drflac_crc8(crc8, blockSize, 4);
5208
5209 if (!drflac__read_uint8(bs, 4, &sampleRate)) {
5210 return DRFLAC_FALSE;
5211 }
5212 crc8 = drflac_crc8(crc8, sampleRate, 4);
5213
5214 if (!drflac__read_uint8(bs, 4, &channelAssignment)) {
5215 return DRFLAC_FALSE;
5216 }
5217 if (channelAssignment > 10) {
5218 continue;
5219 }
5220 crc8 = drflac_crc8(crc8, channelAssignment, 4);
5221
5222 if (!drflac__read_uint8(bs, 3, &bitsPerSample)) {
5223 return DRFLAC_FALSE;
5224 }
5225 if (bitsPerSample == 3 || bitsPerSample == 7) {
5226 continue;
5227 }
5228 crc8 = drflac_crc8(crc8, bitsPerSample, 3);
5229
5230
5231 if (!drflac__read_uint8(bs, 1, &reserved)) {
5232 return DRFLAC_FALSE;
5233 }
5234 if (reserved == 1) {
5235 continue;
5236 }
5237 crc8 = drflac_crc8(crc8, reserved, 1);
5238
5239
5240 isVariableBlockSize = blockingStrategy == 1;
5241 if (isVariableBlockSize) {
5242 drflac_uint64 pcmFrameNumber;
5243 drflac_result result = drflac__read_utf8_coded_number(bs, &pcmFrameNumber, &crc8);
5244 if (result != DRFLAC_SUCCESS) {
5245 if (result == DRFLAC_AT_END) {
5246 return DRFLAC_FALSE;
5247 } else {
5248 continue;
5249 }
5250 }
5251 header->flacFrameNumber = 0;
5252 header->pcmFrameNumber = pcmFrameNumber;
5253 } else {
5254 drflac_uint64 flacFrameNumber = 0;
5255 drflac_result result = drflac__read_utf8_coded_number(bs, &flacFrameNumber, &crc8);
5256 if (result != DRFLAC_SUCCESS) {
5257 if (result == DRFLAC_AT_END) {
5258 return DRFLAC_FALSE;
5259 } else {
5260 continue;
5261 }
5262 }
5263 header->flacFrameNumber = (drflac_uint32)flacFrameNumber; /* <-- Safe cast. */
5264 header->pcmFrameNumber = 0;
5265 }
5266
5267
5268 DRFLAC_ASSERT(blockSize > 0);
5269 if (blockSize == 1) {
5270 header->blockSizeInPCMFrames = 192;
5271 } else if (blockSize <= 5) {
5272 DRFLAC_ASSERT(blockSize >= 2);
5273 header->blockSizeInPCMFrames = 576 * (1 << (blockSize - 2));
5274 } else if (blockSize == 6) {
5275 if (!drflac__read_uint16(bs, 8, &header->blockSizeInPCMFrames)) {
5276 return DRFLAC_FALSE;
5277 }
5278 crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 8);
5279 header->blockSizeInPCMFrames += 1;
5280 } else if (blockSize == 7) {
5281 if (!drflac__read_uint16(bs, 16, &header->blockSizeInPCMFrames)) {
5282 return DRFLAC_FALSE;
5283 }
5284 crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 16);
5285 if (header->blockSizeInPCMFrames == 0xFFFF) {
5286 return DRFLAC_FALSE; /* Frame is too big. This is the size of the frame minus 1. The STREAMINFO block defines the max block size which is 16-bits. Adding one will make it 17 bits and therefore too big. */
5287 }
5288 header->blockSizeInPCMFrames += 1;
5289 } else {
5290 DRFLAC_ASSERT(blockSize >= 8);
5291 header->blockSizeInPCMFrames = 256 * (1 << (blockSize - 8));
5292 }
5293
5294
5295 if (sampleRate <= 11) {
5296 header->sampleRate = sampleRateTable[sampleRate];
5297 } else if (sampleRate == 12) {
5298 if (!drflac__read_uint32(bs, 8, &header->sampleRate)) {
5299 return DRFLAC_FALSE;
5300 }
5301 crc8 = drflac_crc8(crc8, header->sampleRate, 8);
5302 header->sampleRate *= 1000;
5303 } else if (sampleRate == 13) {
5304 if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
5305 return DRFLAC_FALSE;
5306 }
5307 crc8 = drflac_crc8(crc8, header->sampleRate, 16);
5308 } else if (sampleRate == 14) {
5309 if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
5310 return DRFLAC_FALSE;
5311 }
5312 crc8 = drflac_crc8(crc8, header->sampleRate, 16);
5313 header->sampleRate *= 10;
5314 } else {
5315 continue; /* Invalid. Assume an invalid block. */
5316 }
5317
5318
5319 header->channelAssignment = channelAssignment;
5320
5321 header->bitsPerSample = bitsPerSampleTable[bitsPerSample];
5322 if (header->bitsPerSample == 0) {
5323 header->bitsPerSample = streaminfoBitsPerSample;
5324 }
5325
5326 if (header->bitsPerSample != streaminfoBitsPerSample) {
5327 /* If this subframe has a different bitsPerSample then streaminfo or the first frame, reject it */
5328 return DRFLAC_FALSE;
5329 }
5330
5331 if (!drflac__read_uint8(bs, 8, &header->crc8)) {
5332 return DRFLAC_FALSE;
5333 }
5334
5335 #ifndef DR_FLAC_NO_CRC
5336 if (header->crc8 != crc8) {
5337 continue; /* CRC mismatch. Loop back to the top and find the next sync code. */
5338 }
5339 #endif
5340 return DRFLAC_TRUE;
5341 }
5342 }
5343
5344 static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
5345 {
5346 drflac_uint8 header;
5347 int type;
5348
5349 if (!drflac__read_uint8(bs, 8, &header)) {
5350 return DRFLAC_FALSE;
5351 }
5352
5353 /* First bit should always be 0. */
5354 if ((header & 0x80) != 0) {
5355 return DRFLAC_FALSE;
5356 }
5357
5358 type = (header & 0x7E) >> 1;
5359 if (type == 0) {
5360 pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
5361 } else if (type == 1) {
5362 pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM;
5363 } else {
5364 if ((type & 0x20) != 0) {
5365 pSubframe->subframeType = DRFLAC_SUBFRAME_LPC;
5366 pSubframe->lpcOrder = (drflac_uint8)(type & 0x1F) + 1;
5367 } else if ((type & 0x08) != 0) {
5368 pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED;
5369 pSubframe->lpcOrder = (drflac_uint8)(type & 0x07);
5370 if (pSubframe->lpcOrder > 4) {
5371 pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
5372 pSubframe->lpcOrder = 0;
5373 }
5374 } else {
5375 pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
5376 }
5377 }
5378
5379 if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
5380 return DRFLAC_FALSE;
5381 }
5382
5383 /* Wasted bits per sample. */
5384 pSubframe->wastedBitsPerSample = 0;
5385 if ((header & 0x01) == 1) {
5386 unsigned int wastedBitsPerSample;
5387 if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
5388 return DRFLAC_FALSE;
5389 }
5390 pSubframe->wastedBitsPerSample = (drflac_uint8)wastedBitsPerSample + 1;
5391 }
5392
5393 return DRFLAC_TRUE;
5394 }
5395
5396 static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
5397 {
5398 drflac_subframe* pSubframe;
5399 drflac_uint32 subframeBitsPerSample;
5400
5401 DRFLAC_ASSERT(bs != NULL);
5402 DRFLAC_ASSERT(frame != NULL);
5403
5404 pSubframe = frame->subframes + subframeIndex;
5405 if (!drflac__read_subframe_header(bs, pSubframe)) {
5406 return DRFLAC_FALSE;
5407 }
5408
5409 /* Side channels require an extra bit per sample. Took a while to figure that one out... */
5410 subframeBitsPerSample = frame->header.bitsPerSample;
5411 if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
5412 subframeBitsPerSample += 1;
5413 } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
5414 subframeBitsPerSample += 1;
5415 }
5416
5417 if (subframeBitsPerSample > 32) {
5418 /* libFLAC and ffmpeg reject 33-bit subframes as well */
5419 return DRFLAC_FALSE;
5420 }
5421
5422 /* Need to handle wasted bits per sample. */
5423 if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
5424 return DRFLAC_FALSE;
5425 }
5426 subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
5427
5428 pSubframe->pSamplesS32 = pDecodedSamplesOut;
5429
5430 switch (pSubframe->subframeType)
5431 {
5432 case DRFLAC_SUBFRAME_CONSTANT:
5433 {
5434 drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
5435 } break;
5436
5437 case DRFLAC_SUBFRAME_VERBATIM:
5438 {
5439 drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
5440 } break;
5441
5442 case DRFLAC_SUBFRAME_FIXED:
5443 {
5444 drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
5445 } break;
5446
5447 case DRFLAC_SUBFRAME_LPC:
5448 {
5449 drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
5450 } break;
5451
5452 default: return DRFLAC_FALSE;
5453 }
5454
5455 return DRFLAC_TRUE;
5456 }
5457
5458 static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
5459 {
5460 drflac_subframe* pSubframe;
5461 drflac_uint32 subframeBitsPerSample;
5462
5463 DRFLAC_ASSERT(bs != NULL);
5464 DRFLAC_ASSERT(frame != NULL);
5465
5466 pSubframe = frame->subframes + subframeIndex;
5467 if (!drflac__read_subframe_header(bs, pSubframe)) {
5468 return DRFLAC_FALSE;
5469 }
5470
5471 /* Side channels require an extra bit per sample. Took a while to figure that one out... */
5472 subframeBitsPerSample = frame->header.bitsPerSample;
5473 if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
5474 subframeBitsPerSample += 1;
5475 } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
5476 subframeBitsPerSample += 1;
5477 }
5478
5479 /* Need to handle wasted bits per sample. */
5480 if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
5481 return DRFLAC_FALSE;
5482 }
5483 subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
5484
5485 pSubframe->pSamplesS32 = NULL;
5486
5487 switch (pSubframe->subframeType)
5488 {
5489 case DRFLAC_SUBFRAME_CONSTANT:
5490 {
5491 if (!drflac__seek_bits(bs, subframeBitsPerSample)) {
5492 return DRFLAC_FALSE;
5493 }
5494 } break;
5495
5496 case DRFLAC_SUBFRAME_VERBATIM:
5497 {
5498 unsigned int bitsToSeek = frame->header.blockSizeInPCMFrames * subframeBitsPerSample;
5499 if (!drflac__seek_bits(bs, bitsToSeek)) {
5500 return DRFLAC_FALSE;
5501 }
5502 } break;
5503
5504 case DRFLAC_SUBFRAME_FIXED:
5505 {
5506 unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
5507 if (!drflac__seek_bits(bs, bitsToSeek)) {
5508 return DRFLAC_FALSE;
5509 }
5510
5511 if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
5512 return DRFLAC_FALSE;
5513 }
5514 } break;
5515
5516 case DRFLAC_SUBFRAME_LPC:
5517 {
5518 drflac_uint8 lpcPrecision;
5519
5520 unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
5521 if (!drflac__seek_bits(bs, bitsToSeek)) {
5522 return DRFLAC_FALSE;
5523 }
5524
5525 if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
5526 return DRFLAC_FALSE;
5527 }
5528 if (lpcPrecision == 15) {
5529 return DRFLAC_FALSE; /* Invalid. */
5530 }
5531 lpcPrecision += 1;
5532
5533
5534 bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5; /* +5 for shift. */
5535 if (!drflac__seek_bits(bs, bitsToSeek)) {
5536 return DRFLAC_FALSE;
5537 }
5538
5539 if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
5540 return DRFLAC_FALSE;
5541 }
5542 } break;
5543
5544 default: return DRFLAC_FALSE;
5545 }
5546
5547 return DRFLAC_TRUE;
5548 }
5549
5550
5551 static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
5552 {
5553 drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
5554
5555 DRFLAC_ASSERT(channelAssignment <= 10);
5556 return lookup[channelAssignment];
5557 }
5558
5559 static drflac_result drflac__decode_flac_frame(drflac* pFlac)
5560 {
5561 int channelCount;
5562 int i;
5563 drflac_uint8 paddingSizeInBits;
5564 drflac_uint16 desiredCRC16;
5565 #ifndef DR_FLAC_NO_CRC
5566 drflac_uint16 actualCRC16;
5567 #endif
5568
5569 /* This function should be called while the stream is sitting on the first byte after the frame header. */
5570 DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));
5571
5572 /* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */
5573 if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames) {
5574 return DRFLAC_ERROR;
5575 }
5576
5577 /* The number of channels in the frame must match the channel count from the STREAMINFO block. */
5578 channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
5579 if (channelCount != (int)pFlac->channels) {
5580 return DRFLAC_ERROR;
5581 }
5582
5583 for (i = 0; i < channelCount; ++i) {
5584 if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
5585 return DRFLAC_ERROR;
5586 }
5587 }
5588
5589 paddingSizeInBits = (drflac_uint8)(DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7);
5590 if (paddingSizeInBits > 0) {
5591 drflac_uint8 padding = 0;
5592 if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
5593 return DRFLAC_AT_END;
5594 }
5595 }
5596
5597 #ifndef DR_FLAC_NO_CRC
5598 actualCRC16 = drflac__flush_crc16(&pFlac->bs);
5599 #endif
5600 if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
5601 return DRFLAC_AT_END;
5602 }
5603
5604 #ifndef DR_FLAC_NO_CRC
5605 if (actualCRC16 != desiredCRC16) {
5606 return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */
5607 }
5608 #endif
5609
5610 pFlac->currentFLACFrame.pcmFramesRemaining = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
5611
5612 return DRFLAC_SUCCESS;
5613 }
5614
5615 static drflac_result drflac__seek_flac_frame(drflac* pFlac)
5616 {
5617 int channelCount;
5618 int i;
5619 drflac_uint16 desiredCRC16;
5620 #ifndef DR_FLAC_NO_CRC
5621 drflac_uint16 actualCRC16;
5622 #endif
5623
5624 channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
5625 for (i = 0; i < channelCount; ++i) {
5626 if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i)) {
5627 return DRFLAC_ERROR;
5628 }
5629 }
5630
5631 /* Padding. */
5632 if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
5633 return DRFLAC_ERROR;
5634 }
5635
5636 /* CRC. */
5637 #ifndef DR_FLAC_NO_CRC
5638 actualCRC16 = drflac__flush_crc16(&pFlac->bs);
5639 #endif
5640 if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
5641 return DRFLAC_AT_END;
5642 }
5643
5644 #ifndef DR_FLAC_NO_CRC
5645 if (actualCRC16 != desiredCRC16) {
5646 return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */
5647 }
5648 #endif
5649
5650 return DRFLAC_SUCCESS;
5651 }
5652
5653 static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac)
5654 {
5655 DRFLAC_ASSERT(pFlac != NULL);
5656
5657 for (;;) {
5658 drflac_result result;
5659
5660 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5661 return DRFLAC_FALSE;
5662 }
5663
5664 result = drflac__decode_flac_frame(pFlac);
5665 if (result != DRFLAC_SUCCESS) {
5666 if (result == DRFLAC_CRC_MISMATCH) {
5667 continue; /* CRC mismatch. Skip to the next frame. */
5668 } else {
5669 return DRFLAC_FALSE;
5670 }
5671 }
5672
5673 return DRFLAC_TRUE;
5674 }
5675 }
5676
5677 static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
5678 {
5679 drflac_uint64 firstPCMFrame;
5680 drflac_uint64 lastPCMFrame;
5681
5682 DRFLAC_ASSERT(pFlac != NULL);
5683
5684 firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
5685 if (firstPCMFrame == 0) {
5686 firstPCMFrame = ((drflac_uint64)pFlac->currentFLACFrame.header.flacFrameNumber) * pFlac->maxBlockSizeInPCMFrames;
5687 }
5688
5689 lastPCMFrame = firstPCMFrame + pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
5690 if (lastPCMFrame > 0) {
5691 lastPCMFrame -= 1; /* Needs to be zero based. */
5692 }
5693
5694 if (pFirstPCMFrame) {
5695 *pFirstPCMFrame = firstPCMFrame;
5696 }
5697 if (pLastPCMFrame) {
5698 *pLastPCMFrame = lastPCMFrame;
5699 }
5700 }
5701
5702 static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
5703 {
5704 drflac_bool32 result;
5705
5706 DRFLAC_ASSERT(pFlac != NULL);
5707
5708 result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
5709
5710 DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
5711 pFlac->currentPCMFrame = 0;
5712
5713 return result;
5714 }
5715
5716 static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac)
5717 {
5718 /* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */
5719 DRFLAC_ASSERT(pFlac != NULL);
5720 return drflac__seek_flac_frame(pFlac);
5721 }
5722
5723
5724 static drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 pcmFramesToSeek)
5725 {
5726 drflac_uint64 pcmFramesRead = 0;
5727 while (pcmFramesToSeek > 0) {
5728 if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
5729 if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
5730 break; /* Couldn't read the next frame, so just break from the loop and return. */
5731 }
5732 } else {
5733 if (pFlac->currentFLACFrame.pcmFramesRemaining > pcmFramesToSeek) {
5734 pcmFramesRead += pcmFramesToSeek;
5735 pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)pcmFramesToSeek; /* <-- Safe cast. Will always be < currentFrame.pcmFramesRemaining < 65536. */
5736 pcmFramesToSeek = 0;
5737 } else {
5738 pcmFramesRead += pFlac->currentFLACFrame.pcmFramesRemaining;
5739 pcmFramesToSeek -= pFlac->currentFLACFrame.pcmFramesRemaining;
5740 pFlac->currentFLACFrame.pcmFramesRemaining = 0;
5741 }
5742 }
5743 }
5744
5745 pFlac->currentPCMFrame += pcmFramesRead;
5746 return pcmFramesRead;
5747 }
5748
5749
5750 static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac* pFlac, drflac_uint64 pcmFrameIndex)
5751 {
5752 drflac_bool32 isMidFrame = DRFLAC_FALSE;
5753 drflac_uint64 runningPCMFrameCount;
5754
5755 DRFLAC_ASSERT(pFlac != NULL);
5756
5757 /* If we are seeking forward we start from the current position. Otherwise we need to start all the way from the start of the file. */
5758 if (pcmFrameIndex >= pFlac->currentPCMFrame) {
5759 /* Seeking forward. Need to seek from the current position. */
5760 runningPCMFrameCount = pFlac->currentPCMFrame;
5761
5762 /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
5763 if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
5764 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5765 return DRFLAC_FALSE;
5766 }
5767 } else {
5768 isMidFrame = DRFLAC_TRUE;
5769 }
5770 } else {
5771 /* Seeking backwards. Need to seek from the start of the file. */
5772 runningPCMFrameCount = 0;
5773
5774 /* Move back to the start. */
5775 if (!drflac__seek_to_first_frame(pFlac)) {
5776 return DRFLAC_FALSE;
5777 }
5778
5779 /* Decode the first frame in preparation for sample-exact seeking below. */
5780 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5781 return DRFLAC_FALSE;
5782 }
5783 }
5784
5785 /*
5786 We need to as quickly as possible find the frame that contains the target sample. To do this, we iterate over each frame and inspect its
5787 header. If based on the header we can determine that the frame contains the sample, we do a full decode of that frame.
5788 */
5789 for (;;) {
5790 drflac_uint64 pcmFrameCountInThisFLACFrame;
5791 drflac_uint64 firstPCMFrameInFLACFrame = 0;
5792 drflac_uint64 lastPCMFrameInFLACFrame = 0;
5793
5794 drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
5795
5796 pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
5797 if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
5798 /*
5799 The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
5800 it never existed and keep iterating.
5801 */
5802 drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
5803
5804 if (!isMidFrame) {
5805 drflac_result result = drflac__decode_flac_frame(pFlac);
5806 if (result == DRFLAC_SUCCESS) {
5807 /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
5808 return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */
5809 } else {
5810 if (result == DRFLAC_CRC_MISMATCH) {
5811 goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
5812 } else {
5813 return DRFLAC_FALSE;
5814 }
5815 }
5816 } else {
5817 /* We started seeking mid-frame which means we need to skip the frame decoding part. */
5818 return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
5819 }
5820 } else {
5821 /*
5822 It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
5823 frame never existed and leave the running sample count untouched.
5824 */
5825 if (!isMidFrame) {
5826 drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
5827 if (result == DRFLAC_SUCCESS) {
5828 runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
5829 } else {
5830 if (result == DRFLAC_CRC_MISMATCH) {
5831 goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
5832 } else {
5833 return DRFLAC_FALSE;
5834 }
5835 }
5836 } else {
5837 /*
5838 We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
5839 drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
5840 */
5841 runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
5842 pFlac->currentFLACFrame.pcmFramesRemaining = 0;
5843 isMidFrame = DRFLAC_FALSE;
5844 }
5845
5846 /* If we are seeking to the end of the file and we've just hit it, we're done. */
5847 if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
5848 return DRFLAC_TRUE;
5849 }
5850 }
5851
5852 next_iteration:
5853 /* Grab the next frame in preparation for the next iteration. */
5854 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5855 return DRFLAC_FALSE;
5856 }
5857 }
5858 }
5859
5860
5861 #if !defined(DR_FLAC_NO_CRC)
5862 /*
5863 We use an average compression ratio to determine our approximate start location. FLAC files are generally about 50%-70% the size of their
5864 uncompressed counterparts so we'll use this as a basis. I'm going to split the middle and use a factor of 0.6 to determine the starting
5865 location.
5866 */
5867 #define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f
5868
5869 static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
5870 {
5871 DRFLAC_ASSERT(pFlac != NULL);
5872 DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
5873 DRFLAC_ASSERT(targetByte >= rangeLo);
5874 DRFLAC_ASSERT(targetByte <= rangeHi);
5875
5876 *pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;
5877
5878 for (;;) {
5879 /* After rangeLo == rangeHi == targetByte fails, we need to break out. */
5880 drflac_uint64 lastTargetByte = targetByte;
5881
5882 /* When seeking to a byte, failure probably means we've attempted to seek beyond the end of the stream. To counter this we just halve it each attempt. */
5883 if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
5884 /* If we couldn't even seek to the first byte in the stream we have a problem. Just abandon the whole thing. */
5885 if (targetByte == 0) {
5886 drflac__seek_to_first_frame(pFlac); /* Try to recover. */
5887 return DRFLAC_FALSE;
5888 }
5889
5890 /* Halve the byte location and continue. */
5891 targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5892 rangeHi = targetByte;
5893 } else {
5894 /* Getting here should mean that we have seeked to an appropriate byte. */
5895
5896 /* Clear the details of the FLAC frame so we don't misreport data. */
5897 DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
5898
5899 /*
5900 Now seek to the next FLAC frame. We need to decode the entire frame (not just the header) because it's possible for the header to incorrectly pass the
5901 CRC check and return bad data. We need to decode the entire frame to be more certain. Although this seems unlikely, this has happened to me in testing
5902 so it needs to stay this way for now.
5903 */
5904 #if 1
5905 if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
5906 /* Halve the byte location and continue. */
5907 targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5908 rangeHi = targetByte;
5909 } else {
5910 break;
5911 }
5912 #else
5913 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5914 /* Halve the byte location and continue. */
5915 targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5916 rangeHi = targetByte;
5917 } else {
5918 break;
5919 }
5920 #endif
5921 }
5922
5923 /* We already tried this byte and there are no more to try, break out. */
5924 if(targetByte == lastTargetByte) {
5925 return DRFLAC_FALSE;
5926 }
5927 }
5928
5929 /* The current PCM frame needs to be updated based on the frame we just seeked to. */
5930 drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
5931
5932 DRFLAC_ASSERT(targetByte <= rangeHi);
5933
5934 *pLastSuccessfulSeekOffset = targetByte;
5935 return DRFLAC_TRUE;
5936 }
5937
5938 static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 offset)
5939 {
5940 /* This section of code would be used if we were only decoding the FLAC frame header when calling drflac__seek_to_approximate_flac_frame_to_byte(). */
5941 #if 0
5942 if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
5943 /* We failed to decode this frame which may be due to it being corrupt. We'll just use the next valid FLAC frame. */
5944 if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
5945 return DRFLAC_FALSE;
5946 }
5947 }
5948 #endif
5949
5950 return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
5951 }
5952
5953
5954 static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
5955 {
5956 /* This assumes pFlac->currentPCMFrame is sitting on byteRangeLo upon entry. */
5957
5958 drflac_uint64 targetByte;
5959 drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
5960 drflac_uint64 pcmRangeHi = 0;
5961 drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
5962 drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
5963 drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
5964
5965 targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
5966 if (targetByte > byteRangeHi) {
5967 targetByte = byteRangeHi;
5968 }
5969
5970 for (;;) {
5971 if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
5972 /* We found a FLAC frame. We need to check if it contains the sample we're looking for. */
5973 drflac_uint64 newPCMRangeLo;
5974 drflac_uint64 newPCMRangeHi;
5975 drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
5976
5977 /* If we selected the same frame, it means we should be pretty close. Just decode the rest. */
5978 if (pcmRangeLo == newPCMRangeLo) {
5979 if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
5980 break; /* Failed to seek to closest frame. */
5981 }
5982
5983 if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
5984 return DRFLAC_TRUE;
5985 } else {
5986 break; /* Failed to seek forward. */
5987 }
5988 }
5989
5990 pcmRangeLo = newPCMRangeLo;
5991 pcmRangeHi = newPCMRangeHi;
5992
5993 if (pcmRangeLo <= pcmFrameIndex && pcmRangeHi >= pcmFrameIndex) {
5994 /* The target PCM frame is in this FLAC frame. */
5995 if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
5996 return DRFLAC_TRUE;
5997 } else {
5998 break; /* Failed to seek to FLAC frame. */
5999 }
6000 } else {
6001 const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
6002
6003 if (pcmRangeLo > pcmFrameIndex) {
6004 /* We seeked too far forward. We need to move our target byte backward and try again. */
6005 byteRangeHi = lastSuccessfulSeekOffset;
6006 if (byteRangeLo > byteRangeHi) {
6007 byteRangeLo = byteRangeHi;
6008 }
6009
6010 targetByte = byteRangeLo + ((byteRangeHi - byteRangeLo) / 2);
6011 if (targetByte < byteRangeLo) {
6012 targetByte = byteRangeLo;
6013 }
6014 } else /*if (pcmRangeHi < pcmFrameIndex)*/ {
6015 /* We didn't seek far enough. We need to move our target byte forward and try again. */
6016
6017 /* If we're close enough we can just seek forward. */
6018 if ((pcmFrameIndex - pcmRangeLo) < seekForwardThreshold) {
6019 if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
6020 return DRFLAC_TRUE;
6021 } else {
6022 break; /* Failed to seek to FLAC frame. */
6023 }
6024 } else {
6025 byteRangeLo = lastSuccessfulSeekOffset;
6026 if (byteRangeHi < byteRangeLo) {
6027 byteRangeHi = byteRangeLo;
6028 }
6029
6030 targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
6031 if (targetByte > byteRangeHi) {
6032 targetByte = byteRangeHi;
6033 }
6034
6035 if (closestSeekOffsetBeforeTargetPCMFrame < lastSuccessfulSeekOffset) {
6036 closestSeekOffsetBeforeTargetPCMFrame = lastSuccessfulSeekOffset;
6037 }
6038 }
6039 }
6040 }
6041 } else {
6042 /* Getting here is really bad. We just recover as best we can, but moving to the first frame in the stream, and then abort. */
6043 break;
6044 }
6045 }
6046
6047 drflac__seek_to_first_frame(pFlac); /* <-- Try to recover. */
6048 return DRFLAC_FALSE;
6049 }
6050
6051 static drflac_bool32 drflac__seek_to_pcm_frame__binary_search(drflac* pFlac, drflac_uint64 pcmFrameIndex)
6052 {
6053 drflac_uint64 byteRangeLo;
6054 drflac_uint64 byteRangeHi;
6055 drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
6056
6057 /* Our algorithm currently assumes the FLAC stream is currently sitting at the start. */
6058 if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
6059 return DRFLAC_FALSE;
6060 }
6061
6062 /* If we're close enough to the start, just move to the start and seek forward. */
6063 if (pcmFrameIndex < seekForwardThreshold) {
6064 return drflac__seek_forward_by_pcm_frames(pFlac, pcmFrameIndex) == pcmFrameIndex;
6065 }
6066
6067 /*
6068 Our starting byte range is the byte position of the first FLAC frame and the approximate end of the file as if it were completely uncompressed. This ensures
6069 the entire file is included, even though most of the time it'll exceed the end of the actual stream. This is OK as the frame searching logic will handle it.
6070 */
6071 byteRangeLo = pFlac->firstFLACFramePosInBytes;
6072 byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
6073
6074 return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
6075 }
6076 #endif /* !DR_FLAC_NO_CRC */
6077
6078 static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac_uint64 pcmFrameIndex)
6079 {
6080 drflac_uint32 iClosestSeekpoint = 0;
6081 drflac_bool32 isMidFrame = DRFLAC_FALSE;
6082 drflac_uint64 runningPCMFrameCount;
6083 drflac_uint32 iSeekpoint;
6084
6085
6086 DRFLAC_ASSERT(pFlac != NULL);
6087
6088 if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {
6089 return DRFLAC_FALSE;
6090 }
6091
6092 /* Do not use the seektable if pcmFramIndex is not coverd by it. */
6093 if (pFlac->pSeekpoints[0].firstPCMFrame > pcmFrameIndex) {
6094 return DRFLAC_FALSE;
6095 }
6096
6097 for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
6098 if (pFlac->pSeekpoints[iSeekpoint].firstPCMFrame >= pcmFrameIndex) {
6099 break;
6100 }
6101
6102 iClosestSeekpoint = iSeekpoint;
6103 }
6104
6105 /* There's been cases where the seek table contains only zeros. We need to do some basic validation on the closest seekpoint. */
6106 if (pFlac->pSeekpoints[iClosestSeekpoint].pcmFrameCount == 0 || pFlac->pSeekpoints[iClosestSeekpoint].pcmFrameCount > pFlac->maxBlockSizeInPCMFrames) {
6107 return DRFLAC_FALSE;
6108 }
6109 if (pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame > pFlac->totalPCMFrameCount && pFlac->totalPCMFrameCount > 0) {
6110 return DRFLAC_FALSE;
6111 }
6112
6113 #if !defined(DR_FLAC_NO_CRC)
6114 /* At this point we should know the closest seek point. We can use a binary search for this. We need to know the total sample count for this. */
6115 if (pFlac->totalPCMFrameCount > 0) {
6116 drflac_uint64 byteRangeLo;
6117 drflac_uint64 byteRangeHi;
6118
6119 byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
6120 byteRangeLo = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset;
6121
6122 /*
6123 If our closest seek point is not the last one, we only need to search between it and the next one. The section below calculates an appropriate starting
6124 value for byteRangeHi which will clamp it appropriately.
6125
6126 Note that the next seekpoint must have an offset greater than the closest seekpoint because otherwise our binary search algorithm will break down. There
6127 have been cases where a seektable consists of seek points where every byte offset is set to 0 which causes problems. If this happens we need to abort.
6128 */
6129 if (iClosestSeekpoint < pFlac->seekpointCount-1) {
6130 drflac_uint32 iNextSeekpoint = iClosestSeekpoint + 1;
6131
6132 /* Basic validation on the seekpoints to ensure they're usable. */
6133 if (pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset >= pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset || pFlac->pSeekpoints[iNextSeekpoint].pcmFrameCount == 0) {
6134 return DRFLAC_FALSE; /* The next seekpoint doesn't look right. The seek table cannot be trusted from here. Abort. */
6135 }
6136
6137 if (pFlac->pSeekpoints[iNextSeekpoint].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) { /* Make sure it's not a placeholder seekpoint. */
6138 byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset - 1; /* byteRangeHi must be zero based. */
6139 }
6140 }
6141
6142 if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
6143 if (drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6144 drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
6145
6146 if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
6147 return DRFLAC_TRUE;
6148 }
6149 }
6150 }
6151 }
6152 #endif /* !DR_FLAC_NO_CRC */
6153
6154 /* Getting here means we need to use a slower algorithm because the binary search method failed or cannot be used. */
6155
6156 /*
6157 If we are seeking forward and the closest seekpoint is _before_ the current sample, we just seek forward from where we are. Otherwise we start seeking
6158 from the seekpoint's first sample.
6159 */
6160 if (pcmFrameIndex >= pFlac->currentPCMFrame && pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame <= pFlac->currentPCMFrame) {
6161 /* Optimized case. Just seek forward from where we are. */
6162 runningPCMFrameCount = pFlac->currentPCMFrame;
6163
6164 /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
6165 if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
6166 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6167 return DRFLAC_FALSE;
6168 }
6169 } else {
6170 isMidFrame = DRFLAC_TRUE;
6171 }
6172 } else {
6173 /* Slower case. Seek to the start of the seekpoint and then seek forward from there. */
6174 runningPCMFrameCount = pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame;
6175
6176 if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
6177 return DRFLAC_FALSE;
6178 }
6179
6180 /* Grab the frame the seekpoint is sitting on in preparation for the sample-exact seeking below. */
6181 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6182 return DRFLAC_FALSE;
6183 }
6184 }
6185
6186 for (;;) {
6187 drflac_uint64 pcmFrameCountInThisFLACFrame;
6188 drflac_uint64 firstPCMFrameInFLACFrame = 0;
6189 drflac_uint64 lastPCMFrameInFLACFrame = 0;
6190
6191 drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
6192
6193 pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
6194 if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
6195 /*
6196 The sample should be in this frame. We need to fully decode it, but if it's an invalid frame (a CRC mismatch) we need to pretend
6197 it never existed and keep iterating.
6198 */
6199 drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
6200
6201 if (!isMidFrame) {
6202 drflac_result result = drflac__decode_flac_frame(pFlac);
6203 if (result == DRFLAC_SUCCESS) {
6204 /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
6205 return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */
6206 } else {
6207 if (result == DRFLAC_CRC_MISMATCH) {
6208 goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
6209 } else {
6210 return DRFLAC_FALSE;
6211 }
6212 }
6213 } else {
6214 /* We started seeking mid-frame which means we need to skip the frame decoding part. */
6215 return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
6216 }
6217 } else {
6218 /*
6219 It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
6220 frame never existed and leave the running sample count untouched.
6221 */
6222 if (!isMidFrame) {
6223 drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
6224 if (result == DRFLAC_SUCCESS) {
6225 runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
6226 } else {
6227 if (result == DRFLAC_CRC_MISMATCH) {
6228 goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
6229 } else {
6230 return DRFLAC_FALSE;
6231 }
6232 }
6233 } else {
6234 /*
6235 We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
6236 drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
6237 */
6238 runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
6239 pFlac->currentFLACFrame.pcmFramesRemaining = 0;
6240 isMidFrame = DRFLAC_FALSE;
6241 }
6242
6243 /* If we are seeking to the end of the file and we've just hit it, we're done. */
6244 if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
6245 return DRFLAC_TRUE;
6246 }
6247 }
6248
6249 next_iteration:
6250 /* Grab the next frame in preparation for the next iteration. */
6251 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6252 return DRFLAC_FALSE;
6253 }
6254 }
6255 }
6256
6257
6258 #ifndef DR_FLAC_NO_OGG
6259 typedef struct
6260 {
6261 drflac_uint8 capturePattern[4]; /* Should be "OggS" */
6262 drflac_uint8 structureVersion; /* Always 0. */
6263 drflac_uint8 headerType;
6264 drflac_uint64 granulePosition;
6265 drflac_uint32 serialNumber;
6266 drflac_uint32 sequenceNumber;
6267 drflac_uint32 checksum;
6268 drflac_uint8 segmentCount;
6269 drflac_uint8 segmentTable[255];
6270 } drflac_ogg_page_header;
6271 #endif
6272
6273 typedef struct
6274 {
6275 drflac_read_proc onRead;
6276 drflac_seek_proc onSeek;
6277 drflac_meta_proc onMeta;
6278 drflac_container container;
6279 void* pUserData;
6280 void* pUserDataMD;
6281 drflac_uint32 sampleRate;
6282 drflac_uint8 channels;
6283 drflac_uint8 bitsPerSample;
6284 drflac_uint64 totalPCMFrameCount;
6285 drflac_uint16 maxBlockSizeInPCMFrames;
6286 drflac_uint64 runningFilePos;
6287 drflac_bool32 hasStreamInfoBlock;
6288 drflac_bool32 hasMetadataBlocks;
6289 drflac_bs bs; /* <-- A bit streamer is required for loading data during initialization. */
6290 drflac_frame_header firstFrameHeader; /* <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block. */
6291
6292 #ifndef DR_FLAC_NO_OGG
6293 drflac_uint32 oggSerial;
6294 drflac_uint64 oggFirstBytePos;
6295 drflac_ogg_page_header oggBosHeader;
6296 #endif
6297 } drflac_init_info;
6298
6299 static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
6300 {
6301 blockHeader = drflac__be2host_32(blockHeader);
6302 *isLastBlock = (drflac_uint8)((blockHeader & 0x80000000UL) >> 31);
6303 *blockType = (drflac_uint8)((blockHeader & 0x7F000000UL) >> 24);
6304 *blockSize = (blockHeader & 0x00FFFFFFUL);
6305 }
6306
6307 static DRFLAC_INLINE drflac_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
6308 {
6309 drflac_uint32 blockHeader;
6310
6311 *blockSize = 0;
6312 if (onRead(pUserData, &blockHeader, 4) != 4) {
6313 return DRFLAC_FALSE;
6314 }
6315
6316 drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
6317 return DRFLAC_TRUE;
6318 }
6319
6320 static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
6321 {
6322 drflac_uint32 blockSizes;
6323 drflac_uint64 frameSizes = 0;
6324 drflac_uint64 importantProps;
6325 drflac_uint8 md5[16];
6326
6327 /* min/max block size. */
6328 if (onRead(pUserData, &blockSizes, 4) != 4) {
6329 return DRFLAC_FALSE;
6330 }
6331
6332 /* min/max frame size. */
6333 if (onRead(pUserData, &frameSizes, 6) != 6) {
6334 return DRFLAC_FALSE;
6335 }
6336
6337 /* Sample rate, channels, bits per sample and total sample count. */
6338 if (onRead(pUserData, &importantProps, 8) != 8) {
6339 return DRFLAC_FALSE;
6340 }
6341
6342 /* MD5 */
6343 if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
6344 return DRFLAC_FALSE;
6345 }
6346
6347 blockSizes = drflac__be2host_32(blockSizes);
6348 frameSizes = drflac__be2host_64(frameSizes);
6349 importantProps = drflac__be2host_64(importantProps);
6350
6351 pStreamInfo->minBlockSizeInPCMFrames = (drflac_uint16)((blockSizes & 0xFFFF0000) >> 16);
6352 pStreamInfo->maxBlockSizeInPCMFrames = (drflac_uint16) (blockSizes & 0x0000FFFF);
6353 pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
6354 pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 0)) >> 16);
6355 pStreamInfo->sampleRate = (drflac_uint32)((importantProps & (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
6356 pStreamInfo->channels = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
6357 pStreamInfo->bitsPerSample = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
6358 pStreamInfo->totalPCMFrameCount = ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
6359 DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
6360
6361 return DRFLAC_TRUE;
6362 }
6363
6364
6365 static void* drflac__malloc_default(size_t sz, void* pUserData)
6366 {
6367 (void)pUserData;
6368 return DRFLAC_MALLOC(sz);
6369 }
6370
6371 static void* drflac__realloc_default(void* p, size_t sz, void* pUserData)
6372 {
6373 (void)pUserData;
6374 return DRFLAC_REALLOC(p, sz);
6375 }
6376
6377 static void drflac__free_default(void* p, void* pUserData)
6378 {
6379 (void)pUserData;
6380 DRFLAC_FREE(p);
6381 }
6382
6383
6384 static void* drflac__malloc_from_callbacks(size_t sz, const drflac_allocation_callbacks* pAllocationCallbacks)
6385 {
6386 if (pAllocationCallbacks == NULL) {
6387 return NULL;
6388 }
6389
6390 if (pAllocationCallbacks->onMalloc != NULL) {
6391 return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
6392 }
6393
6394 /* Try using realloc(). */
6395 if (pAllocationCallbacks->onRealloc != NULL) {
6396 return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
6397 }
6398
6399 return NULL;
6400 }
6401
6402 static void* drflac__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drflac_allocation_callbacks* pAllocationCallbacks)
6403 {
6404 if (pAllocationCallbacks == NULL) {
6405 return NULL;
6406 }
6407
6408 if (pAllocationCallbacks->onRealloc != NULL) {
6409 return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
6410 }
6411
6412 /* Try emulating realloc() in terms of malloc()/free(). */
6413 if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
6414 void* p2;
6415
6416 p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
6417 if (p2 == NULL) {
6418 return NULL;
6419 }
6420
6421 if (p != NULL) {
6422 DRFLAC_COPY_MEMORY(p2, p, szOld);
6423 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
6424 }
6425
6426 return p2;
6427 }
6428
6429 return NULL;
6430 }
6431
6432 static void drflac__free_from_callbacks(void* p, const drflac_allocation_callbacks* pAllocationCallbacks)
6433 {
6434 if (p == NULL || pAllocationCallbacks == NULL) {
6435 return;
6436 }
6437
6438 if (pAllocationCallbacks->onFree != NULL) {
6439 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
6440 }
6441 }
6442
6443
6444 static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeektableSize, drflac_allocation_callbacks* pAllocationCallbacks)
6445 {
6446 /*
6447 We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
6448 we'll be sitting on byte 42.
6449 */
6450 drflac_uint64 runningFilePos = 42;
6451 drflac_uint64 seektablePos = 0;
6452 drflac_uint32 seektableSize = 0;
6453
6454 for (;;) {
6455 drflac_metadata metadata;
6456 drflac_uint8 isLastBlock = 0;
6457 drflac_uint8 blockType;
6458 drflac_uint32 blockSize;
6459 if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
6460 return DRFLAC_FALSE;
6461 }
6462 runningFilePos += 4;
6463
6464 metadata.type = blockType;
6465 metadata.pRawData = NULL;
6466 metadata.rawDataSize = 0;
6467
6468 switch (blockType)
6469 {
6470 case DRFLAC_METADATA_BLOCK_TYPE_APPLICATION:
6471 {
6472 if (blockSize < 4) {
6473 return DRFLAC_FALSE;
6474 }
6475
6476 if (onMeta) {
6477 void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6478 if (pRawData == NULL) {
6479 return DRFLAC_FALSE;
6480 }
6481
6482 if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6483 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6484 return DRFLAC_FALSE;
6485 }
6486
6487 metadata.pRawData = pRawData;
6488 metadata.rawDataSize = blockSize;
6489 metadata.data.application.id = drflac__be2host_32(*(drflac_uint32*)pRawData);
6490 metadata.data.application.pData = (const void*)((drflac_uint8*)pRawData + sizeof(drflac_uint32));
6491 metadata.data.application.dataSize = blockSize - sizeof(drflac_uint32);
6492 onMeta(pUserDataMD, &metadata);
6493
6494 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6495 }
6496 } break;
6497
6498 case DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE:
6499 {
6500 seektablePos = runningFilePos;
6501 seektableSize = blockSize;
6502
6503 if (onMeta) {
6504 drflac_uint32 iSeekpoint;
6505 void* pRawData;
6506
6507 pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6508 if (pRawData == NULL) {
6509 return DRFLAC_FALSE;
6510 }
6511
6512 if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6513 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6514 return DRFLAC_FALSE;
6515 }
6516
6517 metadata.pRawData = pRawData;
6518 metadata.rawDataSize = blockSize;
6519 metadata.data.seektable.seekpointCount = blockSize/sizeof(drflac_seekpoint);
6520 metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData;
6521
6522 /* Endian swap. */
6523 for (iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) {
6524 drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint;
6525 pSeekpoint->firstPCMFrame = drflac__be2host_64(pSeekpoint->firstPCMFrame);
6526 pSeekpoint->flacFrameOffset = drflac__be2host_64(pSeekpoint->flacFrameOffset);
6527 pSeekpoint->pcmFrameCount = drflac__be2host_16(pSeekpoint->pcmFrameCount);
6528 }
6529
6530 onMeta(pUserDataMD, &metadata);
6531
6532 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6533 }
6534 } break;
6535
6536 case DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT:
6537 {
6538 if (blockSize < 8) {
6539 return DRFLAC_FALSE;
6540 }
6541
6542 if (onMeta) {
6543 void* pRawData;
6544 const char* pRunningData;
6545 const char* pRunningDataEnd;
6546 drflac_uint32 i;
6547
6548 pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6549 if (pRawData == NULL) {
6550 return DRFLAC_FALSE;
6551 }
6552
6553 if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6554 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6555 return DRFLAC_FALSE;
6556 }
6557
6558 metadata.pRawData = pRawData;
6559 metadata.rawDataSize = blockSize;
6560
6561 pRunningData = (const char*)pRawData;
6562 pRunningDataEnd = (const char*)pRawData + blockSize;
6563
6564 metadata.data.vorbis_comment.vendorLength = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6565
6566 /* Need space for the rest of the block */
6567 if ((pRunningDataEnd - pRunningData) - 4 < (drflac_int64)metadata.data.vorbis_comment.vendorLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6568 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6569 return DRFLAC_FALSE;
6570 }
6571 metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
6572 metadata.data.vorbis_comment.commentCount = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6573
6574 /* Need space for 'commentCount' comments after the block, which at minimum is a drflac_uint32 per comment */
6575 if ((pRunningDataEnd - pRunningData) / sizeof(drflac_uint32) < metadata.data.vorbis_comment.commentCount) { /* <-- Note the order of operations to avoid overflow to a valid value */
6576 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6577 return DRFLAC_FALSE;
6578 }
6579 metadata.data.vorbis_comment.pComments = pRunningData;
6580
6581 /* Check that the comments section is valid before passing it to the callback */
6582 for (i = 0; i < metadata.data.vorbis_comment.commentCount; ++i) {
6583 drflac_uint32 commentLength;
6584
6585 if (pRunningDataEnd - pRunningData < 4) {
6586 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6587 return DRFLAC_FALSE;
6588 }
6589
6590 commentLength = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6591 if (pRunningDataEnd - pRunningData < (drflac_int64)commentLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6592 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6593 return DRFLAC_FALSE;
6594 }
6595 pRunningData += commentLength;
6596 }
6597
6598 onMeta(pUserDataMD, &metadata);
6599
6600 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6601 }
6602 } break;
6603
6604 case DRFLAC_METADATA_BLOCK_TYPE_CUESHEET:
6605 {
6606 if (blockSize < 396) {
6607 return DRFLAC_FALSE;
6608 }
6609
6610 if (onMeta) {
6611 void* pRawData;
6612 const char* pRunningData;
6613 const char* pRunningDataEnd;
6614 drflac_uint8 iTrack;
6615 drflac_uint8 iIndex;
6616
6617 pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6618 if (pRawData == NULL) {
6619 return DRFLAC_FALSE;
6620 }
6621
6622 if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6623 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6624 return DRFLAC_FALSE;
6625 }
6626
6627 metadata.pRawData = pRawData;
6628 metadata.rawDataSize = blockSize;
6629
6630 pRunningData = (const char*)pRawData;
6631 pRunningDataEnd = (const char*)pRawData + blockSize;
6632
6633 DRFLAC_COPY_MEMORY(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
6634 metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8;
6635 metadata.data.cuesheet.isCD = (pRunningData[0] & 0x80) != 0; pRunningData += 259;
6636 metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
6637 metadata.data.cuesheet.pTrackData = pRunningData;
6638
6639 /* Check that the cuesheet tracks are valid before passing it to the callback */
6640 for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
6641 drflac_uint8 indexCount;
6642 drflac_uint32 indexPointSize;
6643
6644 if (pRunningDataEnd - pRunningData < 36) {
6645 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6646 return DRFLAC_FALSE;
6647 }
6648
6649 /* Skip to the index point count */
6650 pRunningData += 35;
6651 indexCount = pRunningData[0]; pRunningData += 1;
6652 indexPointSize = indexCount * sizeof(drflac_cuesheet_track_index);
6653 if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) {
6654 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6655 return DRFLAC_FALSE;
6656 }
6657
6658 /* Endian swap. */
6659 for (iIndex = 0; iIndex < indexCount; ++iIndex) {
6660 drflac_cuesheet_track_index* pTrack = (drflac_cuesheet_track_index*)pRunningData;
6661 pRunningData += sizeof(drflac_cuesheet_track_index);
6662 pTrack->offset = drflac__be2host_64(pTrack->offset);
6663 }
6664 }
6665
6666 onMeta(pUserDataMD, &metadata);
6667
6668 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6669 }
6670 } break;
6671
6672 case DRFLAC_METADATA_BLOCK_TYPE_PICTURE:
6673 {
6674 if (blockSize < 32) {
6675 return DRFLAC_FALSE;
6676 }
6677
6678 if (onMeta) {
6679 void* pRawData;
6680 const char* pRunningData;
6681 const char* pRunningDataEnd;
6682
6683 pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6684 if (pRawData == NULL) {
6685 return DRFLAC_FALSE;
6686 }
6687
6688 if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6689 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6690 return DRFLAC_FALSE;
6691 }
6692
6693 metadata.pRawData = pRawData;
6694 metadata.rawDataSize = blockSize;
6695
6696 pRunningData = (const char*)pRawData;
6697 pRunningDataEnd = (const char*)pRawData + blockSize;
6698
6699 metadata.data.picture.type = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6700 metadata.data.picture.mimeLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6701
6702 /* Need space for the rest of the block */
6703 if ((pRunningDataEnd - pRunningData) - 24 < (drflac_int64)metadata.data.picture.mimeLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6704 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6705 return DRFLAC_FALSE;
6706 }
6707 metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
6708 metadata.data.picture.descriptionLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6709
6710 /* Need space for the rest of the block */
6711 if ((pRunningDataEnd - pRunningData) - 20 < (drflac_int64)metadata.data.picture.descriptionLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6712 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6713 return DRFLAC_FALSE;
6714 }
6715 metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
6716 metadata.data.picture.width = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6717 metadata.data.picture.height = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6718 metadata.data.picture.colorDepth = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6719 metadata.data.picture.indexColorCount = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6720 metadata.data.picture.pictureDataSize = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6721 metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData;
6722
6723 /* Need space for the picture after the block */
6724 if (pRunningDataEnd - pRunningData < (drflac_int64)metadata.data.picture.pictureDataSize) { /* <-- Note the order of operations to avoid overflow to a valid value */
6725 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6726 return DRFLAC_FALSE;
6727 }
6728
6729 onMeta(pUserDataMD, &metadata);
6730
6731 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6732 }
6733 } break;
6734
6735 case DRFLAC_METADATA_BLOCK_TYPE_PADDING:
6736 {
6737 if (onMeta) {
6738 metadata.data.padding.unused = 0;
6739
6740 /* Padding doesn't have anything meaningful in it, so just skip over it, but make sure the caller is aware of it by firing the callback. */
6741 if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
6742 isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
6743 } else {
6744 onMeta(pUserDataMD, &metadata);
6745 }
6746 }
6747 } break;
6748
6749 case DRFLAC_METADATA_BLOCK_TYPE_INVALID:
6750 {
6751 /* Invalid chunk. Just skip over this one. */
6752 if (onMeta) {
6753 if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
6754 isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
6755 }
6756 }
6757 } break;
6758
6759 default:
6760 {
6761 /*
6762 It's an unknown chunk, but not necessarily invalid. There's a chance more metadata blocks might be defined later on, so we
6763 can at the very least report the chunk to the application and let it look at the raw data.
6764 */
6765 if (onMeta) {
6766 void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6767 if (pRawData == NULL) {
6768 return DRFLAC_FALSE;
6769 }
6770
6771 if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6772 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6773 return DRFLAC_FALSE;
6774 }
6775
6776 metadata.pRawData = pRawData;
6777 metadata.rawDataSize = blockSize;
6778 onMeta(pUserDataMD, &metadata);
6779
6780 drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6781 }
6782 } break;
6783 }
6784
6785 /* If we're not handling metadata, just skip over the block. If we are, it will have been handled earlier in the switch statement above. */
6786 if (onMeta == NULL && blockSize > 0) {
6787 if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
6788 isLastBlock = DRFLAC_TRUE;
6789 }
6790 }
6791
6792 runningFilePos += blockSize;
6793 if (isLastBlock) {
6794 break;
6795 }
6796 }
6797
6798 *pSeektablePos = seektablePos;
6799 *pSeektableSize = seektableSize;
6800 *pFirstFramePos = runningFilePos;
6801
6802 return DRFLAC_TRUE;
6803 }
6804
6805 static drflac_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
6806 {
6807 /* Pre Condition: The bit stream should be sitting just past the 4-byte id header. */
6808
6809 drflac_uint8 isLastBlock;
6810 drflac_uint8 blockType;
6811 drflac_uint32 blockSize;
6812
6813 (void)onSeek;
6814
6815 pInit->container = drflac_container_native;
6816
6817 /* The first metadata block should be the STREAMINFO block. */
6818 if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
6819 return DRFLAC_FALSE;
6820 }
6821
6822 if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
6823 if (!relaxed) {
6824 /* We're opening in strict mode and the first block is not the STREAMINFO block. Error. */
6825 return DRFLAC_FALSE;
6826 } else {
6827 /*
6828 Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined
6829 for that frame.
6830 */
6831 pInit->hasStreamInfoBlock = DRFLAC_FALSE;
6832 pInit->hasMetadataBlocks = DRFLAC_FALSE;
6833
6834 if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
6835 return DRFLAC_FALSE; /* Couldn't find a frame. */
6836 }
6837
6838 if (pInit->firstFrameHeader.bitsPerSample == 0) {
6839 return DRFLAC_FALSE; /* Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist. */
6840 }
6841
6842 pInit->sampleRate = pInit->firstFrameHeader.sampleRate;
6843 pInit->channels = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment);
6844 pInit->bitsPerSample = pInit->firstFrameHeader.bitsPerSample;
6845 pInit->maxBlockSizeInPCMFrames = 65535; /* <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo */
6846 return DRFLAC_TRUE;
6847 }
6848 } else {
6849 drflac_streaminfo streaminfo;
6850 if (!drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
6851 return DRFLAC_FALSE;
6852 }
6853
6854 pInit->hasStreamInfoBlock = DRFLAC_TRUE;
6855 pInit->sampleRate = streaminfo.sampleRate;
6856 pInit->channels = streaminfo.channels;
6857 pInit->bitsPerSample = streaminfo.bitsPerSample;
6858 pInit->totalPCMFrameCount = streaminfo.totalPCMFrameCount;
6859 pInit->maxBlockSizeInPCMFrames = streaminfo.maxBlockSizeInPCMFrames; /* Don't care about the min block size - only the max (used for determining the size of the memory allocation). */
6860 pInit->hasMetadataBlocks = !isLastBlock;
6861
6862 if (onMeta) {
6863 drflac_metadata metadata;
6864 metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO;
6865 metadata.pRawData = NULL;
6866 metadata.rawDataSize = 0;
6867 metadata.data.streaminfo = streaminfo;
6868 onMeta(pUserDataMD, &metadata);
6869 }
6870
6871 return DRFLAC_TRUE;
6872 }
6873 }
6874
6875 #ifndef DR_FLAC_NO_OGG
6876 #define DRFLAC_OGG_MAX_PAGE_SIZE 65307
6877 #define DRFLAC_OGG_CAPTURE_PATTERN_CRC32 1605413199 /* CRC-32 of "OggS". */
6878
6879 typedef enum
6880 {
6881 drflac_ogg_recover_on_crc_mismatch,
6882 drflac_ogg_fail_on_crc_mismatch
6883 } drflac_ogg_crc_mismatch_recovery;
6884
6885 #ifndef DR_FLAC_NO_CRC
6886 static drflac_uint32 drflac__crc32_table[] = {
6887 0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
6888 0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
6889 0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
6890 0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
6891 0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
6892 0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
6893 0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
6894 0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
6895 0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
6896 0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
6897 0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
6898 0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
6899 0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
6900 0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
6901 0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
6902 0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
6903 0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
6904 0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
6905 0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
6906 0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
6907 0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
6908 0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
6909 0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
6910 0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
6911 0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
6912 0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
6913 0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
6914 0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
6915 0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
6916 0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
6917 0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
6918 0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
6919 0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
6920 0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
6921 0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
6922 0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
6923 0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
6924 0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
6925 0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
6926 0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
6927 0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
6928 0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
6929 0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
6930 0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
6931 0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
6932 0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
6933 0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
6934 0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
6935 0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
6936 0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
6937 0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
6938 0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
6939 0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
6940 0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
6941 0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
6942 0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
6943 0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
6944 0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
6945 0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
6946 0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
6947 0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
6948 0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
6949 0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
6950 0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
6951 };
6952 #endif
6953
6954 static DRFLAC_INLINE drflac_uint32 drflac_crc32_byte(drflac_uint32 crc32, drflac_uint8 data)
6955 {
6956 #ifndef DR_FLAC_NO_CRC
6957 return (crc32 << 8) ^ drflac__crc32_table[(drflac_uint8)((crc32 >> 24) & 0xFF) ^ data];
6958 #else
6959 (void)data;
6960 return crc32;
6961 #endif
6962 }
6963
6964 #if 0
6965 static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint32(drflac_uint32 crc32, drflac_uint32 data)
6966 {
6967 crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF));
6968 crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF));
6969 crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 8) & 0xFF));
6970 crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 0) & 0xFF));
6971 return crc32;
6972 }
6973
6974 static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint64(drflac_uint32 crc32, drflac_uint64 data)
6975 {
6976 crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF));
6977 crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 0) & 0xFFFFFFFF));
6978 return crc32;
6979 }
6980 #endif
6981
6982 static DRFLAC_INLINE drflac_uint32 drflac_crc32_buffer(drflac_uint32 crc32, drflac_uint8* pData, drflac_uint32 dataSize)
6983 {
6984 /* This can be optimized. */
6985 drflac_uint32 i;
6986 for (i = 0; i < dataSize; ++i) {
6987 crc32 = drflac_crc32_byte(crc32, pData[i]);
6988 }
6989 return crc32;
6990 }
6991
6992
6993 static DRFLAC_INLINE drflac_bool32 drflac_ogg__is_capture_pattern(drflac_uint8 pattern[4])
6994 {
6995 return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S';
6996 }
6997
6998 static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_header_size(drflac_ogg_page_header* pHeader)
6999 {
7000 return 27 + pHeader->segmentCount;
7001 }
7002
7003 static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_body_size(drflac_ogg_page_header* pHeader)
7004 {
7005 drflac_uint32 pageBodySize = 0;
7006 int i;
7007
7008 for (i = 0; i < pHeader->segmentCount; ++i) {
7009 pageBodySize += pHeader->segmentTable[i];
7010 }
7011
7012 return pageBodySize;
7013 }
7014
7015 static drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32)
7016 {
7017 drflac_uint8 data[23];
7018 drflac_uint32 i;
7019
7020 DRFLAC_ASSERT(*pCRC32 == DRFLAC_OGG_CAPTURE_PATTERN_CRC32);
7021
7022 if (onRead(pUserData, data, 23) != 23) {
7023 return DRFLAC_AT_END;
7024 }
7025 *pBytesRead += 23;
7026
7027 /*
7028 It's not actually used, but set the capture pattern to 'OggS' for completeness. Not doing this will cause static analysers to complain about
7029 us trying to access uninitialized data. We could alternatively just comment out this member of the drflac_ogg_page_header structure, but I
7030 like to have it map to the structure of the underlying data.
7031 */
7032 pHeader->capturePattern[0] = 'O';
7033 pHeader->capturePattern[1] = 'g';
7034 pHeader->capturePattern[2] = 'g';
7035 pHeader->capturePattern[3] = 'S';
7036
7037 pHeader->structureVersion = data[0];
7038 pHeader->headerType = data[1];
7039 DRFLAC_COPY_MEMORY(&pHeader->granulePosition, &data[ 2], 8);
7040 DRFLAC_COPY_MEMORY(&pHeader->serialNumber, &data[10], 4);
7041 DRFLAC_COPY_MEMORY(&pHeader->sequenceNumber, &data[14], 4);
7042 DRFLAC_COPY_MEMORY(&pHeader->checksum, &data[18], 4);
7043 pHeader->segmentCount = data[22];
7044
7045 /* Calculate the CRC. Note that for the calculation the checksum part of the page needs to be set to 0. */
7046 data[18] = 0;
7047 data[19] = 0;
7048 data[20] = 0;
7049 data[21] = 0;
7050
7051 for (i = 0; i < 23; ++i) {
7052 *pCRC32 = drflac_crc32_byte(*pCRC32, data[i]);
7053 }
7054
7055
7056 if (onRead(pUserData, pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) {
7057 return DRFLAC_AT_END;
7058 }
7059 *pBytesRead += pHeader->segmentCount;
7060
7061 for (i = 0; i < pHeader->segmentCount; ++i) {
7062 *pCRC32 = drflac_crc32_byte(*pCRC32, pHeader->segmentTable[i]);
7063 }
7064
7065 return DRFLAC_SUCCESS;
7066 }
7067
7068 static drflac_result drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32)
7069 {
7070 drflac_uint8 id[4];
7071
7072 *pBytesRead = 0;
7073
7074 if (onRead(pUserData, id, 4) != 4) {
7075 return DRFLAC_AT_END;
7076 }
7077 *pBytesRead += 4;
7078
7079 /* We need to read byte-by-byte until we find the OggS capture pattern. */
7080 for (;;) {
7081 if (drflac_ogg__is_capture_pattern(id)) {
7082 drflac_result result;
7083
7084 *pCRC32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32;
7085
7086 result = drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32);
7087 if (result == DRFLAC_SUCCESS) {
7088 return DRFLAC_SUCCESS;
7089 } else {
7090 if (result == DRFLAC_CRC_MISMATCH) {
7091 continue;
7092 } else {
7093 return result;
7094 }
7095 }
7096 } else {
7097 /* The first 4 bytes did not equal the capture pattern. Read the next byte and try again. */
7098 id[0] = id[1];
7099 id[1] = id[2];
7100 id[2] = id[3];
7101 if (onRead(pUserData, &id[3], 1) != 1) {
7102 return DRFLAC_AT_END;
7103 }
7104 *pBytesRead += 1;
7105 }
7106 }
7107 }
7108
7109
7110 /*
7111 The main part of the Ogg encapsulation is the conversion from the physical Ogg bitstream to the native FLAC bitstream. It works
7112 in three general stages: Ogg Physical Bitstream -> Ogg/FLAC Logical Bitstream -> FLAC Native Bitstream. dr_flac is designed
7113 in such a way that the core sections assume everything is delivered in native format. Therefore, for each encapsulation type
7114 dr_flac is supporting there needs to be a layer sitting on top of the onRead and onSeek callbacks that ensures the bits read from
7115 the physical Ogg bitstream are converted and delivered in native FLAC format.
7116 */
7117 typedef struct
7118 {
7119 drflac_read_proc onRead; /* The original onRead callback from drflac_open() and family. */
7120 drflac_seek_proc onSeek; /* The original onSeek callback from drflac_open() and family. */
7121 void* pUserData; /* The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family. */
7122 drflac_uint64 currentBytePos; /* The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking. */
7123 drflac_uint64 firstBytePos; /* The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page. */
7124 drflac_uint32 serialNumber; /* The serial number of the FLAC audio pages. This is determined by the initial header page that was read during initialization. */
7125 drflac_ogg_page_header bosPageHeader; /* Used for seeking. */
7126 drflac_ogg_page_header currentPageHeader;
7127 drflac_uint32 bytesRemainingInPage;
7128 drflac_uint32 pageDataSize;
7129 drflac_uint8 pageData[DRFLAC_OGG_MAX_PAGE_SIZE];
7130 } drflac_oggbs; /* oggbs = Ogg Bitstream */
7131
7132 static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, size_t bytesToRead)
7133 {
7134 size_t bytesActuallyRead = oggbs->onRead(oggbs->pUserData, bufferOut, bytesToRead);
7135 oggbs->currentBytePos += bytesActuallyRead;
7136
7137 return bytesActuallyRead;
7138 }
7139
7140 static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin)
7141 {
7142 if (origin == drflac_seek_origin_start) {
7143 if (offset <= 0x7FFFFFFF) {
7144 if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_start)) {
7145 return DRFLAC_FALSE;
7146 }
7147 oggbs->currentBytePos = offset;
7148
7149 return DRFLAC_TRUE;
7150 } else {
7151 if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
7152 return DRFLAC_FALSE;
7153 }
7154 oggbs->currentBytePos = offset;
7155
7156 return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, drflac_seek_origin_current);
7157 }
7158 } else {
7159 while (offset > 0x7FFFFFFF) {
7160 if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
7161 return DRFLAC_FALSE;
7162 }
7163 oggbs->currentBytePos += 0x7FFFFFFF;
7164 offset -= 0x7FFFFFFF;
7165 }
7166
7167 if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_current)) { /* <-- Safe cast thanks to the loop above. */
7168 return DRFLAC_FALSE;
7169 }
7170 oggbs->currentBytePos += offset;
7171
7172 return DRFLAC_TRUE;
7173 }
7174 }
7175
7176 static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs, drflac_ogg_crc_mismatch_recovery recoveryMethod)
7177 {
7178 drflac_ogg_page_header header;
7179 for (;;) {
7180 drflac_uint32 crc32 = 0;
7181 drflac_uint32 bytesRead;
7182 drflac_uint32 pageBodySize;
7183 #ifndef DR_FLAC_NO_CRC
7184 drflac_uint32 actualCRC32;
7185 #endif
7186
7187 if (drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
7188 return DRFLAC_FALSE;
7189 }
7190 oggbs->currentBytePos += bytesRead;
7191
7192 pageBodySize = drflac_ogg__get_page_body_size(&header);
7193 if (pageBodySize > DRFLAC_OGG_MAX_PAGE_SIZE) {
7194 continue; /* Invalid page size. Assume it's corrupted and just move to the next page. */
7195 }
7196
7197 if (header.serialNumber != oggbs->serialNumber) {
7198 /* It's not a FLAC page. Skip it. */
7199 if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) {
7200 return DRFLAC_FALSE;
7201 }
7202 continue;
7203 }
7204
7205
7206 /* We need to read the entire page and then do a CRC check on it. If there's a CRC mismatch we need to skip this page. */
7207 if (drflac_oggbs__read_physical(oggbs, oggbs->pageData, pageBodySize) != pageBodySize) {
7208 return DRFLAC_FALSE;
7209 }
7210 oggbs->pageDataSize = pageBodySize;
7211
7212 #ifndef DR_FLAC_NO_CRC
7213 actualCRC32 = drflac_crc32_buffer(crc32, oggbs->pageData, oggbs->pageDataSize);
7214 if (actualCRC32 != header.checksum) {
7215 if (recoveryMethod == drflac_ogg_recover_on_crc_mismatch) {
7216 continue; /* CRC mismatch. Skip this page. */
7217 } else {
7218 /*
7219 Even though we are failing on a CRC mismatch, we still want our stream to be in a good state. Therefore we
7220 go to the next valid page to ensure we're in a good state, but return false to let the caller know that the
7221 seek did not fully complete.
7222 */
7223 drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch);
7224 return DRFLAC_FALSE;
7225 }
7226 }
7227 #else
7228 (void)recoveryMethod; /* <-- Silence a warning. */
7229 #endif
7230
7231 oggbs->currentPageHeader = header;
7232 oggbs->bytesRemainingInPage = pageBodySize;
7233 return DRFLAC_TRUE;
7234 }
7235 }
7236
7237 /* Function below is unused at the moment, but I might be re-adding it later. */
7238 #if 0
7239 static drflac_uint8 drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, drflac_uint8* pBytesRemainingInSeg)
7240 {
7241 drflac_uint32 bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage;
7242 drflac_uint8 iSeg = 0;
7243 drflac_uint32 iByte = 0;
7244 while (iByte < bytesConsumedInPage) {
7245 drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
7246 if (iByte + segmentSize > bytesConsumedInPage) {
7247 break;
7248 } else {
7249 iSeg += 1;
7250 iByte += segmentSize;
7251 }
7252 }
7253
7254 *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (drflac_uint8)(bytesConsumedInPage - iByte);
7255 return iSeg;
7256 }
7257
7258 static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
7259 {
7260 /* The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page. */
7261 for (;;) {
7262 drflac_bool32 atEndOfPage = DRFLAC_FALSE;
7263
7264 drflac_uint8 bytesRemainingInSeg;
7265 drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
7266
7267 drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg;
7268 for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
7269 drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
7270 if (segmentSize < 255) {
7271 if (iSeg == oggbs->currentPageHeader.segmentCount-1) {
7272 atEndOfPage = DRFLAC_TRUE;
7273 }
7274
7275 break;
7276 }
7277
7278 bytesToEndOfPacketOrPage += segmentSize;
7279 }
7280
7281 /*
7282 At this point we will have found either the packet or the end of the page. If were at the end of the page we'll
7283 want to load the next page and keep searching for the end of the packet.
7284 */
7285 drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, drflac_seek_origin_current);
7286 oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
7287
7288 if (atEndOfPage) {
7289 /*
7290 We're potentially at the next packet, but we need to check the next page first to be sure because the packet may
7291 straddle pages.
7292 */
7293 if (!drflac_oggbs__goto_next_page(oggbs)) {
7294 return DRFLAC_FALSE;
7295 }
7296
7297 /* If it's a fresh packet it most likely means we're at the next packet. */
7298 if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
7299 return DRFLAC_TRUE;
7300 }
7301 } else {
7302 /* We're at the next packet. */
7303 return DRFLAC_TRUE;
7304 }
7305 }
7306 }
7307
7308 static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
7309 {
7310 /* The bitstream should be sitting on the first byte just after the header of the frame. */
7311
7312 /* What we're actually doing here is seeking to the start of the next packet. */
7313 return drflac_oggbs__seek_to_next_packet(oggbs);
7314 }
7315 #endif
7316
7317 static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
7318 {
7319 drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
7320 drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;
7321 size_t bytesRead = 0;
7322
7323 DRFLAC_ASSERT(oggbs != NULL);
7324 DRFLAC_ASSERT(pRunningBufferOut != NULL);
7325
7326 /* Reading is done page-by-page. If we've run out of bytes in the page we need to move to the next one. */
7327 while (bytesRead < bytesToRead) {
7328 size_t bytesRemainingToRead = bytesToRead - bytesRead;
7329
7330 if (oggbs->bytesRemainingInPage >= bytesRemainingToRead) {
7331 DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
7332 bytesRead += bytesRemainingToRead;
7333 oggbs->bytesRemainingInPage -= (drflac_uint32)bytesRemainingToRead;
7334 break;
7335 }
7336
7337 /* If we get here it means some of the requested data is contained in the next pages. */
7338 if (oggbs->bytesRemainingInPage > 0) {
7339 DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
7340 bytesRead += oggbs->bytesRemainingInPage;
7341 pRunningBufferOut += oggbs->bytesRemainingInPage;
7342 oggbs->bytesRemainingInPage = 0;
7343 }
7344
7345 DRFLAC_ASSERT(bytesRemainingToRead > 0);
7346 if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
7347 break; /* Failed to go to the next page. Might have simply hit the end of the stream. */
7348 }
7349 }
7350
7351 return bytesRead;
7352 }
7353
7354 static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin)
7355 {
7356 drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
7357 int bytesSeeked = 0;
7358
7359 DRFLAC_ASSERT(oggbs != NULL);
7360 DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
7361
7362 /* Seeking is always forward which makes things a lot simpler. */
7363 if (origin == drflac_seek_origin_start) {
7364 if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, drflac_seek_origin_start)) {
7365 return DRFLAC_FALSE;
7366 }
7367
7368 if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
7369 return DRFLAC_FALSE;
7370 }
7371
7372 return drflac__on_seek_ogg(pUserData, offset, drflac_seek_origin_current);
7373 }
7374
7375 DRFLAC_ASSERT(origin == drflac_seek_origin_current);
7376
7377 while (bytesSeeked < offset) {
7378 int bytesRemainingToSeek = offset - bytesSeeked;
7379 DRFLAC_ASSERT(bytesRemainingToSeek >= 0);
7380
7381 if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
7382 bytesSeeked += bytesRemainingToSeek;
7383 (void)bytesSeeked; /* <-- Silence a dead store warning emitted by Clang Static Analyzer. */
7384 oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
7385 break;
7386 }
7387
7388 /* If we get here it means some of the requested data is contained in the next pages. */
7389 if (oggbs->bytesRemainingInPage > 0) {
7390 bytesSeeked += (int)oggbs->bytesRemainingInPage;
7391 oggbs->bytesRemainingInPage = 0;
7392 }
7393
7394 DRFLAC_ASSERT(bytesRemainingToSeek > 0);
7395 if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
7396 /* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
7397 return DRFLAC_FALSE;
7398 }
7399 }
7400
7401 return DRFLAC_TRUE;
7402 }
7403
7404
7405 static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
7406 {
7407 drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
7408 drflac_uint64 originalBytePos;
7409 drflac_uint64 runningGranulePosition;
7410 drflac_uint64 runningFrameBytePos;
7411 drflac_uint64 runningPCMFrameCount;
7412
7413 DRFLAC_ASSERT(oggbs != NULL);
7414
7415 originalBytePos = oggbs->currentBytePos; /* For recovery. Points to the OggS identifier. */
7416
7417 /* First seek to the first frame. */
7418 if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes)) {
7419 return DRFLAC_FALSE;
7420 }
7421 oggbs->bytesRemainingInPage = 0;
7422
7423 runningGranulePosition = 0;
7424 for (;;) {
7425 if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
7426 drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
7427 return DRFLAC_FALSE; /* Never did find that sample... */
7428 }
7429
7430 runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize;
7431 if (oggbs->currentPageHeader.granulePosition >= pcmFrameIndex) {
7432 break; /* The sample is somewhere in the previous page. */
7433 }
7434
7435 /*
7436 At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we
7437 disregard any pages that do not begin a fresh packet.
7438 */
7439 if ((oggbs->currentPageHeader.headerType & 0x01) == 0) { /* <-- Is it a fresh page? */
7440 if (oggbs->currentPageHeader.segmentTable[0] >= 2) {
7441 drflac_uint8 firstBytesInPage[2];
7442 firstBytesInPage[0] = oggbs->pageData[0];
7443 firstBytesInPage[1] = oggbs->pageData[1];
7444
7445 if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) { /* <-- Does the page begin with a frame's sync code? */
7446 runningGranulePosition = oggbs->currentPageHeader.granulePosition;
7447 }
7448
7449 continue;
7450 }
7451 }
7452 }
7453
7454 /*
7455 We found the page that that is closest to the sample, so now we need to find it. The first thing to do is seek to the
7456 start of that page. In the loop above we checked that it was a fresh page which means this page is also the start of
7457 a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
7458 we find the one containing the target sample.
7459 */
7460 if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) {
7461 return DRFLAC_FALSE;
7462 }
7463 if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
7464 return DRFLAC_FALSE;
7465 }
7466
7467 /*
7468 At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep
7469 looping over these frames until we find the one containing the sample we're after.
7470 */
7471 runningPCMFrameCount = runningGranulePosition;
7472 for (;;) {
7473 /*
7474 There are two ways to find the sample and seek past irrelevant frames:
7475 1) Use the native FLAC decoder.
7476 2) Use Ogg's framing system.
7477
7478 Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to
7479 do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code
7480 duplication for the decoding of frame headers.
7481
7482 Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg
7483 bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the
7484 standard drflac__*() APIs because that will read in extra data for its own internal caching which in turn breaks
7485 the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read
7486 using the native FLAC decoding APIs, such as drflac__read_next_flac_frame_header(), need to be re-implemented so as to
7487 avoid the use of the drflac_bs object.
7488
7489 Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons:
7490 1) Seeking is already partially accelerated using Ogg's paging system in the code block above.
7491 2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon.
7492 3) Simplicity.
7493 */
7494 drflac_uint64 firstPCMFrameInFLACFrame = 0;
7495 drflac_uint64 lastPCMFrameInFLACFrame = 0;
7496 drflac_uint64 pcmFrameCountInThisFrame;
7497
7498 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
7499 return DRFLAC_FALSE;
7500 }
7501
7502 drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
7503
7504 pcmFrameCountInThisFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
7505
7506 /* If we are seeking to the end of the file and we've just hit it, we're done. */
7507 if (pcmFrameIndex == pFlac->totalPCMFrameCount && (runningPCMFrameCount + pcmFrameCountInThisFrame) == pFlac->totalPCMFrameCount) {
7508 drflac_result result = drflac__decode_flac_frame(pFlac);
7509 if (result == DRFLAC_SUCCESS) {
7510 pFlac->currentPCMFrame = pcmFrameIndex;
7511 pFlac->currentFLACFrame.pcmFramesRemaining = 0;
7512 return DRFLAC_TRUE;
7513 } else {
7514 return DRFLAC_FALSE;
7515 }
7516 }
7517
7518 if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFrame)) {
7519 /*
7520 The sample should be in this FLAC frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
7521 it never existed and keep iterating.
7522 */
7523 drflac_result result = drflac__decode_flac_frame(pFlac);
7524 if (result == DRFLAC_SUCCESS) {
7525 /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
7526 drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount); /* <-- Safe cast because the maximum number of samples in a frame is 65535. */
7527 if (pcmFramesToDecode == 0) {
7528 return DRFLAC_TRUE;
7529 }
7530
7531 pFlac->currentPCMFrame = runningPCMFrameCount;
7532
7533 return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */
7534 } else {
7535 if (result == DRFLAC_CRC_MISMATCH) {
7536 continue; /* CRC mismatch. Pretend this frame never existed. */
7537 } else {
7538 return DRFLAC_FALSE;
7539 }
7540 }
7541 } else {
7542 /*
7543 It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
7544 frame never existed and leave the running sample count untouched.
7545 */
7546 drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
7547 if (result == DRFLAC_SUCCESS) {
7548 runningPCMFrameCount += pcmFrameCountInThisFrame;
7549 } else {
7550 if (result == DRFLAC_CRC_MISMATCH) {
7551 continue; /* CRC mismatch. Pretend this frame never existed. */
7552 } else {
7553 return DRFLAC_FALSE;
7554 }
7555 }
7556 }
7557 }
7558 }
7559
7560
7561
7562 static drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
7563 {
7564 drflac_ogg_page_header header;
7565 drflac_uint32 crc32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32;
7566 drflac_uint32 bytesRead = 0;
7567
7568 /* Pre Condition: The bit stream should be sitting just past the 4-byte OggS capture pattern. */
7569 (void)relaxed;
7570
7571 pInit->container = drflac_container_ogg;
7572 pInit->oggFirstBytePos = 0;
7573
7574 /*
7575 We'll get here if the first 4 bytes of the stream were the OggS capture pattern, however it doesn't necessarily mean the
7576 stream includes FLAC encoded audio. To check for this we need to scan the beginning-of-stream page markers and check if
7577 any match the FLAC specification. Important to keep in mind that the stream may be multiplexed.
7578 */
7579 if (drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
7580 return DRFLAC_FALSE;
7581 }
7582 pInit->runningFilePos += bytesRead;
7583
7584 for (;;) {
7585 int pageBodySize;
7586
7587 /* Break if we're past the beginning of stream page. */
7588 if ((header.headerType & 0x02) == 0) {
7589 return DRFLAC_FALSE;
7590 }
7591
7592 /* Check if it's a FLAC header. */
7593 pageBodySize = drflac_ogg__get_page_body_size(&header);
7594 if (pageBodySize == 51) { /* 51 = the lacing value of the FLAC header packet. */
7595 /* It could be a FLAC page... */
7596 drflac_uint32 bytesRemainingInPage = pageBodySize;
7597 drflac_uint8 packetType;
7598
7599 if (onRead(pUserData, &packetType, 1) != 1) {
7600 return DRFLAC_FALSE;
7601 }
7602
7603 bytesRemainingInPage -= 1;
7604 if (packetType == 0x7F) {
7605 /* Increasingly more likely to be a FLAC page... */
7606 drflac_uint8 sig[4];
7607 if (onRead(pUserData, sig, 4) != 4) {
7608 return DRFLAC_FALSE;
7609 }
7610
7611 bytesRemainingInPage -= 4;
7612 if (sig[0] == 'F' && sig[1] == 'L' && sig[2] == 'A' && sig[3] == 'C') {
7613 /* Almost certainly a FLAC page... */
7614 drflac_uint8 mappingVersion[2];
7615 if (onRead(pUserData, mappingVersion, 2) != 2) {
7616 return DRFLAC_FALSE;
7617 }
7618
7619 if (mappingVersion[0] != 1) {
7620 return DRFLAC_FALSE; /* Only supporting version 1.x of the Ogg mapping. */
7621 }
7622
7623 /*
7624 The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to
7625 be handling it in a generic way based on the serial number and packet types.
7626 */
7627 if (!onSeek(pUserData, 2, drflac_seek_origin_current)) {
7628 return DRFLAC_FALSE;
7629 }
7630
7631 /* Expecting the native FLAC signature "fLaC". */
7632 if (onRead(pUserData, sig, 4) != 4) {
7633 return DRFLAC_FALSE;
7634 }
7635
7636 if (sig[0] == 'f' && sig[1] == 'L' && sig[2] == 'a' && sig[3] == 'C') {
7637 /* The remaining data in the page should be the STREAMINFO block. */
7638 drflac_streaminfo streaminfo;
7639 drflac_uint8 isLastBlock;
7640 drflac_uint8 blockType;
7641 drflac_uint32 blockSize;
7642 if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
7643 return DRFLAC_FALSE;
7644 }
7645
7646 if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
7647 return DRFLAC_FALSE; /* Invalid block type. First block must be the STREAMINFO block. */
7648 }
7649
7650 if (drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
7651 /* Success! */
7652 pInit->hasStreamInfoBlock = DRFLAC_TRUE;
7653 pInit->sampleRate = streaminfo.sampleRate;
7654 pInit->channels = streaminfo.channels;
7655 pInit->bitsPerSample = streaminfo.bitsPerSample;
7656 pInit->totalPCMFrameCount = streaminfo.totalPCMFrameCount;
7657 pInit->maxBlockSizeInPCMFrames = streaminfo.maxBlockSizeInPCMFrames;
7658 pInit->hasMetadataBlocks = !isLastBlock;
7659
7660 if (onMeta) {
7661 drflac_metadata metadata;
7662 metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO;
7663 metadata.pRawData = NULL;
7664 metadata.rawDataSize = 0;
7665 metadata.data.streaminfo = streaminfo;
7666 onMeta(pUserDataMD, &metadata);
7667 }
7668
7669 pInit->runningFilePos += pageBodySize;
7670 pInit->oggFirstBytePos = pInit->runningFilePos - 79; /* Subtracting 79 will place us right on top of the "OggS" identifier of the FLAC bos page. */
7671 pInit->oggSerial = header.serialNumber;
7672 pInit->oggBosHeader = header;
7673 break;
7674 } else {
7675 /* Failed to read STREAMINFO block. Aww, so close... */
7676 return DRFLAC_FALSE;
7677 }
7678 } else {
7679 /* Invalid file. */
7680 return DRFLAC_FALSE;
7681 }
7682 } else {
7683 /* Not a FLAC header. Skip it. */
7684 if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
7685 return DRFLAC_FALSE;
7686 }
7687 }
7688 } else {
7689 /* Not a FLAC header. Seek past the entire page and move on to the next. */
7690 if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
7691 return DRFLAC_FALSE;
7692 }
7693 }
7694 } else {
7695 if (!onSeek(pUserData, pageBodySize, drflac_seek_origin_current)) {
7696 return DRFLAC_FALSE;
7697 }
7698 }
7699
7700 pInit->runningFilePos += pageBodySize;
7701
7702
7703 /* Read the header of the next page. */
7704 if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
7705 return DRFLAC_FALSE;
7706 }
7707 pInit->runningFilePos += bytesRead;
7708 }
7709
7710 /*
7711 If we get here it means we found a FLAC audio stream. We should be sitting on the first byte of the header of the next page. The next
7712 packets in the FLAC logical stream contain the metadata. The only thing left to do in the initialization phase for Ogg is to create the
7713 Ogg bistream object.
7714 */
7715 pInit->hasMetadataBlocks = DRFLAC_TRUE; /* <-- Always have at least VORBIS_COMMENT metadata block. */
7716 return DRFLAC_TRUE;
7717 }
7718 #endif
7719
7720 static drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD)
7721 {
7722 drflac_bool32 relaxed;
7723 drflac_uint8 id[4];
7724
7725 if (pInit == NULL || onRead == NULL || onSeek == NULL) {
7726 return DRFLAC_FALSE;
7727 }
7728
7729 DRFLAC_ZERO_MEMORY(pInit, sizeof(*pInit));
7730 pInit->onRead = onRead;
7731 pInit->onSeek = onSeek;
7732 pInit->onMeta = onMeta;
7733 pInit->container = container;
7734 pInit->pUserData = pUserData;
7735 pInit->pUserDataMD = pUserDataMD;
7736
7737 pInit->bs.onRead = onRead;
7738 pInit->bs.onSeek = onSeek;
7739 pInit->bs.pUserData = pUserData;
7740 drflac__reset_cache(&pInit->bs);
7741
7742
7743 /* If the container is explicitly defined then we can try opening in relaxed mode. */
7744 relaxed = container != drflac_container_unknown;
7745
7746 /* Skip over any ID3 tags. */
7747 for (;;) {
7748 if (onRead(pUserData, id, 4) != 4) {
7749 return DRFLAC_FALSE; /* Ran out of data. */
7750 }
7751 pInit->runningFilePos += 4;
7752
7753 if (id[0] == 'I' && id[1] == 'D' && id[2] == '3') {
7754 drflac_uint8 header[6];
7755 drflac_uint8 flags;
7756 drflac_uint32 headerSize;
7757
7758 if (onRead(pUserData, header, 6) != 6) {
7759 return DRFLAC_FALSE; /* Ran out of data. */
7760 }
7761 pInit->runningFilePos += 6;
7762
7763 flags = header[1];
7764
7765 DRFLAC_COPY_MEMORY(&headerSize, header+2, 4);
7766 headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize));
7767 if (flags & 0x10) {
7768 headerSize += 10;
7769 }
7770
7771 if (!onSeek(pUserData, headerSize, drflac_seek_origin_current)) {
7772 return DRFLAC_FALSE; /* Failed to seek past the tag. */
7773 }
7774 pInit->runningFilePos += headerSize;
7775 } else {
7776 break;
7777 }
7778 }
7779
7780 if (id[0] == 'f' && id[1] == 'L' && id[2] == 'a' && id[3] == 'C') {
7781 return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7782 }
7783 #ifndef DR_FLAC_NO_OGG
7784 if (id[0] == 'O' && id[1] == 'g' && id[2] == 'g' && id[3] == 'S') {
7785 return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7786 }
7787 #endif
7788
7789 /* If we get here it means we likely don't have a header. Try opening in relaxed mode, if applicable. */
7790 if (relaxed) {
7791 if (container == drflac_container_native) {
7792 return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7793 }
7794 #ifndef DR_FLAC_NO_OGG
7795 if (container == drflac_container_ogg) {
7796 return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7797 }
7798 #endif
7799 }
7800
7801 /* Unsupported container. */
7802 return DRFLAC_FALSE;
7803 }
7804
7805 static void drflac__init_from_info(drflac* pFlac, const drflac_init_info* pInit)
7806 {
7807 DRFLAC_ASSERT(pFlac != NULL);
7808 DRFLAC_ASSERT(pInit != NULL);
7809
7810 DRFLAC_ZERO_MEMORY(pFlac, sizeof(*pFlac));
7811 pFlac->bs = pInit->bs;
7812 pFlac->onMeta = pInit->onMeta;
7813 pFlac->pUserDataMD = pInit->pUserDataMD;
7814 pFlac->maxBlockSizeInPCMFrames = pInit->maxBlockSizeInPCMFrames;
7815 pFlac->sampleRate = pInit->sampleRate;
7816 pFlac->channels = (drflac_uint8)pInit->channels;
7817 pFlac->bitsPerSample = (drflac_uint8)pInit->bitsPerSample;
7818 pFlac->totalPCMFrameCount = pInit->totalPCMFrameCount;
7819 pFlac->container = pInit->container;
7820 }
7821
7822
7823 static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD, const drflac_allocation_callbacks* pAllocationCallbacks)
7824 {
7825 drflac_init_info init;
7826 drflac_uint32 allocationSize;
7827 drflac_uint32 wholeSIMDVectorCountPerChannel;
7828 drflac_uint32 decodedSamplesAllocationSize;
7829 #ifndef DR_FLAC_NO_OGG
7830 drflac_oggbs oggbs;
7831 #endif
7832 drflac_uint64 firstFramePos;
7833 drflac_uint64 seektablePos;
7834 drflac_uint32 seektableSize;
7835 drflac_allocation_callbacks allocationCallbacks;
7836 drflac* pFlac;
7837
7838 /* CPU support first. */
7839 drflac__init_cpu_caps();
7840
7841 if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
7842 return NULL;
7843 }
7844
7845 if (pAllocationCallbacks != NULL) {
7846 allocationCallbacks = *pAllocationCallbacks;
7847 if (allocationCallbacks.onFree == NULL || (allocationCallbacks.onMalloc == NULL && allocationCallbacks.onRealloc == NULL)) {
7848 return NULL; /* Invalid allocation callbacks. */
7849 }
7850 } else {
7851 allocationCallbacks.pUserData = NULL;
7852 allocationCallbacks.onMalloc = drflac__malloc_default;
7853 allocationCallbacks.onRealloc = drflac__realloc_default;
7854 allocationCallbacks.onFree = drflac__free_default;
7855 }
7856
7857
7858 /*
7859 The size of the allocation for the drflac object needs to be large enough to fit the following:
7860 1) The main members of the drflac structure
7861 2) A block of memory large enough to store the decoded samples of the largest frame in the stream
7862 3) If the container is Ogg, a drflac_oggbs object
7863
7864 The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration
7865 the different SIMD instruction sets.
7866 */
7867 allocationSize = sizeof(drflac);
7868
7869 /*
7870 The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector
7871 we are supporting.
7872 */
7873 if ((init.maxBlockSizeInPCMFrames % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
7874 wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
7875 } else {
7876 wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
7877 }
7878
7879 decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels;
7880
7881 allocationSize += decodedSamplesAllocationSize;
7882 allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE; /* Allocate extra bytes to ensure we have enough for alignment. */
7883
7884 #ifndef DR_FLAC_NO_OGG
7885 /* There's additional data required for Ogg streams. */
7886 if (init.container == drflac_container_ogg) {
7887 allocationSize += sizeof(drflac_oggbs);
7888 }
7889
7890 DRFLAC_ZERO_MEMORY(&oggbs, sizeof(oggbs));
7891 if (init.container == drflac_container_ogg) {
7892 oggbs.onRead = onRead;
7893 oggbs.onSeek = onSeek;
7894 oggbs.pUserData = pUserData;
7895 oggbs.currentBytePos = init.oggFirstBytePos;
7896 oggbs.firstBytePos = init.oggFirstBytePos;
7897 oggbs.serialNumber = init.oggSerial;
7898 oggbs.bosPageHeader = init.oggBosHeader;
7899 oggbs.bytesRemainingInPage = 0;
7900 }
7901 #endif
7902
7903 /*
7904 This part is a bit awkward. We need to load the seektable so that it can be referenced in-memory, but I want the drflac object to
7905 consist of only a single heap allocation. To this, the size of the seek table needs to be known, which we determine when reading
7906 and decoding the metadata.
7907 */
7908 firstFramePos = 42; /* <-- We know we are at byte 42 at this point. */
7909 seektablePos = 0;
7910 seektableSize = 0;
7911 if (init.hasMetadataBlocks) {
7912 drflac_read_proc onReadOverride = onRead;
7913 drflac_seek_proc onSeekOverride = onSeek;
7914 void* pUserDataOverride = pUserData;
7915
7916 #ifndef DR_FLAC_NO_OGG
7917 if (init.container == drflac_container_ogg) {
7918 onReadOverride = drflac__on_read_ogg;
7919 onSeekOverride = drflac__on_seek_ogg;
7920 pUserDataOverride = (void*)&oggbs;
7921 }
7922 #endif
7923
7924 if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seektableSize, &allocationCallbacks)) {
7925 return NULL;
7926 }
7927
7928 allocationSize += seektableSize;
7929 }
7930
7931
7932 pFlac = (drflac*)drflac__malloc_from_callbacks(allocationSize, &allocationCallbacks);
7933 if (pFlac == NULL) {
7934 return NULL;
7935 }
7936
7937 drflac__init_from_info(pFlac, &init);
7938 pFlac->allocationCallbacks = allocationCallbacks;
7939 pFlac->pDecodedSamples = (drflac_int32*)drflac_align((size_t)pFlac->pExtraData, DRFLAC_MAX_SIMD_VECTOR_SIZE);
7940
7941 #ifndef DR_FLAC_NO_OGG
7942 if (init.container == drflac_container_ogg) {
7943 drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + seektableSize);
7944 DRFLAC_COPY_MEMORY(pInternalOggbs, &oggbs, sizeof(oggbs));
7945
7946 /* The Ogg bistream needs to be layered on top of the original bitstream. */
7947 pFlac->bs.onRead = drflac__on_read_ogg;
7948 pFlac->bs.onSeek = drflac__on_seek_ogg;
7949 pFlac->bs.pUserData = (void*)pInternalOggbs;
7950 pFlac->_oggbs = (void*)pInternalOggbs;
7951 }
7952 #endif
7953
7954 pFlac->firstFLACFramePosInBytes = firstFramePos;
7955
7956 /* NOTE: Seektables are not currently compatible with Ogg encapsulation (Ogg has its own accelerated seeking system). I may change this later, so I'm leaving this here for now. */
7957 #ifndef DR_FLAC_NO_OGG
7958 if (init.container == drflac_container_ogg)
7959 {
7960 pFlac->pSeekpoints = NULL;
7961 pFlac->seekpointCount = 0;
7962 }
7963 else
7964 #endif
7965 {
7966 /* If we have a seektable we need to load it now, making sure we move back to where we were previously. */
7967 if (seektablePos != 0) {
7968 pFlac->seekpointCount = seektableSize / sizeof(*pFlac->pSeekpoints);
7969 pFlac->pSeekpoints = (drflac_seekpoint*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
7970
7971 DRFLAC_ASSERT(pFlac->bs.onSeek != NULL);
7972 DRFLAC_ASSERT(pFlac->bs.onRead != NULL);
7973
7974 /* Seek to the seektable, then just read directly into our seektable buffer. */
7975 if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, drflac_seek_origin_start)) {
7976 if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints, seektableSize) == seektableSize) {
7977 /* Endian swap. */
7978 drflac_uint32 iSeekpoint;
7979 for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
7980 pFlac->pSeekpoints[iSeekpoint].firstPCMFrame = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstPCMFrame);
7981 pFlac->pSeekpoints[iSeekpoint].flacFrameOffset = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].flacFrameOffset);
7982 pFlac->pSeekpoints[iSeekpoint].pcmFrameCount = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
7983 }
7984 } else {
7985 /* Failed to read the seektable. Pretend we don't have one. */
7986 pFlac->pSeekpoints = NULL;
7987 pFlac->seekpointCount = 0;
7988 }
7989
7990 /* We need to seek back to where we were. If this fails it's a critical error. */
7991 if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, drflac_seek_origin_start)) {
7992 drflac__free_from_callbacks(pFlac, &allocationCallbacks);
7993 return NULL;
7994 }
7995 } else {
7996 /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */
7997 pFlac->pSeekpoints = NULL;
7998 pFlac->seekpointCount = 0;
7999 }
8000 }
8001 }
8002
8003
8004 /*
8005 If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
8006 the first frame.
8007 */
8008 if (!init.hasStreamInfoBlock) {
8009 pFlac->currentFLACFrame.header = init.firstFrameHeader;
8010 for (;;) {
8011 drflac_result result = drflac__decode_flac_frame(pFlac);
8012 if (result == DRFLAC_SUCCESS) {
8013 break;
8014 } else {
8015 if (result == DRFLAC_CRC_MISMATCH) {
8016 if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
8017 drflac__free_from_callbacks(pFlac, &allocationCallbacks);
8018 return NULL;
8019 }
8020 continue;
8021 } else {
8022 drflac__free_from_callbacks(pFlac, &allocationCallbacks);
8023 return NULL;
8024 }
8025 }
8026 }
8027 }
8028
8029 return pFlac;
8030 }
8031
8032
8033
8034 #ifndef DR_FLAC_NO_STDIO
8035 #include <stdio.h>
8036 #include <wchar.h> /* For wcslen(), wcsrtombs() */
8037
8038 /* drflac_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */
8039 #include <errno.h>
8040 static drflac_result drflac_result_from_errno(int e)
8041 {
8042 switch (e)
8043 {
8044 case 0: return DRFLAC_SUCCESS;
8045 #ifdef EPERM
8046 case EPERM: return DRFLAC_INVALID_OPERATION;
8047 #endif
8048 #ifdef ENOENT
8049 case ENOENT: return DRFLAC_DOES_NOT_EXIST;
8050 #endif
8051 #ifdef ESRCH
8052 case ESRCH: return DRFLAC_DOES_NOT_EXIST;
8053 #endif
8054 #ifdef EINTR
8055 case EINTR: return DRFLAC_INTERRUPT;
8056 #endif
8057 #ifdef EIO
8058 case EIO: return DRFLAC_IO_ERROR;
8059 #endif
8060 #ifdef ENXIO
8061 case ENXIO: return DRFLAC_DOES_NOT_EXIST;
8062 #endif
8063 #ifdef E2BIG
8064 case E2BIG: return DRFLAC_INVALID_ARGS;
8065 #endif
8066 #ifdef ENOEXEC
8067 case ENOEXEC: return DRFLAC_INVALID_FILE;
8068 #endif
8069 #ifdef EBADF
8070 case EBADF: return DRFLAC_INVALID_FILE;
8071 #endif
8072 #ifdef ECHILD
8073 case ECHILD: return DRFLAC_ERROR;
8074 #endif
8075 #ifdef EAGAIN
8076 case EAGAIN: return DRFLAC_UNAVAILABLE;
8077 #endif
8078 #ifdef ENOMEM
8079 case ENOMEM: return DRFLAC_OUT_OF_MEMORY;
8080 #endif
8081 #ifdef EACCES
8082 case EACCES: return DRFLAC_ACCESS_DENIED;
8083 #endif
8084 #ifdef EFAULT
8085 case EFAULT: return DRFLAC_BAD_ADDRESS;
8086 #endif
8087 #ifdef ENOTBLK
8088 case ENOTBLK: return DRFLAC_ERROR;
8089 #endif
8090 #ifdef EBUSY
8091 case EBUSY: return DRFLAC_BUSY;
8092 #endif
8093 #ifdef EEXIST
8094 case EEXIST: return DRFLAC_ALREADY_EXISTS;
8095 #endif
8096 #ifdef EXDEV
8097 case EXDEV: return DRFLAC_ERROR;
8098 #endif
8099 #ifdef ENODEV
8100 case ENODEV: return DRFLAC_DOES_NOT_EXIST;
8101 #endif
8102 #ifdef ENOTDIR
8103 case ENOTDIR: return DRFLAC_NOT_DIRECTORY;
8104 #endif
8105 #ifdef EISDIR
8106 case EISDIR: return DRFLAC_IS_DIRECTORY;
8107 #endif
8108 #ifdef EINVAL
8109 case EINVAL: return DRFLAC_INVALID_ARGS;
8110 #endif
8111 #ifdef ENFILE
8112 case ENFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
8113 #endif
8114 #ifdef EMFILE
8115 case EMFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
8116 #endif
8117 #ifdef ENOTTY
8118 case ENOTTY: return DRFLAC_INVALID_OPERATION;
8119 #endif
8120 #ifdef ETXTBSY
8121 case ETXTBSY: return DRFLAC_BUSY;
8122 #endif
8123 #ifdef EFBIG
8124 case EFBIG: return DRFLAC_TOO_BIG;
8125 #endif
8126 #ifdef ENOSPC
8127 case ENOSPC: return DRFLAC_NO_SPACE;
8128 #endif
8129 #ifdef ESPIPE
8130 case ESPIPE: return DRFLAC_BAD_SEEK;
8131 #endif
8132 #ifdef EROFS
8133 case EROFS: return DRFLAC_ACCESS_DENIED;
8134 #endif
8135 #ifdef EMLINK
8136 case EMLINK: return DRFLAC_TOO_MANY_LINKS;
8137 #endif
8138 #ifdef EPIPE
8139 case EPIPE: return DRFLAC_BAD_PIPE;
8140 #endif
8141 #ifdef EDOM
8142 case EDOM: return DRFLAC_OUT_OF_RANGE;
8143 #endif
8144 #ifdef ERANGE
8145 case ERANGE: return DRFLAC_OUT_OF_RANGE;
8146 #endif
8147 #ifdef EDEADLK
8148 case EDEADLK: return DRFLAC_DEADLOCK;
8149 #endif
8150 #ifdef ENAMETOOLONG
8151 case ENAMETOOLONG: return DRFLAC_PATH_TOO_LONG;
8152 #endif
8153 #ifdef ENOLCK
8154 case ENOLCK: return DRFLAC_ERROR;
8155 #endif
8156 #ifdef ENOSYS
8157 case ENOSYS: return DRFLAC_NOT_IMPLEMENTED;
8158 #endif
8159 #ifdef ENOTEMPTY
8160 case ENOTEMPTY: return DRFLAC_DIRECTORY_NOT_EMPTY;
8161 #endif
8162 #ifdef ELOOP
8163 case ELOOP: return DRFLAC_TOO_MANY_LINKS;
8164 #endif
8165 #ifdef ENOMSG
8166 case ENOMSG: return DRFLAC_NO_MESSAGE;
8167 #endif
8168 #ifdef EIDRM
8169 case EIDRM: return DRFLAC_ERROR;
8170 #endif
8171 #ifdef ECHRNG
8172 case ECHRNG: return DRFLAC_ERROR;
8173 #endif
8174 #ifdef EL2NSYNC
8175 case EL2NSYNC: return DRFLAC_ERROR;
8176 #endif
8177 #ifdef EL3HLT
8178 case EL3HLT: return DRFLAC_ERROR;
8179 #endif
8180 #ifdef EL3RST
8181 case EL3RST: return DRFLAC_ERROR;
8182 #endif
8183 #ifdef ELNRNG
8184 case ELNRNG: return DRFLAC_OUT_OF_RANGE;
8185 #endif
8186 #ifdef EUNATCH
8187 case EUNATCH: return DRFLAC_ERROR;
8188 #endif
8189 #ifdef ENOCSI
8190 case ENOCSI: return DRFLAC_ERROR;
8191 #endif
8192 #ifdef EL2HLT
8193 case EL2HLT: return DRFLAC_ERROR;
8194 #endif
8195 #ifdef EBADE
8196 case EBADE: return DRFLAC_ERROR;
8197 #endif
8198 #ifdef EBADR
8199 case EBADR: return DRFLAC_ERROR;
8200 #endif
8201 #ifdef EXFULL
8202 case EXFULL: return DRFLAC_ERROR;
8203 #endif
8204 #ifdef ENOANO
8205 case ENOANO: return DRFLAC_ERROR;
8206 #endif
8207 #ifdef EBADRQC
8208 case EBADRQC: return DRFLAC_ERROR;
8209 #endif
8210 #ifdef EBADSLT
8211 case EBADSLT: return DRFLAC_ERROR;
8212 #endif
8213 #ifdef EBFONT
8214 case EBFONT: return DRFLAC_INVALID_FILE;
8215 #endif
8216 #ifdef ENOSTR
8217 case ENOSTR: return DRFLAC_ERROR;
8218 #endif
8219 #ifdef ENODATA
8220 case ENODATA: return DRFLAC_NO_DATA_AVAILABLE;
8221 #endif
8222 #ifdef ETIME
8223 case ETIME: return DRFLAC_TIMEOUT;
8224 #endif
8225 #ifdef ENOSR
8226 case ENOSR: return DRFLAC_NO_DATA_AVAILABLE;
8227 #endif
8228 #ifdef ENONET
8229 case ENONET: return DRFLAC_NO_NETWORK;
8230 #endif
8231 #ifdef ENOPKG
8232 case ENOPKG: return DRFLAC_ERROR;
8233 #endif
8234 #ifdef EREMOTE
8235 case EREMOTE: return DRFLAC_ERROR;
8236 #endif
8237 #ifdef ENOLINK
8238 case ENOLINK: return DRFLAC_ERROR;
8239 #endif
8240 #ifdef EADV
8241 case EADV: return DRFLAC_ERROR;
8242 #endif
8243 #ifdef ESRMNT
8244 case ESRMNT: return DRFLAC_ERROR;
8245 #endif
8246 #ifdef ECOMM
8247 case ECOMM: return DRFLAC_ERROR;
8248 #endif
8249 #ifdef EPROTO
8250 case EPROTO: return DRFLAC_ERROR;
8251 #endif
8252 #ifdef EMULTIHOP
8253 case EMULTIHOP: return DRFLAC_ERROR;
8254 #endif
8255 #ifdef EDOTDOT
8256 case EDOTDOT: return DRFLAC_ERROR;
8257 #endif
8258 #ifdef EBADMSG
8259 case EBADMSG: return DRFLAC_BAD_MESSAGE;
8260 #endif
8261 #ifdef EOVERFLOW
8262 case EOVERFLOW: return DRFLAC_TOO_BIG;
8263 #endif
8264 #ifdef ENOTUNIQ
8265 case ENOTUNIQ: return DRFLAC_NOT_UNIQUE;
8266 #endif
8267 #ifdef EBADFD
8268 case EBADFD: return DRFLAC_ERROR;
8269 #endif
8270 #ifdef EREMCHG
8271 case EREMCHG: return DRFLAC_ERROR;
8272 #endif
8273 #ifdef ELIBACC
8274 case ELIBACC: return DRFLAC_ACCESS_DENIED;
8275 #endif
8276 #ifdef ELIBBAD
8277 case ELIBBAD: return DRFLAC_INVALID_FILE;
8278 #endif
8279 #ifdef ELIBSCN
8280 case ELIBSCN: return DRFLAC_INVALID_FILE;
8281 #endif
8282 #ifdef ELIBMAX
8283 case ELIBMAX: return DRFLAC_ERROR;
8284 #endif
8285 #ifdef ELIBEXEC
8286 case ELIBEXEC: return DRFLAC_ERROR;
8287 #endif
8288 #ifdef EILSEQ
8289 case EILSEQ: return DRFLAC_INVALID_DATA;
8290 #endif
8291 #ifdef ERESTART
8292 case ERESTART: return DRFLAC_ERROR;
8293 #endif
8294 #ifdef ESTRPIPE
8295 case ESTRPIPE: return DRFLAC_ERROR;
8296 #endif
8297 #ifdef EUSERS
8298 case EUSERS: return DRFLAC_ERROR;
8299 #endif
8300 #ifdef ENOTSOCK
8301 case ENOTSOCK: return DRFLAC_NOT_SOCKET;
8302 #endif
8303 #ifdef EDESTADDRREQ
8304 case EDESTADDRREQ: return DRFLAC_NO_ADDRESS;
8305 #endif
8306 #ifdef EMSGSIZE
8307 case EMSGSIZE: return DRFLAC_TOO_BIG;
8308 #endif
8309 #ifdef EPROTOTYPE
8310 case EPROTOTYPE: return DRFLAC_BAD_PROTOCOL;
8311 #endif
8312 #ifdef ENOPROTOOPT
8313 case ENOPROTOOPT: return DRFLAC_PROTOCOL_UNAVAILABLE;
8314 #endif
8315 #ifdef EPROTONOSUPPORT
8316 case EPROTONOSUPPORT: return DRFLAC_PROTOCOL_NOT_SUPPORTED;
8317 #endif
8318 #ifdef ESOCKTNOSUPPORT
8319 case ESOCKTNOSUPPORT: return DRFLAC_SOCKET_NOT_SUPPORTED;
8320 #endif
8321 #ifdef EOPNOTSUPP
8322 case EOPNOTSUPP: return DRFLAC_INVALID_OPERATION;
8323 #endif
8324 #ifdef EPFNOSUPPORT
8325 case EPFNOSUPPORT: return DRFLAC_PROTOCOL_FAMILY_NOT_SUPPORTED;
8326 #endif
8327 #ifdef EAFNOSUPPORT
8328 case EAFNOSUPPORT: return DRFLAC_ADDRESS_FAMILY_NOT_SUPPORTED;
8329 #endif
8330 #ifdef EADDRINUSE
8331 case EADDRINUSE: return DRFLAC_ALREADY_IN_USE;
8332 #endif
8333 #ifdef EADDRNOTAVAIL
8334 case EADDRNOTAVAIL: return DRFLAC_ERROR;
8335 #endif
8336 #ifdef ENETDOWN
8337 case ENETDOWN: return DRFLAC_NO_NETWORK;
8338 #endif
8339 #ifdef ENETUNREACH
8340 case ENETUNREACH: return DRFLAC_NO_NETWORK;
8341 #endif
8342 #ifdef ENETRESET
8343 case ENETRESET: return DRFLAC_NO_NETWORK;
8344 #endif
8345 #ifdef ECONNABORTED
8346 case ECONNABORTED: return DRFLAC_NO_NETWORK;
8347 #endif
8348 #ifdef ECONNRESET
8349 case ECONNRESET: return DRFLAC_CONNECTION_RESET;
8350 #endif
8351 #ifdef ENOBUFS
8352 case ENOBUFS: return DRFLAC_NO_SPACE;
8353 #endif
8354 #ifdef EISCONN
8355 case EISCONN: return DRFLAC_ALREADY_CONNECTED;
8356 #endif
8357 #ifdef ENOTCONN
8358 case ENOTCONN: return DRFLAC_NOT_CONNECTED;
8359 #endif
8360 #ifdef ESHUTDOWN
8361 case ESHUTDOWN: return DRFLAC_ERROR;
8362 #endif
8363 #ifdef ETOOMANYREFS
8364 case ETOOMANYREFS: return DRFLAC_ERROR;
8365 #endif
8366 #ifdef ETIMEDOUT
8367 case ETIMEDOUT: return DRFLAC_TIMEOUT;
8368 #endif
8369 #ifdef ECONNREFUSED
8370 case ECONNREFUSED: return DRFLAC_CONNECTION_REFUSED;
8371 #endif
8372 #ifdef EHOSTDOWN
8373 case EHOSTDOWN: return DRFLAC_NO_HOST;
8374 #endif
8375 #ifdef EHOSTUNREACH
8376 case EHOSTUNREACH: return DRFLAC_NO_HOST;
8377 #endif
8378 #ifdef EALREADY
8379 case EALREADY: return DRFLAC_IN_PROGRESS;
8380 #endif
8381 #ifdef EINPROGRESS
8382 case EINPROGRESS: return DRFLAC_IN_PROGRESS;
8383 #endif
8384 #ifdef ESTALE
8385 case ESTALE: return DRFLAC_INVALID_FILE;
8386 #endif
8387 #ifdef EUCLEAN
8388 case EUCLEAN: return DRFLAC_ERROR;
8389 #endif
8390 #ifdef ENOTNAM
8391 case ENOTNAM: return DRFLAC_ERROR;
8392 #endif
8393 #ifdef ENAVAIL
8394 case ENAVAIL: return DRFLAC_ERROR;
8395 #endif
8396 #ifdef EISNAM
8397 case EISNAM: return DRFLAC_ERROR;
8398 #endif
8399 #ifdef EREMOTEIO
8400 case EREMOTEIO: return DRFLAC_IO_ERROR;
8401 #endif
8402 #ifdef EDQUOT
8403 case EDQUOT: return DRFLAC_NO_SPACE;
8404 #endif
8405 #ifdef ENOMEDIUM
8406 case ENOMEDIUM: return DRFLAC_DOES_NOT_EXIST;
8407 #endif
8408 #ifdef EMEDIUMTYPE
8409 case EMEDIUMTYPE: return DRFLAC_ERROR;
8410 #endif
8411 #ifdef ECANCELED
8412 case ECANCELED: return DRFLAC_CANCELLED;
8413 #endif
8414 #ifdef ENOKEY
8415 case ENOKEY: return DRFLAC_ERROR;
8416 #endif
8417 #ifdef EKEYEXPIRED
8418 case EKEYEXPIRED: return DRFLAC_ERROR;
8419 #endif
8420 #ifdef EKEYREVOKED
8421 case EKEYREVOKED: return DRFLAC_ERROR;
8422 #endif
8423 #ifdef EKEYREJECTED
8424 case EKEYREJECTED: return DRFLAC_ERROR;
8425 #endif
8426 #ifdef EOWNERDEAD
8427 case EOWNERDEAD: return DRFLAC_ERROR;
8428 #endif
8429 #ifdef ENOTRECOVERABLE
8430 case ENOTRECOVERABLE: return DRFLAC_ERROR;
8431 #endif
8432 #ifdef ERFKILL
8433 case ERFKILL: return DRFLAC_ERROR;
8434 #endif
8435 #ifdef EHWPOISON
8436 case EHWPOISON: return DRFLAC_ERROR;
8437 #endif
8438 default: return DRFLAC_ERROR;
8439 }
8440 }
8441
8442 static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
8443 {
8444 #if defined(_MSC_VER) && _MSC_VER >= 1400
8445 errno_t err;
8446 #endif
8447
8448 if (ppFile != NULL) {
8449 *ppFile = NULL; /* Safety. */
8450 }
8451
8452 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
8453 return DRFLAC_INVALID_ARGS;
8454 }
8455
8456 #if defined(_MSC_VER) && _MSC_VER >= 1400
8457 err = fopen_s(ppFile, pFilePath, pOpenMode);
8458 if (err != 0) {
8459 return drflac_result_from_errno(err);
8460 }
8461 #else
8462 #if defined(_WIN32) || defined(__APPLE__)
8463 *ppFile = fopen(pFilePath, pOpenMode);
8464 #else
8465 #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
8466 *ppFile = fopen64(pFilePath, pOpenMode);
8467 #else
8468 *ppFile = fopen(pFilePath, pOpenMode);
8469 #endif
8470 #endif
8471 if (*ppFile == NULL) {
8472 drflac_result result = drflac_result_from_errno(errno);
8473 if (result == DRFLAC_SUCCESS) {
8474 result = DRFLAC_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */
8475 }
8476
8477 return result;
8478 }
8479 #endif
8480
8481 return DRFLAC_SUCCESS;
8482 }
8483
8484 /*
8485 _wfopen() isn't always available in all compilation environments.
8486
8487 * Windows only.
8488 * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
8489 * MinGW-64 (both 32- and 64-bit) seems to support it.
8490 * MinGW wraps it in !defined(__STRICT_ANSI__).
8491 * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
8492
8493 This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
8494 fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
8495 */
8496 #if defined(_WIN32)
8497 #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
8498 #define DRFLAC_HAS_WFOPEN
8499 #endif
8500 #endif
8501
8502 static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drflac_allocation_callbacks* pAllocationCallbacks)
8503 {
8504 if (ppFile != NULL) {
8505 *ppFile = NULL; /* Safety. */
8506 }
8507
8508 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
8509 return DRFLAC_INVALID_ARGS;
8510 }
8511
8512 #if defined(DRFLAC_HAS_WFOPEN)
8513 {
8514 /* Use _wfopen() on Windows. */
8515 #if defined(_MSC_VER) && _MSC_VER >= 1400
8516 errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
8517 if (err != 0) {
8518 return drflac_result_from_errno(err);
8519 }
8520 #else
8521 *ppFile = _wfopen(pFilePath, pOpenMode);
8522 if (*ppFile == NULL) {
8523 return drflac_result_from_errno(errno);
8524 }
8525 #endif
8526 (void)pAllocationCallbacks;
8527 }
8528 #else
8529 /*
8530 Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
8531 think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
8532 maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
8533 */
8534 {
8535 mbstate_t mbs;
8536 size_t lenMB;
8537 const wchar_t* pFilePathTemp = pFilePath;
8538 char* pFilePathMB = NULL;
8539 char pOpenModeMB[32] = {0};
8540
8541 /* Get the length first. */
8542 DRFLAC_ZERO_OBJECT(&mbs);
8543 lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
8544 if (lenMB == (size_t)-1) {
8545 return drflac_result_from_errno(errno);
8546 }
8547
8548 pFilePathMB = (char*)drflac__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
8549 if (pFilePathMB == NULL) {
8550 return DRFLAC_OUT_OF_MEMORY;
8551 }
8552
8553 pFilePathTemp = pFilePath;
8554 DRFLAC_ZERO_OBJECT(&mbs);
8555 wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
8556
8557 /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
8558 {
8559 size_t i = 0;
8560 for (;;) {
8561 if (pOpenMode[i] == 0) {
8562 pOpenModeMB[i] = '\0';
8563 break;
8564 }
8565
8566 pOpenModeMB[i] = (char)pOpenMode[i];
8567 i += 1;
8568 }
8569 }
8570
8571 *ppFile = fopen(pFilePathMB, pOpenModeMB);
8572
8573 drflac__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
8574 }
8575
8576 if (*ppFile == NULL) {
8577 return DRFLAC_ERROR;
8578 }
8579 #endif
8580
8581 return DRFLAC_SUCCESS;
8582 }
8583
8584 static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
8585 {
8586 return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData);
8587 }
8588
8589 static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
8590 {
8591 DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
8592
8593 return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
8594 }
8595
8596
8597 DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
8598 {
8599 drflac* pFlac;
8600 FILE* pFile;
8601
8602 if (drflac_fopen(&pFile, pFileName, "rb") != DRFLAC_SUCCESS) {
8603 return NULL;
8604 }
8605
8606 pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
8607 if (pFlac == NULL) {
8608 fclose(pFile);
8609 return NULL;
8610 }
8611
8612 return pFlac;
8613 }
8614
8615 DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
8616 {
8617 drflac* pFlac;
8618 FILE* pFile;
8619
8620 if (drflac_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != DRFLAC_SUCCESS) {
8621 return NULL;
8622 }
8623
8624 pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
8625 if (pFlac == NULL) {
8626 fclose(pFile);
8627 return NULL;
8628 }
8629
8630 return pFlac;
8631 }
8632
8633 DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8634 {
8635 drflac* pFlac;
8636 FILE* pFile;
8637
8638 if (drflac_fopen(&pFile, pFileName, "rb") != DRFLAC_SUCCESS) {
8639 return NULL;
8640 }
8641
8642 pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
8643 if (pFlac == NULL) {
8644 fclose(pFile);
8645 return pFlac;
8646 }
8647
8648 return pFlac;
8649 }
8650
8651 DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8652 {
8653 drflac* pFlac;
8654 FILE* pFile;
8655
8656 if (drflac_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != DRFLAC_SUCCESS) {
8657 return NULL;
8658 }
8659
8660 pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
8661 if (pFlac == NULL) {
8662 fclose(pFile);
8663 return pFlac;
8664 }
8665
8666 return pFlac;
8667 }
8668 #endif /* DR_FLAC_NO_STDIO */
8669
8670 static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead)
8671 {
8672 drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
8673 size_t bytesRemaining;
8674
8675 DRFLAC_ASSERT(memoryStream != NULL);
8676 DRFLAC_ASSERT(memoryStream->dataSize >= memoryStream->currentReadPos);
8677
8678 bytesRemaining = memoryStream->dataSize - memoryStream->currentReadPos;
8679 if (bytesToRead > bytesRemaining) {
8680 bytesToRead = bytesRemaining;
8681 }
8682
8683 if (bytesToRead > 0) {
8684 DRFLAC_COPY_MEMORY(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead);
8685 memoryStream->currentReadPos += bytesToRead;
8686 }
8687
8688 return bytesToRead;
8689 }
8690
8691 static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin)
8692 {
8693 drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
8694
8695 DRFLAC_ASSERT(memoryStream != NULL);
8696 DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
8697
8698 if (offset > (drflac_int64)memoryStream->dataSize) {
8699 return DRFLAC_FALSE;
8700 }
8701
8702 if (origin == drflac_seek_origin_current) {
8703 if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) {
8704 memoryStream->currentReadPos += offset;
8705 } else {
8706 return DRFLAC_FALSE; /* Trying to seek too far forward. */
8707 }
8708 } else {
8709 if ((drflac_uint32)offset <= memoryStream->dataSize) {
8710 memoryStream->currentReadPos = offset;
8711 } else {
8712 return DRFLAC_FALSE; /* Trying to seek too far forward. */
8713 }
8714 }
8715
8716 return DRFLAC_TRUE;
8717 }
8718
8719 DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks)
8720 {
8721 drflac__memory_stream memoryStream;
8722 drflac* pFlac;
8723
8724 memoryStream.data = (const drflac_uint8*)pData;
8725 memoryStream.dataSize = dataSize;
8726 memoryStream.currentReadPos = 0;
8727 pFlac = drflac_open(drflac__on_read_memory, drflac__on_seek_memory, &memoryStream, pAllocationCallbacks);
8728 if (pFlac == NULL) {
8729 return NULL;
8730 }
8731
8732 pFlac->memoryStream = memoryStream;
8733
8734 /* This is an awful hack... */
8735 #ifndef DR_FLAC_NO_OGG
8736 if (pFlac->container == drflac_container_ogg)
8737 {
8738 drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
8739 oggbs->pUserData = &pFlac->memoryStream;
8740 }
8741 else
8742 #endif
8743 {
8744 pFlac->bs.pUserData = &pFlac->memoryStream;
8745 }
8746
8747 return pFlac;
8748 }
8749
8750 DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8751 {
8752 drflac__memory_stream memoryStream;
8753 drflac* pFlac;
8754
8755 memoryStream.data = (const drflac_uint8*)pData;
8756 memoryStream.dataSize = dataSize;
8757 memoryStream.currentReadPos = 0;
8758 pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
8759 if (pFlac == NULL) {
8760 return NULL;
8761 }
8762
8763 pFlac->memoryStream = memoryStream;
8764
8765 /* This is an awful hack... */
8766 #ifndef DR_FLAC_NO_OGG
8767 if (pFlac->container == drflac_container_ogg)
8768 {
8769 drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
8770 oggbs->pUserData = &pFlac->memoryStream;
8771 }
8772 else
8773 #endif
8774 {
8775 pFlac->bs.pUserData = &pFlac->memoryStream;
8776 }
8777
8778 return pFlac;
8779 }
8780
8781
8782
8783 DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8784 {
8785 return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
8786 }
8787 DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8788 {
8789 return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData, pAllocationCallbacks);
8790 }
8791
8792 DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8793 {
8794 return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
8795 }
8796 DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8797 {
8798 return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
8799 }
8800
8801 DRFLAC_API void drflac_close(drflac* pFlac)
8802 {
8803 if (pFlac == NULL) {
8804 return;
8805 }
8806
8807 #ifndef DR_FLAC_NO_STDIO
8808 /*
8809 If we opened the file with drflac_open_file() we will want to close the file handle. We can know whether or not drflac_open_file()
8810 was used by looking at the callbacks.
8811 */
8812 if (pFlac->bs.onRead == drflac__on_read_stdio) {
8813 fclose((FILE*)pFlac->bs.pUserData);
8814 }
8815
8816 #ifndef DR_FLAC_NO_OGG
8817 /* Need to clean up Ogg streams a bit differently due to the way the bit streaming is chained. */
8818 if (pFlac->container == drflac_container_ogg) {
8819 drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
8820 DRFLAC_ASSERT(pFlac->bs.onRead == drflac__on_read_ogg);
8821
8822 if (oggbs->onRead == drflac__on_read_stdio) {
8823 fclose((FILE*)oggbs->pUserData);
8824 }
8825 }
8826 #endif
8827 #endif
8828
8829 drflac__free_from_callbacks(pFlac, &pFlac->allocationCallbacks);
8830 }
8831
8832
8833 #if 0
8834 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8835 {
8836 drflac_uint64 i;
8837 for (i = 0; i < frameCount; ++i) {
8838 drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8839 drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8840 drflac_uint32 right = left - side;
8841
8842 pOutputSamples[i*2+0] = (drflac_int32)left;
8843 pOutputSamples[i*2+1] = (drflac_int32)right;
8844 }
8845 }
8846 #endif
8847
8848 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8849 {
8850 drflac_uint64 i;
8851 drflac_uint64 frameCount4 = frameCount >> 2;
8852 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
8853 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
8854 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8855 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8856
8857 for (i = 0; i < frameCount4; ++i) {
8858 drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
8859 drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
8860 drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
8861 drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
8862
8863 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
8864 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
8865 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
8866 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
8867
8868 drflac_uint32 right0 = left0 - side0;
8869 drflac_uint32 right1 = left1 - side1;
8870 drflac_uint32 right2 = left2 - side2;
8871 drflac_uint32 right3 = left3 - side3;
8872
8873 pOutputSamples[i*8+0] = (drflac_int32)left0;
8874 pOutputSamples[i*8+1] = (drflac_int32)right0;
8875 pOutputSamples[i*8+2] = (drflac_int32)left1;
8876 pOutputSamples[i*8+3] = (drflac_int32)right1;
8877 pOutputSamples[i*8+4] = (drflac_int32)left2;
8878 pOutputSamples[i*8+5] = (drflac_int32)right2;
8879 pOutputSamples[i*8+6] = (drflac_int32)left3;
8880 pOutputSamples[i*8+7] = (drflac_int32)right3;
8881 }
8882
8883 for (i = (frameCount4 << 2); i < frameCount; ++i) {
8884 drflac_uint32 left = pInputSamples0U32[i] << shift0;
8885 drflac_uint32 side = pInputSamples1U32[i] << shift1;
8886 drflac_uint32 right = left - side;
8887
8888 pOutputSamples[i*2+0] = (drflac_int32)left;
8889 pOutputSamples[i*2+1] = (drflac_int32)right;
8890 }
8891 }
8892
8893 #if defined(DRFLAC_SUPPORT_SSE2)
8894 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8895 {
8896 drflac_uint64 i;
8897 drflac_uint64 frameCount4 = frameCount >> 2;
8898 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
8899 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
8900 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8901 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8902
8903 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8904
8905 for (i = 0; i < frameCount4; ++i) {
8906 __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
8907 __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
8908 __m128i right = _mm_sub_epi32(left, side);
8909
8910 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
8911 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
8912 }
8913
8914 for (i = (frameCount4 << 2); i < frameCount; ++i) {
8915 drflac_uint32 left = pInputSamples0U32[i] << shift0;
8916 drflac_uint32 side = pInputSamples1U32[i] << shift1;
8917 drflac_uint32 right = left - side;
8918
8919 pOutputSamples[i*2+0] = (drflac_int32)left;
8920 pOutputSamples[i*2+1] = (drflac_int32)right;
8921 }
8922 }
8923 #endif
8924
8925 #if defined(DRFLAC_SUPPORT_NEON)
8926 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8927 {
8928 drflac_uint64 i;
8929 drflac_uint64 frameCount4 = frameCount >> 2;
8930 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
8931 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
8932 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8933 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8934 int32x4_t shift0_4;
8935 int32x4_t shift1_4;
8936
8937 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8938
8939 shift0_4 = vdupq_n_s32(shift0);
8940 shift1_4 = vdupq_n_s32(shift1);
8941
8942 for (i = 0; i < frameCount4; ++i) {
8943 uint32x4_t left;
8944 uint32x4_t side;
8945 uint32x4_t right;
8946
8947 left = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
8948 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
8949 right = vsubq_u32(left, side);
8950
8951 drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
8952 }
8953
8954 for (i = (frameCount4 << 2); i < frameCount; ++i) {
8955 drflac_uint32 left = pInputSamples0U32[i] << shift0;
8956 drflac_uint32 side = pInputSamples1U32[i] << shift1;
8957 drflac_uint32 right = left - side;
8958
8959 pOutputSamples[i*2+0] = (drflac_int32)left;
8960 pOutputSamples[i*2+1] = (drflac_int32)right;
8961 }
8962 }
8963 #endif
8964
8965 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8966 {
8967 #if defined(DRFLAC_SUPPORT_SSE2)
8968 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
8969 drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8970 } else
8971 #elif defined(DRFLAC_SUPPORT_NEON)
8972 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
8973 drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8974 } else
8975 #endif
8976 {
8977 /* Scalar fallback. */
8978 #if 0
8979 drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8980 #else
8981 drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8982 #endif
8983 }
8984 }
8985
8986
8987 #if 0
8988 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8989 {
8990 drflac_uint64 i;
8991 for (i = 0; i < frameCount; ++i) {
8992 drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8993 drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8994 drflac_uint32 left = right + side;
8995
8996 pOutputSamples[i*2+0] = (drflac_int32)left;
8997 pOutputSamples[i*2+1] = (drflac_int32)right;
8998 }
8999 }
9000 #endif
9001
9002 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9003 {
9004 drflac_uint64 i;
9005 drflac_uint64 frameCount4 = frameCount >> 2;
9006 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9007 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9008 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9009 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9010
9011 for (i = 0; i < frameCount4; ++i) {
9012 drflac_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
9013 drflac_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
9014 drflac_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
9015 drflac_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
9016
9017 drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
9018 drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
9019 drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
9020 drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
9021
9022 drflac_uint32 left0 = right0 + side0;
9023 drflac_uint32 left1 = right1 + side1;
9024 drflac_uint32 left2 = right2 + side2;
9025 drflac_uint32 left3 = right3 + side3;
9026
9027 pOutputSamples[i*8+0] = (drflac_int32)left0;
9028 pOutputSamples[i*8+1] = (drflac_int32)right0;
9029 pOutputSamples[i*8+2] = (drflac_int32)left1;
9030 pOutputSamples[i*8+3] = (drflac_int32)right1;
9031 pOutputSamples[i*8+4] = (drflac_int32)left2;
9032 pOutputSamples[i*8+5] = (drflac_int32)right2;
9033 pOutputSamples[i*8+6] = (drflac_int32)left3;
9034 pOutputSamples[i*8+7] = (drflac_int32)right3;
9035 }
9036
9037 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9038 drflac_uint32 side = pInputSamples0U32[i] << shift0;
9039 drflac_uint32 right = pInputSamples1U32[i] << shift1;
9040 drflac_uint32 left = right + side;
9041
9042 pOutputSamples[i*2+0] = (drflac_int32)left;
9043 pOutputSamples[i*2+1] = (drflac_int32)right;
9044 }
9045 }
9046
9047 #if defined(DRFLAC_SUPPORT_SSE2)
9048 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9049 {
9050 drflac_uint64 i;
9051 drflac_uint64 frameCount4 = frameCount >> 2;
9052 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9053 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9054 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9055 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9056
9057 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9058
9059 for (i = 0; i < frameCount4; ++i) {
9060 __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9061 __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9062 __m128i left = _mm_add_epi32(right, side);
9063
9064 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9065 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9066 }
9067
9068 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9069 drflac_uint32 side = pInputSamples0U32[i] << shift0;
9070 drflac_uint32 right = pInputSamples1U32[i] << shift1;
9071 drflac_uint32 left = right + side;
9072
9073 pOutputSamples[i*2+0] = (drflac_int32)left;
9074 pOutputSamples[i*2+1] = (drflac_int32)right;
9075 }
9076 }
9077 #endif
9078
9079 #if defined(DRFLAC_SUPPORT_NEON)
9080 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9081 {
9082 drflac_uint64 i;
9083 drflac_uint64 frameCount4 = frameCount >> 2;
9084 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9085 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9086 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9087 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9088 int32x4_t shift0_4;
9089 int32x4_t shift1_4;
9090
9091 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9092
9093 shift0_4 = vdupq_n_s32(shift0);
9094 shift1_4 = vdupq_n_s32(shift1);
9095
9096 for (i = 0; i < frameCount4; ++i) {
9097 uint32x4_t side;
9098 uint32x4_t right;
9099 uint32x4_t left;
9100
9101 side = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
9102 right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
9103 left = vaddq_u32(right, side);
9104
9105 drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
9106 }
9107
9108 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9109 drflac_uint32 side = pInputSamples0U32[i] << shift0;
9110 drflac_uint32 right = pInputSamples1U32[i] << shift1;
9111 drflac_uint32 left = right + side;
9112
9113 pOutputSamples[i*2+0] = (drflac_int32)left;
9114 pOutputSamples[i*2+1] = (drflac_int32)right;
9115 }
9116 }
9117 #endif
9118
9119 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9120 {
9121 #if defined(DRFLAC_SUPPORT_SSE2)
9122 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9123 drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9124 } else
9125 #elif defined(DRFLAC_SUPPORT_NEON)
9126 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9127 drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9128 } else
9129 #endif
9130 {
9131 /* Scalar fallback. */
9132 #if 0
9133 drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9134 #else
9135 drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9136 #endif
9137 }
9138 }
9139
9140
9141 #if 0
9142 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9143 {
9144 for (drflac_uint64 i = 0; i < frameCount; ++i) {
9145 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9146 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9147
9148 mid = (mid << 1) | (side & 0x01);
9149
9150 pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
9151 pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
9152 }
9153 }
9154 #endif
9155
9156 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9157 {
9158 drflac_uint64 i;
9159 drflac_uint64 frameCount4 = frameCount >> 2;
9160 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9161 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9162 drflac_int32 shift = unusedBitsPerSample;
9163
9164 if (shift > 0) {
9165 shift -= 1;
9166 for (i = 0; i < frameCount4; ++i) {
9167 drflac_uint32 temp0L;
9168 drflac_uint32 temp1L;
9169 drflac_uint32 temp2L;
9170 drflac_uint32 temp3L;
9171 drflac_uint32 temp0R;
9172 drflac_uint32 temp1R;
9173 drflac_uint32 temp2R;
9174 drflac_uint32 temp3R;
9175
9176 drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9177 drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9178 drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9179 drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9180
9181 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9182 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9183 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9184 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9185
9186 mid0 = (mid0 << 1) | (side0 & 0x01);
9187 mid1 = (mid1 << 1) | (side1 & 0x01);
9188 mid2 = (mid2 << 1) | (side2 & 0x01);
9189 mid3 = (mid3 << 1) | (side3 & 0x01);
9190
9191 temp0L = (mid0 + side0) << shift;
9192 temp1L = (mid1 + side1) << shift;
9193 temp2L = (mid2 + side2) << shift;
9194 temp3L = (mid3 + side3) << shift;
9195
9196 temp0R = (mid0 - side0) << shift;
9197 temp1R = (mid1 - side1) << shift;
9198 temp2R = (mid2 - side2) << shift;
9199 temp3R = (mid3 - side3) << shift;
9200
9201 pOutputSamples[i*8+0] = (drflac_int32)temp0L;
9202 pOutputSamples[i*8+1] = (drflac_int32)temp0R;
9203 pOutputSamples[i*8+2] = (drflac_int32)temp1L;
9204 pOutputSamples[i*8+3] = (drflac_int32)temp1R;
9205 pOutputSamples[i*8+4] = (drflac_int32)temp2L;
9206 pOutputSamples[i*8+5] = (drflac_int32)temp2R;
9207 pOutputSamples[i*8+6] = (drflac_int32)temp3L;
9208 pOutputSamples[i*8+7] = (drflac_int32)temp3R;
9209 }
9210 } else {
9211 for (i = 0; i < frameCount4; ++i) {
9212 drflac_uint32 temp0L;
9213 drflac_uint32 temp1L;
9214 drflac_uint32 temp2L;
9215 drflac_uint32 temp3L;
9216 drflac_uint32 temp0R;
9217 drflac_uint32 temp1R;
9218 drflac_uint32 temp2R;
9219 drflac_uint32 temp3R;
9220
9221 drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9222 drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9223 drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9224 drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9225
9226 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9227 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9228 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9229 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9230
9231 mid0 = (mid0 << 1) | (side0 & 0x01);
9232 mid1 = (mid1 << 1) | (side1 & 0x01);
9233 mid2 = (mid2 << 1) | (side2 & 0x01);
9234 mid3 = (mid3 << 1) | (side3 & 0x01);
9235
9236 temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
9237 temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
9238 temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
9239 temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
9240
9241 temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
9242 temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);
9243 temp2R = (drflac_uint32)((drflac_int32)(mid2 - side2) >> 1);
9244 temp3R = (drflac_uint32)((drflac_int32)(mid3 - side3) >> 1);
9245
9246 pOutputSamples[i*8+0] = (drflac_int32)temp0L;
9247 pOutputSamples[i*8+1] = (drflac_int32)temp0R;
9248 pOutputSamples[i*8+2] = (drflac_int32)temp1L;
9249 pOutputSamples[i*8+3] = (drflac_int32)temp1R;
9250 pOutputSamples[i*8+4] = (drflac_int32)temp2L;
9251 pOutputSamples[i*8+5] = (drflac_int32)temp2R;
9252 pOutputSamples[i*8+6] = (drflac_int32)temp3L;
9253 pOutputSamples[i*8+7] = (drflac_int32)temp3R;
9254 }
9255 }
9256
9257 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9258 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9259 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9260
9261 mid = (mid << 1) | (side & 0x01);
9262
9263 pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
9264 pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
9265 }
9266 }
9267
9268 #if defined(DRFLAC_SUPPORT_SSE2)
9269 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9270 {
9271 drflac_uint64 i;
9272 drflac_uint64 frameCount4 = frameCount >> 2;
9273 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9274 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9275 drflac_int32 shift = unusedBitsPerSample;
9276
9277 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9278
9279 if (shift == 0) {
9280 for (i = 0; i < frameCount4; ++i) {
9281 __m128i mid;
9282 __m128i side;
9283 __m128i left;
9284 __m128i right;
9285
9286 mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9287 side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9288
9289 mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
9290
9291 left = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
9292 right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
9293
9294 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9295 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9296 }
9297
9298 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9299 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9300 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9301
9302 mid = (mid << 1) | (side & 0x01);
9303
9304 pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
9305 pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
9306 }
9307 } else {
9308 shift -= 1;
9309 for (i = 0; i < frameCount4; ++i) {
9310 __m128i mid;
9311 __m128i side;
9312 __m128i left;
9313 __m128i right;
9314
9315 mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9316 side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9317
9318 mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
9319
9320 left = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
9321 right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
9322
9323 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9324 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9325 }
9326
9327 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9328 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9329 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9330
9331 mid = (mid << 1) | (side & 0x01);
9332
9333 pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
9334 pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
9335 }
9336 }
9337 }
9338 #endif
9339
9340 #if defined(DRFLAC_SUPPORT_NEON)
9341 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9342 {
9343 drflac_uint64 i;
9344 drflac_uint64 frameCount4 = frameCount >> 2;
9345 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9346 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9347 drflac_int32 shift = unusedBitsPerSample;
9348 int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
9349 int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
9350 uint32x4_t one4;
9351
9352 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9353
9354 wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9355 wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9356 one4 = vdupq_n_u32(1);
9357
9358 if (shift == 0) {
9359 for (i = 0; i < frameCount4; ++i) {
9360 uint32x4_t mid;
9361 uint32x4_t side;
9362 int32x4_t left;
9363 int32x4_t right;
9364
9365 mid = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
9366 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
9367
9368 mid = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
9369
9370 left = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
9371 right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
9372
9373 drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
9374 }
9375
9376 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9377 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9378 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9379
9380 mid = (mid << 1) | (side & 0x01);
9381
9382 pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
9383 pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
9384 }
9385 } else {
9386 int32x4_t shift4;
9387
9388 shift -= 1;
9389 shift4 = vdupq_n_s32(shift);
9390
9391 for (i = 0; i < frameCount4; ++i) {
9392 uint32x4_t mid;
9393 uint32x4_t side;
9394 int32x4_t left;
9395 int32x4_t right;
9396
9397 mid = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
9398 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
9399
9400 mid = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
9401
9402 left = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
9403 right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
9404
9405 drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
9406 }
9407
9408 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9409 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9410 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9411
9412 mid = (mid << 1) | (side & 0x01);
9413
9414 pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
9415 pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
9416 }
9417 }
9418 }
9419 #endif
9420
9421 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9422 {
9423 #if defined(DRFLAC_SUPPORT_SSE2)
9424 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9425 drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9426 } else
9427 #elif defined(DRFLAC_SUPPORT_NEON)
9428 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9429 drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9430 } else
9431 #endif
9432 {
9433 /* Scalar fallback. */
9434 #if 0
9435 drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9436 #else
9437 drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9438 #endif
9439 }
9440 }
9441
9442
9443 #if 0
9444 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9445 {
9446 for (drflac_uint64 i = 0; i < frameCount; ++i) {
9447 pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
9448 pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
9449 }
9450 }
9451 #endif
9452
9453 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9454 {
9455 drflac_uint64 i;
9456 drflac_uint64 frameCount4 = frameCount >> 2;
9457 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9458 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9459 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9460 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9461
9462 for (i = 0; i < frameCount4; ++i) {
9463 drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
9464 drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
9465 drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
9466 drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
9467
9468 drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
9469 drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
9470 drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
9471 drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
9472
9473 pOutputSamples[i*8+0] = (drflac_int32)tempL0;
9474 pOutputSamples[i*8+1] = (drflac_int32)tempR0;
9475 pOutputSamples[i*8+2] = (drflac_int32)tempL1;
9476 pOutputSamples[i*8+3] = (drflac_int32)tempR1;
9477 pOutputSamples[i*8+4] = (drflac_int32)tempL2;
9478 pOutputSamples[i*8+5] = (drflac_int32)tempR2;
9479 pOutputSamples[i*8+6] = (drflac_int32)tempL3;
9480 pOutputSamples[i*8+7] = (drflac_int32)tempR3;
9481 }
9482
9483 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9484 pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
9485 pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
9486 }
9487 }
9488
9489 #if defined(DRFLAC_SUPPORT_SSE2)
9490 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9491 {
9492 drflac_uint64 i;
9493 drflac_uint64 frameCount4 = frameCount >> 2;
9494 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9495 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9496 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9497 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9498
9499 for (i = 0; i < frameCount4; ++i) {
9500 __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9501 __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9502
9503 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9504 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9505 }
9506
9507 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9508 pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
9509 pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
9510 }
9511 }
9512 #endif
9513
9514 #if defined(DRFLAC_SUPPORT_NEON)
9515 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9516 {
9517 drflac_uint64 i;
9518 drflac_uint64 frameCount4 = frameCount >> 2;
9519 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9520 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9521 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9522 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9523
9524 int32x4_t shift4_0 = vdupq_n_s32(shift0);
9525 int32x4_t shift4_1 = vdupq_n_s32(shift1);
9526
9527 for (i = 0; i < frameCount4; ++i) {
9528 int32x4_t left;
9529 int32x4_t right;
9530
9531 left = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift4_0));
9532 right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift4_1));
9533
9534 drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
9535 }
9536
9537 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9538 pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
9539 pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
9540 }
9541 }
9542 #endif
9543
9544 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9545 {
9546 #if defined(DRFLAC_SUPPORT_SSE2)
9547 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9548 drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9549 } else
9550 #elif defined(DRFLAC_SUPPORT_NEON)
9551 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9552 drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9553 } else
9554 #endif
9555 {
9556 /* Scalar fallback. */
9557 #if 0
9558 drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9559 #else
9560 drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9561 #endif
9562 }
9563 }
9564
9565
9566 DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut)
9567 {
9568 drflac_uint64 framesRead;
9569 drflac_uint32 unusedBitsPerSample;
9570
9571 if (pFlac == NULL || framesToRead == 0) {
9572 return 0;
9573 }
9574
9575 if (pBufferOut == NULL) {
9576 return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
9577 }
9578
9579 DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
9580 unusedBitsPerSample = 32 - pFlac->bitsPerSample;
9581
9582 framesRead = 0;
9583 while (framesToRead > 0) {
9584 /* If we've run out of samples in this frame, go to the next. */
9585 if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
9586 if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
9587 break; /* Couldn't read the next frame, so just break from the loop and return. */
9588 }
9589 } else {
9590 unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
9591 drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
9592 drflac_uint64 frameCountThisIteration = framesToRead;
9593
9594 if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
9595 frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
9596 }
9597
9598 if (channelCount == 2) {
9599 const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
9600 const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
9601
9602 switch (pFlac->currentFLACFrame.header.channelAssignment)
9603 {
9604 case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
9605 {
9606 drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9607 } break;
9608
9609 case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
9610 {
9611 drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9612 } break;
9613
9614 case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
9615 {
9616 drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9617 } break;
9618
9619 case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
9620 default:
9621 {
9622 drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9623 } break;
9624 }
9625 } else {
9626 /* Generic interleaving. */
9627 drflac_uint64 i;
9628 for (i = 0; i < frameCountThisIteration; ++i) {
9629 unsigned int j;
9630 for (j = 0; j < channelCount; ++j) {
9631 pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
9632 }
9633 }
9634 }
9635
9636 framesRead += frameCountThisIteration;
9637 pBufferOut += frameCountThisIteration * channelCount;
9638 framesToRead -= frameCountThisIteration;
9639 pFlac->currentPCMFrame += frameCountThisIteration;
9640 pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
9641 }
9642 }
9643
9644 return framesRead;
9645 }
9646
9647
9648 #if 0
9649 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9650 {
9651 drflac_uint64 i;
9652 for (i = 0; i < frameCount; ++i) {
9653 drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9654 drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9655 drflac_uint32 right = left - side;
9656
9657 left >>= 16;
9658 right >>= 16;
9659
9660 pOutputSamples[i*2+0] = (drflac_int16)left;
9661 pOutputSamples[i*2+1] = (drflac_int16)right;
9662 }
9663 }
9664 #endif
9665
9666 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9667 {
9668 drflac_uint64 i;
9669 drflac_uint64 frameCount4 = frameCount >> 2;
9670 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9671 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9672 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9673 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9674
9675 for (i = 0; i < frameCount4; ++i) {
9676 drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
9677 drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
9678 drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
9679 drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
9680
9681 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
9682 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
9683 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
9684 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
9685
9686 drflac_uint32 right0 = left0 - side0;
9687 drflac_uint32 right1 = left1 - side1;
9688 drflac_uint32 right2 = left2 - side2;
9689 drflac_uint32 right3 = left3 - side3;
9690
9691 left0 >>= 16;
9692 left1 >>= 16;
9693 left2 >>= 16;
9694 left3 >>= 16;
9695
9696 right0 >>= 16;
9697 right1 >>= 16;
9698 right2 >>= 16;
9699 right3 >>= 16;
9700
9701 pOutputSamples[i*8+0] = (drflac_int16)left0;
9702 pOutputSamples[i*8+1] = (drflac_int16)right0;
9703 pOutputSamples[i*8+2] = (drflac_int16)left1;
9704 pOutputSamples[i*8+3] = (drflac_int16)right1;
9705 pOutputSamples[i*8+4] = (drflac_int16)left2;
9706 pOutputSamples[i*8+5] = (drflac_int16)right2;
9707 pOutputSamples[i*8+6] = (drflac_int16)left3;
9708 pOutputSamples[i*8+7] = (drflac_int16)right3;
9709 }
9710
9711 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9712 drflac_uint32 left = pInputSamples0U32[i] << shift0;
9713 drflac_uint32 side = pInputSamples1U32[i] << shift1;
9714 drflac_uint32 right = left - side;
9715
9716 left >>= 16;
9717 right >>= 16;
9718
9719 pOutputSamples[i*2+0] = (drflac_int16)left;
9720 pOutputSamples[i*2+1] = (drflac_int16)right;
9721 }
9722 }
9723
9724 #if defined(DRFLAC_SUPPORT_SSE2)
9725 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9726 {
9727 drflac_uint64 i;
9728 drflac_uint64 frameCount4 = frameCount >> 2;
9729 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9730 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9731 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9732 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9733
9734 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9735
9736 for (i = 0; i < frameCount4; ++i) {
9737 __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9738 __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9739 __m128i right = _mm_sub_epi32(left, side);
9740
9741 left = _mm_srai_epi32(left, 16);
9742 right = _mm_srai_epi32(right, 16);
9743
9744 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
9745 }
9746
9747 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9748 drflac_uint32 left = pInputSamples0U32[i] << shift0;
9749 drflac_uint32 side = pInputSamples1U32[i] << shift1;
9750 drflac_uint32 right = left - side;
9751
9752 left >>= 16;
9753 right >>= 16;
9754
9755 pOutputSamples[i*2+0] = (drflac_int16)left;
9756 pOutputSamples[i*2+1] = (drflac_int16)right;
9757 }
9758 }
9759 #endif
9760
9761 #if defined(DRFLAC_SUPPORT_NEON)
9762 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9763 {
9764 drflac_uint64 i;
9765 drflac_uint64 frameCount4 = frameCount >> 2;
9766 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9767 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9768 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9769 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9770 int32x4_t shift0_4;
9771 int32x4_t shift1_4;
9772
9773 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9774
9775 shift0_4 = vdupq_n_s32(shift0);
9776 shift1_4 = vdupq_n_s32(shift1);
9777
9778 for (i = 0; i < frameCount4; ++i) {
9779 uint32x4_t left;
9780 uint32x4_t side;
9781 uint32x4_t right;
9782
9783 left = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
9784 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
9785 right = vsubq_u32(left, side);
9786
9787 left = vshrq_n_u32(left, 16);
9788 right = vshrq_n_u32(right, 16);
9789
9790 drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
9791 }
9792
9793 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9794 drflac_uint32 left = pInputSamples0U32[i] << shift0;
9795 drflac_uint32 side = pInputSamples1U32[i] << shift1;
9796 drflac_uint32 right = left - side;
9797
9798 left >>= 16;
9799 right >>= 16;
9800
9801 pOutputSamples[i*2+0] = (drflac_int16)left;
9802 pOutputSamples[i*2+1] = (drflac_int16)right;
9803 }
9804 }
9805 #endif
9806
9807 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9808 {
9809 #if defined(DRFLAC_SUPPORT_SSE2)
9810 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9811 drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9812 } else
9813 #elif defined(DRFLAC_SUPPORT_NEON)
9814 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9815 drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9816 } else
9817 #endif
9818 {
9819 /* Scalar fallback. */
9820 #if 0
9821 drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9822 #else
9823 drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9824 #endif
9825 }
9826 }
9827
9828
9829 #if 0
9830 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9831 {
9832 drflac_uint64 i;
9833 for (i = 0; i < frameCount; ++i) {
9834 drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9835 drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9836 drflac_uint32 left = right + side;
9837
9838 left >>= 16;
9839 right >>= 16;
9840
9841 pOutputSamples[i*2+0] = (drflac_int16)left;
9842 pOutputSamples[i*2+1] = (drflac_int16)right;
9843 }
9844 }
9845 #endif
9846
9847 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9848 {
9849 drflac_uint64 i;
9850 drflac_uint64 frameCount4 = frameCount >> 2;
9851 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9852 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9853 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9854 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9855
9856 for (i = 0; i < frameCount4; ++i) {
9857 drflac_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
9858 drflac_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
9859 drflac_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
9860 drflac_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
9861
9862 drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
9863 drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
9864 drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
9865 drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
9866
9867 drflac_uint32 left0 = right0 + side0;
9868 drflac_uint32 left1 = right1 + side1;
9869 drflac_uint32 left2 = right2 + side2;
9870 drflac_uint32 left3 = right3 + side3;
9871
9872 left0 >>= 16;
9873 left1 >>= 16;
9874 left2 >>= 16;
9875 left3 >>= 16;
9876
9877 right0 >>= 16;
9878 right1 >>= 16;
9879 right2 >>= 16;
9880 right3 >>= 16;
9881
9882 pOutputSamples[i*8+0] = (drflac_int16)left0;
9883 pOutputSamples[i*8+1] = (drflac_int16)right0;
9884 pOutputSamples[i*8+2] = (drflac_int16)left1;
9885 pOutputSamples[i*8+3] = (drflac_int16)right1;
9886 pOutputSamples[i*8+4] = (drflac_int16)left2;
9887 pOutputSamples[i*8+5] = (drflac_int16)right2;
9888 pOutputSamples[i*8+6] = (drflac_int16)left3;
9889 pOutputSamples[i*8+7] = (drflac_int16)right3;
9890 }
9891
9892 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9893 drflac_uint32 side = pInputSamples0U32[i] << shift0;
9894 drflac_uint32 right = pInputSamples1U32[i] << shift1;
9895 drflac_uint32 left = right + side;
9896
9897 left >>= 16;
9898 right >>= 16;
9899
9900 pOutputSamples[i*2+0] = (drflac_int16)left;
9901 pOutputSamples[i*2+1] = (drflac_int16)right;
9902 }
9903 }
9904
9905 #if defined(DRFLAC_SUPPORT_SSE2)
9906 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9907 {
9908 drflac_uint64 i;
9909 drflac_uint64 frameCount4 = frameCount >> 2;
9910 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9911 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9912 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9913 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9914
9915 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9916
9917 for (i = 0; i < frameCount4; ++i) {
9918 __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9919 __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9920 __m128i left = _mm_add_epi32(right, side);
9921
9922 left = _mm_srai_epi32(left, 16);
9923 right = _mm_srai_epi32(right, 16);
9924
9925 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
9926 }
9927
9928 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9929 drflac_uint32 side = pInputSamples0U32[i] << shift0;
9930 drflac_uint32 right = pInputSamples1U32[i] << shift1;
9931 drflac_uint32 left = right + side;
9932
9933 left >>= 16;
9934 right >>= 16;
9935
9936 pOutputSamples[i*2+0] = (drflac_int16)left;
9937 pOutputSamples[i*2+1] = (drflac_int16)right;
9938 }
9939 }
9940 #endif
9941
9942 #if defined(DRFLAC_SUPPORT_NEON)
9943 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9944 {
9945 drflac_uint64 i;
9946 drflac_uint64 frameCount4 = frameCount >> 2;
9947 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9948 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9949 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9950 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9951 int32x4_t shift0_4;
9952 int32x4_t shift1_4;
9953
9954 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9955
9956 shift0_4 = vdupq_n_s32(shift0);
9957 shift1_4 = vdupq_n_s32(shift1);
9958
9959 for (i = 0; i < frameCount4; ++i) {
9960 uint32x4_t side;
9961 uint32x4_t right;
9962 uint32x4_t left;
9963
9964 side = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
9965 right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
9966 left = vaddq_u32(right, side);
9967
9968 left = vshrq_n_u32(left, 16);
9969 right = vshrq_n_u32(right, 16);
9970
9971 drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
9972 }
9973
9974 for (i = (frameCount4 << 2); i < frameCount; ++i) {
9975 drflac_uint32 side = pInputSamples0U32[i] << shift0;
9976 drflac_uint32 right = pInputSamples1U32[i] << shift1;
9977 drflac_uint32 left = right + side;
9978
9979 left >>= 16;
9980 right >>= 16;
9981
9982 pOutputSamples[i*2+0] = (drflac_int16)left;
9983 pOutputSamples[i*2+1] = (drflac_int16)right;
9984 }
9985 }
9986 #endif
9987
9988 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9989 {
9990 #if defined(DRFLAC_SUPPORT_SSE2)
9991 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9992 drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9993 } else
9994 #elif defined(DRFLAC_SUPPORT_NEON)
9995 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9996 drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9997 } else
9998 #endif
9999 {
10000 /* Scalar fallback. */
10001 #if 0
10002 drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10003 #else
10004 drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10005 #endif
10006 }
10007 }
10008
10009
10010 #if 0
10011 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10012 {
10013 for (drflac_uint64 i = 0; i < frameCount; ++i) {
10014 drflac_uint32 mid = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10015 drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10016
10017 mid = (mid << 1) | (side & 0x01);
10018
10019 pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
10020 pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
10021 }
10022 }
10023 #endif
10024
10025 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10026 {
10027 drflac_uint64 i;
10028 drflac_uint64 frameCount4 = frameCount >> 2;
10029 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10030 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10031 drflac_uint32 shift = unusedBitsPerSample;
10032
10033 if (shift > 0) {
10034 shift -= 1;
10035 for (i = 0; i < frameCount4; ++i) {
10036 drflac_uint32 temp0L;
10037 drflac_uint32 temp1L;
10038 drflac_uint32 temp2L;
10039 drflac_uint32 temp3L;
10040 drflac_uint32 temp0R;
10041 drflac_uint32 temp1R;
10042 drflac_uint32 temp2R;
10043 drflac_uint32 temp3R;
10044
10045 drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10046 drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10047 drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10048 drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10049
10050 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10051 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10052 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10053 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10054
10055 mid0 = (mid0 << 1) | (side0 & 0x01);
10056 mid1 = (mid1 << 1) | (side1 & 0x01);
10057 mid2 = (mid2 << 1) | (side2 & 0x01);
10058 mid3 = (mid3 << 1) | (side3 & 0x01);
10059
10060 temp0L = (mid0 + side0) << shift;
10061 temp1L = (mid1 + side1) << shift;
10062 temp2L = (mid2 + side2) << shift;
10063 temp3L = (mid3 + side3) << shift;
10064
10065 temp0R = (mid0 - side0) << shift;
10066 temp1R = (mid1 - side1) << shift;
10067 temp2R = (mid2 - side2) << shift;
10068 temp3R = (mid3 - side3) << shift;
10069
10070 temp0L >>= 16;
10071 temp1L >>= 16;
10072 temp2L >>= 16;
10073 temp3L >>= 16;
10074
10075 temp0R >>= 16;
10076 temp1R >>= 16;
10077 temp2R >>= 16;
10078 temp3R >>= 16;
10079
10080 pOutputSamples[i*8+0] = (drflac_int16)temp0L;
10081 pOutputSamples[i*8+1] = (drflac_int16)temp0R;
10082 pOutputSamples[i*8+2] = (drflac_int16)temp1L;
10083 pOutputSamples[i*8+3] = (drflac_int16)temp1R;
10084 pOutputSamples[i*8+4] = (drflac_int16)temp2L;
10085 pOutputSamples[i*8+5] = (drflac_int16)temp2R;
10086 pOutputSamples[i*8+6] = (drflac_int16)temp3L;
10087 pOutputSamples[i*8+7] = (drflac_int16)temp3R;
10088 }
10089 } else {
10090 for (i = 0; i < frameCount4; ++i) {
10091 drflac_uint32 temp0L;
10092 drflac_uint32 temp1L;
10093 drflac_uint32 temp2L;
10094 drflac_uint32 temp3L;
10095 drflac_uint32 temp0R;
10096 drflac_uint32 temp1R;
10097 drflac_uint32 temp2R;
10098 drflac_uint32 temp3R;
10099
10100 drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10101 drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10102 drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10103 drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10104
10105 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10106 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10107 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10108 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10109
10110 mid0 = (mid0 << 1) | (side0 & 0x01);
10111 mid1 = (mid1 << 1) | (side1 & 0x01);
10112 mid2 = (mid2 << 1) | (side2 & 0x01);
10113 mid3 = (mid3 << 1) | (side3 & 0x01);
10114
10115 temp0L = ((drflac_int32)(mid0 + side0) >> 1);
10116 temp1L = ((drflac_int32)(mid1 + side1) >> 1);
10117 temp2L = ((drflac_int32)(mid2 + side2) >> 1);
10118 temp3L = ((drflac_int32)(mid3 + side3) >> 1);
10119
10120 temp0R = ((drflac_int32)(mid0 - side0) >> 1);
10121 temp1R = ((drflac_int32)(mid1 - side1) >> 1);
10122 temp2R = ((drflac_int32)(mid2 - side2) >> 1);
10123 temp3R = ((drflac_int32)(mid3 - side3) >> 1);
10124
10125 temp0L >>= 16;
10126 temp1L >>= 16;
10127 temp2L >>= 16;
10128 temp3L >>= 16;
10129
10130 temp0R >>= 16;
10131 temp1R >>= 16;
10132 temp2R >>= 16;
10133 temp3R >>= 16;
10134
10135 pOutputSamples[i*8+0] = (drflac_int16)temp0L;
10136 pOutputSamples[i*8+1] = (drflac_int16)temp0R;
10137 pOutputSamples[i*8+2] = (drflac_int16)temp1L;
10138 pOutputSamples[i*8+3] = (drflac_int16)temp1R;
10139 pOutputSamples[i*8+4] = (drflac_int16)temp2L;
10140 pOutputSamples[i*8+5] = (drflac_int16)temp2R;
10141 pOutputSamples[i*8+6] = (drflac_int16)temp3L;
10142 pOutputSamples[i*8+7] = (drflac_int16)temp3R;
10143 }
10144 }
10145
10146 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10147 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10148 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10149
10150 mid = (mid << 1) | (side & 0x01);
10151
10152 pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
10153 pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
10154 }
10155 }
10156
10157 #if defined(DRFLAC_SUPPORT_SSE2)
10158 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10159 {
10160 drflac_uint64 i;
10161 drflac_uint64 frameCount4 = frameCount >> 2;
10162 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10163 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10164 drflac_uint32 shift = unusedBitsPerSample;
10165
10166 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10167
10168 if (shift == 0) {
10169 for (i = 0; i < frameCount4; ++i) {
10170 __m128i mid;
10171 __m128i side;
10172 __m128i left;
10173 __m128i right;
10174
10175 mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10176 side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10177
10178 mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
10179
10180 left = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
10181 right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
10182
10183 left = _mm_srai_epi32(left, 16);
10184 right = _mm_srai_epi32(right, 16);
10185
10186 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10187 }
10188
10189 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10190 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10191 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10192
10193 mid = (mid << 1) | (side & 0x01);
10194
10195 pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
10196 pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
10197 }
10198 } else {
10199 shift -= 1;
10200 for (i = 0; i < frameCount4; ++i) {
10201 __m128i mid;
10202 __m128i side;
10203 __m128i left;
10204 __m128i right;
10205
10206 mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10207 side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10208
10209 mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
10210
10211 left = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
10212 right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
10213
10214 left = _mm_srai_epi32(left, 16);
10215 right = _mm_srai_epi32(right, 16);
10216
10217 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10218 }
10219
10220 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10221 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10222 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10223
10224 mid = (mid << 1) | (side & 0x01);
10225
10226 pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
10227 pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
10228 }
10229 }
10230 }
10231 #endif
10232
10233 #if defined(DRFLAC_SUPPORT_NEON)
10234 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10235 {
10236 drflac_uint64 i;
10237 drflac_uint64 frameCount4 = frameCount >> 2;
10238 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10239 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10240 drflac_uint32 shift = unusedBitsPerSample;
10241 int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
10242 int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
10243
10244 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10245
10246 wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10247 wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10248
10249 if (shift == 0) {
10250 for (i = 0; i < frameCount4; ++i) {
10251 uint32x4_t mid;
10252 uint32x4_t side;
10253 int32x4_t left;
10254 int32x4_t right;
10255
10256 mid = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
10257 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
10258
10259 mid = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
10260
10261 left = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
10262 right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
10263
10264 left = vshrq_n_s32(left, 16);
10265 right = vshrq_n_s32(right, 16);
10266
10267 drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
10268 }
10269
10270 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10271 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10272 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10273
10274 mid = (mid << 1) | (side & 0x01);
10275
10276 pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
10277 pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
10278 }
10279 } else {
10280 int32x4_t shift4;
10281
10282 shift -= 1;
10283 shift4 = vdupq_n_s32(shift);
10284
10285 for (i = 0; i < frameCount4; ++i) {
10286 uint32x4_t mid;
10287 uint32x4_t side;
10288 int32x4_t left;
10289 int32x4_t right;
10290
10291 mid = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
10292 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
10293
10294 mid = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
10295
10296 left = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
10297 right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
10298
10299 left = vshrq_n_s32(left, 16);
10300 right = vshrq_n_s32(right, 16);
10301
10302 drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
10303 }
10304
10305 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10306 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10307 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10308
10309 mid = (mid << 1) | (side & 0x01);
10310
10311 pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
10312 pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
10313 }
10314 }
10315 }
10316 #endif
10317
10318 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10319 {
10320 #if defined(DRFLAC_SUPPORT_SSE2)
10321 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10322 drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10323 } else
10324 #elif defined(DRFLAC_SUPPORT_NEON)
10325 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10326 drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10327 } else
10328 #endif
10329 {
10330 /* Scalar fallback. */
10331 #if 0
10332 drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10333 #else
10334 drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10335 #endif
10336 }
10337 }
10338
10339
10340 #if 0
10341 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10342 {
10343 for (drflac_uint64 i = 0; i < frameCount; ++i) {
10344 pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
10345 pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
10346 }
10347 }
10348 #endif
10349
10350 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10351 {
10352 drflac_uint64 i;
10353 drflac_uint64 frameCount4 = frameCount >> 2;
10354 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10355 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10356 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10357 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10358
10359 for (i = 0; i < frameCount4; ++i) {
10360 drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
10361 drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
10362 drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
10363 drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
10364
10365 drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
10366 drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
10367 drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
10368 drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
10369
10370 tempL0 >>= 16;
10371 tempL1 >>= 16;
10372 tempL2 >>= 16;
10373 tempL3 >>= 16;
10374
10375 tempR0 >>= 16;
10376 tempR1 >>= 16;
10377 tempR2 >>= 16;
10378 tempR3 >>= 16;
10379
10380 pOutputSamples[i*8+0] = (drflac_int16)tempL0;
10381 pOutputSamples[i*8+1] = (drflac_int16)tempR0;
10382 pOutputSamples[i*8+2] = (drflac_int16)tempL1;
10383 pOutputSamples[i*8+3] = (drflac_int16)tempR1;
10384 pOutputSamples[i*8+4] = (drflac_int16)tempL2;
10385 pOutputSamples[i*8+5] = (drflac_int16)tempR2;
10386 pOutputSamples[i*8+6] = (drflac_int16)tempL3;
10387 pOutputSamples[i*8+7] = (drflac_int16)tempR3;
10388 }
10389
10390 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10391 pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
10392 pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
10393 }
10394 }
10395
10396 #if defined(DRFLAC_SUPPORT_SSE2)
10397 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10398 {
10399 drflac_uint64 i;
10400 drflac_uint64 frameCount4 = frameCount >> 2;
10401 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10402 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10403 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10404 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10405
10406 for (i = 0; i < frameCount4; ++i) {
10407 __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10408 __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10409
10410 left = _mm_srai_epi32(left, 16);
10411 right = _mm_srai_epi32(right, 16);
10412
10413 /* At this point we have results. We can now pack and interleave these into a single __m128i object and then store the in the output buffer. */
10414 _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10415 }
10416
10417 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10418 pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
10419 pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
10420 }
10421 }
10422 #endif
10423
10424 #if defined(DRFLAC_SUPPORT_NEON)
10425 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10426 {
10427 drflac_uint64 i;
10428 drflac_uint64 frameCount4 = frameCount >> 2;
10429 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10430 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10431 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10432 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10433
10434 int32x4_t shift0_4 = vdupq_n_s32(shift0);
10435 int32x4_t shift1_4 = vdupq_n_s32(shift1);
10436
10437 for (i = 0; i < frameCount4; ++i) {
10438 int32x4_t left;
10439 int32x4_t right;
10440
10441 left = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
10442 right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
10443
10444 left = vshrq_n_s32(left, 16);
10445 right = vshrq_n_s32(right, 16);
10446
10447 drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
10448 }
10449
10450 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10451 pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
10452 pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
10453 }
10454 }
10455 #endif
10456
10457 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10458 {
10459 #if defined(DRFLAC_SUPPORT_SSE2)
10460 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10461 drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10462 } else
10463 #elif defined(DRFLAC_SUPPORT_NEON)
10464 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10465 drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10466 } else
10467 #endif
10468 {
10469 /* Scalar fallback. */
10470 #if 0
10471 drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10472 #else
10473 drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10474 #endif
10475 }
10476 }
10477
10478 DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut)
10479 {
10480 drflac_uint64 framesRead;
10481 drflac_uint32 unusedBitsPerSample;
10482
10483 if (pFlac == NULL || framesToRead == 0) {
10484 return 0;
10485 }
10486
10487 if (pBufferOut == NULL) {
10488 return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
10489 }
10490
10491 DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
10492 unusedBitsPerSample = 32 - pFlac->bitsPerSample;
10493
10494 framesRead = 0;
10495 while (framesToRead > 0) {
10496 /* If we've run out of samples in this frame, go to the next. */
10497 if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
10498 if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
10499 break; /* Couldn't read the next frame, so just break from the loop and return. */
10500 }
10501 } else {
10502 unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
10503 drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
10504 drflac_uint64 frameCountThisIteration = framesToRead;
10505
10506 if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
10507 frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
10508 }
10509
10510 if (channelCount == 2) {
10511 const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
10512 const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
10513
10514 switch (pFlac->currentFLACFrame.header.channelAssignment)
10515 {
10516 case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
10517 {
10518 drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10519 } break;
10520
10521 case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
10522 {
10523 drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10524 } break;
10525
10526 case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
10527 {
10528 drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10529 } break;
10530
10531 case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
10532 default:
10533 {
10534 drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10535 } break;
10536 }
10537 } else {
10538 /* Generic interleaving. */
10539 drflac_uint64 i;
10540 for (i = 0; i < frameCountThisIteration; ++i) {
10541 unsigned int j;
10542 for (j = 0; j < channelCount; ++j) {
10543 drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
10544 pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
10545 }
10546 }
10547 }
10548
10549 framesRead += frameCountThisIteration;
10550 pBufferOut += frameCountThisIteration * channelCount;
10551 framesToRead -= frameCountThisIteration;
10552 pFlac->currentPCMFrame += frameCountThisIteration;
10553 pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
10554 }
10555 }
10556
10557 return framesRead;
10558 }
10559
10560
10561 #if 0
10562 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10563 {
10564 drflac_uint64 i;
10565 for (i = 0; i < frameCount; ++i) {
10566 drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10567 drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10568 drflac_uint32 right = left - side;
10569
10570 pOutputSamples[i*2+0] = (float)((drflac_int32)left / 2147483648.0);
10571 pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
10572 }
10573 }
10574 #endif
10575
10576 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10577 {
10578 drflac_uint64 i;
10579 drflac_uint64 frameCount4 = frameCount >> 2;
10580 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10581 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10582 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10583 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10584
10585 float factor = 1 / 2147483648.0;
10586
10587 for (i = 0; i < frameCount4; ++i) {
10588 drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
10589 drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
10590 drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
10591 drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
10592
10593 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
10594 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
10595 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
10596 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
10597
10598 drflac_uint32 right0 = left0 - side0;
10599 drflac_uint32 right1 = left1 - side1;
10600 drflac_uint32 right2 = left2 - side2;
10601 drflac_uint32 right3 = left3 - side3;
10602
10603 pOutputSamples[i*8+0] = (drflac_int32)left0 * factor;
10604 pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
10605 pOutputSamples[i*8+2] = (drflac_int32)left1 * factor;
10606 pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
10607 pOutputSamples[i*8+4] = (drflac_int32)left2 * factor;
10608 pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
10609 pOutputSamples[i*8+6] = (drflac_int32)left3 * factor;
10610 pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
10611 }
10612
10613 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10614 drflac_uint32 left = pInputSamples0U32[i] << shift0;
10615 drflac_uint32 side = pInputSamples1U32[i] << shift1;
10616 drflac_uint32 right = left - side;
10617
10618 pOutputSamples[i*2+0] = (drflac_int32)left * factor;
10619 pOutputSamples[i*2+1] = (drflac_int32)right * factor;
10620 }
10621 }
10622
10623 #if defined(DRFLAC_SUPPORT_SSE2)
10624 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10625 {
10626 drflac_uint64 i;
10627 drflac_uint64 frameCount4 = frameCount >> 2;
10628 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10629 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10630 drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
10631 drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
10632 __m128 factor;
10633
10634 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10635
10636 factor = _mm_set1_ps(1.0f / 8388608.0f);
10637
10638 for (i = 0; i < frameCount4; ++i) {
10639 __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10640 __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10641 __m128i right = _mm_sub_epi32(left, side);
10642 __m128 leftf = _mm_mul_ps(_mm_cvtepi32_ps(left), factor);
10643 __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
10644
10645 _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
10646 _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
10647 }
10648
10649 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10650 drflac_uint32 left = pInputSamples0U32[i] << shift0;
10651 drflac_uint32 side = pInputSamples1U32[i] << shift1;
10652 drflac_uint32 right = left - side;
10653
10654 pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
10655 pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
10656 }
10657 }
10658 #endif
10659
10660 #if defined(DRFLAC_SUPPORT_NEON)
10661 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10662 {
10663 drflac_uint64 i;
10664 drflac_uint64 frameCount4 = frameCount >> 2;
10665 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10666 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10667 drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
10668 drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
10669 float32x4_t factor4;
10670 int32x4_t shift0_4;
10671 int32x4_t shift1_4;
10672
10673 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10674
10675 factor4 = vdupq_n_f32(1.0f / 8388608.0f);
10676 shift0_4 = vdupq_n_s32(shift0);
10677 shift1_4 = vdupq_n_s32(shift1);
10678
10679 for (i = 0; i < frameCount4; ++i) {
10680 uint32x4_t left;
10681 uint32x4_t side;
10682 uint32x4_t right;
10683 float32x4_t leftf;
10684 float32x4_t rightf;
10685
10686 left = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
10687 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
10688 right = vsubq_u32(left, side);
10689 leftf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)), factor4);
10690 rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
10691
10692 drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
10693 }
10694
10695 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10696 drflac_uint32 left = pInputSamples0U32[i] << shift0;
10697 drflac_uint32 side = pInputSamples1U32[i] << shift1;
10698 drflac_uint32 right = left - side;
10699
10700 pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
10701 pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
10702 }
10703 }
10704 #endif
10705
10706 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10707 {
10708 #if defined(DRFLAC_SUPPORT_SSE2)
10709 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10710 drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10711 } else
10712 #elif defined(DRFLAC_SUPPORT_NEON)
10713 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10714 drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10715 } else
10716 #endif
10717 {
10718 /* Scalar fallback. */
10719 #if 0
10720 drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10721 #else
10722 drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10723 #endif
10724 }
10725 }
10726
10727
10728 #if 0
10729 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10730 {
10731 drflac_uint64 i;
10732 for (i = 0; i < frameCount; ++i) {
10733 drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10734 drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10735 drflac_uint32 left = right + side;
10736
10737 pOutputSamples[i*2+0] = (float)((drflac_int32)left / 2147483648.0);
10738 pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
10739 }
10740 }
10741 #endif
10742
10743 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10744 {
10745 drflac_uint64 i;
10746 drflac_uint64 frameCount4 = frameCount >> 2;
10747 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10748 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10749 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10750 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10751 float factor = 1 / 2147483648.0;
10752
10753 for (i = 0; i < frameCount4; ++i) {
10754 drflac_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
10755 drflac_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
10756 drflac_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
10757 drflac_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
10758
10759 drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
10760 drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
10761 drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
10762 drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
10763
10764 drflac_uint32 left0 = right0 + side0;
10765 drflac_uint32 left1 = right1 + side1;
10766 drflac_uint32 left2 = right2 + side2;
10767 drflac_uint32 left3 = right3 + side3;
10768
10769 pOutputSamples[i*8+0] = (drflac_int32)left0 * factor;
10770 pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
10771 pOutputSamples[i*8+2] = (drflac_int32)left1 * factor;
10772 pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
10773 pOutputSamples[i*8+4] = (drflac_int32)left2 * factor;
10774 pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
10775 pOutputSamples[i*8+6] = (drflac_int32)left3 * factor;
10776 pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
10777 }
10778
10779 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10780 drflac_uint32 side = pInputSamples0U32[i] << shift0;
10781 drflac_uint32 right = pInputSamples1U32[i] << shift1;
10782 drflac_uint32 left = right + side;
10783
10784 pOutputSamples[i*2+0] = (drflac_int32)left * factor;
10785 pOutputSamples[i*2+1] = (drflac_int32)right * factor;
10786 }
10787 }
10788
10789 #if defined(DRFLAC_SUPPORT_SSE2)
10790 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10791 {
10792 drflac_uint64 i;
10793 drflac_uint64 frameCount4 = frameCount >> 2;
10794 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10795 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10796 drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
10797 drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
10798 __m128 factor;
10799
10800 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10801
10802 factor = _mm_set1_ps(1.0f / 8388608.0f);
10803
10804 for (i = 0; i < frameCount4; ++i) {
10805 __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10806 __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10807 __m128i left = _mm_add_epi32(right, side);
10808 __m128 leftf = _mm_mul_ps(_mm_cvtepi32_ps(left), factor);
10809 __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
10810
10811 _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
10812 _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
10813 }
10814
10815 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10816 drflac_uint32 side = pInputSamples0U32[i] << shift0;
10817 drflac_uint32 right = pInputSamples1U32[i] << shift1;
10818 drflac_uint32 left = right + side;
10819
10820 pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
10821 pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
10822 }
10823 }
10824 #endif
10825
10826 #if defined(DRFLAC_SUPPORT_NEON)
10827 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10828 {
10829 drflac_uint64 i;
10830 drflac_uint64 frameCount4 = frameCount >> 2;
10831 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10832 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10833 drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
10834 drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
10835 float32x4_t factor4;
10836 int32x4_t shift0_4;
10837 int32x4_t shift1_4;
10838
10839 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10840
10841 factor4 = vdupq_n_f32(1.0f / 8388608.0f);
10842 shift0_4 = vdupq_n_s32(shift0);
10843 shift1_4 = vdupq_n_s32(shift1);
10844
10845 for (i = 0; i < frameCount4; ++i) {
10846 uint32x4_t side;
10847 uint32x4_t right;
10848 uint32x4_t left;
10849 float32x4_t leftf;
10850 float32x4_t rightf;
10851
10852 side = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
10853 right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
10854 left = vaddq_u32(right, side);
10855 leftf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)), factor4);
10856 rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
10857
10858 drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
10859 }
10860
10861 for (i = (frameCount4 << 2); i < frameCount; ++i) {
10862 drflac_uint32 side = pInputSamples0U32[i] << shift0;
10863 drflac_uint32 right = pInputSamples1U32[i] << shift1;
10864 drflac_uint32 left = right + side;
10865
10866 pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
10867 pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
10868 }
10869 }
10870 #endif
10871
10872 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10873 {
10874 #if defined(DRFLAC_SUPPORT_SSE2)
10875 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10876 drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10877 } else
10878 #elif defined(DRFLAC_SUPPORT_NEON)
10879 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10880 drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10881 } else
10882 #endif
10883 {
10884 /* Scalar fallback. */
10885 #if 0
10886 drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10887 #else
10888 drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10889 #endif
10890 }
10891 }
10892
10893
10894 #if 0
10895 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10896 {
10897 for (drflac_uint64 i = 0; i < frameCount; ++i) {
10898 drflac_uint32 mid = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10899 drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10900
10901 mid = (mid << 1) | (side & 0x01);
10902
10903 pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
10904 pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
10905 }
10906 }
10907 #endif
10908
10909 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10910 {
10911 drflac_uint64 i;
10912 drflac_uint64 frameCount4 = frameCount >> 2;
10913 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10914 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10915 drflac_uint32 shift = unusedBitsPerSample;
10916 float factor = 1 / 2147483648.0;
10917
10918 if (shift > 0) {
10919 shift -= 1;
10920 for (i = 0; i < frameCount4; ++i) {
10921 drflac_uint32 temp0L;
10922 drflac_uint32 temp1L;
10923 drflac_uint32 temp2L;
10924 drflac_uint32 temp3L;
10925 drflac_uint32 temp0R;
10926 drflac_uint32 temp1R;
10927 drflac_uint32 temp2R;
10928 drflac_uint32 temp3R;
10929
10930 drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10931 drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10932 drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10933 drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10934
10935 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10936 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10937 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10938 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10939
10940 mid0 = (mid0 << 1) | (side0 & 0x01);
10941 mid1 = (mid1 << 1) | (side1 & 0x01);
10942 mid2 = (mid2 << 1) | (side2 & 0x01);
10943 mid3 = (mid3 << 1) | (side3 & 0x01);
10944
10945 temp0L = (mid0 + side0) << shift;
10946 temp1L = (mid1 + side1) << shift;
10947 temp2L = (mid2 + side2) << shift;
10948 temp3L = (mid3 + side3) << shift;
10949
10950 temp0R = (mid0 - side0) << shift;
10951 temp1R = (mid1 - side1) << shift;
10952 temp2R = (mid2 - side2) << shift;
10953 temp3R = (mid3 - side3) << shift;
10954
10955 pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
10956 pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
10957 pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
10958 pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
10959 pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
10960 pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
10961 pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
10962 pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
10963 }
10964 } else {
10965 for (i = 0; i < frameCount4; ++i) {
10966 drflac_uint32 temp0L;
10967 drflac_uint32 temp1L;
10968 drflac_uint32 temp2L;
10969 drflac_uint32 temp3L;
10970 drflac_uint32 temp0R;
10971 drflac_uint32 temp1R;
10972 drflac_uint32 temp2R;
10973 drflac_uint32 temp3R;
10974
10975 drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10976 drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10977 drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10978 drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10979
10980 drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10981 drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10982 drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10983 drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10984
10985 mid0 = (mid0 << 1) | (side0 & 0x01);
10986 mid1 = (mid1 << 1) | (side1 & 0x01);
10987 mid2 = (mid2 << 1) | (side2 & 0x01);
10988 mid3 = (mid3 << 1) | (side3 & 0x01);
10989
10990 temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
10991 temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
10992 temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
10993 temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
10994
10995 temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
10996 temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);
10997 temp2R = (drflac_uint32)((drflac_int32)(mid2 - side2) >> 1);
10998 temp3R = (drflac_uint32)((drflac_int32)(mid3 - side3) >> 1);
10999
11000 pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
11001 pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
11002 pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
11003 pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
11004 pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
11005 pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
11006 pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
11007 pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
11008 }
11009 }
11010
11011 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11012 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11013 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11014
11015 mid = (mid << 1) | (side & 0x01);
11016
11017 pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
11018 pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
11019 }
11020 }
11021
11022 #if defined(DRFLAC_SUPPORT_SSE2)
11023 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11024 {
11025 drflac_uint64 i;
11026 drflac_uint64 frameCount4 = frameCount >> 2;
11027 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11028 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11029 drflac_uint32 shift = unusedBitsPerSample - 8;
11030 float factor;
11031 __m128 factor128;
11032
11033 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
11034
11035 factor = 1.0f / 8388608.0f;
11036 factor128 = _mm_set1_ps(factor);
11037
11038 if (shift == 0) {
11039 for (i = 0; i < frameCount4; ++i) {
11040 __m128i mid;
11041 __m128i side;
11042 __m128i tempL;
11043 __m128i tempR;
11044 __m128 leftf;
11045 __m128 rightf;
11046
11047 mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
11048 side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
11049
11050 mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
11051
11052 tempL = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
11053 tempR = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
11054
11055 leftf = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
11056 rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
11057
11058 _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
11059 _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
11060 }
11061
11062 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11063 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11064 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11065
11066 mid = (mid << 1) | (side & 0x01);
11067
11068 pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
11069 pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
11070 }
11071 } else {
11072 shift -= 1;
11073 for (i = 0; i < frameCount4; ++i) {
11074 __m128i mid;
11075 __m128i side;
11076 __m128i tempL;
11077 __m128i tempR;
11078 __m128 leftf;
11079 __m128 rightf;
11080
11081 mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
11082 side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
11083
11084 mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
11085
11086 tempL = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
11087 tempR = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
11088
11089 leftf = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
11090 rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
11091
11092 _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
11093 _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
11094 }
11095
11096 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11097 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11098 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11099
11100 mid = (mid << 1) | (side & 0x01);
11101
11102 pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
11103 pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
11104 }
11105 }
11106 }
11107 #endif
11108
11109 #if defined(DRFLAC_SUPPORT_NEON)
11110 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11111 {
11112 drflac_uint64 i;
11113 drflac_uint64 frameCount4 = frameCount >> 2;
11114 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11115 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11116 drflac_uint32 shift = unusedBitsPerSample - 8;
11117 float factor;
11118 float32x4_t factor4;
11119 int32x4_t shift4;
11120 int32x4_t wbps0_4; /* Wasted Bits Per Sample */
11121 int32x4_t wbps1_4; /* Wasted Bits Per Sample */
11122
11123 DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
11124
11125 factor = 1.0f / 8388608.0f;
11126 factor4 = vdupq_n_f32(factor);
11127 wbps0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
11128 wbps1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
11129
11130 if (shift == 0) {
11131 for (i = 0; i < frameCount4; ++i) {
11132 int32x4_t lefti;
11133 int32x4_t righti;
11134 float32x4_t leftf;
11135 float32x4_t rightf;
11136
11137 uint32x4_t mid = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
11138 uint32x4_t side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
11139
11140 mid = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
11141
11142 lefti = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
11143 righti = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
11144
11145 leftf = vmulq_f32(vcvtq_f32_s32(lefti), factor4);
11146 rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
11147
11148 drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11149 }
11150
11151 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11152 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11153 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11154
11155 mid = (mid << 1) | (side & 0x01);
11156
11157 pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
11158 pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
11159 }
11160 } else {
11161 shift -= 1;
11162 shift4 = vdupq_n_s32(shift);
11163 for (i = 0; i < frameCount4; ++i) {
11164 uint32x4_t mid;
11165 uint32x4_t side;
11166 int32x4_t lefti;
11167 int32x4_t righti;
11168 float32x4_t leftf;
11169 float32x4_t rightf;
11170
11171 mid = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
11172 side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
11173
11174 mid = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
11175
11176 lefti = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
11177 righti = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
11178
11179 leftf = vmulq_f32(vcvtq_f32_s32(lefti), factor4);
11180 rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
11181
11182 drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11183 }
11184
11185 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11186 drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11187 drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11188
11189 mid = (mid << 1) | (side & 0x01);
11190
11191 pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
11192 pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
11193 }
11194 }
11195 }
11196 #endif
11197
11198 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11199 {
11200 #if defined(DRFLAC_SUPPORT_SSE2)
11201 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
11202 drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11203 } else
11204 #elif defined(DRFLAC_SUPPORT_NEON)
11205 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
11206 drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11207 } else
11208 #endif
11209 {
11210 /* Scalar fallback. */
11211 #if 0
11212 drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11213 #else
11214 drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11215 #endif
11216 }
11217 }
11218
11219 #if 0
11220 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11221 {
11222 for (drflac_uint64 i = 0; i < frameCount; ++i) {
11223 pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
11224 pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
11225 }
11226 }
11227 #endif
11228
11229 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11230 {
11231 drflac_uint64 i;
11232 drflac_uint64 frameCount4 = frameCount >> 2;
11233 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11234 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11235 drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11236 drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11237 float factor = 1 / 2147483648.0;
11238
11239 for (i = 0; i < frameCount4; ++i) {
11240 drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
11241 drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
11242 drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
11243 drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
11244
11245 drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
11246 drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
11247 drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
11248 drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
11249
11250 pOutputSamples[i*8+0] = (drflac_int32)tempL0 * factor;
11251 pOutputSamples[i*8+1] = (drflac_int32)tempR0 * factor;
11252 pOutputSamples[i*8+2] = (drflac_int32)tempL1 * factor;
11253 pOutputSamples[i*8+3] = (drflac_int32)tempR1 * factor;
11254 pOutputSamples[i*8+4] = (drflac_int32)tempL2 * factor;
11255 pOutputSamples[i*8+5] = (drflac_int32)tempR2 * factor;
11256 pOutputSamples[i*8+6] = (drflac_int32)tempL3 * factor;
11257 pOutputSamples[i*8+7] = (drflac_int32)tempR3 * factor;
11258 }
11259
11260 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11261 pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
11262 pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
11263 }
11264 }
11265
11266 #if defined(DRFLAC_SUPPORT_SSE2)
11267 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11268 {
11269 drflac_uint64 i;
11270 drflac_uint64 frameCount4 = frameCount >> 2;
11271 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11272 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11273 drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
11274 drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
11275
11276 float factor = 1.0f / 8388608.0f;
11277 __m128 factor128 = _mm_set1_ps(factor);
11278
11279 for (i = 0; i < frameCount4; ++i) {
11280 __m128i lefti;
11281 __m128i righti;
11282 __m128 leftf;
11283 __m128 rightf;
11284
11285 lefti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
11286 righti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
11287
11288 leftf = _mm_mul_ps(_mm_cvtepi32_ps(lefti), factor128);
11289 rightf = _mm_mul_ps(_mm_cvtepi32_ps(righti), factor128);
11290
11291 _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
11292 _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
11293 }
11294
11295 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11296 pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
11297 pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
11298 }
11299 }
11300 #endif
11301
11302 #if defined(DRFLAC_SUPPORT_NEON)
11303 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11304 {
11305 drflac_uint64 i;
11306 drflac_uint64 frameCount4 = frameCount >> 2;
11307 const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11308 const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11309 drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
11310 drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
11311
11312 float factor = 1.0f / 8388608.0f;
11313 float32x4_t factor4 = vdupq_n_f32(factor);
11314 int32x4_t shift0_4 = vdupq_n_s32(shift0);
11315 int32x4_t shift1_4 = vdupq_n_s32(shift1);
11316
11317 for (i = 0; i < frameCount4; ++i) {
11318 int32x4_t lefti;
11319 int32x4_t righti;
11320 float32x4_t leftf;
11321 float32x4_t rightf;
11322
11323 lefti = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
11324 righti = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
11325
11326 leftf = vmulq_f32(vcvtq_f32_s32(lefti), factor4);
11327 rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
11328
11329 drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11330 }
11331
11332 for (i = (frameCount4 << 2); i < frameCount; ++i) {
11333 pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
11334 pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
11335 }
11336 }
11337 #endif
11338
11339 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11340 {
11341 #if defined(DRFLAC_SUPPORT_SSE2)
11342 if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
11343 drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11344 } else
11345 #elif defined(DRFLAC_SUPPORT_NEON)
11346 if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
11347 drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11348 } else
11349 #endif
11350 {
11351 /* Scalar fallback. */
11352 #if 0
11353 drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11354 #else
11355 drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11356 #endif
11357 }
11358 }
11359
11360 DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut)
11361 {
11362 drflac_uint64 framesRead;
11363 drflac_uint32 unusedBitsPerSample;
11364
11365 if (pFlac == NULL || framesToRead == 0) {
11366 return 0;
11367 }
11368
11369 if (pBufferOut == NULL) {
11370 return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
11371 }
11372
11373 DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
11374 unusedBitsPerSample = 32 - pFlac->bitsPerSample;
11375
11376 framesRead = 0;
11377 while (framesToRead > 0) {
11378 /* If we've run out of samples in this frame, go to the next. */
11379 if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
11380 if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
11381 break; /* Couldn't read the next frame, so just break from the loop and return. */
11382 }
11383 } else {
11384 unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
11385 drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
11386 drflac_uint64 frameCountThisIteration = framesToRead;
11387
11388 if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
11389 frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
11390 }
11391
11392 if (channelCount == 2) {
11393 const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
11394 const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
11395
11396 switch (pFlac->currentFLACFrame.header.channelAssignment)
11397 {
11398 case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
11399 {
11400 drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11401 } break;
11402
11403 case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
11404 {
11405 drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11406 } break;
11407
11408 case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
11409 {
11410 drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11411 } break;
11412
11413 case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
11414 default:
11415 {
11416 drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11417 } break;
11418 }
11419 } else {
11420 /* Generic interleaving. */
11421 drflac_uint64 i;
11422 for (i = 0; i < frameCountThisIteration; ++i) {
11423 unsigned int j;
11424 for (j = 0; j < channelCount; ++j) {
11425 drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
11426 pBufferOut[(i*channelCount)+j] = (float)(sampleS32 / 2147483648.0);
11427 }
11428 }
11429 }
11430
11431 framesRead += frameCountThisIteration;
11432 pBufferOut += frameCountThisIteration * channelCount;
11433 framesToRead -= frameCountThisIteration;
11434 pFlac->currentPCMFrame += frameCountThisIteration;
11435 pFlac->currentFLACFrame.pcmFramesRemaining -= (unsigned int)frameCountThisIteration;
11436 }
11437 }
11438
11439 return framesRead;
11440 }
11441
11442
11443 DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
11444 {
11445 if (pFlac == NULL) {
11446 return DRFLAC_FALSE;
11447 }
11448
11449 /* Don't do anything if we're already on the seek point. */
11450 if (pFlac->currentPCMFrame == pcmFrameIndex) {
11451 return DRFLAC_TRUE;
11452 }
11453
11454 /*
11455 If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present
11456 when the decoder was opened.
11457 */
11458 if (pFlac->firstFLACFramePosInBytes == 0) {
11459 return DRFLAC_FALSE;
11460 }
11461
11462 if (pcmFrameIndex == 0) {
11463 pFlac->currentPCMFrame = 0;
11464 return drflac__seek_to_first_frame(pFlac);
11465 } else {
11466 drflac_bool32 wasSuccessful = DRFLAC_FALSE;
11467 drflac_uint64 originalPCMFrame = pFlac->currentPCMFrame;
11468
11469 /* Clamp the sample to the end. */
11470 if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
11471 pcmFrameIndex = pFlac->totalPCMFrameCount;
11472 }
11473
11474 /* If the target sample and the current sample are in the same frame we just move the position forward. */
11475 if (pcmFrameIndex > pFlac->currentPCMFrame) {
11476 /* Forward. */
11477 drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex - pFlac->currentPCMFrame);
11478 if (pFlac->currentFLACFrame.pcmFramesRemaining > offset) {
11479 pFlac->currentFLACFrame.pcmFramesRemaining -= offset;
11480 pFlac->currentPCMFrame = pcmFrameIndex;
11481 return DRFLAC_TRUE;
11482 }
11483 } else {
11484 /* Backward. */
11485 drflac_uint32 offsetAbs = (drflac_uint32)(pFlac->currentPCMFrame - pcmFrameIndex);
11486 drflac_uint32 currentFLACFramePCMFrameCount = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
11487 drflac_uint32 currentFLACFramePCMFramesConsumed = currentFLACFramePCMFrameCount - pFlac->currentFLACFrame.pcmFramesRemaining;
11488 if (currentFLACFramePCMFramesConsumed > offsetAbs) {
11489 pFlac->currentFLACFrame.pcmFramesRemaining += offsetAbs;
11490 pFlac->currentPCMFrame = pcmFrameIndex;
11491 return DRFLAC_TRUE;
11492 }
11493 }
11494
11495 /*
11496 Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so
11497 we'll instead use Ogg's natural seeking facility.
11498 */
11499 #ifndef DR_FLAC_NO_OGG
11500 if (pFlac->container == drflac_container_ogg)
11501 {
11502 wasSuccessful = drflac_ogg__seek_to_pcm_frame(pFlac, pcmFrameIndex);
11503 }
11504 else
11505 #endif
11506 {
11507 /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */
11508 if (/*!wasSuccessful && */!pFlac->_noSeekTableSeek) {
11509 wasSuccessful = drflac__seek_to_pcm_frame__seek_table(pFlac, pcmFrameIndex);
11510 }
11511
11512 #if !defined(DR_FLAC_NO_CRC)
11513 /* Fall back to binary search if seek table seeking fails. This requires the length of the stream to be known. */
11514 if (!wasSuccessful && !pFlac->_noBinarySearchSeek && pFlac->totalPCMFrameCount > 0) {
11515 wasSuccessful = drflac__seek_to_pcm_frame__binary_search(pFlac, pcmFrameIndex);
11516 }
11517 #endif
11518
11519 /* Fall back to brute force if all else fails. */
11520 if (!wasSuccessful && !pFlac->_noBruteForceSeek) {
11521 wasSuccessful = drflac__seek_to_pcm_frame__brute_force(pFlac, pcmFrameIndex);
11522 }
11523 }
11524
11525 if (wasSuccessful) {
11526 pFlac->currentPCMFrame = pcmFrameIndex;
11527 } else {
11528 /* Seek failed. Try putting the decoder back to it's original state. */
11529 if (drflac_seek_to_pcm_frame(pFlac, originalPCMFrame) == DRFLAC_FALSE) {
11530 /* Failed to seek back to the original PCM frame. Fall back to 0. */
11531 drflac_seek_to_pcm_frame(pFlac, 0);
11532 }
11533 }
11534
11535 return wasSuccessful;
11536 }
11537 }
11538
11539
11540
11541 /* High Level APIs */
11542
11543 #if defined(SIZE_MAX)
11544 #define DRFLAC_SIZE_MAX SIZE_MAX
11545 #else
11546 #if defined(DRFLAC_64BIT)
11547 #define DRFLAC_SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF)
11548 #else
11549 #define DRFLAC_SIZE_MAX 0xFFFFFFFF
11550 #endif
11551 #endif
11552
11553
11554 /* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */
11555 #define DRFLAC_DEFINE_FULL_READ_AND_CLOSE(extension, type) \
11556 static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut)\
11557 { \
11558 type* pSampleData = NULL; \
11559 drflac_uint64 totalPCMFrameCount; \
11560 \
11561 DRFLAC_ASSERT(pFlac != NULL); \
11562 \
11563 totalPCMFrameCount = pFlac->totalPCMFrameCount; \
11564 \
11565 if (totalPCMFrameCount == 0) { \
11566 type buffer[4096]; \
11567 drflac_uint64 pcmFramesRead; \
11568 size_t sampleDataBufferSize = sizeof(buffer); \
11569 \
11570 pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \
11571 if (pSampleData == NULL) { \
11572 goto on_error; \
11573 } \
11574 \
11575 while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
11576 if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \
11577 type* pNewSampleData; \
11578 size_t newSampleDataBufferSize; \
11579 \
11580 newSampleDataBufferSize = sampleDataBufferSize * 2; \
11581 pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
11582 if (pNewSampleData == NULL) { \
11583 drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \
11584 goto on_error; \
11585 } \
11586 \
11587 sampleDataBufferSize = newSampleDataBufferSize; \
11588 pSampleData = pNewSampleData; \
11589 } \
11590 \
11591 DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
11592 totalPCMFrameCount += pcmFramesRead; \
11593 } \
11594 \
11595 /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
11596 protect those ears from random noise! */ \
11597 DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
11598 } else { \
11599 drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \
11600 if (dataSize > (drflac_uint64)DRFLAC_SIZE_MAX) { \
11601 goto on_error; /* The decoded data is too big. */ \
11602 } \
11603 \
11604 pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks); /* <-- Safe cast as per the check above. */ \
11605 if (pSampleData == NULL) { \
11606 goto on_error; \
11607 } \
11608 \
11609 totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData); \
11610 } \
11611 \
11612 if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \
11613 if (channelsOut) *channelsOut = pFlac->channels; \
11614 if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount; \
11615 \
11616 drflac_close(pFlac); \
11617 return pSampleData; \
11618 \
11619 on_error: \
11620 drflac_close(pFlac); \
11621 return NULL; \
11622 }
11623
11624 DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
11625 DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
11626 DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
11627
11628 DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
11629 {
11630 drflac* pFlac;
11631
11632 if (channelsOut) {
11633 *channelsOut = 0;
11634 }
11635 if (sampleRateOut) {
11636 *sampleRateOut = 0;
11637 }
11638 if (totalPCMFrameCountOut) {
11639 *totalPCMFrameCountOut = 0;
11640 }
11641
11642 pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
11643 if (pFlac == NULL) {
11644 return NULL;
11645 }
11646
11647 return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
11648 }
11649
11650 DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
11651 {
11652 drflac* pFlac;
11653
11654 if (channelsOut) {
11655 *channelsOut = 0;
11656 }
11657 if (sampleRateOut) {
11658 *sampleRateOut = 0;
11659 }
11660 if (totalPCMFrameCountOut) {
11661 *totalPCMFrameCountOut = 0;
11662 }
11663
11664 pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
11665 if (pFlac == NULL) {
11666 return NULL;
11667 }
11668
11669 return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
11670 }
11671
11672 DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
11673 {
11674 drflac* pFlac;
11675
11676 if (channelsOut) {
11677 *channelsOut = 0;
11678 }
11679 if (sampleRateOut) {
11680 *sampleRateOut = 0;
11681 }
11682 if (totalPCMFrameCountOut) {
11683 *totalPCMFrameCountOut = 0;
11684 }
11685
11686 pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
11687 if (pFlac == NULL) {
11688 return NULL;
11689 }
11690
11691 return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
11692 }
11693
11694 #ifndef DR_FLAC_NO_STDIO
11695 DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
11696 {
11697 drflac* pFlac;
11698
11699 if (sampleRate) {
11700 *sampleRate = 0;
11701 }
11702 if (channels) {
11703 *channels = 0;
11704 }
11705 if (totalPCMFrameCount) {
11706 *totalPCMFrameCount = 0;
11707 }
11708
11709 pFlac = drflac_open_file(filename, pAllocationCallbacks);
11710 if (pFlac == NULL) {
11711 return NULL;
11712 }
11713
11714 return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
11715 }
11716
11717 DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
11718 {
11719 drflac* pFlac;
11720
11721 if (sampleRate) {
11722 *sampleRate = 0;
11723 }
11724 if (channels) {
11725 *channels = 0;
11726 }
11727 if (totalPCMFrameCount) {
11728 *totalPCMFrameCount = 0;
11729 }
11730
11731 pFlac = drflac_open_file(filename, pAllocationCallbacks);
11732 if (pFlac == NULL) {
11733 return NULL;
11734 }
11735
11736 return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
11737 }
11738
11739 DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
11740 {
11741 drflac* pFlac;
11742
11743 if (sampleRate) {
11744 *sampleRate = 0;
11745 }
11746 if (channels) {
11747 *channels = 0;
11748 }
11749 if (totalPCMFrameCount) {
11750 *totalPCMFrameCount = 0;
11751 }
11752
11753 pFlac = drflac_open_file(filename, pAllocationCallbacks);
11754 if (pFlac == NULL) {
11755 return NULL;
11756 }
11757
11758 return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
11759 }
11760 #endif
11761
11762 DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
11763 {
11764 drflac* pFlac;
11765
11766 if (sampleRate) {
11767 *sampleRate = 0;
11768 }
11769 if (channels) {
11770 *channels = 0;
11771 }
11772 if (totalPCMFrameCount) {
11773 *totalPCMFrameCount = 0;
11774 }
11775
11776 pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
11777 if (pFlac == NULL) {
11778 return NULL;
11779 }
11780
11781 return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
11782 }
11783
11784 DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
11785 {
11786 drflac* pFlac;
11787
11788 if (sampleRate) {
11789 *sampleRate = 0;
11790 }
11791 if (channels) {
11792 *channels = 0;
11793 }
11794 if (totalPCMFrameCount) {
11795 *totalPCMFrameCount = 0;
11796 }
11797
11798 pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
11799 if (pFlac == NULL) {
11800 return NULL;
11801 }
11802
11803 return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
11804 }
11805
11806 DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
11807 {
11808 drflac* pFlac;
11809
11810 if (sampleRate) {
11811 *sampleRate = 0;
11812 }
11813 if (channels) {
11814 *channels = 0;
11815 }
11816 if (totalPCMFrameCount) {
11817 *totalPCMFrameCount = 0;
11818 }
11819
11820 pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
11821 if (pFlac == NULL) {
11822 return NULL;
11823 }
11824
11825 return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
11826 }
11827
11828
11829 DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks)
11830 {
11831 if (pAllocationCallbacks != NULL) {
11832 drflac__free_from_callbacks(p, pAllocationCallbacks);
11833 } else {
11834 drflac__free_default(p, NULL);
11835 }
11836 }
11837
11838
11839
11840
11841 DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments)
11842 {
11843 if (pIter == NULL) {
11844 return;
11845 }
11846
11847 pIter->countRemaining = commentCount;
11848 pIter->pRunningData = (const char*)pComments;
11849 }
11850
11851 DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut)
11852 {
11853 drflac_int32 length;
11854 const char* pComment;
11855
11856 /* Safety. */
11857 if (pCommentLengthOut) {
11858 *pCommentLengthOut = 0;
11859 }
11860
11861 if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) {
11862 return NULL;
11863 }
11864
11865 length = drflac__le2host_32_ptr_unaligned(pIter->pRunningData);
11866 pIter->pRunningData += 4;
11867
11868 pComment = pIter->pRunningData;
11869 pIter->pRunningData += length;
11870 pIter->countRemaining -= 1;
11871
11872 if (pCommentLengthOut) {
11873 *pCommentLengthOut = length;
11874 }
11875
11876 return pComment;
11877 }
11878
11879
11880
11881
11882 DRFLAC_API void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData)
11883 {
11884 if (pIter == NULL) {
11885 return;
11886 }
11887
11888 pIter->countRemaining = trackCount;
11889 pIter->pRunningData = (const char*)pTrackData;
11890 }
11891
11892 DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack)
11893 {
11894 drflac_cuesheet_track cuesheetTrack;
11895 const char* pRunningData;
11896 drflac_uint64 offsetHi;
11897 drflac_uint64 offsetLo;
11898
11899 if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) {
11900 return DRFLAC_FALSE;
11901 }
11902
11903 pRunningData = pIter->pRunningData;
11904
11905 offsetHi = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
11906 offsetLo = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
11907 cuesheetTrack.offset = offsetLo | (offsetHi << 32);
11908 cuesheetTrack.trackNumber = pRunningData[0]; pRunningData += 1;
11909 DRFLAC_COPY_MEMORY(cuesheetTrack.ISRC, pRunningData, sizeof(cuesheetTrack.ISRC)); pRunningData += 12;
11910 cuesheetTrack.isAudio = (pRunningData[0] & 0x80) != 0;
11911 cuesheetTrack.preEmphasis = (pRunningData[0] & 0x40) != 0; pRunningData += 14;
11912 cuesheetTrack.indexCount = pRunningData[0]; pRunningData += 1;
11913 cuesheetTrack.pIndexPoints = (const drflac_cuesheet_track_index*)pRunningData; pRunningData += cuesheetTrack.indexCount * sizeof(drflac_cuesheet_track_index);
11914
11915 pIter->pRunningData = pRunningData;
11916 pIter->countRemaining -= 1;
11917
11918 if (pCuesheetTrack) {
11919 *pCuesheetTrack = cuesheetTrack;
11920 }
11921
11922 return DRFLAC_TRUE;
11923 }
11924
11925 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
11926 #pragma GCC diagnostic pop
11927 #endif
11928 #endif /* dr_flac_c */
11929 #endif /* DR_FLAC_IMPLEMENTATION */
11930
11931
11932 /*
11933 REVISION HISTORY
11934 ================
11935 v0.12.38 - 2022-04-10
11936 - Fix compilation error on older versions of GCC.
11937
11938 v0.12.37 - 2022-02-12
11939 - Improve ARM detection.
11940
11941 v0.12.36 - 2022-02-07
11942 - Fix a compilation error with the ARM build.
11943
11944 v0.12.35 - 2022-02-06
11945 - Fix a bug due to underestimating the amount of precision required for the prediction stage.
11946 - Fix some bugs found from fuzz testing.
11947
11948 v0.12.34 - 2022-01-07
11949 - Fix some misalignment bugs when reading metadata.
11950
11951 v0.12.33 - 2021-12-22
11952 - Fix a bug with seeking when the seek table does not start at PCM frame 0.
11953
11954 v0.12.32 - 2021-12-11
11955 - Fix a warning with Clang.
11956
11957 v0.12.31 - 2021-08-16
11958 - Silence some warnings.
11959
11960 v0.12.30 - 2021-07-31
11961 - Fix platform detection for ARM64.
11962
11963 v0.12.29 - 2021-04-02
11964 - Fix a bug where the running PCM frame index is set to an invalid value when over-seeking.
11965 - Fix a decoding error due to an incorrect validation check.
11966
11967 v0.12.28 - 2021-02-21
11968 - Fix a warning due to referencing _MSC_VER when it is undefined.
11969
11970 v0.12.27 - 2021-01-31
11971 - Fix a static analysis warning.
11972
11973 v0.12.26 - 2021-01-17
11974 - Fix a compilation warning due to _BSD_SOURCE being deprecated.
11975
11976 v0.12.25 - 2020-12-26
11977 - Update documentation.
11978
11979 v0.12.24 - 2020-11-29
11980 - Fix ARM64/NEON detection when compiling with MSVC.
11981
11982 v0.12.23 - 2020-11-21
11983 - Fix compilation with OpenWatcom.
11984
11985 v0.12.22 - 2020-11-01
11986 - Fix an error with the previous release.
11987
11988 v0.12.21 - 2020-11-01
11989 - Fix a possible deadlock when seeking.
11990 - Improve compiler support for older versions of GCC.
11991
11992 v0.12.20 - 2020-09-08
11993 - Fix a compilation error on older compilers.
11994
11995 v0.12.19 - 2020-08-30
11996 - Fix a bug due to an undefined 32-bit shift.
11997
11998 v0.12.18 - 2020-08-14
11999 - Fix a crash when compiling with clang-cl.
12000
12001 v0.12.17 - 2020-08-02
12002 - Simplify sized types.
12003
12004 v0.12.16 - 2020-07-25
12005 - Fix a compilation warning.
12006
12007 v0.12.15 - 2020-07-06
12008 - Check for negative LPC shifts and return an error.
12009
12010 v0.12.14 - 2020-06-23
12011 - Add include guard for the implementation section.
12012
12013 v0.12.13 - 2020-05-16
12014 - Add compile-time and run-time version querying.
12015 - DRFLAC_VERSION_MINOR
12016 - DRFLAC_VERSION_MAJOR
12017 - DRFLAC_VERSION_REVISION
12018 - DRFLAC_VERSION_STRING
12019 - drflac_version()
12020 - drflac_version_string()
12021
12022 v0.12.12 - 2020-04-30
12023 - Fix compilation errors with VC6.
12024
12025 v0.12.11 - 2020-04-19
12026 - Fix some pedantic warnings.
12027 - Fix some undefined behaviour warnings.
12028
12029 v0.12.10 - 2020-04-10
12030 - Fix some bugs when trying to seek with an invalid seek table.
12031
12032 v0.12.9 - 2020-04-05
12033 - Fix warnings.
12034
12035 v0.12.8 - 2020-04-04
12036 - Add drflac_open_file_w() and drflac_open_file_with_metadata_w().
12037 - Fix some static analysis warnings.
12038 - Minor documentation updates.
12039
12040 v0.12.7 - 2020-03-14
12041 - Fix compilation errors with VC6.
12042
12043 v0.12.6 - 2020-03-07
12044 - Fix compilation error with Visual Studio .NET 2003.
12045
12046 v0.12.5 - 2020-01-30
12047 - Silence some static analysis warnings.
12048
12049 v0.12.4 - 2020-01-29
12050 - Silence some static analysis warnings.
12051
12052 v0.12.3 - 2019-12-02
12053 - Fix some warnings when compiling with GCC and the -Og flag.
12054 - Fix a crash in out-of-memory situations.
12055 - Fix potential integer overflow bug.
12056 - Fix some static analysis warnings.
12057 - Fix a possible crash when using custom memory allocators without a custom realloc() implementation.
12058 - Fix a bug with binary search seeking where the bits per sample is not a multiple of 8.
12059
12060 v0.12.2 - 2019-10-07
12061 - Internal code clean up.
12062
12063 v0.12.1 - 2019-09-29
12064 - Fix some Clang Static Analyzer warnings.
12065 - Fix an unused variable warning.
12066
12067 v0.12.0 - 2019-09-23
12068 - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
12069 routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
12070 - drflac_open()
12071 - drflac_open_relaxed()
12072 - drflac_open_with_metadata()
12073 - drflac_open_with_metadata_relaxed()
12074 - drflac_open_file()
12075 - drflac_open_file_with_metadata()
12076 - drflac_open_memory()
12077 - drflac_open_memory_with_metadata()
12078 - drflac_open_and_read_pcm_frames_s32()
12079 - drflac_open_and_read_pcm_frames_s16()
12080 - drflac_open_and_read_pcm_frames_f32()
12081 - drflac_open_file_and_read_pcm_frames_s32()
12082 - drflac_open_file_and_read_pcm_frames_s16()
12083 - drflac_open_file_and_read_pcm_frames_f32()
12084 - drflac_open_memory_and_read_pcm_frames_s32()
12085 - drflac_open_memory_and_read_pcm_frames_s16()
12086 - drflac_open_memory_and_read_pcm_frames_f32()
12087 Set this extra parameter to NULL to use defaults which is the same as the previous behaviour. Setting this NULL will use
12088 DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
12089 - Remove deprecated APIs:
12090 - drflac_read_s32()
12091 - drflac_read_s16()
12092 - drflac_read_f32()
12093 - drflac_seek_to_sample()
12094 - drflac_open_and_decode_s32()
12095 - drflac_open_and_decode_s16()
12096 - drflac_open_and_decode_f32()
12097 - drflac_open_and_decode_file_s32()
12098 - drflac_open_and_decode_file_s16()
12099 - drflac_open_and_decode_file_f32()
12100 - drflac_open_and_decode_memory_s32()
12101 - drflac_open_and_decode_memory_s16()
12102 - drflac_open_and_decode_memory_f32()
12103 - Remove drflac.totalSampleCount which is now replaced with drflac.totalPCMFrameCount. You can emulate drflac.totalSampleCount
12104 by doing pFlac->totalPCMFrameCount*pFlac->channels.
12105 - Rename drflac.currentFrame to drflac.currentFLACFrame to remove ambiguity with PCM frames.
12106 - Fix errors when seeking to the end of a stream.
12107 - Optimizations to seeking.
12108 - SSE improvements and optimizations.
12109 - ARM NEON optimizations.
12110 - Optimizations to drflac_read_pcm_frames_s16().
12111 - Optimizations to drflac_read_pcm_frames_s32().
12112
12113 v0.11.10 - 2019-06-26
12114 - Fix a compiler error.
12115
12116 v0.11.9 - 2019-06-16
12117 - Silence some ThreadSanitizer warnings.
12118
12119 v0.11.8 - 2019-05-21
12120 - Fix warnings.
12121
12122 v0.11.7 - 2019-05-06
12123 - C89 fixes.
12124
12125 v0.11.6 - 2019-05-05
12126 - Add support for C89.
12127 - Fix a compiler warning when CRC is disabled.
12128 - Change license to choice of public domain or MIT-0.
12129
12130 v0.11.5 - 2019-04-19
12131 - Fix a compiler error with GCC.
12132
12133 v0.11.4 - 2019-04-17
12134 - Fix some warnings with GCC when compiling with -std=c99.
12135
12136 v0.11.3 - 2019-04-07
12137 - Silence warnings with GCC.
12138
12139 v0.11.2 - 2019-03-10
12140 - Fix a warning.
12141
12142 v0.11.1 - 2019-02-17
12143 - Fix a potential bug with seeking.
12144
12145 v0.11.0 - 2018-12-16
12146 - API CHANGE: Deprecated drflac_read_s32(), drflac_read_s16() and drflac_read_f32() and replaced them with
12147 drflac_read_pcm_frames_s32(), drflac_read_pcm_frames_s16() and drflac_read_pcm_frames_f32(). The new APIs take
12148 and return PCM frame counts instead of sample counts. To upgrade you will need to change the input count by
12149 dividing it by the channel count, and then do the same with the return value.
12150 - API_CHANGE: Deprecated drflac_seek_to_sample() and replaced with drflac_seek_to_pcm_frame(). Same rules as
12151 the changes to drflac_read_*() apply.
12152 - API CHANGE: Deprecated drflac_open_and_decode_*() and replaced with drflac_open_*_and_read_*(). Same rules as
12153 the changes to drflac_read_*() apply.
12154 - Optimizations.
12155
12156 v0.10.0 - 2018-09-11
12157 - Remove the DR_FLAC_NO_WIN32_IO option and the Win32 file IO functionality. If you need to use Win32 file IO you
12158 need to do it yourself via the callback API.
12159 - Fix the clang build.
12160 - Fix undefined behavior.
12161 - Fix errors with CUESHEET metdata blocks.
12162 - Add an API for iterating over each cuesheet track in the CUESHEET metadata block. This works the same way as the
12163 Vorbis comment API.
12164 - Other miscellaneous bug fixes, mostly relating to invalid FLAC streams.
12165 - Minor optimizations.
12166
12167 v0.9.11 - 2018-08-29
12168 - Fix a bug with sample reconstruction.
12169
12170 v0.9.10 - 2018-08-07
12171 - Improve 64-bit detection.
12172
12173 v0.9.9 - 2018-08-05
12174 - Fix C++ build on older versions of GCC.
12175
12176 v0.9.8 - 2018-07-24
12177 - Fix compilation errors.
12178
12179 v0.9.7 - 2018-07-05
12180 - Fix a warning.
12181
12182 v0.9.6 - 2018-06-29
12183 - Fix some typos.
12184
12185 v0.9.5 - 2018-06-23
12186 - Fix some warnings.
12187
12188 v0.9.4 - 2018-06-14
12189 - Optimizations to seeking.
12190 - Clean up.
12191
12192 v0.9.3 - 2018-05-22
12193 - Bug fix.
12194
12195 v0.9.2 - 2018-05-12
12196 - Fix a compilation error due to a missing break statement.
12197
12198 v0.9.1 - 2018-04-29
12199 - Fix compilation error with Clang.
12200
12201 v0.9 - 2018-04-24
12202 - Fix Clang build.
12203 - Start using major.minor.revision versioning.
12204
12205 v0.8g - 2018-04-19
12206 - Fix build on non-x86/x64 architectures.
12207
12208 v0.8f - 2018-02-02
12209 - Stop pretending to support changing rate/channels mid stream.
12210
12211 v0.8e - 2018-02-01
12212 - Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream.
12213 - Fix a crash the the Rice partition order is invalid.
12214
12215 v0.8d - 2017-09-22
12216 - Add support for decoding streams with ID3 tags. ID3 tags are just skipped.
12217
12218 v0.8c - 2017-09-07
12219 - Fix warning on non-x86/x64 architectures.
12220
12221 v0.8b - 2017-08-19
12222 - Fix build on non-x86/x64 architectures.
12223
12224 v0.8a - 2017-08-13
12225 - A small optimization for the Clang build.
12226
12227 v0.8 - 2017-08-12
12228 - API CHANGE: Rename dr_* types to drflac_*.
12229 - Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation.
12230 - Add support for custom implementations of malloc(), realloc(), etc.
12231 - Add CRC checking to Ogg encapsulated streams.
12232 - Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported.
12233 - Bug fixes.
12234
12235 v0.7 - 2017-07-23
12236 - Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed().
12237
12238 v0.6 - 2017-07-22
12239 - Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they
12240 never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame.
12241
12242 v0.5 - 2017-07-16
12243 - Fix typos.
12244 - Change drflac_bool* types to unsigned.
12245 - Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC.
12246
12247 v0.4f - 2017-03-10
12248 - Fix a couple of bugs with the bitstreaming code.
12249
12250 v0.4e - 2017-02-17
12251 - Fix some warnings.
12252
12253 v0.4d - 2016-12-26
12254 - Add support for 32-bit floating-point PCM decoding.
12255 - Use drflac_int* and drflac_uint* sized types to improve compiler support.
12256 - Minor improvements to documentation.
12257
12258 v0.4c - 2016-12-26
12259 - Add support for signed 16-bit integer PCM decoding.
12260
12261 v0.4b - 2016-10-23
12262 - A minor change to drflac_bool8 and drflac_bool32 types.
12263
12264 v0.4a - 2016-10-11
12265 - Rename drBool32 to drflac_bool32 for styling consistency.
12266
12267 v0.4 - 2016-09-29
12268 - API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type.
12269 - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32().
12270 - API CHANGE: Swap the order of "channels" and "sampleRate" parameters in drflac_open_and_decode*(). Rationale for this is to
12271 keep it consistent with drflac_audio.
12272
12273 v0.3f - 2016-09-21
12274 - Fix a warning with GCC.
12275
12276 v0.3e - 2016-09-18
12277 - Fixed a bug where GCC 4.3+ was not getting properly identified.
12278 - Fixed a few typos.
12279 - Changed date formats to ISO 8601 (YYYY-MM-DD).
12280
12281 v0.3d - 2016-06-11
12282 - Minor clean up.
12283
12284 v0.3c - 2016-05-28
12285 - Fixed compilation error.
12286
12287 v0.3b - 2016-05-16
12288 - Fixed Linux/GCC build.
12289 - Updated documentation.
12290
12291 v0.3a - 2016-05-15
12292 - Minor fixes to documentation.
12293
12294 v0.3 - 2016-05-11
12295 - Optimizations. Now at about parity with the reference implementation on 32-bit builds.
12296 - Lots of clean up.
12297
12298 v0.2b - 2016-05-10
12299 - Bug fixes.
12300
12301 v0.2a - 2016-05-10
12302 - Made drflac_open_and_decode() more robust.
12303 - Removed an unused debugging variable
12304
12305 v0.2 - 2016-05-09
12306 - Added support for Ogg encapsulation.
12307 - API CHANGE. Have the onSeek callback take a third argument which specifies whether or not the seek
12308 should be relative to the start or the current position. Also changes the seeking rules such that
12309 seeking offsets will never be negative.
12310 - Have drflac_open_and_decode() fail gracefully if the stream has an unknown total sample count.
12311
12312 v0.1b - 2016-05-07
12313 - Properly close the file handle in drflac_open_file() and family when the decoder fails to initialize.
12314 - Removed a stale comment.
12315
12316 v0.1a - 2016-05-05
12317 - Minor formatting changes.
12318 - Fixed a warning on the GCC build.
12319
12320 v0.1 - 2016-05-03
12321 - Initial versioned release.
12322 */
12323
12324 /*
12325 This software is available as a choice of the following licenses. Choose
12326 whichever you prefer.
12327
12328 ===============================================================================
12329 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
12330 ===============================================================================
12331 This is free and unencumbered software released into the public domain.
12332
12333 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
12334 software, either in source code form or as a compiled binary, for any purpose,
12335 commercial or non-commercial, and by any means.
12336
12337 In jurisdictions that recognize copyright laws, the author or authors of this
12338 software dedicate any and all copyright interest in the software to the public
12339 domain. We make this dedication for the benefit of the public at large and to
12340 the detriment of our heirs and successors. We intend this dedication to be an
12341 overt act of relinquishment in perpetuity of all present and future rights to
12342 this software under copyright law.
12343
12344 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12345 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12346 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12347 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
12348 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
12349 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12350
12351 For more information, please refer to <http://unlicense.org/>
12352
12353 ===============================================================================
12354 ALTERNATIVE 2 - MIT No Attribution
12355 ===============================================================================
12356 Copyright 2020 David Reid
12357
12358 Permission is hereby granted, free of charge, to any person obtaining a copy of
12359 this software and associated documentation files (the "Software"), to deal in
12360 the Software without restriction, including without limitation the rights to
12361 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12362 of the Software, and to permit persons to whom the Software is furnished to do
12363 so.
12364
12365 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12366 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12367 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12368 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12369 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12370 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
12371 SOFTWARE.
12372 */
0 /*
1 MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
2 dr_mp3 - v0.6.33 - 2022-04-10
3
4 David Reid - mackron@gmail.com
5
6 GitHub: https://github.com/mackron/dr_libs
7
8 Based on minimp3 (https://github.com/lieff/minimp3) which is where the real work was done. See the bottom of this file for differences between minimp3 and dr_mp3.
9 */
10
11 /*
12 RELEASE NOTES - VERSION 0.6
13 ===========================
14 Version 0.6 includes breaking changes with the configuration of decoders. The ability to customize the number of output channels and the sample rate has been
15 removed. You must now use the channel count and sample rate reported by the MP3 stream itself, and all channel and sample rate conversion must be done
16 yourself.
17
18
19 Changes to Initialization
20 -------------------------
21 Previously, `drmp3_init()`, etc. took a pointer to a `drmp3_config` object that allowed you to customize the output channels and sample rate. This has been
22 removed. If you need the old behaviour you will need to convert the data yourself or just not upgrade. The following APIs have changed.
23
24 `drmp3_init()`
25 `drmp3_init_memory()`
26 `drmp3_init_file()`
27
28
29 Miscellaneous Changes
30 ---------------------
31 Support for loading a file from a `wchar_t` string has been added via the `drmp3_init_file_w()` API.
32 */
33
34 /*
35 Introducation
36 =============
37 dr_mp3 is a single file library. To use it, do something like the following in one .c file.
38
39 ```c
40 #define DR_MP3_IMPLEMENTATION
41 #include "dr_mp3.h"
42 ```
43
44 You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following:
45
46 ```c
47 drmp3 mp3;
48 if (!drmp3_init_file(&mp3, "MySong.mp3", NULL)) {
49 // Failed to open file
50 }
51
52 ...
53
54 drmp3_uint64 framesRead = drmp3_read_pcm_frames_f32(pMP3, framesToRead, pFrames);
55 ```
56
57 The drmp3 object is transparent so you can get access to the channel count and sample rate like so:
58
59 ```
60 drmp3_uint32 channels = mp3.channels;
61 drmp3_uint32 sampleRate = mp3.sampleRate;
62 ```
63
64 The example above initializes a decoder from a file, but you can also initialize it from a block of memory and read and seek callbacks with
65 `drmp3_init_memory()` and `drmp3_init()` respectively.
66
67 You do not need to do any annoying memory management when reading PCM frames - this is all managed internally. You can request any number of PCM frames in each
68 call to `drmp3_read_pcm_frames_f32()` and it will return as many PCM frames as it can, up to the requested amount.
69
70 You can also decode an entire file in one go with `drmp3_open_and_read_pcm_frames_f32()`, `drmp3_open_memory_and_read_pcm_frames_f32()` and
71 `drmp3_open_file_and_read_pcm_frames_f32()`.
72
73
74 Build Options
75 =============
76 #define these options before including this file.
77
78 #define DR_MP3_NO_STDIO
79 Disable drmp3_init_file(), etc.
80
81 #define DR_MP3_NO_SIMD
82 Disable SIMD optimizations.
83 */
84
85 #ifndef dr_mp3_h
86 #define dr_mp3_h
87
88 #ifdef __cplusplus
89 extern "C" {
90 #endif
91
92 #define DRMP3_STRINGIFY(x) #x
93 #define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x)
94
95 #define DRMP3_VERSION_MAJOR 0
96 #define DRMP3_VERSION_MINOR 6
97 #define DRMP3_VERSION_REVISION 33
98 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
99
100 #include <stddef.h> /* For size_t. */
101
102 /* Sized types. */
103 typedef signed char drmp3_int8;
104 typedef unsigned char drmp3_uint8;
105 typedef signed short drmp3_int16;
106 typedef unsigned short drmp3_uint16;
107 typedef signed int drmp3_int32;
108 typedef unsigned int drmp3_uint32;
109 #if defined(_MSC_VER) && !defined(__clang__)
110 typedef signed __int64 drmp3_int64;
111 typedef unsigned __int64 drmp3_uint64;
112 #else
113 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
114 #pragma GCC diagnostic push
115 #pragma GCC diagnostic ignored "-Wlong-long"
116 #if defined(__clang__)
117 #pragma GCC diagnostic ignored "-Wc++11-long-long"
118 #endif
119 #endif
120 typedef signed long long drmp3_int64;
121 typedef unsigned long long drmp3_uint64;
122 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
123 #pragma GCC diagnostic pop
124 #endif
125 #endif
126 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
127 typedef drmp3_uint64 drmp3_uintptr;
128 #else
129 typedef drmp3_uint32 drmp3_uintptr;
130 #endif
131 typedef drmp3_uint8 drmp3_bool8;
132 typedef drmp3_uint32 drmp3_bool32;
133 #define DRMP3_TRUE 1
134 #define DRMP3_FALSE 0
135
136 #if !defined(DRMP3_API)
137 #if defined(DRMP3_DLL)
138 #if defined(_WIN32)
139 #define DRMP3_DLL_IMPORT __declspec(dllimport)
140 #define DRMP3_DLL_EXPORT __declspec(dllexport)
141 #define DRMP3_DLL_PRIVATE static
142 #else
143 #if defined(__GNUC__) && __GNUC__ >= 4
144 #define DRMP3_DLL_IMPORT __attribute__((visibility("default")))
145 #define DRMP3_DLL_EXPORT __attribute__((visibility("default")))
146 #define DRMP3_DLL_PRIVATE __attribute__((visibility("hidden")))
147 #else
148 #define DRMP3_DLL_IMPORT
149 #define DRMP3_DLL_EXPORT
150 #define DRMP3_DLL_PRIVATE static
151 #endif
152 #endif
153
154 #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION)
155 #define DRMP3_API DRMP3_DLL_EXPORT
156 #else
157 #define DRMP3_API DRMP3_DLL_IMPORT
158 #endif
159 #define DRMP3_PRIVATE DRMP3_DLL_PRIVATE
160 #else
161 #define DRMP3_API extern
162 #define DRMP3_PRIVATE static
163 #endif
164 #endif
165
166 typedef drmp3_int32 drmp3_result;
167 #define DRMP3_SUCCESS 0
168 #define DRMP3_ERROR -1 /* A generic error. */
169 #define DRMP3_INVALID_ARGS -2
170 #define DRMP3_INVALID_OPERATION -3
171 #define DRMP3_OUT_OF_MEMORY -4
172 #define DRMP3_OUT_OF_RANGE -5
173 #define DRMP3_ACCESS_DENIED -6
174 #define DRMP3_DOES_NOT_EXIST -7
175 #define DRMP3_ALREADY_EXISTS -8
176 #define DRMP3_TOO_MANY_OPEN_FILES -9
177 #define DRMP3_INVALID_FILE -10
178 #define DRMP3_TOO_BIG -11
179 #define DRMP3_PATH_TOO_LONG -12
180 #define DRMP3_NAME_TOO_LONG -13
181 #define DRMP3_NOT_DIRECTORY -14
182 #define DRMP3_IS_DIRECTORY -15
183 #define DRMP3_DIRECTORY_NOT_EMPTY -16
184 #define DRMP3_END_OF_FILE -17
185 #define DRMP3_NO_SPACE -18
186 #define DRMP3_BUSY -19
187 #define DRMP3_IO_ERROR -20
188 #define DRMP3_INTERRUPT -21
189 #define DRMP3_UNAVAILABLE -22
190 #define DRMP3_ALREADY_IN_USE -23
191 #define DRMP3_BAD_ADDRESS -24
192 #define DRMP3_BAD_SEEK -25
193 #define DRMP3_BAD_PIPE -26
194 #define DRMP3_DEADLOCK -27
195 #define DRMP3_TOO_MANY_LINKS -28
196 #define DRMP3_NOT_IMPLEMENTED -29
197 #define DRMP3_NO_MESSAGE -30
198 #define DRMP3_BAD_MESSAGE -31
199 #define DRMP3_NO_DATA_AVAILABLE -32
200 #define DRMP3_INVALID_DATA -33
201 #define DRMP3_TIMEOUT -34
202 #define DRMP3_NO_NETWORK -35
203 #define DRMP3_NOT_UNIQUE -36
204 #define DRMP3_NOT_SOCKET -37
205 #define DRMP3_NO_ADDRESS -38
206 #define DRMP3_BAD_PROTOCOL -39
207 #define DRMP3_PROTOCOL_UNAVAILABLE -40
208 #define DRMP3_PROTOCOL_NOT_SUPPORTED -41
209 #define DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED -42
210 #define DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED -43
211 #define DRMP3_SOCKET_NOT_SUPPORTED -44
212 #define DRMP3_CONNECTION_RESET -45
213 #define DRMP3_ALREADY_CONNECTED -46
214 #define DRMP3_NOT_CONNECTED -47
215 #define DRMP3_CONNECTION_REFUSED -48
216 #define DRMP3_NO_HOST -49
217 #define DRMP3_IN_PROGRESS -50
218 #define DRMP3_CANCELLED -51
219 #define DRMP3_MEMORY_ALREADY_MAPPED -52
220 #define DRMP3_AT_END -53
221
222
223 #define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
224 #define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
225
226 #ifdef _MSC_VER
227 #define DRMP3_INLINE __forceinline
228 #elif defined(__GNUC__)
229 /*
230 I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
231 the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
232 case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
233 command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
234 I am using "__inline__" only when we're compiling in strict ANSI mode.
235 */
236 #if defined(__STRICT_ANSI__)
237 #define DRMP3_GNUC_INLINE_HINT __inline__
238 #else
239 #define DRMP3_GNUC_INLINE_HINT inline
240 #endif
241
242 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
243 #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT __attribute__((always_inline))
244 #else
245 #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT
246 #endif
247 #elif defined(__WATCOMC__)
248 #define DRMP3_INLINE __inline
249 #else
250 #define DRMP3_INLINE
251 #endif
252
253
254 DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
255 DRMP3_API const char* drmp3_version_string(void);
256
257
258 /*
259 Low Level Push API
260 ==================
261 */
262 typedef struct
263 {
264 int frame_bytes, channels, hz, layer, bitrate_kbps;
265 } drmp3dec_frame_info;
266
267 typedef struct
268 {
269 float mdct_overlap[2][9*32], qmf_state[15*2*32];
270 int reserv, free_format_bytes;
271 drmp3_uint8 header[4], reserv_buf[511];
272 } drmp3dec;
273
274 /* Initializes a low level decoder. */
275 DRMP3_API void drmp3dec_init(drmp3dec *dec);
276
277 /* Reads a frame from a low level decoder. */
278 DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info);
279
280 /* Helper for converting between f32 and s16. */
281 DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples);
282
283
284
285 /*
286 Main API (Pull API)
287 ===================
288 */
289 typedef enum
290 {
291 drmp3_seek_origin_start,
292 drmp3_seek_origin_current
293 } drmp3_seek_origin;
294
295 typedef struct
296 {
297 drmp3_uint64 seekPosInBytes; /* Points to the first byte of an MP3 frame. */
298 drmp3_uint64 pcmFrameIndex; /* The index of the PCM frame this seek point targets. */
299 drmp3_uint16 mp3FramesToDiscard; /* The number of whole MP3 frames to be discarded before pcmFramesToDiscard. */
300 drmp3_uint16 pcmFramesToDiscard; /* The number of leading samples to read and discard. These are discarded after mp3FramesToDiscard. */
301 } drmp3_seek_point;
302
303 /*
304 Callback for when data is read. Return value is the number of bytes actually read.
305
306 pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family.
307 pBufferOut [out] The output buffer.
308 bytesToRead [in] The number of bytes to read.
309
310 Returns the number of bytes actually read.
311
312 A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
313 either the entire bytesToRead is filled or you have reached the end of the stream.
314 */
315 typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
316
317 /*
318 Callback for when data needs to be seeked.
319
320 pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family.
321 offset [in] The number of bytes to move, relative to the origin. Will never be negative.
322 origin [in] The origin of the seek - the current position or the start of the stream.
323
324 Returns whether or not the seek was successful.
325
326 Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which
327 will be either drmp3_seek_origin_start or drmp3_seek_origin_current.
328 */
329 typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin);
330
331 typedef struct
332 {
333 void* pUserData;
334 void* (* onMalloc)(size_t sz, void* pUserData);
335 void* (* onRealloc)(void* p, size_t sz, void* pUserData);
336 void (* onFree)(void* p, void* pUserData);
337 } drmp3_allocation_callbacks;
338
339 typedef struct
340 {
341 drmp3_uint32 channels;
342 drmp3_uint32 sampleRate;
343 } drmp3_config;
344
345 typedef struct
346 {
347 drmp3dec decoder;
348 drmp3dec_frame_info frameInfo;
349 drmp3_uint32 channels;
350 drmp3_uint32 sampleRate;
351 drmp3_read_proc onRead;
352 drmp3_seek_proc onSeek;
353 void* pUserData;
354 drmp3_allocation_callbacks allocationCallbacks;
355 drmp3_uint32 mp3FrameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */
356 drmp3_uint32 mp3FrameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only. */
357 drmp3_uint32 pcmFramesConsumedInMP3Frame;
358 drmp3_uint32 pcmFramesRemainingInMP3Frame;
359 drmp3_uint8 pcmFrames[sizeof(float)*DRMP3_MAX_SAMPLES_PER_FRAME]; /* <-- Multipled by sizeof(float) to ensure there's enough room for DR_MP3_FLOAT_OUTPUT. */
360 drmp3_uint64 currentPCMFrame; /* The current PCM frame, globally, based on the output sample rate. Mainly used for seeking. */
361 drmp3_uint64 streamCursor; /* The current byte the decoder is sitting on in the raw stream. */
362 drmp3_seek_point* pSeekPoints; /* NULL by default. Set with drmp3_bind_seek_table(). Memory is owned by the client. dr_mp3 will never attempt to free this pointer. */
363 drmp3_uint32 seekPointCount; /* The number of items in pSeekPoints. When set to 0 assumes to no seek table. Defaults to zero. */
364 size_t dataSize;
365 size_t dataCapacity;
366 size_t dataConsumed;
367 drmp3_uint8* pData;
368 drmp3_bool32 atEnd : 1;
369 struct
370 {
371 const drmp3_uint8* pData;
372 size_t dataSize;
373 size_t currentReadPos;
374 } memory; /* Only used for decoders that were opened against a block of memory. */
375 } drmp3;
376
377 /*
378 Initializes an MP3 decoder.
379
380 onRead [in] The function to call when data needs to be read from the client.
381 onSeek [in] The function to call when the read position of the client data needs to move.
382 pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
383
384 Returns true if successful; false otherwise.
385
386 Close the loader with drmp3_uninit().
387
388 See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit()
389 */
390 DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks);
391
392 /*
393 Initializes an MP3 decoder from a block of memory.
394
395 This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
396 the lifetime of the drmp3 object.
397
398 The buffer should contain the contents of the entire MP3 file.
399 */
400 DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
401
402 #ifndef DR_MP3_NO_STDIO
403 /*
404 Initializes an MP3 decoder from a file.
405
406 This holds the internal FILE object until drmp3_uninit() is called. Keep this in mind if you're caching drmp3
407 objects because the operating system may restrict the number of file handles an application can have open at
408 any given time.
409 */
410 DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
411 DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
412 #endif
413
414 /*
415 Uninitializes an MP3 decoder.
416 */
417 DRMP3_API void drmp3_uninit(drmp3* pMP3);
418
419 /*
420 Reads PCM frames as interleaved 32-bit IEEE floating point PCM.
421
422 Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
423 */
424 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
425
426 /*
427 Reads PCM frames as interleaved signed 16-bit integer PCM.
428
429 Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
430 */
431 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut);
432
433 /*
434 Seeks to a specific frame.
435
436 Note that this is _not_ an MP3 frame, but rather a PCM frame.
437 */
438 DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex);
439
440 /*
441 Calculates the total number of PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
442 radio. Runs in linear time. Returns 0 on error.
443 */
444 DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3);
445
446 /*
447 Calculates the total number of MP3 frames in the MP3 stream. Cannot be used for infinite streams such as internet
448 radio. Runs in linear time. Returns 0 on error.
449 */
450 DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3);
451
452 /*
453 Calculates the total number of MP3 and PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
454 radio. Runs in linear time. Returns 0 on error.
455
456 This is equivalent to calling drmp3_get_mp3_frame_count() and drmp3_get_pcm_frame_count() except that it's more efficient.
457 */
458 DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount);
459
460 /*
461 Calculates the seekpoints based on PCM frames. This is slow.
462
463 pSeekpoint count is a pointer to a uint32 containing the seekpoint count. On input it contains the desired count.
464 On output it contains the actual count. The reason for this design is that the client may request too many
465 seekpoints, in which case dr_mp3 will return a corrected count.
466
467 Note that seektable seeking is not quite sample exact when the MP3 stream contains inconsistent sample rates.
468 */
469 DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints);
470
471 /*
472 Binds a seek table to the decoder.
473
474 This does _not_ make a copy of pSeekPoints - it only references it. It is up to the application to ensure this
475 remains valid while it is bound to the decoder.
476
477 Use drmp3_calculate_seek_points() to calculate the seek points.
478 */
479 DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints);
480
481
482 /*
483 Opens an decodes an entire MP3 stream as a single operation.
484
485 On output pConfig will receive the channel count and sample rate of the stream.
486
487 Free the returned pointer with drmp3_free().
488 */
489 DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
490 DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
491
492 DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
493 DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
494
495 #ifndef DR_MP3_NO_STDIO
496 DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
497 DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
498 #endif
499
500 /*
501 Allocates a block of memory on the heap.
502 */
503 DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks);
504
505 /*
506 Frees any memory that was allocated by a public drmp3 API.
507 */
508 DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
509
510 #ifdef __cplusplus
511 }
512 #endif
513 #endif /* dr_mp3_h */
514
515
516 /************************************************************************************************************************************************************
517 ************************************************************************************************************************************************************
518
519 IMPLEMENTATION
520
521 ************************************************************************************************************************************************************
522 ************************************************************************************************************************************************************/
523 #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION)
524 #ifndef dr_mp3_c
525 #define dr_mp3_c
526
527 #include <stdlib.h>
528 #include <string.h>
529 #include <limits.h> /* For INT_MAX */
530
531 DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision)
532 {
533 if (pMajor) {
534 *pMajor = DRMP3_VERSION_MAJOR;
535 }
536
537 if (pMinor) {
538 *pMinor = DRMP3_VERSION_MINOR;
539 }
540
541 if (pRevision) {
542 *pRevision = DRMP3_VERSION_REVISION;
543 }
544 }
545
546 DRMP3_API const char* drmp3_version_string(void)
547 {
548 return DRMP3_VERSION_STRING;
549 }
550
551 /* Disable SIMD when compiling with TCC for now. */
552 #if defined(__TINYC__)
553 #define DR_MP3_NO_SIMD
554 #endif
555
556 #define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset)))
557
558 #define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */
559 #ifndef DRMP3_MAX_FRAME_SYNC_MATCHES
560 #define DRMP3_MAX_FRAME_SYNC_MATCHES 10
561 #endif
562
563 #define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */
564
565 #define DRMP3_MAX_BITRESERVOIR_BYTES 511
566 #define DRMP3_SHORT_BLOCK_TYPE 2
567 #define DRMP3_STOP_BLOCK_TYPE 3
568 #define DRMP3_MODE_MONO 3
569 #define DRMP3_MODE_JOINT_STEREO 1
570 #define DRMP3_HDR_SIZE 4
571 #define DRMP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0)
572 #define DRMP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60)
573 #define DRMP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0)
574 #define DRMP3_HDR_IS_CRC(h) (!((h[1]) & 1))
575 #define DRMP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2)
576 #define DRMP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8)
577 #define DRMP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10)
578 #define DRMP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10)
579 #define DRMP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20)
580 #define DRMP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3)
581 #define DRMP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3)
582 #define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
583 #define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4)
584 #define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3)
585 #define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3)
586 #define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2)
587 #define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
588
589 #define DRMP3_BITS_DEQUANTIZER_OUT -1
590 #define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210)
591 #define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3)
592
593 #define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a))
594 #define DRMP3_MAX(a, b) ((a) < (b) ? (b) : (a))
595
596 #if !defined(DR_MP3_NO_SIMD)
597
598 #if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
599 /* x64 always have SSE2, arm64 always have neon, no need for generic code */
600 #define DR_MP3_ONLY_SIMD
601 #endif
602
603 #if ((defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__))
604 #if defined(_MSC_VER)
605 #include <intrin.h>
606 #endif
607 #include <emmintrin.h>
608 #define DRMP3_HAVE_SSE 1
609 #define DRMP3_HAVE_SIMD 1
610 #define DRMP3_VSTORE _mm_storeu_ps
611 #define DRMP3_VLD _mm_loadu_ps
612 #define DRMP3_VSET _mm_set1_ps
613 #define DRMP3_VADD _mm_add_ps
614 #define DRMP3_VSUB _mm_sub_ps
615 #define DRMP3_VMUL _mm_mul_ps
616 #define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y))
617 #define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y))
618 #define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s))
619 #define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3))
620 typedef __m128 drmp3_f4;
621 #if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD)
622 #define drmp3_cpuid __cpuid
623 #else
624 static __inline__ __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType)
625 {
626 #if defined(__PIC__)
627 __asm__ __volatile__(
628 #if defined(__x86_64__)
629 "push %%rbx\n"
630 "cpuid\n"
631 "xchgl %%ebx, %1\n"
632 "pop %%rbx\n"
633 #else
634 "xchgl %%ebx, %1\n"
635 "cpuid\n"
636 "xchgl %%ebx, %1\n"
637 #endif
638 : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
639 : "a" (InfoType));
640 #else
641 __asm__ __volatile__(
642 "cpuid"
643 : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
644 : "a" (InfoType));
645 #endif
646 }
647 #endif
648 static int drmp3_have_simd(void)
649 {
650 #ifdef DR_MP3_ONLY_SIMD
651 return 1;
652 #else
653 static int g_have_simd;
654 int CPUInfo[4];
655 #ifdef MINIMP3_TEST
656 static int g_counter;
657 if (g_counter++ > 100)
658 return 0;
659 #endif
660 if (g_have_simd)
661 goto end;
662 drmp3_cpuid(CPUInfo, 0);
663 if (CPUInfo[0] > 0)
664 {
665 drmp3_cpuid(CPUInfo, 1);
666 g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */
667 return g_have_simd - 1;
668 }
669
670 end:
671 return g_have_simd - 1;
672 #endif
673 }
674 #elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)
675 #include <arm_neon.h>
676 #define DRMP3_HAVE_SSE 0
677 #define DRMP3_HAVE_SIMD 1
678 #define DRMP3_VSTORE vst1q_f32
679 #define DRMP3_VLD vld1q_f32
680 #define DRMP3_VSET vmovq_n_f32
681 #define DRMP3_VADD vaddq_f32
682 #define DRMP3_VSUB vsubq_f32
683 #define DRMP3_VMUL vmulq_f32
684 #define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y)
685 #define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y)
686 #define DRMP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s))
687 #define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
688 typedef float32x4_t drmp3_f4;
689 static int drmp3_have_simd(void)
690 { /* TODO: detect neon for !DR_MP3_ONLY_SIMD */
691 return 1;
692 }
693 #else
694 #define DRMP3_HAVE_SSE 0
695 #define DRMP3_HAVE_SIMD 0
696 #ifdef DR_MP3_ONLY_SIMD
697 #error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled
698 #endif
699 #endif
700
701 #else
702
703 #define DRMP3_HAVE_SIMD 0
704
705 #endif
706
707 #if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64)
708 #define DRMP3_HAVE_ARMV6 1
709 static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a)
710 {
711 drmp3_int32 x = 0;
712 __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a));
713 return x;
714 }
715 #else
716 #define DRMP3_HAVE_ARMV6 0
717 #endif
718
719
720 /* Standard library stuff. */
721 #ifndef DRMP3_ASSERT
722 #include <assert.h>
723 #define DRMP3_ASSERT(expression) assert(expression)
724 #endif
725 #ifndef DRMP3_COPY_MEMORY
726 #define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
727 #endif
728 #ifndef DRMP3_MOVE_MEMORY
729 #define DRMP3_MOVE_MEMORY(dst, src, sz) memmove((dst), (src), (sz))
730 #endif
731 #ifndef DRMP3_ZERO_MEMORY
732 #define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
733 #endif
734 #define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p)))
735 #ifndef DRMP3_MALLOC
736 #define DRMP3_MALLOC(sz) malloc((sz))
737 #endif
738 #ifndef DRMP3_REALLOC
739 #define DRMP3_REALLOC(p, sz) realloc((p), (sz))
740 #endif
741 #ifndef DRMP3_FREE
742 #define DRMP3_FREE(p) free((p))
743 #endif
744
745 typedef struct
746 {
747 const drmp3_uint8 *buf;
748 int pos, limit;
749 } drmp3_bs;
750
751 typedef struct
752 {
753 float scf[3*64];
754 drmp3_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64];
755 } drmp3_L12_scale_info;
756
757 typedef struct
758 {
759 drmp3_uint8 tab_offset, code_tab_width, band_count;
760 } drmp3_L12_subband_alloc;
761
762 typedef struct
763 {
764 const drmp3_uint8 *sfbtab;
765 drmp3_uint16 part_23_length, big_values, scalefac_compress;
766 drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb;
767 drmp3_uint8 table_select[3], region_count[3], subblock_gain[3];
768 drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi;
769 } drmp3_L3_gr_info;
770
771 typedef struct
772 {
773 drmp3_bs bs;
774 drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES];
775 drmp3_L3_gr_info gr_info[4];
776 float grbuf[2][576], scf[40], syn[18 + 15][2*32];
777 drmp3_uint8 ist_pos[2][39];
778 } drmp3dec_scratch;
779
780 static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes)
781 {
782 bs->buf = data;
783 bs->pos = 0;
784 bs->limit = bytes*8;
785 }
786
787 static drmp3_uint32 drmp3_bs_get_bits(drmp3_bs *bs, int n)
788 {
789 drmp3_uint32 next, cache = 0, s = bs->pos & 7;
790 int shl = n + s;
791 const drmp3_uint8 *p = bs->buf + (bs->pos >> 3);
792 if ((bs->pos += n) > bs->limit)
793 return 0;
794 next = *p++ & (255 >> s);
795 while ((shl -= 8) > 0)
796 {
797 cache |= next << shl;
798 next = *p++;
799 }
800 return cache | (next >> -shl);
801 }
802
803 static int drmp3_hdr_valid(const drmp3_uint8 *h)
804 {
805 return h[0] == 0xff &&
806 ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) &&
807 (DRMP3_HDR_GET_LAYER(h) != 0) &&
808 (DRMP3_HDR_GET_BITRATE(h) != 15) &&
809 (DRMP3_HDR_GET_SAMPLE_RATE(h) != 3);
810 }
811
812 static int drmp3_hdr_compare(const drmp3_uint8 *h1, const drmp3_uint8 *h2)
813 {
814 return drmp3_hdr_valid(h2) &&
815 ((h1[1] ^ h2[1]) & 0xFE) == 0 &&
816 ((h1[2] ^ h2[2]) & 0x0C) == 0 &&
817 !(DRMP3_HDR_IS_FREE_FORMAT(h1) ^ DRMP3_HDR_IS_FREE_FORMAT(h2));
818 }
819
820 static unsigned drmp3_hdr_bitrate_kbps(const drmp3_uint8 *h)
821 {
822 static const drmp3_uint8 halfrate[2][3][15] = {
823 { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } },
824 { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } },
825 };
826 return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)];
827 }
828
829 static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h)
830 {
831 static const unsigned g_hz[3] = { 44100, 48000, 32000 };
832 return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h);
833 }
834
835 static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h)
836 {
837 return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h));
838 }
839
840 static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size)
841 {
842 int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h);
843 if (DRMP3_HDR_IS_LAYER_1(h))
844 {
845 frame_bytes &= ~3; /* slot align */
846 }
847 return frame_bytes ? frame_bytes : free_format_size;
848 }
849
850 static int drmp3_hdr_padding(const drmp3_uint8 *h)
851 {
852 return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0;
853 }
854
855 #ifndef DR_MP3_ONLY_MP3
856 static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci)
857 {
858 const drmp3_L12_subband_alloc *alloc;
859 int mode = DRMP3_HDR_GET_STEREO_MODE(hdr);
860 int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32;
861
862 if (DRMP3_HDR_IS_LAYER_1(hdr))
863 {
864 static const drmp3_L12_subband_alloc g_alloc_L1[] = { { 76, 4, 32 } };
865 alloc = g_alloc_L1;
866 nbands = 32;
867 } else if (!DRMP3_HDR_TEST_MPEG1(hdr))
868 {
869 static const drmp3_L12_subband_alloc g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } };
870 alloc = g_alloc_L2M2;
871 nbands = 30;
872 } else
873 {
874 static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } };
875 int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr);
876 unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO);
877 if (!kbps) /* free-format */
878 {
879 kbps = 192;
880 }
881
882 alloc = g_alloc_L2M1;
883 nbands = 27;
884 if (kbps < 56)
885 {
886 static const drmp3_L12_subband_alloc g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } };
887 alloc = g_alloc_L2M1_lowrate;
888 nbands = sample_rate_idx == 2 ? 12 : 8;
889 } else if (kbps >= 96 && sample_rate_idx != 1)
890 {
891 nbands = 30;
892 }
893 }
894
895 sci->total_bands = (drmp3_uint8)nbands;
896 sci->stereo_bands = (drmp3_uint8)DRMP3_MIN(stereo_bands, nbands);
897
898 return alloc;
899 }
900
901 static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_uint8 *scfcod, int bands, float *scf)
902 {
903 static const float g_deq_L12[18*3] = {
904 #define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x
905 DRMP3_DQ(3),DRMP3_DQ(7),DRMP3_DQ(15),DRMP3_DQ(31),DRMP3_DQ(63),DRMP3_DQ(127),DRMP3_DQ(255),DRMP3_DQ(511),DRMP3_DQ(1023),DRMP3_DQ(2047),DRMP3_DQ(4095),DRMP3_DQ(8191),DRMP3_DQ(16383),DRMP3_DQ(32767),DRMP3_DQ(65535),DRMP3_DQ(3),DRMP3_DQ(5),DRMP3_DQ(9)
906 };
907 int i, m;
908 for (i = 0; i < bands; i++)
909 {
910 float s = 0;
911 int ba = *pba++;
912 int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0;
913 for (m = 4; m; m >>= 1)
914 {
915 if (mask & m)
916 {
917 int b = drmp3_bs_get_bits(bs, 6);
918 s = g_deq_L12[ba*3 - 6 + b % 3]*(int)(1 << 21 >> b/3);
919 }
920 *scf++ = s;
921 }
922 }
923 }
924
925 static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp3_L12_scale_info *sci)
926 {
927 static const drmp3_uint8 g_bitalloc_code_tab[] = {
928 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16,
929 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16,
930 0,17,18, 3,19,4,5,16,
931 0,17,18,16,
932 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15,
933 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14,
934 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16
935 };
936 const drmp3_L12_subband_alloc *subband_alloc = drmp3_L12_subband_alloc_table(hdr, sci);
937
938 int i, k = 0, ba_bits = 0;
939 const drmp3_uint8 *ba_code_tab = g_bitalloc_code_tab;
940
941 for (i = 0; i < sci->total_bands; i++)
942 {
943 drmp3_uint8 ba;
944 if (i == k)
945 {
946 k += subband_alloc->band_count;
947 ba_bits = subband_alloc->code_tab_width;
948 ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset;
949 subband_alloc++;
950 }
951 ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
952 sci->bitalloc[2*i] = ba;
953 if (i < sci->stereo_bands)
954 {
955 ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
956 }
957 sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0;
958 }
959
960 for (i = 0; i < 2*sci->total_bands; i++)
961 {
962 sci->scfcod[i] = (drmp3_uint8)(sci->bitalloc[i] ? DRMP3_HDR_IS_LAYER_1(hdr) ? 2 : drmp3_bs_get_bits(bs, 2) : 6);
963 }
964
965 drmp3_L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf);
966
967 for (i = sci->stereo_bands; i < sci->total_bands; i++)
968 {
969 sci->bitalloc[2*i + 1] = 0;
970 }
971 }
972
973 static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_scale_info *sci, int group_size)
974 {
975 int i, j, k, choff = 576;
976 for (j = 0; j < 4; j++)
977 {
978 float *dst = grbuf + group_size*j;
979 for (i = 0; i < 2*sci->total_bands; i++)
980 {
981 int ba = sci->bitalloc[i];
982 if (ba != 0)
983 {
984 if (ba < 17)
985 {
986 int half = (1 << (ba - 1)) - 1;
987 for (k = 0; k < group_size; k++)
988 {
989 dst[k] = (float)((int)drmp3_bs_get_bits(bs, ba) - half);
990 }
991 } else
992 {
993 unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */
994 unsigned code = drmp3_bs_get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */
995 for (k = 0; k < group_size; k++, code /= mod)
996 {
997 dst[k] = (float)((int)(code % mod - mod/2));
998 }
999 }
1000 }
1001 dst += choff;
1002 choff = 18 - choff;
1003 }
1004 }
1005 return group_size*4;
1006 }
1007
1008 static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst)
1009 {
1010 int i, k;
1011 DRMP3_COPY_MEMORY(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float));
1012 for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6)
1013 {
1014 for (k = 0; k < 12; k++)
1015 {
1016 dst[k + 0] *= scf[0];
1017 dst[k + 576] *= scf[3];
1018 }
1019 }
1020 }
1021 #endif
1022
1023 static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
1024 {
1025 static const drmp3_uint8 g_scf_long[8][23] = {
1026 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
1027 { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 },
1028 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
1029 { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 },
1030 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
1031 { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 },
1032 { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 },
1033 { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 }
1034 };
1035 static const drmp3_uint8 g_scf_short[8][40] = {
1036 { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1037 { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
1038 { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
1039 { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
1040 { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1041 { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
1042 { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
1043 { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
1044 };
1045 static const drmp3_uint8 g_scf_mixed[8][40] = {
1046 { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1047 { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
1048 { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
1049 { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
1050 { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1051 { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
1052 { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
1053 { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
1054 };
1055
1056 unsigned tables, scfsi = 0;
1057 int main_data_begin, part_23_sum = 0;
1058 int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
1059 int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
1060
1061 if (DRMP3_HDR_TEST_MPEG1(hdr))
1062 {
1063 gr_count *= 2;
1064 main_data_begin = drmp3_bs_get_bits(bs, 9);
1065 scfsi = drmp3_bs_get_bits(bs, 7 + gr_count);
1066 } else
1067 {
1068 main_data_begin = drmp3_bs_get_bits(bs, 8 + gr_count) >> gr_count;
1069 }
1070
1071 do
1072 {
1073 if (DRMP3_HDR_IS_MONO(hdr))
1074 {
1075 scfsi <<= 4;
1076 }
1077 gr->part_23_length = (drmp3_uint16)drmp3_bs_get_bits(bs, 12);
1078 part_23_sum += gr->part_23_length;
1079 gr->big_values = (drmp3_uint16)drmp3_bs_get_bits(bs, 9);
1080 if (gr->big_values > 288)
1081 {
1082 return -1;
1083 }
1084 gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8);
1085 gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9);
1086 gr->sfbtab = g_scf_long[sr_idx];
1087 gr->n_long_sfb = 22;
1088 gr->n_short_sfb = 0;
1089 if (drmp3_bs_get_bits(bs, 1))
1090 {
1091 gr->block_type = (drmp3_uint8)drmp3_bs_get_bits(bs, 2);
1092 if (!gr->block_type)
1093 {
1094 return -1;
1095 }
1096 gr->mixed_block_flag = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1097 gr->region_count[0] = 7;
1098 gr->region_count[1] = 255;
1099 if (gr->block_type == DRMP3_SHORT_BLOCK_TYPE)
1100 {
1101 scfsi &= 0x0F0F;
1102 if (!gr->mixed_block_flag)
1103 {
1104 gr->region_count[0] = 8;
1105 gr->sfbtab = g_scf_short[sr_idx];
1106 gr->n_long_sfb = 0;
1107 gr->n_short_sfb = 39;
1108 } else
1109 {
1110 gr->sfbtab = g_scf_mixed[sr_idx];
1111 gr->n_long_sfb = DRMP3_HDR_TEST_MPEG1(hdr) ? 8 : 6;
1112 gr->n_short_sfb = 30;
1113 }
1114 }
1115 tables = drmp3_bs_get_bits(bs, 10);
1116 tables <<= 5;
1117 gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1118 gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1119 gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1120 } else
1121 {
1122 gr->block_type = 0;
1123 gr->mixed_block_flag = 0;
1124 tables = drmp3_bs_get_bits(bs, 15);
1125 gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4);
1126 gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1127 gr->region_count[2] = 255;
1128 }
1129 gr->table_select[0] = (drmp3_uint8)(tables >> 10);
1130 gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31);
1131 gr->table_select[2] = (drmp3_uint8)((tables) & 31);
1132 gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500));
1133 gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1134 gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1135 gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15);
1136 scfsi <<= 4;
1137 gr++;
1138 } while(--gr_count);
1139
1140 if (part_23_sum + bs->pos > bs->limit + main_data_begin*8)
1141 {
1142 return -1;
1143 }
1144
1145 return main_data_begin;
1146 }
1147
1148 static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, const drmp3_uint8 *scf_size, const drmp3_uint8 *scf_count, drmp3_bs *bitbuf, int scfsi)
1149 {
1150 int i, k;
1151 for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2)
1152 {
1153 int cnt = scf_count[i];
1154 if (scfsi & 8)
1155 {
1156 DRMP3_COPY_MEMORY(scf, ist_pos, cnt);
1157 } else
1158 {
1159 int bits = scf_size[i];
1160 if (!bits)
1161 {
1162 DRMP3_ZERO_MEMORY(scf, cnt);
1163 DRMP3_ZERO_MEMORY(ist_pos, cnt);
1164 } else
1165 {
1166 int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1;
1167 for (k = 0; k < cnt; k++)
1168 {
1169 int s = drmp3_bs_get_bits(bitbuf, bits);
1170 ist_pos[k] = (drmp3_uint8)(s == max_scf ? -1 : s);
1171 scf[k] = (drmp3_uint8)s;
1172 }
1173 }
1174 }
1175 ist_pos += cnt;
1176 scf += cnt;
1177 }
1178 scf[0] = scf[1] = scf[2] = 0;
1179 }
1180
1181 static float drmp3_L3_ldexp_q2(float y, int exp_q2)
1182 {
1183 static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f };
1184 int e;
1185 do
1186 {
1187 e = DRMP3_MIN(30*4, exp_q2);
1188 y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2));
1189 } while ((exp_q2 -= e) > 0);
1190 return y;
1191 }
1192
1193 static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch)
1194 {
1195 static const drmp3_uint8 g_scf_partitions[3][28] = {
1196 { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 },
1197 { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 },
1198 { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 }
1199 };
1200 const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb];
1201 drmp3_uint8 scf_size[4], iscf[40];
1202 int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi;
1203 float gain;
1204
1205 if (DRMP3_HDR_TEST_MPEG1(hdr))
1206 {
1207 static const drmp3_uint8 g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 };
1208 int part = g_scfc_decode[gr->scalefac_compress];
1209 scf_size[1] = scf_size[0] = (drmp3_uint8)(part >> 2);
1210 scf_size[3] = scf_size[2] = (drmp3_uint8)(part & 3);
1211 } else
1212 {
1213 static const drmp3_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 };
1214 int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch;
1215 sfc = gr->scalefac_compress >> ist;
1216 for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4)
1217 {
1218 for (modprod = 1, i = 3; i >= 0; i--)
1219 {
1220 scf_size[i] = (drmp3_uint8)(sfc / modprod % g_mod[k + i]);
1221 modprod *= g_mod[k + i];
1222 }
1223 }
1224 scf_partition += k;
1225 scfsi = -16;
1226 }
1227 drmp3_L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi);
1228
1229 if (gr->n_short_sfb)
1230 {
1231 int sh = 3 - scf_shift;
1232 for (i = 0; i < gr->n_short_sfb; i += 3)
1233 {
1234 iscf[gr->n_long_sfb + i + 0] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh));
1235 iscf[gr->n_long_sfb + i + 1] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh));
1236 iscf[gr->n_long_sfb + i + 2] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh));
1237 }
1238 } else if (gr->preflag)
1239 {
1240 static const drmp3_uint8 g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 };
1241 for (i = 0; i < 10; i++)
1242 {
1243 iscf[11 + i] = (drmp3_uint8)(iscf[11 + i] + g_preamp[i]);
1244 }
1245 }
1246
1247 gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0);
1248 gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4), DRMP3_MAX_SCFI - gain_exp);
1249 for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++)
1250 {
1251 scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift);
1252 }
1253 }
1254
1255 static const float g_drmp3_pow43[129 + 16] = {
1256 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f,
1257 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f
1258 };
1259
1260 static float drmp3_L3_pow_43(int x)
1261 {
1262 float frac;
1263 int sign, mult = 256;
1264
1265 if (x < 129)
1266 {
1267 return g_drmp3_pow43[16 + x];
1268 }
1269
1270 if (x < 1024)
1271 {
1272 mult = 16;
1273 x <<= 3;
1274 }
1275
1276 sign = 2*x & 64;
1277 frac = (float)((x & 63) - sign) / ((x & ~63) + sign);
1278 return g_drmp3_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult;
1279 }
1280
1281 static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
1282 {
1283 static const drmp3_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1284 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
1285 -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288,
1286 -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288,
1287 -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258,
1288 -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259,
1289 -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258,
1290 -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258,
1291 -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259,
1292 -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258,
1293 -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290,
1294 -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259,
1295 -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258,
1296 -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259,
1297 -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258,
1298 -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 };
1299 static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205};
1300 static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
1301 static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
1302 static const drmp3_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
1303
1304 #define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n))
1305 #define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); }
1306 #define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
1307 #define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
1308
1309 float one = 0.0f;
1310 int ireg = 0, big_val_cnt = gr_info->big_values;
1311 const drmp3_uint8 *sfb = gr_info->sfbtab;
1312 const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8;
1313 drmp3_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7);
1314 int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8;
1315 bs_next_ptr += 4;
1316
1317 while (big_val_cnt > 0)
1318 {
1319 int tab_num = gr_info->table_select[ireg];
1320 int sfb_cnt = gr_info->region_count[ireg++];
1321 const drmp3_int16 *codebook = tabs + tabindex[tab_num];
1322 int linbits = g_linbits[tab_num];
1323 if (linbits)
1324 {
1325 do
1326 {
1327 np = *sfb++ / 2;
1328 pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
1329 one = *scf++;
1330 do
1331 {
1332 int j, w = 5;
1333 int leaf = codebook[DRMP3_PEEK_BITS(w)];
1334 while (leaf < 0)
1335 {
1336 DRMP3_FLUSH_BITS(w);
1337 w = leaf & 7;
1338 leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
1339 }
1340 DRMP3_FLUSH_BITS(leaf >> 8);
1341
1342 for (j = 0; j < 2; j++, dst++, leaf >>= 4)
1343 {
1344 int lsb = leaf & 0x0F;
1345 if (lsb == 15)
1346 {
1347 lsb += DRMP3_PEEK_BITS(linbits);
1348 DRMP3_FLUSH_BITS(linbits);
1349 DRMP3_CHECK_BITS;
1350 *dst = one*drmp3_L3_pow_43(lsb)*((drmp3_int32)bs_cache < 0 ? -1: 1);
1351 } else
1352 {
1353 *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
1354 }
1355 DRMP3_FLUSH_BITS(lsb ? 1 : 0);
1356 }
1357 DRMP3_CHECK_BITS;
1358 } while (--pairs_to_decode);
1359 } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
1360 } else
1361 {
1362 do
1363 {
1364 np = *sfb++ / 2;
1365 pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
1366 one = *scf++;
1367 do
1368 {
1369 int j, w = 5;
1370 int leaf = codebook[DRMP3_PEEK_BITS(w)];
1371 while (leaf < 0)
1372 {
1373 DRMP3_FLUSH_BITS(w);
1374 w = leaf & 7;
1375 leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
1376 }
1377 DRMP3_FLUSH_BITS(leaf >> 8);
1378
1379 for (j = 0; j < 2; j++, dst++, leaf >>= 4)
1380 {
1381 int lsb = leaf & 0x0F;
1382 *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
1383 DRMP3_FLUSH_BITS(lsb ? 1 : 0);
1384 }
1385 DRMP3_CHECK_BITS;
1386 } while (--pairs_to_decode);
1387 } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
1388 }
1389 }
1390
1391 for (np = 1 - big_val_cnt;; dst += 4)
1392 {
1393 const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32;
1394 int leaf = codebook_count1[DRMP3_PEEK_BITS(4)];
1395 if (!(leaf & 8))
1396 {
1397 leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))];
1398 }
1399 DRMP3_FLUSH_BITS(leaf & 7);
1400 if (DRMP3_BSPOS > layer3gr_limit)
1401 {
1402 break;
1403 }
1404 #define DRMP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; }
1405 #define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) }
1406 DRMP3_RELOAD_SCALEFACTOR;
1407 DRMP3_DEQ_COUNT1(0);
1408 DRMP3_DEQ_COUNT1(1);
1409 DRMP3_RELOAD_SCALEFACTOR;
1410 DRMP3_DEQ_COUNT1(2);
1411 DRMP3_DEQ_COUNT1(3);
1412 DRMP3_CHECK_BITS;
1413 }
1414
1415 bs->pos = layer3gr_limit;
1416 }
1417
1418 static void drmp3_L3_midside_stereo(float *left, int n)
1419 {
1420 int i = 0;
1421 float *right = left + 576;
1422 #if DRMP3_HAVE_SIMD
1423 if (drmp3_have_simd())
1424 {
1425 for (; i < n - 3; i += 4)
1426 {
1427 drmp3_f4 vl = DRMP3_VLD(left + i);
1428 drmp3_f4 vr = DRMP3_VLD(right + i);
1429 DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr));
1430 DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr));
1431 }
1432 #ifdef __GNUC__
1433 /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc.
1434 * For more info see: https://github.com/lieff/minimp3/issues/88
1435 */
1436 if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0)
1437 return;
1438 #endif
1439 }
1440 #endif
1441 for (; i < n; i++)
1442 {
1443 float a = left[i];
1444 float b = right[i];
1445 left[i] = a + b;
1446 right[i] = a - b;
1447 }
1448 }
1449
1450 static void drmp3_L3_intensity_stereo_band(float *left, int n, float kl, float kr)
1451 {
1452 int i;
1453 for (i = 0; i < n; i++)
1454 {
1455 left[i + 576] = left[i]*kr;
1456 left[i] = left[i]*kl;
1457 }
1458 }
1459
1460 static void drmp3_L3_stereo_top_band(const float *right, const drmp3_uint8 *sfb, int nbands, int max_band[3])
1461 {
1462 int i, k;
1463
1464 max_band[0] = max_band[1] = max_band[2] = -1;
1465
1466 for (i = 0; i < nbands; i++)
1467 {
1468 for (k = 0; k < sfb[i]; k += 2)
1469 {
1470 if (right[k] != 0 || right[k + 1] != 0)
1471 {
1472 max_band[i % 3] = i;
1473 break;
1474 }
1475 }
1476 right += sfb[i];
1477 }
1478 }
1479
1480 static void drmp3_L3_stereo_process(float *left, const drmp3_uint8 *ist_pos, const drmp3_uint8 *sfb, const drmp3_uint8 *hdr, int max_band[3], int mpeg2_sh)
1481 {
1482 static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 };
1483 unsigned i, max_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 7 : 64;
1484
1485 for (i = 0; sfb[i]; i++)
1486 {
1487 unsigned ipos = ist_pos[i];
1488 if ((int)i > max_band[i % 3] && ipos < max_pos)
1489 {
1490 float kl, kr, s = DRMP3_HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1;
1491 if (DRMP3_HDR_TEST_MPEG1(hdr))
1492 {
1493 kl = g_pan[2*ipos];
1494 kr = g_pan[2*ipos + 1];
1495 } else
1496 {
1497 kl = 1;
1498 kr = drmp3_L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh);
1499 if (ipos & 1)
1500 {
1501 kl = kr;
1502 kr = 1;
1503 }
1504 }
1505 drmp3_L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s);
1506 } else if (DRMP3_HDR_TEST_MS_STEREO(hdr))
1507 {
1508 drmp3_L3_midside_stereo(left, sfb[i]);
1509 }
1510 left += sfb[i];
1511 }
1512 }
1513
1514 static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
1515 {
1516 int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb;
1517 int i, max_blocks = gr->n_short_sfb ? 3 : 1;
1518
1519 drmp3_L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band);
1520 if (gr->n_long_sfb)
1521 {
1522 max_band[0] = max_band[1] = max_band[2] = DRMP3_MAX(DRMP3_MAX(max_band[0], max_band[1]), max_band[2]);
1523 }
1524 for (i = 0; i < max_blocks; i++)
1525 {
1526 int default_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 3 : 0;
1527 int itop = n_sfb - max_blocks + i;
1528 int prev = itop - max_blocks;
1529 ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]);
1530 }
1531 drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1);
1532 }
1533
1534 static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb)
1535 {
1536 int i, len;
1537 float *src = grbuf, *dst = scratch;
1538
1539 for (;0 != (len = *sfb); sfb += 3, src += 2*len)
1540 {
1541 for (i = 0; i < len; i++, src++)
1542 {
1543 *dst++ = src[0*len];
1544 *dst++ = src[1*len];
1545 *dst++ = src[2*len];
1546 }
1547 }
1548 DRMP3_COPY_MEMORY(grbuf, scratch, (dst - scratch)*sizeof(float));
1549 }
1550
1551 static void drmp3_L3_antialias(float *grbuf, int nbands)
1552 {
1553 static const float g_aa[2][8] = {
1554 {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f},
1555 {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f}
1556 };
1557
1558 for (; nbands > 0; nbands--, grbuf += 18)
1559 {
1560 int i = 0;
1561 #if DRMP3_HAVE_SIMD
1562 if (drmp3_have_simd()) for (; i < 8; i += 4)
1563 {
1564 drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i);
1565 drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i);
1566 drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i);
1567 drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i);
1568 vd = DRMP3_VREV(vd);
1569 DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1)));
1570 vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0));
1571 DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd));
1572 }
1573 #endif
1574 #ifndef DR_MP3_ONLY_SIMD
1575 for(; i < 8; i++)
1576 {
1577 float u = grbuf[18 + i];
1578 float d = grbuf[17 - i];
1579 grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i];
1580 grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i];
1581 }
1582 #endif
1583 }
1584 }
1585
1586 static void drmp3_L3_dct3_9(float *y)
1587 {
1588 float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4;
1589
1590 s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8];
1591 t0 = s0 + s6*0.5f;
1592 s0 -= s6;
1593 t4 = (s4 + s2)*0.93969262f;
1594 t2 = (s8 + s2)*0.76604444f;
1595 s6 = (s4 - s8)*0.17364818f;
1596 s4 += s8 - s2;
1597
1598 s2 = s0 - s4*0.5f;
1599 y[4] = s4 + s0;
1600 s8 = t0 - t2 + s6;
1601 s0 = t0 - t4 + t2;
1602 s4 = t0 + t4 - s6;
1603
1604 s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7];
1605
1606 s3 *= 0.86602540f;
1607 t0 = (s5 + s1)*0.98480775f;
1608 t4 = (s5 - s7)*0.34202014f;
1609 t2 = (s1 + s7)*0.64278761f;
1610 s1 = (s1 - s5 - s7)*0.86602540f;
1611
1612 s5 = t0 - s3 - t2;
1613 s7 = t4 - s3 - t0;
1614 s3 = t4 + s3 - t2;
1615
1616 y[0] = s4 - s7;
1617 y[1] = s2 + s1;
1618 y[2] = s0 - s3;
1619 y[3] = s8 + s5;
1620 y[5] = s8 - s5;
1621 y[6] = s0 + s3;
1622 y[7] = s2 - s1;
1623 y[8] = s4 + s7;
1624 }
1625
1626 static void drmp3_L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands)
1627 {
1628 int i, j;
1629 static const float g_twid9[18] = {
1630 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f
1631 };
1632
1633 for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9)
1634 {
1635 float co[9], si[9];
1636 co[0] = -grbuf[0];
1637 si[0] = grbuf[17];
1638 for (i = 0; i < 4; i++)
1639 {
1640 si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2];
1641 co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2];
1642 si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3];
1643 co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]);
1644 }
1645 drmp3_L3_dct3_9(co);
1646 drmp3_L3_dct3_9(si);
1647
1648 si[1] = -si[1];
1649 si[3] = -si[3];
1650 si[5] = -si[5];
1651 si[7] = -si[7];
1652
1653 i = 0;
1654
1655 #if DRMP3_HAVE_SIMD
1656 if (drmp3_have_simd()) for (; i < 8; i += 4)
1657 {
1658 drmp3_f4 vovl = DRMP3_VLD(overlap + i);
1659 drmp3_f4 vc = DRMP3_VLD(co + i);
1660 drmp3_f4 vs = DRMP3_VLD(si + i);
1661 drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i);
1662 drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i);
1663 drmp3_f4 vw0 = DRMP3_VLD(window + i);
1664 drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i);
1665 drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0));
1666 DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1)));
1667 DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1)));
1668 vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0));
1669 DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum));
1670 }
1671 #endif
1672 for (; i < 9; i++)
1673 {
1674 float ovl = overlap[i];
1675 float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i];
1676 overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i];
1677 grbuf[i] = ovl*window[0 + i] - sum*window[9 + i];
1678 grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i];
1679 }
1680 }
1681 }
1682
1683 static void drmp3_L3_idct3(float x0, float x1, float x2, float *dst)
1684 {
1685 float m1 = x1*0.86602540f;
1686 float a1 = x0 - x2*0.5f;
1687 dst[1] = x0 + x2;
1688 dst[0] = a1 + m1;
1689 dst[2] = a1 - m1;
1690 }
1691
1692 static void drmp3_L3_imdct12(float *x, float *dst, float *overlap)
1693 {
1694 static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f };
1695 float co[3], si[3];
1696 int i;
1697
1698 drmp3_L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co);
1699 drmp3_L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si);
1700 si[1] = -si[1];
1701
1702 for (i = 0; i < 3; i++)
1703 {
1704 float ovl = overlap[i];
1705 float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i];
1706 overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i];
1707 dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i];
1708 dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i];
1709 }
1710 }
1711
1712 static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands)
1713 {
1714 for (;nbands > 0; nbands--, overlap += 9, grbuf += 18)
1715 {
1716 float tmp[18];
1717 DRMP3_COPY_MEMORY(tmp, grbuf, sizeof(tmp));
1718 DRMP3_COPY_MEMORY(grbuf, overlap, 6*sizeof(float));
1719 drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6);
1720 drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6);
1721 drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6);
1722 }
1723 }
1724
1725 static void drmp3_L3_change_sign(float *grbuf)
1726 {
1727 int b, i;
1728 for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36)
1729 for (i = 1; i < 18; i += 2)
1730 grbuf[i] = -grbuf[i];
1731 }
1732
1733 static void drmp3_L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands)
1734 {
1735 static const float g_mdct_window[2][18] = {
1736 { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f },
1737 { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f }
1738 };
1739 if (n_long_bands)
1740 {
1741 drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands);
1742 grbuf += 18*n_long_bands;
1743 overlap += 9*n_long_bands;
1744 }
1745 if (block_type == DRMP3_SHORT_BLOCK_TYPE)
1746 drmp3_L3_imdct_short(grbuf, overlap, 32 - n_long_bands);
1747 else
1748 drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[block_type == DRMP3_STOP_BLOCK_TYPE], 32 - n_long_bands);
1749 }
1750
1751 static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s)
1752 {
1753 int pos = (s->bs.pos + 7)/8u;
1754 int remains = s->bs.limit/8u - pos;
1755 if (remains > DRMP3_MAX_BITRESERVOIR_BYTES)
1756 {
1757 pos += remains - DRMP3_MAX_BITRESERVOIR_BYTES;
1758 remains = DRMP3_MAX_BITRESERVOIR_BYTES;
1759 }
1760 if (remains > 0)
1761 {
1762 DRMP3_MOVE_MEMORY(h->reserv_buf, s->maindata + pos, remains);
1763 }
1764 h->reserv = remains;
1765 }
1766
1767 static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin)
1768 {
1769 int frame_bytes = (bs->limit - bs->pos)/8;
1770 int bytes_have = DRMP3_MIN(h->reserv, main_data_begin);
1771 DRMP3_COPY_MEMORY(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin));
1772 DRMP3_COPY_MEMORY(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
1773 drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
1774 return h->reserv >= main_data_begin;
1775 }
1776
1777 static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch)
1778 {
1779 int ch;
1780
1781 for (ch = 0; ch < nch; ch++)
1782 {
1783 int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length;
1784 drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
1785 drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);
1786 }
1787
1788 if (DRMP3_HDR_TEST_I_STEREO(h->header))
1789 {
1790 drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header);
1791 } else if (DRMP3_HDR_IS_MS_STEREO(h->header))
1792 {
1793 drmp3_L3_midside_stereo(s->grbuf[0], 576);
1794 }
1795
1796 for (ch = 0; ch < nch; ch++, gr_info++)
1797 {
1798 int aa_bands = 31;
1799 int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(DRMP3_HDR_GET_MY_SAMPLE_RATE(h->header) == 2);
1800
1801 if (gr_info->n_short_sfb)
1802 {
1803 aa_bands = n_long_bands - 1;
1804 drmp3_L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb);
1805 }
1806
1807 drmp3_L3_antialias(s->grbuf[ch], aa_bands);
1808 drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands);
1809 drmp3_L3_change_sign(s->grbuf[ch]);
1810 }
1811 }
1812
1813 static void drmp3d_DCT_II(float *grbuf, int n)
1814 {
1815 static const float g_sec[24] = {
1816 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f
1817 };
1818 int i, k = 0;
1819 #if DRMP3_HAVE_SIMD
1820 if (drmp3_have_simd()) for (; k < n; k += 4)
1821 {
1822 drmp3_f4 t[4][8], *x;
1823 float *y = grbuf + k;
1824
1825 for (x = t[0], i = 0; i < 8; i++, x++)
1826 {
1827 drmp3_f4 x0 = DRMP3_VLD(&y[i*18]);
1828 drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]);
1829 drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]);
1830 drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]);
1831 drmp3_f4 t0 = DRMP3_VADD(x0, x3);
1832 drmp3_f4 t1 = DRMP3_VADD(x1, x2);
1833 drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]);
1834 drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]);
1835 x[0] = DRMP3_VADD(t0, t1);
1836 x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]);
1837 x[16] = DRMP3_VADD(t3, t2);
1838 x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]);
1839 }
1840 for (x = t[0], i = 0; i < 4; i++, x += 8)
1841 {
1842 drmp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
1843 xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7);
1844 x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6);
1845 x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5);
1846 x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4);
1847 x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3);
1848 x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2);
1849 x[0] = DRMP3_VADD(x0, x1);
1850 x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f);
1851 x5 = DRMP3_VADD(x5, x6);
1852 x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f);
1853 x7 = DRMP3_VADD(x7, xt);
1854 x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f);
1855 x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */
1856 x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f));
1857 x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f));
1858 x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6);
1859 x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f);
1860 x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f);
1861 x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f);
1862 x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f);
1863 x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f);
1864 x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f);
1865 }
1866
1867 if (k > n - 3)
1868 {
1869 #if DRMP3_HAVE_SSE
1870 #define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v)
1871 #else
1872 #define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v))
1873 #endif
1874 for (i = 0; i < 7; i++, y += 4*18)
1875 {
1876 drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
1877 DRMP3_VSAVE2(0, t[0][i]);
1878 DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s));
1879 DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
1880 DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s));
1881 }
1882 DRMP3_VSAVE2(0, t[0][7]);
1883 DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7]));
1884 DRMP3_VSAVE2(2, t[1][7]);
1885 DRMP3_VSAVE2(3, t[3][7]);
1886 } else
1887 {
1888 #define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[i*18], v)
1889 for (i = 0; i < 7; i++, y += 4*18)
1890 {
1891 drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
1892 DRMP3_VSAVE4(0, t[0][i]);
1893 DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s));
1894 DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
1895 DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s));
1896 }
1897 DRMP3_VSAVE4(0, t[0][7]);
1898 DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7]));
1899 DRMP3_VSAVE4(2, t[1][7]);
1900 DRMP3_VSAVE4(3, t[3][7]);
1901 }
1902 } else
1903 #endif
1904 #ifdef DR_MP3_ONLY_SIMD
1905 {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
1906 #else
1907 for (; k < n; k++)
1908 {
1909 float t[4][8], *x, *y = grbuf + k;
1910
1911 for (x = t[0], i = 0; i < 8; i++, x++)
1912 {
1913 float x0 = y[i*18];
1914 float x1 = y[(15 - i)*18];
1915 float x2 = y[(16 + i)*18];
1916 float x3 = y[(31 - i)*18];
1917 float t0 = x0 + x3;
1918 float t1 = x1 + x2;
1919 float t2 = (x1 - x2)*g_sec[3*i + 0];
1920 float t3 = (x0 - x3)*g_sec[3*i + 1];
1921 x[0] = t0 + t1;
1922 x[8] = (t0 - t1)*g_sec[3*i + 2];
1923 x[16] = t3 + t2;
1924 x[24] = (t3 - t2)*g_sec[3*i + 2];
1925 }
1926 for (x = t[0], i = 0; i < 4; i++, x += 8)
1927 {
1928 float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
1929 xt = x0 - x7; x0 += x7;
1930 x7 = x1 - x6; x1 += x6;
1931 x6 = x2 - x5; x2 += x5;
1932 x5 = x3 - x4; x3 += x4;
1933 x4 = x0 - x3; x0 += x3;
1934 x3 = x1 - x2; x1 += x2;
1935 x[0] = x0 + x1;
1936 x[4] = (x0 - x1)*0.70710677f;
1937 x5 = x5 + x6;
1938 x6 = (x6 + x7)*0.70710677f;
1939 x7 = x7 + xt;
1940 x3 = (x3 + x4)*0.70710677f;
1941 x5 -= x7*0.198912367f; /* rotate by PI/8 */
1942 x7 += x5*0.382683432f;
1943 x5 -= x7*0.198912367f;
1944 x0 = xt - x6; xt += x6;
1945 x[1] = (xt + x7)*0.50979561f;
1946 x[2] = (x4 + x3)*0.54119611f;
1947 x[3] = (x0 - x5)*0.60134488f;
1948 x[5] = (x0 + x5)*0.89997619f;
1949 x[6] = (x4 - x3)*1.30656302f;
1950 x[7] = (xt - x7)*2.56291556f;
1951
1952 }
1953 for (i = 0; i < 7; i++, y += 4*18)
1954 {
1955 y[0*18] = t[0][i];
1956 y[1*18] = t[2][i] + t[3][i] + t[3][i + 1];
1957 y[2*18] = t[1][i] + t[1][i + 1];
1958 y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1];
1959 }
1960 y[0*18] = t[0][7];
1961 y[1*18] = t[2][7] + t[3][7];
1962 y[2*18] = t[1][7];
1963 y[3*18] = t[3][7];
1964 }
1965 #endif
1966 }
1967
1968 #ifndef DR_MP3_FLOAT_OUTPUT
1969 typedef drmp3_int16 drmp3d_sample_t;
1970
1971 static drmp3_int16 drmp3d_scale_pcm(float sample)
1972 {
1973 drmp3_int16 s;
1974 #if DRMP3_HAVE_ARMV6
1975 drmp3_int32 s32 = (drmp3_int32)(sample + .5f);
1976 s32 -= (s32 < 0);
1977 s = (drmp3_int16)drmp3_clip_int16_arm(s32);
1978 #else
1979 if (sample >= 32766.5) return (drmp3_int16) 32767;
1980 if (sample <= -32767.5) return (drmp3_int16)-32768;
1981 s = (drmp3_int16)(sample + .5f);
1982 s -= (s < 0); /* away from zero, to be compliant */
1983 #endif
1984 return s;
1985 }
1986 #else
1987 typedef float drmp3d_sample_t;
1988
1989 static float drmp3d_scale_pcm(float sample)
1990 {
1991 return sample*(1.f/32768.f);
1992 }
1993 #endif
1994
1995 static void drmp3d_synth_pair(drmp3d_sample_t *pcm, int nch, const float *z)
1996 {
1997 float a;
1998 a = (z[14*64] - z[ 0]) * 29;
1999 a += (z[ 1*64] + z[13*64]) * 213;
2000 a += (z[12*64] - z[ 2*64]) * 459;
2001 a += (z[ 3*64] + z[11*64]) * 2037;
2002 a += (z[10*64] - z[ 4*64]) * 5153;
2003 a += (z[ 5*64] + z[ 9*64]) * 6574;
2004 a += (z[ 8*64] - z[ 6*64]) * 37489;
2005 a += z[ 7*64] * 75038;
2006 pcm[0] = drmp3d_scale_pcm(a);
2007
2008 z += 2;
2009 a = z[14*64] * 104;
2010 a += z[12*64] * 1567;
2011 a += z[10*64] * 9727;
2012 a += z[ 8*64] * 64019;
2013 a += z[ 6*64] * -9975;
2014 a += z[ 4*64] * -45;
2015 a += z[ 2*64] * 146;
2016 a += z[ 0*64] * -5;
2017 pcm[16*nch] = drmp3d_scale_pcm(a);
2018 }
2019
2020 static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins)
2021 {
2022 int i;
2023 float *xr = xl + 576*(nch - 1);
2024 drmp3d_sample_t *dstr = dstl + (nch - 1);
2025
2026 static const float g_win[] = {
2027 -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992,
2028 -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856,
2029 -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630,
2030 -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313,
2031 -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908,
2032 -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415,
2033 -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835,
2034 -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169,
2035 -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420,
2036 -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590,
2037 -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679,
2038 -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692,
2039 -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629,
2040 -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494,
2041 -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290
2042 };
2043 float *zlin = lins + 15*64;
2044 const float *w = g_win;
2045
2046 zlin[4*15] = xl[18*16];
2047 zlin[4*15 + 1] = xr[18*16];
2048 zlin[4*15 + 2] = xl[0];
2049 zlin[4*15 + 3] = xr[0];
2050
2051 zlin[4*31] = xl[1 + 18*16];
2052 zlin[4*31 + 1] = xr[1 + 18*16];
2053 zlin[4*31 + 2] = xl[1];
2054 zlin[4*31 + 3] = xr[1];
2055
2056 drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1);
2057 drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1);
2058 drmp3d_synth_pair(dstl, nch, lins + 4*15);
2059 drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64);
2060
2061 #if DRMP3_HAVE_SIMD
2062 if (drmp3_have_simd()) for (i = 14; i >= 0; i--)
2063 {
2064 #define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]);
2065 #define DRMP3_V0(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1)); }
2066 #define DRMP3_V1(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1))); }
2067 #define DRMP3_V2(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1), DRMP3_VMUL(vz, w0))); }
2068 drmp3_f4 a, b;
2069 zlin[4*i] = xl[18*(31 - i)];
2070 zlin[4*i + 1] = xr[18*(31 - i)];
2071 zlin[4*i + 2] = xl[1 + 18*(31 - i)];
2072 zlin[4*i + 3] = xr[1 + 18*(31 - i)];
2073 zlin[4*i + 64] = xl[1 + 18*(1 + i)];
2074 zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)];
2075 zlin[4*i - 64 + 2] = xl[18*(1 + i)];
2076 zlin[4*i - 64 + 3] = xr[18*(1 + i)];
2077
2078 DRMP3_V0(0) DRMP3_V2(1) DRMP3_V1(2) DRMP3_V2(3) DRMP3_V1(4) DRMP3_V2(5) DRMP3_V1(6) DRMP3_V2(7)
2079
2080 {
2081 #ifndef DR_MP3_FLOAT_OUTPUT
2082 #if DRMP3_HAVE_SSE
2083 static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
2084 static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
2085 __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)),
2086 _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min)));
2087 dstr[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
2088 dstr[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
2089 dstl[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
2090 dstl[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
2091 dstr[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
2092 dstr[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
2093 dstl[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
2094 dstl[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
2095 #else
2096 int16x4_t pcma, pcmb;
2097 a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
2098 b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
2099 pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
2100 pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
2101 vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1);
2102 vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1);
2103 vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0);
2104 vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0);
2105 vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3);
2106 vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3);
2107 vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2);
2108 vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2);
2109 #endif
2110 #else
2111 #if DRMP3_HAVE_SSE
2112 static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
2113 #else
2114 const drmp3_f4 g_scale = vdupq_n_f32(1.0f/32768.0f);
2115 #endif
2116 a = DRMP3_VMUL(a, g_scale);
2117 b = DRMP3_VMUL(b, g_scale);
2118 #if DRMP3_HAVE_SSE
2119 _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)));
2120 _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1)));
2121 _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)));
2122 _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0)));
2123 _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)));
2124 _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3)));
2125 _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)));
2126 _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2)));
2127 #else
2128 vst1q_lane_f32(dstr + (15 - i)*nch, a, 1);
2129 vst1q_lane_f32(dstr + (17 + i)*nch, b, 1);
2130 vst1q_lane_f32(dstl + (15 - i)*nch, a, 0);
2131 vst1q_lane_f32(dstl + (17 + i)*nch, b, 0);
2132 vst1q_lane_f32(dstr + (47 - i)*nch, a, 3);
2133 vst1q_lane_f32(dstr + (49 + i)*nch, b, 3);
2134 vst1q_lane_f32(dstl + (47 - i)*nch, a, 2);
2135 vst1q_lane_f32(dstl + (49 + i)*nch, b, 2);
2136 #endif
2137 #endif /* DR_MP3_FLOAT_OUTPUT */
2138 }
2139 } else
2140 #endif
2141 #ifdef DR_MP3_ONLY_SIMD
2142 {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
2143 #else
2144 for (i = 14; i >= 0; i--)
2145 {
2146 #define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64];
2147 #define DRMP3_S0(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; }
2148 #define DRMP3_S1(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; }
2149 #define DRMP3_S2(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; }
2150 float a[4], b[4];
2151
2152 zlin[4*i] = xl[18*(31 - i)];
2153 zlin[4*i + 1] = xr[18*(31 - i)];
2154 zlin[4*i + 2] = xl[1 + 18*(31 - i)];
2155 zlin[4*i + 3] = xr[1 + 18*(31 - i)];
2156 zlin[4*(i + 16)] = xl[1 + 18*(1 + i)];
2157 zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)];
2158 zlin[4*(i - 16) + 2] = xl[18*(1 + i)];
2159 zlin[4*(i - 16) + 3] = xr[18*(1 + i)];
2160
2161 DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7)
2162
2163 dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]);
2164 dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]);
2165 dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]);
2166 dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]);
2167 dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]);
2168 dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]);
2169 dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]);
2170 dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]);
2171 }
2172 #endif
2173 }
2174
2175 static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, drmp3d_sample_t *pcm, float *lins)
2176 {
2177 int i;
2178 for (i = 0; i < nch; i++)
2179 {
2180 drmp3d_DCT_II(grbuf + 576*i, nbands);
2181 }
2182
2183 DRMP3_COPY_MEMORY(lins, qmf_state, sizeof(float)*15*64);
2184
2185 for (i = 0; i < nbands; i += 2)
2186 {
2187 drmp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64);
2188 }
2189 #ifndef DR_MP3_NONSTANDARD_BUT_LOGICAL
2190 if (nch == 1)
2191 {
2192 for (i = 0; i < 15*64; i += 2)
2193 {
2194 qmf_state[i] = lins[nbands*64 + i];
2195 }
2196 } else
2197 #endif
2198 {
2199 DRMP3_COPY_MEMORY(qmf_state, lins + nbands*64, sizeof(float)*15*64);
2200 }
2201 }
2202
2203 static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes)
2204 {
2205 int i, nmatch;
2206 for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++)
2207 {
2208 i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i);
2209 if (i + DRMP3_HDR_SIZE > mp3_bytes)
2210 return nmatch > 0;
2211 if (!drmp3_hdr_compare(hdr, hdr + i))
2212 return 0;
2213 }
2214 return 1;
2215 }
2216
2217 static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes)
2218 {
2219 int i, k;
2220 for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++)
2221 {
2222 if (drmp3_hdr_valid(mp3))
2223 {
2224 int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes);
2225 int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3);
2226
2227 for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++)
2228 {
2229 if (drmp3_hdr_compare(mp3, mp3 + k))
2230 {
2231 int fb = k - drmp3_hdr_padding(mp3);
2232 int nextfb = fb + drmp3_hdr_padding(mp3 + k);
2233 if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb))
2234 continue;
2235 frame_and_padding = k;
2236 frame_bytes = fb;
2237 *free_format_bytes = fb;
2238 }
2239 }
2240
2241 if ((frame_bytes && i + frame_and_padding <= mp3_bytes &&
2242 drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) ||
2243 (!i && frame_and_padding == mp3_bytes))
2244 {
2245 *ptr_frame_bytes = frame_and_padding;
2246 return i;
2247 }
2248 *free_format_bytes = 0;
2249 }
2250 }
2251 *ptr_frame_bytes = 0;
2252 return mp3_bytes;
2253 }
2254
2255 DRMP3_API void drmp3dec_init(drmp3dec *dec)
2256 {
2257 dec->header[0] = 0;
2258 }
2259
2260 DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info)
2261 {
2262 int i = 0, igr, frame_size = 0, success = 1;
2263 const drmp3_uint8 *hdr;
2264 drmp3_bs bs_frame[1];
2265 drmp3dec_scratch scratch;
2266
2267 if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3))
2268 {
2269 frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3);
2270 if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size)))
2271 {
2272 frame_size = 0;
2273 }
2274 }
2275 if (!frame_size)
2276 {
2277 DRMP3_ZERO_MEMORY(dec, sizeof(drmp3dec));
2278 i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
2279 if (!frame_size || i + frame_size > mp3_bytes)
2280 {
2281 info->frame_bytes = i;
2282 return 0;
2283 }
2284 }
2285
2286 hdr = mp3 + i;
2287 DRMP3_COPY_MEMORY(dec->header, hdr, DRMP3_HDR_SIZE);
2288 info->frame_bytes = i + frame_size;
2289 info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
2290 info->hz = drmp3_hdr_sample_rate_hz(hdr);
2291 info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr);
2292 info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr);
2293
2294 drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE);
2295 if (DRMP3_HDR_IS_CRC(hdr))
2296 {
2297 drmp3_bs_get_bits(bs_frame, 16);
2298 }
2299
2300 if (info->layer == 3)
2301 {
2302 int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr);
2303 if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit)
2304 {
2305 drmp3dec_init(dec);
2306 return 0;
2307 }
2308 success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin);
2309 if (success && pcm != NULL)
2310 {
2311 for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels))
2312 {
2313 DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
2314 drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
2315 drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
2316 }
2317 }
2318 drmp3_L3_save_reservoir(dec, &scratch);
2319 } else
2320 {
2321 #ifdef DR_MP3_ONLY_MP3
2322 return 0;
2323 #else
2324 drmp3_L12_scale_info sci[1];
2325
2326 if (pcm == NULL) {
2327 return drmp3_hdr_frame_samples(hdr);
2328 }
2329
2330 drmp3_L12_read_scale_info(hdr, bs_frame, sci);
2331
2332 DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
2333 for (i = 0, igr = 0; igr < 3; igr++)
2334 {
2335 if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1)))
2336 {
2337 i = 0;
2338 drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
2339 drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
2340 DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
2341 pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels);
2342 }
2343 if (bs_frame->pos > bs_frame->limit)
2344 {
2345 drmp3dec_init(dec);
2346 return 0;
2347 }
2348 }
2349 #endif
2350 }
2351
2352 return success*drmp3_hdr_frame_samples(dec->header);
2353 }
2354
2355 DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples)
2356 {
2357 size_t i = 0;
2358 #if DRMP3_HAVE_SIMD
2359 size_t aligned_count = num_samples & ~7;
2360 for(; i < aligned_count; i+=8)
2361 {
2362 drmp3_f4 scale = DRMP3_VSET(32768.0f);
2363 drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i ]), scale);
2364 drmp3_f4 b = DRMP3_VMUL(DRMP3_VLD(&in[i+4]), scale);
2365 #if DRMP3_HAVE_SSE
2366 drmp3_f4 s16max = DRMP3_VSET( 32767.0f);
2367 drmp3_f4 s16min = DRMP3_VSET(-32768.0f);
2368 __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, s16max), s16min)),
2369 _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, s16max), s16min)));
2370 out[i ] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
2371 out[i+1] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
2372 out[i+2] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
2373 out[i+3] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
2374 out[i+4] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
2375 out[i+5] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
2376 out[i+6] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
2377 out[i+7] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
2378 #else
2379 int16x4_t pcma, pcmb;
2380 a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
2381 b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
2382 pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
2383 pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
2384 vst1_lane_s16(out+i , pcma, 0);
2385 vst1_lane_s16(out+i+1, pcma, 1);
2386 vst1_lane_s16(out+i+2, pcma, 2);
2387 vst1_lane_s16(out+i+3, pcma, 3);
2388 vst1_lane_s16(out+i+4, pcmb, 0);
2389 vst1_lane_s16(out+i+5, pcmb, 1);
2390 vst1_lane_s16(out+i+6, pcmb, 2);
2391 vst1_lane_s16(out+i+7, pcmb, 3);
2392 #endif
2393 }
2394 #endif
2395 for(; i < num_samples; i++)
2396 {
2397 float sample = in[i] * 32768.0f;
2398 if (sample >= 32766.5)
2399 out[i] = (drmp3_int16) 32767;
2400 else if (sample <= -32767.5)
2401 out[i] = (drmp3_int16)-32768;
2402 else
2403 {
2404 short s = (drmp3_int16)(sample + .5f);
2405 s -= (s < 0); /* away from zero, to be compliant */
2406 out[i] = s;
2407 }
2408 }
2409 }
2410
2411
2412
2413 /************************************************************************************************************************************************************
2414
2415 Main Public API
2416
2417 ************************************************************************************************************************************************************/
2418 #if defined(SIZE_MAX)
2419 #define DRMP3_SIZE_MAX SIZE_MAX
2420 #else
2421 #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
2422 #define DRMP3_SIZE_MAX ((drmp3_uint64)0xFFFFFFFFFFFFFFFF)
2423 #else
2424 #define DRMP3_SIZE_MAX 0xFFFFFFFF
2425 #endif
2426 #endif
2427
2428 /* Options. */
2429 #ifndef DRMP3_SEEK_LEADING_MP3_FRAMES
2430 #define DRMP3_SEEK_LEADING_MP3_FRAMES 2
2431 #endif
2432
2433 #define DRMP3_MIN_DATA_CHUNK_SIZE 16384
2434
2435 /* The size in bytes of each chunk of data to read from the MP3 stream. minimp3 recommends at least 16K, but in an attempt to reduce data movement I'm making this slightly larger. */
2436 #ifndef DRMP3_DATA_CHUNK_SIZE
2437 #define DRMP3_DATA_CHUNK_SIZE DRMP3_MIN_DATA_CHUNK_SIZE*4
2438 #endif
2439
2440
2441 #define DRMP3_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
2442 #define DRMP3_CLAMP(x, lo, hi) (DRMP3_MAX(lo, DRMP3_MIN(x, hi)))
2443
2444 #ifndef DRMP3_PI_D
2445 #define DRMP3_PI_D 3.14159265358979323846264
2446 #endif
2447
2448 #define DRMP3_DEFAULT_RESAMPLER_LPF_ORDER 2
2449
2450 static DRMP3_INLINE float drmp3_mix_f32(float x, float y, float a)
2451 {
2452 return x*(1-a) + y*a;
2453 }
2454 static DRMP3_INLINE float drmp3_mix_f32_fast(float x, float y, float a)
2455 {
2456 float r0 = (y - x);
2457 float r1 = r0*a;
2458 return x + r1;
2459 /*return x + (y - x)*a;*/
2460 }
2461
2462
2463 /*
2464 Greatest common factor using Euclid's algorithm iteratively.
2465 */
2466 static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b)
2467 {
2468 for (;;) {
2469 if (b == 0) {
2470 break;
2471 } else {
2472 drmp3_uint32 t = a;
2473 a = b;
2474 b = t % a;
2475 }
2476 }
2477
2478 return a;
2479 }
2480
2481
2482 static void* drmp3__malloc_default(size_t sz, void* pUserData)
2483 {
2484 (void)pUserData;
2485 return DRMP3_MALLOC(sz);
2486 }
2487
2488 static void* drmp3__realloc_default(void* p, size_t sz, void* pUserData)
2489 {
2490 (void)pUserData;
2491 return DRMP3_REALLOC(p, sz);
2492 }
2493
2494 static void drmp3__free_default(void* p, void* pUserData)
2495 {
2496 (void)pUserData;
2497 DRMP3_FREE(p);
2498 }
2499
2500
2501 static void* drmp3__malloc_from_callbacks(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
2502 {
2503 if (pAllocationCallbacks == NULL) {
2504 return NULL;
2505 }
2506
2507 if (pAllocationCallbacks->onMalloc != NULL) {
2508 return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
2509 }
2510
2511 /* Try using realloc(). */
2512 if (pAllocationCallbacks->onRealloc != NULL) {
2513 return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
2514 }
2515
2516 return NULL;
2517 }
2518
2519 static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks)
2520 {
2521 if (pAllocationCallbacks == NULL) {
2522 return NULL;
2523 }
2524
2525 if (pAllocationCallbacks->onRealloc != NULL) {
2526 return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
2527 }
2528
2529 /* Try emulating realloc() in terms of malloc()/free(). */
2530 if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
2531 void* p2;
2532
2533 p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
2534 if (p2 == NULL) {
2535 return NULL;
2536 }
2537
2538 if (p != NULL) {
2539 DRMP3_COPY_MEMORY(p2, p, szOld);
2540 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
2541 }
2542
2543 return p2;
2544 }
2545
2546 return NULL;
2547 }
2548
2549 static void drmp3__free_from_callbacks(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
2550 {
2551 if (p == NULL || pAllocationCallbacks == NULL) {
2552 return;
2553 }
2554
2555 if (pAllocationCallbacks->onFree != NULL) {
2556 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
2557 }
2558 }
2559
2560
2561 static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks)
2562 {
2563 if (pAllocationCallbacks != NULL) {
2564 /* Copy. */
2565 return *pAllocationCallbacks;
2566 } else {
2567 /* Defaults. */
2568 drmp3_allocation_callbacks allocationCallbacks;
2569 allocationCallbacks.pUserData = NULL;
2570 allocationCallbacks.onMalloc = drmp3__malloc_default;
2571 allocationCallbacks.onRealloc = drmp3__realloc_default;
2572 allocationCallbacks.onFree = drmp3__free_default;
2573 return allocationCallbacks;
2574 }
2575 }
2576
2577
2578
2579 static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead)
2580 {
2581 size_t bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead);
2582 pMP3->streamCursor += bytesRead;
2583 return bytesRead;
2584 }
2585
2586 static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin)
2587 {
2588 DRMP3_ASSERT(offset >= 0);
2589
2590 if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) {
2591 return DRMP3_FALSE;
2592 }
2593
2594 if (origin == drmp3_seek_origin_start) {
2595 pMP3->streamCursor = (drmp3_uint64)offset;
2596 } else {
2597 pMP3->streamCursor += offset;
2598 }
2599
2600 return DRMP3_TRUE;
2601 }
2602
2603 static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_seek_origin origin)
2604 {
2605 if (offset <= 0x7FFFFFFF) {
2606 return drmp3__on_seek(pMP3, (int)offset, origin);
2607 }
2608
2609
2610 /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */
2611 if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) {
2612 return DRMP3_FALSE;
2613 }
2614
2615 offset -= 0x7FFFFFFF;
2616 while (offset > 0) {
2617 if (offset <= 0x7FFFFFFF) {
2618 if (!drmp3__on_seek(pMP3, (int)offset, drmp3_seek_origin_current)) {
2619 return DRMP3_FALSE;
2620 }
2621 offset = 0;
2622 } else {
2623 if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) {
2624 return DRMP3_FALSE;
2625 }
2626 offset -= 0x7FFFFFFF;
2627 }
2628 }
2629
2630 return DRMP3_TRUE;
2631 }
2632
2633
2634 static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2635 {
2636 drmp3_uint32 pcmFramesRead = 0;
2637
2638 DRMP3_ASSERT(pMP3 != NULL);
2639 DRMP3_ASSERT(pMP3->onRead != NULL);
2640
2641 if (pMP3->atEnd) {
2642 return 0;
2643 }
2644
2645 for (;;) {
2646 drmp3dec_frame_info info;
2647
2648 /* minimp3 recommends doing data submission in chunks of at least 16K. If we don't have at least 16K bytes available, get more. */
2649 if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) {
2650 size_t bytesRead;
2651
2652 /* First we need to move the data down. */
2653 if (pMP3->pData != NULL) {
2654 DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2655 }
2656
2657 pMP3->dataConsumed = 0;
2658
2659 if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
2660 drmp3_uint8* pNewData;
2661 size_t newDataCap;
2662
2663 newDataCap = DRMP3_DATA_CHUNK_SIZE;
2664
2665 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2666 if (pNewData == NULL) {
2667 return 0; /* Out of memory. */
2668 }
2669
2670 pMP3->pData = pNewData;
2671 pMP3->dataCapacity = newDataCap;
2672 }
2673
2674 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2675 if (bytesRead == 0) {
2676 if (pMP3->dataSize == 0) {
2677 pMP3->atEnd = DRMP3_TRUE;
2678 return 0; /* No data. */
2679 }
2680 }
2681
2682 pMP3->dataSize += bytesRead;
2683 }
2684
2685 if (pMP3->dataSize > INT_MAX) {
2686 pMP3->atEnd = DRMP3_TRUE;
2687 return 0; /* File too big. */
2688 }
2689
2690 DRMP3_ASSERT(pMP3->pData != NULL);
2691 DRMP3_ASSERT(pMP3->dataCapacity > 0);
2692
2693 pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */
2694
2695 /* Consume the data. */
2696 if (info.frame_bytes > 0) {
2697 pMP3->dataConsumed += (size_t)info.frame_bytes;
2698 pMP3->dataSize -= (size_t)info.frame_bytes;
2699 }
2700
2701 /* pcmFramesRead will be equal to 0 if decoding failed. If it is zero and info.frame_bytes > 0 then we have successfully decoded the frame. */
2702 if (pcmFramesRead > 0) {
2703 pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
2704 pMP3->pcmFramesConsumedInMP3Frame = 0;
2705 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2706 pMP3->mp3FrameChannels = info.channels;
2707 pMP3->mp3FrameSampleRate = info.hz;
2708 break;
2709 } else if (info.frame_bytes == 0) {
2710 /* Need more data. minimp3 recommends doing data submission in 16K chunks. */
2711 size_t bytesRead;
2712
2713 /* First we need to move the data down. */
2714 DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2715 pMP3->dataConsumed = 0;
2716
2717 if (pMP3->dataCapacity == pMP3->dataSize) {
2718 /* No room. Expand. */
2719 drmp3_uint8* pNewData;
2720 size_t newDataCap;
2721
2722 newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
2723
2724 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2725 if (pNewData == NULL) {
2726 return 0; /* Out of memory. */
2727 }
2728
2729 pMP3->pData = pNewData;
2730 pMP3->dataCapacity = newDataCap;
2731 }
2732
2733 /* Fill in a chunk. */
2734 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2735 if (bytesRead == 0) {
2736 pMP3->atEnd = DRMP3_TRUE;
2737 return 0; /* Error reading more data. */
2738 }
2739
2740 pMP3->dataSize += bytesRead;
2741 }
2742 };
2743
2744 return pcmFramesRead;
2745 }
2746
2747 static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2748 {
2749 drmp3_uint32 pcmFramesRead = 0;
2750 drmp3dec_frame_info info;
2751
2752 DRMP3_ASSERT(pMP3 != NULL);
2753 DRMP3_ASSERT(pMP3->memory.pData != NULL);
2754
2755 if (pMP3->atEnd) {
2756 return 0;
2757 }
2758
2759 for (;;) {
2760 pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
2761 if (pcmFramesRead > 0) {
2762 pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
2763 pMP3->pcmFramesConsumedInMP3Frame = 0;
2764 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2765 pMP3->mp3FrameChannels = info.channels;
2766 pMP3->mp3FrameSampleRate = info.hz;
2767 break;
2768 } else if (info.frame_bytes > 0) {
2769 /* No frames were read, but it looks like we skipped past one. Read the next MP3 frame. */
2770 pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
2771 } else {
2772 /* Nothing at all was read. Abort. */
2773 break;
2774 }
2775 }
2776
2777 /* Consume the data. */
2778 pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
2779
2780 return pcmFramesRead;
2781 }
2782
2783 static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2784 {
2785 if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
2786 return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames);
2787 } else {
2788 return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames);
2789 }
2790 }
2791
2792 static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
2793 {
2794 DRMP3_ASSERT(pMP3 != NULL);
2795 return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames);
2796 }
2797
2798 #if 0
2799 static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
2800 {
2801 drmp3_uint32 pcmFrameCount;
2802
2803 DRMP3_ASSERT(pMP3 != NULL);
2804
2805 pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL);
2806 if (pcmFrameCount == 0) {
2807 return 0;
2808 }
2809
2810 /* We have essentially just skipped past the frame, so just set the remaining samples to 0. */
2811 pMP3->currentPCMFrame += pcmFrameCount;
2812 pMP3->pcmFramesConsumedInMP3Frame = pcmFrameCount;
2813 pMP3->pcmFramesRemainingInMP3Frame = 0;
2814
2815 return pcmFrameCount;
2816 }
2817 #endif
2818
2819 static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
2820 {
2821 DRMP3_ASSERT(pMP3 != NULL);
2822 DRMP3_ASSERT(onRead != NULL);
2823
2824 /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */
2825 drmp3dec_init(&pMP3->decoder);
2826
2827 pMP3->onRead = onRead;
2828 pMP3->onSeek = onSeek;
2829 pMP3->pUserData = pUserData;
2830 pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
2831
2832 if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
2833 return DRMP3_FALSE; /* Invalid allocation callbacks. */
2834 }
2835
2836 /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */
2837 if (drmp3_decode_next_frame(pMP3) == 0) {
2838 drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */
2839 return DRMP3_FALSE; /* Not a valid MP3 stream. */
2840 }
2841
2842 pMP3->channels = pMP3->mp3FrameChannels;
2843 pMP3->sampleRate = pMP3->mp3FrameSampleRate;
2844
2845 return DRMP3_TRUE;
2846 }
2847
2848 DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
2849 {
2850 if (pMP3 == NULL || onRead == NULL) {
2851 return DRMP3_FALSE;
2852 }
2853
2854 DRMP3_ZERO_OBJECT(pMP3);
2855 return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks);
2856 }
2857
2858
2859 static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
2860 {
2861 drmp3* pMP3 = (drmp3*)pUserData;
2862 size_t bytesRemaining;
2863
2864 DRMP3_ASSERT(pMP3 != NULL);
2865 DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos);
2866
2867 bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos;
2868 if (bytesToRead > bytesRemaining) {
2869 bytesToRead = bytesRemaining;
2870 }
2871
2872 if (bytesToRead > 0) {
2873 DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead);
2874 pMP3->memory.currentReadPos += bytesToRead;
2875 }
2876
2877 return bytesToRead;
2878 }
2879
2880 static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin)
2881 {
2882 drmp3* pMP3 = (drmp3*)pUserData;
2883
2884 DRMP3_ASSERT(pMP3 != NULL);
2885
2886 if (origin == drmp3_seek_origin_current) {
2887 if (byteOffset > 0) {
2888 if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) {
2889 byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */
2890 }
2891 } else {
2892 if (pMP3->memory.currentReadPos < (size_t)-byteOffset) {
2893 byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */
2894 }
2895 }
2896
2897 /* This will never underflow thanks to the clamps above. */
2898 pMP3->memory.currentReadPos += byteOffset;
2899 } else {
2900 if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) {
2901 pMP3->memory.currentReadPos = byteOffset;
2902 } else {
2903 pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */
2904 }
2905 }
2906
2907 return DRMP3_TRUE;
2908 }
2909
2910 DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks)
2911 {
2912 if (pMP3 == NULL) {
2913 return DRMP3_FALSE;
2914 }
2915
2916 DRMP3_ZERO_OBJECT(pMP3);
2917
2918 if (pData == NULL || dataSize == 0) {
2919 return DRMP3_FALSE;
2920 }
2921
2922 pMP3->memory.pData = (const drmp3_uint8*)pData;
2923 pMP3->memory.dataSize = dataSize;
2924 pMP3->memory.currentReadPos = 0;
2925
2926 return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pAllocationCallbacks);
2927 }
2928
2929
2930 #ifndef DR_MP3_NO_STDIO
2931 #include <stdio.h>
2932 #include <wchar.h> /* For wcslen(), wcsrtombs() */
2933
2934 /* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */
2935 #include <errno.h>
2936 static drmp3_result drmp3_result_from_errno(int e)
2937 {
2938 switch (e)
2939 {
2940 case 0: return DRMP3_SUCCESS;
2941 #ifdef EPERM
2942 case EPERM: return DRMP3_INVALID_OPERATION;
2943 #endif
2944 #ifdef ENOENT
2945 case ENOENT: return DRMP3_DOES_NOT_EXIST;
2946 #endif
2947 #ifdef ESRCH
2948 case ESRCH: return DRMP3_DOES_NOT_EXIST;
2949 #endif
2950 #ifdef EINTR
2951 case EINTR: return DRMP3_INTERRUPT;
2952 #endif
2953 #ifdef EIO
2954 case EIO: return DRMP3_IO_ERROR;
2955 #endif
2956 #ifdef ENXIO
2957 case ENXIO: return DRMP3_DOES_NOT_EXIST;
2958 #endif
2959 #ifdef E2BIG
2960 case E2BIG: return DRMP3_INVALID_ARGS;
2961 #endif
2962 #ifdef ENOEXEC
2963 case ENOEXEC: return DRMP3_INVALID_FILE;
2964 #endif
2965 #ifdef EBADF
2966 case EBADF: return DRMP3_INVALID_FILE;
2967 #endif
2968 #ifdef ECHILD
2969 case ECHILD: return DRMP3_ERROR;
2970 #endif
2971 #ifdef EAGAIN
2972 case EAGAIN: return DRMP3_UNAVAILABLE;
2973 #endif
2974 #ifdef ENOMEM
2975 case ENOMEM: return DRMP3_OUT_OF_MEMORY;
2976 #endif
2977 #ifdef EACCES
2978 case EACCES: return DRMP3_ACCESS_DENIED;
2979 #endif
2980 #ifdef EFAULT
2981 case EFAULT: return DRMP3_BAD_ADDRESS;
2982 #endif
2983 #ifdef ENOTBLK
2984 case ENOTBLK: return DRMP3_ERROR;
2985 #endif
2986 #ifdef EBUSY
2987 case EBUSY: return DRMP3_BUSY;
2988 #endif
2989 #ifdef EEXIST
2990 case EEXIST: return DRMP3_ALREADY_EXISTS;
2991 #endif
2992 #ifdef EXDEV
2993 case EXDEV: return DRMP3_ERROR;
2994 #endif
2995 #ifdef ENODEV
2996 case ENODEV: return DRMP3_DOES_NOT_EXIST;
2997 #endif
2998 #ifdef ENOTDIR
2999 case ENOTDIR: return DRMP3_NOT_DIRECTORY;
3000 #endif
3001 #ifdef EISDIR
3002 case EISDIR: return DRMP3_IS_DIRECTORY;
3003 #endif
3004 #ifdef EINVAL
3005 case EINVAL: return DRMP3_INVALID_ARGS;
3006 #endif
3007 #ifdef ENFILE
3008 case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES;
3009 #endif
3010 #ifdef EMFILE
3011 case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES;
3012 #endif
3013 #ifdef ENOTTY
3014 case ENOTTY: return DRMP3_INVALID_OPERATION;
3015 #endif
3016 #ifdef ETXTBSY
3017 case ETXTBSY: return DRMP3_BUSY;
3018 #endif
3019 #ifdef EFBIG
3020 case EFBIG: return DRMP3_TOO_BIG;
3021 #endif
3022 #ifdef ENOSPC
3023 case ENOSPC: return DRMP3_NO_SPACE;
3024 #endif
3025 #ifdef ESPIPE
3026 case ESPIPE: return DRMP3_BAD_SEEK;
3027 #endif
3028 #ifdef EROFS
3029 case EROFS: return DRMP3_ACCESS_DENIED;
3030 #endif
3031 #ifdef EMLINK
3032 case EMLINK: return DRMP3_TOO_MANY_LINKS;
3033 #endif
3034 #ifdef EPIPE
3035 case EPIPE: return DRMP3_BAD_PIPE;
3036 #endif
3037 #ifdef EDOM
3038 case EDOM: return DRMP3_OUT_OF_RANGE;
3039 #endif
3040 #ifdef ERANGE
3041 case ERANGE: return DRMP3_OUT_OF_RANGE;
3042 #endif
3043 #ifdef EDEADLK
3044 case EDEADLK: return DRMP3_DEADLOCK;
3045 #endif
3046 #ifdef ENAMETOOLONG
3047 case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG;
3048 #endif
3049 #ifdef ENOLCK
3050 case ENOLCK: return DRMP3_ERROR;
3051 #endif
3052 #ifdef ENOSYS
3053 case ENOSYS: return DRMP3_NOT_IMPLEMENTED;
3054 #endif
3055 #ifdef ENOTEMPTY
3056 case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY;
3057 #endif
3058 #ifdef ELOOP
3059 case ELOOP: return DRMP3_TOO_MANY_LINKS;
3060 #endif
3061 #ifdef ENOMSG
3062 case ENOMSG: return DRMP3_NO_MESSAGE;
3063 #endif
3064 #ifdef EIDRM
3065 case EIDRM: return DRMP3_ERROR;
3066 #endif
3067 #ifdef ECHRNG
3068 case ECHRNG: return DRMP3_ERROR;
3069 #endif
3070 #ifdef EL2NSYNC
3071 case EL2NSYNC: return DRMP3_ERROR;
3072 #endif
3073 #ifdef EL3HLT
3074 case EL3HLT: return DRMP3_ERROR;
3075 #endif
3076 #ifdef EL3RST
3077 case EL3RST: return DRMP3_ERROR;
3078 #endif
3079 #ifdef ELNRNG
3080 case ELNRNG: return DRMP3_OUT_OF_RANGE;
3081 #endif
3082 #ifdef EUNATCH
3083 case EUNATCH: return DRMP3_ERROR;
3084 #endif
3085 #ifdef ENOCSI
3086 case ENOCSI: return DRMP3_ERROR;
3087 #endif
3088 #ifdef EL2HLT
3089 case EL2HLT: return DRMP3_ERROR;
3090 #endif
3091 #ifdef EBADE
3092 case EBADE: return DRMP3_ERROR;
3093 #endif
3094 #ifdef EBADR
3095 case EBADR: return DRMP3_ERROR;
3096 #endif
3097 #ifdef EXFULL
3098 case EXFULL: return DRMP3_ERROR;
3099 #endif
3100 #ifdef ENOANO
3101 case ENOANO: return DRMP3_ERROR;
3102 #endif
3103 #ifdef EBADRQC
3104 case EBADRQC: return DRMP3_ERROR;
3105 #endif
3106 #ifdef EBADSLT
3107 case EBADSLT: return DRMP3_ERROR;
3108 #endif
3109 #ifdef EBFONT
3110 case EBFONT: return DRMP3_INVALID_FILE;
3111 #endif
3112 #ifdef ENOSTR
3113 case ENOSTR: return DRMP3_ERROR;
3114 #endif
3115 #ifdef ENODATA
3116 case ENODATA: return DRMP3_NO_DATA_AVAILABLE;
3117 #endif
3118 #ifdef ETIME
3119 case ETIME: return DRMP3_TIMEOUT;
3120 #endif
3121 #ifdef ENOSR
3122 case ENOSR: return DRMP3_NO_DATA_AVAILABLE;
3123 #endif
3124 #ifdef ENONET
3125 case ENONET: return DRMP3_NO_NETWORK;
3126 #endif
3127 #ifdef ENOPKG
3128 case ENOPKG: return DRMP3_ERROR;
3129 #endif
3130 #ifdef EREMOTE
3131 case EREMOTE: return DRMP3_ERROR;
3132 #endif
3133 #ifdef ENOLINK
3134 case ENOLINK: return DRMP3_ERROR;
3135 #endif
3136 #ifdef EADV
3137 case EADV: return DRMP3_ERROR;
3138 #endif
3139 #ifdef ESRMNT
3140 case ESRMNT: return DRMP3_ERROR;
3141 #endif
3142 #ifdef ECOMM
3143 case ECOMM: return DRMP3_ERROR;
3144 #endif
3145 #ifdef EPROTO
3146 case EPROTO: return DRMP3_ERROR;
3147 #endif
3148 #ifdef EMULTIHOP
3149 case EMULTIHOP: return DRMP3_ERROR;
3150 #endif
3151 #ifdef EDOTDOT
3152 case EDOTDOT: return DRMP3_ERROR;
3153 #endif
3154 #ifdef EBADMSG
3155 case EBADMSG: return DRMP3_BAD_MESSAGE;
3156 #endif
3157 #ifdef EOVERFLOW
3158 case EOVERFLOW: return DRMP3_TOO_BIG;
3159 #endif
3160 #ifdef ENOTUNIQ
3161 case ENOTUNIQ: return DRMP3_NOT_UNIQUE;
3162 #endif
3163 #ifdef EBADFD
3164 case EBADFD: return DRMP3_ERROR;
3165 #endif
3166 #ifdef EREMCHG
3167 case EREMCHG: return DRMP3_ERROR;
3168 #endif
3169 #ifdef ELIBACC
3170 case ELIBACC: return DRMP3_ACCESS_DENIED;
3171 #endif
3172 #ifdef ELIBBAD
3173 case ELIBBAD: return DRMP3_INVALID_FILE;
3174 #endif
3175 #ifdef ELIBSCN
3176 case ELIBSCN: return DRMP3_INVALID_FILE;
3177 #endif
3178 #ifdef ELIBMAX
3179 case ELIBMAX: return DRMP3_ERROR;
3180 #endif
3181 #ifdef ELIBEXEC
3182 case ELIBEXEC: return DRMP3_ERROR;
3183 #endif
3184 #ifdef EILSEQ
3185 case EILSEQ: return DRMP3_INVALID_DATA;
3186 #endif
3187 #ifdef ERESTART
3188 case ERESTART: return DRMP3_ERROR;
3189 #endif
3190 #ifdef ESTRPIPE
3191 case ESTRPIPE: return DRMP3_ERROR;
3192 #endif
3193 #ifdef EUSERS
3194 case EUSERS: return DRMP3_ERROR;
3195 #endif
3196 #ifdef ENOTSOCK
3197 case ENOTSOCK: return DRMP3_NOT_SOCKET;
3198 #endif
3199 #ifdef EDESTADDRREQ
3200 case EDESTADDRREQ: return DRMP3_NO_ADDRESS;
3201 #endif
3202 #ifdef EMSGSIZE
3203 case EMSGSIZE: return DRMP3_TOO_BIG;
3204 #endif
3205 #ifdef EPROTOTYPE
3206 case EPROTOTYPE: return DRMP3_BAD_PROTOCOL;
3207 #endif
3208 #ifdef ENOPROTOOPT
3209 case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE;
3210 #endif
3211 #ifdef EPROTONOSUPPORT
3212 case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED;
3213 #endif
3214 #ifdef ESOCKTNOSUPPORT
3215 case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED;
3216 #endif
3217 #ifdef EOPNOTSUPP
3218 case EOPNOTSUPP: return DRMP3_INVALID_OPERATION;
3219 #endif
3220 #ifdef EPFNOSUPPORT
3221 case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED;
3222 #endif
3223 #ifdef EAFNOSUPPORT
3224 case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED;
3225 #endif
3226 #ifdef EADDRINUSE
3227 case EADDRINUSE: return DRMP3_ALREADY_IN_USE;
3228 #endif
3229 #ifdef EADDRNOTAVAIL
3230 case EADDRNOTAVAIL: return DRMP3_ERROR;
3231 #endif
3232 #ifdef ENETDOWN
3233 case ENETDOWN: return DRMP3_NO_NETWORK;
3234 #endif
3235 #ifdef ENETUNREACH
3236 case ENETUNREACH: return DRMP3_NO_NETWORK;
3237 #endif
3238 #ifdef ENETRESET
3239 case ENETRESET: return DRMP3_NO_NETWORK;
3240 #endif
3241 #ifdef ECONNABORTED
3242 case ECONNABORTED: return DRMP3_NO_NETWORK;
3243 #endif
3244 #ifdef ECONNRESET
3245 case ECONNRESET: return DRMP3_CONNECTION_RESET;
3246 #endif
3247 #ifdef ENOBUFS
3248 case ENOBUFS: return DRMP3_NO_SPACE;
3249 #endif
3250 #ifdef EISCONN
3251 case EISCONN: return DRMP3_ALREADY_CONNECTED;
3252 #endif
3253 #ifdef ENOTCONN
3254 case ENOTCONN: return DRMP3_NOT_CONNECTED;
3255 #endif
3256 #ifdef ESHUTDOWN
3257 case ESHUTDOWN: return DRMP3_ERROR;
3258 #endif
3259 #ifdef ETOOMANYREFS
3260 case ETOOMANYREFS: return DRMP3_ERROR;
3261 #endif
3262 #ifdef ETIMEDOUT
3263 case ETIMEDOUT: return DRMP3_TIMEOUT;
3264 #endif
3265 #ifdef ECONNREFUSED
3266 case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED;
3267 #endif
3268 #ifdef EHOSTDOWN
3269 case EHOSTDOWN: return DRMP3_NO_HOST;
3270 #endif
3271 #ifdef EHOSTUNREACH
3272 case EHOSTUNREACH: return DRMP3_NO_HOST;
3273 #endif
3274 #ifdef EALREADY
3275 case EALREADY: return DRMP3_IN_PROGRESS;
3276 #endif
3277 #ifdef EINPROGRESS
3278 case EINPROGRESS: return DRMP3_IN_PROGRESS;
3279 #endif
3280 #ifdef ESTALE
3281 case ESTALE: return DRMP3_INVALID_FILE;
3282 #endif
3283 #ifdef EUCLEAN
3284 case EUCLEAN: return DRMP3_ERROR;
3285 #endif
3286 #ifdef ENOTNAM
3287 case ENOTNAM: return DRMP3_ERROR;
3288 #endif
3289 #ifdef ENAVAIL
3290 case ENAVAIL: return DRMP3_ERROR;
3291 #endif
3292 #ifdef EISNAM
3293 case EISNAM: return DRMP3_ERROR;
3294 #endif
3295 #ifdef EREMOTEIO
3296 case EREMOTEIO: return DRMP3_IO_ERROR;
3297 #endif
3298 #ifdef EDQUOT
3299 case EDQUOT: return DRMP3_NO_SPACE;
3300 #endif
3301 #ifdef ENOMEDIUM
3302 case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST;
3303 #endif
3304 #ifdef EMEDIUMTYPE
3305 case EMEDIUMTYPE: return DRMP3_ERROR;
3306 #endif
3307 #ifdef ECANCELED
3308 case ECANCELED: return DRMP3_CANCELLED;
3309 #endif
3310 #ifdef ENOKEY
3311 case ENOKEY: return DRMP3_ERROR;
3312 #endif
3313 #ifdef EKEYEXPIRED
3314 case EKEYEXPIRED: return DRMP3_ERROR;
3315 #endif
3316 #ifdef EKEYREVOKED
3317 case EKEYREVOKED: return DRMP3_ERROR;
3318 #endif
3319 #ifdef EKEYREJECTED
3320 case EKEYREJECTED: return DRMP3_ERROR;
3321 #endif
3322 #ifdef EOWNERDEAD
3323 case EOWNERDEAD: return DRMP3_ERROR;
3324 #endif
3325 #ifdef ENOTRECOVERABLE
3326 case ENOTRECOVERABLE: return DRMP3_ERROR;
3327 #endif
3328 #ifdef ERFKILL
3329 case ERFKILL: return DRMP3_ERROR;
3330 #endif
3331 #ifdef EHWPOISON
3332 case EHWPOISON: return DRMP3_ERROR;
3333 #endif
3334 default: return DRMP3_ERROR;
3335 }
3336 }
3337
3338 static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
3339 {
3340 #if defined(_MSC_VER) && _MSC_VER >= 1400
3341 errno_t err;
3342 #endif
3343
3344 if (ppFile != NULL) {
3345 *ppFile = NULL; /* Safety. */
3346 }
3347
3348 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3349 return DRMP3_INVALID_ARGS;
3350 }
3351
3352 #if defined(_MSC_VER) && _MSC_VER >= 1400
3353 err = fopen_s(ppFile, pFilePath, pOpenMode);
3354 if (err != 0) {
3355 return drmp3_result_from_errno(err);
3356 }
3357 #else
3358 #if defined(_WIN32) || defined(__APPLE__)
3359 *ppFile = fopen(pFilePath, pOpenMode);
3360 #else
3361 #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
3362 *ppFile = fopen64(pFilePath, pOpenMode);
3363 #else
3364 *ppFile = fopen(pFilePath, pOpenMode);
3365 #endif
3366 #endif
3367 if (*ppFile == NULL) {
3368 drmp3_result result = drmp3_result_from_errno(errno);
3369 if (result == DRMP3_SUCCESS) {
3370 result = DRMP3_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */
3371 }
3372
3373 return result;
3374 }
3375 #endif
3376
3377 return DRMP3_SUCCESS;
3378 }
3379
3380 /*
3381 _wfopen() isn't always available in all compilation environments.
3382
3383 * Windows only.
3384 * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
3385 * MinGW-64 (both 32- and 64-bit) seems to support it.
3386 * MinGW wraps it in !defined(__STRICT_ANSI__).
3387 * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
3388
3389 This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
3390 fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
3391 */
3392 #if defined(_WIN32)
3393 #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
3394 #define DRMP3_HAS_WFOPEN
3395 #endif
3396 #endif
3397
3398 static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks)
3399 {
3400 if (ppFile != NULL) {
3401 *ppFile = NULL; /* Safety. */
3402 }
3403
3404 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3405 return DRMP3_INVALID_ARGS;
3406 }
3407
3408 #if defined(DRMP3_HAS_WFOPEN)
3409 {
3410 /* Use _wfopen() on Windows. */
3411 #if defined(_MSC_VER) && _MSC_VER >= 1400
3412 errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
3413 if (err != 0) {
3414 return drmp3_result_from_errno(err);
3415 }
3416 #else
3417 *ppFile = _wfopen(pFilePath, pOpenMode);
3418 if (*ppFile == NULL) {
3419 return drmp3_result_from_errno(errno);
3420 }
3421 #endif
3422 (void)pAllocationCallbacks;
3423 }
3424 #else
3425 /*
3426 Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
3427 think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
3428 maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
3429 */
3430 {
3431 mbstate_t mbs;
3432 size_t lenMB;
3433 const wchar_t* pFilePathTemp = pFilePath;
3434 char* pFilePathMB = NULL;
3435 char pOpenModeMB[32] = {0};
3436
3437 /* Get the length first. */
3438 DRMP3_ZERO_OBJECT(&mbs);
3439 lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
3440 if (lenMB == (size_t)-1) {
3441 return drmp3_result_from_errno(errno);
3442 }
3443
3444 pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
3445 if (pFilePathMB == NULL) {
3446 return DRMP3_OUT_OF_MEMORY;
3447 }
3448
3449 pFilePathTemp = pFilePath;
3450 DRMP3_ZERO_OBJECT(&mbs);
3451 wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
3452
3453 /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
3454 {
3455 size_t i = 0;
3456 for (;;) {
3457 if (pOpenMode[i] == 0) {
3458 pOpenModeMB[i] = '\0';
3459 break;
3460 }
3461
3462 pOpenModeMB[i] = (char)pOpenMode[i];
3463 i += 1;
3464 }
3465 }
3466
3467 *ppFile = fopen(pFilePathMB, pOpenModeMB);
3468
3469 drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
3470 }
3471
3472 if (*ppFile == NULL) {
3473 return DRMP3_ERROR;
3474 }
3475 #endif
3476
3477 return DRMP3_SUCCESS;
3478 }
3479
3480
3481
3482 static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
3483 {
3484 return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
3485 }
3486
3487 static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin)
3488 {
3489 return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
3490 }
3491
3492 DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
3493 {
3494 drmp3_bool32 result;
3495 FILE* pFile;
3496
3497 if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) {
3498 return DRMP3_FALSE;
3499 }
3500
3501 result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
3502 if (result != DRMP3_TRUE) {
3503 fclose(pFile);
3504 return result;
3505 }
3506
3507 return DRMP3_TRUE;
3508 }
3509
3510 DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
3511 {
3512 drmp3_bool32 result;
3513 FILE* pFile;
3514
3515 if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) {
3516 return DRMP3_FALSE;
3517 }
3518
3519 result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
3520 if (result != DRMP3_TRUE) {
3521 fclose(pFile);
3522 return result;
3523 }
3524
3525 return DRMP3_TRUE;
3526 }
3527 #endif
3528
3529 DRMP3_API void drmp3_uninit(drmp3* pMP3)
3530 {
3531 if (pMP3 == NULL) {
3532 return;
3533 }
3534
3535 #ifndef DR_MP3_NO_STDIO
3536 if (pMP3->onRead == drmp3__on_read_stdio) {
3537 FILE* pFile = (FILE*)pMP3->pUserData;
3538 if (pFile != NULL) {
3539 fclose(pFile);
3540 pMP3->pUserData = NULL; /* Make sure the file handle is cleared to NULL to we don't attempt to close it a second time. */
3541 }
3542 }
3543 #endif
3544
3545 drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
3546 }
3547
3548 #if defined(DR_MP3_FLOAT_OUTPUT)
3549 static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount)
3550 {
3551 drmp3_uint64 i;
3552 drmp3_uint64 i4;
3553 drmp3_uint64 sampleCount4;
3554
3555 /* Unrolled. */
3556 i = 0;
3557 sampleCount4 = sampleCount >> 2;
3558 for (i4 = 0; i4 < sampleCount4; i4 += 1) {
3559 float x0 = src[i+0];
3560 float x1 = src[i+1];
3561 float x2 = src[i+2];
3562 float x3 = src[i+3];
3563
3564 x0 = ((x0 < -1) ? -1 : ((x0 > 1) ? 1 : x0));
3565 x1 = ((x1 < -1) ? -1 : ((x1 > 1) ? 1 : x1));
3566 x2 = ((x2 < -1) ? -1 : ((x2 > 1) ? 1 : x2));
3567 x3 = ((x3 < -1) ? -1 : ((x3 > 1) ? 1 : x3));
3568
3569 x0 = x0 * 32767.0f;
3570 x1 = x1 * 32767.0f;
3571 x2 = x2 * 32767.0f;
3572 x3 = x3 * 32767.0f;
3573
3574 dst[i+0] = (drmp3_int16)x0;
3575 dst[i+1] = (drmp3_int16)x1;
3576 dst[i+2] = (drmp3_int16)x2;
3577 dst[i+3] = (drmp3_int16)x3;
3578
3579 i += 4;
3580 }
3581
3582 /* Leftover. */
3583 for (; i < sampleCount; i += 1) {
3584 float x = src[i];
3585 x = ((x < -1) ? -1 : ((x > 1) ? 1 : x)); /* clip */
3586 x = x * 32767.0f; /* -1..1 to -32767..32767 */
3587
3588 dst[i] = (drmp3_int16)x;
3589 }
3590 }
3591 #endif
3592
3593 #if !defined(DR_MP3_FLOAT_OUTPUT)
3594 static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
3595 {
3596 drmp3_uint64 i;
3597 for (i = 0; i < sampleCount; i += 1) {
3598 float x = (float)src[i];
3599 x = x * 0.000030517578125f; /* -32768..32767 to -1..0.999969482421875 */
3600 dst[i] = x;
3601 }
3602 }
3603 #endif
3604
3605
3606 static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut)
3607 {
3608 drmp3_uint64 totalFramesRead = 0;
3609
3610 DRMP3_ASSERT(pMP3 != NULL);
3611 DRMP3_ASSERT(pMP3->onRead != NULL);
3612
3613 while (framesToRead > 0) {
3614 drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
3615 if (pBufferOut != NULL) {
3616 #if defined(DR_MP3_FLOAT_OUTPUT)
3617 /* f32 */
3618 float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
3619 float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
3620 DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
3621 #else
3622 /* s16 */
3623 drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels);
3624 drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
3625 DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
3626 #endif
3627 }
3628
3629 pMP3->currentPCMFrame += framesToConsume;
3630 pMP3->pcmFramesConsumedInMP3Frame += framesToConsume;
3631 pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume;
3632 totalFramesRead += framesToConsume;
3633 framesToRead -= framesToConsume;
3634
3635 if (framesToRead == 0) {
3636 break;
3637 }
3638
3639 DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
3640
3641 /*
3642 At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed
3643 at this point which means we'll also need to update our sample rate conversion pipeline.
3644 */
3645 if (drmp3_decode_next_frame(pMP3) == 0) {
3646 break;
3647 }
3648 }
3649
3650 return totalFramesRead;
3651 }
3652
3653
3654 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
3655 {
3656 if (pMP3 == NULL || pMP3->onRead == NULL) {
3657 return 0;
3658 }
3659
3660 #if defined(DR_MP3_FLOAT_OUTPUT)
3661 /* Fast path. No conversion required. */
3662 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
3663 #else
3664 /* Slow path. Convert from s16 to f32. */
3665 {
3666 drmp3_int16 pTempS16[8192];
3667 drmp3_uint64 totalPCMFramesRead = 0;
3668
3669 while (totalPCMFramesRead < framesToRead) {
3670 drmp3_uint64 framesJustRead;
3671 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
3672 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
3673 if (framesToReadNow > framesRemaining) {
3674 framesToReadNow = framesRemaining;
3675 }
3676
3677 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16);
3678 if (framesJustRead == 0) {
3679 break;
3680 }
3681
3682 drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
3683 totalPCMFramesRead += framesJustRead;
3684 }
3685
3686 return totalPCMFramesRead;
3687 }
3688 #endif
3689 }
3690
3691 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut)
3692 {
3693 if (pMP3 == NULL || pMP3->onRead == NULL) {
3694 return 0;
3695 }
3696
3697 #if !defined(DR_MP3_FLOAT_OUTPUT)
3698 /* Fast path. No conversion required. */
3699 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
3700 #else
3701 /* Slow path. Convert from f32 to s16. */
3702 {
3703 float pTempF32[4096];
3704 drmp3_uint64 totalPCMFramesRead = 0;
3705
3706 while (totalPCMFramesRead < framesToRead) {
3707 drmp3_uint64 framesJustRead;
3708 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
3709 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
3710 if (framesToReadNow > framesRemaining) {
3711 framesToReadNow = framesRemaining;
3712 }
3713
3714 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32);
3715 if (framesJustRead == 0) {
3716 break;
3717 }
3718
3719 drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
3720 totalPCMFramesRead += framesJustRead;
3721 }
3722
3723 return totalPCMFramesRead;
3724 }
3725 #endif
3726 }
3727
3728 static void drmp3_reset(drmp3* pMP3)
3729 {
3730 DRMP3_ASSERT(pMP3 != NULL);
3731
3732 pMP3->pcmFramesConsumedInMP3Frame = 0;
3733 pMP3->pcmFramesRemainingInMP3Frame = 0;
3734 pMP3->currentPCMFrame = 0;
3735 pMP3->dataSize = 0;
3736 pMP3->atEnd = DRMP3_FALSE;
3737 drmp3dec_init(&pMP3->decoder);
3738 }
3739
3740 static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
3741 {
3742 DRMP3_ASSERT(pMP3 != NULL);
3743 DRMP3_ASSERT(pMP3->onSeek != NULL);
3744
3745 /* Seek to the start of the stream to begin with. */
3746 if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
3747 return DRMP3_FALSE;
3748 }
3749
3750 /* Clear any cached data. */
3751 drmp3_reset(pMP3);
3752 return DRMP3_TRUE;
3753 }
3754
3755
3756 static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset)
3757 {
3758 drmp3_uint64 framesRead;
3759
3760 /*
3761 Just using a dumb read-and-discard for now. What would be nice is to parse only the header of the MP3 frame, and then skip over leading
3762 frames without spending the time doing a full decode. I cannot see an easy way to do this in minimp3, however, so it may involve some
3763 kind of manual processing.
3764 */
3765 #if defined(DR_MP3_FLOAT_OUTPUT)
3766 framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
3767 #else
3768 framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL);
3769 #endif
3770 if (framesRead != frameOffset) {
3771 return DRMP3_FALSE;
3772 }
3773
3774 return DRMP3_TRUE;
3775 }
3776
3777 static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
3778 {
3779 DRMP3_ASSERT(pMP3 != NULL);
3780
3781 if (frameIndex == pMP3->currentPCMFrame) {
3782 return DRMP3_TRUE;
3783 }
3784
3785 /*
3786 If we're moving foward we just read from where we're at. Otherwise we need to move back to the start of
3787 the stream and read from the beginning.
3788 */
3789 if (frameIndex < pMP3->currentPCMFrame) {
3790 /* Moving backward. Move to the start of the stream and then move forward. */
3791 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3792 return DRMP3_FALSE;
3793 }
3794 }
3795
3796 DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
3797 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
3798 }
3799
3800 static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex)
3801 {
3802 drmp3_uint32 iSeekPoint;
3803
3804 DRMP3_ASSERT(pSeekPointIndex != NULL);
3805
3806 *pSeekPointIndex = 0;
3807
3808 if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) {
3809 return DRMP3_FALSE;
3810 }
3811
3812 /* Linear search for simplicity to begin with while I'm getting this thing working. Once it's all working change this to a binary search. */
3813 for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) {
3814 if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) {
3815 break; /* Found it. */
3816 }
3817
3818 *pSeekPointIndex = iSeekPoint;
3819 }
3820
3821 return DRMP3_TRUE;
3822 }
3823
3824 static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex)
3825 {
3826 drmp3_seek_point seekPoint;
3827 drmp3_uint32 priorSeekPointIndex;
3828 drmp3_uint16 iMP3Frame;
3829 drmp3_uint64 leftoverFrames;
3830
3831 DRMP3_ASSERT(pMP3 != NULL);
3832 DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
3833 DRMP3_ASSERT(pMP3->seekPointCount > 0);
3834
3835 /* If there is no prior seekpoint it means the target PCM frame comes before the first seek point. Just assume a seekpoint at the start of the file in this case. */
3836 if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
3837 seekPoint = pMP3->pSeekPoints[priorSeekPointIndex];
3838 } else {
3839 seekPoint.seekPosInBytes = 0;
3840 seekPoint.pcmFrameIndex = 0;
3841 seekPoint.mp3FramesToDiscard = 0;
3842 seekPoint.pcmFramesToDiscard = 0;
3843 }
3844
3845 /* First thing to do is seek to the first byte of the relevant MP3 frame. */
3846 if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) {
3847 return DRMP3_FALSE; /* Failed to seek. */
3848 }
3849
3850 /* Clear any cached data. */
3851 drmp3_reset(pMP3);
3852
3853 /* Whole MP3 frames need to be discarded first. */
3854 for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) {
3855 drmp3_uint32 pcmFramesRead;
3856 drmp3d_sample_t* pPCMFrames;
3857
3858 /* Pass in non-null for the last frame because we want to ensure the sample rate converter is preloaded correctly. */
3859 pPCMFrames = NULL;
3860 if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
3861 pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames;
3862 }
3863
3864 /* We first need to decode the next frame. */
3865 pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames);
3866 if (pcmFramesRead == 0) {
3867 return DRMP3_FALSE;
3868 }
3869 }
3870
3871 /* We seeked to an MP3 frame in the raw stream so we need to make sure the current PCM frame is set correctly. */
3872 pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard;
3873
3874 /*
3875 Now at this point we can follow the same process as the brute force technique where we just skip over unnecessary MP3 frames and then
3876 read-and-discard at least 2 whole MP3 frames.
3877 */
3878 leftoverFrames = frameIndex - pMP3->currentPCMFrame;
3879 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames);
3880 }
3881
3882 DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex)
3883 {
3884 if (pMP3 == NULL || pMP3->onSeek == NULL) {
3885 return DRMP3_FALSE;
3886 }
3887
3888 if (frameIndex == 0) {
3889 return drmp3_seek_to_start_of_stream(pMP3);
3890 }
3891
3892 /* Use the seek table if we have one. */
3893 if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) {
3894 return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex);
3895 } else {
3896 return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex);
3897 }
3898 }
3899
3900 DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
3901 {
3902 drmp3_uint64 currentPCMFrame;
3903 drmp3_uint64 totalPCMFrameCount;
3904 drmp3_uint64 totalMP3FrameCount;
3905
3906 if (pMP3 == NULL) {
3907 return DRMP3_FALSE;
3908 }
3909
3910 /*
3911 The way this works is we move back to the start of the stream, iterate over each MP3 frame and calculate the frame count based
3912 on our output sample rate, the seek back to the PCM frame we were sitting on before calling this function.
3913 */
3914
3915 /* The stream must support seeking for this to work. */
3916 if (pMP3->onSeek == NULL) {
3917 return DRMP3_FALSE;
3918 }
3919
3920 /* We'll need to seek back to where we were, so grab the PCM frame we're currently sitting on so we can restore later. */
3921 currentPCMFrame = pMP3->currentPCMFrame;
3922
3923 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3924 return DRMP3_FALSE;
3925 }
3926
3927 totalPCMFrameCount = 0;
3928 totalMP3FrameCount = 0;
3929
3930 for (;;) {
3931 drmp3_uint32 pcmFramesInCurrentMP3Frame;
3932
3933 pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL);
3934 if (pcmFramesInCurrentMP3Frame == 0) {
3935 break;
3936 }
3937
3938 totalPCMFrameCount += pcmFramesInCurrentMP3Frame;
3939 totalMP3FrameCount += 1;
3940 }
3941
3942 /* Finally, we need to seek back to where we were. */
3943 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3944 return DRMP3_FALSE;
3945 }
3946
3947 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
3948 return DRMP3_FALSE;
3949 }
3950
3951 if (pMP3FrameCount != NULL) {
3952 *pMP3FrameCount = totalMP3FrameCount;
3953 }
3954 if (pPCMFrameCount != NULL) {
3955 *pPCMFrameCount = totalPCMFrameCount;
3956 }
3957
3958 return DRMP3_TRUE;
3959 }
3960
3961 DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3)
3962 {
3963 drmp3_uint64 totalPCMFrameCount;
3964 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
3965 return 0;
3966 }
3967
3968 return totalPCMFrameCount;
3969 }
3970
3971 DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3)
3972 {
3973 drmp3_uint64 totalMP3FrameCount;
3974 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) {
3975 return 0;
3976 }
3977
3978 return totalMP3FrameCount;
3979 }
3980
3981 static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
3982 {
3983 float srcRatio;
3984 float pcmFrameCountOutF;
3985 drmp3_uint32 pcmFrameCountOut;
3986
3987 srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
3988 DRMP3_ASSERT(srcRatio > 0);
3989
3990 pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
3991 pcmFrameCountOut = (drmp3_uint32)pcmFrameCountOutF;
3992 *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut;
3993 *pRunningPCMFrameCount += pcmFrameCountOut;
3994 }
3995
3996 typedef struct
3997 {
3998 drmp3_uint64 bytePos;
3999 drmp3_uint64 pcmFrameIndex; /* <-- After sample rate conversion. */
4000 } drmp3__seeking_mp3_frame_info;
4001
4002 DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
4003 {
4004 drmp3_uint32 seekPointCount;
4005 drmp3_uint64 currentPCMFrame;
4006 drmp3_uint64 totalMP3FrameCount;
4007 drmp3_uint64 totalPCMFrameCount;
4008
4009 if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) {
4010 return DRMP3_FALSE; /* Invalid args. */
4011 }
4012
4013 seekPointCount = *pSeekPointCount;
4014 if (seekPointCount == 0) {
4015 return DRMP3_FALSE; /* The client has requested no seek points. Consider this to be invalid arguments since the client has probably not intended this. */
4016 }
4017
4018 /* We'll need to seek back to the current sample after calculating the seekpoints so we need to go ahead and grab the current location at the top. */
4019 currentPCMFrame = pMP3->currentPCMFrame;
4020
4021 /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */
4022 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) {
4023 return DRMP3_FALSE;
4024 }
4025
4026 /* If there's less than DRMP3_SEEK_LEADING_MP3_FRAMES+1 frames we just report 1 seek point which will be the very start of the stream. */
4027 if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) {
4028 seekPointCount = 1;
4029 pSeekPoints[0].seekPosInBytes = 0;
4030 pSeekPoints[0].pcmFrameIndex = 0;
4031 pSeekPoints[0].mp3FramesToDiscard = 0;
4032 pSeekPoints[0].pcmFramesToDiscard = 0;
4033 } else {
4034 drmp3_uint64 pcmFramesBetweenSeekPoints;
4035 drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
4036 drmp3_uint64 runningPCMFrameCount = 0;
4037 float runningPCMFrameCountFractionalPart = 0;
4038 drmp3_uint64 nextTargetPCMFrame;
4039 drmp3_uint32 iMP3Frame;
4040 drmp3_uint32 iSeekPoint;
4041
4042 if (seekPointCount > totalMP3FrameCount-1) {
4043 seekPointCount = (drmp3_uint32)totalMP3FrameCount-1;
4044 }
4045
4046 pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1);
4047
4048 /*
4049 Here is where we actually calculate the seek points. We need to start by moving the start of the stream. We then enumerate over each
4050 MP3 frame.
4051 */
4052 if (!drmp3_seek_to_start_of_stream(pMP3)) {
4053 return DRMP3_FALSE;
4054 }
4055
4056 /*
4057 We need to cache the byte positions of the previous MP3 frames. As a new MP3 frame is iterated, we cycle the byte positions in this
4058 array. The value in the first item in this array is the byte position that will be reported in the next seek point.
4059 */
4060
4061 /* We need to initialize the array of MP3 byte positions for the leading MP3 frames. */
4062 for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
4063 drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4064
4065 /* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */
4066 DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
4067 mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize;
4068 mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
4069
4070 /* We need to get information about this frame so we can know how many samples it contained. */
4071 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
4072 if (pcmFramesInCurrentMP3FrameIn == 0) {
4073 return DRMP3_FALSE; /* This should never happen. */
4074 }
4075
4076 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4077 }
4078
4079 /*
4080 At this point we will have extracted the byte positions of the leading MP3 frames. We can now start iterating over each seek point and
4081 calculate them.
4082 */
4083 nextTargetPCMFrame = 0;
4084 for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) {
4085 nextTargetPCMFrame += pcmFramesBetweenSeekPoints;
4086
4087 for (;;) {
4088 if (nextTargetPCMFrame < runningPCMFrameCount) {
4089 /* The next seek point is in the current MP3 frame. */
4090 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
4091 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
4092 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4093 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4094 break;
4095 } else {
4096 size_t i;
4097 drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4098
4099 /*
4100 The next seek point is not in the current MP3 frame, so continue on to the next one. The first thing to do is cycle the cached
4101 MP3 frame info.
4102 */
4103 for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) {
4104 mp3FrameInfo[i] = mp3FrameInfo[i+1];
4105 }
4106
4107 /* Cache previous MP3 frame info. */
4108 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize;
4109 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
4110
4111 /*
4112 Go to the next MP3 frame. This shouldn't ever fail, but just in case it does we just set the seek point and break. If it happens, it
4113 should only ever do it for the last seek point.
4114 */
4115 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
4116 if (pcmFramesInCurrentMP3FrameIn == 0) {
4117 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
4118 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
4119 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4120 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4121 break;
4122 }
4123
4124 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4125 }
4126 }
4127 }
4128
4129 /* Finally, we need to seek back to where we were. */
4130 if (!drmp3_seek_to_start_of_stream(pMP3)) {
4131 return DRMP3_FALSE;
4132 }
4133 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
4134 return DRMP3_FALSE;
4135 }
4136 }
4137
4138 *pSeekPointCount = seekPointCount;
4139 return DRMP3_TRUE;
4140 }
4141
4142 DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
4143 {
4144 if (pMP3 == NULL) {
4145 return DRMP3_FALSE;
4146 }
4147
4148 if (seekPointCount == 0 || pSeekPoints == NULL) {
4149 /* Unbinding. */
4150 pMP3->seekPointCount = 0;
4151 pMP3->pSeekPoints = NULL;
4152 } else {
4153 /* Binding. */
4154 pMP3->seekPointCount = seekPointCount;
4155 pMP3->pSeekPoints = pSeekPoints;
4156 }
4157
4158 return DRMP3_TRUE;
4159 }
4160
4161
4162 static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4163 {
4164 drmp3_uint64 totalFramesRead = 0;
4165 drmp3_uint64 framesCapacity = 0;
4166 float* pFrames = NULL;
4167 float temp[4096];
4168
4169 DRMP3_ASSERT(pMP3 != NULL);
4170
4171 for (;;) {
4172 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4173 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
4174 if (framesJustRead == 0) {
4175 break;
4176 }
4177
4178 /* Reallocate the output buffer if there's not enough room. */
4179 if (framesCapacity < totalFramesRead + framesJustRead) {
4180 drmp3_uint64 oldFramesBufferSize;
4181 drmp3_uint64 newFramesBufferSize;
4182 drmp3_uint64 newFramesCap;
4183 float* pNewFrames;
4184
4185 newFramesCap = framesCapacity * 2;
4186 if (newFramesCap < totalFramesRead + framesJustRead) {
4187 newFramesCap = totalFramesRead + framesJustRead;
4188 }
4189
4190 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
4191 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float);
4192 if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
4193 break;
4194 }
4195
4196 pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4197 if (pNewFrames == NULL) {
4198 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4199 break;
4200 }
4201
4202 pFrames = pNewFrames;
4203 framesCapacity = newFramesCap;
4204 }
4205
4206 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
4207 totalFramesRead += framesJustRead;
4208
4209 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4210 if (framesJustRead != framesToReadRightNow) {
4211 break;
4212 }
4213 }
4214
4215 if (pConfig != NULL) {
4216 pConfig->channels = pMP3->channels;
4217 pConfig->sampleRate = pMP3->sampleRate;
4218 }
4219
4220 drmp3_uninit(pMP3);
4221
4222 if (pTotalFrameCount) {
4223 *pTotalFrameCount = totalFramesRead;
4224 }
4225
4226 return pFrames;
4227 }
4228
4229 static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4230 {
4231 drmp3_uint64 totalFramesRead = 0;
4232 drmp3_uint64 framesCapacity = 0;
4233 drmp3_int16* pFrames = NULL;
4234 drmp3_int16 temp[4096];
4235
4236 DRMP3_ASSERT(pMP3 != NULL);
4237
4238 for (;;) {
4239 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4240 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
4241 if (framesJustRead == 0) {
4242 break;
4243 }
4244
4245 /* Reallocate the output buffer if there's not enough room. */
4246 if (framesCapacity < totalFramesRead + framesJustRead) {
4247 drmp3_uint64 newFramesBufferSize;
4248 drmp3_uint64 oldFramesBufferSize;
4249 drmp3_uint64 newFramesCap;
4250 drmp3_int16* pNewFrames;
4251
4252 newFramesCap = framesCapacity * 2;
4253 if (newFramesCap < totalFramesRead + framesJustRead) {
4254 newFramesCap = totalFramesRead + framesJustRead;
4255 }
4256
4257 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
4258 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16);
4259 if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
4260 break;
4261 }
4262
4263 pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4264 if (pNewFrames == NULL) {
4265 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4266 break;
4267 }
4268
4269 pFrames = pNewFrames;
4270 framesCapacity = newFramesCap;
4271 }
4272
4273 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
4274 totalFramesRead += framesJustRead;
4275
4276 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4277 if (framesJustRead != framesToReadRightNow) {
4278 break;
4279 }
4280 }
4281
4282 if (pConfig != NULL) {
4283 pConfig->channels = pMP3->channels;
4284 pConfig->sampleRate = pMP3->sampleRate;
4285 }
4286
4287 drmp3_uninit(pMP3);
4288
4289 if (pTotalFrameCount) {
4290 *pTotalFrameCount = totalFramesRead;
4291 }
4292
4293 return pFrames;
4294 }
4295
4296
4297 DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4298 {
4299 drmp3 mp3;
4300 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
4301 return NULL;
4302 }
4303
4304 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4305 }
4306
4307 DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4308 {
4309 drmp3 mp3;
4310 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
4311 return NULL;
4312 }
4313
4314 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4315 }
4316
4317
4318 DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4319 {
4320 drmp3 mp3;
4321 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4322 return NULL;
4323 }
4324
4325 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4326 }
4327
4328 DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4329 {
4330 drmp3 mp3;
4331 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4332 return NULL;
4333 }
4334
4335 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4336 }
4337
4338
4339 #ifndef DR_MP3_NO_STDIO
4340 DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4341 {
4342 drmp3 mp3;
4343 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
4344 return NULL;
4345 }
4346
4347 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4348 }
4349
4350 DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4351 {
4352 drmp3 mp3;
4353 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
4354 return NULL;
4355 }
4356
4357 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4358 }
4359 #endif
4360
4361 DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
4362 {
4363 if (pAllocationCallbacks != NULL) {
4364 return drmp3__malloc_from_callbacks(sz, pAllocationCallbacks);
4365 } else {
4366 return drmp3__malloc_default(sz, NULL);
4367 }
4368 }
4369
4370 DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
4371 {
4372 if (pAllocationCallbacks != NULL) {
4373 drmp3__free_from_callbacks(p, pAllocationCallbacks);
4374 } else {
4375 drmp3__free_default(p, NULL);
4376 }
4377 }
4378
4379 #endif /* dr_mp3_c */
4380 #endif /*DR_MP3_IMPLEMENTATION*/
4381
4382 /*
4383 DIFFERENCES BETWEEN minimp3 AND dr_mp3
4384 ======================================
4385 - First, keep in mind that minimp3 (https://github.com/lieff/minimp3) is where all the real work was done. All of the
4386 code relating to the actual decoding remains mostly unmodified, apart from some namespacing changes.
4387 - dr_mp3 adds a pulling style API which allows you to deliver raw data via callbacks. So, rather than pushing data
4388 to the decoder, the decoder _pulls_ data from your callbacks.
4389 - In addition to callbacks, a decoder can be initialized from a block of memory and a file.
4390 - The dr_mp3 pull API reads PCM frames rather than whole MP3 frames.
4391 - dr_mp3 adds convenience APIs for opening and decoding entire files in one go.
4392 - dr_mp3 is fully namespaced, including the implementation section, which is more suitable when compiling projects
4393 as a single translation unit (aka unity builds). At the time of writing this, a unity build is not possible when
4394 using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this.
4395 */
4396
4397 /*
4398 RELEASE NOTES - v0.5.0
4399 =======================
4400 Version 0.5.0 has breaking API changes.
4401
4402 Improved Client-Defined Memory Allocation
4403 -----------------------------------------
4404 The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
4405 existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom
4406 allocation callbacks are specified.
4407
4408 To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this:
4409
4410 void* my_malloc(size_t sz, void* pUserData)
4411 {
4412 return malloc(sz);
4413 }
4414 void* my_realloc(void* p, size_t sz, void* pUserData)
4415 {
4416 return realloc(p, sz);
4417 }
4418 void my_free(void* p, void* pUserData)
4419 {
4420 free(p);
4421 }
4422
4423 ...
4424
4425 drmp3_allocation_callbacks allocationCallbacks;
4426 allocationCallbacks.pUserData = &myData;
4427 allocationCallbacks.onMalloc = my_malloc;
4428 allocationCallbacks.onRealloc = my_realloc;
4429 allocationCallbacks.onFree = my_free;
4430 drmp3_init_file(&mp3, "my_file.mp3", NULL, &allocationCallbacks);
4431
4432 The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
4433
4434 Passing in null for the allocation callbacks object will cause dr_mp3 to use defaults which is the same as DRMP3_MALLOC,
4435 DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions.
4436
4437 Every API that opens a drmp3 object now takes this extra parameter. These include the following:
4438
4439 drmp3_init()
4440 drmp3_init_file()
4441 drmp3_init_memory()
4442 drmp3_open_and_read_pcm_frames_f32()
4443 drmp3_open_and_read_pcm_frames_s16()
4444 drmp3_open_memory_and_read_pcm_frames_f32()
4445 drmp3_open_memory_and_read_pcm_frames_s16()
4446 drmp3_open_file_and_read_pcm_frames_f32()
4447 drmp3_open_file_and_read_pcm_frames_s16()
4448
4449 Renamed APIs
4450 ------------
4451 The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame
4452 counts rather than sample counts.
4453
4454 drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
4455 drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
4456 drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
4457 drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
4458 drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
4459 drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
4460 */
4461
4462 /*
4463 REVISION HISTORY
4464 ================
4465 v0.6.33 - 2022-04-10
4466 - Fix compilation error with the MSVC ARM64 build.
4467 - Fix compilation error on older versions of GCC.
4468 - Remove some unused functions.
4469
4470 v0.6.32 - 2021-12-11
4471 - Fix a warning with Clang.
4472
4473 v0.6.31 - 2021-08-22
4474 - Fix a bug when loading from memory.
4475
4476 v0.6.30 - 2021-08-16
4477 - Silence some warnings.
4478 - Replace memory operations with DRMP3_* macros.
4479
4480 v0.6.29 - 2021-08-08
4481 - Bring up to date with minimp3.
4482
4483 v0.6.28 - 2021-07-31
4484 - Fix platform detection for ARM64.
4485 - Fix a compilation error with C89.
4486
4487 v0.6.27 - 2021-02-21
4488 - Fix a warning due to referencing _MSC_VER when it is undefined.
4489
4490 v0.6.26 - 2021-01-31
4491 - Bring up to date with minimp3.
4492
4493 v0.6.25 - 2020-12-26
4494 - Remove DRMP3_DEFAULT_CHANNELS and DRMP3_DEFAULT_SAMPLE_RATE which are leftovers from some removed APIs.
4495
4496 v0.6.24 - 2020-12-07
4497 - Fix a typo in version date for 0.6.23.
4498
4499 v0.6.23 - 2020-12-03
4500 - Fix an error where a file can be closed twice when initialization of the decoder fails.
4501
4502 v0.6.22 - 2020-12-02
4503 - Fix an error where it's possible for a file handle to be left open when initialization of the decoder fails.
4504
4505 v0.6.21 - 2020-11-28
4506 - Bring up to date with minimp3.
4507
4508 v0.6.20 - 2020-11-21
4509 - Fix compilation with OpenWatcom.
4510
4511 v0.6.19 - 2020-11-13
4512 - Minor code clean up.
4513
4514 v0.6.18 - 2020-11-01
4515 - Improve compiler support for older versions of GCC.
4516
4517 v0.6.17 - 2020-09-28
4518 - Bring up to date with minimp3.
4519
4520 v0.6.16 - 2020-08-02
4521 - Simplify sized types.
4522
4523 v0.6.15 - 2020-07-25
4524 - Fix a compilation warning.
4525
4526 v0.6.14 - 2020-07-23
4527 - Fix undefined behaviour with memmove().
4528
4529 v0.6.13 - 2020-07-06
4530 - Fix a bug when converting from s16 to f32 in drmp3_read_pcm_frames_f32().
4531
4532 v0.6.12 - 2020-06-23
4533 - Add include guard for the implementation section.
4534
4535 v0.6.11 - 2020-05-26
4536 - Fix use of uninitialized variable error.
4537
4538 v0.6.10 - 2020-05-16
4539 - Add compile-time and run-time version querying.
4540 - DRMP3_VERSION_MINOR
4541 - DRMP3_VERSION_MAJOR
4542 - DRMP3_VERSION_REVISION
4543 - DRMP3_VERSION_STRING
4544 - drmp3_version()
4545 - drmp3_version_string()
4546
4547 v0.6.9 - 2020-04-30
4548 - Change the `pcm` parameter of drmp3dec_decode_frame() to a `const drmp3_uint8*` for consistency with internal APIs.
4549
4550 v0.6.8 - 2020-04-26
4551 - Optimizations to decoding when initializing from memory.
4552
4553 v0.6.7 - 2020-04-25
4554 - Fix a compilation error with DR_MP3_NO_STDIO
4555 - Optimization to decoding by reducing some data movement.
4556
4557 v0.6.6 - 2020-04-23
4558 - Fix a minor bug with the running PCM frame counter.
4559
4560 v0.6.5 - 2020-04-19
4561 - Fix compilation error on ARM builds.
4562
4563 v0.6.4 - 2020-04-19
4564 - Bring up to date with changes to minimp3.
4565
4566 v0.6.3 - 2020-04-13
4567 - Fix some pedantic warnings.
4568
4569 v0.6.2 - 2020-04-10
4570 - Fix a crash in drmp3_open_*_and_read_pcm_frames_*() if the output config object is NULL.
4571
4572 v0.6.1 - 2020-04-05
4573 - Fix warnings.
4574
4575 v0.6.0 - 2020-04-04
4576 - API CHANGE: Remove the pConfig parameter from the following APIs:
4577 - drmp3_init()
4578 - drmp3_init_memory()
4579 - drmp3_init_file()
4580 - Add drmp3_init_file_w() for opening a file from a wchar_t encoded path.
4581
4582 v0.5.6 - 2020-02-12
4583 - Bring up to date with minimp3.
4584
4585 v0.5.5 - 2020-01-29
4586 - Fix a memory allocation bug in high level s16 decoding APIs.
4587
4588 v0.5.4 - 2019-12-02
4589 - Fix a possible null pointer dereference when using custom memory allocators for realloc().
4590
4591 v0.5.3 - 2019-11-14
4592 - Fix typos in documentation.
4593
4594 v0.5.2 - 2019-11-02
4595 - Bring up to date with minimp3.
4596
4597 v0.5.1 - 2019-10-08
4598 - Fix a warning with GCC.
4599
4600 v0.5.0 - 2019-10-07
4601 - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
4602 routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
4603 - drmp3_init()
4604 - drmp3_init_file()
4605 - drmp3_init_memory()
4606 - drmp3_open_and_read_pcm_frames_f32()
4607 - drmp3_open_and_read_pcm_frames_s16()
4608 - drmp3_open_memory_and_read_pcm_frames_f32()
4609 - drmp3_open_memory_and_read_pcm_frames_s16()
4610 - drmp3_open_file_and_read_pcm_frames_f32()
4611 - drmp3_open_file_and_read_pcm_frames_s16()
4612 - API CHANGE: Renamed the following APIs:
4613 - drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
4614 - drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
4615 - drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
4616 - drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
4617 - drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
4618 - drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
4619
4620 v0.4.7 - 2019-07-28
4621 - Fix a compiler error.
4622
4623 v0.4.6 - 2019-06-14
4624 - Fix a compiler error.
4625
4626 v0.4.5 - 2019-06-06
4627 - Bring up to date with minimp3.
4628
4629 v0.4.4 - 2019-05-06
4630 - Fixes to the VC6 build.
4631
4632 v0.4.3 - 2019-05-05
4633 - Use the channel count and/or sample rate of the first MP3 frame instead of DRMP3_DEFAULT_CHANNELS and
4634 DRMP3_DEFAULT_SAMPLE_RATE when they are set to 0. To use the old behaviour, just set the relevant property to
4635 DRMP3_DEFAULT_CHANNELS or DRMP3_DEFAULT_SAMPLE_RATE.
4636 - Add s16 reading APIs
4637 - drmp3_read_pcm_frames_s16
4638 - drmp3_open_memory_and_read_pcm_frames_s16
4639 - drmp3_open_and_read_pcm_frames_s16
4640 - drmp3_open_file_and_read_pcm_frames_s16
4641 - Add drmp3_get_mp3_and_pcm_frame_count() to the public header section.
4642 - Add support for C89.
4643 - Change license to choice of public domain or MIT-0.
4644
4645 v0.4.2 - 2019-02-21
4646 - Fix a warning.
4647
4648 v0.4.1 - 2018-12-30
4649 - Fix a warning.
4650
4651 v0.4.0 - 2018-12-16
4652 - API CHANGE: Rename some APIs:
4653 - drmp3_read_f32 -> to drmp3_read_pcm_frames_f32
4654 - drmp3_seek_to_frame -> drmp3_seek_to_pcm_frame
4655 - drmp3_open_and_decode_f32 -> drmp3_open_and_read_pcm_frames_f32
4656 - drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_pcm_frames_f32
4657 - drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_pcm_frames_f32
4658 - Add drmp3_get_pcm_frame_count().
4659 - Add drmp3_get_mp3_frame_count().
4660 - Improve seeking performance.
4661
4662 v0.3.2 - 2018-09-11
4663 - Fix a couple of memory leaks.
4664 - Bring up to date with minimp3.
4665
4666 v0.3.1 - 2018-08-25
4667 - Fix C++ build.
4668
4669 v0.3.0 - 2018-08-25
4670 - Bring up to date with minimp3. This has a minor API change: the "pcm" parameter of drmp3dec_decode_frame() has
4671 been changed from short* to void* because it can now output both s16 and f32 samples, depending on whether or
4672 not the DR_MP3_FLOAT_OUTPUT option is set.
4673
4674 v0.2.11 - 2018-08-08
4675 - Fix a bug where the last part of a file is not read.
4676
4677 v0.2.10 - 2018-08-07
4678 - Improve 64-bit detection.
4679
4680 v0.2.9 - 2018-08-05
4681 - Fix C++ build on older versions of GCC.
4682 - Bring up to date with minimp3.
4683
4684 v0.2.8 - 2018-08-02
4685 - Fix compilation errors with older versions of GCC.
4686
4687 v0.2.7 - 2018-07-13
4688 - Bring up to date with minimp3.
4689
4690 v0.2.6 - 2018-07-12
4691 - Bring up to date with minimp3.
4692
4693 v0.2.5 - 2018-06-22
4694 - Bring up to date with minimp3.
4695
4696 v0.2.4 - 2018-05-12
4697 - Bring up to date with minimp3.
4698
4699 v0.2.3 - 2018-04-29
4700 - Fix TCC build.
4701
4702 v0.2.2 - 2018-04-28
4703 - Fix bug when opening a decoder from memory.
4704
4705 v0.2.1 - 2018-04-27
4706 - Efficiency improvements when the decoder reaches the end of the stream.
4707
4708 v0.2 - 2018-04-21
4709 - Bring up to date with minimp3.
4710 - Start using major.minor.revision versioning.
4711
4712 v0.1d - 2018-03-30
4713 - Bring up to date with minimp3.
4714
4715 v0.1c - 2018-03-11
4716 - Fix C++ build error.
4717
4718 v0.1b - 2018-03-07
4719 - Bring up to date with minimp3.
4720
4721 v0.1a - 2018-02-28
4722 - Fix compilation error on GCC/Clang.
4723 - Fix some warnings.
4724
4725 v0.1 - 2018-02-xx
4726 - Initial versioned release.
4727 */
4728
4729 /*
4730 This software is available as a choice of the following licenses. Choose
4731 whichever you prefer.
4732
4733 ===============================================================================
4734 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
4735 ===============================================================================
4736 This is free and unencumbered software released into the public domain.
4737
4738 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
4739 software, either in source code form or as a compiled binary, for any purpose,
4740 commercial or non-commercial, and by any means.
4741
4742 In jurisdictions that recognize copyright laws, the author or authors of this
4743 software dedicate any and all copyright interest in the software to the public
4744 domain. We make this dedication for the benefit of the public at large and to
4745 the detriment of our heirs and successors. We intend this dedication to be an
4746 overt act of relinquishment in perpetuity of all present and future rights to
4747 this software under copyright law.
4748
4749 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4750 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4751 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4752 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
4753 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
4754 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4755
4756 For more information, please refer to <http://unlicense.org/>
4757
4758 ===============================================================================
4759 ALTERNATIVE 2 - MIT No Attribution
4760 ===============================================================================
4761 Copyright 2020 David Reid
4762
4763 Permission is hereby granted, free of charge, to any person obtaining a copy of
4764 this software and associated documentation files (the "Software"), to deal in
4765 the Software without restriction, including without limitation the rights to
4766 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
4767 of the Software, and to permit persons to whom the Software is furnished to do
4768 so.
4769
4770 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4771 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4772 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4773 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4774 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4775 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4776 SOFTWARE.
4777 */
4778
4779 /*
4780 https://github.com/lieff/minimp3
4781 To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
4782 This software is distributed without any warranty.
4783 See <http://creativecommons.org/publicdomain/zero/1.0/>.
4784 */
2222 * written by O.Sezer <sezero@users.sourceforge.net>, put into public domain.
2323 */
2424
25 /* Functions to parse some of MP3 tags -
26 * written by V.Novichkov <admin@wohlnet.ru>, put into public domain.
27 */
28
2529 #include "SDL_stdinc.h"
2630 #include "SDL_error.h"
2731 #include "SDL_rwops.h"
2832
2933 #include "mp3utils.h"
3034
31 #if defined(MUSIC_MP3_MAD) || defined(MUSIC_MP3_MPG123)
32
35 #include "SDL_log.h"
36
37 #ifdef ENABLE_ID3V2_TAG
3338 /*********************** SDL_RW WITH BOOKKEEPING ************************/
3439
3540 int MP3_RWinit(struct mp3file_t *fil, SDL_RWops *src) {
7479 return offset;
7580 }
7681
77
78 /*************************** TAG HANDLING: ******************************/
79
80 static SDL_INLINE SDL_bool is_id3v1(const unsigned char *data, long length) {
82 Sint64 MP3_RWtell(struct mp3file_t *fil)
83 {
84 return fil->pos;
85 }
86 #endif /* ENABLE_ID3V2_TAG */
87
88 #ifdef ENABLE_ALL_MP3_TAGS
89 static SDL_INLINE Sint32 read_sint32le(const Uint8 *data)
90 {
91 Uint32 result = (Uint32)data[0];
92 result |= (Uint32)data[1] << 8;
93 result |= (Uint32)data[2] << 16;
94 result |= (Uint32)data[3] << 24;
95 return (Sint32)result;
96 }
97 #endif /* ENABLE_ALL_MP3_TAGS */
98
99 #ifdef ENABLE_ID3V2_TAG
100 static SDL_INLINE Sint32 read_sint24be(const Uint8 *data)
101 {
102 Uint32 result = (Uint32)data[2];
103 result |= (Uint32)data[1] << 8;
104 result |= (Uint32)data[0] << 16;
105 return (Sint32)result;
106 }
107
108 static SDL_INLINE Sint32 read_sint32be(const Uint8 *data)
109 {
110 Uint32 result = (Uint32)data[3];
111 result |= (Uint32)data[2] << 8;
112 result |= (Uint32)data[1] << 16;
113 result |= (Uint32)data[0] << 24;
114 return (Sint32)result;
115 }
116 #endif /* ENABLE_ID3V2_TAG */
117
118
119 #ifdef ENABLE_ALL_MP3_TAGS
120 #define TAGS_INPUT_BUFFER_SIZE 128
121
122 /********************************************************
123 * ID3v1 *
124 ********************************************************/
125
126 #define ID3v1_TAG_SIZE 128
127 #define ID3v1_SIZE_OF_FIELD 30
128
129 #define ID3v1_FIELD_TITLE 3
130 #define ID3v1_FIELD_ARTIST 33
131 #define ID3v1_FIELD_ALBUM 63
132 #define ID3v1_FIELD_COPYRIGHT 97
133
134 static SDL_INLINE SDL_bool is_id3v1(const Uint8 *data, size_t length)
135 {
81136 /* http://id3.org/ID3v1 : 3 bytes "TAG" identifier and 125 bytes tag data */
82 if (length < 128 || SDL_memcmp(data,"TAG",3) != 0) {
137 if (length < ID3v1_TAG_SIZE || SDL_memcmp(data,"TAG", 3) != 0) {
83138 return SDL_FALSE;
84139 }
85140 return SDL_TRUE;
86141 }
87 static SDL_bool is_id3v2(const unsigned char *data, size_t length) {
142 #endif
143
144 #ifdef ENABLE_ID3V2_TAG
145 /* Parse ISO-8859-1 string and convert it into UTF-8 */
146 static char *parse_id3v1_ansi_string(const Uint8 *buffer, size_t src_len)
147 {
148 char *src_buffer = (char*)SDL_malloc(src_len + 1);
149 char *ret;
150 if (!src_buffer) {
151 return NULL; /* Out of memory */
152 }
153 SDL_memset(src_buffer, 0, src_len + 1);
154 SDL_memcpy(src_buffer, buffer, src_len);
155 ret = SDL_iconv_string("UTF-8", "ISO-8859-1", src_buffer, src_len + 1);
156 SDL_free(src_buffer);
157 return ret;
158 }
159 #endif /* ENABLE_ID3V2_TAG */
160
161 #ifdef ENABLE_ALL_MP3_TAGS
162 static void id3v1_set_tag(Mix_MusicMetaTags *out_tags, Mix_MusicMetaTag tag, const Uint8 *buffer, size_t len)
163 {
164 char *src_buf = parse_id3v1_ansi_string(buffer, len);
165 if (src_buf) {
166 meta_tags_set(out_tags, tag, src_buf);
167 SDL_free(src_buf);
168 }
169 }
170
171 /* Parse content of ID3v1 tag */
172 static void parse_id3v1(Mix_MusicMetaTags *out_tags, const Uint8 *buffer)
173 {
174 id3v1_set_tag(out_tags, MIX_META_TITLE, buffer + ID3v1_FIELD_TITLE, ID3v1_SIZE_OF_FIELD);
175 id3v1_set_tag(out_tags, MIX_META_ARTIST, buffer + ID3v1_FIELD_ARTIST, ID3v1_SIZE_OF_FIELD);
176 id3v1_set_tag(out_tags, MIX_META_ALBUM, buffer + ID3v1_FIELD_ALBUM, ID3v1_SIZE_OF_FIELD);
177 id3v1_set_tag(out_tags, MIX_META_COPYRIGHT, buffer + ID3v1_FIELD_COPYRIGHT, ID3v1_SIZE_OF_FIELD);
178 }
179 #endif /* ENABLE_ALL_MP3_TAGS */
180
181 #ifdef ENABLE_ID3V2_TAG
182 /********************************************************
183 * ID3v2 *
184 ********************************************************/
185
186 #define ID3v2_BUFFER_SIZE 1024
187
188 #define ID3v2_HEADER_SIZE 10
189
190 #define ID3v2_FIELD_VERSION_MAJOR 3
191 #define ID3v2_FIELD_VERSION_MINOR 4
192 #define ID3v2_FIELD_HEAD_FLAGS 5
193 #define ID3v2_FIELD_TAG_LENGTH 6
194 #define ID3v2_FIELD_EXTRA_HEADER_LENGTH 10
195
196 #define ID3v2_FLAG_HAS_FOOTER 0x10
197 #define ID3v2_FLAG_HAS_EXTRA_HEAD 0x40
198
199 #define ID3v2_3_FRAME_HEADER_SIZE 10
200 #define ID3v2_2_FRAME_HEADER_SIZE 6
201 #define ID3v2_FIELD_FRAME_SIZE 4
202 #define ID3v2_FIELD_FRAME_SIZEv2 3
203 #define ID3v2_FIELD_FLAGS 8
204
205 static SDL_bool is_id3v2(const Uint8 *data, size_t length)
206 {
88207 /* ID3v2 header is 10 bytes: http://id3.org/id3v2.4.0-structure */
89208 /* bytes 0-2: "ID3" identifier */
90 if (length < 10 || SDL_memcmp(data,"ID3",3) != 0) {
209 if (length < ID3v2_HEADER_SIZE || SDL_memcmp(data, "ID3",3) != 0) {
91210 return SDL_FALSE;
92211 }
93212 /* bytes 3-4: version num (major,revision), each byte always less than 0xff. */
102221 }
103222 return SDL_TRUE;
104223 }
105 static long get_id3v2_len(const unsigned char *data, long length) {
224
225 static SDL_INLINE Sint32 id3v2_synchsafe_decode(const Uint8 *data)
226 {
227 return ((data[0] << 21) + (data[1] << 14) + (data[2] << 7) + data[3]);
228 }
229
230 static long get_id3v2_len(const Uint8 *data, long length)
231 {
106232 /* size is a 'synchsafe' integer (see above) */
107 long size = (long)((data[6]<<21) + (data[7]<<14) + (data[8]<<7) + data[9]);
108 size += 10; /* header size */
233 long size = id3v2_synchsafe_decode(data + 6);
234 size += ID3v2_HEADER_SIZE; /* header size */
109235 /* ID3v2 header[5] is flags (bits 4-7 only, 0-3 are zero).
110236 * bit 4 set: footer is present (a copy of the header but
111237 * with "3DI" as ident.) */
112238 if (data[5] & 0x10) {
113 size += 10; /* footer size */
239 size += ID3v2_HEADER_SIZE; /* footer size */
114240 }
115241 /* optional padding (always zeroes) */
116242 while (size < length && data[size] == 0) {
118244 }
119245 return size;
120246 }
121 static SDL_bool is_apetag(const unsigned char *data, size_t length) {
247
248 /* Decode a string in the frame according to an encoding marker */
249 static char *id3v2_decode_string(const Uint8 *string, size_t size)
250 {
251 char *str_buffer = NULL;
252 char *src_buffer = NULL;
253 size_t copy_size = size;
254
255 if (size == 0) {
256 SDL_Log("id3v2_decode_string: Bad string size: a string should have at least 1 byte");
257 return NULL;
258 }
259
260 if (size < 2) {
261 return NULL;
262 }
263
264 if (string[0] == '\x01') { /* UTF-16 string with a BOM */
265 if (size <= 5) {
266 if (size < 5) {
267 SDL_Log("id3v2_decode_string: Bad BOM-UTF16 string size: %u < 5", (unsigned int)size);
268 }
269 return NULL;
270 }
271
272 copy_size = size - 3 + 2; /* exclude 3 bytes of encoding hint, append 2 bytes for a NULL termination */
273 src_buffer = (char*)SDL_malloc(copy_size);
274 if (!src_buffer) {
275 return NULL; /* Out of memory */
276 }
277 SDL_memset(src_buffer, 0, copy_size);
278 SDL_memcpy(src_buffer, (string + 3), copy_size - 2);
279
280 if (SDL_memcmp(string, "\x01\xFE\xFF", 3) == 0) { /* UTF-16BE*/
281 str_buffer = SDL_iconv_string("UTF-8", "UCS-2BE", src_buffer, copy_size);
282 } else if (SDL_memcmp(string, "\x01\xFF\xFE", 3) == 0) { /* UTF-16LE*/
283 str_buffer = SDL_iconv_string("UTF-8", "UCS-2LE", src_buffer, copy_size);
284 }
285 SDL_free(src_buffer);
286
287 } else if (string[0] == '\x02') { /* UTF-16BEstring without a BOM */
288 if (size <= 3) {
289 if (size < 3) {
290 SDL_Log("id3v2_decode_string: Bad UTF16BE string size: %u < 3", (unsigned int)size);
291 }
292 return NULL; /* Blank string*/
293 }
294
295 copy_size = size - 1 + 2; /* exclude 1 byte of encoding hint, append 2 bytes for a NULL termination */
296 src_buffer = (char*)SDL_malloc(copy_size);
297 if (!src_buffer) {
298 return NULL; /* Out of memory */
299 }
300 SDL_memset(src_buffer, 0, copy_size);
301 SDL_memcpy(src_buffer, (string + 1), copy_size - 2);
302
303 str_buffer = SDL_iconv_string("UTF-8", "UCS-2BE", src_buffer, copy_size);
304 SDL_free(src_buffer);
305
306 } else if (string[0] == '\x03') { /* UTF-8 string */
307 if (size <= 2) {
308 return NULL; /* Blank string*/
309 }
310 str_buffer = (char*)SDL_malloc(size);
311 if (!str_buffer) {
312 return NULL; /* Out of memory */
313 }
314 SDL_strlcpy(str_buffer, (const char*)(string + 1), size);
315
316 } else if (string[0] == '\x00') { /* Latin-1 string */
317 if (size <= 2) {
318 return NULL; /* Blank string*/
319 }
320 str_buffer = parse_id3v1_ansi_string((string + 1), size - 1);
321 }
322
323 return str_buffer;
324 }
325
326 /* Write a tag string into internal meta-tags storage */
327 static void write_id3v2_string(Mix_MusicMetaTags *out_tags, Mix_MusicMetaTag tag, const Uint8 *string, size_t size)
328 {
329 char *str_buffer = id3v2_decode_string(string, size);
330
331 if (str_buffer) {
332 meta_tags_set(out_tags, tag, str_buffer);
333 SDL_free(str_buffer);
334 }
335
336 }
337
338 /* Identify a meta-key and decode the string (Note: input buffer should have at least 4 characters!) */
339 static void handle_id3v2_string(Mix_MusicMetaTags *out_tags, const char *key, const Uint8 *string, size_t size)
340 {
341 if (SDL_memcmp(key, "TIT2", 4) == 0) {
342 write_id3v2_string(out_tags, MIX_META_TITLE, string, size);
343 } else if (SDL_memcmp(key, "TPE1", 4) == 0) {
344 write_id3v2_string(out_tags, MIX_META_ARTIST, string, size);
345 } else if (SDL_memcmp(key, "TALB", 4) == 0) {
346 write_id3v2_string(out_tags, MIX_META_ALBUM, string, size);
347 } else if (SDL_memcmp(key, "TCOP", 4) == 0) {
348 write_id3v2_string(out_tags, MIX_META_COPYRIGHT, string, size);
349 }
350 /* TODO: Extract "Copyright message" from TXXX value: a KEY=VALUE string divided by a zero byte:*/
351 /*
352 else if (SDL_memcmp(key, "TXXX", 4) == 0) {
353 write_id3v2_string(out_tags, MIX_META_COPYRIGHT, string, size);
354 }
355 */
356 }
357
358 /* Identify a meta-key and decode the string (Note: input buffer should have at least 4 characters!) */
359 static void handle_id3v2x2_string(Mix_MusicMetaTags *out_tags, const char *key, const Uint8 *string, size_t size)
360 {
361 if (SDL_memcmp(key, "TT2", 3) == 0) {
362 write_id3v2_string(out_tags, MIX_META_TITLE, string, size);
363 } else if (SDL_memcmp(key, "TP1", 3) == 0) {
364 write_id3v2_string(out_tags, MIX_META_ARTIST, string, size);
365 } else if (SDL_memcmp(key, "TAL", 3) == 0) {
366 write_id3v2_string(out_tags, MIX_META_ALBUM, string, size);
367 } else if (SDL_memcmp(key, "TCR", 3) == 0) {
368 write_id3v2_string(out_tags, MIX_META_COPYRIGHT, string, size);
369 }
370 }
371
372 /* Parse a frame in ID3v2.2 format */
373 static size_t id3v22_parse_frame(Mix_MusicMetaTags *out_tags, struct mp3file_t *src, Uint8 *buffer)
374 {
375 size_t size;
376 char key[4];
377 size_t read_size;
378 Sint64 frame_begin = MP3_RWtell(src);
379
380 read_size = MP3_RWread(src, buffer, 1, ID3v2_2_FRAME_HEADER_SIZE);
381
382 if (read_size < ID3v2_2_FRAME_HEADER_SIZE) {
383 SDL_Log("id3v2_parse_frame: Buffer size that left is too small %u < 6", (unsigned int)read_size);
384 MP3_RWseek(src, frame_begin, RW_SEEK_SET);
385 return 0; /* Buffer size that left is too small */
386 }
387
388 if (SDL_memcmp(buffer, "\0\0\0", 3) == 0) {
389 MP3_RWseek(src, frame_begin, RW_SEEK_SET);
390 return 0;
391 }
392
393 SDL_memcpy(key, buffer, 3); /* Tag title (key) */
394
395 size = (size_t)read_sint24be(buffer + ID3v2_FIELD_FRAME_SIZEv2);
396
397 if (size < ID3v2_BUFFER_SIZE) {
398 read_size = MP3_RWread(src, buffer, 1, size);
399 } else {
400 read_size = MP3_RWread(src, buffer, 1, ID3v2_BUFFER_SIZE);
401 MP3_RWseek(src, frame_begin + (Sint64)size, RW_SEEK_SET);
402 }
403
404 handle_id3v2x2_string(out_tags, key, buffer, read_size);
405
406 return (size_t)(size + ID3v2_2_FRAME_HEADER_SIZE); /* data size + size of the header */
407 }
408
409 /* Parse a frame in ID3v2.3 and ID3v2.4 formats */
410 static size_t id3v2x_parse_frame(Mix_MusicMetaTags *out_tags, struct mp3file_t *src, Uint8 *buffer, Uint8 version)
411 {
412 Uint32 size;
413 char key[4];
414 Uint8 flags[2];
415 size_t read_size;
416 Sint64 frame_begin = MP3_RWtell(src);
417
418 read_size = MP3_RWread(src, buffer, 1, ID3v2_3_FRAME_HEADER_SIZE);
419
420 if (read_size < ID3v2_3_FRAME_HEADER_SIZE) {
421 SDL_Log("id3v2_parse_frame: Buffer size that left is too small %u < 10", (unsigned int)read_size);
422 MP3_RWseek(src, frame_begin, RW_SEEK_SET);
423 return 0; /* Can't read frame header, possibly, a file size was reached */
424 }
425
426 if (SDL_memcmp(buffer, "\0\0\0\0", 4) == 0) {
427 MP3_RWseek(src, frame_begin, RW_SEEK_SET);
428 return 0;
429 }
430
431 SDL_memcpy(key, buffer, 4); /* Tag title (key) */
432
433 if (version == 4) {
434 size = (Uint32)id3v2_synchsafe_decode(buffer + ID3v2_FIELD_FRAME_SIZE);
435 } else {
436 size = (Uint32)read_sint32be(buffer + ID3v2_FIELD_FRAME_SIZE);
437 }
438
439 SDL_memcpy(flags, buffer + ID3v2_FIELD_FLAGS, 2);
440
441 if (size < ID3v2_BUFFER_SIZE) {
442 read_size = MP3_RWread(src, buffer, 1, size);
443 } else {
444 read_size = MP3_RWread(src, buffer, 1, ID3v2_BUFFER_SIZE);
445 MP3_RWseek(src, frame_begin + (Sint64)size, RW_SEEK_SET);
446 }
447
448 handle_id3v2_string(out_tags, key, buffer, size);
449
450 return (size_t)(size + ID3v2_3_FRAME_HEADER_SIZE); /* data size + size of the header */
451 }
452
453
454 /* Parse content of ID3v2 */
455 static SDL_bool parse_id3v2(Mix_MusicMetaTags *out_tags, struct mp3file_t *src)
456 {
457 Uint8 version_major, flags;
458 long total_length, tag_len, tag_extended_len = 0;
459 Uint8 buffer[ID3v2_BUFFER_SIZE];
460 size_t read_size;
461 size_t frame_length;
462 Sint64 file_size;
463
464 total_length = 0;
465
466 file_size = src->length;
467 MP3_RWseek(src, 0, RW_SEEK_SET);
468 read_size = MP3_RWread(src, buffer, 1, ID3v2_HEADER_SIZE); /* Retrieve the header */
469 if (read_size < ID3v2_HEADER_SIZE) {
470 SDL_Log("parse_id3v2: fail to read a header (%u < 10)", (unsigned int)read_size);
471 return SDL_FALSE; /* Unsupported version of the tag */
472 }
473
474 total_length += ID3v2_HEADER_SIZE;
475
476 version_major = buffer[ID3v2_FIELD_VERSION_MAJOR]; /* Major version */
477 /* version_minor = buffer[ID3v2_VERSION_MINOR]; * Minor version, UNUSED */
478 flags = buffer[ID3v2_FIELD_HEAD_FLAGS]; /* Flags */
479 tag_len = id3v2_synchsafe_decode(buffer + ID3v2_FIELD_TAG_LENGTH); /* Length of a tag */
480
481 if (version_major != 2 && version_major != 3 && version_major != 4) {
482 SDL_Log("parse_id3v2: Unsupported version %d", version_major);
483 return SDL_FALSE; /* Unsupported version of the tag */
484 }
485
486 if ((version_major > 2) && ((flags & ID3v2_FLAG_HAS_EXTRA_HEAD) == ID3v2_FLAG_HAS_EXTRA_HEAD)) {
487 MP3_RWread(src, buffer + ID3v2_FIELD_EXTRA_HEADER_LENGTH, 1, 4);
488 MP3_RWseek(src, -4, RW_SEEK_CUR);
489 tag_extended_len = id3v2_synchsafe_decode(buffer + ID3v2_FIELD_EXTRA_HEADER_LENGTH); /* Length of an extended header */
490 }
491
492 if (tag_extended_len) {
493 total_length += tag_extended_len + 4;
494 MP3_RWseek(src, tag_extended_len + 4, RW_SEEK_CUR); /* Skip extended header and it's size value */
495 }
496
497 total_length += tag_len;
498
499 if (flags & ID3v2_FLAG_HAS_FOOTER) {
500 total_length += ID3v2_HEADER_SIZE; /* footer size */
501 }
502
503 if ((MP3_RWtell(src) + tag_len) > file_size) {
504 SDL_Log("parse_id3v2: Tag size bigger than actual file size");
505 return SDL_FALSE; /* Tag size is bigger than actual buffer data */
506 }
507
508 while ((MP3_RWtell(src) >= 0) && (MP3_RWtell(src) < (total_length))) {
509 if (version_major == 2) {
510 frame_length = id3v22_parse_frame(out_tags, src, buffer);
511 } else {
512 frame_length = id3v2x_parse_frame(out_tags, src, buffer, version_major);
513 }
514 if (!frame_length) {
515 break;
516 }
517 }
518
519 return SDL_TRUE;
520 }
521 #endif /* ENABLE_ID3V2_TAG */
522
523 #ifdef ENABLE_ALL_MP3_TAGS
524 /********************************************************
525 * APE v1 and v2 *
526 ********************************************************/
527
528 #define APE_BUFFER_SIZE 256
529
530 #define APE_V1 1000U
531 #define APE_V2 2000U
532 #define APE_HEADER_SIZE 32
533
534 #define APE_HEAD_FIELD_VERSION 8
535 #define APE_HEAD_FIELD_TAGSIZE 12
536 #define APE_HEAD_FIELD_ITEMS_COUNT 16
537 #define APE_HEAD_FIELD_FLAGS 20
538 #define APE_HEAD_FIELD_RESERVED 24
539
540 #define APE_FRAME_TAG_KEY 4
541
542 static SDL_bool is_apetag(const Uint8 *data, size_t length)
543 {
122544 /* http://wiki.hydrogenaud.io/index.php?title=APEv2_specification
123545 * Header/footer is 32 bytes: bytes 0-7 ident, bytes 8-11 version,
124546 * bytes 12-17 size. bytes 24-31 are reserved: must be all zeroes. */
127549 if (length < 32 || SDL_memcmp(data,"APETAGEX",8) != 0) {
128550 return SDL_FALSE;
129551 }
130 v = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]); /* version */
131 if (v != 2000U && v != 1000U) {
552 v = (Uint32) read_sint32le(data + 8); /* version */
553 if (v != APE_V2 && v != APE_V1) {
132554 return SDL_FALSE;
133555 }
134556 v = 0; /* reserved bits : */
137559 }
138560 return SDL_TRUE;
139561 }
140 static long get_ape_len(const unsigned char *data) {
141 Uint32 flags, version;
142 long size = (long)((data[15]<<24) | (data[14]<<16) | (data[13]<<8) | data[12]);
143 version = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]);
144 flags = (Uint32)((data[23]<<24) | (data[22]<<16) | (data[21]<<8) | data[20]);
145 if (version == 2000U && (flags & (1U<<31))) size += 32; /* header present. */
562
563 static long get_ape_len(const Uint8 *data, Uint32 *version)
564 {
565 Uint32 flags;
566 long size = (long) read_sint32le(data + APE_HEAD_FIELD_TAGSIZE);
567 *version = (Uint32) read_sint32le(data + APE_HEAD_FIELD_VERSION);
568 flags = (Uint32) read_sint32le(data + APE_HEAD_FIELD_FLAGS);
569 if (*version == APE_V2 && (flags & (1U<<31))) {
570 size += APE_HEADER_SIZE; /* header present. */
571 }
146572 return size;
147573 }
148 static SDL_INLINE int is_lyrics3tag(const unsigned char *data, long length) {
574
575 static char *ape_find_value(char *key)
576 {
577 char *end = (key + APE_BUFFER_SIZE - 4);
578
579 while (*key && key != end) {
580 key++;
581 }
582
583 if (key >= end) {
584 return NULL;
585 }
586
587 return key + 1;
588 }
589
590 static Uint32 ape_handle_tag(Mix_MusicMetaTags *out_tags, Uint8 *data, size_t valsize)
591 {
592 /* http://wiki.hydrogenaud.io/index.php?title=APE_Tag_Item
593 * Tag entry has unclear size because of no size value for a key field
594 * However, we only know next sizes:
595 * - 4 bytes is a [length] of value field
596 * - 4 bytes of value-specific flags
597 * - unknown lenght of a key field. To detect it's size
598 * it's need to find a zero byte looking at begin of the key field
599 * - 1 byte of a null-terminator
600 * - [length] bytes a value content
601 */
602 char *key = (char*)(data + APE_FRAME_TAG_KEY);
603 char *value = NULL;
604 Uint32 key_len; /* Length of the key field */
605
606 value = ape_find_value(key);
607
608 if (!value) {
609 return 0;
610 }
611
612 key_len = (Uint32)(value - key);
613
614 if (valsize > APE_BUFFER_SIZE - key_len) {
615 data[APE_BUFFER_SIZE] = '\0';
616 } else {
617 value[valsize] = '\0';
618 }
619
620 if (SDL_strncasecmp(key, "Title", 6) == 0) {
621 meta_tags_set(out_tags, MIX_META_TITLE, (const char*)(value));
622 } else if (SDL_strncasecmp(key, "Album", 6) == 0) {
623 meta_tags_set(out_tags, MIX_META_ALBUM, (const char*)(value));
624 } else if (SDL_strncasecmp(key, "Artist", 7) == 0) {
625 meta_tags_set(out_tags, MIX_META_ARTIST, (const char*)(value));
626 } else if (SDL_strncasecmp(key, "Copyright", 10) == 0) {
627 meta_tags_set(out_tags, MIX_META_COPYRIGHT, (const char*)(value));
628 }
629
630 return 4 + (Uint32)valsize + key_len;
631 }
632
633 /* Parse content of APE tag */
634 static SDL_bool parse_ape(Mix_MusicMetaTags *out_tags, struct mp3file_t *src, Sint64 ape_head_pos, Uint32 version)
635 {
636 Uint8 buffer[APE_BUFFER_SIZE + 1];
637 Uint32 v, i, tag_size, tag_items_count, tag_item_size;
638 Uint32 zero8[2] = {0, 0};
639 Sint64 file_size, cur_tag;
640 size_t read_size;
641
642 file_size = src->length;
643 MP3_RWseek(src, ape_head_pos, RW_SEEK_SET);
644 read_size = MP3_RWread(src, buffer, 1, APE_HEADER_SIZE); /* Retrieve the header */
645
646 if (read_size < APE_HEADER_SIZE) {
647 MP3_RWseek(src, ape_head_pos, RW_SEEK_SET);
648 return SDL_FALSE;
649 }
650
651 v = (Uint32)read_sint32le(buffer + APE_HEAD_FIELD_VERSION); /* version */
652 if (v != APE_V2 && v != APE_V1) {
653 return SDL_FALSE;
654 }
655
656 tag_size = (Uint32)read_sint32le(buffer + APE_HEAD_FIELD_TAGSIZE); /* tag size */
657
658 if (version == APE_V1) { /* If version 1, we are at footer */
659 if (ape_head_pos - (tag_size - APE_HEADER_SIZE) < 0) {
660 MP3_RWseek(src, ape_head_pos, RW_SEEK_SET);
661 return SDL_FALSE;
662 }
663 MP3_RWseek(src, ape_head_pos - (tag_size - APE_HEADER_SIZE), RW_SEEK_SET);
664 } else if ((ape_head_pos + tag_size + APE_HEADER_SIZE) > file_size) {
665 MP3_RWseek(src, ape_head_pos, RW_SEEK_SET);
666 return SDL_FALSE;
667 }
668
669 tag_items_count = (Uint32)read_sint32le(buffer + APE_HEAD_FIELD_ITEMS_COUNT); /* count tag items */
670
671 /*flags = (Uint32)read_sint32be(buffer + APE_HEAD_FIELD_FLAGS);*/ /* global flags, unused */
672
673 /* reserved bits : */
674 if (SDL_memcmp(buffer + APE_HEAD_FIELD_RESERVED, zero8, 8) != 0) {
675 return SDL_FALSE;
676 }
677
678 for(i = 0; i < tag_items_count; i++) {
679 cur_tag = MP3_RWtell(src);
680 if (cur_tag < 0) {
681 break;
682 }
683 read_size = MP3_RWread(src, buffer, 1, 4); /* Retrieve the size */
684 if (read_size < 4) {
685 MP3_RWseek(src, ape_head_pos, RW_SEEK_SET);
686 return SDL_FALSE;
687 }
688
689 v = (Uint32)read_sint32le(buffer); /* size of the tag's value field */
690 /* (we still need to find key size by a null termination) */
691
692 /* Retrieve the tag's data with an aproximal size as we can */
693 if (v + 40 < APE_BUFFER_SIZE) {
694 read_size = MP3_RWread(src, buffer, 1, v + 40);
695 } else {
696 read_size = MP3_RWread(src, buffer, 1, APE_BUFFER_SIZE);
697 }
698 buffer[read_size] = '\0';
699
700 tag_item_size = ape_handle_tag(out_tags, buffer, v);
701 if (tag_item_size == 0) {
702 break;
703 }
704 MP3_RWseek(src, cur_tag + tag_item_size + 4, RW_SEEK_SET);
705 }
706
707 MP3_RWseek(src, ape_head_pos, RW_SEEK_SET);
708
709 return SDL_TRUE;
710 }
711
712
713 /********************************************************
714 * Lyrics3 skip *
715 ********************************************************/
716
717 /* Header : "LYRICSBEGIN" -- 11 bytes
718 * Size field: (decimal) (v2 only) 6 bytes
719 * End marker: "LYRICS200" (v2) - 9 bytes
720 * End marker: "LYRICSEND" (v1) - 9 bytes
721 *
722 * The maximum length of Lyrics3v1 is 5100 bytes.
723 */
724
725 #define LYRICS3v1_SEARCH_BUFFER 5120 /* 5100 + 20 of tag begin and end keywords */
726
727 #define LYRICS3v1_HEAD_SIZE 11
728 #define LYRICS3v1_TAIL_SIZE 9
729 #define LYRICS3v2_TAG_SIZE_VALUE 6
730 #define LYRICS3_FOOTER_SIZE 15
731
732 static SDL_INLINE int is_lyrics3tag(const Uint8 *data, size_t length)
733 {
149734 /* http://id3.org/Lyrics3
150735 * http://id3.org/Lyrics3v2 */
151 if (length < 15) return 0;
152 if (SDL_memcmp(data+6,"LYRICS200",9) == 0) return 2; /* v2 */
153 if (SDL_memcmp(data+6,"LYRICSEND",9) == 0) return 1; /* v1 */
736 if (length < LYRICS3_FOOTER_SIZE) return 0;
737 if (SDL_memcmp(data+LYRICS3v2_TAG_SIZE_VALUE,"LYRICS200",9) == 0) return 2; /* v2 */
738 if (SDL_memcmp(data+LYRICS3v2_TAG_SIZE_VALUE,"LYRICSEND",9) == 0) return 1; /* v1 */
154739 return 0;
155740 }
156 static long get_lyrics3v1_len(struct mp3file_t *m) {
741 static long get_lyrics3v1_len(struct mp3file_t *m)
742 {
157743 const char *p; long i, len;
158 char buf[5104];
744 char buf[LYRICS3v1_SEARCH_BUFFER + 1];
159745 /* needs manual search: http://id3.org/Lyrics3 */
160746 if (m->length < 20) return -1;
161 len = (m->length > 5109)? 5109 : (long)m->length;
747 len = (m->length > LYRICS3v1_SEARCH_BUFFER)? LYRICS3v1_SEARCH_BUFFER : (long)m->length;
162748 MP3_RWseek(m, -len, RW_SEEK_END);
163 MP3_RWread(m, buf, 1, (len -= 9)); /* exclude footer */
749 MP3_RWread(m, buf, 1, (size_t)(len -= LYRICS3v1_TAIL_SIZE)); /* exclude footer */
164750 /* strstr() won't work here. */
165 for (i = len - 11, p = buf; i >= 0; --i, ++p) {
166 if (SDL_memcmp(p, "LYRICSBEGIN", 11) == 0)
751 p = buf;
752 for (i = len - LYRICS3v1_HEAD_SIZE; i >= 0; --i, ++p) {
753 if (SDL_memcmp(p, "LYRICSBEGIN", LYRICS3v1_HEAD_SIZE) == 0)
167754 break;
168755 }
169756 if (i < 0) return -1;
170 return len - (long)(p - buf) + 9 /* footer */;
171 }
172 static SDL_INLINE long get_lyrics3v2_len(const unsigned char *data, long length) {
757 return len - (long)(p - buf) + LYRICS3v1_TAIL_SIZE /* footer */;
758 }
759 static SDL_INLINE long get_lyrics3v2_len(const Uint8 *data, size_t length)
760 {
173761 /* 6 bytes before the end marker is size in decimal format -
174762 * does not include the 9 bytes end marker and size field. */
175 if (length != 6) return 0;
176 return SDL_strtol((const char *)data, NULL, 10) + 15;
177 }
178 static SDL_INLINE SDL_bool verify_lyrics3v2(const unsigned char *data, long length) {
179 if (length < 11) return SDL_FALSE;
180 if (SDL_memcmp(data,"LYRICSBEGIN",11) == 0) return SDL_TRUE;
763 if (length != LYRICS3v2_TAG_SIZE_VALUE) return 0;
764 return SDL_strtol((const char *)data, NULL, 10) + LYRICS3_FOOTER_SIZE;
765 }
766 static SDL_INLINE SDL_bool verify_lyrics3v2(const Uint8 *data, size_t length)
767 {
768 if (length < LYRICS3v1_HEAD_SIZE) return SDL_FALSE;
769 if (SDL_memcmp(data,"LYRICSBEGIN",LYRICS3v1_HEAD_SIZE) == 0) return SDL_TRUE;
181770 return SDL_FALSE;
182771 }
772
773
774 /********************************************************
775 * MusicMatch *
776 ********************************************************/
777
778 #define MUSICMATCH_HEADER_SIZE 256
779 #define MUSICMATCH_VERSION_INFO_SIZE 256
780 #define MUSICMATCH_FOOTER_SIZE 48
781 #define MUSICMATCH_OFFSETS_SIZE 20
782
183783 #define MMTAG_PARANOID
184 static SDL_bool is_musicmatch(const unsigned char *data, long length) {
784 static SDL_bool is_musicmatch(const Uint8 *data, long length)
785 {
185786 /* From docs/musicmatch.txt in id3lib: https://sourceforge.net/projects/id3lib/
186787 Overall tag structure:
187788
206807 | Footer (48 bytes) |
207808 +-----------------------------+
208809 */
209 if (length < 48) return SDL_FALSE;
810 if (length < MUSICMATCH_FOOTER_SIZE) return SDL_FALSE;
210811 /* sig: 19 bytes company name + 13 bytes space */
211812 if (SDL_memcmp(data,"Brava Software Inc. ",32) != 0) {
212813 return SDL_FALSE;
218819 }
219820 #ifdef MMTAG_PARANOID
220821 /* [36..47]: 12 bytes trailing space */
221 for (length = 36; length < 48; ++length) {
822 for (length = 36; length < MUSICMATCH_FOOTER_SIZE; ++length) {
222823 if (data[length] != ' ') return SDL_FALSE;
223824 }
224825 #endif
225826 return SDL_TRUE;
226827 }
227 static long get_musicmatch_len(struct mp3file_t *m) {
828
829 static long get_musicmatch_len(struct mp3file_t *m)
830 {
228831 const Sint32 metasizes[4] = { 7868, 7936, 8004, 8132 };
229832 const unsigned char syncstr[10] = {'1','8','2','7','3','6','4','5',0,0};
230833 unsigned char buf[256];
244847 * section. */
245848 for (i = 0; i < 4; ++i) {
246849 /* 48: footer, 20: offsets, 256: version info */
247 len = metasizes[i] + 48 + 20 + 256;
850 len = metasizes[i] + MUSICMATCH_FOOTER_SIZE + MUSICMATCH_OFFSETS_SIZE + MUSICMATCH_VERSION_INFO_SIZE;
248851 if (m->length < len) return -1;
249852 MP3_RWseek(m, -len, RW_SEEK_END);
250 MP3_RWread(m, buf, 1, 256);
853 MP3_RWread(m, buf, 1, MUSICMATCH_VERSION_INFO_SIZE);
251854 /* [0..9]: sync string, [30..255]: 0x20 */
252855 #ifdef MMTAG_PARANOID
253 for (j = 30; j < 256; ++j) {
856 for (j = 30; j < MUSICMATCH_VERSION_INFO_SIZE; ++j) {
254857 if (buf[j] != ' ') break;
255858 }
256 if (j < 256) continue;
859 if (j < MUSICMATCH_VERSION_INFO_SIZE) continue;
257860 #endif
258861 if (SDL_memcmp(buf, syncstr, 10) == 0) {
259862 break;
276879 /* without this, we may land at a wrong place. */
277880 if (j + 12 != version_ofs - imgext_ofs) return -1;
278881 /* try finding the optional header */
279 if (m->length < len + 256) return len;
280 MP3_RWseek(m, -(len + 256), RW_SEEK_END);
281 MP3_RWread(m, buf, 1, 256);
882 if (m->length < len + MUSICMATCH_HEADER_SIZE) return len;
883 MP3_RWseek(m, -(len + MUSICMATCH_HEADER_SIZE), RW_SEEK_END);
884 MP3_RWread(m, buf, 1, MUSICMATCH_HEADER_SIZE);
282885 /* [0..9]: sync string, [30..255]: 0x20 */
283886 if (SDL_memcmp(buf, syncstr, 10) != 0) {
284887 return len;
285888 }
286889 #ifdef MMTAG_PARANOID
287 for (j = 30; j < 256; ++j) {
890 for (j = 30; j < MUSICMATCH_HEADER_SIZE; ++j) {
288891 if (buf[j] != ' ') return len;
289892 }
290893 #endif
291 return len + 256; /* header is present. */
292 }
293
294 static int probe_id3v1(struct mp3file_t *fil, unsigned char *buf, int atend) {
295 if (fil->length >= 128) {
296 MP3_RWseek(fil, -128, RW_SEEK_END);
297 if (MP3_RWread(fil, buf, 1, 128) != 128)
298 return -1;
299 if (is_id3v1(buf, 128)) {
894 return len + MUSICMATCH_HEADER_SIZE; /* header is present. */
895 }
896
897
898 #define TAG_FOUND 1
899 #define TAG_INVALID -1
900 #define TAG_NOT_FOUND 0
901
902 static int probe_id3v1(Mix_MusicMetaTags *out_tags, struct mp3file_t *fil, Uint8 *buf, SDL_bool tag_handled, int atend)
903 {
904 if (fil->length >= ID3v1_TAG_SIZE) {
905 MP3_RWseek(fil, -ID3v1_TAG_SIZE, RW_SEEK_END);
906 if (MP3_RWread(fil, buf, 1, ID3v1_TAG_SIZE) != ID3v1_TAG_SIZE)
907 return TAG_INVALID;
908 if (is_id3v1(buf, ID3v1_TAG_SIZE)) {
300909 if (!atend) { /* possible false positive? */
301910 if (is_musicmatch(buf + 128 - 48, 48) ||
302911 is_apetag (buf + 128 - 32, 32) ||
303912 is_lyrics3tag(buf + 128 - 15, 15)) {
304 return 0;
913 return TAG_NOT_FOUND;
305914 }
306915 }
307 fil->length -= 128;
308 return 1;
916 if (!tag_handled) {
917 parse_id3v1(out_tags, buf);
918 }
919 fil->length -= ID3v1_TAG_SIZE;
920 return TAG_FOUND;
309921 /* FIXME: handle possible double-ID3v1 tags?? */
310922 }
311923 }
312 return 0;
313 }
314 static int probe_mmtag(struct mp3file_t *fil, unsigned char *buf) {
924
925 return TAG_NOT_FOUND;
926 }
927
928 static int probe_mmtag(Mix_MusicMetaTags *out_tags, struct mp3file_t *fil, Uint8 *buf)
929 {
315930 long len;
931 (void)out_tags; /* TODO: Implement reading tag contents. */
316932 if (fil->length >= 68) {
317 MP3_RWseek(fil, -48, RW_SEEK_END);
318 if (MP3_RWread(fil, buf, 1, 48) != 48)
319 return -1;
320 if (is_musicmatch(buf, 48)) {
933 MP3_RWseek(fil, -MUSICMATCH_FOOTER_SIZE, RW_SEEK_END);
934 if (MP3_RWread(fil, buf, 1, MUSICMATCH_FOOTER_SIZE) != MUSICMATCH_FOOTER_SIZE)
935 return TAG_INVALID;
936 if (is_musicmatch(buf, MUSICMATCH_FOOTER_SIZE)) {
321937 len = get_musicmatch_len(fil);
322 if (len < 0) return -1;
323 if (len >= fil->length) return -1;
938 if (len < 0) return TAG_INVALID;
939 if (len >= fil->length) return TAG_INVALID;
324940 fil->length -= len;
325 return 1;
326 }
327 }
328 return 0;
329 }
330 static int probe_apetag(struct mp3file_t *fil, unsigned char *buf) {
941 return TAG_FOUND;
942 }
943 }
944 return TAG_NOT_FOUND;
945 }
946
947 static int probe_apetag(Mix_MusicMetaTags *out_tags, struct mp3file_t *fil, Uint8 *buf, SDL_bool tag_handled)
948 {
949 Sint64 ape_tag_pos;
950 size_t readsize;
331951 long len;
332 if (fil->length >= 32) {
333 MP3_RWseek(fil, -32, RW_SEEK_END);
334 if (MP3_RWread(fil, buf, 1, 32) != 32)
335 return -1;
336 if (is_apetag(buf, 32)) {
337 len = get_ape_len(buf);
338 if (len >= fil->length) return -1;
952 Uint32 v;
953
954 /* APE tag may be at the end: read the footer */
955 if (fil->length >= APE_HEADER_SIZE) {
956 MP3_RWseek(fil, -APE_HEADER_SIZE, RW_SEEK_END);
957 readsize = MP3_RWread(fil, buf, 1, APE_HEADER_SIZE);
958 if (readsize != APE_HEADER_SIZE) {
959 return TAG_INVALID;
960 }
961
962 /* APE tag may be at end or before ID3v1 tag */
963 if (is_apetag(buf, APE_HEADER_SIZE)) {
964 len = get_ape_len(buf, &v);
965 if (len >= fil->length) {
966 return TAG_INVALID;
967 }
968 if (v == APE_V2) { /* verify header : */
969 MP3_RWseek(fil, -len, RW_SEEK_END);
970 ape_tag_pos = MP3_RWtell(fil);
971 readsize = MP3_RWread(fil, buf, 1, APE_HEADER_SIZE);
972 if (readsize != APE_HEADER_SIZE) {
973 return TAG_INVALID;
974 }
975 if (!is_apetag(buf, APE_HEADER_SIZE)) {
976 fil->length -= len;
977 return TAG_NOT_FOUND;
978 }
979 if (!tag_handled) {
980 parse_ape(out_tags, fil, ape_tag_pos, APE_V2);
981 }
982 } else if (!tag_handled) {
983 SDL_bool ape_tag_valid;
984 MP3_RWseek(fil, -APE_HEADER_SIZE, RW_SEEK_END);
985 ape_tag_pos = MP3_RWtell(fil);
986 ape_tag_valid = parse_ape(out_tags, fil, ape_tag_pos, APE_V1);
987 if (!ape_tag_valid) {
988 fil->length -= len;
989 return TAG_NOT_FOUND;
990 }
991 }
339992 fil->length -= len;
340 return 1;
341 }
342 }
343 return 0;
344 }
345 static int probe_lyrics3(struct mp3file_t *fil, unsigned char *buf) {
993 return TAG_FOUND;
994 }
995 }
996
997 return TAG_NOT_FOUND;
998 }
999
1000 static int probe_lyrics3(struct mp3file_t *fil, Uint8 *buf)
1001 {
3461002 long len;
347 if (fil->length >= 15) {
348 MP3_RWseek(fil, -15, RW_SEEK_END);
349 if (MP3_RWread(fil, buf, 1, 15) != 15)
350 return -1;
351 len = is_lyrics3tag(buf, 15);
352 if (len == 2) {
353 len = get_lyrics3v2_len(buf, 6);
354 if (len >= fil->length) return -1;
355 if (len < 15) return -1;
1003 int ver;
1004
1005 if (fil->length >= LYRICS3_FOOTER_SIZE) {
1006 MP3_RWseek(fil, -LYRICS3_FOOTER_SIZE, RW_SEEK_END);
1007 if (MP3_RWread(fil, buf, 1, LYRICS3_FOOTER_SIZE) != LYRICS3_FOOTER_SIZE)
1008 return TAG_INVALID;
1009 ver = is_lyrics3tag(buf, LYRICS3_FOOTER_SIZE);
1010 if (ver == 2) {
1011 len = get_lyrics3v2_len(buf, LYRICS3v2_TAG_SIZE_VALUE);
1012 if (len >= fil->length) return TAG_INVALID;
1013 if (len < LYRICS3_FOOTER_SIZE) return TAG_INVALID;
3561014 MP3_RWseek(fil, -len, RW_SEEK_END);
357 if (MP3_RWread(fil, buf, 1, 11) != 11)
358 return -1;
359 if (!verify_lyrics3v2(buf, 11)) return -1;
1015 if (MP3_RWread(fil, buf, 1, LYRICS3v1_HEAD_SIZE) != LYRICS3v1_HEAD_SIZE)
1016 return TAG_INVALID;
1017 if (!verify_lyrics3v2(buf, LYRICS3v1_HEAD_SIZE)) return -1;
3601018 fil->length -= len;
361 return 1;
362 }
363 else if (len == 1) {
1019 return TAG_FOUND;
1020 }
1021 else if (ver == 1) {
3641022 len = get_lyrics3v1_len(fil);
365 if (len < 0) return -1;
1023 if (len < 0) return TAG_INVALID;
3661024 fil->length -= len;
367 return 1;
368 }
369 }
370 return 0;
371 }
372
373 int mp3_skiptags(struct mp3file_t *fil, SDL_bool keep_id3v2)
374 {
375 unsigned char buf[128];
1025 return TAG_FOUND;
1026 }
1027 }
1028 return TAG_NOT_FOUND;
1029 }
1030
1031 int mp3_read_tags(Mix_MusicMetaTags *out_tags, struct mp3file_t *fil, SDL_bool keep_id3v2)
1032 {
1033 Uint8 buf[TAGS_INPUT_BUFFER_SIZE];
3761034 long len; size_t readsize;
3771035 int c_id3, c_ape, c_lyr, c_mm;
3781036 int rc = -1;
1037 SDL_bool tag_handled = SDL_FALSE;
3791038
3801039 /* MP3 standard has no metadata format, so everyone invented
3811040 * their own thing, even with extensions, until ID3v2 became
3851044 * double tags. -- O.S.
3861045 */
3871046
388 readsize = MP3_RWread(fil, buf, 1, 128);
1047 MP3_RWseek(fil, 0, RW_SEEK_SET);
1048 readsize = MP3_RWread(fil, buf, 1, TAGS_INPUT_BUFFER_SIZE);
3891049 if (!readsize) goto fail;
3901050
3911051 /* ID3v2 tag is at the start */
3921052 if (is_id3v2(buf, readsize)) {
3931053 len = get_id3v2_len(buf, (long)readsize);
3941054 if (len >= fil->length) goto fail;
1055 tag_handled = parse_id3v2(out_tags, fil);
3951056 if (!keep_id3v2) {
3961057 fil->start += len;
3971058 fil->length -= len;
4001061 /* APE tag _might_ be at the start (discouraged
4011062 * but not forbidden, either.) read the header. */
4021063 else if (is_apetag(buf, readsize)) {
403 len = get_ape_len(buf);
1064 Uint32 v;
1065 len = get_ape_len(buf, &v);
4041066 if (len >= fil->length) goto fail;
1067 if (v == APE_V1 || v == APE_V2) {
1068 tag_handled = parse_ape(out_tags, fil, 0, v);
1069 }
4051070 fil->start += len;
4061071 fil->length -= len;
4071072 }
4081073
4091074 /* it's not impossible that _old_ MusicMatch tag
4101075 * placing itself after ID3v1. */
411 if ((c_mm = probe_mmtag(fil, buf)) < 0) {
1076 if ((c_mm = probe_mmtag(out_tags, fil, buf)) < 0) {
4121077 goto fail;
4131078 }
4141079 /* ID3v1 tag is at the end */
415 if ((c_id3 = probe_id3v1(fil, buf, !c_mm)) < 0) {
1080 if ((c_id3 = probe_id3v1(out_tags, fil, buf, tag_handled, !c_mm)) < 0) {
4161081 goto fail;
4171082 }
4181083 /* we do not know the order of ape or lyrics3
4221087 for (;;) {
4231088 if (!c_lyr) {
4241089 /* care about mp3s with double Lyrics3 tags? */
425 if ((c_lyr = probe_lyrics3(fil, buf)) < 0)
1090 if ((c_lyr = probe_lyrics3(fil, buf)) == TAG_INVALID)
4261091 goto fail;
4271092 if (c_lyr) continue;
4281093 }
4291094 if (!c_mm) {
430 if ((c_mm = probe_mmtag(fil, buf)) < 0)
1095 if ((c_mm = probe_mmtag(out_tags, fil, buf)) == TAG_INVALID)
4311096 goto fail;
4321097 if (c_mm) continue;
4331098 }
4341099 if (!c_ape) {
435 if ((c_ape = probe_apetag(fil, buf)) < 0)
1100 if ((c_ape = probe_apetag(out_tags, fil, buf, tag_handled)) == TAG_INVALID)
4361101 goto fail;
4371102 if (c_ape) continue;
4381103 }
4441109 MP3_RWseek(fil, 0, RW_SEEK_SET);
4451110 return rc;
4461111 }
447 #endif /* MUSIC_MP3_??? */
448
449 /* vi: set ts=4 sw=4 expandtab: */
1112 #endif /* ENABLE_ALL_MP3_TAGS */
1113
1114 #ifdef ENABLE_ID3V2_TAG
1115 int read_id3v2_from_mem(Mix_MusicMetaTags *out_tags, Uint8 *data, size_t length)
1116 {
1117 SDL_RWops *src = SDL_RWFromConstMem(data, (int)length);
1118 SDL_bool is_valid;
1119 struct mp3file_t fil;
1120
1121 if (src) {
1122 fil.src = src;
1123 fil.start = 0;
1124 fil.length = (Sint64)length;
1125
1126 if (!is_id3v2(data, length)) {
1127 SDL_RWclose(src);
1128 return -1;
1129 }
1130
1131 if (get_id3v2_len(data, (long)length) > (long)length) {
1132 SDL_RWclose(src);
1133 return -1;
1134 }
1135
1136 is_valid = parse_id3v2(out_tags, &fil);
1137 SDL_RWclose(src);
1138
1139 return is_valid ? 0 : -1;
1140 }
1141 return -1;
1142 }
1143 #endif /* ENABLE_ID3V2_TAG */
1818 3. This notice may not be removed or altered from any source distribution.
1919 */
2020
21 /* This file provides utility functions to work with MP3 files including reading of tags. */
22
2123 #ifndef MIX_MP3UTILS_H
2224 #define MIX_MP3UTILS_H
2325
26 #include "music.h"
27
28 #define ENABLE_ALL_MP3_TAGS
29
30 #if defined(MUSIC_WAV) || defined(ENABLE_ALL_MP3_TAGS)
31 #define ENABLE_ID3V2_TAG
2432 struct mp3file_t {
2533 SDL_RWops *src;
2634 Sint64 start, length, pos;
2735 };
36 #endif
2837
29 extern int mp3_skiptags(struct mp3file_t *fil, SDL_bool keep_id3v2);
38 #ifdef ENABLE_ALL_MP3_TAGS
39 extern int mp3_read_tags(Mix_MusicMetaTags *out_tags, struct mp3file_t *fil, SDL_bool keep_id3v2);
40 #endif /* ENABLE_ALL_MP3_TAGS */
41
42 #ifdef ENABLE_ID3V2_TAG
43 extern int read_id3v2_from_mem(Mix_MusicMetaTags *out_tags, Uint8 *data, size_t length);
44 #endif
45
46 #ifdef ENABLE_ALL_MP3_TAGS
3047 extern int MP3_RWinit(struct mp3file_t *fil, SDL_RWops *src);
3148 extern size_t MP3_RWread(struct mp3file_t *fil, void *ptr, size_t size, size_t maxnum);
3249 extern Sint64 MP3_RWseek(struct mp3file_t *fil, Sint64 offset, int whence);
50 extern Sint64 MP3_RWtell(struct mp3file_t *fil);
51 #endif /* ENABLE_ALL_MP3_TAGS */
3352
3453 #endif /* MIX_MP3UTILS_H */
3554
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_FLAC_DRFLAC
22
23 #include "music_drflac.h"
24 #include "mp3utils.h"
25 #include "../utils.h"
26
27 #include "SDL.h"
28
29 #define DR_FLAC_IMPLEMENTATION
30 #if defined(__GNUC__) && (__GNUC__ >= 4) && \
31 !(defined(_WIN32) || defined(__EMX__))
32 #define DRFLAC_API __attribute__((visibility("hidden")))
33 #elif defined(__APPLE__)
34 #define DRFLAC_API __private_extern__
35 #else
36 #define DRFLAC_API /* just in case.. */
37 #endif
38 #define DR_FLAC_NO_STDIO
39 #define DRFLAC_ASSERT(expression)
40 #define DRFLAC_COPY_MEMORY(dst, src, sz) SDL_memcpy((dst), (src), (sz))
41 #define DRFLAC_MOVE_MEMORY(dst, src, sz) SDL_memmove((dst), (src), (sz))
42 #define DRFLAC_ZERO_MEMORY(p, sz) SDL_memset((p), 0, (sz))
43 #define DRFLAC_MALLOC(sz) SDL_malloc((sz))
44 #define DRFLAC_REALLOC(p, sz) SDL_realloc((p), (sz))
45 #define DRFLAC_FREE(p) SDL_free((p))
46 #include "dr_libs/dr_flac.h"
47
48
49 typedef struct {
50 struct mp3file_t file;
51 drflac *dec;
52 int play_count;
53 int freesrc;
54 int volume;
55 int status;
56 int sample_rate;
57 int channels;
58 SDL_AudioStream *stream;
59 drflac_int16 *buffer;
60 int buffer_size;
61 int loop;
62 SDL_bool loop_flag;
63 Sint64 loop_start;
64 Sint64 loop_end;
65 Sint64 loop_len;
66 Mix_MusicMetaTags tags;
67 } DRFLAC_Music;
68
69
70 static size_t DRFLAC_ReadCB(void *context, void *buf, size_t size)
71 {
72 DRFLAC_Music *music = (DRFLAC_Music *)context;
73 return MP3_RWread(&music->file, buf, 1, size);
74 }
75
76 static drflac_bool32 DRFLAC_SeekCB(void *context, int offset, drflac_seek_origin origin)
77 {
78 DRFLAC_Music *music = (DRFLAC_Music *)context;
79 int whence = (origin == drflac_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR;
80 if (MP3_RWseek(&music->file, offset, whence) < 0) {
81 return DRFLAC_FALSE;
82 }
83 return DRFLAC_TRUE;
84 }
85
86 static void DRFLAC_MetaCB(void *context, drflac_metadata *metadata)
87 {
88 DRFLAC_Music *music = (DRFLAC_Music *)context;
89
90 if (metadata->type == DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO) {
91 music->sample_rate = metadata->data.streaminfo.sampleRate;
92 music->channels = metadata->data.streaminfo.channels;
93 } else if (metadata->type == DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT) {
94 drflac_uint32 i;
95 char *param, *argument, *value;
96 SDL_bool is_loop_length = SDL_FALSE;
97 const char *pRunningData = (const char *)metadata->data.vorbis_comment.pComments;
98
99 for (i = 0; i < metadata->data.vorbis_comment.commentCount; ++i) {
100 drflac_uint32 commentLength = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
101
102 param = (char *)SDL_malloc(commentLength + 1);
103 if (param) {
104 SDL_memcpy(param, pRunningData, commentLength);
105 param[commentLength] = '\0';
106 argument = param;
107 value = SDL_strchr(param, '=');
108
109 if (value == NULL) {
110 value = param + SDL_strlen(param);
111 } else {
112 *(value++) = '\0';
113 }
114
115 /* Want to match LOOP-START, LOOP_START, etc. Remove - or _ from
116 * string if it is present at position 4. */
117 if (_Mix_IsLoopTag(argument) && ((argument[4] == '_') || (argument[4] == '-'))) {
118 SDL_memmove(argument + 4, argument + 5, SDL_strlen(argument) - 4);
119 }
120
121 if (SDL_strcasecmp(argument, "LOOPSTART") == 0)
122 music->loop_start = _Mix_ParseTime(value, music->sample_rate);
123 else if (SDL_strcasecmp(argument, "LOOPLENGTH") == 0) {
124 music->loop_len = SDL_strtoll(value, NULL, 10);
125 is_loop_length = SDL_TRUE;
126 } else if (SDL_strcasecmp(argument, "LOOPEND") == 0) {
127 music->loop_end = _Mix_ParseTime(value, music->sample_rate);
128 is_loop_length = SDL_FALSE;
129 } else if (SDL_strcasecmp(argument, "TITLE") == 0) {
130 meta_tags_set(&music->tags, MIX_META_TITLE, value);
131 } else if (SDL_strcasecmp(argument, "ARTIST") == 0) {
132 meta_tags_set(&music->tags, MIX_META_ARTIST, value);
133 } else if (SDL_strcasecmp(argument, "ALBUM") == 0) {
134 meta_tags_set(&music->tags, MIX_META_ALBUM, value);
135 } else if (SDL_strcasecmp(argument, "COPYRIGHT") == 0) {
136 meta_tags_set(&music->tags, MIX_META_COPYRIGHT, value);
137 }
138 SDL_free(param);
139 }
140 pRunningData += commentLength;
141 }
142
143 if (is_loop_length) {
144 music->loop_end = music->loop_start + music->loop_len;
145 } else {
146 music->loop_len = music->loop_end - music->loop_start;
147 }
148
149 /* Ignore invalid loop tag */
150 if (music->loop_start < 0 || music->loop_len < 0 || music->loop_end < 0) {
151 music->loop_start = 0;
152 music->loop_len = 0;
153 music->loop_end = 0;
154 }
155 }
156 }
157
158 static int DRFLAC_Seek(void *context, double position);
159
160 static void *DRFLAC_CreateFromRW(SDL_RWops *src, int freesrc)
161 {
162 DRFLAC_Music *music;
163
164 music = (DRFLAC_Music *)SDL_calloc(1, sizeof(DRFLAC_Music));
165 if (!music) {
166 SDL_OutOfMemory();
167 return NULL;
168 }
169 music->volume = MIX_MAX_VOLUME;
170
171 if (MP3_RWinit(&music->file, src) < 0) {
172 SDL_free(music);
173 return NULL;
174 }
175
176 meta_tags_init(&music->tags);
177
178 music->dec = drflac_open_with_metadata(DRFLAC_ReadCB, DRFLAC_SeekCB, DRFLAC_MetaCB, music, NULL);
179 if (!music->dec) {
180 SDL_free(music);
181 Mix_SetError("music_drflac: corrupt flac file (bad stream).");
182 return NULL;
183 }
184
185 /* We should have channels and sample rate set up here */
186 music->stream = SDL_NewAudioStream(AUDIO_S16SYS,
187 (Uint8)music->channels,
188 music->sample_rate,
189 music_spec.format,
190 music_spec.channels,
191 music_spec.freq);
192 if (!music->stream) {
193 SDL_OutOfMemory();
194 drflac_close(music->dec);
195 SDL_free(music);
196 return NULL;
197 }
198
199 music->buffer_size = music_spec.samples * sizeof(drflac_int16) * music->channels;
200 music->buffer = (drflac_int16*)SDL_calloc(1, music->buffer_size);
201 if (!music->buffer) {
202 drflac_close(music->dec);
203 SDL_OutOfMemory();
204 SDL_free(music);
205 return NULL;
206 }
207
208 /* loop_start, loop_end and loop_len get set by metadata callback if tags
209 * are present in metadata.
210 */
211 if ((music->loop_end > 0) && (music->loop_end <= (Sint64)music->dec->totalPCMFrameCount) &&
212 (music->loop_start < music->loop_end)) {
213 music->loop = 1;
214 }
215
216 music->freesrc = freesrc;
217 return music;
218 }
219
220 static void DRFLAC_SetVolume(void *context, int volume)
221 {
222 DRFLAC_Music *music = (DRFLAC_Music *)context;
223 music->volume = volume;
224 }
225
226 static int DRFLAC_GetVolume(void *context)
227 {
228 DRFLAC_Music *music = (DRFLAC_Music *)context;
229 return music->volume;
230 }
231
232 /* Starts the playback. */
233 static int DRFLAC_Play(void *context, int play_count)
234 {
235 DRFLAC_Music *music = (DRFLAC_Music *)context;
236 music->play_count = play_count;
237 return DRFLAC_Seek(music, 0.0);
238 }
239
240 static void DRFLAC_Stop(void *context)
241 {
242 DRFLAC_Music *music = (DRFLAC_Music *)context;
243 SDL_AudioStreamClear(music->stream);
244 }
245
246 static int DRFLAC_GetSome(void *context, void *data, int bytes, SDL_bool *done)
247 {
248 DRFLAC_Music *music = (DRFLAC_Music *)context;
249 int filled;
250 drflac_uint64 amount;
251
252 if (music->stream) {
253 filled = SDL_AudioStreamGet(music->stream, data, bytes);
254 if (filled != 0) {
255 return filled;
256 }
257 }
258
259 if (!music->play_count) {
260 /* All done */
261 *done = SDL_TRUE;
262 return 0;
263 }
264
265 if (music->loop_flag) {
266 if (!drflac_seek_to_pcm_frame(music->dec, music->loop_start)) {
267 SDL_SetError("drflac_seek_to_pcm_frame() failed");
268 return -1;
269 } else {
270 int play_count = -1;
271 if (music->play_count > 0) {
272 play_count = (music->play_count - 1);
273 }
274 music->play_count = play_count;
275 music->loop_flag = SDL_FALSE;
276 }
277 }
278
279 amount = drflac_read_pcm_frames_s16(music->dec, music_spec.samples, music->buffer);
280 if (amount > 0) {
281 if (music->loop && (music->play_count != 1) &&
282 ((Sint64)music->dec->currentPCMFrame >= music->loop_end)) {
283 amount -= (music->dec->currentPCMFrame - music->loop_end) * sizeof(drflac_int16) * music->channels;
284 music->loop_flag = SDL_TRUE;
285 }
286 if (SDL_AudioStreamPut(music->stream, music->buffer, (int)amount * sizeof(drflac_int16) * music->channels) < 0) {
287 return -1;
288 }
289 } else {
290 if (music->play_count == 1) {
291 music->play_count = 0;
292 SDL_AudioStreamFlush(music->stream);
293 } else {
294 int play_count = -1;
295 if (music->play_count > 0) {
296 play_count = (music->play_count - 1);
297 }
298 if (DRFLAC_Play(music, play_count) < 0) {
299 return -1;
300 }
301 }
302 }
303
304 return 0;
305 }
306
307 static int DRFLAC_GetAudio(void *context, void *data, int bytes)
308 {
309 DRFLAC_Music *music = (DRFLAC_Music *)context;
310 return music_pcm_getaudio(context, data, bytes, music->volume, DRFLAC_GetSome);
311 }
312
313 static int DRFLAC_Seek(void *context, double position)
314 {
315 DRFLAC_Music *music = (DRFLAC_Music *)context;
316 drflac_uint64 destpos = (drflac_uint64)(position * music->sample_rate);
317 drflac_seek_to_pcm_frame(music->dec, destpos);
318 return 0;
319 }
320
321 static double DRFLAC_Tell(void *context)
322 {
323 DRFLAC_Music *music = (DRFLAC_Music *)context;
324 return (double)music->dec->currentPCMFrame / music->sample_rate;
325 }
326
327 static double DRFLAC_Duration(void *context)
328 {
329 DRFLAC_Music *music = (DRFLAC_Music *)context;
330 drflac_uint64 samples = music->dec->totalPCMFrameCount;
331 return (double)samples / music->sample_rate;
332 }
333
334 static double DRFLAC_LoopStart(void *context)
335 {
336 DRFLAC_Music *music = (DRFLAC_Music *)context;
337 if (music->loop > 0) {
338 return (double)music->loop_start / music->sample_rate;
339 }
340 return -1.0;
341 }
342
343 static double DRFLAC_LoopEnd(void *context)
344 {
345 DRFLAC_Music *music = (DRFLAC_Music *)context;
346 if (music->loop > 0) {
347 return (double)music->loop_end / music->sample_rate;
348 }
349 return -1.0;
350 }
351
352 static double DRFLAC_LoopLength(void *context)
353 {
354 DRFLAC_Music *music = (DRFLAC_Music *)context;
355 if (music->loop > 0) {
356 return (double)music->loop_len / music->sample_rate;
357 }
358 return -1.0;
359 }
360
361 static const char* DRFLAC_GetMetaTag(void *context, Mix_MusicMetaTag tag_type)
362 {
363 DRFLAC_Music *music = (DRFLAC_Music *)context;
364 return meta_tags_get(&music->tags, tag_type);
365 }
366
367 static void DRFLAC_Delete(void *context)
368 {
369 DRFLAC_Music *music = (DRFLAC_Music *)context;
370
371 drflac_close(music->dec);
372 meta_tags_clear(&music->tags);
373
374 if (music->stream) {
375 SDL_FreeAudioStream(music->stream);
376 }
377 if (music->buffer) {
378 SDL_free(music->buffer);
379 }
380 if (music->freesrc) {
381 SDL_RWclose(music->file.src);
382 }
383 SDL_free(music);
384 }
385
386 Mix_MusicInterface Mix_MusicInterface_DRFLAC =
387 {
388 "DRFLAC",
389 MIX_MUSIC_DRFLAC,
390 MUS_FLAC,
391 SDL_FALSE,
392 SDL_FALSE,
393
394 NULL, /* Load */
395 NULL, /* Open */
396 DRFLAC_CreateFromRW,
397 NULL, /* CreateFromFile */
398 DRFLAC_SetVolume,
399 DRFLAC_GetVolume,
400 DRFLAC_Play,
401 NULL, /* IsPlaying */
402 DRFLAC_GetAudio,
403 NULL, /* Jump */
404 DRFLAC_Seek,
405 DRFLAC_Tell,
406 DRFLAC_Duration,
407 DRFLAC_LoopStart,
408 DRFLAC_LoopEnd,
409 DRFLAC_LoopLength,
410 DRFLAC_GetMetaTag,
411 NULL, /* Pause */
412 NULL, /* Resume */
413 DRFLAC_Stop,
414 DRFLAC_Delete,
415 NULL, /* Close */
416 NULL /* Unload */
417 };
418
419 #endif /* MUSIC_FLAC_DRFLAC */
420
421 /* vi: set ts=4 sw=4 expandtab: */
0 /*
1 SDL_mixer: An audio mixer library based on the SDL library
2 Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 */
20
21 /* This file supports playing FLAC files with dr_flac */
22
23 #include "music.h"
24
25 extern Mix_MusicInterface Mix_MusicInterface_DRFLAC;
26
27 /* vi: set ts=4 sw=4 expandtab: */
0 /*
1 SDL_mixer: An audio mixer library based on the SDL library
2 Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 */
20
21 #ifdef MUSIC_MP3_DRMP3
22
23 #include "music_drmp3.h"
24 #include "mp3utils.h"
25 #include "SDL.h"
26
27 #define DR_MP3_IMPLEMENTATION
28 #if defined(__GNUC__) && (__GNUC__ >= 4) && \
29 !(defined(_WIN32) || defined(__EMX__))
30 #define DRMP3_API __attribute__((visibility("hidden")))
31 #elif defined(__APPLE__)
32 #define DRMP3_API __private_extern__
33 #else
34 #define DRMP3_API /* just in case.. */
35 #endif
36 #define DR_MP3_NO_STDIO
37 #define DRMP3_ASSERT(expression)
38 #define DRMP3_COPY_MEMORY(dst, src, sz) SDL_memcpy((dst), (src), (sz))
39 #define DRMP3_MOVE_MEMORY(dst, src, sz) SDL_memmove((dst), (src), (sz))
40 #define DRMP3_ZERO_MEMORY(p, sz) SDL_memset((p), 0, (sz))
41 #define DRMP3_MALLOC(sz) SDL_malloc((sz))
42 #define DRMP3_REALLOC(p, sz) SDL_realloc((p), (sz))
43 #define DRMP3_FREE(p) SDL_free((p))
44 #include "dr_libs/dr_mp3.h"
45
46
47 typedef struct {
48 struct mp3file_t file;
49 drmp3 dec;
50 int play_count;
51 int freesrc;
52 int volume;
53 int status;
54 SDL_AudioStream *stream;
55 drmp3_int16 *buffer;
56 int buffer_size;
57 int channels;
58
59 Mix_MusicMetaTags tags;
60 } DRMP3_Music;
61
62
63 static size_t DRMP3_ReadCB(void *context, void *buf, size_t size)
64 {
65 DRMP3_Music *music = (DRMP3_Music *)context;
66 return MP3_RWread(&music->file, buf, 1, size);
67 }
68
69 static drmp3_bool32 DRMP3_SeekCB(void *context, int offset, drmp3_seek_origin origin)
70 {
71 DRMP3_Music *music = (DRMP3_Music *)context;
72 int whence = (origin == drmp3_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR;
73 if (MP3_RWseek(&music->file, offset, whence) < 0) {
74 return DRMP3_FALSE;
75 }
76 return DRMP3_TRUE;
77 }
78
79 static int DRMP3_Seek(void *context, double position);
80
81 static void *DRMP3_CreateFromRW(SDL_RWops *src, int freesrc)
82 {
83 DRMP3_Music *music;
84
85 music = (DRMP3_Music *)SDL_calloc(1, sizeof(DRMP3_Music));
86 if (!music) {
87 SDL_OutOfMemory();
88 return NULL;
89 }
90 music->volume = MIX_MAX_VOLUME;
91
92 if (MP3_RWinit(&music->file, src) < 0) {
93 SDL_free(music);
94 return NULL;
95 }
96
97 meta_tags_init(&music->tags);
98 if (mp3_read_tags(&music->tags, &music->file, SDL_FALSE) < 0) {
99 SDL_free(music);
100 Mix_SetError("music_drmp3: corrupt mp3 file (bad tags).");
101 return NULL;
102 }
103
104 MP3_RWseek(&music->file, 0, RW_SEEK_SET);
105
106 if (!drmp3_init(&music->dec, DRMP3_ReadCB, DRMP3_SeekCB, music, NULL)) {
107 SDL_free(music);
108 Mix_SetError("music_drmp3: corrupt mp3 file (bad stream).");
109 return NULL;
110 }
111
112 music->channels = music->dec.channels;
113 music->stream = SDL_NewAudioStream(AUDIO_S16SYS,
114 (Uint8)music->channels,
115 (int)music->dec.sampleRate,
116 music_spec.format,
117 music_spec.channels,
118 music_spec.freq);
119 if (!music->stream) {
120 SDL_OutOfMemory();
121 drmp3_uninit(&music->dec);
122 SDL_free(music);
123 return NULL;
124 }
125
126 music->buffer_size = music_spec.samples * sizeof(drmp3_int16) * music->channels;
127 music->buffer = (drmp3_int16*)SDL_calloc(1, music->buffer_size);
128 if (!music->buffer) {
129 drmp3_uninit(&music->dec);
130 SDL_OutOfMemory();
131 SDL_free(music);
132 return NULL;
133 }
134
135 music->freesrc = freesrc;
136 return music;
137 }
138
139 static void DRMP3_SetVolume(void *context, int volume)
140 {
141 DRMP3_Music *music = (DRMP3_Music *)context;
142 music->volume = volume;
143 }
144
145 static int DRMP3_GetVolume(void *context)
146 {
147 DRMP3_Music *music = (DRMP3_Music *)context;
148 return music->volume;
149 }
150
151 /* Starts the playback. */
152 static int DRMP3_Play(void *context, int play_count)
153 {
154 DRMP3_Music *music = (DRMP3_Music *)context;
155 music->play_count = play_count;
156 return DRMP3_Seek(music, 0.0);
157 }
158
159 static void DRMP3_Stop(void *context)
160 {
161 DRMP3_Music *music = (DRMP3_Music *)context;
162 SDL_AudioStreamClear(music->stream);
163 }
164
165 static int DRMP3_GetSome(void *context, void *data, int bytes, SDL_bool *done)
166 {
167 DRMP3_Music *music = (DRMP3_Music *)context;
168 int filled;
169 drmp3_uint64 amount;
170
171 if (music->stream) {
172 filled = SDL_AudioStreamGet(music->stream, data, bytes);
173 if (filled != 0) {
174 return filled;
175 }
176 }
177
178 if (!music->play_count) {
179 /* All done */
180 *done = SDL_TRUE;
181 return 0;
182 }
183
184 amount = drmp3_read_pcm_frames_s16(&music->dec, music_spec.samples, music->buffer);
185 if (amount > 0) {
186 if (SDL_AudioStreamPut(music->stream, music->buffer, (int)amount * sizeof(drmp3_int16) * music->channels) < 0) {
187 return -1;
188 }
189 } else {
190 if (music->play_count == 1) {
191 music->play_count = 0;
192 SDL_AudioStreamFlush(music->stream);
193 } else {
194 int play_count = -1;
195 if (music->play_count > 0) {
196 play_count = (music->play_count - 1);
197 }
198 if (DRMP3_Play(music, play_count) < 0) {
199 return -1;
200 }
201 }
202 }
203
204 return 0;
205 }
206
207 static int DRMP3_GetAudio(void *context, void *data, int bytes)
208 {
209 DRMP3_Music *music = (DRMP3_Music *)context;
210 return music_pcm_getaudio(context, data, bytes, music->volume, DRMP3_GetSome);
211 }
212
213 static int DRMP3_Seek(void *context, double position)
214 {
215 DRMP3_Music *music = (DRMP3_Music *)context;
216 drmp3_uint64 destpos = (drmp3_uint64)(position * music->dec.sampleRate);
217 drmp3_seek_to_pcm_frame(&music->dec, destpos);
218 return 0;
219 }
220
221 static double DRMP3_Tell(void *context)
222 {
223 DRMP3_Music *music = (DRMP3_Music *)context;
224 return (double)music->dec.currentPCMFrame / music->dec.sampleRate;
225 }
226
227 static double DRMP3_Duration(void *context)
228 {
229 DRMP3_Music *music = (DRMP3_Music *)context;
230 drmp3_uint64 samples = drmp3_get_pcm_frame_count(&music->dec);
231 return (double)samples / music->dec.sampleRate;
232 }
233
234 static const char* DRMP3_GetMetaTag(void *context, Mix_MusicMetaTag tag_type)
235 {
236 DRMP3_Music *music = (DRMP3_Music *)context;
237 return meta_tags_get(&music->tags, tag_type);
238 }
239
240 static void DRMP3_Delete(void *context)
241 {
242 DRMP3_Music *music = (DRMP3_Music *)context;
243
244 drmp3_uninit(&music->dec);
245 meta_tags_clear(&music->tags);
246
247 if (music->stream) {
248 SDL_FreeAudioStream(music->stream);
249 }
250 if (music->buffer) {
251 SDL_free(music->buffer);
252 }
253 if (music->freesrc) {
254 SDL_RWclose(music->file.src);
255 }
256 SDL_free(music);
257 }
258
259 Mix_MusicInterface Mix_MusicInterface_DRMP3 =
260 {
261 "DRMP3",
262 MIX_MUSIC_DRMP3,
263 MUS_MP3,
264 SDL_FALSE,
265 SDL_FALSE,
266
267 NULL, /* Load */
268 NULL, /* Open */
269 DRMP3_CreateFromRW,
270 NULL, /* CreateFromFile */
271 DRMP3_SetVolume,
272 DRMP3_GetVolume,
273 DRMP3_Play,
274 NULL, /* IsPlaying */
275 DRMP3_GetAudio,
276 NULL, /* Jump */
277 DRMP3_Seek,
278 DRMP3_Tell,
279 DRMP3_Duration,
280 NULL, /* LoopStart */
281 NULL, /* LoopEnd */
282 NULL, /* LoopLength */
283 DRMP3_GetMetaTag,
284 NULL, /* Pause */
285 NULL, /* Resume */
286 DRMP3_Stop,
287 DRMP3_Delete,
288 NULL, /* Close */
289 NULL /* Unload */
290 };
291
292 #endif /* MUSIC_MP3_DRMP3 */
293
294 /* vi: set ts=4 sw=4 expandtab: */
0 /*
1 SDL_mixer: An audio mixer library based on the SDL library
2 Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 */
20
21 /* This file supports playing MP3 files with dr_mp3 */
22
23 #include "music.h"
24
25 extern Mix_MusicInterface Mix_MusicInterface_DRMP3;
26
27 /* vi: set ts=4 sw=4 expandtab: */
2121 ~ Austen Dicken (admin@cvpcs.org)
2222 */
2323
24 #ifdef MUSIC_FLAC
24 #ifdef MUSIC_FLAC_LIBFLAC
2525
2626 #include "SDL_loadso.h"
2727 #include "SDL_assert.h"
574574 return FLAC_Seek(music, 0.0);
575575 }
576576
577 static void FLAC_Stop(void *context)
578 {
579 FLAC_Music *music = (FLAC_Music *)context;
580 SDL_AudioStreamClear(music->stream);
581 }
582
577583 /* Read some FLAC stream data and convert it for output */
578584 static int FLAC_GetSome(void *context, void *data, int bytes, SDL_bool *done)
579585 {
644650 FLAC__uint64 seek_sample = (FLAC__uint64) (music->sample_rate * position);
645651
646652 SDL_AudioStreamClear(music->stream);
653
647654 music->pcm_pos = (FLAC__int64) seek_sample;
648655 if (!flac.FLAC__stream_decoder_seek_absolute(music->flac_decoder, seek_sample)) {
649656 if (flac.FLAC__stream_decoder_get_state(music->flac_decoder) == FLAC__STREAM_DECODER_SEEK_ERROR) {
743750 FLAC_GetMetaTag,/* GetMetaTag */
744751 NULL, /* Pause */
745752 NULL, /* Resume */
746 NULL, /* Stop */
753 FLAC_Stop, /* Stop */
747754 FLAC_Delete,
748755 NULL, /* Close */
749756 FLAC_Unload
750757 };
751758
752 #endif /* MUSIC_FLAC */
759 #endif /* MUSIC_FLAC_LIBFLAC */
753760
754761 /* vi: set ts=4 sw=4 expandtab: */
152152 double total_length;
153153 int sample_rate;
154154 int sample_position;
155 Mix_MusicMetaTags tags;
155156
156157 unsigned char input_buffer[MAD_INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD];
157158 } MAD_Music;
159
158160
159161 static void read_update_buffer(struct mad_stream *stream, MAD_Music *music);
160162
325327 SDL_free(music);
326328 return NULL;
327329 }
328 if (mp3_skiptags(&music->mp3file, SDL_FALSE) < 0) {
330 meta_tags_init(&music->tags);
331 if (mp3_read_tags(&music->tags, &music->mp3file, SDL_FALSE) < 0) {
329332 SDL_free(music);
330333 Mix_SetError("music_mad: corrupt mp3 file (bad tags.)");
331334 return NULL;
364367 MAD_Music *music = (MAD_Music *)context;
365368 music->play_count = play_count;
366369 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);
367376 }
368377
369378
622631 return music->total_length;
623632 }
624633
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
625640 static void MAD_Delete(void *context)
626641 {
627642 MAD_Music *music = (MAD_Music *)context;
629644 mad_stream_finish(&music->stream);
630645 mad_frame_finish(&music->frame);
631646 mad_synth_finish(&music->synth);
647 meta_tags_clear(&music->tags);
632648
633649 if (music->audiostream) {
634650 SDL_FreeAudioStream(music->audiostream);
663679 NULL, /* LoopStart */
664680 NULL, /* LoopEnd */
665681 NULL, /* LoopLength */
666 NULL, /* GetMetaTag */
682 MAD_GetMetaTag,
667683 NULL, /* Pause */
668684 NULL, /* Resume */
669 NULL, /* Stop */
685 MAD_Stop,
670686 MAD_Delete,
671687 NULL, /* Close */
672688 NULL /* Unload */
3939 int (*ModPlug_Read)(ModPlugFile* file, void* buffer, int size);
4040 void (*ModPlug_Seek)(ModPlugFile* file, int millisecond);
4141 void (*ModPlug_SeekOrder)(ModPlugFile* file, int order);
42 int (*ModPlug_Tell)(ModPlugFile* file);
4243 int (*ModPlug_GetLength)(ModPlugFile* file);
4344 void (*ModPlug_GetSettings)(ModPlug_Settings* settings);
4445 void (*ModPlug_SetSettings)(const ModPlug_Settings* settings);
7980 FUNCTION_LOADER(ModPlug_SetSettings, void (*)(const ModPlug_Settings* settings))
8081 FUNCTION_LOADER(ModPlug_SetMasterVolume, void (*)(ModPlugFile* file,unsigned int cvol))
8182 FUNCTION_LOADER(ModPlug_GetName, const char* (*)(ModPlugFile* file))
83 #ifdef MODPLUG_DYNAMIC
84 modplug.ModPlug_Tell = (int (*)(ModPlugFile* file)) SDL_LoadFunction(modplug.handle, "ModPlug_Tell");
85 #elif defined(MODPLUG_HAS_TELL)
86 modplug.ModPlug_Tell = ModPlug_Tell;
87 #else
88 modplug.ModPlug_Tell = NULL;
89 #endif
8290 }
8391 ++modplug.loaded;
8492
221229 MODPLUG_Music *music = (MODPLUG_Music *)context;
222230 music->play_count = play_count;
223231 return MODPLUG_Seek(music, 0.0);
232 }
233
234 static void MODPLUG_Stop(void *context)
235 {
236 MODPLUG_Music *music = (MODPLUG_Music *)context;
237 SDL_AudioStreamClear(music->stream);
224238 }
225239
226240 /* Play some of a stream previously started with modplug_play() */
283297 return 0;
284298 }
285299
300 static double MODPLUG_Tell(void *context)
301 {
302 if (modplug.ModPlug_Tell) {
303 MODPLUG_Music *music = (MODPLUG_Music *)context;
304 return (double)(modplug.ModPlug_Tell(music->file)) / 1000.0;
305 } else {
306 return -1.0;
307 }
308 }
309
286310 /* Return music duration in seconds */
287311 static double MODPLUG_Duration(void *context)
288312 {
332356 MODPLUG_GetAudio,
333357 MODPLUG_Jump,
334358 MODPLUG_Seek,
335 NULL, /* Tell */
359 MODPLUG_Tell,
336360 MODPLUG_Duration,
337361 NULL, /* LoopStart */
338362 NULL, /* LoopEnd */
340364 MODPLUG_GetMetaTag,
341365 NULL, /* Pause */
342366 NULL, /* Resume */
343 NULL, /* Stop */
367 MODPLUG_Stop,
344368 MODPLUG_Delete,
345369 NULL, /* Close */
346370 MODPLUG_Unload
143143 size_t buffer_size;
144144 long sample_rate;
145145 off_t total_length;
146 Mix_MusicMetaTags tags;
146147 } MPG123_Music;
147148
148149
240241 SDL_free(music);
241242 return NULL;
242243 }
243 if (mp3_skiptags(&music->mp3file, SDL_TRUE) < 0) {
244 meta_tags_init(&music->tags);
245 if (mp3_read_tags(&music->tags, &music->mp3file, SDL_TRUE) < 0) {
244246 SDL_free(music);
245247 Mix_SetError("music_mpg123: corrupt mp3 file (bad tags.)");
246248 return NULL;
346348 return MPG123_Seek(music, 0.0);
347349 }
348350
351 static void MPG123_Stop(void *context)
352 {
353 MPG123_Music *music = (MPG123_Music *)context;
354 SDL_AudioStreamClear(music->stream);
355 }
356
349357 /* read some mp3 stream data and convert it for output */
350358 static int MPG123_GetSome(void *context, void *data, int bytes, SDL_bool *done)
351359 {
393401 if (music->stream) {
394402 SDL_FreeAudioStream(music->stream);
395403 }
404
396405 music->stream = SDL_NewAudioStream((SDL_AudioFormat)format, (Uint8)channels, (int)rate,
397406 music_spec.format, music_spec.channels, music_spec.freq);
398407 if (!music->stream) {
461470 return (double)music->total_length / music->sample_rate;
462471 }
463472
473 static const char* MPG123_GetMetaTag(void *context, Mix_MusicMetaTag tag_type)
474 {
475 MPG123_Music *music = (MPG123_Music *)context;
476 return meta_tags_get(&music->tags, tag_type);
477 }
478
464479 static void MPG123_Delete(void *context)
465480 {
466481 MPG123_Music *music = (MPG123_Music *)context;
467482
483 meta_tags_clear(&music->tags);
468484 if (music->handle) {
469485 mpg123.mpg123_close(music->handle);
470486 mpg123.mpg123_delete(music->handle);
510526 NULL, /* LoopStart */
511527 NULL, /* LoopEnd */
512528 NULL, /* LoopLength */
513 NULL, /* GetMetaTag */
529 MPG123_GetMetaTag,
514530 NULL, /* Pause */
515531 NULL, /* Resume */
516 NULL, /* Stop */
532 MPG123_Stop,
517533 MPG123_Delete,
518534 MPG123_Close,
519535 MPG123_Unload
1818 3. This notice may not be removed or altered from any source distribution.
1919 */
2020
21 #ifdef MUSIC_OGG
21 #if defined(MUSIC_OGG) && !defined(OGG_USE_STB)
2222
2323 /* This file supports Ogg Vorbis music streams */
2424
347347 return OGG_Seek(music, 0.0);
348348 }
349349
350 static void OGG_Stop(void *context)
351 {
352 OGG_music *music = (OGG_music *)context;
353 SDL_AudioStreamClear(music->stream);
354 }
355
350356 /* Play some of a stream previously started with OGG_play() */
351357 static int OGG_GetSome(void *context, void *data, int bytes, SDL_bool *done)
352358 {
538544 OGG_GetMetaTag, /* GetMetaTag */
539545 NULL, /* Pause */
540546 NULL, /* Resume */
541 NULL, /* Stop */
547 OGG_Stop,
542548 OGG_Delete,
543549 NULL, /* Close */
544550 OGG_Unload
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 #if defined(MUSIC_OGG) && defined(OGG_USE_STB)
22
23 /* This file supports Ogg Vorbis music streams using a modified stb_vorbis module */
24
25 #include "music_ogg.h"
26 #include "utils.h"
27 #include "SDL_assert.h"
28
29 #define STB_VORBIS_SDL 1 /* for SDL_mixer-specific stuff. */
30 #define STB_VORBIS_NO_STDIO 1
31 #define STB_VORBIS_NO_CRT 1
32 #define STB_VORBIS_NO_PUSHDATA_API 1
33 #define STB_VORBIS_MAX_CHANNELS 8 /* For 7.1 surround sound */
34 #define STB_FORCEINLINE SDL_FORCE_INLINE
35 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
36 #define STB_VORBIS_BIG_ENDIAN 1
37 #endif
38 #define STBV_CDECL SDLCALL /* for SDL_qsort */
39
40 #ifdef assert
41 #undef assert
42 #endif
43 #ifdef memset
44 #undef memset
45 #endif
46 #ifdef memcpy
47 #undef memcpy
48 #endif
49 #define assert SDL_assert
50 #define memset SDL_memset
51 #define memcmp SDL_memcmp
52 #define memcpy SDL_memcpy
53 #define qsort SDL_qsort
54 #define malloc SDL_malloc
55 #define realloc SDL_realloc
56 #define free SDL_free
57
58 #define pow SDL_pow
59 #define floor SDL_floor
60 #define ldexp(v, e) SDL_scalbn((v), (e))
61 #define abs(x) SDL_abs(x)
62 #define cos(x) SDL_cos(x)
63 #define sin(x) SDL_sin(x)
64 #define log(x) SDL_log(x)
65 #define exp(x) SDL_exp(x)
66
67 #include "stb_vorbis/stb_vorbis.h"
68
69 typedef struct {
70 SDL_RWops *src;
71 int freesrc;
72 int play_count;
73 int volume;
74 stb_vorbis *vf;
75 stb_vorbis_info vi;
76 int section;
77 SDL_AudioStream *stream;
78 char *buffer;
79 int buffer_size;
80 int loop;
81 Sint64 loop_start;
82 Sint64 loop_end;
83 Sint64 loop_len;
84 Sint64 full_length;
85 Mix_MusicMetaTags tags;
86 } OGG_music;
87
88 static int set_ov_error(const char *function, int error)
89 {
90 #define HANDLE_ERROR_CASE(X) case X: Mix_SetError("%s: %s", function, #X); break;
91 switch (error) {
92 HANDLE_ERROR_CASE(VORBIS_need_more_data)
93 HANDLE_ERROR_CASE(VORBIS_invalid_api_mixing)
94 HANDLE_ERROR_CASE(VORBIS_outofmem)
95 HANDLE_ERROR_CASE(VORBIS_feature_not_supported)
96 HANDLE_ERROR_CASE(VORBIS_too_many_channels)
97 HANDLE_ERROR_CASE(VORBIS_file_open_failure)
98 HANDLE_ERROR_CASE(VORBIS_seek_without_length)
99 HANDLE_ERROR_CASE(VORBIS_unexpected_eof)
100 HANDLE_ERROR_CASE(VORBIS_seek_invalid)
101 HANDLE_ERROR_CASE(VORBIS_invalid_setup)
102 HANDLE_ERROR_CASE(VORBIS_invalid_stream)
103 HANDLE_ERROR_CASE(VORBIS_missing_capture_pattern)
104 HANDLE_ERROR_CASE(VORBIS_invalid_stream_structure_version)
105 HANDLE_ERROR_CASE(VORBIS_continued_packet_flag_invalid)
106 HANDLE_ERROR_CASE(VORBIS_incorrect_stream_serial_number)
107 HANDLE_ERROR_CASE(VORBIS_invalid_first_page)
108 HANDLE_ERROR_CASE(VORBIS_bad_packet_type)
109 HANDLE_ERROR_CASE(VORBIS_cant_find_last_page)
110 HANDLE_ERROR_CASE(VORBIS_seek_failed)
111 HANDLE_ERROR_CASE(VORBIS_ogg_skeleton_not_supported)
112 default:
113 Mix_SetError("%s: unknown error %d\n", function, error);
114 break;
115 }
116 return -1;
117 }
118
119 static int OGG_Seek(void *context, double time);
120 static void OGG_Delete(void *context);
121
122 static int OGG_UpdateSection(OGG_music *music)
123 {
124 stb_vorbis_info vi;
125
126 vi = stb_vorbis_get_info(music->vf);
127
128 if (vi.channels == music->vi.channels && vi.sample_rate == music->vi.sample_rate) {
129 return 0;
130 }
131 SDL_memcpy(&music->vi, &vi, sizeof(vi));
132
133 if (music->buffer) {
134 SDL_free(music->buffer);
135 music->buffer = NULL;
136 }
137
138 if (music->stream) {
139 SDL_FreeAudioStream(music->stream);
140 music->stream = NULL;
141 }
142
143 music->stream = SDL_NewAudioStream(AUDIO_F32SYS, (Uint8)vi.channels, (int)vi.sample_rate,
144 music_spec.format, music_spec.channels, music_spec.freq);
145 if (!music->stream) {
146 return -1;
147 }
148
149 music->buffer_size = music_spec.samples * (int)sizeof(float) * vi.channels;
150 if (music->buffer_size <= 0) {
151 return -1;
152 }
153
154 music->buffer = (char *)SDL_malloc((size_t)music->buffer_size);
155 if (!music->buffer) {
156 return -1;
157 }
158 return 0;
159 }
160
161 /* Load an OGG stream from an SDL_RWops object */
162 static void *OGG_CreateFromRW(SDL_RWops *src, int freesrc)
163 {
164 OGG_music *music;
165 stb_vorbis_comment vc;
166 long rate;
167 SDL_bool is_loop_length = SDL_FALSE;
168 int i, error;
169
170 music = (OGG_music *)SDL_calloc(1, sizeof *music);
171 if (!music) {
172 SDL_OutOfMemory();
173 return NULL;
174 }
175 music->src = src;
176 music->volume = MIX_MAX_VOLUME;
177 music->section = -1;
178
179 music->vf = stb_vorbis_open_rwops(src, 0, &error, NULL);
180
181 if (music->vf == NULL) {
182 set_ov_error("stb_vorbis_open_rwops", error);
183 SDL_free(music);
184 return NULL;
185 }
186
187 if (OGG_UpdateSection(music) < 0) {
188 OGG_Delete(music);
189 return NULL;
190 }
191
192 music->vi = stb_vorbis_get_info(music->vf);
193 if ((int)music->vi.sample_rate <= 0) {
194 Mix_SetError("Invalid sample rate value");
195 OGG_Delete(music);
196 return NULL;
197 }
198
199 rate = music->vi.sample_rate;
200 vc = stb_vorbis_get_comment(music->vf);
201 if (vc.comment_list != NULL) {
202 for (i = 0; i < vc.comment_list_length; i++) {
203 char *param = SDL_strdup(vc.comment_list[i]);
204 char *argument = param;
205 char *value = SDL_strchr(param, '=');
206 if (value == NULL) {
207 value = param + SDL_strlen(param);
208 } else {
209 *(value++) = '\0';
210 }
211
212 /* Want to match LOOP-START, LOOP_START, etc. Remove - or _ from
213 * string if it is present at position 4. */
214 if (_Mix_IsLoopTag(argument) && ((argument[4] == '_') || (argument[4] == '-'))) {
215 SDL_memmove(argument + 4, argument + 5, SDL_strlen(argument) - 4);
216 }
217
218 if (SDL_strcasecmp(argument, "LOOPSTART") == 0)
219 music->loop_start = _Mix_ParseTime(value, rate);
220 else if (SDL_strcasecmp(argument, "LOOPLENGTH") == 0) {
221 music->loop_len = SDL_strtoll(value, NULL, 10);
222 is_loop_length = SDL_TRUE;
223 } else if (SDL_strcasecmp(argument, "LOOPEND") == 0) {
224 music->loop_end = _Mix_ParseTime(value, rate);
225 is_loop_length = SDL_FALSE;
226 } else if (SDL_strcasecmp(argument, "TITLE") == 0) {
227 meta_tags_set(&music->tags, MIX_META_TITLE, value);
228 } else if (SDL_strcasecmp(argument, "ARTIST") == 0) {
229 meta_tags_set(&music->tags, MIX_META_ARTIST, value);
230 } else if (SDL_strcasecmp(argument, "ALBUM") == 0) {
231 meta_tags_set(&music->tags, MIX_META_ALBUM, value);
232 } else if (SDL_strcasecmp(argument, "COPYRIGHT") == 0) {
233 meta_tags_set(&music->tags, MIX_META_COPYRIGHT, value);
234 }
235 SDL_free(param);
236 }
237
238 if (is_loop_length) {
239 music->loop_end = music->loop_start + music->loop_len;
240 } else {
241 music->loop_len = music->loop_end - music->loop_start;
242 }
243
244 /* Ignore invalid loop tag */
245 if (music->loop_start < 0 || music->loop_len < 0 || music->loop_end < 0) {
246 music->loop_start = 0;
247 music->loop_len = 0;
248 music->loop_end = 0;
249 }
250 }
251
252 music->full_length = stb_vorbis_stream_length_in_samples(music->vf);
253 if ((music->loop_end > 0) && (music->loop_end <= music->full_length) &&
254 (music->loop_start < music->loop_end)) {
255 music->loop = 1;
256 }
257
258 OGG_Seek(music, 0.0);
259
260 music->freesrc = freesrc;
261 return music;
262 }
263
264 static const char* OGG_GetMetaTag(void *context, Mix_MusicMetaTag tag_type)
265 {
266 OGG_music *music = (OGG_music *)context;
267 return meta_tags_get(&music->tags, tag_type);
268 }
269
270 /* Set the volume for an OGG stream */
271 static void OGG_SetVolume(void *context, int volume)
272 {
273 OGG_music *music = (OGG_music *)context;
274 music->volume = volume;
275 }
276
277 /* Get the volume for an OGG stream */
278 static int OGG_GetVolume(void *context)
279 {
280 OGG_music *music = (OGG_music *)context;
281 return music->volume;
282 }
283
284 /* Start playback of a given OGG stream */
285 static int OGG_Play(void *context, int play_count)
286 {
287 OGG_music *music = (OGG_music *)context;
288 music->play_count = play_count;
289 return OGG_Seek(music, 0.0);
290 }
291
292 static void OGG_Stop(void *context)
293 {
294 OGG_music *music = (OGG_music *)context;
295 SDL_AudioStreamClear(music->stream);
296 }
297
298 /* Play some of a stream previously started with OGG_play() */
299 static int OGG_GetSome(void *context, void *data, int bytes, SDL_bool *done)
300 {
301 OGG_music *music = (OGG_music *)context;
302 SDL_bool looped = SDL_FALSE;
303 int filled, amount, result;
304 int section;
305 Sint64 pcmPos;
306
307 filled = SDL_AudioStreamGet(music->stream, data, bytes);
308 if (filled != 0) {
309 return filled;
310 }
311
312 if (!music->play_count) {
313 /* All done */
314 *done = SDL_TRUE;
315 return 0;
316 }
317
318 section = music->section;
319 amount = stb_vorbis_get_samples_float_interleaved(music->vf,
320 music->vi.channels,
321 (float *)music->buffer,
322 music_spec.samples * music->vi.channels);
323
324 amount *= music->vi.channels * sizeof(float);
325
326 if (section != music->section) {
327 music->section = section;
328 if (OGG_UpdateSection(music) < 0) {
329 return -1;
330 }
331 }
332
333 pcmPos = stb_vorbis_get_playback_sample_offset(music->vf);
334 if (music->loop && (music->play_count != 1) && (pcmPos >= music->loop_end)) {
335 amount -= (int)((pcmPos - music->loop_end) * music->vi.channels) * (int)sizeof(float);
336 result = stb_vorbis_seek(music->vf, (Uint32)music->loop_start);
337 if (!result) {
338 set_ov_error("stb_vorbis_seek", stb_vorbis_get_error(music->vf));
339 return -1;
340 } else {
341 int play_count = -1;
342 if (music->play_count > 0) {
343 play_count = (music->play_count - 1);
344 }
345 music->play_count = play_count;
346 }
347 looped = SDL_TRUE;
348 }
349
350 if (amount > 0) {
351 if (SDL_AudioStreamPut(music->stream, music->buffer, amount) < 0) {
352 return -1;
353 }
354 } else if (!looped) {
355 if (music->play_count == 1) {
356 music->play_count = 0;
357 SDL_AudioStreamFlush(music->stream);
358 } else {
359 int play_count = -1;
360 if (music->play_count > 0) {
361 play_count = (music->play_count - 1);
362 }
363 if (OGG_Play(music, play_count) < 0) {
364 return -1;
365 }
366 }
367 }
368 return 0;
369 }
370 static int OGG_GetAudio(void *context, void *data, int bytes)
371 {
372 OGG_music *music = (OGG_music *)context;
373 return music_pcm_getaudio(context, data, bytes, music->volume, OGG_GetSome);
374 }
375
376 /* Jump (seek) to a given position (time is in seconds) */
377 static int OGG_Seek(void *context, double time)
378 {
379 OGG_music *music = (OGG_music *)context;
380 int result;
381
382 result = stb_vorbis_seek(music->vf, (unsigned int)(time * music->vi.sample_rate));
383 if (!result) {
384 set_ov_error("stb_vorbis_seek", stb_vorbis_get_error(music->vf));
385 return -1;
386 }
387 return 0;
388 }
389
390 static double OGG_Tell(void *context)
391 {
392 OGG_music *music = (OGG_music *)context;
393 return (double)stb_vorbis_get_playback_sample_offset(music->vf) / music->vi.sample_rate;
394 }
395
396 /* Return music duration in seconds */
397 static double OGG_Duration(void *context)
398 {
399 OGG_music *music = (OGG_music *)context;
400 return (double)music->full_length / music->vi.sample_rate;
401 }
402
403 static double OGG_LoopStart(void *music_p)
404 {
405 OGG_music *music = (OGG_music *)music_p;
406 if (music->loop > 0) {
407 return (double)music->loop_start / music->vi.sample_rate;
408 }
409 return -1.0;
410 }
411
412 static double OGG_LoopEnd(void *music_p)
413 {
414 OGG_music *music = (OGG_music *)music_p;
415 if (music->loop > 0) {
416 return (double)music->loop_end / music->vi.sample_rate;
417 }
418 return -1.0;
419 }
420
421 static double OGG_LoopLength(void *music_p)
422 {
423 OGG_music *music = (OGG_music *)music_p;
424 if (music->loop > 0) {
425 return (double)music->loop_len / music->vi.sample_rate;
426 }
427 return -1.0;
428 }
429
430
431 /* Close the given OGG stream */
432 static void OGG_Delete(void *context)
433 {
434 OGG_music *music = (OGG_music *)context;
435 meta_tags_clear(&music->tags);
436 stb_vorbis_close(music->vf);
437 if (music->stream) {
438 SDL_FreeAudioStream(music->stream);
439 }
440 if (music->buffer) {
441 SDL_free(music->buffer);
442 }
443 if (music->freesrc) {
444 SDL_RWclose(music->src);
445 }
446 SDL_free(music);
447 }
448
449 Mix_MusicInterface Mix_MusicInterface_OGG =
450 {
451 "OGG",
452 MIX_MUSIC_OGG,
453 MUS_OGG,
454 SDL_FALSE,
455 SDL_FALSE,
456
457 NULL, /* Load */
458 NULL, /* Open */
459 OGG_CreateFromRW,
460 NULL, /* CreateFromFile */
461 OGG_SetVolume,
462 OGG_GetVolume,
463 OGG_Play,
464 NULL, /* IsPlaying */
465 OGG_GetAudio,
466 NULL, /* Jump */
467 OGG_Seek,
468 OGG_Tell,
469 OGG_Duration,
470 OGG_LoopStart,
471 OGG_LoopEnd,
472 OGG_LoopLength,
473 OGG_GetMetaTag, /* GetMetaTag */
474 NULL, /* Pause */
475 NULL, /* Resume */
476 OGG_Stop,
477 OGG_Delete,
478 NULL, /* Close */
479 NULL /* Unload */
480 };
481
482 #endif /* MUSIC_OGG */
483
484 /* vi: set ts=4 sw=4 expandtab: */
2727 #include "music_opus.h"
2828 #include "utils.h"
2929
30 #ifdef OPUSFILE_HEADER
31 #include OPUSFILE_HEADER
32 #else
3033 #include <opus/opusfile.h>
34 #endif
3135
3236 typedef struct {
3337 int loaded;
330334 return OPUS_Seek(music, 0.0);
331335 }
332336
337 /* Clean-up the output buffer */
338 static void OPUS_Stop(void *context)
339 {
340 OPUS_music *music = (OPUS_music *)context;
341 SDL_AudioStreamClear(music->stream);
342 }
343
333344 /* Play some of a stream previously started with OPUS_Play() */
334345 static int OPUS_GetSome(void *context, void *data, int bytes, SDL_bool *done)
335346 {
504515 OPUS_GetMetaTag,
505516 NULL, /* Pause */
506517 NULL, /* Resume */
507 NULL, /* Stop */
518 OPUS_Stop,
508519 OPUS_Delete,
509520 NULL, /* Close */
510521 OPUS_Unload
2323 /* This file supports streaming WAV files */
2424
2525 #include "music_wav.h"
26
26 #include "mp3utils.h"
2727
2828 typedef struct {
2929 SDL_bool active;
246246 return -1;
247247 }
248248 return 0;
249 }
250
251 static void WAV_Stop(void *context)
252 {
253 WAV_Music *music = (WAV_Music *)context;
254 SDL_AudioStreamClear(music->stream);
249255 }
250256
251257 static int fetch_pcm(void *context, int length)
651657 Mix_SetError("Couldn't read %d bytes from WAV file", chunk_length);
652658 return SDL_FALSE;
653659 }
654 chunk_length -= size;
660 chunk_length = (Uint32)(chunk_length - size);
655661 if (chunk_length != 0 && SDL_RWseek(wave->src, chunk_length, RW_SEEK_CUR) < 0) {
656662 Mix_SetError("Couldn't read %d bytes from WAV file", chunk_length);
657663 return SDL_FALSE;
869875 return SDL_TRUE;
870876 }
871877
878 static SDL_bool ParseID3(WAV_Music *wave, Uint32 chunk_length)
879 {
880 SDL_bool loaded = SDL_TRUE;
881
882 Uint8 *data;
883 data = (Uint8 *)SDL_malloc(chunk_length);
884
885 if (!data) {
886 SDL_OutOfMemory();
887 return SDL_FALSE;
888 }
889
890 if (!SDL_RWread(wave->src, data, chunk_length, 1)) {
891 Mix_SetError("Couldn't read %d bytes from WAV file", chunk_length);
892 loaded = SDL_FALSE;
893 }
894
895 if (loaded) {
896 read_id3v2_from_mem(&wave->tags, data, chunk_length);
897 }
898
899 /* done: */
900 SDL_free(data);
901
902 return loaded;
903 }
904
872905 static SDL_bool LoadWAVMusic(WAV_Music *wave)
873906 {
874907 SDL_RWops *src = wave->src;
915948 break;
916949 case LIST:
917950 if (!ParseLIST(wave, chunk_length))
951 return SDL_FALSE;
952 break;
953 case ID3_:
954 if (!ParseID3(wave, chunk_length))
918955 return SDL_FALSE;
919956 break;
920957 default:
10331070 found_FVER = SDL_TRUE;
10341071 AIFCVersion1 = SDL_ReadBE32(src);
10351072 (void)AIFCVersion1; /* unused */
1073 break;
1074
1075 case AIFF_ID3_:
1076 if (!ParseID3(wave, chunk_length))
1077 return SDL_FALSE;
10361078 break;
10371079
10381080 case MARK:
12131255 WAV_GetMetaTag, /* GetMetaTag */
12141256 NULL, /* Pause */
12151257 NULL, /* Resume */
1216 NULL, /* Stop */
1258 WAV_Stop, /* Stop */
12171259 WAV_Delete,
12181260 NULL, /* Close */
12191261 NULL /* Unload */
282282 XMP_Music *music = (XMP_Music *)context;
283283 music->play_count = play_count;
284284 return XMP_Seek(music, 0);
285 }
286
287 /* Clean-up the output buffer */
288 static void XMP_Stop(void *context)
289 {
290 XMP_Music *music = (XMP_Music *)context;
291 SDL_AudioStreamClear(music->stream);
285292 }
286293
287294 /* Play some of a stream previously started with xmp_play() */
420427 XMP_GetMetaTag,
421428 NULL, /* Pause */
422429 NULL, /* Resume */
423 NULL, /* Stop */
430 XMP_Stop,
424431 XMP_Delete,
425432 NULL, /* Close */
426433 XMP_Unload
293293 if (song == NULL)
294294 return;
295295
296 SDL_PauseAudio(1);
297 Mix_UnlockAudio();
298
299296 if (currentsong)
300297 MusicPlayerStop(currentsong->player);
301298
314311
315312 MusicPlayerSetTime(song->player, 0);
316313 MusicPlayerStart(song->player);
317
318 Mix_LockAudio();
319 SDL_PauseAudio(0);
320314 }
321315
322316 void native_midi_pause(void)
330324 void native_midi_stop(void)
331325 {
332326 if (currentsong) {
333 SDL_PauseAudio(1);
334 Mix_UnlockAudio();
335327 MusicPlayerStop(currentsong->player);
336328 currentsong = NULL;
337 Mix_LockAudio();
338 SDL_PauseAudio(0);
339329 }
340330 }
341331
0 stb
1 -------------------
2 single-file public domain (or MIT licensed) libraries for C/C++
3 -------------------
4 https://github.com/nothings/stb
5 -------------------
6 stv_vorbis.c (renamed into h) version 1.22
7
8 decode ogg vorbis files from file/memory to float/16-bit signed output
0 // Ogg Vorbis audio decoder - v1.22 - public domain
1 // http://nothings.org/stb_vorbis/
2 //
3 // Original version written by Sean Barrett in 2007.
4 //
5 // Originally sponsored by RAD Game Tools. Seeking implementation
6 // sponsored by Phillip Bennefall, Marc Andersen, Aaron Baker,
7 // Elias Software, Aras Pranckevicius, and Sean Barrett.
8 //
9 // LICENSE
10 //
11 // See end of file for license information.
12 //
13 // Limitations:
14 //
15 // - floor 0 not supported (used in old ogg vorbis files pre-2004)
16 // - lossless sample-truncation at beginning ignored
17 // - cannot concatenate multiple vorbis streams
18 // - sample positions are 32-bit, limiting seekable 192Khz
19 // files to around 6 hours (Ogg supports 64-bit)
20 //
21 // Feature contributors:
22 // Dougall Johnson (sample-exact seeking)
23 // Vitaly Novichkov (sample-accurate tell)
24 //
25 // Bugfix/warning contributors:
26 // Terje Mathisen Niklas Frykholm Andy Hill
27 // Casey Muratori John Bolton Gargaj
28 // Laurent Gomila Marc LeBlanc Ronny Chevalier
29 // Bernhard Wodo Evan Balster github:alxprd
30 // Tom Beaumont Ingo Leitgeb Nicolas Guillemot
31 // Phillip Bennefall Rohit Thiago Goulart
32 // github:manxorist Saga Musix github:infatum
33 // Timur Gagiev Maxwell Koo Peter Waller
34 // github:audinowho Dougall Johnson David Reid
35 // github:Clownacy Pedro J. Estebanez Remi Verschelde
36 // AnthoFoxo github:morlat Gabriel Ravier
37 // Alice Rowan
38 //
39 // Partial history:
40 // 1.22 - 2021-07-11 - various small fixes
41 // 1.21 - 2021-07-02 - fix bug for files with no comments
42 // 1.20 - 2020-07-11 - several small fixes
43 // 1.19 - 2020-02-05 - warnings
44 // 1.18 - 2020-02-02 - fix seek bugs; parse header comments; misc warnings etc.
45 // 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure)
46 // 1.16 - 2019-03-04 - fix warnings
47 // 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
48 // 1.14 - 2018-02-11 - delete bogus dealloca usage
49 // 1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
50 // 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
51 // 1.11 - 2017-07-23 - fix MinGW compilation
52 // 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory
53 // 1.09 - 2016-04-04 - back out 'truncation of last frame' fix from previous version
54 // 1.08 - 2016-04-02 - warnings; setup memory leaks; truncation of last frame
55 // 1.07 - 2015-01-16 - fixes for crashes on invalid files; warning fixes; const
56 // 1.06 - 2015-08-31 - full, correct support for seeking API (Dougall Johnson)
57 // some crash fixes when out of memory or with corrupt files
58 // fix some inappropriately signed shifts
59 // 1.05 - 2015-04-19 - don't define __forceinline if it's redundant
60 // 1.04 - 2014-08-27 - fix missing const-correct case in API
61 // 1.03 - 2014-08-07 - warning fixes
62 // 1.02 - 2014-07-09 - declare qsort comparison as explicitly _cdecl in Windows
63 // 1.01 - 2014-06-18 - fix stb_vorbis_get_samples_float (interleaved was correct)
64 // 1.0 - 2014-05-26 - fix memory leaks; fix warnings; fix bugs in >2-channel;
65 // (API change) report sample rate for decode-full-file funcs
66 //
67 // See end of file for full version history.
68
69
70 //////////////////////////////////////////////////////////////////////////////
71 //
72 // HEADER BEGINS HERE
73 //
74
75 #ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H
76 #define STB_VORBIS_INCLUDE_STB_VORBIS_H
77
78 #if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO)
79 #define STB_VORBIS_NO_STDIO 1
80 #endif
81
82 #ifndef STB_VORBIS_NO_STDIO
83 #include <stdio.h>
84 #endif
85
86 #ifdef __cplusplus
87 extern "C" {
88 #endif
89
90 /////////// THREAD SAFETY
91
92 // Individual stb_vorbis* handles are not thread-safe; you cannot decode from
93 // them from multiple threads at the same time. However, you can have multiple
94 // stb_vorbis* handles and decode from them independently in multiple thrads.
95
96
97 /////////// MEMORY ALLOCATION
98
99 // normally stb_vorbis uses malloc() to allocate memory at startup,
100 // and alloca() to allocate temporary memory during a frame on the
101 // stack. (Memory consumption will depend on the amount of setup
102 // data in the file and how you set the compile flags for speed
103 // vs. size. In my test files the maximal-size usage is ~150KB.)
104 //
105 // You can modify the wrapper functions in the source (setup_malloc,
106 // setup_temp_malloc, temp_malloc) to change this behavior, or you
107 // can use a simpler allocation model: you pass in a buffer from
108 // which stb_vorbis will allocate _all_ its memory (including the
109 // temp memory). "open" may fail with a VORBIS_outofmem if you
110 // do not pass in enough data; there is no way to determine how
111 // much you do need except to succeed (at which point you can
112 // query get_info to find the exact amount required. yes I know
113 // this is lame).
114 //
115 // If you pass in a non-NULL buffer of the type below, allocation
116 // will occur from it as described above. Otherwise just pass NULL
117 // to use malloc()/alloca()
118
119 typedef struct
120 {
121 char *alloc_buffer;
122 int alloc_buffer_length_in_bytes;
123 } stb_vorbis_alloc;
124
125
126 /////////// FUNCTIONS USEABLE WITH ALL INPUT MODES
127
128 typedef struct stb_vorbis stb_vorbis;
129
130 typedef struct
131 {
132 unsigned int sample_rate;
133 int channels;
134
135 unsigned int setup_memory_required;
136 unsigned int setup_temp_memory_required;
137 unsigned int temp_memory_required;
138
139 int max_frame_size;
140 } stb_vorbis_info;
141
142 typedef struct
143 {
144 char *vendor;
145
146 int comment_list_length;
147 char **comment_list;
148 } stb_vorbis_comment;
149
150 // get general information about the file
151 extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f);
152
153 // get ogg comments
154 extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f);
155
156 // get the last error detected (clears it, too)
157 extern int stb_vorbis_get_error(stb_vorbis *f);
158
159 // close an ogg vorbis file and free all memory in use
160 extern void stb_vorbis_close(stb_vorbis *f);
161
162 // this function returns the offset (in samples) from the beginning of the
163 // file that will be returned by the next decode, if it is known, or -1
164 // otherwise. after a flush_pushdata() call, this may take a while before
165 // it becomes valid again.
166 // NOT WORKING YET after a seek with PULLDATA API
167 extern int stb_vorbis_get_sample_offset(stb_vorbis *f);
168
169 // this function returns the count of returned samples from the beginning of the
170 // file. Functions "stb_vorbis_get_samples_*", "stb_vorbis_seek_*()" will
171 // affect the returned value. Use this call to get the accurate sample position
172 // during playback.
173 extern int stb_vorbis_get_playback_sample_offset(stb_vorbis *f);
174
175 // returns the current seek point within the file, or offset from the beginning
176 // of the memory buffer. In pushdata mode it returns 0.
177 extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f);
178
179 /////////// PUSHDATA API
180
181 #ifndef STB_VORBIS_NO_PUSHDATA_API
182
183 // this API allows you to get blocks of data from any source and hand
184 // them to stb_vorbis. you have to buffer them; stb_vorbis will tell
185 // you how much it used, and you have to give it the rest next time;
186 // and stb_vorbis may not have enough data to work with and you will
187 // need to give it the same data again PLUS more. Note that the Vorbis
188 // specification does not bound the size of an individual frame.
189
190 extern stb_vorbis *stb_vorbis_open_pushdata(
191 const unsigned char * datablock, int datablock_length_in_bytes,
192 int *datablock_memory_consumed_in_bytes,
193 int *error,
194 const stb_vorbis_alloc *alloc_buffer);
195 // create a vorbis decoder by passing in the initial data block containing
196 // the ogg&vorbis headers (you don't need to do parse them, just provide
197 // the first N bytes of the file--you're told if it's not enough, see below)
198 // on success, returns an stb_vorbis *, does not set error, returns the amount of
199 // data parsed/consumed on this call in *datablock_memory_consumed_in_bytes;
200 // on failure, returns NULL on error and sets *error, does not change *datablock_memory_consumed
201 // if returns NULL and *error is VORBIS_need_more_data, then the input block was
202 // incomplete and you need to pass in a larger block from the start of the file
203
204 extern int stb_vorbis_decode_frame_pushdata(
205 stb_vorbis *f,
206 const unsigned char *datablock, int datablock_length_in_bytes,
207 int *channels, // place to write number of float * buffers
208 float ***output, // place to write float ** array of float * buffers
209 int *samples // place to write number of output samples
210 );
211 // decode a frame of audio sample data if possible from the passed-in data block
212 //
213 // return value: number of bytes we used from datablock
214 //
215 // possible cases:
216 // 0 bytes used, 0 samples output (need more data)
217 // N bytes used, 0 samples output (resynching the stream, keep going)
218 // N bytes used, M samples output (one frame of data)
219 // note that after opening a file, you will ALWAYS get one N-bytes,0-sample
220 // frame, because Vorbis always "discards" the first frame.
221 //
222 // Note that on resynch, stb_vorbis will rarely consume all of the buffer,
223 // instead only datablock_length_in_bytes-3 or less. This is because it wants
224 // to avoid missing parts of a page header if they cross a datablock boundary,
225 // without writing state-machiney code to record a partial detection.
226 //
227 // The number of channels returned are stored in *channels (which can be
228 // NULL--it is always the same as the number of channels reported by
229 // get_info). *output will contain an array of float* buffers, one per
230 // channel. In other words, (*output)[0][0] contains the first sample from
231 // the first channel, and (*output)[1][0] contains the first sample from
232 // the second channel.
233 //
234 // *output points into stb_vorbis's internal output buffer storage; these
235 // buffers are owned by stb_vorbis and application code should not free
236 // them or modify their contents. They are transient and will be overwritten
237 // once you ask for more data to get decoded, so be sure to grab any data
238 // you need before then.
239
240 extern void stb_vorbis_flush_pushdata(stb_vorbis *f);
241 // inform stb_vorbis that your next datablock will not be contiguous with
242 // previous ones (e.g. you've seeked in the data); future attempts to decode
243 // frames will cause stb_vorbis to resynchronize (as noted above), and
244 // once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it
245 // will begin decoding the _next_ frame.
246 //
247 // if you want to seek using pushdata, you need to seek in your file, then
248 // call stb_vorbis_flush_pushdata(), then start calling decoding, then once
249 // decoding is returning you data, call stb_vorbis_get_sample_offset, and
250 // if you don't like the result, seek your file again and repeat.
251 #endif
252
253
254 ////////// PULLING INPUT API
255
256 #ifndef STB_VORBIS_NO_PULLDATA_API
257 // This API assumes stb_vorbis is allowed to pull data from a source--
258 // either a block of memory containing the _entire_ vorbis stream, or a
259 // FILE * that you or it create, or possibly some other reading mechanism
260 // if you go modify the source to replace the FILE * case with some kind
261 // of callback to your code. (But if you don't support seeking, you may
262 // just want to go ahead and use pushdata.)
263
264 #if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
265 extern int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output);
266 #endif
267 #if !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
268 extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output);
269 #endif
270 // decode an entire file and output the data interleaved into a malloc()ed
271 // buffer stored in *output. The return value is the number of samples
272 // decoded, or -1 if the file could not be opened or was not an ogg vorbis file.
273 // When you're done with it, just free() the pointer returned in *output.
274
275 extern stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len,
276 int *error, const stb_vorbis_alloc *alloc_buffer);
277 // create an ogg vorbis decoder from an ogg vorbis stream in memory (note
278 // this must be the entire stream!). on failure, returns NULL and sets *error
279
280 #ifndef STB_VORBIS_NO_STDIO
281 extern stb_vorbis * stb_vorbis_open_filename(const char *filename,
282 int *error, const stb_vorbis_alloc *alloc_buffer);
283 // create an ogg vorbis decoder from a filename via fopen(). on failure,
284 // returns NULL and sets *error (possibly to VORBIS_file_open_failure).
285
286 extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
287 int *error, const stb_vorbis_alloc *alloc_buffer);
288 // create an ogg vorbis decoder from an open FILE *, looking for a stream at
289 // the _current_ seek point (ftell). on failure, returns NULL and sets *error.
290 // note that stb_vorbis must "own" this stream; if you seek it in between
291 // calls to stb_vorbis, it will become confused. Moreover, if you attempt to
292 // perform stb_vorbis_seek_*() operations on this file, it will assume it
293 // owns the _entire_ rest of the file after the start point. Use the next
294 // function, stb_vorbis_open_file_section(), to limit it.
295
296 extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close,
297 int *error, const stb_vorbis_alloc *alloc_buffer, unsigned int len);
298 // create an ogg vorbis decoder from an open FILE *, looking for a stream at
299 // the _current_ seek point (ftell); the stream will be of length 'len' bytes.
300 // on failure, returns NULL and sets *error. note that stb_vorbis must "own"
301 // this stream; if you seek it in between calls to stb_vorbis, it will become
302 // confused.
303 #endif
304
305 #ifdef STB_VORBIS_SDL
306 extern stb_vorbis * stb_vorbis_open_rwops_section(SDL_RWops *rwops, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length);
307 extern stb_vorbis * stb_vorbis_open_rwops(SDL_RWops *rwops, int close_on_free, int *error, const stb_vorbis_alloc *alloc);
308 #endif
309
310 extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number);
311 extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number);
312 // these functions seek in the Vorbis file to (approximately) 'sample_number'.
313 // after calling seek_frame(), the next call to get_frame_*() will include
314 // the specified sample. after calling stb_vorbis_seek(), the next call to
315 // stb_vorbis_get_samples_* will start with the specified sample. If you
316 // do not need to seek to EXACTLY the target sample when using get_samples_*,
317 // you can also use seek_frame().
318
319 extern int stb_vorbis_seek_start(stb_vorbis *f);
320 // this function is equivalent to stb_vorbis_seek(f,0)
321
322 extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);
323 extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f);
324 // these functions return the total length of the vorbis stream
325
326 extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output);
327 // decode the next frame and return the number of samples. the number of
328 // channels returned are stored in *channels (which can be NULL--it is always
329 // the same as the number of channels reported by get_info). *output will
330 // contain an array of float* buffers, one per channel. These outputs will
331 // be overwritten on the next call to stb_vorbis_get_frame_*.
332 //
333 // You generally should not intermix calls to stb_vorbis_get_frame_*()
334 // and stb_vorbis_get_samples_*(), since the latter calls the former.
335
336 #ifndef STB_VORBIS_NO_INTEGER_CONVERSION
337 extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts);
338 extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples);
339 #endif
340 // decode the next frame and return the number of *samples* per channel.
341 // Note that for interleaved data, you pass in the number of shorts (the
342 // size of your array), but the return value is the number of samples per
343 // channel, not the total number of samples.
344 //
345 // The data is coerced to the number of channels you request according to the
346 // channel coercion rules (see below). You must pass in the size of your
347 // buffer(s) so that stb_vorbis will not overwrite the end of the buffer.
348 // The maximum buffer size needed can be gotten from get_info(); however,
349 // the Vorbis I specification implies an absolute maximum of 4096 samples
350 // per channel.
351
352 // Channel coercion rules:
353 // Let M be the number of channels requested, and N the number of channels present,
354 // and Cn be the nth channel; let stereo L be the sum of all L and center channels,
355 // and stereo R be the sum of all R and center channels (channel assignment from the
356 // vorbis spec).
357 // M N output
358 // 1 k sum(Ck) for all k
359 // 2 * stereo L, stereo R
360 // k l k > l, the first l channels, then 0s
361 // k l k <= l, the first k channels
362 // Note that this is not _good_ surround etc. mixing at all! It's just so
363 // you get something useful.
364
365 extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats);
366 extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples);
367 // gets num_samples samples, not necessarily on a frame boundary--this requires
368 // buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES.
369 // Returns the number of samples stored per channel; it may be less than requested
370 // at the end of the file. If there are no more samples in the file, returns 0.
371
372 #ifndef STB_VORBIS_NO_INTEGER_CONVERSION
373 extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts);
374 extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples);
375 #endif
376 // gets num_samples samples, not necessarily on a frame boundary--this requires
377 // buffering so you have to supply the buffers. Applies the coercion rules above
378 // to produce 'channels' channels. Returns the number of samples stored per channel;
379 // it may be less than requested at the end of the file. If there are no more
380 // samples in the file, returns 0.
381
382 #endif
383
384 //////// ERROR CODES
385
386 enum STBVorbisError
387 {
388 VORBIS__no_error,
389
390 VORBIS_need_more_data=1, // not a real error
391
392 VORBIS_invalid_api_mixing, // can't mix API modes
393 VORBIS_outofmem, // not enough memory
394 VORBIS_feature_not_supported, // uses floor 0
395 VORBIS_too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small
396 VORBIS_file_open_failure, // fopen() failed
397 VORBIS_seek_without_length, // can't seek in unknown-length file
398
399 VORBIS_unexpected_eof=10, // file is truncated?
400 VORBIS_seek_invalid, // seek past EOF
401
402 // decoding errors (corrupt/invalid stream) -- you probably
403 // don't care about the exact details of these
404
405 // vorbis errors:
406 VORBIS_invalid_setup=20,
407 VORBIS_invalid_stream,
408
409 // ogg errors:
410 VORBIS_missing_capture_pattern=30,
411 VORBIS_invalid_stream_structure_version,
412 VORBIS_continued_packet_flag_invalid,
413 VORBIS_incorrect_stream_serial_number,
414 VORBIS_invalid_first_page,
415 VORBIS_bad_packet_type,
416 VORBIS_cant_find_last_page,
417 VORBIS_seek_failed,
418 VORBIS_ogg_skeleton_not_supported
419 };
420
421
422 #ifdef __cplusplus
423 }
424 #endif
425
426 #endif // STB_VORBIS_INCLUDE_STB_VORBIS_H
427 //
428 // HEADER ENDS HERE
429 //
430 //////////////////////////////////////////////////////////////////////////////
431
432 #ifndef STB_VORBIS_HEADER_ONLY
433
434 // global configuration settings (e.g. set these in the project/makefile),
435 // or just set them in this file at the top (although ideally the first few
436 // should be visible when the header file is compiled too, although it's not
437 // crucial)
438
439 // STB_VORBIS_NO_PUSHDATA_API
440 // does not compile the code for the various stb_vorbis_*_pushdata()
441 // functions
442 // #define STB_VORBIS_NO_PUSHDATA_API
443
444 // STB_VORBIS_NO_PULLDATA_API
445 // does not compile the code for the non-pushdata APIs
446 // #define STB_VORBIS_NO_PULLDATA_API
447
448 // STB_VORBIS_NO_STDIO
449 // does not compile the code for the APIs that use FILE *s internally
450 // or externally (implied by STB_VORBIS_NO_PULLDATA_API)
451 // #define STB_VORBIS_NO_STDIO
452
453 // STB_VORBIS_NO_INTEGER_CONVERSION
454 // does not compile the code for converting audio sample data from
455 // float to integer (implied by STB_VORBIS_NO_PULLDATA_API)
456 // #define STB_VORBIS_NO_INTEGER_CONVERSION
457
458 // STB_VORBIS_NO_FAST_SCALED_FLOAT
459 // does not use a fast float-to-int trick to accelerate float-to-int on
460 // most platforms which requires endianness be defined correctly.
461 //#define STB_VORBIS_NO_FAST_SCALED_FLOAT
462
463
464 // STB_VORBIS_MAX_CHANNELS [number]
465 // globally define this to the maximum number of channels you need.
466 // The spec does not put a restriction on channels except that
467 // the count is stored in a byte, so 255 is the hard limit.
468 // Reducing this saves about 16 bytes per value, so using 16 saves
469 // (255-16)*16 or around 4KB. Plus anything other memory usage
470 // I forgot to account for. Can probably go as low as 8 (7.1 audio),
471 // 6 (5.1 audio), or 2 (stereo only).
472 #ifndef STB_VORBIS_MAX_CHANNELS
473 #define STB_VORBIS_MAX_CHANNELS 16 // enough for anyone?
474 #endif
475
476 // STB_VORBIS_PUSHDATA_CRC_COUNT [number]
477 // after a flush_pushdata(), stb_vorbis begins scanning for the
478 // next valid page, without backtracking. when it finds something
479 // that looks like a page, it streams through it and verifies its
480 // CRC32. Should that validation fail, it keeps scanning. But it's
481 // possible that _while_ streaming through to check the CRC32 of
482 // one candidate page, it sees another candidate page. This #define
483 // determines how many "overlapping" candidate pages it can search
484 // at once. Note that "real" pages are typically ~4KB to ~8KB, whereas
485 // garbage pages could be as big as 64KB, but probably average ~16KB.
486 // So don't hose ourselves by scanning an apparent 64KB page and
487 // missing a ton of real ones in the interim; so minimum of 2
488 #ifndef STB_VORBIS_PUSHDATA_CRC_COUNT
489 #define STB_VORBIS_PUSHDATA_CRC_COUNT 4
490 #endif
491
492 // STB_VORBIS_FAST_HUFFMAN_LENGTH [number]
493 // sets the log size of the huffman-acceleration table. Maximum
494 // supported value is 24. with larger numbers, more decodings are O(1),
495 // but the table size is larger so worse cache missing, so you'll have
496 // to probe (and try multiple ogg vorbis files) to find the sweet spot.
497 #ifndef STB_VORBIS_FAST_HUFFMAN_LENGTH
498 #define STB_VORBIS_FAST_HUFFMAN_LENGTH 10
499 #endif
500
501 // STB_VORBIS_FAST_BINARY_LENGTH [number]
502 // sets the log size of the binary-search acceleration table. this
503 // is used in similar fashion to the fast-huffman size to set initial
504 // parameters for the binary search
505
506 // STB_VORBIS_FAST_HUFFMAN_INT
507 // The fast huffman tables are much more efficient if they can be
508 // stored as 16-bit results instead of 32-bit results. This restricts
509 // the codebooks to having only 65535 possible outcomes, though.
510 // (At least, accelerated by the huffman table.)
511 #ifndef STB_VORBIS_FAST_HUFFMAN_INT
512 #define STB_VORBIS_FAST_HUFFMAN_SHORT
513 #endif
514
515 // STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
516 // If the 'fast huffman' search doesn't succeed, then stb_vorbis falls
517 // back on binary searching for the correct one. This requires storing
518 // extra tables with the huffman codes in sorted order. Defining this
519 // symbol trades off space for speed by forcing a linear search in the
520 // non-fast case, except for "sparse" codebooks.
521 // #define STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
522
523 // STB_VORBIS_DIVIDES_IN_RESIDUE
524 // stb_vorbis precomputes the result of the scalar residue decoding
525 // that would otherwise require a divide per chunk. you can trade off
526 // space for time by defining this symbol.
527 // #define STB_VORBIS_DIVIDES_IN_RESIDUE
528
529 // STB_VORBIS_DIVIDES_IN_CODEBOOK
530 // vorbis VQ codebooks can be encoded two ways: with every case explicitly
531 // stored, or with all elements being chosen from a small range of values,
532 // and all values possible in all elements. By default, stb_vorbis expands
533 // this latter kind out to look like the former kind for ease of decoding,
534 // because otherwise an integer divide-per-vector-element is required to
535 // unpack the index. If you define STB_VORBIS_DIVIDES_IN_CODEBOOK, you can
536 // trade off storage for speed.
537 //#define STB_VORBIS_DIVIDES_IN_CODEBOOK
538
539 #ifdef STB_VORBIS_CODEBOOK_SHORTS
540 #error "STB_VORBIS_CODEBOOK_SHORTS is no longer supported as it produced incorrect results for some input formats"
541 #endif
542
543 // STB_VORBIS_DIVIDE_TABLE
544 // this replaces small integer divides in the floor decode loop with
545 // table lookups. made less than 1% difference, so disabled by default.
546
547 // STB_VORBIS_NO_INLINE_DECODE
548 // disables the inlining of the scalar codebook fast-huffman decode.
549 // might save a little codespace; useful for debugging
550 // #define STB_VORBIS_NO_INLINE_DECODE
551
552 // STB_VORBIS_NO_DEFER_FLOOR
553 // Normally we only decode the floor without synthesizing the actual
554 // full curve. We can instead synthesize the curve immediately. This
555 // requires more memory and is very likely slower, so I don't think
556 // you'd ever want to do it except for debugging.
557 // #define STB_VORBIS_NO_DEFER_FLOOR
558
559
560 //////////////////////////////////////////////////////////////////////////////
561
562 #ifdef STB_VORBIS_NO_PULLDATA_API
563 #define STB_VORBIS_NO_INTEGER_CONVERSION
564 #define STB_VORBIS_NO_STDIO
565 #endif
566
567 #if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO)
568 #define STB_VORBIS_NO_STDIO 1
569 #endif
570
571 #ifndef STB_VORBIS_NO_INTEGER_CONVERSION
572 #ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT
573
574 // only need endianness for fast-float-to-int, which we don't
575 // use for pushdata
576
577 #ifndef STB_VORBIS_BIG_ENDIAN
578 #define STB_VORBIS_ENDIAN 0
579 #else
580 #define STB_VORBIS_ENDIAN 1
581 #endif
582
583 #endif
584 #endif
585
586
587 #ifndef STB_VORBIS_NO_STDIO
588 #include <stdio.h>
589 #endif
590
591 #ifndef STB_VORBIS_NO_CRT
592 #include <stdlib.h>
593 #include <string.h>
594 #include <assert.h>
595 #include <math.h>
596 #else // STB_VORBIS_NO_CRT
597 #ifndef NULL
598 #define NULL 0
599 #endif
600 #ifndef malloc
601 #define malloc(s) 0
602 #endif
603 #ifndef free
604 #define free(p) ((void) 0)
605 #endif
606 #ifndef realloc
607 #define realloc(p, s) 0
608 #endif
609 #endif // STB_VORBIS_NO_CRT
610
611 #include <limits.h>
612
613 #ifndef STB_FORCEINLINE
614 #if defined(_MSC_VER)
615 #define STB_FORCEINLINE __forceinline
616 #elif (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2))) || defined(__clang__)
617 #define STB_FORCEINLINE static __inline __attribute__((always_inline))
618 #else
619 #define STB_FORCEINLINE static inline
620 #endif
621 #endif
622
623 #if STB_VORBIS_MAX_CHANNELS > 256
624 #error "Value of STB_VORBIS_MAX_CHANNELS outside of allowed range"
625 #endif
626
627 #if STB_VORBIS_FAST_HUFFMAN_LENGTH > 24
628 #error "Value of STB_VORBIS_FAST_HUFFMAN_LENGTH outside of allowed range"
629 #endif
630
631
632 #if 0
633 #include <crtdbg.h>
634 #define CHECK(f) _CrtIsValidHeapPointer(f->channel_buffers[1])
635 #else
636 #define CHECK(f) do {} while(0)
637 #endif
638
639 #define MAX_BLOCKSIZE_LOG 13 // from specification
640 #define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG)
641
642 #ifdef STB_VORBIS_SDL
643 typedef Uint8 uint8;
644 typedef Sint8 int8;
645 typedef Uint16 uint16;
646 typedef Sint16 int16;
647 typedef Uint32 uint32;
648 typedef Sint32 int32;
649 #else
650 typedef unsigned char uint8;
651 typedef signed char int8;
652 typedef unsigned short uint16;
653 typedef signed short int16;
654 typedef unsigned int uint32;
655 typedef signed int int32;
656 #endif
657
658 #ifdef __has_feature
659 #if __has_feature(undefined_behavior_sanitizer)
660 #define HAS_UBSAN
661 #endif
662 #endif
663 #ifdef HAS_UBSAN
664 #define STB_NO_SANITIZE(s) __attribute__((no_sanitize(s)))
665 #else
666 #define STB_NO_SANITIZE(s)
667 #endif
668
669 #ifndef TRUE
670 #define TRUE 1
671 #define FALSE 0
672 #endif
673
674 typedef float codetype;
675
676 #ifdef _MSC_VER
677 #define STBV_NOTUSED(v) (void)(v)
678 #else
679 #define STBV_NOTUSED(v) (void)sizeof(v)
680 #endif
681
682 // @NOTE
683 //
684 // Some arrays below are tagged "//varies", which means it's actually
685 // a variable-sized piece of data, but rather than malloc I assume it's
686 // small enough it's better to just allocate it all together with the
687 // main thing
688 //
689 // Most of the variables are specified with the smallest size I could pack
690 // them into. It might give better performance to make them all full-sized
691 // integers. It should be safe to freely rearrange the structures or change
692 // the sizes larger--nothing relies on silently truncating etc., nor the
693 // order of variables.
694
695 #define FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH)
696 #define FAST_HUFFMAN_TABLE_MASK (FAST_HUFFMAN_TABLE_SIZE - 1)
697
698 typedef struct
699 {
700 int dimensions, entries;
701 uint8 *codeword_lengths;
702 float minimum_value;
703 float delta_value;
704 uint8 value_bits;
705 uint8 lookup_type;
706 uint8 sequence_p;
707 uint8 sparse;
708 uint32 lookup_values;
709 codetype *multiplicands;
710 uint32 *codewords;
711 #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT
712 int16 fast_huffman[FAST_HUFFMAN_TABLE_SIZE];
713 #else
714 int32 fast_huffman[FAST_HUFFMAN_TABLE_SIZE];
715 #endif
716 uint32 *sorted_codewords;
717 int *sorted_values;
718 int sorted_entries;
719 } Codebook;
720
721 typedef struct
722 {
723 uint8 order;
724 uint16 rate;
725 uint16 bark_map_size;
726 uint8 amplitude_bits;
727 uint8 amplitude_offset;
728 uint8 number_of_books;
729 uint8 book_list[16]; // varies
730 } Floor0;
731
732 typedef struct
733 {
734 uint8 partitions;
735 uint8 partition_class_list[32]; // varies
736 uint8 class_dimensions[16]; // varies
737 uint8 class_subclasses[16]; // varies
738 uint8 class_masterbooks[16]; // varies
739 int16 subclass_books[16][8]; // varies
740 uint16 Xlist[31*8+2]; // varies
741 uint8 sorted_order[31*8+2];
742 uint8 neighbors[31*8+2][2];
743 uint8 floor1_multiplier;
744 uint8 rangebits;
745 int values;
746 } Floor1;
747
748 typedef union
749 {
750 Floor0 floor0;
751 Floor1 floor1;
752 } Floor;
753
754 typedef struct
755 {
756 uint32 begin, end;
757 uint32 part_size;
758 uint8 classifications;
759 uint8 classbook;
760 uint8 **classdata;
761 int16 (*residue_books)[8];
762 } Residue;
763
764 typedef struct
765 {
766 uint8 magnitude;
767 uint8 angle;
768 uint8 mux;
769 } MappingChannel;
770
771 typedef struct
772 {
773 // https://github.com/nothings/stb/pull/1312
774 MappingChannel *chan;
775 uint16 coupling_steps;
776 uint8 submaps;
777 uint8 submap_floor[16]; // varies
778 uint8 submap_residue[16]; // varies
779 } Mapping;
780
781 typedef struct
782 {
783 uint8 blockflag;
784 uint8 mapping;
785 uint16 windowtype;
786 uint16 transformtype;
787 } Mode;
788
789 typedef struct
790 {
791 uint32 goal_crc; // expected crc if match
792 int bytes_left; // bytes left in packet
793 uint32 crc_so_far; // running crc
794 int bytes_done; // bytes processed in _current_ chunk
795 uint32 sample_loc; // granule pos encoded in page
796 } CRCscan;
797
798 typedef struct
799 {
800 uint32 page_start, page_end;
801 uint32 last_decoded_sample;
802 } ProbedPage;
803
804 struct stb_vorbis
805 {
806 // user-accessible info
807 unsigned int sample_rate;
808 int channels;
809
810 unsigned int setup_memory_required;
811 unsigned int temp_memory_required;
812 unsigned int setup_temp_memory_required;
813
814 char *vendor;
815 int comment_list_length;
816 char **comment_list;
817
818 // input config
819 #ifndef STB_VORBIS_NO_STDIO
820 FILE *f;
821 uint32 f_start;
822 int close_on_free;
823 #endif
824 #ifdef STB_VORBIS_SDL
825 SDL_RWops *rwops;
826 uint32 rwops_start;
827 int close_on_free;
828 #endif
829
830 uint8 *stream;
831 uint8 *stream_start;
832 uint8 *stream_end;
833
834 uint32 stream_len;
835
836 uint8 push_mode;
837
838 // the page to seek to when seeking to start, may be zero
839 uint32 first_audio_page_offset;
840
841 // p_first is the page on which the first audio packet ends
842 // (but not necessarily the page on which it starts)
843 ProbedPage p_first, p_last;
844
845 // memory management
846 stb_vorbis_alloc alloc;
847 int setup_offset;
848 int temp_offset;
849
850 // run-time results
851 int eof;
852 enum STBVorbisError error;
853
854 // user-useful data
855
856 // header info
857 int blocksize[2];
858 int blocksize_0, blocksize_1;
859 int codebook_count;
860 Codebook *codebooks;
861 int floor_count;
862 uint16 floor_types[64]; // varies
863 Floor *floor_config;
864 int residue_count;
865 uint16 residue_types[64]; // varies
866 Residue *residue_config;
867 int mapping_count;
868 Mapping *mapping;
869 int mode_count;
870 Mode mode_config[64]; // varies
871
872 uint32 total_samples;
873
874 // decode buffer
875 float *channel_buffers[STB_VORBIS_MAX_CHANNELS];
876 float *outputs [STB_VORBIS_MAX_CHANNELS];
877
878 float *previous_window[STB_VORBIS_MAX_CHANNELS];
879 int previous_length;
880
881 #ifndef STB_VORBIS_NO_DEFER_FLOOR
882 int16 *finalY[STB_VORBIS_MAX_CHANNELS];
883 #else
884 float *floor_buffers[STB_VORBIS_MAX_CHANNELS];
885 #endif
886
887 uint32 current_loc; // sample location of next frame to decode
888 int current_loc_valid;
889
890 int32 current_playback_loc; // sample location of played samples
891 int current_playback_loc_valid;
892
893 // per-blocksize precomputed data
894
895 // twiddle factors
896 float *A[2],*B[2],*C[2];
897 float *window[2];
898 uint16 *bit_reverse[2];
899
900 // current page/packet/segment streaming info
901 uint32 serial; // stream serial number for verification
902 int last_page;
903 int segment_count;
904 uint8 segments[255];
905 uint8 page_flag;
906 uint8 bytes_in_seg;
907 uint8 first_decode;
908 int next_seg;
909 int last_seg; // flag that we're on the last segment
910 int last_seg_which; // what was the segment number of the last seg?
911 uint32 acc;
912 int valid_bits;
913 int packet_bytes;
914 int end_seg_with_known_loc;
915 uint32 known_loc_for_packet;
916 int discard_samples_deferred;
917 uint32 samples_output;
918
919 // push mode scanning
920 int page_crc_tests; // only in push_mode: number of tests active; -1 if not searching
921 #ifndef STB_VORBIS_NO_PUSHDATA_API
922 CRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT];
923 #endif
924
925 // sample-access
926 int channel_buffer_start;
927 int channel_buffer_end;
928
929 // hack: decode work buffer (used in inverse_mdct and decode_residues)
930 void *work_buffer;
931
932 // temporary buffers
933 void *temp_lengths;
934 void *temp_codewords;
935 void *temp_values;
936 void *temp_mults;
937 };
938
939 #if defined(STB_VORBIS_NO_PUSHDATA_API)
940 #define IS_PUSH_MODE(f) FALSE
941 #elif defined(STB_VORBIS_NO_PULLDATA_API)
942 #define IS_PUSH_MODE(f) TRUE
943 #else
944 #define IS_PUSH_MODE(f) ((f)->push_mode)
945 #endif
946
947 typedef struct stb_vorbis vorb;
948
949 static int error(vorb *f, enum STBVorbisError e)
950 {
951 f->error = e;
952 if (!f->eof && e != VORBIS_need_more_data) {
953 f->error=e; // breakpoint for debugging
954 }
955 return 0;
956 }
957
958
959 // these functions are used for allocating temporary memory
960 // while decoding. if you can afford the stack space, use
961 // alloca(); otherwise, provide a temp buffer and it will
962 // allocate out of those.
963
964 #define array_size_required(count,size) (count*(sizeof(void *)+(size)))
965
966 #define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : f->work_buffer)
967 #define temp_free(f,p) do {} while (0)
968 #define temp_alloc_save(f) ((f)->temp_offset)
969 #define temp_alloc_restore(f,p) ((f)->temp_offset = (p))
970
971 #define temp_block_array(f,count,size) make_block_array(temp_alloc(f,array_size_required(count,size)), count, size)
972
973 // given a sufficiently large block of memory, make an array of pointers to subblocks of it
974 static void *make_block_array(void *mem, int count, int size)
975 {
976 int i;
977 void ** p = (void **) mem;
978 char *q = (char *) (p + count);
979 for (i=0; i < count; ++i) {
980 p[i] = q;
981 q += size;
982 }
983 return p;
984 }
985
986 static void *setup_malloc(vorb *f, int sz)
987 {
988 sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
989 f->setup_memory_required += sz;
990 if (f->alloc.alloc_buffer) {
991 void *p = (char *) f->alloc.alloc_buffer + f->setup_offset;
992 if (f->setup_offset + sz > f->temp_offset) return NULL;
993 f->setup_offset += sz;
994 return p;
995 }
996 return sz ? malloc(sz) : NULL;
997 }
998
999 static void setup_free(vorb *f, void *p)
1000 {
1001 if (f->alloc.alloc_buffer) return; // do nothing; setup mem is a stack
1002 free(p);
1003 }
1004
1005 static void *setup_temp_malloc(vorb *f, int sz)
1006 {
1007 sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
1008 if (f->alloc.alloc_buffer) {
1009 if (f->temp_offset - sz < f->setup_offset) return NULL;
1010 f->temp_offset -= sz;
1011 return (char *) f->alloc.alloc_buffer + f->temp_offset;
1012 }
1013 return malloc(sz);
1014 }
1015
1016 static void setup_temp_free(vorb *f, void **_p, int sz)
1017 {
1018 void *p = *_p;
1019 *_p = NULL;
1020 if (f->alloc.alloc_buffer) {
1021 f->temp_offset += (sz+7)&~7;
1022 return;
1023 }
1024 free(p);
1025 }
1026
1027 #define CRC32_POLY 0x04c11db7 // from spec
1028
1029 static uint32 crc_table[256];
1030 static void crc32_init(void)
1031 {
1032 int i,j;
1033 uint32 s;
1034 for(i=0; i < 256; i++) {
1035 for (s=(uint32) i << 24, j=0; j < 8; ++j)
1036 s = (s << 1) ^ (s >= (1U<<31) ? CRC32_POLY : 0);
1037 crc_table[i] = s;
1038 }
1039 }
1040
1041 STB_FORCEINLINE uint32 crc32_update(uint32 crc, uint8 byte)
1042 {
1043 return (crc << 8) ^ crc_table[byte ^ (crc >> 24)];
1044 }
1045
1046
1047 // used in setup, and for huffman that doesn't go fast path
1048 static unsigned int bit_reverse(unsigned int n)
1049 {
1050 n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1);
1051 n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2);
1052 n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4);
1053 n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8);
1054 return (n >> 16) | (n << 16);
1055 }
1056
1057 static float square(float x)
1058 {
1059 return x*x;
1060 }
1061
1062 // this is a weird definition of log2() for which log2(1) = 1, log2(2) = 2, log2(4) = 3
1063 // as required by the specification. fast(?) implementation from stb.h
1064 // @OPTIMIZE: called multiple times per-packet with "constants"; move to setup
1065 static int ilog(int32 n)
1066 {
1067 static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };
1068
1069 if (n < 0) return 0; // signed n returns 0
1070
1071 // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
1072 if (n < (1 << 14))
1073 if (n < (1 << 4)) return 0 + log2_4[n ];
1074 else if (n < (1 << 9)) return 5 + log2_4[n >> 5];
1075 else return 10 + log2_4[n >> 10];
1076 else if (n < (1 << 24))
1077 if (n < (1 << 19)) return 15 + log2_4[n >> 15];
1078 else return 20 + log2_4[n >> 20];
1079 else if (n < (1 << 29)) return 25 + log2_4[n >> 25];
1080 else return 30 + log2_4[n >> 30];
1081 }
1082
1083 #ifndef M_PI
1084 #define M_PI 3.14159265358979323846264f // from CRC
1085 #endif
1086
1087 // code length assigned to a value with no huffman encoding
1088 #define NO_CODE 255
1089
1090 /////////////////////// LEAF SETUP FUNCTIONS //////////////////////////
1091 //
1092 // these functions are only called at setup, and only a few times
1093 // per file
1094
1095 static float float32_unpack(uint32 x)
1096 {
1097 // from the specification
1098 uint32 mantissa = x & 0x1fffff;
1099 uint32 sign = x & 0x80000000;
1100 uint32 exp = (x & 0x7fe00000) >> 21;
1101 double res = sign ? -(double)mantissa : (double)mantissa;
1102 return (float) ldexp((float)res, (int)exp-788);
1103 }
1104
1105
1106 // zlib & jpeg huffman tables assume that the output symbols
1107 // can either be arbitrarily arranged, or have monotonically
1108 // increasing frequencies--they rely on the lengths being sorted;
1109 // this makes for a very simple generation algorithm.
1110 // vorbis allows a huffman table with non-sorted lengths. This
1111 // requires a more sophisticated construction, since symbols in
1112 // order do not map to huffman codes "in order".
1113 static void add_entry(Codebook *c, uint32 huff_code, int symbol, int count, int len, uint32 *values)
1114 {
1115 if (!c->sparse) {
1116 c->codewords [symbol] = huff_code;
1117 } else {
1118 c->codewords [count] = huff_code;
1119 c->codeword_lengths[count] = len;
1120 values [count] = symbol;
1121 }
1122 }
1123
1124 static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
1125 {
1126 int i,k,m=0;
1127 uint32 available[32];
1128
1129 memset(available, 0, sizeof(available));
1130 // find the first entry
1131 for (k=0; k < n; ++k) if (len[k] < NO_CODE) break;
1132 if (k == n) { assert(c->sorted_entries == 0); return TRUE; }
1133 assert(len[k] < 32); // no error return required, code reading lens checks this
1134 // add to the list
1135 add_entry(c, 0, k, m++, len[k], values);
1136 // add all available leaves
1137 for (i=1; i <= len[k]; ++i)
1138 available[i] = 1U << (32-i);
1139 // note that the above code treats the first case specially,
1140 // but it's really the same as the following code, so they
1141 // could probably be combined (except the initial code is 0,
1142 // and I use 0 in available[] to mean 'empty')
1143 for (i=k+1; i < n; ++i) {
1144 uint32 res;
1145 int z = len[i], y;
1146 if (z == NO_CODE) continue;
1147 assert(z < 32); // no error return required, code reading lens checks this
1148 // find lowest available leaf (should always be earliest,
1149 // which is what the specification calls for)
1150 // note that this property, and the fact we can never have
1151 // more than one free leaf at a given level, isn't totally
1152 // trivial to prove, but it seems true and the assert never
1153 // fires, so!
1154 while (z > 0 && !available[z]) --z;
1155 if (z == 0) { return FALSE; }
1156 res = available[z];
1157 available[z] = 0;
1158 add_entry(c, bit_reverse(res), i, m++, len[i], values);
1159 // propagate availability up the tree
1160 if (z != len[i]) {
1161 for (y=len[i]; y > z; --y) {
1162 assert(available[y] == 0);
1163 available[y] = res + (1 << (32-y));
1164 }
1165 }
1166 }
1167 return TRUE;
1168 }
1169
1170 // accelerated huffman table allows fast O(1) match of all symbols
1171 // of length <= STB_VORBIS_FAST_HUFFMAN_LENGTH
1172 static void compute_accelerated_huffman(Codebook *c)
1173 {
1174 int i, len;
1175 for (i=0; i < FAST_HUFFMAN_TABLE_SIZE; ++i)
1176 c->fast_huffman[i] = -1;
1177
1178 len = c->sparse ? c->sorted_entries : c->entries;
1179 #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT
1180 if (len > 32767) len = 32767; // largest possible value we can encode!
1181 #endif
1182 for (i=0; i < len; ++i) {
1183 if (c->codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) {
1184 uint32 z = c->sparse ? bit_reverse(c->sorted_codewords[i]) : c->codewords[i];
1185 // set table entries for all bit combinations in the higher bits
1186 while (z < FAST_HUFFMAN_TABLE_SIZE) {
1187 c->fast_huffman[z] = i;
1188 z += 1 << c->codeword_lengths[i];
1189 }
1190 }
1191 }
1192 }
1193
1194 #ifndef STBV_CDECL
1195 #ifdef _MSC_VER
1196 #define STBV_CDECL __cdecl
1197 #else
1198 #define STBV_CDECL
1199 #endif
1200 #endif
1201
1202 static int STBV_CDECL uint32_compare(const void *p, const void *q)
1203 {
1204 uint32 x = * (uint32 *) p;
1205 uint32 y = * (uint32 *) q;
1206 return x < y ? -1 : x > y;
1207 }
1208
1209 static int include_in_sort(Codebook *c, uint8 len)
1210 {
1211 if (c->sparse) { assert(len != NO_CODE); return TRUE; }
1212 if (len == NO_CODE) return FALSE;
1213 if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return TRUE;
1214 return FALSE;
1215 }
1216
1217 // if the fast table above doesn't work, we want to binary
1218 // search them... need to reverse the bits
1219 static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values)
1220 {
1221 int i, len;
1222 // build a list of all the entries
1223 // OPTIMIZATION: don't include the short ones, since they'll be caught by FAST_HUFFMAN.
1224 // this is kind of a frivolous optimization--I don't see any performance improvement,
1225 // but it's like 4 extra lines of code, so.
1226 if (!c->sparse) {
1227 int k = 0;
1228 for (i=0; i < c->entries; ++i)
1229 if (include_in_sort(c, lengths[i]))
1230 c->sorted_codewords[k++] = bit_reverse(c->codewords[i]);
1231 assert(k == c->sorted_entries);
1232 } else {
1233 for (i=0; i < c->sorted_entries; ++i)
1234 c->sorted_codewords[i] = bit_reverse(c->codewords[i]);
1235 }
1236
1237 qsort(c->sorted_codewords, c->sorted_entries, sizeof(c->sorted_codewords[0]), uint32_compare);
1238 c->sorted_codewords[c->sorted_entries] = 0xffffffff;
1239
1240 len = c->sparse ? c->sorted_entries : c->entries;
1241 // now we need to indicate how they correspond; we could either
1242 // #1: sort a different data structure that says who they correspond to
1243 // #2: for each sorted entry, search the original list to find who corresponds
1244 // #3: for each original entry, find the sorted entry
1245 // #1 requires extra storage, #2 is slow, #3 can use binary search!
1246 for (i=0; i < len; ++i) {
1247 int huff_len = c->sparse ? lengths[values[i]] : lengths[i];
1248 if (include_in_sort(c,huff_len)) {
1249 uint32 code = bit_reverse(c->codewords[i]);
1250 int x=0, n=c->sorted_entries;
1251 while (n > 1) {
1252 // invariant: sc[x] <= code < sc[x+n]
1253 int m = x + (n >> 1);
1254 if (c->sorted_codewords[m] <= code) {
1255 x = m;
1256 n -= (n>>1);
1257 } else {
1258 n >>= 1;
1259 }
1260 }
1261 assert(c->sorted_codewords[x] == code);
1262 if (c->sparse) {
1263 c->sorted_values[x] = values[i];
1264 c->codeword_lengths[x] = huff_len;
1265 } else {
1266 c->sorted_values[x] = i;
1267 }
1268 }
1269 }
1270 }
1271
1272 // only run while parsing the header (3 times)
1273 static int vorbis_validate(uint8 *data)
1274 {
1275 static uint8 vorbis[6] = { 'v', 'o', 'r', 'b', 'i', 's' };
1276 return memcmp(data, vorbis, 6) == 0;
1277 }
1278
1279 // called from setup only, once per code book
1280 // (formula implied by specification)
1281 //
1282 // suppress an UBSan error caused by invalid input data.
1283 // upstream: https://github.com/nothings/stb/issues/1168.
1284 STB_NO_SANITIZE("float-cast-overflow")
1285 static int lookup1_values(int entries, int dim)
1286 {
1287 int r = (int) floor(exp((float) log((float) entries) / dim));
1288 if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning;
1289 ++r; // floor() to avoid _ftol() when non-CRT
1290 if (pow((float) r+1, dim) <= entries)
1291 return -1;
1292 if ((int) floor(pow((float) r, dim)) > entries)
1293 return -1;
1294 return r;
1295 }
1296
1297 // called twice per file
1298 static void compute_twiddle_factors(int n, float *A, float *B, float *C)
1299 {
1300 int n4 = n >> 2, n8 = n >> 3;
1301 int k,k2;
1302
1303 for (k=k2=0; k < n4; ++k,k2+=2) {
1304 A[k2 ] = (float) cos(4*k*M_PI/n);
1305 A[k2+1] = (float) -sin(4*k*M_PI/n);
1306 B[k2 ] = (float) cos((k2+1)*M_PI/n/2) * 0.5f;
1307 B[k2+1] = (float) sin((k2+1)*M_PI/n/2) * 0.5f;
1308 }
1309 for (k=k2=0; k < n8; ++k,k2+=2) {
1310 C[k2 ] = (float) cos(2*(k2+1)*M_PI/n);
1311 C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n);
1312 }
1313 }
1314
1315 static void compute_window(int n, float *window)
1316 {
1317 int n2 = n >> 1, i;
1318 for (i=0; i < n2; ++i)
1319 window[i] = (float) sin(0.5 * M_PI * square((float) sin((i - 0 + 0.5) / n2 * 0.5 * M_PI)));
1320 }
1321
1322 static void compute_bitreverse(int n, uint16 *rev)
1323 {
1324 int ld = ilog(n) - 1; // ilog is off-by-one from normal definitions
1325 int i, n8 = n >> 3;
1326 for (i=0; i < n8; ++i)
1327 rev[i] = (bit_reverse(i) >> (32-ld+3)) << 2;
1328 }
1329
1330 static int init_blocksize(vorb *f, int b, int n)
1331 {
1332 int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3;
1333 f->A[b] = (float *) setup_malloc(f, sizeof(float) * n2);
1334 f->B[b] = (float *) setup_malloc(f, sizeof(float) * n2);
1335 f->C[b] = (float *) setup_malloc(f, sizeof(float) * n4);
1336 if (!f->A[b] || !f->B[b] || !f->C[b]) return error(f, VORBIS_outofmem);
1337 compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]);
1338 f->window[b] = (float *) setup_malloc(f, sizeof(float) * n2);
1339 if (!f->window[b]) return error(f, VORBIS_outofmem);
1340 compute_window(n, f->window[b]);
1341 f->bit_reverse[b] = (uint16 *) setup_malloc(f, sizeof(uint16) * n8);
1342 if (!f->bit_reverse[b]) return error(f, VORBIS_outofmem);
1343 compute_bitreverse(n, f->bit_reverse[b]);
1344 return TRUE;
1345 }
1346
1347 static void neighbors(uint16 *x, int n, int *plow, int *phigh)
1348 {
1349 int low = -1;
1350 int high = 65536;
1351 int i;
1352 for (i=0; i < n; ++i) {
1353 if (x[i] > low && x[i] < x[n]) { *plow = i; low = x[i]; }
1354 if (x[i] < high && x[i] > x[n]) { *phigh = i; high = x[i]; }
1355 }
1356 }
1357
1358 // this has been repurposed so y is now the original index instead of y
1359 typedef struct
1360 {
1361 uint16 x,id;
1362 } stbv__floor_ordering;
1363
1364 static int STBV_CDECL point_compare(const void *p, const void *q)
1365 {
1366 stbv__floor_ordering *a = (stbv__floor_ordering *) p;
1367 stbv__floor_ordering *b = (stbv__floor_ordering *) q;
1368 return a->x < b->x ? -1 : a->x > b->x;
1369 }
1370
1371 //
1372 /////////////////////// END LEAF SETUP FUNCTIONS //////////////////////////
1373
1374
1375 #ifdef STB_VORBIS_SDL
1376 #define USE_MEMORY(z) FALSE
1377 #elif defined(STB_VORBIS_NO_STDIO)
1378 #define USE_MEMORY(z) TRUE
1379 #else
1380 #define USE_MEMORY(z) ((z)->stream)
1381 #endif
1382
1383 static uint8 get8(vorb *z)
1384 {
1385 #ifdef STB_VORBIS_SDL
1386 uint8 c;
1387 if (SDL_RWread(z->rwops, &c, 1, 1) != 1) { z->eof = TRUE; return 0; }
1388 return c;
1389
1390 #else
1391 if (USE_MEMORY(z)) {
1392 if (z->stream >= z->stream_end) { z->eof = TRUE; return 0; }
1393 return *z->stream++;
1394 }
1395 #endif
1396
1397 #ifndef STB_VORBIS_NO_STDIO
1398 {
1399 int c = fgetc(z->f);
1400 if (c == EOF) { z->eof = TRUE; return 0; }
1401 return c;
1402 }
1403 #endif
1404 }
1405
1406 static uint32 get32(vorb *f)
1407 {
1408 uint32 x;
1409 x = get8(f);
1410 x += get8(f) << 8;
1411 x += get8(f) << 16;
1412 x += (uint32) get8(f) << 24;
1413 return x;
1414 }
1415
1416 static int getn(vorb *z, uint8 *data, int n)
1417 {
1418 #ifdef STB_VORBIS_SDL
1419 if (SDL_RWread(z->rwops, data, n, 1) == 1) return 1;
1420 z->eof = 1;
1421 return 0;
1422
1423 #else
1424 if (USE_MEMORY(z)) {
1425 if (z->stream+n > z->stream_end) { z->eof = 1; return 0; }
1426 memcpy(data, z->stream, n);
1427 z->stream += n;
1428 return 1;
1429 }
1430 #endif
1431
1432 #ifndef STB_VORBIS_NO_STDIO
1433 if (fread(data, n, 1, z->f) == 1)
1434 return 1;
1435 else {
1436 z->eof = 1;
1437 return 0;
1438 }
1439 #endif
1440 }
1441
1442 static void skip(vorb *z, int n)
1443 {
1444 #ifdef STB_VORBIS_SDL
1445 SDL_RWseek(z->rwops, n, RW_SEEK_CUR);
1446
1447 #else
1448 if (USE_MEMORY(z)) {
1449 z->stream += n;
1450 if (z->stream >= z->stream_end) z->eof = 1;
1451 return;
1452 }
1453 #endif
1454
1455 #ifndef STB_VORBIS_NO_STDIO
1456 {
1457 long x = ftell(z->f);
1458 fseek(z->f, x+n, SEEK_SET);
1459 }
1460 #endif
1461 }
1462
1463 static int set_file_offset(stb_vorbis *f, unsigned int loc)
1464 {
1465 #ifndef STB_VORBIS_NO_PUSHDATA_API
1466 if (f->push_mode) return 0;
1467 #endif
1468 f->eof = 0;
1469
1470 #ifdef STB_VORBIS_SDL
1471 if (loc + f->rwops_start < loc || loc >= 0x80000000) {
1472 loc = 0x7fffffff;
1473 f->eof = 1;
1474 } else {
1475 loc += f->rwops_start;
1476 }
1477 if (SDL_RWseek(f->rwops, loc, RW_SEEK_SET) != -1)
1478 return 1;
1479 f->eof = 1;
1480 SDL_RWseek(f->rwops, f->rwops_start, RW_SEEK_END);
1481 return 0;
1482
1483 #else
1484 if (USE_MEMORY(f)) {
1485 if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) {
1486 f->stream = f->stream_end;
1487 f->eof = 1;
1488 return 0;
1489 } else {
1490 f->stream = f->stream_start + loc;
1491 return 1;
1492 }
1493 }
1494 #endif
1495
1496 #ifndef STB_VORBIS_NO_STDIO
1497 if (loc + f->f_start < loc || loc >= 0x80000000) {
1498 loc = 0x7fffffff;
1499 f->eof = 1;
1500 } else {
1501 loc += f->f_start;
1502 }
1503 if (!fseek(f->f, loc, SEEK_SET))
1504 return 1;
1505 f->eof = 1;
1506 fseek(f->f, f->f_start, SEEK_END);
1507 return 0;
1508 #endif
1509 }
1510
1511
1512 static uint8 ogg_page_header[4] = { 0x4f, 0x67, 0x67, 0x53 };
1513
1514 static int capture_pattern(vorb *f)
1515 {
1516 if (0x4f != get8(f)) return FALSE;
1517 if (0x67 != get8(f)) return FALSE;
1518 if (0x67 != get8(f)) return FALSE;
1519 if (0x53 != get8(f)) return FALSE;
1520 return TRUE;
1521 }
1522
1523 #define PAGEFLAG_continued_packet 1
1524 #define PAGEFLAG_first_page 2
1525 #define PAGEFLAG_last_page 4
1526
1527 static int start_page_no_capturepattern(vorb *f)
1528 {
1529 uint32 loc0,loc1,n;
1530 if (f->first_decode && !IS_PUSH_MODE(f)) {
1531 f->p_first.page_start = stb_vorbis_get_file_offset(f) - 4;
1532 }
1533 // stream structure version
1534 if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version);
1535 // header flag
1536 f->page_flag = get8(f);
1537 // absolute granule position
1538 loc0 = get32(f);
1539 loc1 = get32(f);
1540 // @TODO: validate loc0,loc1 as valid positions?
1541 // stream serial number -- vorbis doesn't interleave, so discard
1542 get32(f);
1543 //if (f->serial != get32(f)) return error(f, VORBIS_incorrect_stream_serial_number);
1544 // page sequence number
1545 n = get32(f);
1546 f->last_page = n;
1547 // CRC32
1548 get32(f);
1549 // page_segments
1550 f->segment_count = get8(f);
1551 if (!getn(f, f->segments, f->segment_count))
1552 return error(f, VORBIS_unexpected_eof);
1553 // assume we _don't_ know any the sample position of any segments
1554 f->end_seg_with_known_loc = -2;
1555 if (loc0 != ~0U || loc1 != ~0U) {
1556 int i;
1557 // determine which packet is the last one that will complete
1558 for (i=f->segment_count-1; i >= 0; --i)
1559 if (f->segments[i] < 255)
1560 break;
1561 // 'i' is now the index of the _last_ segment of a packet that ends
1562 if (i >= 0) {
1563 f->end_seg_with_known_loc = i;
1564 f->known_loc_for_packet = loc0;
1565 }
1566 }
1567 if (f->first_decode) {
1568 int i,len;
1569 len = 0;
1570 for (i=0; i < f->segment_count; ++i)
1571 len += f->segments[i];
1572 len += 27 + f->segment_count;
1573 f->p_first.page_end = f->p_first.page_start + len;
1574 f->p_first.last_decoded_sample = loc0;
1575 }
1576 f->next_seg = 0;
1577 return TRUE;
1578 }
1579
1580 static int start_page(vorb *f)
1581 {
1582 if (!capture_pattern(f)) return error(f, VORBIS_missing_capture_pattern);
1583 return start_page_no_capturepattern(f);
1584 }
1585
1586 static int start_packet(vorb *f)
1587 {
1588 while (f->next_seg == -1) {
1589 if (!start_page(f)) return FALSE;
1590 if (f->page_flag & PAGEFLAG_continued_packet)
1591 return error(f, VORBIS_continued_packet_flag_invalid);
1592 }
1593 f->last_seg = FALSE;
1594 f->valid_bits = 0;
1595 f->packet_bytes = 0;
1596 f->bytes_in_seg = 0;
1597 // f->next_seg is now valid
1598 return TRUE;
1599 }
1600
1601 static int maybe_start_packet(vorb *f)
1602 {
1603 if (f->next_seg == -1) {
1604 int x = get8(f);
1605 if (f->eof) return FALSE; // EOF at page boundary is not an error!
1606 if (0x4f != x ) return error(f, VORBIS_missing_capture_pattern);
1607 if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern);
1608 if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern);
1609 if (0x53 != get8(f)) return error(f, VORBIS_missing_capture_pattern);
1610 if (!start_page_no_capturepattern(f)) return FALSE;
1611 if (f->page_flag & PAGEFLAG_continued_packet) {
1612 // set up enough state that we can read this packet if we want,
1613 // e.g. during recovery
1614 f->last_seg = FALSE;
1615 f->bytes_in_seg = 0;
1616 return error(f, VORBIS_continued_packet_flag_invalid);
1617 }
1618 }
1619 return start_packet(f);
1620 }
1621
1622 static int next_segment(vorb *f)
1623 {
1624 int len;
1625 if (f->last_seg) return 0;
1626 if (f->next_seg == -1) {
1627 f->last_seg_which = f->segment_count-1; // in case start_page fails
1628 if (!start_page(f)) { f->last_seg = 1; return 0; }
1629 if (!(f->page_flag & PAGEFLAG_continued_packet)) return error(f, VORBIS_continued_packet_flag_invalid);
1630 }
1631 len = f->segments[f->next_seg++];
1632 if (len < 255) {
1633 f->last_seg = TRUE;
1634 f->last_seg_which = f->next_seg-1;
1635 }
1636 if (f->next_seg >= f->segment_count)
1637 f->next_seg = -1;
1638 assert(f->bytes_in_seg == 0);
1639 f->bytes_in_seg = len;
1640 return len;
1641 }
1642
1643 #define EOP (-1)
1644 #define INVALID_BITS (-1)
1645
1646 static int get8_packet_raw(vorb *f)
1647 {
1648 if (!f->bytes_in_seg) { // CLANG!
1649 if (f->last_seg) return EOP;
1650 else if (!next_segment(f)) return EOP;
1651 }
1652 assert(f->bytes_in_seg > 0);
1653 --f->bytes_in_seg;
1654 ++f->packet_bytes;
1655 return get8(f);
1656 }
1657
1658 static int get8_packet(vorb *f)
1659 {
1660 int x = get8_packet_raw(f);
1661 f->valid_bits = 0;
1662 return x;
1663 }
1664
1665 static int get32_packet(vorb *f)
1666 {
1667 uint32 x;
1668 x = get8_packet(f);
1669 x += get8_packet(f) << 8;
1670 x += get8_packet(f) << 16;
1671 x += (uint32) get8_packet(f) << 24;
1672 return x;
1673 }
1674
1675 static void flush_packet(vorb *f)
1676 {
1677 while (get8_packet_raw(f) != EOP);
1678 }
1679
1680 // @OPTIMIZE: this is the secondary bit decoder, so it's probably not as important
1681 // as the huffman decoder?
1682 static uint32 get_bits(vorb *f, int n)
1683 {
1684 uint32 z;
1685
1686 if (f->valid_bits < 0) return 0;
1687 if (f->valid_bits < n) {
1688 if (n > 24) {
1689 // the accumulator technique below would not work correctly in this case
1690 z = get_bits(f, 24);
1691 z += get_bits(f, n-24) << 24;
1692 return z;
1693 }
1694 if (f->valid_bits == 0) f->acc = 0;
1695 while (f->valid_bits < n) {
1696 int z = get8_packet_raw(f);
1697 if (z == EOP) {
1698 f->valid_bits = INVALID_BITS;
1699 return 0;
1700 }
1701 f->acc += z << f->valid_bits;
1702 f->valid_bits += 8;
1703 }
1704 }
1705
1706 assert(f->valid_bits >= n);
1707 z = f->acc & ((1 << n)-1);
1708 f->acc >>= n;
1709 f->valid_bits -= n;
1710 return z;
1711 }
1712
1713 // @OPTIMIZE: primary accumulator for huffman
1714 // expand the buffer to as many bits as possible without reading off end of packet
1715 // it might be nice to allow f->valid_bits and f->acc to be stored in registers,
1716 // e.g. cache them locally and decode locally
1717 STB_FORCEINLINE void prep_huffman(vorb *f)
1718 {
1719 if (f->valid_bits <= 24) {
1720 if (f->valid_bits == 0) f->acc = 0;
1721 do {
1722 int z;
1723 if (f->last_seg && !f->bytes_in_seg) return;
1724 z = get8_packet_raw(f);
1725 if (z == EOP) return;
1726 f->acc += (unsigned) z << f->valid_bits;
1727 f->valid_bits += 8;
1728 } while (f->valid_bits <= 24);
1729 }
1730 }
1731
1732 enum
1733 {
1734 VORBIS_packet_id = 1,
1735 VORBIS_packet_comment = 3,
1736 VORBIS_packet_setup = 5
1737 };
1738
1739 static int codebook_decode_scalar_raw(vorb *f, Codebook *c)
1740 {
1741 int i;
1742 prep_huffman(f);
1743
1744 if (c->codewords == NULL && c->sorted_codewords == NULL)
1745 return -1;
1746
1747 // cases to use binary search: sorted_codewords && !c->codewords
1748 // sorted_codewords && c->entries > 8
1749 if (c->entries > 8 ? c->sorted_codewords!=NULL : !c->codewords) {
1750 // binary search
1751 uint32 code = bit_reverse(f->acc);
1752 int x=0, n=c->sorted_entries, len;
1753
1754 while (n > 1) {
1755 // invariant: sc[x] <= code < sc[x+n]
1756 int m = x + (n >> 1);
1757 if (c->sorted_codewords[m] <= code) {
1758 x = m;
1759 n -= (n>>1);
1760 } else {
1761 n >>= 1;
1762 }
1763 }
1764 // x is now the sorted index
1765 if (!c->sparse) x = c->sorted_values[x];
1766 // x is now sorted index if sparse, or symbol otherwise
1767 len = c->codeword_lengths[x];
1768 if (f->valid_bits >= len) {
1769 f->acc >>= len;
1770 f->valid_bits -= len;
1771 return x;
1772 }
1773
1774 f->valid_bits = 0;
1775 return -1;
1776 }
1777
1778 // if small, linear search
1779 assert(!c->sparse);
1780 for (i=0; i < c->entries; ++i) {
1781 if (c->codeword_lengths[i] == NO_CODE) continue;
1782 /* unsigned left shift for 32-bit codewords.
1783 * https://github.com/nothings/stb/issues/1168 */
1784 if (c->codewords[i] == (f->acc & ((1U << c->codeword_lengths[i])-1))) {
1785 if (f->valid_bits >= c->codeword_lengths[i]) {
1786 f->acc >>= c->codeword_lengths[i];
1787 f->valid_bits -= c->codeword_lengths[i];
1788 return i;
1789 }
1790 f->valid_bits = 0;
1791 return -1;
1792 }
1793 }
1794
1795 error(f, VORBIS_invalid_stream);
1796 f->valid_bits = 0;
1797 return -1;
1798 }
1799
1800 #ifndef STB_VORBIS_NO_INLINE_DECODE
1801
1802 #define DECODE_RAW(var, f,c) \
1803 if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) \
1804 prep_huffman(f); \
1805 var = f->acc & FAST_HUFFMAN_TABLE_MASK; \
1806 var = c->fast_huffman[var]; \
1807 if (var >= 0) { \
1808 int n = c->codeword_lengths[var]; \
1809 f->acc >>= n; \
1810 f->valid_bits -= n; \
1811 if (f->valid_bits < 0) { f->valid_bits = 0; var = -1; } \
1812 } else { \
1813 var = codebook_decode_scalar_raw(f,c); \
1814 }
1815
1816 #else
1817
1818 static int codebook_decode_scalar(vorb *f, Codebook *c)
1819 {
1820 int i;
1821 if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH)
1822 prep_huffman(f);
1823 // fast huffman table lookup
1824 i = f->acc & FAST_HUFFMAN_TABLE_MASK;
1825 i = c->fast_huffman[i];
1826 if (i >= 0) {
1827 f->acc >>= c->codeword_lengths[i];
1828 f->valid_bits -= c->codeword_lengths[i];
1829 if (f->valid_bits < 0) { f->valid_bits = 0; return -1; }
1830 return i;
1831 }
1832 return codebook_decode_scalar_raw(f,c);
1833 }
1834
1835 #define DECODE_RAW(var,f,c) var = codebook_decode_scalar(f,c);
1836
1837 #endif
1838
1839 #define DECODE(var,f,c) \
1840 DECODE_RAW(var,f,c) \
1841 if (c->sparse) var = c->sorted_values[var];
1842
1843 #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
1844 #define DECODE_VQ(var,f,c) DECODE_RAW(var,f,c)
1845 #else
1846 #define DECODE_VQ(var,f,c) DECODE(var,f,c)
1847 #endif
1848
1849
1850
1851
1852
1853
1854 // CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case
1855 // where we avoid one addition
1856 #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off])
1857 #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off])
1858 #define CODEBOOK_ELEMENT_BASE(c) (0)
1859
1860 static int codebook_decode_start(vorb *f, Codebook *c)
1861 {
1862 int z = -1;
1863
1864 // type 0 is only legal in a scalar context
1865 if (c->lookup_type == 0)
1866 error(f, VORBIS_invalid_stream);
1867 else {
1868 DECODE_VQ(z,f,c);
1869 if (c->sparse) assert(z < c->sorted_entries);
1870 if (z < 0) { // check for EOP
1871 if (!f->bytes_in_seg)
1872 if (f->last_seg)
1873 return z;
1874 error(f, VORBIS_invalid_stream);
1875 }
1876 }
1877 return z;
1878 }
1879
1880 static int codebook_decode(vorb *f, Codebook *c, float *output, int len)
1881 {
1882 int i,z = codebook_decode_start(f,c);
1883 if (z < 0) return FALSE;
1884 if (len > c->dimensions) len = c->dimensions;
1885
1886 #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
1887 if (c->lookup_type == 1) {
1888 float last = CODEBOOK_ELEMENT_BASE(c);
1889 int div = 1;
1890 for (i=0; i < len; ++i) {
1891 int off = (z / div) % c->lookup_values;
1892 float val = CODEBOOK_ELEMENT_FAST(c,off) + last;
1893 output[i] += val;
1894 if (c->sequence_p) last = val + c->minimum_value;
1895 div *= c->lookup_values;
1896 }
1897 return TRUE;
1898 }
1899 #endif
1900
1901 z *= c->dimensions;
1902 if (c->sequence_p) {
1903 float last = CODEBOOK_ELEMENT_BASE(c);
1904 for (i=0; i < len; ++i) {
1905 float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
1906 output[i] += val;
1907 last = val + c->minimum_value;
1908 }
1909 } else {
1910 float last = CODEBOOK_ELEMENT_BASE(c);
1911 for (i=0; i < len; ++i) {
1912 output[i] += CODEBOOK_ELEMENT_FAST(c,z+i) + last;
1913 }
1914 }
1915
1916 return TRUE;
1917 }
1918
1919 static int codebook_decode_step(vorb *f, Codebook *c, float *output, int len, int step)
1920 {
1921 int i,z = codebook_decode_start(f,c);
1922 float last = CODEBOOK_ELEMENT_BASE(c);
1923 if (z < 0) return FALSE;
1924 if (len > c->dimensions) len = c->dimensions;
1925
1926 #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
1927 if (c->lookup_type == 1) {
1928 int div = 1;
1929 for (i=0; i < len; ++i) {
1930 int off = (z / div) % c->lookup_values;
1931 float val = CODEBOOK_ELEMENT_FAST(c,off) + last;
1932 output[i*step] += val;
1933 if (c->sequence_p) last = val;
1934 div *= c->lookup_values;
1935 }
1936 return TRUE;
1937 }
1938 #endif
1939
1940 z *= c->dimensions;
1941 for (i=0; i < len; ++i) {
1942 float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
1943 output[i*step] += val;
1944 if (c->sequence_p) last = val;
1945 }
1946
1947 return TRUE;
1948 }
1949
1950 static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **outputs, int ch, int *c_inter_p, int *p_inter_p, int len, int total_decode)
1951 {
1952 int c_inter = *c_inter_p;
1953 int p_inter = *p_inter_p;
1954 int i,z, effective = c->dimensions;
1955
1956 // type 0 is only legal in a scalar context
1957 if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream);
1958
1959 while (total_decode > 0) {
1960 float last = CODEBOOK_ELEMENT_BASE(c);
1961 DECODE_VQ(z,f,c);
1962 #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
1963 assert(!c->sparse || z < c->sorted_entries);
1964 #endif
1965 if (z < 0) {
1966 if (!f->bytes_in_seg)
1967 if (f->last_seg) return FALSE;
1968 return error(f, VORBIS_invalid_stream);
1969 }
1970
1971 // if this will take us off the end of the buffers, stop short!
1972 // we check by computing the length of the virtual interleaved
1973 // buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter),
1974 // and the length we'll be using (effective)
1975 if (c_inter + p_inter*ch + effective > len * ch) {
1976 effective = len*ch - (p_inter*ch - c_inter);
1977 }
1978
1979 #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
1980 if (c->lookup_type == 1) {
1981 int div = 1;
1982 for (i=0; i < effective; ++i) {
1983 int off = (z / div) % c->lookup_values;
1984 float val = CODEBOOK_ELEMENT_FAST(c,off) + last;
1985 if (outputs[c_inter])
1986 outputs[c_inter][p_inter] += val;
1987 if (++c_inter == ch) { c_inter = 0; ++p_inter; }
1988 if (c->sequence_p) last = val;
1989 div *= c->lookup_values;
1990 }
1991 } else
1992 #endif
1993 {
1994 z *= c->dimensions;
1995 if (c->sequence_p) {
1996 for (i=0; i < effective; ++i) {
1997 float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
1998 if (outputs[c_inter])
1999 outputs[c_inter][p_inter] += val;
2000 if (++c_inter == ch) { c_inter = 0; ++p_inter; }
2001 last = val;
2002 }
2003 } else {
2004 for (i=0; i < effective; ++i) {
2005 float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
2006 if (outputs[c_inter])
2007 outputs[c_inter][p_inter] += val;
2008 if (++c_inter == ch) { c_inter = 0; ++p_inter; }
2009 }
2010 }
2011 }
2012
2013 total_decode -= effective;
2014 }
2015 *c_inter_p = c_inter;
2016 *p_inter_p = p_inter;
2017 return TRUE;
2018 }
2019
2020 static int predict_point(int x, int x0, int x1, int y0, int y1)
2021 {
2022 int dy = y1 - y0;
2023 int adx = x1 - x0;
2024 // @OPTIMIZE: force int division to round in the right direction... is this necessary on x86?
2025 int err = abs(dy) * (x - x0);
2026 int off = err / adx;
2027 return dy < 0 ? y0 - off : y0 + off;
2028 }
2029
2030 // the following table is block-copied from the specification
2031 static float inverse_db_table[256] =
2032 {
2033 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f,
2034 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f,
2035 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f,
2036 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f,
2037 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f,
2038 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f,
2039 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f,
2040 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f,
2041 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f,
2042 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f,
2043 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f,
2044 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f,
2045 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f,
2046 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f,
2047 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f,
2048 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f,
2049 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f,
2050 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f,
2051 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f,
2052 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f,
2053 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f,
2054 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f,
2055 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f,
2056 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f,
2057 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f,
2058 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f,
2059 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f,
2060 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f,
2061 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f,
2062 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f,
2063 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f,
2064 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f,
2065 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f,
2066 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f,
2067 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f,
2068 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f,
2069 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f,
2070 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f,
2071 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f,
2072 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f,
2073 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f,
2074 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f,
2075 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f,
2076 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f,
2077 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f,
2078 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f,
2079 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f,
2080 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f,
2081 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f,
2082 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f,
2083 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f,
2084 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f,
2085 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f,
2086 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f,
2087 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f,
2088 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f,
2089 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f,
2090 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f,
2091 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f,
2092 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f,
2093 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f,
2094 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f,
2095 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f,
2096 0.82788260f, 0.88168307f, 0.9389798f, 1.0f
2097 };
2098
2099
2100 // @OPTIMIZE: if you want to replace this bresenham line-drawing routine,
2101 // note that you must produce bit-identical output to decode correctly;
2102 // this specific sequence of operations is specified in the spec (it's
2103 // drawing integer-quantized frequency-space lines that the encoder
2104 // expects to be exactly the same)
2105 // ... also, isn't the whole point of Bresenham's algorithm to NOT
2106 // have to divide in the setup? sigh.
2107 #ifndef STB_VORBIS_NO_DEFER_FLOOR
2108 #define LINE_OP(a,b) a *= b
2109 #else
2110 #define LINE_OP(a,b) a = b
2111 #endif
2112
2113 #ifdef STB_VORBIS_DIVIDE_TABLE
2114 #define DIVTAB_NUMER 32
2115 #define DIVTAB_DENOM 64
2116 int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; // 2KB
2117 #endif
2118
2119 STB_FORCEINLINE void draw_line(float *output, int x0, int y0, int x1, int y1, int n)
2120 {
2121 int dy = y1 - y0;
2122 int adx = x1 - x0;
2123 int ady = abs(dy);
2124 int base;
2125 int x=x0,y=y0;
2126 int err = 0;
2127 int sy;
2128
2129 #ifdef STB_VORBIS_DIVIDE_TABLE
2130 if (adx < DIVTAB_DENOM && ady < DIVTAB_NUMER) {
2131 if (dy < 0) {
2132 base = -integer_divide_table[ady][adx];
2133 sy = base-1;
2134 } else {
2135 base = integer_divide_table[ady][adx];
2136 sy = base+1;
2137 }
2138 } else {
2139 base = dy / adx;
2140 if (dy < 0)
2141 sy = base - 1;
2142 else
2143 sy = base+1;
2144 }
2145 #else
2146 base = dy / adx;
2147 if (dy < 0)
2148 sy = base - 1;
2149 else
2150 sy = base+1;
2151 #endif
2152 ady -= abs(base) * adx;
2153 if (x1 > n) x1 = n;
2154 if (x < x1) {
2155 LINE_OP(output[x], inverse_db_table[y&255]);
2156 for (++x; x < x1; ++x) {
2157 err += ady;
2158 if (err >= adx) {
2159 err -= adx;
2160 y += sy;
2161 } else
2162 y += base;
2163 LINE_OP(output[x], inverse_db_table[y&255]);
2164 }
2165 }
2166 }
2167
2168 static int residue_decode(vorb *f, Codebook *book, float *target, int offset, int n, int rtype)
2169 {
2170 int k;
2171 if (rtype == 0) {
2172 int step = n / book->dimensions;
2173 for (k=0; k < step; ++k)
2174 if (!codebook_decode_step(f, book, target+offset+k, n-offset-k, step))
2175 return FALSE;
2176 } else {
2177 for (k=0; k < n; ) {
2178 if (!codebook_decode(f, book, target+offset, n-k))
2179 return FALSE;
2180 k += book->dimensions;
2181 offset += book->dimensions;
2182 }
2183 }
2184 return TRUE;
2185 }
2186
2187 // n is 1/2 of the blocksize --
2188 // specification: "Correct per-vector decode length is [n]/2"
2189 static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode)
2190 {
2191 int i,j,pass;
2192 Residue *r = f->residue_config + rn;
2193 int rtype = f->residue_types[rn];
2194 int c = r->classbook;
2195 int classwords = f->codebooks[c].dimensions;
2196 unsigned int actual_size = rtype == 2 ? n*2 : n;
2197 unsigned int limit_r_begin = (r->begin < actual_size ? r->begin : actual_size);
2198 unsigned int limit_r_end = (r->end < actual_size ? r->end : actual_size);
2199 int n_read = limit_r_end - limit_r_begin;
2200 int part_read = n_read / r->part_size;
2201 int temp_alloc_point = temp_alloc_save(f);
2202 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2203 uint8 ***part_classdata = (uint8 ***) temp_block_array(f,f->channels, part_read * sizeof(**part_classdata));
2204 #else
2205 int **classifications = (int **) temp_block_array(f,f->channels, part_read * sizeof(**classifications));
2206 #endif
2207
2208 CHECK(f);
2209
2210 for (i=0; i < ch; ++i)
2211 if (!do_not_decode[i])
2212 memset(residue_buffers[i], 0, sizeof(float) * n);
2213
2214 if (rtype == 2 && ch != 1) {
2215 for (j=0; j < ch; ++j)
2216 if (!do_not_decode[j])
2217 break;
2218 if (j == ch)
2219 goto done;
2220
2221 for (pass=0; pass < 8; ++pass) {
2222 int pcount = 0, class_set = 0;
2223 if (ch == 2) {
2224 while (pcount < part_read) {
2225 int z = r->begin + pcount*r->part_size;
2226 int c_inter = (z & 1), p_inter = z>>1;
2227 if (pass == 0) {
2228 Codebook *c = f->codebooks+r->classbook;
2229 int q;
2230 DECODE(q,f,c);
2231 if (q == EOP) goto done;
2232 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2233 part_classdata[0][class_set] = r->classdata[q];
2234 #else
2235 for (i=classwords-1; i >= 0; --i) {
2236 classifications[0][i+pcount] = q % r->classifications;
2237 q /= r->classifications;
2238 }
2239 #endif
2240 }
2241 for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) {
2242 int z = r->begin + pcount*r->part_size;
2243 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2244 int c = part_classdata[0][class_set][i];
2245 #else
2246 int c = classifications[0][pcount];
2247 #endif
2248 int b = r->residue_books[c][pass];
2249 if (b >= 0) {
2250 Codebook *book = f->codebooks + b;
2251 #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
2252 if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size))
2253 goto done;
2254 #else
2255 // saves 1%
2256 if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size))
2257 goto done;
2258 #endif
2259 } else {
2260 z += r->part_size;
2261 c_inter = z & 1;
2262 p_inter = z >> 1;
2263 }
2264 }
2265 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2266 ++class_set;
2267 #endif
2268 }
2269 } else if (ch > 2) {
2270 while (pcount < part_read) {
2271 int z = r->begin + pcount*r->part_size;
2272 int c_inter = z % ch, p_inter = z/ch;
2273 if (pass == 0) {
2274 Codebook *c = f->codebooks+r->classbook;
2275 int q;
2276 DECODE(q,f,c);
2277 if (q == EOP) goto done;
2278 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2279 part_classdata[0][class_set] = r->classdata[q];
2280 #else
2281 for (i=classwords-1; i >= 0; --i) {
2282 classifications[0][i+pcount] = q % r->classifications;
2283 q /= r->classifications;
2284 }
2285 #endif
2286 }
2287 for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) {
2288 int z = r->begin + pcount*r->part_size;
2289 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2290 int c = part_classdata[0][class_set][i];
2291 #else
2292 int c = classifications[0][pcount];
2293 #endif
2294 int b = r->residue_books[c][pass];
2295 if (b >= 0) {
2296 Codebook *book = f->codebooks + b;
2297 if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size))
2298 goto done;
2299 } else {
2300 z += r->part_size;
2301 c_inter = z % ch;
2302 p_inter = z / ch;
2303 }
2304 }
2305 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2306 ++class_set;
2307 #endif
2308 }
2309 }
2310 }
2311 goto done;
2312 }
2313 CHECK(f);
2314
2315 for (pass=0; pass < 8; ++pass) {
2316 int pcount = 0, class_set=0;
2317 while (pcount < part_read) {
2318 if (pass == 0) {
2319 for (j=0; j < ch; ++j) {
2320 if (!do_not_decode[j]) {
2321 Codebook *c = f->codebooks+r->classbook;
2322 int temp;
2323 DECODE(temp,f,c);
2324 if (temp == EOP) goto done;
2325 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2326 part_classdata[j][class_set] = r->classdata[temp];
2327 #else
2328 for (i=classwords-1; i >= 0; --i) {
2329 classifications[j][i+pcount] = temp % r->classifications;
2330 temp /= r->classifications;
2331 }
2332 #endif
2333 }
2334 }
2335 }
2336 for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) {
2337 for (j=0; j < ch; ++j) {
2338 if (!do_not_decode[j]) {
2339 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2340 int c = part_classdata[j][class_set][i];
2341 #else
2342 int c = classifications[j][pcount];
2343 #endif
2344 int b = r->residue_books[c][pass];
2345 if (b >= 0) {
2346 float *target = residue_buffers[j];
2347 int offset = r->begin + pcount * r->part_size;
2348 int n = r->part_size;
2349 Codebook *book = f->codebooks + b;
2350 if (!residue_decode(f, book, target, offset, n, rtype))
2351 goto done;
2352 }
2353 }
2354 }
2355 }
2356 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2357 ++class_set;
2358 #endif
2359 }
2360 }
2361 done:
2362 CHECK(f);
2363 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
2364 temp_free(f,part_classdata);
2365 #else
2366 temp_free(f,classifications);
2367 #endif
2368 temp_alloc_restore(f,temp_alloc_point);
2369 }
2370
2371
2372 #if 0
2373 // slow way for debugging
2374 void inverse_mdct_slow(float *buffer, int n)
2375 {
2376 int i,j;
2377 int n2 = n >> 1;
2378 float *x = (float *) malloc(sizeof(*x) * n2);
2379 memcpy(x, buffer, sizeof(*x) * n2);
2380 for (i=0; i < n; ++i) {
2381 float acc = 0;
2382 for (j=0; j < n2; ++j)
2383 // formula from paper:
2384 //acc += n/4.0f * x[j] * (float) cos(M_PI / 2 / n * (2 * i + 1 + n/2.0)*(2*j+1));
2385 // formula from wikipedia
2386 //acc += 2.0f / n2 * x[j] * (float) cos(M_PI/n2 * (i + 0.5 + n2/2)*(j + 0.5));
2387 // these are equivalent, except the formula from the paper inverts the multiplier!
2388 // however, what actually works is NO MULTIPLIER!?!
2389 //acc += 64 * 2.0f / n2 * x[j] * (float) cos(M_PI/n2 * (i + 0.5 + n2/2)*(j + 0.5));
2390 acc += x[j] * (float) cos(M_PI / 2 / n * (2 * i + 1 + n/2.0)*(2*j+1));
2391 buffer[i] = acc;
2392 }
2393 free(x);
2394 }
2395 #elif 0
2396 // same as above, but just barely able to run in real time on modern machines
2397 void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)
2398 {
2399 float mcos[16384];
2400 int i,j;
2401 int n2 = n >> 1, nmask = (n << 2) -1;
2402 float *x = (float *) malloc(sizeof(*x) * n2);
2403 memcpy(x, buffer, sizeof(*x) * n2);
2404 for (i=0; i < 4*n; ++i)
2405 mcos[i] = (float) cos(M_PI / 2 * i / n);
2406
2407 for (i=0; i < n; ++i) {
2408 float acc = 0;
2409 for (j=0; j < n2; ++j)
2410 acc += x[j] * mcos[(2 * i + 1 + n2)*(2*j+1) & nmask];
2411 buffer[i] = acc;
2412 }
2413 free(x);
2414 }
2415 #elif 0
2416 // transform to use a slow dct-iv; this is STILL basically trivial,
2417 // but only requires half as many ops
2418 void dct_iv_slow(float *buffer, int n)
2419 {
2420 float mcos[16384];
2421 float x[2048];
2422 int i,j;
2423 int n2 = n >> 1, nmask = (n << 3) - 1;
2424 memcpy(x, buffer, sizeof(*x) * n);
2425 for (i=0; i < 8*n; ++i)
2426 mcos[i] = (float) cos(M_PI / 4 * i / n);
2427 for (i=0; i < n; ++i) {
2428 float acc = 0;
2429 for (j=0; j < n; ++j)
2430 acc += x[j] * mcos[((2 * i + 1)*(2*j+1)) & nmask];
2431 buffer[i] = acc;
2432 }
2433 }
2434
2435 void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)
2436 {
2437 int i, n4 = n >> 2, n2 = n >> 1, n3_4 = n - n4;
2438 float temp[4096];
2439
2440 memcpy(temp, buffer, n2 * sizeof(float));
2441 dct_iv_slow(temp, n2); // returns -c'-d, a-b'
2442
2443 for (i=0; i < n4 ; ++i) buffer[i] = temp[i+n4]; // a-b'
2444 for ( ; i < n3_4; ++i) buffer[i] = -temp[n3_4 - i - 1]; // b-a', c+d'
2445 for ( ; i < n ; ++i) buffer[i] = -temp[i - n3_4]; // c'+d
2446 }
2447 #endif
2448
2449 #ifndef LIBVORBIS_MDCT
2450 #define LIBVORBIS_MDCT 0
2451 #endif
2452
2453 #if LIBVORBIS_MDCT
2454 // directly call the vorbis MDCT using an interface documented
2455 // by Jeff Roberts... useful for performance comparison
2456 typedef struct
2457 {
2458 int n;
2459 int log2n;
2460
2461 float *trig;
2462 int *bitrev;
2463
2464 float scale;
2465 } mdct_lookup;
2466
2467 extern void mdct_init(mdct_lookup *lookup, int n);
2468 extern void mdct_clear(mdct_lookup *l);
2469 extern void mdct_backward(mdct_lookup *init, float *in, float *out);
2470
2471 mdct_lookup M1,M2;
2472
2473 void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
2474 {
2475 mdct_lookup *M;
2476 if (M1.n == n) M = &M1;
2477 else if (M2.n == n) M = &M2;
2478 else if (M1.n == 0) { mdct_init(&M1, n); M = &M1; }
2479 else {
2480 if (M2.n) __asm int 3;
2481 mdct_init(&M2, n);
2482 M = &M2;
2483 }
2484
2485 mdct_backward(M, buffer, buffer);
2486 }
2487 #endif
2488
2489
2490 // the following were split out into separate functions while optimizing;
2491 // they could be pushed back up but eh. __forceinline showed no change;
2492 // they're probably already being inlined.
2493 static void imdct_step3_iter0_loop(int n, float *e, int i_off, int k_off, float *A)
2494 {
2495 float *ee0 = e + i_off;
2496 float *ee2 = ee0 + k_off;
2497 int i;
2498
2499 assert((n & 3) == 0);
2500 for (i=(n>>2); i > 0; --i) {
2501 float k00_20, k01_21;
2502 k00_20 = ee0[ 0] - ee2[ 0];
2503 k01_21 = ee0[-1] - ee2[-1];
2504 ee0[ 0] += ee2[ 0];//ee0[ 0] = ee0[ 0] + ee2[ 0];
2505 ee0[-1] += ee2[-1];//ee0[-1] = ee0[-1] + ee2[-1];
2506 ee2[ 0] = k00_20 * A[0] - k01_21 * A[1];
2507 ee2[-1] = k01_21 * A[0] + k00_20 * A[1];
2508 A += 8;
2509
2510 k00_20 = ee0[-2] - ee2[-2];
2511 k01_21 = ee0[-3] - ee2[-3];
2512 ee0[-2] += ee2[-2];//ee0[-2] = ee0[-2] + ee2[-2];
2513 ee0[-3] += ee2[-3];//ee0[-3] = ee0[-3] + ee2[-3];
2514 ee2[-2] = k00_20 * A[0] - k01_21 * A[1];
2515 ee2[-3] = k01_21 * A[0] + k00_20 * A[1];
2516 A += 8;
2517
2518 k00_20 = ee0[-4] - ee2[-4];
2519 k01_21 = ee0[-5] - ee2[-5];
2520 ee0[-4] += ee2[-4];//ee0[-4] = ee0[-4] + ee2[-4];
2521 ee0[-5] += ee2[-5];//ee0[-5] = ee0[-5] + ee2[-5];
2522 ee2[-4] = k00_20 * A[0] - k01_21 * A[1];
2523 ee2[-5] = k01_21 * A[0] + k00_20 * A[1];
2524 A += 8;
2525
2526 k00_20 = ee0[-6] - ee2[-6];
2527 k01_21 = ee0[-7] - ee2[-7];
2528 ee0[-6] += ee2[-6];//ee0[-6] = ee0[-6] + ee2[-6];
2529 ee0[-7] += ee2[-7];//ee0[-7] = ee0[-7] + ee2[-7];
2530 ee2[-6] = k00_20 * A[0] - k01_21 * A[1];
2531 ee2[-7] = k01_21 * A[0] + k00_20 * A[1];
2532 A += 8;
2533 ee0 -= 8;
2534 ee2 -= 8;
2535 }
2536 }
2537
2538 static void imdct_step3_inner_r_loop(int lim, float *e, int d0, int k_off, float *A, int k1)
2539 {
2540 int i;
2541 float k00_20, k01_21;
2542
2543 float *e0 = e + d0;
2544 float *e2 = e0 + k_off;
2545
2546 for (i=lim >> 2; i > 0; --i) {
2547 k00_20 = e0[-0] - e2[-0];
2548 k01_21 = e0[-1] - e2[-1];
2549 e0[-0] += e2[-0];//e0[-0] = e0[-0] + e2[-0];
2550 e0[-1] += e2[-1];//e0[-1] = e0[-1] + e2[-1];
2551 e2[-0] = (k00_20)*A[0] - (k01_21) * A[1];
2552 e2[-1] = (k01_21)*A[0] + (k00_20) * A[1];
2553
2554 A += k1;
2555
2556 k00_20 = e0[-2] - e2[-2];
2557 k01_21 = e0[-3] - e2[-3];
2558 e0[-2] += e2[-2];//e0[-2] = e0[-2] + e2[-2];
2559 e0[-3] += e2[-3];//e0[-3] = e0[-3] + e2[-3];
2560 e2[-2] = (k00_20)*A[0] - (k01_21) * A[1];
2561 e2[-3] = (k01_21)*A[0] + (k00_20) * A[1];
2562
2563 A += k1;
2564
2565 k00_20 = e0[-4] - e2[-4];
2566 k01_21 = e0[-5] - e2[-5];
2567 e0[-4] += e2[-4];//e0[-4] = e0[-4] + e2[-4];
2568 e0[-5] += e2[-5];//e0[-5] = e0[-5] + e2[-5];
2569 e2[-4] = (k00_20)*A[0] - (k01_21) * A[1];
2570 e2[-5] = (k01_21)*A[0] + (k00_20) * A[1];
2571
2572 A += k1;
2573
2574 k00_20 = e0[-6] - e2[-6];
2575 k01_21 = e0[-7] - e2[-7];
2576 e0[-6] += e2[-6];//e0[-6] = e0[-6] + e2[-6];
2577 e0[-7] += e2[-7];//e0[-7] = e0[-7] + e2[-7];
2578 e2[-6] = (k00_20)*A[0] - (k01_21) * A[1];
2579 e2[-7] = (k01_21)*A[0] + (k00_20) * A[1];
2580
2581 e0 -= 8;
2582 e2 -= 8;
2583
2584 A += k1;
2585 }
2586 }
2587
2588 static void imdct_step3_inner_s_loop(int n, float *e, int i_off, int k_off, float *A, int a_off, int k0)
2589 {
2590 int i;
2591 float A0 = A[0];
2592 float A1 = A[0+1];
2593 float A2 = A[0+a_off];
2594 float A3 = A[0+a_off+1];
2595 float A4 = A[0+a_off*2+0];
2596 float A5 = A[0+a_off*2+1];
2597 float A6 = A[0+a_off*3+0];
2598 float A7 = A[0+a_off*3+1];
2599
2600 float k00,k11;
2601
2602 float *ee0 = e +i_off;
2603 float *ee2 = ee0+k_off;
2604
2605 for (i=n; i > 0; --i) {
2606 k00 = ee0[ 0] - ee2[ 0];
2607 k11 = ee0[-1] - ee2[-1];
2608 ee0[ 0] = ee0[ 0] + ee2[ 0];
2609 ee0[-1] = ee0[-1] + ee2[-1];
2610 ee2[ 0] = (k00) * A0 - (k11) * A1;
2611 ee2[-1] = (k11) * A0 + (k00) * A1;
2612
2613 k00 = ee0[-2] - ee2[-2];
2614 k11 = ee0[-3] - ee2[-3];
2615 ee0[-2] = ee0[-2] + ee2[-2];
2616 ee0[-3] = ee0[-3] + ee2[-3];
2617 ee2[-2] = (k00) * A2 - (k11) * A3;
2618 ee2[-3] = (k11) * A2 + (k00) * A3;
2619
2620 k00 = ee0[-4] - ee2[-4];
2621 k11 = ee0[-5] - ee2[-5];
2622 ee0[-4] = ee0[-4] + ee2[-4];
2623 ee0[-5] = ee0[-5] + ee2[-5];
2624 ee2[-4] = (k00) * A4 - (k11) * A5;
2625 ee2[-5] = (k11) * A4 + (k00) * A5;
2626
2627 k00 = ee0[-6] - ee2[-6];
2628 k11 = ee0[-7] - ee2[-7];
2629 ee0[-6] = ee0[-6] + ee2[-6];
2630 ee0[-7] = ee0[-7] + ee2[-7];
2631 ee2[-6] = (k00) * A6 - (k11) * A7;
2632 ee2[-7] = (k11) * A6 + (k00) * A7;
2633
2634 ee0 -= k0;
2635 ee2 -= k0;
2636 }
2637 }
2638
2639 STB_FORCEINLINE void iter_54(float *z)
2640 {
2641 float k00,k11,k22,k33;
2642 float y0,y1,y2,y3;
2643
2644 k00 = z[ 0] - z[-4];
2645 y0 = z[ 0] + z[-4];
2646 y2 = z[-2] + z[-6];
2647 k22 = z[-2] - z[-6];
2648
2649 z[-0] = y0 + y2; // z0 + z4 + z2 + z6
2650 z[-2] = y0 - y2; // z0 + z4 - z2 - z6
2651
2652 // done with y0,y2
2653
2654 k33 = z[-3] - z[-7];
2655
2656 z[-4] = k00 + k33; // z0 - z4 + z3 - z7
2657 z[-6] = k00 - k33; // z0 - z4 - z3 + z7
2658
2659 // done with k33
2660
2661 k11 = z[-1] - z[-5];
2662 y1 = z[-1] + z[-5];
2663 y3 = z[-3] + z[-7];
2664
2665 z[-1] = y1 + y3; // z1 + z5 + z3 + z7
2666 z[-3] = y1 - y3; // z1 + z5 - z3 - z7
2667 z[-5] = k11 - k22; // z1 - z5 + z2 - z6
2668 z[-7] = k11 + k22; // z1 - z5 - z2 + z6
2669 }
2670
2671 static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, int base_n)
2672 {
2673 int a_off = base_n >> 3;
2674 float A2 = A[0+a_off];
2675 float *z = e + i_off;
2676 float *base = z - 16 * n;
2677
2678 while (z > base) {
2679 float k00,k11;
2680 float l00,l11;
2681
2682 k00 = z[-0] - z[ -8];
2683 k11 = z[-1] - z[ -9];
2684 l00 = z[-2] - z[-10];
2685 l11 = z[-3] - z[-11];
2686 z[ -0] = z[-0] + z[ -8];
2687 z[ -1] = z[-1] + z[ -9];
2688 z[ -2] = z[-2] + z[-10];
2689 z[ -3] = z[-3] + z[-11];
2690 z[ -8] = k00;
2691 z[ -9] = k11;
2692 z[-10] = (l00+l11) * A2;
2693 z[-11] = (l11-l00) * A2;
2694
2695 k00 = z[ -4] - z[-12];
2696 k11 = z[ -5] - z[-13];
2697 l00 = z[ -6] - z[-14];
2698 l11 = z[ -7] - z[-15];
2699 z[ -4] = z[ -4] + z[-12];
2700 z[ -5] = z[ -5] + z[-13];
2701 z[ -6] = z[ -6] + z[-14];
2702 z[ -7] = z[ -7] + z[-15];
2703 z[-12] = k11;
2704 z[-13] = -k00;
2705 z[-14] = (l11-l00) * A2;
2706 z[-15] = (l00+l11) * -A2;
2707
2708 iter_54(z);
2709 iter_54(z-8);
2710 z -= 16;
2711 }
2712 }
2713
2714 static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
2715 {
2716 int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l;
2717 int ld;
2718 // @OPTIMIZE: reduce register pressure by using fewer variables?
2719 int save_point = temp_alloc_save(f);
2720 float *buf2 = (float *) temp_alloc(f, n2 * sizeof(*buf2));
2721 float *u=NULL,*v=NULL;
2722 // twiddle factors
2723 float *A = f->A[blocktype];
2724
2725 // IMDCT algorithm from "The use of multirate filter banks for coding of high quality digital audio"
2726 // See notes about bugs in that paper in less-optimal implementation 'inverse_mdct_old' after this function.
2727
2728 // kernel from paper
2729
2730
2731 // merged:
2732 // copy and reflect spectral data
2733 // step 0
2734
2735 // note that it turns out that the items added together during
2736 // this step are, in fact, being added to themselves (as reflected
2737 // by step 0). inexplicable inefficiency! this became obvious
2738 // once I combined the passes.
2739
2740 // so there's a missing 'times 2' here (for adding X to itself).
2741 // this propagates through linearly to the end, where the numbers
2742 // are 1/2 too small, and need to be compensated for.
2743
2744 {
2745 float *d,*e, *AA, *e_stop;
2746 d = &buf2[n2-2];
2747 AA = A;
2748 e = &buffer[0];
2749 e_stop = &buffer[n2];
2750 while (e != e_stop) {
2751 d[1] = (e[0] * AA[0] - e[2]*AA[1]);
2752 d[0] = (e[0] * AA[1] + e[2]*AA[0]);
2753 d -= 2;
2754 AA += 2;
2755 e += 4;
2756 }
2757
2758 e = &buffer[n2-3];
2759 while (d >= buf2) {
2760 d[1] = (-e[2] * AA[0] - -e[0]*AA[1]);
2761 d[0] = (-e[2] * AA[1] + -e[0]*AA[0]);
2762 d -= 2;
2763 AA += 2;
2764 e -= 4;
2765 }
2766 }
2767
2768 // now we use symbolic names for these, so that we can
2769 // possibly swap their meaning as we change which operations
2770 // are in place
2771
2772 u = buffer;
2773 v = buf2;
2774
2775 // step 2 (paper output is w, now u)
2776 // this could be in place, but the data ends up in the wrong
2777 // place... _somebody_'s got to swap it, so this is nominated
2778 {
2779 float *AA = &A[n2-8];
2780 float *d0,*d1, *e0, *e1;
2781
2782 e0 = &v[n4];
2783 e1 = &v[0];
2784
2785 d0 = &u[n4];
2786 d1 = &u[0];
2787
2788 while (AA >= A) {
2789 float v40_20, v41_21;
2790
2791 v41_21 = e0[1] - e1[1];
2792 v40_20 = e0[0] - e1[0];
2793 d0[1] = e0[1] + e1[1];
2794 d0[0] = e0[0] + e1[0];
2795 d1[1] = v41_21*AA[4] - v40_20*AA[5];
2796 d1[0] = v40_20*AA[4] + v41_21*AA[5];
2797
2798 v41_21 = e0[3] - e1[3];
2799 v40_20 = e0[2] - e1[2];
2800 d0[3] = e0[3] + e1[3];
2801 d0[2] = e0[2] + e1[2];
2802 d1[3] = v41_21*AA[0] - v40_20*AA[1];
2803 d1[2] = v40_20*AA[0] + v41_21*AA[1];
2804
2805 AA -= 8;
2806
2807 d0 += 4;
2808 d1 += 4;
2809 e0 += 4;
2810 e1 += 4;
2811 }
2812 }
2813
2814 // step 3
2815 ld = ilog(n) - 1; // ilog is off-by-one from normal definitions
2816
2817 // optimized step 3:
2818
2819 // the original step3 loop can be nested r inside s or s inside r;
2820 // it's written originally as s inside r, but this is dumb when r
2821 // iterates many times, and s few. So I have two copies of it and
2822 // switch between them halfway.
2823
2824 // this is iteration 0 of step 3
2825 imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*0, -(n >> 3), A);
2826 imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*1, -(n >> 3), A);
2827
2828 // this is iteration 1 of step 3
2829 imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*0, -(n >> 4), A, 16);
2830 imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*1, -(n >> 4), A, 16);
2831 imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*2, -(n >> 4), A, 16);
2832 imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*3, -(n >> 4), A, 16);
2833
2834 l=2;
2835 for (; l < (ld-3)>>1; ++l) {
2836 int k0 = n >> (l+2), k0_2 = k0>>1;
2837 int lim = 1 << (l+1);
2838 int i;
2839 for (i=0; i < lim; ++i)
2840 imdct_step3_inner_r_loop(n >> (l+4), u, n2-1 - k0*i, -k0_2, A, 1 << (l+3));
2841 }
2842
2843 for (; l < ld-6; ++l) {
2844 int k0 = n >> (l+2), k1 = 1 << (l+3), k0_2 = k0>>1;
2845 int rlim = n >> (l+6), r;
2846 int lim = 1 << (l+1);
2847 int i_off;
2848 float *A0 = A;
2849 i_off = n2-1;
2850 for (r=rlim; r > 0; --r) {
2851 imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0);
2852 A0 += k1*4;
2853 i_off -= 8;
2854 }
2855 }
2856
2857 // iterations with count:
2858 // ld-6,-5,-4 all interleaved together
2859 // the big win comes from getting rid of needless flops
2860 // due to the constants on pass 5 & 4 being all 1 and 0;
2861 // combining them to be simultaneous to improve cache made little difference
2862 imdct_step3_inner_s_loop_ld654(n >> 5, u, n2-1, A, n);
2863
2864 // output is u
2865
2866 // step 4, 5, and 6
2867 // cannot be in-place because of step 5
2868 {
2869 uint16 *bitrev = f->bit_reverse[blocktype];
2870 // weirdly, I'd have thought reading sequentially and writing
2871 // erratically would have been better than vice-versa, but in
2872 // fact that's not what my testing showed. (That is, with
2873 // j = bitreverse(i), do you read i and write j, or read j and write i.)
2874
2875 float *d0 = &v[n4-4];
2876 float *d1 = &v[n2-4];
2877 while (d0 >= v) {
2878 int k4;
2879
2880 k4 = bitrev[0];
2881 d1[3] = u[k4+0];
2882 d1[2] = u[k4+1];
2883 d0[3] = u[k4+2];
2884 d0[2] = u[k4+3];
2885
2886 k4 = bitrev[1];
2887 d1[1] = u[k4+0];
2888 d1[0] = u[k4+1];
2889 d0[1] = u[k4+2];
2890 d0[0] = u[k4+3];
2891
2892 d0 -= 4;
2893 d1 -= 4;
2894 bitrev += 2;
2895 }
2896 }
2897 // (paper output is u, now v)
2898
2899
2900 // data must be in buf2
2901 assert(v == buf2);
2902
2903 // step 7 (paper output is v, now v)
2904 // this is now in place
2905 {
2906 float *C = f->C[blocktype];
2907 float *d, *e;
2908
2909 d = v;
2910 e = v + n2 - 4;
2911
2912 while (d < e) {
2913 float a02,a11,b0,b1,b2,b3;
2914
2915 a02 = d[0] - e[2];
2916 a11 = d[1] + e[3];
2917
2918 b0 = C[1]*a02 + C[0]*a11;
2919 b1 = C[1]*a11 - C[0]*a02;
2920
2921 b2 = d[0] + e[ 2];
2922 b3 = d[1] - e[ 3];
2923
2924 d[0] = b2 + b0;
2925 d[1] = b3 + b1;
2926 e[2] = b2 - b0;
2927 e[3] = b1 - b3;
2928
2929 a02 = d[2] - e[0];
2930 a11 = d[3] + e[1];
2931
2932 b0 = C[3]*a02 + C[2]*a11;
2933 b1 = C[3]*a11 - C[2]*a02;
2934
2935 b2 = d[2] + e[ 0];
2936 b3 = d[3] - e[ 1];
2937
2938 d[2] = b2 + b0;
2939 d[3] = b3 + b1;
2940 e[0] = b2 - b0;
2941 e[1] = b1 - b3;
2942
2943 C += 4;
2944 d += 4;
2945 e -= 4;
2946 }
2947 }
2948
2949 // data must be in buf2
2950
2951
2952 // step 8+decode (paper output is X, now buffer)
2953 // this generates pairs of data a la 8 and pushes them directly through
2954 // the decode kernel (pushing rather than pulling) to avoid having
2955 // to make another pass later
2956
2957 // this cannot POSSIBLY be in place, so we refer to the buffers directly
2958
2959 {
2960 float *d0,*d1,*d2,*d3;
2961
2962 float *B = f->B[blocktype] + n2 - 8;
2963 float *e = buf2 + n2 - 8;
2964 d0 = &buffer[0];
2965 d1 = &buffer[n2-4];
2966 d2 = &buffer[n2];
2967 d3 = &buffer[n-4];
2968 while (e >= v) {
2969 float p0,p1,p2,p3;
2970
2971 p3 = e[6]*B[7] - e[7]*B[6];
2972 p2 = -e[6]*B[6] - e[7]*B[7];
2973
2974 d0[0] = p3;
2975 d1[3] = - p3;
2976 d2[0] = p2;
2977 d3[3] = p2;
2978
2979 p1 = e[4]*B[5] - e[5]*B[4];
2980 p0 = -e[4]*B[4] - e[5]*B[5];
2981
2982 d0[1] = p1;
2983 d1[2] = - p1;
2984 d2[1] = p0;
2985 d3[2] = p0;
2986
2987 p3 = e[2]*B[3] - e[3]*B[2];
2988 p2 = -e[2]*B[2] - e[3]*B[3];
2989
2990 d0[2] = p3;
2991 d1[1] = - p3;
2992 d2[2] = p2;
2993 d3[1] = p2;
2994
2995 p1 = e[0]*B[1] - e[1]*B[0];
2996 p0 = -e[0]*B[0] - e[1]*B[1];
2997
2998 d0[3] = p1;
2999 d1[0] = - p1;
3000 d2[3] = p0;
3001 d3[0] = p0;
3002
3003 B -= 8;
3004 e -= 8;
3005 d0 += 4;
3006 d2 += 4;
3007 d1 -= 4;
3008 d3 -= 4;
3009 }
3010 }
3011
3012 temp_free(f,buf2);
3013 temp_alloc_restore(f,save_point);
3014 }
3015
3016 #if 0
3017 // this is the original version of the above code, if you want to optimize it from scratch
3018 void inverse_mdct_naive(float *buffer, int n)
3019 {
3020 float s;
3021 float A[1 << 12], B[1 << 12], C[1 << 11];
3022 int i,k,k2,k4, n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l;
3023 int n3_4 = n - n4, ld;
3024 // how can they claim this only uses N words?!
3025 // oh, because they're only used sparsely, whoops
3026 float u[1 << 13], X[1 << 13], v[1 << 13], w[1 << 13];
3027 // set up twiddle factors
3028
3029 for (k=k2=0; k < n4; ++k,k2+=2) {
3030 A[k2 ] = (float) cos(4*k*M_PI/n);
3031 A[k2+1] = (float) -sin(4*k*M_PI/n);
3032 B[k2 ] = (float) cos((k2+1)*M_PI/n/2);
3033 B[k2+1] = (float) sin((k2+1)*M_PI/n/2);
3034 }
3035 for (k=k2=0; k < n8; ++k,k2+=2) {
3036 C[k2 ] = (float) cos(2*(k2+1)*M_PI/n);
3037 C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n);
3038 }
3039
3040 // IMDCT algorithm from "The use of multirate filter banks for coding of high quality digital audio"
3041 // Note there are bugs in that pseudocode, presumably due to them attempting
3042 // to rename the arrays nicely rather than representing the way their actual
3043 // implementation bounces buffers back and forth. As a result, even in the
3044 // "some formulars corrected" version, a direct implementation fails. These
3045 // are noted below as "paper bug".
3046
3047 // copy and reflect spectral data
3048 for (k=0; k < n2; ++k) u[k] = buffer[k];
3049 for ( ; k < n ; ++k) u[k] = -buffer[n - k - 1];
3050 // kernel from paper
3051 // step 1
3052 for (k=k2=k4=0; k < n4; k+=1, k2+=2, k4+=4) {
3053 v[n-k4-1] = (u[k4] - u[n-k4-1]) * A[k2] - (u[k4+2] - u[n-k4-3])*A[k2+1];
3054 v[n-k4-3] = (u[k4] - u[n-k4-1]) * A[k2+1] + (u[k4+2] - u[n-k4-3])*A[k2];
3055 }
3056 // step 2
3057 for (k=k4=0; k < n8; k+=1, k4+=4) {
3058 w[n2+3+k4] = v[n2+3+k4] + v[k4+3];
3059 w[n2+1+k4] = v[n2+1+k4] + v[k4+1];
3060 w[k4+3] = (v[n2+3+k4] - v[k4+3])*A[n2-4-k4] - (v[n2+1+k4]-v[k4+1])*A[n2-3-k4];
3061 w[k4+1] = (v[n2+1+k4] - v[k4+1])*A[n2-4-k4] + (v[n2+3+k4]-v[k4+3])*A[n2-3-k4];
3062 }
3063 // step 3
3064 ld = ilog(n) - 1; // ilog is off-by-one from normal definitions
3065 for (l=0; l < ld-3; ++l) {
3066 int k0 = n >> (l+2), k1 = 1 << (l+3);
3067 int rlim = n >> (l+4), r4, r;
3068 int s2lim = 1 << (l+2), s2;
3069 for (r=r4=0; r < rlim; r4+=4,++r) {
3070 for (s2=0; s2 < s2lim; s2+=2) {
3071 u[n-1-k0*s2-r4] = w[n-1-k0*s2-r4] + w[n-1-k0*(s2+1)-r4];
3072 u[n-3-k0*s2-r4] = w[n-3-k0*s2-r4] + w[n-3-k0*(s2+1)-r4];
3073 u[n-1-k0*(s2+1)-r4] = (w[n-1-k0*s2-r4] - w[n-1-k0*(s2+1)-r4]) * A[r*k1]
3074 - (w[n-3-k0*s2-r4] - w[n-3-k0*(s2+1)-r4]) * A[r*k1+1];
3075 u[n-3-k0*(s2+1)-r4] = (w[n-3-k0*s2-r4] - w[n-3-k0*(s2+1)-r4]) * A[r*k1]
3076 + (w[n-1-k0*s2-r4] - w[n-1-k0*(s2+1)-r4]) * A[r*k1+1];
3077 }
3078 }
3079 if (l+1 < ld-3) {
3080 // paper bug: ping-ponging of u&w here is omitted
3081 memcpy(w, u, sizeof(u));
3082 }
3083 }
3084
3085 // step 4
3086 for (i=0; i < n8; ++i) {
3087 int j = bit_reverse(i) >> (32-ld+3);
3088 assert(j < n8);
3089 if (i == j) {
3090 // paper bug: original code probably swapped in place; if copying,
3091 // need to directly copy in this case
3092 int i8 = i << 3;
3093 v[i8+1] = u[i8+1];
3094 v[i8+3] = u[i8+3];
3095 v[i8+5] = u[i8+5];
3096 v[i8+7] = u[i8+7];
3097 } else if (i < j) {
3098 int i8 = i << 3, j8 = j << 3;
3099 v[j8+1] = u[i8+1], v[i8+1] = u[j8 + 1];
3100 v[j8+3] = u[i8+3], v[i8+3] = u[j8 + 3];
3101 v[j8+5] = u[i8+5], v[i8+5] = u[j8 + 5];
3102 v[j8+7] = u[i8+7], v[i8+7] = u[j8 + 7];
3103 }
3104 }
3105 // step 5
3106 for (k=0; k < n2; ++k) {
3107 w[k] = v[k*2+1];
3108 }
3109 // step 6
3110 for (k=k2=k4=0; k < n8; ++k, k2 += 2, k4 += 4) {
3111 u[n-1-k2] = w[k4];
3112 u[n-2-k2] = w[k4+1];
3113 u[n3_4 - 1 - k2] = w[k4+2];
3114 u[n3_4 - 2 - k2] = w[k4+3];
3115 }
3116 // step 7
3117 for (k=k2=0; k < n8; ++k, k2 += 2) {
3118 v[n2 + k2 ] = ( u[n2 + k2] + u[n-2-k2] + C[k2+1]*(u[n2+k2]-u[n-2-k2]) + C[k2]*(u[n2+k2+1]+u[n-2-k2+1]))/2;
3119 v[n-2 - k2] = ( u[n2 + k2] + u[n-2-k2] - C[k2+1]*(u[n2+k2]-u[n-2-k2]) - C[k2]*(u[n2+k2+1]+u[n-2-k2+1]))/2;
3120 v[n2+1+ k2] = ( u[n2+1+k2] - u[n-1-k2] + C[k2+1]*(u[n2+1+k2]+u[n-1-k2]) - C[k2]*(u[n2+k2]-u[n-2-k2]))/2;
3121 v[n-1 - k2] = (-u[n2+1+k2] + u[n-1-k2] + C[k2+1]*(u[n2+1+k2]+u[n-1-k2]) - C[k2]*(u[n2+k2]-u[n-2-k2]))/2;
3122 }
3123 // step 8
3124 for (k=k2=0; k < n4; ++k,k2 += 2) {
3125 X[k] = v[k2+n2]*B[k2 ] + v[k2+1+n2]*B[k2+1];
3126 X[n2-1-k] = v[k2+n2]*B[k2+1] - v[k2+1+n2]*B[k2 ];
3127 }
3128
3129 // decode kernel to output
3130 // determined the following value experimentally
3131 // (by first figuring out what made inverse_mdct_slow work); then matching that here
3132 // (probably vorbis encoder premultiplies by n or n/2, to save it on the decoder?)
3133 s = 0.5; // theoretically would be n4
3134
3135 // [[[ note! the s value of 0.5 is compensated for by the B[] in the current code,
3136 // so it needs to use the "old" B values to behave correctly, or else
3137 // set s to 1.0 ]]]
3138 for (i=0; i < n4 ; ++i) buffer[i] = s * X[i+n4];
3139 for ( ; i < n3_4; ++i) buffer[i] = -s * X[n3_4 - i - 1];
3140 for ( ; i < n ; ++i) buffer[i] = -s * X[i - n3_4];
3141 }
3142 #endif
3143
3144 static float *get_window(vorb *f, int len)
3145 {
3146 len <<= 1;
3147 if (len == f->blocksize_0) return f->window[0];
3148 if (len == f->blocksize_1) return f->window[1];
3149 return NULL;
3150 }
3151
3152 #ifndef STB_VORBIS_NO_DEFER_FLOOR
3153 typedef int16 YTYPE;
3154 #else
3155 typedef int YTYPE;
3156 #endif
3157 static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *finalY, uint8 *step2_flag)
3158 {
3159 int n2 = n >> 1;
3160 int s = map->chan[i].mux, floor;
3161 floor = map->submap_floor[s];
3162 if (f->floor_types[floor] == 0) {
3163 return error(f, VORBIS_invalid_stream);
3164 } else {
3165 Floor1 *g = &f->floor_config[floor].floor1;
3166 int j,q;
3167 int lx = 0, ly = finalY[0] * g->floor1_multiplier;
3168 for (q=1; q < g->values; ++q) {
3169 j = g->sorted_order[q];
3170 #ifndef STB_VORBIS_NO_DEFER_FLOOR
3171 STBV_NOTUSED(step2_flag);
3172 if (finalY[j] >= 0)
3173 #else
3174 if (step2_flag[j])
3175 #endif
3176 {
3177 int hy = finalY[j] * g->floor1_multiplier;
3178 int hx = g->Xlist[j];
3179 if (lx != hx)
3180 draw_line(target, lx,ly, hx,hy, n2);
3181 CHECK(f);
3182 lx = hx, ly = hy;
3183 }
3184 }
3185 if (lx < n2) {
3186 // optimization of: draw_line(target, lx,ly, n,ly, n2);
3187 for (j=lx; j < n2; ++j)
3188 LINE_OP(target[j], inverse_db_table[ly]);
3189 CHECK(f);
3190 }
3191 }
3192 return TRUE;
3193 }
3194
3195 // The meaning of "left" and "right"
3196 //
3197 // For a given frame:
3198 // we compute samples from 0..n
3199 // window_center is n/2
3200 // we'll window and mix the samples from left_start to left_end with data from the previous frame
3201 // all of the samples from left_end to right_start can be output without mixing; however,
3202 // this interval is 0-length except when transitioning between short and long frames
3203 // all of the samples from right_start to right_end need to be mixed with the next frame,
3204 // which we don't have, so those get saved in a buffer
3205 // frame N's right_end-right_start, the number of samples to mix with the next frame,
3206 // has to be the same as frame N+1's left_end-left_start (which they are by
3207 // construction)
3208
3209 static int vorbis_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode)
3210 {
3211 Mode *m;
3212 int i, n, prev, next, window_center;
3213 f->channel_buffer_start = f->channel_buffer_end = 0;
3214
3215 retry:
3216 if (f->eof) return FALSE;
3217 if (!maybe_start_packet(f))
3218 return FALSE;
3219 // check packet type
3220 if (get_bits(f,1) != 0) {
3221 if (IS_PUSH_MODE(f))
3222 return error(f,VORBIS_bad_packet_type);
3223 while (EOP != get8_packet(f));
3224 goto retry;
3225 }
3226
3227 if (f->alloc.alloc_buffer)
3228 assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset);
3229
3230 i = get_bits(f, ilog(f->mode_count-1));
3231 if (i == EOP) return FALSE;
3232 if (i >= f->mode_count) return FALSE;
3233 *mode = i;
3234 m = f->mode_config + i;
3235 if (m->blockflag) {
3236 n = f->blocksize_1;
3237 prev = get_bits(f,1);
3238 next = get_bits(f,1);
3239 } else {
3240 prev = next = 0;
3241 n = f->blocksize_0;
3242 }
3243
3244 // WINDOWING
3245
3246 window_center = n >> 1;
3247 if (m->blockflag && !prev) {
3248 *p_left_start = (n - f->blocksize_0) >> 2;
3249 *p_left_end = (n + f->blocksize_0) >> 2;
3250 } else {
3251 *p_left_start = 0;
3252 *p_left_end = window_center;
3253 }
3254 if (m->blockflag && !next) {
3255 *p_right_start = (n*3 - f->blocksize_0) >> 2;
3256 *p_right_end = (n*3 + f->blocksize_0) >> 2;
3257 } else {
3258 *p_right_start = window_center;
3259 *p_right_end = n;
3260 }
3261
3262 return TRUE;
3263 }
3264
3265 static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, int left_end, int right_start, int right_end, int *p_left)
3266 {
3267 Mapping *map;
3268 int i,j,k,n,n2;
3269 int zero_channel[256];
3270 int really_zero_channel[256];
3271
3272 // WINDOWING
3273
3274 STBV_NOTUSED(left_end);
3275 n = f->blocksize[m->blockflag];
3276 map = &f->mapping[m->mapping];
3277
3278 // FLOORS
3279 n2 = n >> 1;
3280
3281 CHECK(f);
3282
3283 for (i=0; i < f->channels; ++i) {
3284 int s = map->chan[i].mux, floor;
3285 zero_channel[i] = FALSE;
3286 floor = map->submap_floor[s];
3287 if (f->floor_types[floor] == 0) {
3288 return error(f, VORBIS_invalid_stream);
3289 } else {
3290 Floor1 *g = &f->floor_config[floor].floor1;
3291 if (get_bits(f, 1)) {
3292 short *finalY;
3293 uint8 step2_flag[256];
3294 static int range_list[4] = { 256, 128, 86, 64 };
3295 int range = range_list[g->floor1_multiplier-1];
3296 int offset = 2;
3297 finalY = f->finalY[i];
3298 finalY[0] = get_bits(f, ilog(range)-1);
3299 finalY[1] = get_bits(f, ilog(range)-1);
3300 for (j=0; j < g->partitions; ++j) {
3301 int pclass = g->partition_class_list[j];
3302 int cdim = g->class_dimensions[pclass];
3303 int cbits = g->class_subclasses[pclass];
3304 int csub = (1 << cbits)-1;
3305 int cval = 0;
3306 if (cbits) {
3307 Codebook *c = f->codebooks + g->class_masterbooks[pclass];
3308 DECODE(cval,f,c);
3309 }
3310 for (k=0; k < cdim; ++k) {
3311 int book = g->subclass_books[pclass][cval & csub];
3312 cval = cval >> cbits;
3313 if (book >= 0) {
3314 int temp;
3315 Codebook *c = f->codebooks + book;
3316 DECODE(temp,f,c);
3317 finalY[offset++] = temp;
3318 } else
3319 finalY[offset++] = 0;
3320 }
3321 }
3322 if (f->valid_bits == INVALID_BITS) goto error; // behavior according to spec
3323 step2_flag[0] = step2_flag[1] = 1;
3324 for (j=2; j < g->values; ++j) {
3325 int low, high, pred, highroom, lowroom, room, val;
3326 low = g->neighbors[j][0];
3327 high = g->neighbors[j][1];
3328 //neighbors(g->Xlist, j, &low, &high);
3329 pred = predict_point(g->Xlist[j], g->Xlist[low], g->Xlist[high], finalY[low], finalY[high]);
3330 val = finalY[j];
3331 highroom = range - pred;
3332 lowroom = pred;
3333 if (highroom < lowroom)
3334 room = highroom * 2;
3335 else
3336 room = lowroom * 2;
3337 if (val) {
3338 step2_flag[low] = step2_flag[high] = 1;
3339 step2_flag[j] = 1;
3340 if (val >= room)
3341 if (highroom > lowroom)
3342 finalY[j] = val - lowroom + pred;
3343 else
3344 finalY[j] = pred - val + highroom - 1;
3345 else
3346 if (val & 1)
3347 finalY[j] = pred - ((val+1)>>1);
3348 else
3349 finalY[j] = pred + (val>>1);
3350 } else {
3351 step2_flag[j] = 0;
3352 finalY[j] = pred;
3353 }
3354 }
3355
3356 #ifdef STB_VORBIS_NO_DEFER_FLOOR
3357 do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag);
3358 #else
3359 // defer final floor computation until _after_ residue
3360 for (j=0; j < g->values; ++j) {
3361 if (!step2_flag[j])
3362 finalY[j] = -1;
3363 }
3364 #endif
3365 } else {
3366 error:
3367 zero_channel[i] = TRUE;
3368 }
3369 // So we just defer everything else to later
3370
3371 // at this point we've decoded the floor into buffer
3372 }
3373 }
3374 CHECK(f);
3375 // at this point we've decoded all floors
3376
3377 if (f->alloc.alloc_buffer)
3378 assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset);
3379
3380 // re-enable coupled channels if necessary
3381 memcpy(really_zero_channel, zero_channel, sizeof(really_zero_channel[0]) * f->channels);
3382 for (i=0; i < map->coupling_steps; ++i)
3383 if (!zero_channel[map->chan[i].magnitude] || !zero_channel[map->chan[i].angle]) {
3384 zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = FALSE;
3385 }
3386
3387 CHECK(f);
3388 // RESIDUE DECODE
3389 for (i=0; i < map->submaps; ++i) {
3390 float *residue_buffers[STB_VORBIS_MAX_CHANNELS];
3391 int r;
3392 uint8 do_not_decode[256];
3393 int ch = 0;
3394 for (j=0; j < f->channels; ++j) {
3395 if (map->chan[j].mux == i) {
3396 if (zero_channel[j]) {
3397 do_not_decode[ch] = TRUE;
3398 residue_buffers[ch] = NULL;
3399 } else {
3400 do_not_decode[ch] = FALSE;
3401 residue_buffers[ch] = f->channel_buffers[j];
3402 }
3403 ++ch;
3404 }
3405 }
3406 r = map->submap_residue[i];
3407 decode_residue(f, residue_buffers, ch, n2, r, do_not_decode);
3408 }
3409
3410 if (f->alloc.alloc_buffer)
3411 assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset);
3412 CHECK(f);
3413
3414 // INVERSE COUPLING
3415 for (i = map->coupling_steps-1; i >= 0; --i) {
3416 int n2 = n >> 1;
3417 float *m = f->channel_buffers[map->chan[i].magnitude];
3418 float *a = f->channel_buffers[map->chan[i].angle ];
3419 for (j=0; j < n2; ++j) {
3420 float a2,m2;
3421 if (m[j] > 0)
3422 if (a[j] > 0)
3423 m2 = m[j], a2 = m[j] - a[j];
3424 else
3425 a2 = m[j], m2 = m[j] + a[j];
3426 else
3427 if (a[j] > 0)
3428 m2 = m[j], a2 = m[j] + a[j];
3429 else
3430 a2 = m[j], m2 = m[j] - a[j];
3431 m[j] = m2;
3432 a[j] = a2;
3433 }
3434 }
3435 CHECK(f);
3436
3437 // finish decoding the floors
3438 #ifndef STB_VORBIS_NO_DEFER_FLOOR
3439 for (i=0; i < f->channels; ++i) {
3440 if (really_zero_channel[i]) {
3441 memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2);
3442 } else {
3443 do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL);
3444 }
3445 }
3446 #else
3447 for (i=0; i < f->channels; ++i) {
3448 if (really_zero_channel[i]) {
3449 memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2);
3450 } else {
3451 for (j=0; j < n2; ++j)
3452 f->channel_buffers[i][j] *= f->floor_buffers[i][j];
3453 }
3454 }
3455 #endif
3456
3457 // INVERSE MDCT
3458 CHECK(f);
3459 for (i=0; i < f->channels; ++i)
3460 inverse_mdct(f->channel_buffers[i], n, f, m->blockflag);
3461 CHECK(f);
3462
3463 // this shouldn't be necessary, unless we exited on an error
3464 // and want to flush to get to the next packet
3465 flush_packet(f);
3466
3467 if (f->first_decode) {
3468 // assume we start so first non-discarded sample is sample 0
3469 // this isn't to spec, but spec would require us to read ahead
3470 // and decode the size of all current frames--could be done,
3471 // but presumably it's not a commonly used feature
3472 f->current_loc = 0u - n2; // start of first frame is positioned for discard (NB this is an intentional unsigned overflow/wrap-around)
3473 // we might have to discard samples "from" the next frame too,
3474 // if we're lapping a large block then a small at the start?
3475 f->discard_samples_deferred = n - right_end;
3476 f->current_loc_valid = TRUE;
3477 f->first_decode = FALSE;
3478 } else if (f->discard_samples_deferred) {
3479 if (f->discard_samples_deferred >= right_start - left_start) {
3480 f->discard_samples_deferred -= (right_start - left_start);
3481 left_start = right_start;
3482 *p_left = left_start;
3483 } else {
3484 left_start += f->discard_samples_deferred;
3485 *p_left = left_start;
3486 f->discard_samples_deferred = 0;
3487 }
3488 } else if (f->previous_length == 0 && f->current_loc_valid) {
3489 // we're recovering from a seek... that means we're going to discard
3490 // the samples from this packet even though we know our position from
3491 // the last page header, so we need to update the position based on
3492 // the discarded samples here
3493 // but wait, the code below is going to add this in itself even
3494 // on a discard, so we don't need to do it here...
3495 }
3496
3497 // check if we have ogg information about the sample # for this packet
3498 if (f->last_seg_which == f->end_seg_with_known_loc) {
3499 // if we have a valid current loc, and this is final:
3500 if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) {
3501 uint32 current_end = f->known_loc_for_packet;
3502 // then let's infer the size of the (probably) short final frame
3503 if (current_end < f->current_loc + (right_end-left_start)) {
3504 if (current_end < f->current_loc) {
3505 // negative truncation, that's impossible!
3506 *len = 0;
3507 } else {
3508 *len = current_end - f->current_loc;
3509 }
3510 *len += left_start; // this doesn't seem right, but has no ill effect on my test files
3511 if (*len > right_end) *len = right_end; // this should never happen
3512 f->current_loc += *len;
3513 return TRUE;
3514 }
3515 }
3516 // otherwise, just set our sample loc
3517 // guess that the ogg granule pos refers to the _middle_ of the
3518 // last frame?
3519 // set f->current_loc to the position of left_start
3520 f->current_loc = f->known_loc_for_packet - (n2-left_start);
3521 f->current_loc_valid = TRUE;
3522 }
3523 if (f->current_loc_valid)
3524 f->current_loc += (right_start - left_start);
3525
3526 if (f->alloc.alloc_buffer)
3527 assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset);
3528 *len = right_end; // ignore samples after the window goes to 0
3529 CHECK(f);
3530
3531 return TRUE;
3532 }
3533
3534 static int vorbis_decode_packet(vorb *f, int *len, int *p_left, int *p_right)
3535 {
3536 int mode, left_end, right_end;
3537 if (!vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, &mode)) return 0;
3538 return vorbis_decode_packet_rest(f, len, f->mode_config + mode, *p_left, left_end, *p_right, right_end, p_left);
3539 }
3540
3541 static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
3542 {
3543 int prev,i,j;
3544 // we use right&left (the start of the right- and left-window sin()-regions)
3545 // to determine how much to return, rather than inferring from the rules
3546 // (same result, clearer code); 'left' indicates where our sin() window
3547 // starts, therefore where the previous window's right edge starts, and
3548 // therefore where to start mixing from the previous buffer. 'right'
3549 // indicates where our sin() ending-window starts, therefore that's where
3550 // we start saving, and where our returned-data ends.
3551
3552 // mixin from previous window
3553 if (f->previous_length) {
3554 int i,j, n = f->previous_length;
3555 float *w = get_window(f, n);
3556 if (w == NULL) return 0;
3557 for (i=0; i < f->channels; ++i) {
3558 for (j=0; j < n; ++j)
3559 f->channel_buffers[i][left+j] =
3560 f->channel_buffers[i][left+j]*w[ j] +
3561 f->previous_window[i][ j]*w[n-1-j];
3562 }
3563 }
3564
3565 prev = f->previous_length;
3566
3567 // last half of this data becomes previous window
3568 f->previous_length = len - right;
3569
3570 // @OPTIMIZE: could avoid this copy by double-buffering the
3571 // output (flipping previous_window with channel_buffers), but
3572 // then previous_window would have to be 2x as large, and
3573 // channel_buffers couldn't be temp mem (although they're NOT
3574 // currently temp mem, they could be (unless we want to level
3575 // performance by spreading out the computation))
3576 for (i=0; i < f->channels; ++i)
3577 for (j=0; right+j < len; ++j)
3578 f->previous_window[i][j] = f->channel_buffers[i][right+j];
3579
3580 if (!prev)
3581 // there was no previous packet, so this data isn't valid...
3582 // this isn't entirely true, only the would-have-overlapped data
3583 // isn't valid, but this seems to be what the spec requires
3584 return 0;
3585
3586 // truncate a short frame
3587 if (len < right) right = len;
3588
3589 f->samples_output += right-left;
3590
3591 return right - left;
3592 }
3593
3594 static int vorbis_pump_first_frame(stb_vorbis *f)
3595 {
3596 int len, right, left, res;
3597 res = vorbis_decode_packet(f, &len, &left, &right);
3598 if (res)
3599 vorbis_finish_frame(f, len, left, right);
3600 f->current_playback_loc = 0;
3601 f->current_playback_loc_valid = TRUE;
3602 return res;
3603 }
3604
3605 #ifndef STB_VORBIS_NO_PUSHDATA_API
3606 static int is_whole_packet_present(stb_vorbis *f)
3607 {
3608 // make sure that we have the packet available before continuing...
3609 // this requires a full ogg parse, but we know we can fetch from f->stream
3610
3611 // instead of coding this out explicitly, we could save the current read state,
3612 // read the next packet with get8() until end-of-packet, check f->eof, then
3613 // reset the state? but that would be slower, esp. since we'd have over 256 bytes
3614 // of state to restore (primarily the page segment table)
3615
3616 int s = f->next_seg, first = TRUE;
3617 uint8 *p = f->stream;
3618
3619 if (s != -1) { // if we're not starting the packet with a 'continue on next page' flag
3620 for (; s < f->segment_count; ++s) {
3621 p += f->segments[s];
3622 if (f->segments[s] < 255) // stop at first short segment
3623 break;
3624 }
3625 // either this continues, or it ends it...
3626 if (s == f->segment_count)
3627 s = -1; // set 'crosses page' flag
3628 if (p > f->stream_end) return error(f, VORBIS_need_more_data);
3629 first = FALSE;
3630 }
3631 for (; s == -1;) {
3632 uint8 *q;
3633 int n;
3634
3635 // check that we have the page header ready
3636 if (p + 26 >= f->stream_end) return error(f, VORBIS_need_more_data);
3637 // validate the page
3638 if (memcmp(p, ogg_page_header, 4)) return error(f, VORBIS_invalid_stream);
3639 if (p[4] != 0) return error(f, VORBIS_invalid_stream);
3640 if (first) { // the first segment must NOT have 'continued_packet', later ones MUST
3641 if (f->previous_length)
3642 if ((p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream);
3643 // if no previous length, we're resynching, so we can come in on a continued-packet,
3644 // which we'll just drop
3645 } else {
3646 if (!(p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream);
3647 }
3648 n = p[26]; // segment counts
3649 q = p+27; // q points to segment table
3650 p = q + n; // advance past header
3651 // make sure we've read the segment table
3652 if (p > f->stream_end) return error(f, VORBIS_need_more_data);
3653 for (s=0; s < n; ++s) {
3654 p += q[s];
3655 if (q[s] < 255)
3656 break;
3657 }
3658 if (s == n)
3659 s = -1; // set 'crosses page' flag
3660 if (p > f->stream_end) return error(f, VORBIS_need_more_data);
3661 first = FALSE;
3662 }
3663 return TRUE;
3664 }
3665 #endif // !STB_VORBIS_NO_PUSHDATA_API
3666
3667 static int start_decoder(vorb *f)
3668 {
3669 uint8 header[6], x,y;
3670 int len,i,j,k, max_submaps = 0;
3671 int longest_floorlist=0;
3672
3673 // first page, first packet
3674 f->first_decode = TRUE;
3675
3676 if (!start_page(f)) return FALSE;
3677 // validate page flag
3678 if (!(f->page_flag & PAGEFLAG_first_page)) return error(f, VORBIS_invalid_first_page);
3679 if (f->page_flag & PAGEFLAG_last_page) return error(f, VORBIS_invalid_first_page);
3680 if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page);
3681 // check for expected packet length
3682 if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page);
3683 if (f->segments[0] != 30) {
3684 // check for the Ogg skeleton fishead identifying header to refine our error
3685 if (f->segments[0] == 64 &&
3686 getn(f, header, 6) &&
3687 header[0] == 'f' &&
3688 header[1] == 'i' &&
3689 header[2] == 's' &&
3690 header[3] == 'h' &&
3691 header[4] == 'e' &&
3692 header[5] == 'a' &&
3693 get8(f) == 'd' &&
3694 get8(f) == '\0') return error(f, VORBIS_ogg_skeleton_not_supported);
3695 else
3696 return error(f, VORBIS_invalid_first_page);
3697 }
3698
3699 // read packet
3700 // check packet header
3701 if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page);
3702 if (!getn(f, header, 6)) return error(f, VORBIS_unexpected_eof);
3703 if (!vorbis_validate(header)) return error(f, VORBIS_invalid_first_page);
3704 // vorbis_version
3705 if (get32(f) != 0) return error(f, VORBIS_invalid_first_page);
3706 f->channels = get8(f); if (!f->channels) return error(f, VORBIS_invalid_first_page);
3707 if (f->channels > STB_VORBIS_MAX_CHANNELS) return error(f, VORBIS_too_many_channels);
3708 f->sample_rate = get32(f); if (!f->sample_rate) return error(f, VORBIS_invalid_first_page);
3709 get32(f); // bitrate_maximum
3710 get32(f); // bitrate_nominal
3711 get32(f); // bitrate_minimum
3712 x = get8(f);
3713 {
3714 int log0,log1;
3715 log0 = x & 15;
3716 log1 = x >> 4;
3717 f->blocksize_0 = 1 << log0;
3718 f->blocksize_1 = 1 << log1;
3719 if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup);
3720 if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup);
3721 if (log0 > log1) return error(f, VORBIS_invalid_setup);
3722 }
3723
3724 // framing_flag
3725 x = get8(f);
3726 if (!(x & 1)) return error(f, VORBIS_invalid_first_page);
3727
3728 // second packet!
3729 if (!start_page(f)) return FALSE;
3730
3731 if (!start_packet(f)) return FALSE;
3732
3733 if (!next_segment(f)) return FALSE;
3734
3735 if (get8_packet(f) != VORBIS_packet_comment) return error(f, VORBIS_invalid_setup);
3736 for (i=0; i < 6; ++i) header[i] = get8_packet(f);
3737 if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup);
3738 //file vendor
3739 len = get32_packet(f);
3740 f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1));
3741 if (f->vendor == NULL) return error(f, VORBIS_outofmem);
3742 for(i=0; i < len; ++i) {
3743 f->vendor[i] = get8_packet(f);
3744 }
3745 f->vendor[len] = (char)'\0';
3746 //user comments
3747 f->comment_list_length = get32_packet(f);
3748 f->comment_list = NULL;
3749 if (f->comment_list_length > 0)
3750 {
3751 f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length));
3752 if (f->comment_list == NULL) return error(f, VORBIS_outofmem);
3753 }
3754
3755 for(i=0; i < f->comment_list_length; ++i) {
3756 len = get32_packet(f);
3757 f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1));
3758 if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem);
3759
3760 for(j=0; j < len; ++j) {
3761 f->comment_list[i][j] = get8_packet(f);
3762 }
3763 f->comment_list[i][len] = (char)'\0';
3764 }
3765
3766 // framing_flag
3767 x = get8_packet(f);
3768 if (!(x & 1)) return error(f, VORBIS_invalid_setup);
3769
3770
3771 skip(f, f->bytes_in_seg);
3772 f->bytes_in_seg = 0;
3773
3774 do {
3775 len = next_segment(f);
3776 skip(f, len);
3777 f->bytes_in_seg = 0;
3778 } while (len);
3779
3780 // third packet!
3781 if (!start_packet(f)) return FALSE;
3782
3783 #ifndef STB_VORBIS_NO_PUSHDATA_API
3784 if (IS_PUSH_MODE(f)) {
3785 if (!is_whole_packet_present(f)) {
3786 // convert error in ogg header to write type
3787 if (f->error == VORBIS_invalid_stream)
3788 f->error = VORBIS_invalid_setup;
3789 return FALSE;
3790 }
3791 }
3792 #endif
3793
3794 crc32_init(); // always init it, to avoid multithread race conditions
3795
3796 if (get8_packet(f) != VORBIS_packet_setup) return error(f, VORBIS_invalid_setup);
3797 for (i=0; i < 6; ++i) header[i] = get8_packet(f);
3798 if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup);
3799
3800 // codebooks
3801
3802 f->codebook_count = get_bits(f,8) + 1;
3803 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
3804 f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count);
3805 if (f->codebooks == NULL) return error(f, VORBIS_outofmem);
3806 memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count);
3807 for (i=0; i < f->codebook_count; ++i) {
3808 uint32 *values;
3809 int ordered, sorted_count;
3810 int total=0;
3811 uint8 *lengths;
3812 Codebook *c = f->codebooks+i;
3813 CHECK(f);
3814 x = get_bits(f, 8); if (x != 0x42) return error(f, VORBIS_invalid_setup);
3815 x = get_bits(f, 8); if (x != 0x43) return error(f, VORBIS_invalid_setup);
3816 x = get_bits(f, 8); if (x != 0x56) return error(f, VORBIS_invalid_setup);
3817 x = get_bits(f, 8);
3818 c->dimensions = (get_bits(f, 8)<<8) + x;
3819 x = get_bits(f, 8);
3820 y = get_bits(f, 8);
3821 c->entries = (get_bits(f, 8)<<16) + (y<<8) + x;
3822 ordered = get_bits(f,1);
3823 c->sparse = ordered ? 0 : get_bits(f,1);
3824
3825 if (c->dimensions == 0 && c->entries != 0) return error(f, VORBIS_invalid_setup);
3826 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
3827
3828 if (c->sparse) {
3829 lengths = (uint8 *) setup_temp_malloc(f, c->entries);
3830 f->temp_lengths = lengths;
3831 } else
3832 lengths = c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries);
3833
3834 if (!lengths) return error(f, VORBIS_outofmem);
3835
3836 if (ordered) {
3837 int current_entry = 0;
3838 int current_length = get_bits(f,5) + 1;
3839 while (current_entry < c->entries) {
3840 int limit = c->entries - current_entry;
3841 int n = get_bits(f, ilog(limit));
3842 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
3843 if (current_length >= 32) return error(f, VORBIS_invalid_setup);
3844 if (current_entry + n > (int) c->entries) return error(f, VORBIS_invalid_setup);
3845 memset(lengths + current_entry, current_length, n);
3846 current_entry += n;
3847 ++current_length;
3848 }
3849 } else {
3850 for (j=0; j < c->entries; ++j) {
3851 int present = c->sparse ? get_bits(f,1) : 1;
3852 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
3853 if (present) {
3854 lengths[j] = get_bits(f, 5) + 1;
3855 ++total;
3856 if (lengths[j] == 32) return error(f, VORBIS_invalid_setup);
3857 } else {
3858 lengths[j] = NO_CODE;
3859 }
3860 }
3861 }
3862
3863 if (c->sparse && total >= c->entries >> 2) {
3864 // convert sparse items to non-sparse!
3865 if (c->entries > (int) f->setup_temp_memory_required)
3866 f->setup_temp_memory_required = c->entries;
3867
3868 c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries);
3869 if (c->codeword_lengths == NULL) return error(f, VORBIS_outofmem);
3870 memcpy(c->codeword_lengths, lengths, c->entries);
3871 setup_temp_free(f, &f->temp_lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs!
3872 lengths = c->codeword_lengths;
3873 c->sparse = 0;
3874 }
3875
3876 // compute the size of the sorted tables
3877 if (c->sparse) {
3878 sorted_count = total;
3879 } else {
3880 sorted_count = 0;
3881 #ifndef STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
3882 for (j=0; j < c->entries; ++j)
3883 if (lengths[j] > STB_VORBIS_FAST_HUFFMAN_LENGTH && lengths[j] != NO_CODE)
3884 ++sorted_count;
3885 #endif
3886 }
3887
3888 c->sorted_entries = sorted_count;
3889 values = NULL;
3890
3891 CHECK(f);
3892 if (!c->sparse) {
3893 c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries);
3894 if (!c->codewords) return error(f, VORBIS_outofmem);
3895 } else {
3896 unsigned int size;
3897 if (c->sorted_entries) {
3898 c->codeword_lengths = (uint8 *) setup_malloc(f, c->sorted_entries);
3899 if (!c->codeword_lengths) return error(f, VORBIS_outofmem);
3900 c->codewords = (uint32 *) setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries);
3901 f->temp_codewords = c->codewords;
3902 if (!c->codewords) return error(f, VORBIS_outofmem);
3903 values = (uint32 *) setup_temp_malloc(f, sizeof(*values) * c->sorted_entries);
3904 f->temp_values = values;
3905 if (!values) return error(f, VORBIS_outofmem);
3906 }
3907 size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * c->sorted_entries;
3908 if (size > f->setup_temp_memory_required)
3909 f->setup_temp_memory_required = size;
3910 }
3911
3912 if (!compute_codewords(c, lengths, c->entries, values)) {
3913 return error(f, VORBIS_invalid_setup);
3914 }
3915
3916 if (c->sorted_entries) {
3917 // allocate an extra slot for sentinels
3918 c->sorted_codewords = (uint32 *) setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1));
3919 if (c->sorted_codewords == NULL) return error(f, VORBIS_outofmem);
3920 // allocate an extra slot at the front so that c->sorted_values[-1] is defined
3921 // so that we can catch that case without an extra if
3922 c->sorted_values = ( int *) setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1));
3923 if (c->sorted_values == NULL) return error(f, VORBIS_outofmem);
3924 ++c->sorted_values;
3925 c->sorted_values[-1] = -1;
3926 compute_sorted_huffman(c, lengths, values);
3927 }
3928
3929 if (c->sparse) {
3930 setup_temp_free(f, &f->temp_values, sizeof(*values)*c->sorted_entries);
3931 setup_temp_free(f, &f->temp_codewords, sizeof(*c->codewords)*c->sorted_entries);
3932 setup_temp_free(f, &f->temp_lengths, c->entries);
3933 c->codewords = NULL;
3934 }
3935
3936 compute_accelerated_huffman(c);
3937
3938 CHECK(f);
3939 c->lookup_type = get_bits(f, 4);
3940 if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup);
3941 if (c->lookup_type > 0) {
3942 uint16 *mults;
3943 c->minimum_value = float32_unpack(get_bits(f, 32));
3944 c->delta_value = float32_unpack(get_bits(f, 32));
3945 c->value_bits = get_bits(f, 4)+1;
3946 c->sequence_p = get_bits(f,1);
3947 if (c->lookup_type == 1) {
3948 int values = lookup1_values(c->entries, c->dimensions);
3949 if (values < 0) return error(f, VORBIS_invalid_setup);
3950 c->lookup_values = (uint32) values;
3951 } else {
3952 /* unsigned multiply to suppress (legitimate) warning.
3953 * https://github.com/nothings/stb/issues/1168 */
3954 c->lookup_values = (unsigned)c->entries * (unsigned)c->dimensions;
3955 }
3956 if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup);
3957 mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values);
3958 f->temp_mults = mults;
3959 if (mults == NULL) return error(f, VORBIS_outofmem);
3960 for (j=0; j < (int) c->lookup_values; ++j) {
3961 int q = get_bits(f, c->value_bits);
3962 if (f->valid_bits < 0) return error(f, VORBIS_invalid_setup);
3963 mults[j] = q;
3964 }
3965
3966 #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
3967 if (c->lookup_type == 1) {
3968 int len, sparse = c->sparse;
3969 float last=0;
3970 // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop
3971 if (sparse) {
3972 if (c->sorted_entries == 0) goto skip;
3973 c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions);
3974 } else
3975 c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions);
3976 if (c->multiplicands == NULL) return error(f, VORBIS_outofmem);
3977 len = sparse ? c->sorted_entries : c->entries;
3978 for (j=0; j < len; ++j) {
3979 unsigned int z = sparse ? c->sorted_values[j] : j;
3980 unsigned int div=1;
3981 for (k=0; k < c->dimensions; ++k) {
3982 int off = (z / div) % c->lookup_values;
3983 float val = mults[off]*c->delta_value + c->minimum_value + last;
3984 c->multiplicands[j*c->dimensions + k] = val;
3985 if (c->sequence_p)
3986 last = val;
3987 if (k+1 < c->dimensions) {
3988 if (div > UINT_MAX / (unsigned int) c->lookup_values) {
3989 return error(f, VORBIS_invalid_setup);
3990 }
3991 div *= c->lookup_values;
3992 }
3993 }
3994 }
3995 c->lookup_type = 2;
3996 }
3997 else
3998 #endif
3999 {
4000 float last=0;
4001 CHECK(f);
4002 c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values);
4003 if (c->multiplicands == NULL) return error(f, VORBIS_outofmem);
4004 for (j=0; j < (int) c->lookup_values; ++j) {
4005 float val = mults[j] * c->delta_value + c->minimum_value + last;
4006 c->multiplicands[j] = val;
4007 if (c->sequence_p)
4008 last = val;
4009 }
4010 }
4011 #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
4012 skip:;
4013 #endif
4014 setup_temp_free(f, &f->temp_mults, sizeof(mults[0])*c->lookup_values);
4015
4016 CHECK(f);
4017 }
4018 CHECK(f);
4019 }
4020
4021 // time domain transfers (notused)
4022
4023 x = get_bits(f, 6) + 1;
4024 for (i=0; i < x; ++i) {
4025 uint32 z = get_bits(f, 16);
4026 if (z != 0) return error(f, VORBIS_invalid_setup);
4027 }
4028
4029 // Floors
4030 f->floor_count = get_bits(f, 6)+1;
4031 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4032 f->floor_config = (Floor *) setup_malloc(f, f->floor_count * sizeof(*f->floor_config));
4033 if (f->floor_config == NULL) return error(f, VORBIS_outofmem);
4034 for (i=0; i < f->floor_count; ++i) {
4035 f->floor_types[i] = get_bits(f, 16);
4036 if (f->floor_types[i] > 1) return error(f, VORBIS_invalid_setup);
4037 if (f->floor_types[i] == 0) {
4038 Floor0 *g = &f->floor_config[i].floor0;
4039 g->order = get_bits(f,8);
4040 g->rate = get_bits(f,16);
4041 g->bark_map_size = get_bits(f,16);
4042 g->amplitude_bits = get_bits(f,6);
4043 g->amplitude_offset = get_bits(f,8);
4044 g->number_of_books = get_bits(f,4) + 1;
4045 for (j=0; j < g->number_of_books; ++j)
4046 g->book_list[j] = get_bits(f,8);
4047 return error(f, VORBIS_feature_not_supported);
4048 } else {
4049 stbv__floor_ordering p[31*8+2];
4050 Floor1 *g = &f->floor_config[i].floor1;
4051 int max_class = -1;
4052 g->partitions = get_bits(f, 5);
4053 for (j=0; j < g->partitions; ++j) {
4054 g->partition_class_list[j] = get_bits(f, 4);
4055 if (g->partition_class_list[j] > max_class)
4056 max_class = g->partition_class_list[j];
4057 }
4058 for (j=0; j <= max_class; ++j) {
4059 g->class_dimensions[j] = get_bits(f, 3)+1;
4060 g->class_subclasses[j] = get_bits(f, 2);
4061 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4062 if (g->class_subclasses[j]) {
4063 g->class_masterbooks[j] = get_bits(f, 8);
4064 if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
4065 }
4066 for (k=0; k < 1 << g->class_subclasses[j]; ++k) {
4067 g->subclass_books[j][k] = (int16)get_bits(f,8)-1;
4068 if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
4069 }
4070 }
4071 g->floor1_multiplier = get_bits(f,2)+1;
4072 g->rangebits = get_bits(f,4);
4073 g->Xlist[0] = 0;
4074 g->Xlist[1] = 1 << g->rangebits;
4075 g->values = 2;
4076 for (j=0; j < g->partitions; ++j) {
4077 int c = g->partition_class_list[j];
4078 for (k=0; k < g->class_dimensions[c]; ++k) {
4079 g->Xlist[g->values] = get_bits(f, g->rangebits);
4080 ++g->values;
4081 }
4082 }
4083 // precompute the sorting
4084 for (j=0; j < g->values; ++j) {
4085 p[j].x = g->Xlist[j];
4086 p[j].id = j;
4087 }
4088 qsort(p, g->values, sizeof(p[0]), point_compare);
4089 for (j=0; j < g->values-1; ++j)
4090 if (p[j].x == p[j+1].x)
4091 return error(f, VORBIS_invalid_setup);
4092 for (j=0; j < g->values; ++j)
4093 g->sorted_order[j] = (uint8) p[j].id;
4094 // precompute the neighbors
4095 for (j=2; j < g->values; ++j) {
4096 int low = 0,hi = 0;
4097 neighbors(g->Xlist, j, &low,&hi);
4098 g->neighbors[j][0] = low;
4099 g->neighbors[j][1] = hi;
4100 }
4101
4102 if (g->values > longest_floorlist)
4103 longest_floorlist = g->values;
4104 }
4105 }
4106
4107 // Residue
4108 f->residue_count = get_bits(f, 6)+1;
4109 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4110 f->residue_config = (Residue *) setup_malloc(f, f->residue_count * sizeof(f->residue_config[0]));
4111 if (f->residue_config == NULL) return error(f, VORBIS_outofmem);
4112 memset(f->residue_config, 0, f->residue_count * sizeof(f->residue_config[0]));
4113 for (i=0; i < f->residue_count; ++i) {
4114 uint8 residue_cascade[64];
4115 Residue *r = f->residue_config+i;
4116 f->residue_types[i] = get_bits(f, 16);
4117 if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup);
4118 r->begin = get_bits(f, 24);
4119 r->end = get_bits(f, 24);
4120 if (r->end < r->begin) return error(f, VORBIS_invalid_setup);
4121 r->part_size = get_bits(f,24)+1;
4122 r->classifications = get_bits(f,6)+1;
4123 r->classbook = get_bits(f,8);
4124 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4125 if (r->classbook >= f->codebook_count) return error(f, VORBIS_invalid_setup);
4126 for (j=0; j < r->classifications; ++j) {
4127 uint8 high_bits=0;
4128 uint8 low_bits=get_bits(f,3);
4129 if (get_bits(f,1))
4130 high_bits = get_bits(f,5);
4131 residue_cascade[j] = high_bits*8 + low_bits;
4132 }
4133 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4134 r->residue_books = (short (*)[8]) setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications);
4135 if (r->residue_books == NULL) return error(f, VORBIS_outofmem);
4136 for (j=0; j < r->classifications; ++j) {
4137 for (k=0; k < 8; ++k) {
4138 if (residue_cascade[j] & (1 << k)) {
4139 r->residue_books[j][k] = get_bits(f, 8);
4140 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4141 if (r->residue_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
4142 } else {
4143 r->residue_books[j][k] = -1;
4144 }
4145 }
4146 }
4147 // precompute the classifications[] array to avoid inner-loop mod/divide
4148 // call it 'classdata' since we already have r->classifications
4149 r->classdata = (uint8 **) setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries);
4150 if (!r->classdata) return error(f, VORBIS_outofmem);
4151 memset(r->classdata, 0, sizeof(*r->classdata) * f->codebooks[r->classbook].entries);
4152 for (j=0; j < f->codebooks[r->classbook].entries; ++j) {
4153 int classwords = f->codebooks[r->classbook].dimensions;
4154 int temp = j;
4155 r->classdata[j] = (uint8 *) setup_malloc(f, sizeof(r->classdata[j][0]) * classwords);
4156 if (r->classdata[j] == NULL) return error(f, VORBIS_outofmem);
4157 for (k=classwords-1; k >= 0; --k) {
4158 r->classdata[j][k] = temp % r->classifications;
4159 temp /= r->classifications;
4160 }
4161 }
4162 }
4163
4164 f->mapping_count = get_bits(f,6)+1;
4165 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4166 f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping));
4167 if (f->mapping == NULL) return error(f, VORBIS_outofmem);
4168 memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping));
4169 for (i=0; i < f->mapping_count; ++i) {
4170 Mapping *m = f->mapping + i;
4171 int mapping_type = get_bits(f,16);
4172 if (mapping_type != 0) return error(f, VORBIS_invalid_setup);
4173 m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan));
4174 if (m->chan == NULL) return error(f, VORBIS_outofmem);
4175 if (get_bits(f,1))
4176 m->submaps = get_bits(f,4)+1;
4177 else
4178 m->submaps = 1;
4179 if (m->submaps > max_submaps)
4180 max_submaps = m->submaps;
4181 if (get_bits(f,1)) {
4182 m->coupling_steps = get_bits(f,8)+1;
4183 if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup);
4184 for (k=0; k < m->coupling_steps; ++k) {
4185 m->chan[k].magnitude = get_bits(f, ilog(f->channels-1));
4186 m->chan[k].angle = get_bits(f, ilog(f->channels-1));
4187 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4188 if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup);
4189 if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup);
4190 if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup);
4191 }
4192 } else
4193 m->coupling_steps = 0;
4194
4195 // reserved field
4196 if (get_bits(f,2)) return error(f, VORBIS_invalid_setup);
4197 if (m->submaps > 1) {
4198 for (j=0; j < f->channels; ++j) {
4199 m->chan[j].mux = get_bits(f, 4);
4200 if (m->chan[j].mux >= m->submaps) return error(f, VORBIS_invalid_setup);
4201 }
4202 } else
4203 // @SPECIFICATION: this case is missing from the spec
4204 for (j=0; j < f->channels; ++j)
4205 m->chan[j].mux = 0;
4206
4207 for (j=0; j < m->submaps; ++j) {
4208 get_bits(f,8); // discard
4209 m->submap_floor[j] = get_bits(f,8);
4210 m->submap_residue[j] = get_bits(f,8);
4211 if (m->submap_floor[j] >= f->floor_count) return error(f, VORBIS_invalid_setup);
4212 if (m->submap_residue[j] >= f->residue_count) return error(f, VORBIS_invalid_setup);
4213 }
4214 }
4215
4216 // Modes
4217 f->mode_count = get_bits(f, 6)+1;
4218 for (i=0; i < f->mode_count; ++i) {
4219 Mode *m = f->mode_config+i;
4220 m->blockflag = get_bits(f,1);
4221 m->windowtype = get_bits(f,16);
4222 m->transformtype = get_bits(f,16);
4223 m->mapping = get_bits(f,8);
4224 if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
4225 if (m->windowtype != 0) return error(f, VORBIS_invalid_setup);
4226 if (m->transformtype != 0) return error(f, VORBIS_invalid_setup);
4227 if (m->mapping >= f->mapping_count) return error(f, VORBIS_invalid_setup);
4228 }
4229
4230 flush_packet(f);
4231
4232 f->previous_length = 0;
4233
4234 for (i=0; i < f->channels; ++i) {
4235 f->channel_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1);
4236 f->previous_window[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2);
4237 f->finalY[i] = (int16 *) setup_malloc(f, sizeof(int16) * longest_floorlist);
4238 if (f->channel_buffers[i] == NULL || f->previous_window[i] == NULL || f->finalY[i] == NULL) return error(f, VORBIS_outofmem);
4239 memset(f->channel_buffers[i], 0, sizeof(float) * f->blocksize_1);
4240 #ifdef STB_VORBIS_NO_DEFER_FLOOR
4241 f->floor_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2);
4242 if (f->floor_buffers[i] == NULL) return error(f, VORBIS_outofmem);
4243 #endif
4244 }
4245
4246 if (!init_blocksize(f, 0, f->blocksize_0)) return FALSE;
4247 if (!init_blocksize(f, 1, f->blocksize_1)) return FALSE;
4248 f->blocksize[0] = f->blocksize_0;
4249 f->blocksize[1] = f->blocksize_1;
4250
4251 #ifdef STB_VORBIS_DIVIDE_TABLE
4252 if (integer_divide_table[1][1]==0)
4253 for (i=0; i < DIVTAB_NUMER; ++i)
4254 for (j=1; j < DIVTAB_DENOM; ++j)
4255 integer_divide_table[i][j] = i / j;
4256 #endif
4257
4258 // compute how much temporary memory is needed
4259
4260 // 1.
4261 {
4262 uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1);
4263 uint32 classify_mem;
4264 int i,max_part_read=0;
4265 for (i=0; i < f->residue_count; ++i) {
4266 Residue *r = f->residue_config + i;
4267 unsigned int actual_size = f->blocksize_1 / 2;
4268 unsigned int limit_r_begin = r->begin < actual_size ? r->begin : actual_size;
4269 unsigned int limit_r_end = r->end < actual_size ? r->end : actual_size;
4270 int n_read = limit_r_end - limit_r_begin;
4271 int part_read = n_read / r->part_size;
4272 if (part_read > max_part_read)
4273 max_part_read = part_read;
4274 }
4275 #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
4276 classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(uint8 *));
4277 #else
4278 classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *));
4279 #endif
4280
4281 // maximum reasonable partition size is f->blocksize_1
4282
4283 f->temp_memory_required = classify_mem;
4284 if (imdct_mem > f->temp_memory_required)
4285 f->temp_memory_required = imdct_mem;
4286 }
4287
4288
4289 if (f->alloc.alloc_buffer) {
4290 assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes);
4291 // check if there's enough temp memory so we don't error later
4292 if (f->setup_offset + sizeof(*f) + f->temp_memory_required > (unsigned) f->temp_offset)
4293 return error(f, VORBIS_outofmem);
4294 } else {
4295 f->work_buffer = setup_malloc(f, f->temp_memory_required);
4296 if (f->work_buffer == NULL) return error(f, VORBIS_outofmem);
4297 }
4298
4299 // @TODO: stb_vorbis_seek_start expects first_audio_page_offset to point to a page
4300 // without PAGEFLAG_continued_packet, so this either points to the first page, or
4301 // the page after the end of the headers. It might be cleaner to point to a page
4302 // in the middle of the headers, when that's the page where the first audio packet
4303 // starts, but we'd have to also correctly skip the end of any continued packet in
4304 // stb_vorbis_seek_start.
4305 if (f->next_seg == -1) {
4306 f->first_audio_page_offset = stb_vorbis_get_file_offset(f);
4307 } else {
4308 f->first_audio_page_offset = 0;
4309 }
4310
4311 return TRUE;
4312 }
4313
4314 static void vorbis_deinit(stb_vorbis *p)
4315 {
4316 int i,j;
4317
4318 setup_free(p, p->vendor);
4319 for (i=0; i < p->comment_list_length; ++i) {
4320 setup_free(p, p->comment_list[i]);
4321 }
4322 setup_free(p, p->comment_list);
4323
4324 if (p->residue_config) {
4325 for (i=0; i < p->residue_count; ++i) {
4326 Residue *r = p->residue_config+i;
4327 if (r->classdata) {
4328 for (j=0; j < p->codebooks[r->classbook].entries; ++j)
4329 setup_free(p, r->classdata[j]);
4330 setup_free(p, r->classdata);
4331 }
4332 setup_free(p, r->residue_books);
4333 }
4334 }
4335
4336 if (p->codebooks) {
4337 CHECK(p);
4338 for (i=0; i < p->codebook_count; ++i) {
4339 Codebook *c = p->codebooks + i;
4340 setup_free(p, c->codeword_lengths);
4341 setup_free(p, c->multiplicands);
4342 if (c->codewords != p->temp_codewords) // Might be the temporary buffer-allocated array.
4343 setup_free(p, c->codewords);
4344 setup_free(p, c->sorted_codewords);
4345 // c->sorted_values[-1] is the first entry in the array
4346 setup_free(p, c->sorted_values ? c->sorted_values-1 : NULL);
4347 }
4348 setup_free(p, p->codebooks);
4349 }
4350 setup_free(p, p->floor_config);
4351 setup_free(p, p->residue_config);
4352 if (p->mapping) {
4353 for (i=0; i < p->mapping_count; ++i)
4354 setup_free(p, p->mapping[i].chan);
4355 setup_free(p, p->mapping);
4356 }
4357 CHECK(p);
4358 for (i=0; i < p->channels && i < STB_VORBIS_MAX_CHANNELS; ++i) {
4359 setup_free(p, p->channel_buffers[i]);
4360 setup_free(p, p->previous_window[i]);
4361 #ifdef STB_VORBIS_NO_DEFER_FLOOR
4362 setup_free(p, p->floor_buffers[i]);
4363 #endif
4364 setup_free(p, p->finalY[i]);
4365 }
4366 for (i=0; i < 2; ++i) {
4367 setup_free(p, p->A[i]);
4368 setup_free(p, p->B[i]);
4369 setup_free(p, p->C[i]);
4370 setup_free(p, p->window[i]);
4371 setup_free(p, p->bit_reverse[i]);
4372 }
4373 if (!p->alloc.alloc_buffer) {
4374 setup_free(p, p->work_buffer);
4375 setup_temp_free(p, &p->temp_lengths, 0);
4376 setup_temp_free(p, &p->temp_codewords, 0);
4377 setup_temp_free(p, &p->temp_values, 0);
4378 setup_temp_free(p, &p->temp_mults, 0);
4379 }
4380 #ifdef STB_VORBIS_SDL
4381 if (p->close_on_free) SDL_RWclose(p->rwops);
4382 #endif
4383 #ifndef STB_VORBIS_NO_STDIO
4384 if (p->close_on_free) fclose(p->f);
4385 #endif
4386 }
4387
4388 void stb_vorbis_close(stb_vorbis *p)
4389 {
4390 if (p == NULL) return;
4391 vorbis_deinit(p);
4392 setup_free(p,p);
4393 }
4394
4395 static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z)
4396 {
4397 memset(p, 0, sizeof(*p)); // NULL out all malloc'd pointers to start
4398 if (z) {
4399 p->alloc = *z;
4400 p->alloc.alloc_buffer_length_in_bytes &= ~7;
4401 p->temp_offset = p->alloc.alloc_buffer_length_in_bytes;
4402 }
4403 p->eof = 0;
4404 p->error = VORBIS__no_error;
4405 p->stream = NULL;
4406 p->codebooks = NULL;
4407 p->page_crc_tests = -1;
4408 #ifdef STB_VORBIS_SDL
4409 p->close_on_free = FALSE;
4410 p->rwops = NULL;
4411 #endif
4412 #ifndef STB_VORBIS_NO_STDIO
4413 p->close_on_free = FALSE;
4414 p->f = NULL;
4415 #endif
4416 }
4417
4418 int stb_vorbis_get_sample_offset(stb_vorbis *f)
4419 {
4420 if (f->current_loc_valid)
4421 return f->current_loc;
4422 else
4423 return -1;
4424 }
4425
4426 int stb_vorbis_get_playback_sample_offset(stb_vorbis *f)
4427 {
4428 if (f->current_playback_loc_valid)
4429 return f->current_playback_loc;
4430 else
4431 return -1;
4432 }
4433
4434 stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f)
4435 {
4436 stb_vorbis_info d;
4437 d.channels = f->channels;
4438 d.sample_rate = f->sample_rate;
4439 d.setup_memory_required = f->setup_memory_required;
4440 d.setup_temp_memory_required = f->setup_temp_memory_required;
4441 d.temp_memory_required = f->temp_memory_required;
4442 d.max_frame_size = f->blocksize_1 >> 1;
4443 return d;
4444 }
4445
4446 stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f)
4447 {
4448 stb_vorbis_comment d;
4449 d.vendor = f->vendor;
4450 d.comment_list_length = f->comment_list_length;
4451 d.comment_list = f->comment_list;
4452 return d;
4453 }
4454
4455 int stb_vorbis_get_error(stb_vorbis *f)
4456 {
4457 int e = f->error;
4458 f->error = VORBIS__no_error;
4459 return e;
4460 }
4461
4462 static stb_vorbis * vorbis_alloc(stb_vorbis *f)
4463 {
4464 stb_vorbis *p = (stb_vorbis *) setup_malloc(f, sizeof(*p));
4465 return p;
4466 }
4467
4468 #ifndef STB_VORBIS_NO_PUSHDATA_API
4469
4470 void stb_vorbis_flush_pushdata(stb_vorbis *f)
4471 {
4472 f->previous_length = 0;
4473 f->page_crc_tests = 0;
4474 f->discard_samples_deferred = 0;
4475 f->current_loc_valid = FALSE;
4476 f->first_decode = FALSE;
4477 f->samples_output = 0;
4478 f->channel_buffer_start = 0;
4479 f->channel_buffer_end = 0;
4480 }
4481
4482 static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len)
4483 {
4484 int i,n;
4485 for (i=0; i < f->page_crc_tests; ++i)
4486 f->scan[i].bytes_done = 0;
4487
4488 // if we have room for more scans, search for them first, because
4489 // they may cause us to stop early if their header is incomplete
4490 if (f->page_crc_tests < STB_VORBIS_PUSHDATA_CRC_COUNT) {
4491 if (data_len < 4) return 0;
4492 data_len -= 3; // need to look for 4-byte sequence, so don't miss
4493 // one that straddles a boundary
4494 for (i=0; i < data_len; ++i) {
4495 if (data[i] == 0x4f) {
4496 if (0==memcmp(data+i, ogg_page_header, 4)) {
4497 int j,len;
4498 uint32 crc;
4499 // make sure we have the whole page header
4500 if (i+26 >= data_len || i+27+data[i+26] >= data_len) {
4501 // only read up to this page start, so hopefully we'll
4502 // have the whole page header start next time
4503 data_len = i;
4504 break;
4505 }
4506 // ok, we have it all; compute the length of the page
4507 len = 27 + data[i+26];
4508 for (j=0; j < data[i+26]; ++j)
4509 len += data[i+27+j];
4510 // scan everything up to the embedded crc (which we must 0)
4511 crc = 0;
4512 for (j=0; j < 22; ++j)
4513 crc = crc32_update(crc, data[i+j]);
4514 // now process 4 0-bytes
4515 for ( ; j < 26; ++j)
4516 crc = crc32_update(crc, 0);
4517 // len is the total number of bytes we need to scan
4518 n = f->page_crc_tests++;
4519 f->scan[n].bytes_left = len-j;
4520 f->scan[n].crc_so_far = crc;
4521 f->scan[n].goal_crc = data[i+22] + (data[i+23] << 8) + (data[i+24]<<16) + (data[i+25]<<24);
4522 // if the last frame on a page is continued to the next, then
4523 // we can't recover the sample_loc immediately
4524 if (data[i+27+data[i+26]-1] == 255)
4525 f->scan[n].sample_loc = ~0;
4526 else
4527 f->scan[n].sample_loc = data[i+6] + (data[i+7] << 8) + (data[i+ 8]<<16) + (data[i+ 9]<<24);
4528 f->scan[n].bytes_done = i+j;
4529 if (f->page_crc_tests == STB_VORBIS_PUSHDATA_CRC_COUNT)
4530 break;
4531 // keep going if we still have room for more
4532 }
4533 }
4534 }
4535 }
4536
4537 for (i=0; i < f->page_crc_tests;) {
4538 uint32 crc;
4539 int j;
4540 int n = f->scan[i].bytes_done;
4541 int m = f->scan[i].bytes_left;
4542 if (m > data_len - n) m = data_len - n;
4543 // m is the bytes to scan in the current chunk
4544 crc = f->scan[i].crc_so_far;
4545 for (j=0; j < m; ++j)
4546 crc = crc32_update(crc, data[n+j]);
4547 f->scan[i].bytes_left -= m;
4548 f->scan[i].crc_so_far = crc;
4549 if (f->scan[i].bytes_left == 0) {
4550 // does it match?
4551 if (f->scan[i].crc_so_far == f->scan[i].goal_crc) {
4552 // Houston, we have page
4553 data_len = n+m; // consumption amount is wherever that scan ended
4554 f->page_crc_tests = -1; // drop out of page scan mode
4555 f->previous_length = 0; // decode-but-don't-output one frame
4556 f->next_seg = -1; // start a new page
4557 f->current_loc = f->scan[i].sample_loc; // set the current sample location
4558 // to the amount we'd have decoded had we decoded this page
4559 f->current_loc_valid = f->current_loc != ~0U;
4560 return data_len;
4561 }
4562 // delete entry
4563 f->scan[i] = f->scan[--f->page_crc_tests];
4564 } else {
4565 ++i;
4566 }
4567 }
4568
4569 return data_len;
4570 }
4571
4572 // return value: number of bytes we used
4573 int stb_vorbis_decode_frame_pushdata(
4574 stb_vorbis *f, // the file we're decoding
4575 const uint8 *data, int data_len, // the memory available for decoding
4576 int *channels, // place to write number of float * buffers
4577 float ***output, // place to write float ** array of float * buffers
4578 int *samples // place to write number of output samples
4579 )
4580 {
4581 int i;
4582 int len,right,left;
4583
4584 if (!IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);
4585
4586 if (f->page_crc_tests >= 0) {
4587 *samples = 0;
4588 return vorbis_search_for_page_pushdata(f, (uint8 *) data, data_len);
4589 }
4590
4591 f->stream = (uint8 *) data;
4592 f->stream_end = (uint8 *) data + data_len;
4593 f->error = VORBIS__no_error;
4594
4595 // check that we have the entire packet in memory
4596 if (!is_whole_packet_present(f)) {
4597 *samples = 0;
4598 return 0;
4599 }
4600
4601 if (!vorbis_decode_packet(f, &len, &left, &right)) {
4602 // save the actual error we encountered
4603 enum STBVorbisError error = f->error;
4604 if (error == VORBIS_bad_packet_type) {
4605 // flush and resynch
4606 f->error = VORBIS__no_error;
4607 while (get8_packet(f) != EOP)
4608 if (f->eof) break;
4609 *samples = 0;
4610 return (int) (f->stream - data);
4611 }
4612 if (error == VORBIS_continued_packet_flag_invalid) {
4613 if (f->previous_length == 0) {
4614 // we may be resynching, in which case it's ok to hit one
4615 // of these; just discard the packet
4616 f->error = VORBIS__no_error;
4617 while (get8_packet(f) != EOP)
4618 if (f->eof) break;
4619 *samples = 0;
4620 return (int) (f->stream - data);
4621 }
4622 }
4623 // if we get an error while parsing, what to do?
4624 // well, it DEFINITELY won't work to continue from where we are!
4625 stb_vorbis_flush_pushdata(f);
4626 // restore the error that actually made us bail
4627 f->error = error;
4628 *samples = 0;
4629 return 1;
4630 }
4631
4632 // success!
4633 len = vorbis_finish_frame(f, len, left, right);
4634 for (i=0; i < f->channels; ++i)
4635 f->outputs[i] = f->channel_buffers[i] + left;
4636
4637 if (channels) *channels = f->channels;
4638 *samples = len;
4639 *output = f->outputs;
4640 return (int) (f->stream - data);
4641 }
4642
4643 stb_vorbis *stb_vorbis_open_pushdata(
4644 const unsigned char *data, int data_len, // the memory available for decoding
4645 int *data_used, // only defined if result is not NULL
4646 int *error, const stb_vorbis_alloc *alloc)
4647 {
4648 stb_vorbis *f, p;
4649 vorbis_init(&p, alloc);
4650 p.stream = (uint8 *) data;
4651 p.stream_end = (uint8 *) data + data_len;
4652 p.push_mode = TRUE;
4653 if (!start_decoder(&p)) {
4654 if (p.eof)
4655 *error = VORBIS_need_more_data;
4656 else
4657 *error = p.error;
4658 vorbis_deinit(&p);
4659 return NULL;
4660 }
4661 f = vorbis_alloc(&p);
4662 if (f) {
4663 *f = p;
4664 *data_used = (int) (f->stream - data);
4665 *error = 0;
4666 return f;
4667 } else {
4668 vorbis_deinit(&p);
4669 return NULL;
4670 }
4671 }
4672 #endif // STB_VORBIS_NO_PUSHDATA_API
4673
4674 unsigned int stb_vorbis_get_file_offset(stb_vorbis *f)
4675 {
4676 #ifndef STB_VORBIS_NO_PUSHDATA_API
4677 if (f->push_mode) return 0;
4678 #endif
4679 #ifdef STB_VORBIS_SDL
4680 return (unsigned int) (SDL_RWtell(f->rwops) - f->rwops_start);
4681 #else
4682 if (USE_MEMORY(f)) return (unsigned int) (f->stream - f->stream_start);
4683 #endif
4684 #ifndef STB_VORBIS_NO_STDIO
4685 return (unsigned int) (ftell(f->f) - f->f_start);
4686 #endif
4687 }
4688
4689 #ifndef STB_VORBIS_NO_PULLDATA_API
4690 //
4691 // DATA-PULLING API
4692 //
4693
4694 static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last)
4695 {
4696 for(;;) {
4697 int n;
4698 if (f->eof) return 0;
4699 n = get8(f);
4700 if (n == 0x4f) { // page header candidate
4701 unsigned int retry_loc = stb_vorbis_get_file_offset(f);
4702 int i;
4703 // check if we're off the end of a file_section stream
4704 if (retry_loc - 25 > f->stream_len)
4705 return 0;
4706 // check the rest of the header
4707 for (i=1; i < 4; ++i)
4708 if (get8(f) != ogg_page_header[i])
4709 break;
4710 if (f->eof) return 0;
4711 if (i == 4) {
4712 uint8 header[27];
4713 uint32 i, crc, goal, len;
4714 for (i=0; i < 4; ++i)
4715 header[i] = ogg_page_header[i];
4716 for (; i < 27; ++i)
4717 header[i] = get8(f);
4718 if (f->eof) return 0;
4719 if (header[4] != 0) goto invalid;
4720 goal = header[22] + (header[23] << 8) + (header[24]<<16) + ((uint32)header[25]<<24);
4721 for (i=22; i < 26; ++i)
4722 header[i] = 0;
4723 crc = 0;
4724 for (i=0; i < 27; ++i)
4725 crc = crc32_update(crc, header[i]);
4726 len = 0;
4727 for (i=0; i < header[26]; ++i) {
4728 int s = get8(f);
4729 crc = crc32_update(crc, s);
4730 len += s;
4731 }
4732 if (len && f->eof) return 0;
4733 for (i=0; i < len; ++i)
4734 crc = crc32_update(crc, get8(f));
4735 // finished parsing probable page
4736 if (crc == goal) {
4737 // we could now check that it's either got the last
4738 // page flag set, OR it's followed by the capture
4739 // pattern, but I guess TECHNICALLY you could have
4740 // a file with garbage between each ogg page and recover
4741 // from it automatically? So even though that paranoia
4742 // might decrease the chance of an invalid decode by
4743 // another 2^32, not worth it since it would hose those
4744 // invalid-but-useful files?
4745 if (end)
4746 *end = stb_vorbis_get_file_offset(f);
4747 if (last) {
4748 if (header[5] & 0x04)
4749 *last = 1;
4750 else
4751 *last = 0;
4752 }
4753 set_file_offset(f, retry_loc-1);
4754 return 1;
4755 }
4756 }
4757 invalid:
4758 // not a valid page, so rewind and look for next one
4759 set_file_offset(f, retry_loc);
4760 }
4761 }
4762 }
4763
4764
4765 #define SAMPLE_unknown 0xffffffff
4766
4767 // seeking is implemented with a binary search, which narrows down the range to
4768 // 64K, before using a linear search (because finding the synchronization
4769 // pattern can be expensive, and the chance we'd find the end page again is
4770 // relatively high for small ranges)
4771 //
4772 // two initial interpolation-style probes are used at the start of the search
4773 // to try to bound either side of the binary search sensibly, while still
4774 // working in O(log n) time if they fail.
4775
4776 static int get_seek_page_info(stb_vorbis *f, ProbedPage *z)
4777 {
4778 uint8 header[27], lacing[255];
4779 int i,len;
4780
4781 // record where the page starts
4782 z->page_start = stb_vorbis_get_file_offset(f);
4783
4784 // parse the header
4785 if (!getn(f, header, 27))
4786 return 0;
4787 if (header[0] != 'O' || header[1] != 'g' || header[2] != 'g' || header[3] != 'S')
4788 return 0;
4789 if (!getn(f, lacing, header[26]))
4790 return 0;
4791
4792 // determine the length of the payload
4793 len = 0;
4794 for (i=0; i < header[26]; ++i)
4795 len += lacing[i];
4796
4797 // this implies where the page ends
4798 z->page_end = z->page_start + 27 + header[26] + len;
4799
4800 // read the last-decoded sample out of the data
4801 z->last_decoded_sample = header[6] + (header[7] << 8) + (header[8] << 16) + (header[9] << 24);
4802
4803 // restore file state to where we were
4804 set_file_offset(f, z->page_start);
4805 return 1;
4806 }
4807
4808 // rarely used function to seek back to the preceding page while finding the
4809 // start of a packet
4810 static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset)
4811 {
4812 unsigned int previous_safe;
4813 uint32 end;
4814
4815 // now we want to seek back 64K from the limit
4816 if (limit_offset >= 65536 && limit_offset-65536 >= f->first_audio_page_offset)
4817 previous_safe = limit_offset - 65536;
4818 else
4819 previous_safe = f->first_audio_page_offset;
4820
4821 set_file_offset(f, previous_safe);
4822
4823 while (vorbis_find_page(f, &end, NULL)) {
4824 if (end >= limit_offset && stb_vorbis_get_file_offset(f) < limit_offset)
4825 return 1;
4826 set_file_offset(f, end);
4827 }
4828
4829 return 0;
4830 }
4831
4832 // implements the search logic for finding a page and starting decoding. if
4833 // the function succeeds, current_loc_valid will be true and current_loc will
4834 // be less than or equal to the provided sample number (the closer the
4835 // better).
4836 static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
4837 {
4838 ProbedPage left, right, mid;
4839 int i, start_seg_with_known_loc, end_pos, page_start;
4840 uint32 delta, stream_length, padding, last_sample_limit;
4841 double offset = 0.0, bytes_per_sample = 0.0;
4842 int probe = 0;
4843
4844 // find the last page and validate the target sample
4845 stream_length = stb_vorbis_stream_length_in_samples(f);
4846 if (stream_length == 0) return error(f, VORBIS_seek_without_length);
4847 if (sample_number > stream_length) return error(f, VORBIS_seek_invalid);
4848
4849 // this is the maximum difference between the window-center (which is the
4850 // actual granule position value), and the right-start (which the spec
4851 // indicates should be the granule position (give or take one)).
4852 padding = ((f->blocksize_1 - f->blocksize_0) >> 2);
4853 if (sample_number < padding)
4854 last_sample_limit = 0;
4855 else
4856 last_sample_limit = sample_number - padding;
4857
4858 left = f->p_first;
4859 while (left.last_decoded_sample == ~0U) {
4860 // (untested) the first page does not have a 'last_decoded_sample'
4861 set_file_offset(f, left.page_end);
4862 if (!get_seek_page_info(f, &left)) goto error;
4863 }
4864
4865 right = f->p_last;
4866 assert(right.last_decoded_sample != ~0U);
4867
4868 // starting from the start is handled differently
4869 if (last_sample_limit <= left.last_decoded_sample) {
4870 if (stb_vorbis_seek_start(f)) {
4871 if (f->current_loc > sample_number)
4872 return error(f, VORBIS_seek_failed);
4873 return 1;
4874 }
4875 return 0;
4876 }
4877
4878 while (left.page_end != right.page_start) {
4879 assert(left.page_end < right.page_start);
4880 // search range in bytes
4881 delta = right.page_start - left.page_end;
4882 if (delta <= 65536) {
4883 // there's only 64K left to search - handle it linearly
4884 set_file_offset(f, left.page_end);
4885 } else {
4886 if (probe < 2) {
4887 if (probe == 0) {
4888 // first probe (interpolate)
4889 double data_bytes = right.page_end - left.page_start;
4890 bytes_per_sample = data_bytes / right.last_decoded_sample;
4891 offset = left.page_start + bytes_per_sample * (last_sample_limit - left.last_decoded_sample);
4892 } else {
4893 // second probe (try to bound the other side)
4894 double error = ((double) last_sample_limit - mid.last_decoded_sample) * bytes_per_sample;
4895 if (error >= 0 && error < 8000) error = 8000;
4896 if (error < 0 && error > -8000) error = -8000;
4897 offset += error * 2;
4898 }
4899
4900 // ensure the offset is valid
4901 if (offset < left.page_end)
4902 offset = left.page_end;
4903 if (offset > right.page_start - 65536)
4904 offset = right.page_start - 65536;
4905
4906 set_file_offset(f, (unsigned int) offset);
4907 } else {
4908 // binary search for large ranges (offset by 32K to ensure
4909 // we don't hit the right page)
4910 set_file_offset(f, left.page_end + (delta / 2) - 32768);
4911 }
4912
4913 if (!vorbis_find_page(f, NULL, NULL)) goto error;
4914 }
4915
4916 for (;;) {
4917 if (!get_seek_page_info(f, &mid)) goto error;
4918 if (mid.last_decoded_sample != ~0U) break;
4919 // (untested) no frames end on this page
4920 set_file_offset(f, mid.page_end);
4921 assert(mid.page_start < right.page_start);
4922 }
4923
4924 // if we've just found the last page again then we're in a tricky file,
4925 // and we're close enough (if it wasn't an interpolation probe).
4926 if (mid.page_start == right.page_start) {
4927 if (probe >= 2 || delta <= 65536)
4928 break;
4929 } else {
4930 if (last_sample_limit < mid.last_decoded_sample)
4931 right = mid;
4932 else
4933 left = mid;
4934 }
4935
4936 ++probe;
4937 }
4938
4939 // seek back to start of the last packet
4940 page_start = left.page_start;
4941 set_file_offset(f, page_start);
4942 if (!start_page(f)) return error(f, VORBIS_seek_failed);
4943 end_pos = f->end_seg_with_known_loc;
4944 assert(end_pos >= 0);
4945
4946 for (;;) {
4947 for (i = end_pos; i > 0; --i)
4948 if (f->segments[i-1] != 255)
4949 break;
4950
4951 start_seg_with_known_loc = i;
4952
4953 if (start_seg_with_known_loc > 0 || !(f->page_flag & PAGEFLAG_continued_packet))
4954 break;
4955
4956 // (untested) the final packet begins on an earlier page
4957 if (!go_to_page_before(f, page_start))
4958 goto error;
4959
4960 page_start = stb_vorbis_get_file_offset(f);
4961 if (!start_page(f)) goto error;
4962 end_pos = f->segment_count - 1;
4963 }
4964
4965 // prepare to start decoding
4966 f->current_loc_valid = FALSE;
4967 f->last_seg = FALSE;
4968 f->valid_bits = 0;
4969 f->packet_bytes = 0;
4970 f->bytes_in_seg = 0;
4971 f->previous_length = 0;
4972 f->next_seg = start_seg_with_known_loc;
4973
4974 for (i = 0; i < start_seg_with_known_loc; i++)
4975 skip(f, f->segments[i]);
4976
4977 // start decoding (optimizable - this frame is generally discarded)
4978 if (!vorbis_pump_first_frame(f))
4979 return 0;
4980 if (f->current_loc > sample_number)
4981 return error(f, VORBIS_seek_failed);
4982 return 1;
4983
4984 error:
4985 // try to restore the file to a valid state
4986 stb_vorbis_seek_start(f);
4987 return error(f, VORBIS_seek_failed);
4988 }
4989
4990 // the same as vorbis_decode_initial, but without advancing
4991 static int peek_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode)
4992 {
4993 int bits_read, bytes_read;
4994
4995 if (!vorbis_decode_initial(f, p_left_start, p_left_end, p_right_start, p_right_end, mode))
4996 return 0;
4997
4998 // either 1 or 2 bytes were read, figure out which so we can rewind
4999 bits_read = 1 + ilog(f->mode_count-1);
5000 if (f->mode_config[*mode].blockflag)
5001 bits_read += 2;
5002 bytes_read = (bits_read + 7) / 8;
5003
5004 f->bytes_in_seg += bytes_read;
5005 f->packet_bytes -= bytes_read;
5006 skip(f, -bytes_read);
5007 if (f->next_seg == -1)
5008 f->next_seg = f->segment_count - 1;
5009 else
5010 f->next_seg--;
5011 f->valid_bits = 0;
5012
5013 return 1;
5014 }
5015
5016 int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number)
5017 {
5018 uint32 max_frame_samples;
5019
5020 if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);
5021
5022 // fast page-level search
5023 if (!seek_to_sample_coarse(f, sample_number))
5024 return 0;
5025
5026 assert(f->current_loc_valid);
5027 assert(f->current_loc <= sample_number);
5028
5029 // linear search for the relevant packet
5030 max_frame_samples = (f->blocksize_1*3 - f->blocksize_0) >> 2;
5031 while (f->current_loc < sample_number) {
5032 int left_start, left_end, right_start, right_end, mode, frame_samples;
5033 if (!peek_decode_initial(f, &left_start, &left_end, &right_start, &right_end, &mode))
5034 return error(f, VORBIS_seek_failed);
5035 // calculate the number of samples returned by the next frame
5036 frame_samples = right_start - left_start;
5037 if (f->current_loc + frame_samples > sample_number) {
5038 return 1; // the next frame will contain the sample
5039 } else if (f->current_loc + frame_samples + max_frame_samples > sample_number) {
5040 // there's a chance the frame after this could contain the sample
5041 vorbis_pump_first_frame(f);
5042 } else {
5043 // this frame is too early to be relevant
5044 f->current_loc += frame_samples;
5045 f->previous_length = 0;
5046 maybe_start_packet(f);
5047 flush_packet(f);
5048 }
5049 }
5050 // the next frame should start with the sample
5051 if (f->current_loc != sample_number) return error(f, VORBIS_seek_failed);
5052 f->current_playback_loc = sample_number;
5053 return 1;
5054 }
5055
5056 int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number)
5057 {
5058 if (!stb_vorbis_seek_frame(f, sample_number)) {
5059 f->current_playback_loc_valid = FALSE;
5060 return 0;
5061 }
5062
5063 if (sample_number != f->current_loc) {
5064 int n;
5065 uint32 frame_start = f->current_loc;
5066 stb_vorbis_get_frame_float(f, &n, NULL);
5067 assert(sample_number > frame_start);
5068 assert(f->channel_buffer_start + (int) (sample_number-frame_start) <= f->channel_buffer_end);
5069 f->channel_buffer_start += (sample_number - frame_start);
5070 }
5071
5072 f->current_playback_loc_valid = TRUE;
5073 f->current_playback_loc = sample_number;
5074
5075 return 1;
5076 }
5077
5078 int stb_vorbis_seek_start(stb_vorbis *f)
5079 {
5080 if (IS_PUSH_MODE(f)) { return error(f, VORBIS_invalid_api_mixing); }
5081 set_file_offset(f, f->first_audio_page_offset);
5082 f->previous_length = 0;
5083 f->first_decode = TRUE;
5084 f->next_seg = -1;
5085 return vorbis_pump_first_frame(f);
5086 }
5087
5088 unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
5089 {
5090 unsigned int restore_offset, previous_safe;
5091 unsigned int last_page_loc;
5092
5093 if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);
5094 if (!f->total_samples) {
5095 uint32 end,last;
5096 uint32 lo,hi;
5097 char header[6];
5098
5099 // first, store the current decode position so we can restore it
5100 restore_offset = stb_vorbis_get_file_offset(f);
5101
5102 // now we want to seek back 64K from the end (the last page must
5103 // be at most a little less than 64K, but let's allow a little slop)
5104 if (f->stream_len >= 65536 && f->stream_len-65536 >= f->first_audio_page_offset)
5105 previous_safe = f->stream_len - 65536;
5106 else
5107 previous_safe = f->first_audio_page_offset;
5108
5109 set_file_offset(f, previous_safe);
5110 // previous_safe is now our candidate 'earliest known place that seeking
5111 // to will lead to the final page'
5112
5113 if (!vorbis_find_page(f, &end, &last)) {
5114 // if we can't find a page, we're hosed!
5115 f->error = VORBIS_cant_find_last_page;
5116 f->total_samples = 0xffffffff;
5117 goto done;
5118 }
5119
5120 // check if there are more pages
5121 last_page_loc = stb_vorbis_get_file_offset(f);
5122
5123 // stop when the last_page flag is set, not when we reach eof;
5124 // this allows us to stop short of a 'file_section' end without
5125 // explicitly checking the length of the section
5126 while (!last) {
5127 set_file_offset(f, end);
5128 if (!vorbis_find_page(f, &end, &last)) {
5129 // the last page we found didn't have the 'last page' flag
5130 // set. whoops!
5131 break;
5132 }
5133 //previous_safe = last_page_loc+1; // NOTE: not used after this point, but note for debugging
5134 last_page_loc = stb_vorbis_get_file_offset(f);
5135 }
5136
5137 set_file_offset(f, last_page_loc);
5138
5139 // parse the header
5140 getn(f, (unsigned char *)header, 6);
5141 // extract the absolute granule position
5142 lo = get32(f);
5143 hi = get32(f);
5144 if (lo == 0xffffffff && hi == 0xffffffff) {
5145 f->error = VORBIS_cant_find_last_page;
5146 f->total_samples = SAMPLE_unknown;
5147 goto done;
5148 }
5149 if (hi)
5150 lo = 0xfffffffe; // saturate
5151 f->total_samples = lo;
5152
5153 f->p_last.page_start = last_page_loc;
5154 f->p_last.page_end = end;
5155 f->p_last.last_decoded_sample = lo;
5156
5157 done:
5158 set_file_offset(f, restore_offset);
5159 }
5160 return f->total_samples == SAMPLE_unknown ? 0 : f->total_samples;
5161 }
5162
5163 float stb_vorbis_stream_length_in_seconds(stb_vorbis *f)
5164 {
5165 return stb_vorbis_stream_length_in_samples(f) / (float) f->sample_rate;
5166 }
5167
5168
5169
5170 int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output)
5171 {
5172 int len, right,left,i;
5173 if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);
5174
5175 if (!vorbis_decode_packet(f, &len, &left, &right)) {
5176 f->channel_buffer_start = f->channel_buffer_end = 0;
5177 return 0;
5178 }
5179
5180 len = vorbis_finish_frame(f, len, left, right);
5181 for (i=0; i < f->channels; ++i)
5182 f->outputs[i] = f->channel_buffers[i] + left;
5183
5184 f->channel_buffer_start = left;
5185 f->channel_buffer_end = left+len;
5186
5187 if (channels) *channels = f->channels;
5188 if (output) *output = f->outputs;
5189 return len;
5190 }
5191
5192 #ifndef STB_VORBIS_NO_STDIO
5193
5194 stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length)
5195 {
5196 stb_vorbis *f, p;
5197 vorbis_init(&p, alloc);
5198 p.f = file;
5199 p.f_start = (uint32) ftell(file);
5200 p.stream_len = length;
5201 p.close_on_free = close_on_free;
5202 if (start_decoder(&p)) {
5203 f = vorbis_alloc(&p);
5204 if (f) {
5205 *f = p;
5206 vorbis_pump_first_frame(f);
5207 return f;
5208 }
5209 }
5210 if (error) *error = p.error;
5211 vorbis_deinit(&p);
5212 return NULL;
5213 }
5214
5215 stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc)
5216 {
5217 unsigned int len, start;
5218 start = (unsigned int) ftell(file);
5219 fseek(file, 0, SEEK_END);
5220 len = (unsigned int) (ftell(file) - start);
5221 fseek(file, start, SEEK_SET);
5222 return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len);
5223 }
5224
5225 stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc)
5226 {
5227 FILE *f;
5228 #if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
5229 if (0 != fopen_s(&f, filename, "rb"))
5230 f = NULL;
5231 #else
5232 f = fopen(filename, "rb");
5233 #endif
5234 if (f)
5235 return stb_vorbis_open_file(f, TRUE, error, alloc);
5236 if (error) *error = VORBIS_file_open_failure;
5237 return NULL;
5238 }
5239 #endif // STB_VORBIS_NO_STDIO
5240
5241 #ifdef STB_VORBIS_SDL
5242 stb_vorbis * stb_vorbis_open_rwops_section(SDL_RWops *rwops, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length)
5243 {
5244 stb_vorbis *f, p;
5245 vorbis_init(&p, alloc);
5246 p.rwops = rwops;
5247 p.rwops_start = (uint32) SDL_RWtell(rwops);
5248 p.stream_len = length;
5249 p.close_on_free = close_on_free;
5250 if (start_decoder(&p)) {
5251 f = vorbis_alloc(&p);
5252 if (f) {
5253 memcpy(f, &p, sizeof (stb_vorbis));
5254 vorbis_pump_first_frame(f);
5255 return f;
5256 }
5257 }
5258 if (error) *error = p.error;
5259 vorbis_deinit(&p);
5260 return NULL;
5261 }
5262
5263 stb_vorbis * stb_vorbis_open_rwops(SDL_RWops *rwops, int close_on_free, int *error, const stb_vorbis_alloc *alloc)
5264 {
5265 const unsigned int start = (unsigned int) SDL_RWtell(rwops);
5266 const unsigned int len = (unsigned int) (SDL_RWsize(rwops) - start);
5267 return stb_vorbis_open_rwops_section(rwops, close_on_free, error, alloc, len);
5268 }
5269 #endif
5270
5271 stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc)
5272 {
5273 stb_vorbis *f, p;
5274 if (!data) {
5275 if (error) *error = VORBIS_unexpected_eof;
5276 return NULL;
5277 }
5278 vorbis_init(&p, alloc);
5279 p.stream = (uint8 *) data;
5280 p.stream_end = (uint8 *) data + len;
5281 p.stream_start = (uint8 *) p.stream;
5282 p.stream_len = len;
5283 p.push_mode = FALSE;
5284 if (start_decoder(&p)) {
5285 f = vorbis_alloc(&p);
5286 if (f) {
5287 memcpy(f, &p, sizeof (stb_vorbis));
5288 vorbis_pump_first_frame(f);
5289 if (error) *error = VORBIS__no_error;
5290 return f;
5291 }
5292 }
5293 if (error) *error = p.error;
5294 vorbis_deinit(&p);
5295 return NULL;
5296 }
5297
5298 #ifndef STB_VORBIS_NO_INTEGER_CONVERSION
5299 #define PLAYBACK_MONO 1
5300 #define PLAYBACK_LEFT 2
5301 #define PLAYBACK_RIGHT 4
5302
5303 #define L (PLAYBACK_LEFT | PLAYBACK_MONO)
5304 #define C (PLAYBACK_LEFT | PLAYBACK_RIGHT | PLAYBACK_MONO)
5305 #define R (PLAYBACK_RIGHT | PLAYBACK_MONO)
5306
5307 static int8 channel_position[7][6] =
5308 {
5309 { 0 },
5310 { C },
5311 { L, R },
5312 { L, C, R },
5313 { L, R, L, R },
5314 { L, C, R, L, R },
5315 { L, C, R, L, R, C },
5316 };
5317
5318
5319 #ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT
5320 typedef union {
5321 float f;
5322 // changed this to unsigned to suppress an UBSan error.
5323 // upstream: https://github.com/nothings/stb/issues/1168.
5324 unsigned int i;
5325 } float_conv;
5326 typedef char stb_vorbis_float_size_test[sizeof(float)==4 && sizeof(int) == 4];
5327 #define FASTDEF(x) float_conv x
5328 // add (1<<23) to convert to int, then divide by 2^SHIFT, then add 0.5/2^SHIFT to round
5329 #define MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT))
5330 #define ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22))
5331 #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) (int)(temp.f = (x) + MAGIC(s), temp.i - ADDEND(s))
5332 #define check_endianness()
5333 #else
5334 #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s))))
5335 #define check_endianness()
5336 #define FASTDEF(x)
5337 #endif
5338
5339 static void copy_samples(short *dest, float *src, int len)
5340 {
5341 int i;
5342 check_endianness();
5343 for (i=0; i < len; ++i) {
5344 FASTDEF(temp);
5345 int v = FAST_SCALED_FLOAT_TO_INT(temp, src[i],15);
5346 if ((unsigned int)v + 32768 > 65535)
5347 v = v < 0 ? -32768 : 32767;
5348 dest[i] = v;
5349 }
5350 }
5351
5352 static void compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len)
5353 {
5354 #define STB_BUFFER_SIZE 32
5355 float buffer[STB_BUFFER_SIZE];
5356 int i,j,o,n = STB_BUFFER_SIZE;
5357 check_endianness();
5358 for (o = 0; o < len; o += STB_BUFFER_SIZE) {
5359 memset(buffer, 0, sizeof(buffer));
5360 if (o + n > len) n = len - o;
5361 for (j=0; j < num_c; ++j) {
5362 if (channel_position[num_c][j] & mask) {
5363 for (i=0; i < n; ++i)
5364 buffer[i] += data[j][d_offset+o+i];
5365 }
5366 }
5367 for (i=0; i < n; ++i) {
5368 FASTDEF(temp);
5369 int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15);
5370 if ((unsigned int)v + 32768 > 65535)
5371 v = v < 0 ? -32768 : 32767;
5372 output[o+i] = v;
5373 }
5374 }
5375 #undef STB_BUFFER_SIZE
5376 }
5377
5378 static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len)
5379 {
5380 #define STB_BUFFER_SIZE 32
5381 float buffer[STB_BUFFER_SIZE];
5382 int i,j,o,n = STB_BUFFER_SIZE >> 1;
5383 // o is the offset in the source data
5384 check_endianness();
5385 for (o = 0; o < len; o += STB_BUFFER_SIZE >> 1) {
5386 // o2 is the offset in the output data
5387 int o2 = o << 1;
5388 memset(buffer, 0, sizeof(buffer));
5389 if (o + n > len) n = len - o;
5390 for (j=0; j < num_c; ++j) {
5391 int m = channel_position[num_c][j] & (PLAYBACK_LEFT | PLAYBACK_RIGHT);
5392 if (m == (PLAYBACK_LEFT | PLAYBACK_RIGHT)) {
5393 for (i=0; i < n; ++i) {
5394 buffer[i*2+0] += data[j][d_offset+o+i];
5395 buffer[i*2+1] += data[j][d_offset+o+i];
5396 }
5397 } else if (m == PLAYBACK_LEFT) {
5398 for (i=0; i < n; ++i) {
5399 buffer[i*2+0] += data[j][d_offset+o+i];
5400 }
5401 } else if (m == PLAYBACK_RIGHT) {
5402 for (i=0; i < n; ++i) {
5403 buffer[i*2+1] += data[j][d_offset+o+i];
5404 }
5405 }
5406 }
5407 for (i=0; i < (n<<1); ++i) {
5408 FASTDEF(temp);
5409 int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15);
5410 if ((unsigned int)v + 32768 > 65535)
5411 v = v < 0 ? -32768 : 32767;
5412 output[o2+i] = v;
5413 }
5414 }
5415 #undef STB_BUFFER_SIZE
5416 }
5417
5418 static void convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples)
5419 {
5420 int i;
5421 if (buf_c != data_c && buf_c <= 2 && data_c <= 6) {
5422 static int channel_selector[3][2] = { {0}, {PLAYBACK_MONO}, {PLAYBACK_LEFT, PLAYBACK_RIGHT} };
5423 for (i=0; i < buf_c; ++i)
5424 compute_samples(channel_selector[buf_c][i], buffer[i]+b_offset, data_c, data, d_offset, samples);
5425 } else {
5426 int limit = buf_c < data_c ? buf_c : data_c;
5427 for (i=0; i < limit; ++i)
5428 copy_samples(buffer[i]+b_offset, data[i]+d_offset, samples);
5429 for ( ; i < buf_c; ++i)
5430 memset(buffer[i]+b_offset, 0, sizeof(short) * samples);
5431 }
5432 }
5433
5434 int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples)
5435 {
5436 float **output = NULL;
5437 int len = stb_vorbis_get_frame_float(f, NULL, &output);
5438 if (len > num_samples) len = num_samples;
5439 if (len)
5440 convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len);
5441 return len;
5442 }
5443
5444 static void convert_channels_short_interleaved(int buf_c, short *buffer, int data_c, float **data, int d_offset, int len)
5445 {
5446 int i;
5447 check_endianness();
5448 if (buf_c != data_c && buf_c <= 2 && data_c <= 6) {
5449 assert(buf_c == 2);
5450 for (i=0; i < buf_c; ++i)
5451 compute_stereo_samples(buffer, data_c, data, d_offset, len);
5452 } else {
5453 int limit = buf_c < data_c ? buf_c : data_c;
5454 int j;
5455 for (j=0; j < len; ++j) {
5456 for (i=0; i < limit; ++i) {
5457 FASTDEF(temp);
5458 float f = data[i][d_offset+j];
5459 int v = FAST_SCALED_FLOAT_TO_INT(temp, f,15);//data[i][d_offset+j],15);
5460 if ((unsigned int)v + 32768 > 65535)
5461 v = v < 0 ? -32768 : 32767;
5462 *buffer++ = v;
5463 }
5464 for ( ; i < buf_c; ++i)
5465 *buffer++ = 0;
5466 }
5467 }
5468 }
5469
5470 int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts)
5471 {
5472 float **output;
5473 int len;
5474 if (num_c == 1) return stb_vorbis_get_frame_short(f,num_c,&buffer, num_shorts);
5475 len = stb_vorbis_get_frame_float(f, NULL, &output);
5476 if (len) {
5477 if (len*num_c > num_shorts) len = num_shorts / num_c;
5478 convert_channels_short_interleaved(num_c, buffer, f->channels, output, 0, len);
5479 }
5480 return len;
5481 }
5482
5483 int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts)
5484 {
5485 float **outputs;
5486 int len = num_shorts / channels;
5487 int n=0;
5488 while (n < len) {
5489 int k = f->channel_buffer_end - f->channel_buffer_start;
5490 if (n+k >= len) k = len - n;
5491 if (k)
5492 convert_channels_short_interleaved(channels, buffer, f->channels, f->channel_buffers, f->channel_buffer_start, k);
5493 buffer += k*channels;
5494 n += k;
5495 f->channel_buffer_start += k;
5496 if (n == len) break;
5497 if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
5498 }
5499 f->current_playback_loc += n;
5500 return n;
5501 }
5502
5503 int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int len)
5504 {
5505 float **outputs;
5506 int n=0;
5507 while (n < len) {
5508 int k = f->channel_buffer_end - f->channel_buffer_start;
5509 if (n+k >= len) k = len - n;
5510 if (k)
5511 convert_samples_short(channels, buffer, n, f->channels, f->channel_buffers, f->channel_buffer_start, k);
5512 n += k;
5513 f->channel_buffer_start += k;
5514 if (n == len) break;
5515 if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
5516 }
5517 f->current_playback_loc += n;
5518 return n;
5519 }
5520
5521 #ifndef STB_VORBIS_NO_STDIO
5522 int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output)
5523 {
5524 int data_len, offset, total, limit, error;
5525 short *data;
5526 stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL);
5527 if (v == NULL) return -1;
5528 limit = v->channels * 4096;
5529 *channels = v->channels;
5530 if (sample_rate)
5531 *sample_rate = v->sample_rate;
5532 offset = data_len = 0;
5533 total = limit;
5534 data = (short *) malloc(total * sizeof(*data));
5535 if (data == NULL) {
5536 stb_vorbis_close(v);
5537 return -2;
5538 }
5539 for (;;) {
5540 int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset);
5541 if (n == 0) break;
5542 data_len += n;
5543 offset += n * v->channels;
5544 if (offset + limit > total) {
5545 short *data2;
5546 total *= 2;
5547 data2 = (short *) realloc(data, total * sizeof(*data));
5548 if (data2 == NULL) {
5549 free(data);
5550 stb_vorbis_close(v);
5551 return -2;
5552 }
5553 data = data2;
5554 }
5555 }
5556 *output = data;
5557 stb_vorbis_close(v);
5558 return data_len;
5559 }
5560 #endif // NO_STDIO
5561
5562 int stb_vorbis_decode_memory(const uint8 *mem, int len, int *channels, int *sample_rate, short **output)
5563 {
5564 int data_len, offset, total, limit, error;
5565 short *data;
5566 stb_vorbis *v = stb_vorbis_open_memory(mem, len, &error, NULL);
5567 if (v == NULL) return -1;
5568 limit = v->channels * 4096;
5569 *channels = v->channels;
5570 if (sample_rate)
5571 *sample_rate = v->sample_rate;
5572 offset = data_len = 0;
5573 total = limit;
5574 data = (short *) malloc(total * sizeof(*data));
5575 if (data == NULL) {
5576 stb_vorbis_close(v);
5577 return -2;
5578 }
5579 for (;;) {
5580 int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset);
5581 if (n == 0) break;
5582 data_len += n;
5583 offset += n * v->channels;
5584 if (offset + limit > total) {
5585 short *data2;
5586 total *= 2;
5587 data2 = (short *) realloc(data, total * sizeof(*data));
5588 if (data2 == NULL) {
5589 free(data);
5590 stb_vorbis_close(v);
5591 return -2;
5592 }
5593 data = data2;
5594 }
5595 }
5596 *output = data;
5597 stb_vorbis_close(v);
5598 return data_len;
5599 }
5600 #endif // STB_VORBIS_NO_INTEGER_CONVERSION
5601
5602 int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats)
5603 {
5604 float **outputs;
5605 int len = num_floats / channels;
5606 int n=0;
5607 int z = f->channels;
5608 if (z > channels) z = channels;
5609 while (n < len) {
5610 int i,j;
5611 int k = f->channel_buffer_end - f->channel_buffer_start;
5612 if (n+k >= len) k = len - n;
5613 for (j=0; j < k; ++j) {
5614 for (i=0; i < z; ++i)
5615 *buffer++ = f->channel_buffers[i][f->channel_buffer_start+j];
5616 for ( ; i < channels; ++i)
5617 *buffer++ = 0;
5618 }
5619 n += k;
5620 f->channel_buffer_start += k;
5621 if (n == len)
5622 break;
5623 if (!stb_vorbis_get_frame_float(f, NULL, &outputs))
5624 break;
5625 }
5626 f->current_playback_loc += n;
5627 return n;
5628 }
5629
5630 int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples)
5631 {
5632 float **outputs;
5633 int n=0;
5634 int z = f->channels;
5635 if (z > channels) z = channels;
5636 while (n < num_samples) {
5637 int i;
5638 int k = f->channel_buffer_end - f->channel_buffer_start;
5639 if (n+k >= num_samples) k = num_samples - n;
5640 if (k) {
5641 for (i=0; i < z; ++i)
5642 memcpy(buffer[i]+n, f->channel_buffers[i]+f->channel_buffer_start, sizeof(float)*k);
5643 for ( ; i < channels; ++i)
5644 memset(buffer[i]+n, 0, sizeof(float) * k);
5645 }
5646 n += k;
5647 f->channel_buffer_start += k;
5648 if (n == num_samples)
5649 break;
5650 if (!stb_vorbis_get_frame_float(f, NULL, &outputs))
5651 break;
5652 }
5653 f->current_playback_loc += n;
5654 return n;
5655 }
5656 #endif // STB_VORBIS_NO_PULLDATA_API
5657
5658 /* Version history
5659 1.17 - 2019-07-08 - fix CVE-2019-13217, -13218, -13219, -13220, -13221, -13222, -13223
5660 found with Mayhem by ForAllSecure
5661 1.16 - 2019-03-04 - fix warnings
5662 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
5663 1.14 - 2018-02-11 - delete bogus dealloca usage
5664 1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
5665 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
5666 1.11 - 2017-07-23 - fix MinGW compilation
5667 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory
5668 1.09 - 2016-04-04 - back out 'avoid discarding last frame' fix from previous version
5669 1.08 - 2016-04-02 - fixed multiple warnings; fix setup memory leaks;
5670 avoid discarding last frame of audio data
5671 1.07 - 2015-01-16 - fixed some warnings, fix mingw, const-correct API
5672 some more crash fixes when out of memory or with corrupt files
5673 1.06 - 2015-08-31 - full, correct support for seeking API (Dougall Johnson)
5674 some crash fixes when out of memory or with corrupt files
5675 1.05 - 2015-04-19 - don't define __forceinline if it's redundant
5676 1.04 - 2014-08-27 - fix missing const-correct case in API
5677 1.03 - 2014-08-07 - Warning fixes
5678 1.02 - 2014-07-09 - Declare qsort compare function _cdecl on windows
5679 1.01 - 2014-06-18 - fix stb_vorbis_get_samples_float
5680 1.0 - 2014-05-26 - fix memory leaks; fix warnings; fix bugs in multichannel
5681 (API change) report sample rate for decode-full-file funcs
5682 0.99996 - bracket #include <malloc.h> for macintosh compilation by Laurent Gomila
5683 0.99995 - use union instead of pointer-cast for fast-float-to-int to avoid alias-optimization problem
5684 0.99994 - change fast-float-to-int to work in single-precision FPU mode, remove endian-dependence
5685 0.99993 - remove assert that fired on legal files with empty tables
5686 0.99992 - rewind-to-start
5687 0.99991 - bugfix to stb_vorbis_get_samples_short by Bernhard Wodo
5688 0.9999 - (should have been 0.99990) fix no-CRT support, compiling as C++
5689 0.9998 - add a full-decode function with a memory source
5690 0.9997 - fix a bug in the read-from-FILE case in 0.9996 addition
5691 0.9996 - query length of vorbis stream in samples/seconds
5692 0.9995 - bugfix to another optimization that only happened in certain files
5693 0.9994 - bugfix to one of the optimizations that caused significant (but inaudible?) errors
5694 0.9993 - performance improvements; runs in 99% to 104% of time of reference implementation
5695 0.9992 - performance improvement of IMDCT; now performs close to reference implementation
5696 0.9991 - performance improvement of IMDCT
5697 0.999 - (should have been 0.9990) performance improvement of IMDCT
5698 0.998 - no-CRT support from Casey Muratori
5699 0.997 - bugfixes for bugs found by Terje Mathisen
5700 0.996 - bugfix: fast-huffman decode initialized incorrectly for sparse codebooks; fixing gives 10% speedup - found by Terje Mathisen
5701 0.995 - bugfix: fix to 'effective' overrun detection - found by Terje Mathisen
5702 0.994 - bugfix: garbage decode on final VQ symbol of a non-multiple - found by Terje Mathisen
5703 0.993 - bugfix: pushdata API required 1 extra byte for empty page (failed to consume final page if empty) - found by Terje Mathisen
5704 0.992 - fixes for MinGW warning
5705 0.991 - turn fast-float-conversion on by default
5706 0.990 - fix push-mode seek recovery if you seek into the headers
5707 0.98b - fix to bad release of 0.98
5708 0.98 - fix push-mode seek recovery; robustify float-to-int and support non-fast mode
5709 0.97 - builds under c++ (typecasting, don't use 'class' keyword)
5710 0.96 - somehow MY 0.95 was right, but the web one was wrong, so here's my 0.95 rereleased as 0.96, fixes a typo in the clamping code
5711 0.95 - clamping code for 16-bit functions
5712 0.94 - not publically released
5713 0.93 - fixed all-zero-floor case (was decoding garbage)
5714 0.92 - fixed a memory leak
5715 0.91 - conditional compiles to omit parts of the API and the infrastructure to support them: STB_VORBIS_NO_PULLDATA_API, STB_VORBIS_NO_PUSHDATA_API, STB_VORBIS_NO_STDIO, STB_VORBIS_NO_INTEGER_CONVERSION
5716 0.90 - first public release
5717 */
5718
5719 #endif // STB_VORBIS_HEADER_ONLY
5720
5721
5722 /*
5723 ------------------------------------------------------------------------------
5724 This software is available under 2 licenses -- choose whichever you prefer.
5725 ------------------------------------------------------------------------------
5726 ALTERNATIVE A - MIT License
5727 Copyright (c) 2017 Sean Barrett
5728 Permission is hereby granted, free of charge, to any person obtaining a copy of
5729 this software and associated documentation files (the "Software"), to deal in
5730 the Software without restriction, including without limitation the rights to
5731 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5732 of the Software, and to permit persons to whom the Software is furnished to do
5733 so, subject to the following conditions:
5734 The above copyright notice and this permission notice shall be included in all
5735 copies or substantial portions of the Software.
5736 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5737 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5738 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5739 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5740 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5741 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5742 SOFTWARE.
5743 ------------------------------------------------------------------------------
5744 ALTERNATIVE B - Public Domain (www.unlicense.org)
5745 This is free and unencumbered software released into the public domain.
5746 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
5747 software, either in source code form or as a compiled binary, for any purpose,
5748 commercial or non-commercial, and by any means.
5749 In jurisdictions that recognize copyright laws, the author or authors of this
5750 software dedicate any and all copyright interest in the software to the public
5751 domain. We make this dedication for the benefit of the public at large and to
5752 the detriment of our heirs and successors. We intend this dedication to be an
5753 overt act of relinquishment in perpetuity of all present and future rights to
5754 this software under copyright law.
5755 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5756 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5757 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5758 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5759 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5760 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5761 ------------------------------------------------------------------------------
5762 */
1010 #ifndef TIMIDITY_TABLES_H
1111 #define TIMIDITY_TABLES_H
1212
13 #if defined(HAVE_LIBC) && defined(__WATCOMC__) /* Watcom has issues... */
14 #define SDL_sin sin
15 #endif
1613 #define timi_sine(x) (SDL_sin((2*PI/1024.0) * (x)))
1714
1815 #define SINE_CYCLE_LENGTH 1024
109109 static const char **chunk_decoders = NULL;
110110 static int num_decoders = 0;
111111
112 static SDL_atomic_t master_volume = { MIX_MAX_VOLUME };
112113
113114 int Mix_GetNumChunkDecoders(void)
114115 {
162163 return(&linked_version);
163164 }
164165
166 /*
167 * Returns a bitmap of already loaded modules (MIX_INIT_* flags).
168 *
169 * Note that functions other than Mix_Init() may cause a module to get loaded
170 * (hence the looping over the interfaces instead of maintaining a set of flags
171 * just in Mix_Init() and Mix_Quit()).
172 */
173 static int get_loaded_mix_init_flags(void)
174 {
175 int i;
176 int loaded_init_flags = 0;
177
178 for (i = 0; i < get_num_music_interfaces(); ++i) {
179 Mix_MusicInterface *interface;
180
181 interface = get_music_interface(i);
182 if (interface->loaded) {
183 switch (interface->type) {
184 case MUS_FLAC:
185 loaded_init_flags |= MIX_INIT_FLAC;
186 break;
187 case MUS_MOD:
188 loaded_init_flags |= MIX_INIT_MOD;
189 break;
190 case MUS_MP3:
191 loaded_init_flags |= MIX_INIT_MP3;
192 break;
193 case MUS_OGG:
194 loaded_init_flags |= MIX_INIT_OGG;
195 break;
196 case MUS_MID:
197 loaded_init_flags |= MIX_INIT_MID;
198 break;
199 case MUS_OPUS:
200 loaded_init_flags |= MIX_INIT_OPUS;
201 break;
202 default:
203 break;
204 }
205 }
206 }
207
208 return loaded_init_flags;
209 }
210
165211 int Mix_Init(int flags)
166212 {
167213 int result = 0;
214 int already_loaded = get_loaded_mix_init_flags();
168215
169216 if (flags & MIX_INIT_FLAC) {
170217 if (load_music_type(MUS_FLAC)) {
214261 Mix_SetError("MIDI support not available");
215262 }
216263 }
264 result |= already_loaded;
265
217266 return result;
218267 }
219268
276325 mix_channels(void *udata, Uint8 *stream, int len)
277326 {
278327 Uint8 *mix_input;
279 int i, mixable, volume = MIX_MAX_VOLUME;
328 int i, mixable, volume, master_vol;
280329 Uint32 sdl_ticks;
281330
282331 (void)udata;
283332
284 #if SDL_VERSION_ATLEAST(1, 3, 0)
285333 /* Need to initialize the stream in SDL 1.3+ */
286334 SDL_memset(stream, mixer.silence, (size_t)len);
287 #endif
288335
289336 /* Mix the music (must be done before the channels are added) */
290337 mix_music(music_data, stream, len);
338
339 volume = Mix_MasterVolume(-1);
340 master_vol = volume;
291341
292342 /* Mix any playing channels... */
293343 sdl_ticks = SDL_GetTicks();
325375 int remaining = len;
326376 while (mix_channel[i].playing > 0 && index < len) {
327377 remaining = len - index;
328 volume = (mix_channel[i].volume*mix_channel[i].chunk->volume) / MIX_MAX_VOLUME;
378 volume = (master_vol * (mix_channel[i].volume * mix_channel[i].chunk->volume)) / (MIX_MAX_VOLUME * MIX_MAX_VOLUME);
329379 mixable = mix_channel[i].playing;
330380 if (mixable > remaining) {
331381 mixable = remaining;
10021052
10031053 /* Queue up the audio data for this channel */
10041054 if (which >= 0 && which < num_channels) {
1005 Uint32 sdl_ticks = SDL_GetTicks();
1055 Uint32 sdl_ticks = SDL_GetTicks();
10061056 mix_channel[which].samples = chunk->abuf;
10071057 mix_channel[which].playing = (int)chunk->alen;
10081058 mix_channel[which].looping = loops;
10731123
10741124 /* Queue up the audio data for this channel */
10751125 if (which >= 0 && which < num_channels) {
1076 Uint32 sdl_ticks = SDL_GetTicks();
1126 Uint32 sdl_ticks = SDL_GetTicks();
10771127 mix_channel[which].samples = chunk->abuf;
10781128 mix_channel[which].playing = (int)chunk->alen;
10791129 mix_channel[which].looping = loops;
16391689 SDL_UnlockAudioDevice(audio_device);
16401690 }
16411691
1692 int Mix_MasterVolume(int volume)
1693 {
1694 int prev_volume = SDL_AtomicGet(&master_volume);
1695 if (volume < 0) {
1696 return prev_volume;
1697 }
1698 if (volume > SDL_MIX_MAXVOLUME) {
1699 volume = SDL_MIX_MAXVOLUME;
1700 }
1701 SDL_AtomicSet(&master_volume, volume);
1702 return(prev_volume);
1703 }
1704
16421705 /* end of mixer.c ... */
16431706
16441707 /* vi: set ts=4 sw=4 expandtab: */
3535 #include "music_timidity.h"
3636 #include "music_ogg.h"
3737 #include "music_opus.h"
38 #include "music_drmp3.h"
3839 #include "music_mpg123.h"
3940 #include "music_mad.h"
41 #include "music_drflac.h"
4042 #include "music_flac.h"
4143 #include "native_midi/native_midi.h"
4244
162164 #ifdef MUSIC_WAV
163165 &Mix_MusicInterface_WAV,
164166 #endif
165 #ifdef MUSIC_FLAC
167 #ifdef MUSIC_FLAC_DRFLAC
168 &Mix_MusicInterface_DRFLAC,
169 #endif
170 #ifdef MUSIC_FLAC_LIBFLAC
166171 &Mix_MusicInterface_FLAC,
167172 #endif
168173 #ifdef MUSIC_OGG
170175 #endif
171176 #ifdef MUSIC_OPUS
172177 &Mix_MusicInterface_Opus,
178 #endif
179 #ifdef MUSIC_MP3_DRMP3
180 &Mix_MusicInterface_DRMP3,
173181 #endif
174182 #ifdef MUSIC_MP3_MPG123
175183 &Mix_MusicInterface_MPG123,
315323 /* Handle fading */
316324 if (music_playing->fading != MIX_NO_FADING) {
317325 if (music_playing->fade_step++ < music_playing->fade_steps) {
318 int volume;
326 int volume = Mix_MasterVolume(-1);
319327 int fade_step = music_playing->fade_step;
320328 int fade_steps = music_playing->fade_steps;
321329
322330 if (music_playing->fading == MIX_FADING_OUT) {
323 volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
331 volume = (volume * (music_volume * (fade_steps-fade_step))) / (fade_steps * MIX_MAX_VOLUME);
324332 } else { /* Fading in */
325 volume = (music_volume * fade_step) / fade_steps;
333 volume = (volume * (music_volume * fade_step)) / (fade_steps * MIX_MAX_VOLUME);
326334 }
327335 music_internal_volume(volume);
328336 } else {
816824 {
817825 int retval = 0;
818826
819 #if defined(__MACOSX__) && defined(MID_MUSIC_NATIVE)
820 /* This fixes a bug with native MIDI on Mac OS X, where you
821 can't really stop and restart MIDI from the audio callback.
822 */
823 if (music == music_playing && music->api == MIX_MUSIC_NATIVEMIDI) {
824 /* Just a seek suffices to restart playing */
825 music_internal_position(position);
826 return 0;
827 }
828 #endif
829
830827 /* Note the music we're playing */
831828 if (music_playing) {
832829 music_internal_halt();
882879 music->fading = MIX_NO_FADING;
883880 }
884881 music->fade_step = 0;
885 music->fade_steps = ms/ms_per_step;
882 music->fade_steps = (ms + ms_per_step - 1) / ms_per_step;
886883
887884 /* Play the puppy */
888885 Mix_LockAudio();
3434 MIX_MUSIC_TIMIDITY,
3535 MIX_MUSIC_NATIVEMIDI,
3636 MIX_MUSIC_OGG,
37 MIX_MUSIC_DRMP3,
3738 MIX_MUSIC_MPG123,
3839 MIX_MUSIC_MAD,
40 MIX_MUSIC_DRFLAC,
3941 MIX_MUSIC_FLAC,
4042 MIX_MUSIC_OPUS,
4143 MIX_MUSIC_LIBXMP,