gosu 0.15.2 → 1.1.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +138 -0
  3. data/dependencies/SDL/include/SDL_assert.h +293 -0
  4. data/dependencies/SDL/include/SDL_atomic.h +295 -0
  5. data/dependencies/SDL/include/SDL_audio.h +859 -0
  6. data/dependencies/SDL/include/SDL_bits.h +121 -0
  7. data/dependencies/SDL/include/SDL_blendmode.h +123 -0
  8. data/dependencies/SDL/include/SDL_clipboard.h +71 -0
  9. data/dependencies/SDL/include/SDL_config.h +55 -0
  10. data/dependencies/SDL/include/SDL_config_android.h +182 -0
  11. data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
  12. data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
  13. data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
  14. data/dependencies/SDL/include/SDL_config_os2.h +188 -0
  15. data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
  16. data/dependencies/SDL/include/SDL_config_psp.h +165 -0
  17. data/dependencies/SDL/include/SDL_config_windows.h +288 -0
  18. data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
  19. data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
  20. data/dependencies/SDL/include/SDL_copying.h +20 -0
  21. data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
  22. data/dependencies/SDL/include/SDL_egl.h +1676 -0
  23. data/dependencies/SDL/include/SDL_endian.h +263 -0
  24. data/dependencies/SDL/include/SDL_error.h +112 -0
  25. data/dependencies/SDL/include/SDL_events.h +827 -0
  26. data/dependencies/SDL/include/SDL_filesystem.h +136 -0
  27. data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
  28. data/dependencies/SDL/include/SDL_gesture.h +87 -0
  29. data/dependencies/SDL/include/SDL_haptic.h +1247 -0
  30. data/dependencies/SDL/include/SDL_hints.h +1578 -0
  31. data/dependencies/SDL/include/SDL_joystick.h +499 -0
  32. data/dependencies/SDL/include/SDL_keyboard.h +217 -0
  33. data/dependencies/SDL/include/SDL_keycode.h +351 -0
  34. data/dependencies/SDL/include/SDL_loadso.h +81 -0
  35. data/dependencies/SDL/include/SDL_locale.h +101 -0
  36. data/dependencies/SDL/include/SDL_log.h +211 -0
  37. data/dependencies/SDL/include/SDL_main.h +180 -0
  38. data/dependencies/SDL/include/SDL_messagebox.h +146 -0
  39. data/dependencies/SDL/include/SDL_metal.h +117 -0
  40. data/dependencies/SDL/include/SDL_misc.h +75 -0
  41. data/dependencies/SDL/include/SDL_mouse.h +302 -0
  42. data/dependencies/SDL/include/SDL_mutex.h +251 -0
  43. data/dependencies/SDL/include/SDL_name.h +33 -0
  44. data/dependencies/SDL/include/SDL_opengl.h +2183 -0
  45. data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
  46. data/dependencies/SDL/include/SDL_opengles.h +39 -0
  47. data/dependencies/SDL/include/SDL_opengles2.h +52 -0
  48. data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
  49. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
  50. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
  51. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
  52. data/dependencies/SDL/include/SDL_pixels.h +479 -0
  53. data/dependencies/SDL/include/SDL_platform.h +198 -0
  54. data/dependencies/SDL/include/SDL_power.h +75 -0
  55. data/dependencies/SDL/include/SDL_quit.h +58 -0
  56. data/dependencies/SDL/include/SDL_rect.h +174 -0
  57. data/dependencies/SDL/include/SDL_render.h +1158 -0
  58. data/dependencies/SDL/include/SDL_revision.h +2 -0
  59. data/dependencies/SDL/include/SDL_rwops.h +283 -0
  60. data/dependencies/SDL/include/SDL_scancode.h +413 -0
  61. data/dependencies/SDL/include/SDL_sensor.h +267 -0
  62. data/dependencies/SDL/include/SDL_shape.h +144 -0
  63. data/dependencies/SDL/include/SDL_stdinc.h +647 -0
  64. data/dependencies/SDL/include/SDL_surface.h +563 -0
  65. data/dependencies/SDL/include/SDL_system.h +325 -0
  66. data/dependencies/SDL/include/SDL_syswm.h +354 -0
  67. data/dependencies/SDL/include/SDL_test.h +69 -0
  68. data/dependencies/SDL/include/SDL_test_assert.h +105 -0
  69. data/dependencies/SDL/include/SDL_test_common.h +218 -0
  70. data/dependencies/SDL/include/SDL_test_compare.h +69 -0
  71. data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
  72. data/dependencies/SDL/include/SDL_test_font.h +81 -0
  73. data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
  74. data/dependencies/SDL/include/SDL_test_harness.h +134 -0
  75. data/dependencies/SDL/include/SDL_test_images.h +78 -0
  76. data/dependencies/SDL/include/SDL_test_log.h +67 -0
  77. data/dependencies/SDL/include/SDL_test_md5.h +129 -0
  78. data/dependencies/SDL/include/SDL_test_memory.h +63 -0
  79. data/dependencies/SDL/include/SDL_test_random.h +115 -0
  80. data/dependencies/SDL/include/SDL_thread.h +366 -0
  81. data/dependencies/SDL/include/SDL_timer.h +115 -0
  82. data/dependencies/SDL/include/SDL_touch.h +102 -0
  83. data/dependencies/SDL/include/SDL_types.h +29 -0
  84. data/dependencies/SDL/include/SDL_version.h +162 -0
  85. data/dependencies/SDL/include/SDL_video.h +1282 -0
  86. data/dependencies/SDL/include/SDL_vulkan.h +276 -0
  87. data/dependencies/SDL/include/begin_code.h +166 -0
  88. data/dependencies/SDL/include/close_code.h +40 -0
  89. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  90. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  91. data/dependencies/SDL_sound/SDL_sound.c +795 -0
  92. data/dependencies/SDL_sound/SDL_sound.h +725 -0
  93. data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
  94. data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
  95. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
  96. data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
  97. data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
  98. data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
  99. data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
  100. data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
  101. data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
  102. data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
  103. data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
  104. data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
  105. data/dependencies/SDL_sound/dr_flac.h +5906 -0
  106. data/dependencies/SDL_sound/dr_mp3.h +2832 -0
  107. data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
  108. data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
  109. data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
  110. data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
  111. data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
  112. data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
  113. data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
  114. data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
  115. data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
  116. data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
  117. data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
  118. data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
  119. data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
  120. data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
  121. data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
  122. data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
  123. data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
  124. data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
  125. data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
  126. data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
  127. data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
  128. data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
  129. data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
  130. data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
  131. data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
  132. data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
  133. data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
  134. data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
  135. data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
  136. data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
  137. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
  138. data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
  139. data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
  140. data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
  141. data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
  142. data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
  143. data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
  144. data/dependencies/al_soft/AL/al.h +655 -0
  145. data/dependencies/al_soft/AL/alc.h +270 -0
  146. data/dependencies/al_soft/AL/alext.h +585 -0
  147. data/dependencies/al_soft/AL/efx-creative.h +3 -0
  148. data/dependencies/al_soft/AL/efx-presets.h +402 -0
  149. data/dependencies/al_soft/AL/efx.h +762 -0
  150. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  151. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  152. data/{src → dependencies/stb}/stb_image.h +330 -127
  153. data/{src → dependencies/stb}/stb_image_write.h +156 -85
  154. data/{src → dependencies/stb}/stb_truetype.h +192 -69
  155. data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
  156. data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
  157. data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
  158. data/ext/gosu/extconf.rb +53 -39
  159. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  160. data/include/Gosu/Bitmap.hpp +100 -0
  161. data/{Gosu → include/Gosu}/Buttons.hpp +104 -44
  162. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  163. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  164. data/{Gosu → include/Gosu}/Font.hpp +1 -1
  165. data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
  166. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  167. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  168. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  169. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  170. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  171. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  172. data/{Gosu → include/Gosu}/Input.hpp +39 -51
  173. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  174. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  175. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  176. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  177. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  178. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  179. data/{Gosu → include/Gosu}/Utility.hpp +15 -4
  180. data/{Gosu → include/Gosu}/Version.hpp +3 -3
  181. data/{Gosu → include/Gosu}/Window.hpp +46 -34
  182. data/lib/OpenAL32.dll +0 -0
  183. data/lib/SDL2.dll +0 -0
  184. data/lib/gosu.rb +0 -3
  185. data/lib/gosu/patches.rb +0 -23
  186. data/lib/gosu/preview.rb +1 -3
  187. data/lib/gosu/swig_patches.rb +14 -12
  188. data/lib64/OpenAL32.dll +0 -0
  189. data/lib64/SDL2.dll +0 -0
  190. data/rdoc/gosu.rb +112 -23
  191. data/src/Audio.cpp +50 -224
  192. data/src/AudioFile.hpp +20 -37
  193. data/src/AudioFileAudioToolbox.cpp +237 -0
  194. data/src/AudioFileSDLSound.cpp +147 -0
  195. data/src/AudioImpl.cpp +3 -12
  196. data/src/AudioImpl.hpp +3 -1
  197. data/src/Bitmap.cpp +85 -83
  198. data/src/BitmapIO.cpp +52 -58
  199. data/src/Font.cpp +3 -1
  200. data/src/Graphics.cpp +7 -4
  201. data/src/Image.cpp +13 -16
  202. data/src/Input.cpp +412 -164
  203. data/src/LargeImageData.cpp +1 -1
  204. data/src/MarkupParser.cpp +2 -1
  205. data/src/Resolution.cpp +8 -8
  206. data/src/RubyGosu.cxx +1017 -196
  207. data/src/RubyGosu.h +4 -2
  208. data/src/TexChunk.cpp +1 -1
  209. data/src/TextBuilder.cpp +3 -1
  210. data/src/Texture.cpp +1 -1
  211. data/src/TrueTypeFont.cpp +1 -1
  212. data/src/TrueTypeFontWin.cpp +3 -3
  213. data/src/Utility.cpp +11 -7
  214. data/src/Window.cpp +90 -62
  215. data/src/WindowUIKit.cpp +21 -9
  216. metadata +194 -65
  217. data/Gosu/AutoLink.hpp +0 -14
  218. data/Gosu/Bitmap.hpp +0 -113
  219. data/Gosu/Channel.h +0 -25
  220. data/Gosu/Color.h +0 -38
  221. data/Gosu/Font.h +0 -36
  222. data/Gosu/Gosu.h +0 -79
  223. data/Gosu/Image.h +0 -54
  224. data/Gosu/Sample.h +0 -19
  225. data/Gosu/Song.h +0 -24
  226. data/Gosu/TextInput.h +0 -30
  227. data/Gosu/Window.h +0 -61
  228. data/lib/gosu/zen.rb +0 -89
  229. data/src/AudioToolboxFile.hpp +0 -210
  230. data/src/ChannelWrapper.cpp +0 -50
  231. data/src/ColorWrapper.cpp +0 -126
  232. data/src/Constants.cpp +0 -287
  233. data/src/FontWrapper.cpp +0 -74
  234. data/src/GosuWrapper.cpp +0 -232
  235. data/src/ImageWrapper.cpp +0 -168
  236. data/src/MPEGFile.hpp +0 -90
  237. data/src/OggFile.hpp +0 -92
  238. data/src/SampleWrapper.cpp +0 -30
  239. data/src/SndFile.hpp +0 -174
  240. data/src/SongWrapper.cpp +0 -52
  241. data/src/TextInputWrapper.cpp +0 -101
  242. data/src/WinMain.cpp +0 -64
  243. data/src/WindowWrapper.cpp +0 -289
@@ -0,0 +1,795 @@
1
+ /**
2
+ * SDL_sound; An abstract sound format decoding API.
3
+ *
4
+ * Please see the file LICENSE.txt in the source's root directory.
5
+ *
6
+ * This file written by Ryan C. Gordon.
7
+ */
8
+
9
+ /**
10
+ * This file implements the core API, which is relatively simple.
11
+ * The real meat of SDL_sound is in the decoders.
12
+ *
13
+ * Documentation is in SDL_sound.h ... It's verbose, honest. :)
14
+ */
15
+
16
+ #define __SDL_SOUND_INTERNAL__
17
+ #include "SDL_sound_internal.h"
18
+
19
+ /* The various decoder drivers... */
20
+
21
+ /* All these externs may be missing; we check SOUND_SUPPORTS_xxx before use. */
22
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MODPLUG;
23
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MP3;
24
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV;
25
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_AIFF;
26
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_AU;
27
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_VORBIS;
28
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_VOC;
29
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_RAW;
30
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_SHN;
31
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_FLAC;
32
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_QuickTime;
33
+ extern const Sound_DecoderFunctions __Sound_DecoderFunctions_CoreAudio;
34
+
35
+ typedef struct
36
+ {
37
+ int available;
38
+ const Sound_DecoderFunctions *funcs;
39
+ } decoder_element;
40
+
41
+ static decoder_element decoders[] =
42
+ {
43
+ #if SOUND_SUPPORTS_MODPLUG
44
+ { 0, &__Sound_DecoderFunctions_MODPLUG },
45
+ #endif
46
+ #if SOUND_SUPPORTS_MP3
47
+ { 0, &__Sound_DecoderFunctions_MP3 },
48
+ #endif
49
+ #if SOUND_SUPPORTS_WAV
50
+ { 0, &__Sound_DecoderFunctions_WAV },
51
+ #endif
52
+ #if SOUND_SUPPORTS_AIFF
53
+ { 0, &__Sound_DecoderFunctions_AIFF },
54
+ #endif
55
+ #if SOUND_SUPPORTS_AU
56
+ { 0, &__Sound_DecoderFunctions_AU },
57
+ #endif
58
+ #if SOUND_SUPPORTS_VORBIS
59
+ { 0, &__Sound_DecoderFunctions_VORBIS },
60
+ #endif
61
+ #if SOUND_SUPPORTS_VOC
62
+ { 0, &__Sound_DecoderFunctions_VOC },
63
+ #endif
64
+ #if SOUND_SUPPORTS_RAW
65
+ { 0, &__Sound_DecoderFunctions_RAW },
66
+ #endif
67
+ #if SOUND_SUPPORTS_SHN
68
+ { 0, &__Sound_DecoderFunctions_SHN },
69
+ #endif
70
+ #if SOUND_SUPPORTS_FLAC
71
+ { 0, &__Sound_DecoderFunctions_FLAC },
72
+ #endif
73
+ #if SOUND_SUPPORTS_COREAUDIO
74
+ { 0, &__Sound_DecoderFunctions_CoreAudio },
75
+ #endif
76
+
77
+ { 0, NULL }
78
+ };
79
+
80
+
81
+
82
+ /* General SDL_sound state ... */
83
+
84
+ typedef struct __SOUND_ERRMSGTYPE__
85
+ {
86
+ Uint32 tid;
87
+ int error_available;
88
+ char error_string[128];
89
+ struct __SOUND_ERRMSGTYPE__ *next;
90
+ } ErrMsg;
91
+
92
+ static ErrMsg *error_msgs = NULL;
93
+ static SDL_mutex *errorlist_mutex = NULL;
94
+
95
+ static Sound_Sample *sample_list = NULL; /* this is a linked list. */
96
+ static SDL_mutex *samplelist_mutex = NULL;
97
+
98
+ static const Sound_DecoderInfo **available_decoders = NULL;
99
+ static int initialized = 0;
100
+
101
+
102
+ /* functions ... */
103
+
104
+ void Sound_GetLinkedVersion(Sound_Version *ver)
105
+ {
106
+ if (ver != NULL)
107
+ {
108
+ ver->major = SOUND_VER_MAJOR;
109
+ ver->minor = SOUND_VER_MINOR;
110
+ ver->patch = SOUND_VER_PATCH;
111
+ } /* if */
112
+ } /* Sound_GetLinkedVersion */
113
+
114
+
115
+ int Sound_Init(void)
116
+ {
117
+ size_t i;
118
+ size_t pos = 0;
119
+ size_t total = sizeof (decoders) / sizeof (decoders[0]);
120
+ BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
121
+
122
+ sample_list = NULL;
123
+ error_msgs = NULL;
124
+
125
+ available_decoders = (const Sound_DecoderInfo **)
126
+ SDL_calloc(total, sizeof (Sound_DecoderInfo *));
127
+ BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0);
128
+
129
+ SDL_InitSubSystem(SDL_INIT_AUDIO);
130
+
131
+ errorlist_mutex = SDL_CreateMutex();
132
+ samplelist_mutex = SDL_CreateMutex();
133
+
134
+ for (i = 0; decoders[i].funcs != NULL; i++)
135
+ {
136
+ decoders[i].available = decoders[i].funcs->init();
137
+ if (decoders[i].available)
138
+ {
139
+ available_decoders[pos] = &(decoders[i].funcs->info);
140
+ pos++;
141
+ } /* if */
142
+ } /* for */
143
+
144
+ initialized = 1;
145
+ return 1;
146
+ } /* Sound_Init */
147
+
148
+
149
+ int Sound_Quit(void)
150
+ {
151
+ ErrMsg *err;
152
+ ErrMsg *nexterr = NULL;
153
+ size_t i;
154
+
155
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
156
+
157
+ while (((volatile Sound_Sample *) sample_list) != NULL)
158
+ Sound_FreeSample(sample_list);
159
+
160
+ initialized = 0;
161
+
162
+ SDL_DestroyMutex(samplelist_mutex);
163
+ samplelist_mutex = NULL;
164
+ sample_list = NULL;
165
+
166
+ for (i = 0; decoders[i].funcs != NULL; i++)
167
+ {
168
+ if (decoders[i].available)
169
+ {
170
+ decoders[i].funcs->quit();
171
+ decoders[i].available = 0;
172
+ } /* if */
173
+ } /* for */
174
+
175
+ if (available_decoders != NULL)
176
+ SDL_free((void *) available_decoders);
177
+ available_decoders = NULL;
178
+
179
+ /* clean up error state for each thread... */
180
+ SDL_LockMutex(errorlist_mutex);
181
+ for (err = error_msgs; err != NULL; err = nexterr)
182
+ {
183
+ nexterr = err->next;
184
+ SDL_free(err);
185
+ } /* for */
186
+ error_msgs = NULL;
187
+ SDL_UnlockMutex(errorlist_mutex);
188
+ SDL_DestroyMutex(errorlist_mutex);
189
+ errorlist_mutex = NULL;
190
+
191
+ return 1;
192
+ } /* Sound_Quit */
193
+
194
+
195
+ const Sound_DecoderInfo **Sound_AvailableDecoders(void)
196
+ {
197
+ return available_decoders; /* READ. ONLY. */
198
+ } /* Sound_AvailableDecoders */
199
+
200
+
201
+ static ErrMsg *findErrorForCurrentThread(void)
202
+ {
203
+ ErrMsg *i;
204
+ Uint32 tid;
205
+
206
+ if (error_msgs != NULL)
207
+ {
208
+ tid = SDL_ThreadID();
209
+
210
+ SDL_LockMutex(errorlist_mutex);
211
+ for (i = error_msgs; i != NULL; i = i->next)
212
+ {
213
+ if (i->tid == tid)
214
+ {
215
+ SDL_UnlockMutex(errorlist_mutex);
216
+ return i;
217
+ } /* if */
218
+ } /* for */
219
+ SDL_UnlockMutex(errorlist_mutex);
220
+ } /* if */
221
+
222
+ return NULL; /* no error available. */
223
+ } /* findErrorForCurrentThread */
224
+
225
+
226
+ const char *Sound_GetError(void)
227
+ {
228
+ const char *retval = NULL;
229
+ ErrMsg *err;
230
+
231
+ if (!initialized)
232
+ return ERR_NOT_INITIALIZED;
233
+
234
+ err = findErrorForCurrentThread();
235
+ if ((err != NULL) && (err->error_available))
236
+ {
237
+ retval = err->error_string;
238
+ err->error_available = 0;
239
+ } /* if */
240
+
241
+ return retval;
242
+ } /* Sound_GetError */
243
+
244
+
245
+ void Sound_ClearError(void)
246
+ {
247
+ ErrMsg *err;
248
+
249
+ if (!initialized)
250
+ return;
251
+
252
+ err = findErrorForCurrentThread();
253
+ if (err != NULL)
254
+ err->error_available = 0;
255
+ } /* Sound_ClearError */
256
+
257
+
258
+ /*
259
+ * This is declared in the internal header.
260
+ */
261
+ void __Sound_SetError(const char *str)
262
+ {
263
+ ErrMsg *err;
264
+
265
+ if (str == NULL)
266
+ return;
267
+
268
+ SNDDBG(("__Sound_SetError(\"%s\");%s\n", str,
269
+ (initialized) ? "" : " [NOT INITIALIZED!]"));
270
+
271
+ if (!initialized)
272
+ return;
273
+
274
+ err = findErrorForCurrentThread();
275
+ if (err == NULL)
276
+ {
277
+ err = (ErrMsg *) SDL_calloc(1, sizeof (ErrMsg));
278
+ if (err == NULL)
279
+ return; /* uhh...? */
280
+
281
+ err->tid = SDL_ThreadID();
282
+
283
+ SDL_LockMutex(errorlist_mutex);
284
+ err->next = error_msgs;
285
+ error_msgs = err;
286
+ SDL_UnlockMutex(errorlist_mutex);
287
+ } /* if */
288
+
289
+ err->error_available = 1;
290
+ SDL_strlcpy(err->error_string, str, sizeof (err->error_string));
291
+ } /* __Sound_SetError */
292
+
293
+
294
+ Uint32 __Sound_convertMsToBytePos(Sound_AudioInfo *info, Uint32 ms)
295
+ {
296
+ /* "frames" == "sample frames" */
297
+ float frames_per_ms = ((float) info->rate) / 1000.0f;
298
+ Uint32 frame_offset = (Uint32) (frames_per_ms * ((float) ms));
299
+ Uint32 frame_size = (Uint32) ((info->format & 0xFF) / 8) * info->channels;
300
+ return frame_offset * frame_size;
301
+ } /* __Sound_convertMsToBytePos */
302
+
303
+
304
+ /*
305
+ * Allocate a Sound_Sample, and fill in most of its fields. Those that need
306
+ * to be filled in later, by a decoder, will be initialized to zero.
307
+ */
308
+ static Sound_Sample *alloc_sample(SDL_RWops *rw, Sound_AudioInfo *desired,
309
+ Uint32 bufferSize)
310
+ {
311
+ /*
312
+ * !!! FIXME: We're going to need to pool samples, since the mixer
313
+ * !!! FIXME: might be allocating tons of these on a regular basis.
314
+ */
315
+ Sound_Sample *retval = SDL_calloc(1, sizeof (Sound_Sample));
316
+ Sound_SampleInternal *internal = SDL_calloc(1, sizeof (Sound_SampleInternal));
317
+ if ((retval == NULL) || (internal == NULL))
318
+ {
319
+ __Sound_SetError(ERR_OUT_OF_MEMORY);
320
+ if (retval)
321
+ SDL_free(retval);
322
+ if (internal)
323
+ SDL_free(internal);
324
+
325
+ return NULL;
326
+ } /* if */
327
+
328
+ SDL_assert(bufferSize > 0);
329
+ retval->buffer = SDL_calloc(1, bufferSize); /* pure ugly. */
330
+ if (!retval->buffer)
331
+ {
332
+ __Sound_SetError(ERR_OUT_OF_MEMORY);
333
+ SDL_free(internal);
334
+ SDL_free(retval);
335
+ return NULL;
336
+ } /* if */
337
+ retval->buffer_size = bufferSize;
338
+
339
+ if (desired != NULL)
340
+ SDL_memcpy(&retval->desired, desired, sizeof (Sound_AudioInfo));
341
+
342
+ internal->rw = rw;
343
+ retval->opaque = internal;
344
+ return retval;
345
+ } /* alloc_sample */
346
+
347
+
348
+ #if (defined DEBUG_CHATTER)
349
+ static SDL_INLINE const char *fmt_to_str(Uint16 fmt)
350
+ {
351
+ switch(fmt)
352
+ {
353
+ case AUDIO_U8:
354
+ return "U8";
355
+ case AUDIO_S8:
356
+ return "S8";
357
+ case AUDIO_U16LSB:
358
+ return "U16LSB";
359
+ case AUDIO_S16LSB:
360
+ return "S16LSB";
361
+ case AUDIO_S32LSB:
362
+ return "S32LSB";
363
+ case AUDIO_F32LSB:
364
+ return "F32LSB";
365
+ case AUDIO_U16MSB:
366
+ return "U16MSB";
367
+ case AUDIO_S16MSB:
368
+ return "S16MSB";
369
+ case AUDIO_S32MSB:
370
+ return "S32MSB";
371
+ case AUDIO_F32MSB:
372
+ return "F32MSB";
373
+ } /* switch */
374
+
375
+ return "Unknown";
376
+ } /* fmt_to_str */
377
+ #endif
378
+
379
+
380
+ /*
381
+ * The bulk of the Sound_NewSample() work is done here...
382
+ * Ask the specified decoder to handle the data in (rw), and if
383
+ * so, construct the Sound_Sample. Otherwise, try to wind (rw)'s stream
384
+ * back to where it was, and return false.
385
+ */
386
+ static int init_sample(const Sound_DecoderFunctions *funcs,
387
+ Sound_Sample *sample, const char *ext,
388
+ Sound_AudioInfo *_desired)
389
+ {
390
+ Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
391
+ Sound_AudioInfo desired;
392
+ int pos = SDL_RWtell(internal->rw);
393
+
394
+ /* fill in the funcs for this decoder... */
395
+ sample->decoder = &funcs->info;
396
+ internal->funcs = funcs;
397
+ if (!funcs->open(sample, ext))
398
+ {
399
+ SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */
400
+ return 0;
401
+ } /* if */
402
+
403
+ /* success; we've got a decoder! */
404
+
405
+ /* Now we need to set up the conversion buffer... */
406
+
407
+ if (_desired == NULL)
408
+ SDL_memcpy(&desired, &sample->actual, sizeof (Sound_AudioInfo));
409
+ else
410
+ {
411
+ desired.format = _desired->format ? _desired->format : sample->actual.format;
412
+ desired.channels = _desired->channels ? _desired->channels : sample->actual.channels;
413
+ desired.rate = _desired->rate ? _desired->rate : sample->actual.rate;
414
+ } /* else */
415
+
416
+ if (SDL_BuildAudioCVT(&internal->sdlcvt,
417
+ sample->actual.format,
418
+ sample->actual.channels,
419
+ sample->actual.rate,
420
+ desired.format,
421
+ desired.channels,
422
+ desired.rate) == -1)
423
+ {
424
+ __Sound_SetError(SDL_GetError());
425
+ funcs->close(sample);
426
+ SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */
427
+ return 0;
428
+ } /* if */
429
+
430
+ if (internal->sdlcvt.len_mult > 1)
431
+ {
432
+ void *rc = SDL_realloc(sample->buffer, sample->buffer_size * internal->sdlcvt.len_mult);
433
+ if (rc == NULL)
434
+ {
435
+ funcs->close(sample);
436
+ SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */
437
+ return 0;
438
+ } /* if */
439
+
440
+ sample->buffer = rc;
441
+ } /* if */
442
+
443
+ /* these pointers are all one and the same. */
444
+ SDL_memcpy(&sample->desired, &desired, sizeof (Sound_AudioInfo));
445
+ internal->sdlcvt.buf = internal->buffer = sample->buffer;
446
+ internal->buffer_size = sample->buffer_size / internal->sdlcvt.len_mult;
447
+ internal->sdlcvt.len = internal->buffer_size;
448
+
449
+ /* Prepend our new Sound_Sample to the sample_list... */
450
+ SDL_LockMutex(samplelist_mutex);
451
+ internal->next = sample_list;
452
+ if (sample_list != NULL)
453
+ ((Sound_SampleInternal *) sample_list->opaque)->prev = sample;
454
+ sample_list = sample;
455
+ SDL_UnlockMutex(samplelist_mutex);
456
+
457
+ SNDDBG(("New sample DESIRED format: %s format, %d rate, %d channels.\n",
458
+ fmt_to_str(sample->desired.format),
459
+ sample->desired.rate,
460
+ sample->desired.channels));
461
+
462
+ SNDDBG(("New sample ACTUAL format: %s format, %d rate, %d channels.\n",
463
+ fmt_to_str(sample->actual.format),
464
+ sample->actual.rate,
465
+ sample->actual.channels));
466
+
467
+ SNDDBG(("On-the-fly conversion: %s.\n",
468
+ internal->sdlcvt.needed ? "ENABLED" : "DISABLED"));
469
+
470
+ return 1;
471
+ } /* init_sample */
472
+
473
+
474
+ Sound_Sample *Sound_NewSample(SDL_RWops *rw, const char *ext,
475
+ Sound_AudioInfo *desired, Uint32 bSize)
476
+ {
477
+ Sound_Sample *retval;
478
+ decoder_element *decoder;
479
+
480
+ /* sanity checks. */
481
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL);
482
+ BAIL_IF_MACRO(rw == NULL, ERR_INVALID_ARGUMENT, NULL);
483
+
484
+ retval = alloc_sample(rw, desired, bSize);
485
+ if (!retval)
486
+ return NULL; /* alloc_sample() sets error message... */
487
+
488
+ if (ext != NULL)
489
+ {
490
+ for (decoder = &decoders[0]; decoder->funcs != NULL; decoder++)
491
+ {
492
+ if (decoder->available)
493
+ {
494
+ const char **decoderExt = decoder->funcs->info.extensions;
495
+ while (*decoderExt)
496
+ {
497
+ if (SDL_strcasecmp(*decoderExt, ext) == 0)
498
+ {
499
+ if (init_sample(decoder->funcs, retval, ext, desired))
500
+ return retval;
501
+ break; /* done with this decoder either way. */
502
+ } /* if */
503
+ decoderExt++;
504
+ } /* while */
505
+ } /* if */
506
+ } /* for */
507
+ } /* if */
508
+
509
+ /* no direct extension match? Try everything we've got... */
510
+ for (decoder = &decoders[0]; decoder->funcs != NULL; decoder++)
511
+ {
512
+ if (decoder->available)
513
+ {
514
+ int should_try = 1;
515
+ const char **decoderExt = decoder->funcs->info.extensions;
516
+
517
+ /* skip if we would have tried decoder above... */
518
+ while (*decoderExt)
519
+ {
520
+ if (SDL_strcasecmp(*decoderExt, ext) == 0)
521
+ {
522
+ should_try = 0;
523
+ break;
524
+ } /* if */
525
+ decoderExt++;
526
+ } /* while */
527
+
528
+ if (should_try)
529
+ {
530
+ if (init_sample(decoder->funcs, retval, ext, desired))
531
+ return retval;
532
+ } /* if */
533
+ } /* if */
534
+ } /* for */
535
+
536
+ /* nothing could handle the sound data... */
537
+ SDL_free(retval->opaque);
538
+ if (retval->buffer != NULL)
539
+ SDL_free(retval->buffer);
540
+ SDL_free(retval);
541
+ SDL_RWclose(rw);
542
+ __Sound_SetError(ERR_UNSUPPORTED_FORMAT);
543
+ return NULL;
544
+ } /* Sound_NewSample */
545
+
546
+
547
+ Sound_Sample *Sound_NewSampleFromFile(const char *filename,
548
+ Sound_AudioInfo *desired,
549
+ Uint32 bufferSize)
550
+ {
551
+ const char *ext;
552
+ SDL_RWops *rw;
553
+
554
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL);
555
+ BAIL_IF_MACRO(filename == NULL, ERR_INVALID_ARGUMENT, NULL);
556
+
557
+ ext = SDL_strrchr(filename, '.');
558
+ rw = SDL_RWFromFile(filename, "rb");
559
+ BAIL_IF_MACRO(rw == NULL, SDL_GetError(), NULL);
560
+
561
+ if (ext != NULL)
562
+ ext++;
563
+
564
+ return Sound_NewSample(rw, ext, desired, bufferSize);
565
+ } /* Sound_NewSampleFromFile */
566
+
567
+
568
+ Sound_Sample *Sound_NewSampleFromMem(const Uint8 *data,
569
+ Uint32 size,
570
+ const char *ext,
571
+ Sound_AudioInfo *desired,
572
+ Uint32 bufferSize)
573
+ {
574
+ SDL_RWops *rw;
575
+
576
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL);
577
+ BAIL_IF_MACRO(data == NULL, ERR_INVALID_ARGUMENT, NULL);
578
+ BAIL_IF_MACRO(size == 0, ERR_INVALID_ARGUMENT, NULL);
579
+
580
+ rw = SDL_RWFromConstMem(data, size);
581
+ BAIL_IF_MACRO(rw == NULL, SDL_GetError(), NULL);
582
+
583
+ return Sound_NewSample(rw, ext, desired, bufferSize);
584
+ } /* Sound_NewSampleFromMem */
585
+
586
+
587
+ void Sound_FreeSample(Sound_Sample *sample)
588
+ {
589
+ Sound_SampleInternal *internal;
590
+
591
+ if (!initialized)
592
+ {
593
+ __Sound_SetError(ERR_NOT_INITIALIZED);
594
+ return;
595
+ } /* if */
596
+
597
+ if (sample == NULL)
598
+ {
599
+ __Sound_SetError(ERR_INVALID_ARGUMENT);
600
+ return;
601
+ } /* if */
602
+
603
+ internal = (Sound_SampleInternal *) sample->opaque;
604
+
605
+ SDL_LockMutex(samplelist_mutex);
606
+
607
+ /* update the sample_list... */
608
+ if (internal->prev != NULL)
609
+ {
610
+ Sound_SampleInternal *prevInternal;
611
+ prevInternal = (Sound_SampleInternal *) internal->prev->opaque;
612
+ prevInternal->next = internal->next;
613
+ } /* if */
614
+ else
615
+ {
616
+ SDL_assert(sample_list == sample);
617
+ sample_list = internal->next;
618
+ } /* else */
619
+
620
+ if (internal->next != NULL)
621
+ {
622
+ Sound_SampleInternal *nextInternal;
623
+ nextInternal = (Sound_SampleInternal *) internal->next->opaque;
624
+ nextInternal->prev = internal->prev;
625
+ } /* if */
626
+
627
+ SDL_UnlockMutex(samplelist_mutex);
628
+
629
+ /* nuke it... */
630
+ internal->funcs->close(sample);
631
+
632
+ if (internal->rw != NULL) /* this condition is a "just in case" thing. */
633
+ SDL_RWclose(internal->rw);
634
+
635
+ if ((internal->buffer != NULL) && (internal->buffer != sample->buffer))
636
+ SDL_free(internal->buffer);
637
+
638
+ SDL_free(internal);
639
+
640
+ if (sample->buffer != NULL)
641
+ SDL_free(sample->buffer);
642
+
643
+ SDL_free(sample);
644
+ } /* Sound_FreeSample */
645
+
646
+
647
+ int Sound_SetBufferSize(Sound_Sample *sample, Uint32 newSize)
648
+ {
649
+ void *newBuf = NULL;
650
+ Sound_SampleInternal *internal = NULL;
651
+
652
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
653
+ BAIL_IF_MACRO(sample == NULL, ERR_INVALID_ARGUMENT, 0);
654
+ internal = ((Sound_SampleInternal *) sample->opaque);
655
+ newBuf = SDL_realloc(sample->buffer, newSize * internal->sdlcvt.len_mult);
656
+ BAIL_IF_MACRO(newBuf == NULL, ERR_OUT_OF_MEMORY, 0);
657
+
658
+ internal->sdlcvt.buf = internal->buffer = sample->buffer = newBuf;
659
+ sample->buffer_size = newSize;
660
+ internal->buffer_size = newSize / internal->sdlcvt.len_mult;
661
+ internal->sdlcvt.len = internal->buffer_size;
662
+
663
+ return 1;
664
+ } /* Sound_SetBufferSize */
665
+
666
+
667
+ Uint32 Sound_Decode(Sound_Sample *sample)
668
+ {
669
+ Sound_SampleInternal *internal = NULL;
670
+ Uint32 retval = 0;
671
+
672
+ /* a boatload of sanity checks... */
673
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
674
+ BAIL_IF_MACRO(sample == NULL, ERR_INVALID_ARGUMENT, 0);
675
+ BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_ERROR, ERR_PREV_ERROR, 0);
676
+ BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_EOF, ERR_PREV_EOF, 0);
677
+
678
+ internal = (Sound_SampleInternal *) sample->opaque;
679
+
680
+ SDL_assert(sample->buffer != NULL);
681
+ SDL_assert(sample->buffer_size > 0);
682
+ SDL_assert(internal->buffer != NULL);
683
+ SDL_assert(internal->buffer_size > 0);
684
+
685
+ /* reset EAGAIN. Decoder can flip it back on if it needs to. */
686
+ sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
687
+ retval = internal->funcs->read(sample);
688
+
689
+ if (retval > 0 && internal->sdlcvt.needed)
690
+ {
691
+ internal->sdlcvt.len = retval;
692
+ SDL_ConvertAudio(&internal->sdlcvt);
693
+ retval = internal->sdlcvt.len_cvt;
694
+ } /* if */
695
+
696
+ return retval;
697
+ } /* Sound_Decode */
698
+
699
+
700
+ Uint32 Sound_DecodeAll(Sound_Sample *sample)
701
+ {
702
+ Sound_SampleInternal *internal = NULL;
703
+ void *buf = NULL;
704
+ Uint32 newBufSize = 0;
705
+
706
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
707
+ BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_EOF, ERR_PREV_EOF, 0);
708
+ BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_ERROR, ERR_PREV_ERROR, 0);
709
+
710
+ internal = (Sound_SampleInternal *) sample->opaque;
711
+
712
+ while ( ((sample->flags & SOUND_SAMPLEFLAG_EOF) == 0) &&
713
+ ((sample->flags & SOUND_SAMPLEFLAG_ERROR) == 0) )
714
+ {
715
+ Uint32 br = Sound_Decode(sample);
716
+ void *ptr = SDL_realloc(buf, newBufSize + br);
717
+ if (ptr == NULL)
718
+ {
719
+ sample->flags |= SOUND_SAMPLEFLAG_ERROR;
720
+ __Sound_SetError(ERR_OUT_OF_MEMORY);
721
+ } /* if */
722
+ else
723
+ {
724
+ buf = ptr;
725
+ SDL_memcpy( ((char *) buf) + newBufSize, sample->buffer, br );
726
+ newBufSize += br;
727
+ } /* else */
728
+ } /* while */
729
+
730
+ if (buf == NULL) /* ...in case first call to SDL_realloc() fails... */
731
+ return sample->buffer_size;
732
+
733
+ if (internal->buffer != sample->buffer)
734
+ SDL_free(internal->buffer);
735
+
736
+ SDL_free(sample->buffer);
737
+
738
+ internal->sdlcvt.buf = internal->buffer = sample->buffer = buf;
739
+ sample->buffer_size = newBufSize;
740
+ internal->buffer_size = newBufSize / internal->sdlcvt.len_mult;
741
+ internal->sdlcvt.len = internal->buffer_size;
742
+
743
+ return newBufSize;
744
+ } /* Sound_DecodeAll */
745
+
746
+
747
+ int Sound_Rewind(Sound_Sample *sample)
748
+ {
749
+ Sound_SampleInternal *internal;
750
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
751
+
752
+ internal = (Sound_SampleInternal *) sample->opaque;
753
+ if (!internal->funcs->rewind(sample))
754
+ {
755
+ sample->flags |= SOUND_SAMPLEFLAG_ERROR;
756
+ return 0;
757
+ } /* if */
758
+
759
+ sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
760
+ sample->flags &= ~SOUND_SAMPLEFLAG_ERROR;
761
+ sample->flags &= ~SOUND_SAMPLEFLAG_EOF;
762
+
763
+ return 1;
764
+ } /* Sound_Rewind */
765
+
766
+
767
+ int Sound_Seek(Sound_Sample *sample, Uint32 ms)
768
+ {
769
+ Sound_SampleInternal *internal;
770
+
771
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
772
+ if (!(sample->flags & SOUND_SAMPLEFLAG_CANSEEK))
773
+ BAIL_MACRO(ERR_CANNOT_SEEK, 0);
774
+
775
+ internal = (Sound_SampleInternal *) sample->opaque;
776
+ BAIL_IF_MACRO(!internal->funcs->seek(sample, ms), NULL, 0);
777
+
778
+ sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
779
+ sample->flags &= ~SOUND_SAMPLEFLAG_ERROR;
780
+ sample->flags &= ~SOUND_SAMPLEFLAG_EOF;
781
+
782
+ return 1;
783
+ } /* Sound_Rewind */
784
+
785
+
786
+ Sint32 Sound_GetDuration(Sound_Sample *sample)
787
+ {
788
+ Sound_SampleInternal *internal;
789
+ BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, -1);
790
+ internal = (Sound_SampleInternal *) sample->opaque;
791
+ return internal->total_time;
792
+ } /* Sound_GetDuration */
793
+
794
+ /* end of SDL_sound.c ... */
795
+