gosu 0.14.6.pre1 → 1.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/COPYING +1 -1
  4. data/dependencies/SDL/include/SDL.h +138 -0
  5. data/dependencies/SDL/include/SDL_assert.h +293 -0
  6. data/dependencies/SDL/include/SDL_atomic.h +295 -0
  7. data/dependencies/SDL/include/SDL_audio.h +859 -0
  8. data/dependencies/SDL/include/SDL_bits.h +121 -0
  9. data/dependencies/SDL/include/SDL_blendmode.h +123 -0
  10. data/dependencies/SDL/include/SDL_clipboard.h +71 -0
  11. data/dependencies/SDL/include/SDL_config.h +55 -0
  12. data/dependencies/SDL/include/SDL_config_android.h +182 -0
  13. data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
  14. data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
  15. data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
  16. data/dependencies/SDL/include/SDL_config_os2.h +188 -0
  17. data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
  18. data/dependencies/SDL/include/SDL_config_psp.h +165 -0
  19. data/dependencies/SDL/include/SDL_config_windows.h +288 -0
  20. data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
  21. data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
  22. data/dependencies/SDL/include/SDL_copying.h +20 -0
  23. data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
  24. data/dependencies/SDL/include/SDL_egl.h +1676 -0
  25. data/dependencies/SDL/include/SDL_endian.h +263 -0
  26. data/dependencies/SDL/include/SDL_error.h +112 -0
  27. data/dependencies/SDL/include/SDL_events.h +827 -0
  28. data/dependencies/SDL/include/SDL_filesystem.h +136 -0
  29. data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
  30. data/dependencies/SDL/include/SDL_gesture.h +87 -0
  31. data/dependencies/SDL/include/SDL_haptic.h +1247 -0
  32. data/dependencies/SDL/include/SDL_hints.h +1578 -0
  33. data/dependencies/SDL/include/SDL_joystick.h +499 -0
  34. data/dependencies/SDL/include/SDL_keyboard.h +217 -0
  35. data/dependencies/SDL/include/SDL_keycode.h +351 -0
  36. data/dependencies/SDL/include/SDL_loadso.h +81 -0
  37. data/dependencies/SDL/include/SDL_locale.h +101 -0
  38. data/dependencies/SDL/include/SDL_log.h +211 -0
  39. data/dependencies/SDL/include/SDL_main.h +180 -0
  40. data/dependencies/SDL/include/SDL_messagebox.h +146 -0
  41. data/dependencies/SDL/include/SDL_metal.h +117 -0
  42. data/dependencies/SDL/include/SDL_misc.h +75 -0
  43. data/dependencies/SDL/include/SDL_mouse.h +302 -0
  44. data/dependencies/SDL/include/SDL_mutex.h +251 -0
  45. data/dependencies/SDL/include/SDL_name.h +33 -0
  46. data/dependencies/SDL/include/SDL_opengl.h +2183 -0
  47. data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
  48. data/dependencies/SDL/include/SDL_opengles.h +39 -0
  49. data/dependencies/SDL/include/SDL_opengles2.h +52 -0
  50. data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
  51. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
  52. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
  53. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
  54. data/dependencies/SDL/include/SDL_pixels.h +479 -0
  55. data/dependencies/SDL/include/SDL_platform.h +198 -0
  56. data/dependencies/SDL/include/SDL_power.h +75 -0
  57. data/dependencies/SDL/include/SDL_quit.h +58 -0
  58. data/dependencies/SDL/include/SDL_rect.h +174 -0
  59. data/dependencies/SDL/include/SDL_render.h +1158 -0
  60. data/dependencies/SDL/include/SDL_revision.h +2 -0
  61. data/dependencies/SDL/include/SDL_rwops.h +283 -0
  62. data/dependencies/SDL/include/SDL_scancode.h +413 -0
  63. data/dependencies/SDL/include/SDL_sensor.h +267 -0
  64. data/dependencies/SDL/include/SDL_shape.h +144 -0
  65. data/dependencies/SDL/include/SDL_stdinc.h +647 -0
  66. data/dependencies/SDL/include/SDL_surface.h +563 -0
  67. data/dependencies/SDL/include/SDL_system.h +325 -0
  68. data/dependencies/SDL/include/SDL_syswm.h +354 -0
  69. data/dependencies/SDL/include/SDL_test.h +69 -0
  70. data/dependencies/SDL/include/SDL_test_assert.h +105 -0
  71. data/dependencies/SDL/include/SDL_test_common.h +218 -0
  72. data/dependencies/SDL/include/SDL_test_compare.h +69 -0
  73. data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
  74. data/dependencies/SDL/include/SDL_test_font.h +81 -0
  75. data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
  76. data/dependencies/SDL/include/SDL_test_harness.h +134 -0
  77. data/dependencies/SDL/include/SDL_test_images.h +78 -0
  78. data/dependencies/SDL/include/SDL_test_log.h +67 -0
  79. data/dependencies/SDL/include/SDL_test_md5.h +129 -0
  80. data/dependencies/SDL/include/SDL_test_memory.h +63 -0
  81. data/dependencies/SDL/include/SDL_test_random.h +115 -0
  82. data/dependencies/SDL/include/SDL_thread.h +366 -0
  83. data/dependencies/SDL/include/SDL_timer.h +115 -0
  84. data/dependencies/SDL/include/SDL_touch.h +102 -0
  85. data/dependencies/SDL/include/SDL_types.h +29 -0
  86. data/dependencies/SDL/include/SDL_version.h +162 -0
  87. data/dependencies/SDL/include/SDL_video.h +1282 -0
  88. data/dependencies/SDL/include/SDL_vulkan.h +276 -0
  89. data/dependencies/SDL/include/begin_code.h +166 -0
  90. data/dependencies/SDL/include/close_code.h +40 -0
  91. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  92. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  93. data/dependencies/SDL_sound/SDL_sound.c +795 -0
  94. data/dependencies/SDL_sound/SDL_sound.h +725 -0
  95. data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
  96. data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
  97. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
  98. data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
  99. data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
  100. data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
  101. data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
  102. data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
  103. data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
  104. data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
  105. data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
  106. data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
  107. data/dependencies/SDL_sound/dr_flac.h +5906 -0
  108. data/dependencies/SDL_sound/dr_mp3.h +2832 -0
  109. data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
  110. data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
  111. data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
  112. data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
  113. data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
  114. data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
  115. data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
  116. data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
  117. data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
  118. data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
  119. data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
  120. data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
  121. data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
  122. data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
  123. data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
  124. data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
  125. data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
  126. data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
  127. data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
  128. data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
  129. data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
  130. data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
  131. data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
  132. data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
  133. data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
  134. data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
  135. data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
  136. data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
  137. data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
  138. data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
  139. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
  140. data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
  141. data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
  142. data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
  143. data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
  144. data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
  145. data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +128 -23
  146. data/dependencies/al_soft/AL/al.h +655 -0
  147. data/dependencies/al_soft/AL/alc.h +270 -0
  148. data/dependencies/al_soft/AL/alext.h +585 -0
  149. data/dependencies/al_soft/AL/efx-creative.h +3 -0
  150. data/dependencies/al_soft/AL/efx-presets.h +402 -0
  151. data/dependencies/al_soft/AL/efx.h +762 -0
  152. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  153. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  154. data/{src → dependencies/stb}/stb_image.h +476 -176
  155. data/{src → dependencies/stb}/stb_image_write.h +253 -131
  156. data/{src → dependencies/stb}/stb_truetype.h +262 -104
  157. data/{src → dependencies/utf8proc}/utf8proc.c +47 -29
  158. data/{src → dependencies/utf8proc}/utf8proc.h +46 -24
  159. data/{src → dependencies/utf8proc}/utf8proc_data.h +10043 -9609
  160. data/ext/gosu/extconf.rb +53 -39
  161. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  162. data/include/Gosu/Bitmap.hpp +100 -0
  163. data/{Gosu → include/Gosu}/Buttons.hpp +104 -44
  164. data/include/Gosu/Channel.h +25 -0
  165. data/include/Gosu/Color.h +38 -0
  166. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  167. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  168. data/include/Gosu/Font.h +36 -0
  169. data/{Gosu → include/Gosu}/Font.hpp +0 -0
  170. data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
  171. data/include/Gosu/Gosu.h +82 -0
  172. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  173. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  174. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  175. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  176. data/include/Gosu/Image.h +54 -0
  177. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  178. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  179. data/{Gosu → include/Gosu}/Input.hpp +39 -51
  180. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  181. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  182. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  183. data/include/Gosu/Sample.h +19 -0
  184. data/include/Gosu/Song.h +24 -0
  185. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  186. data/include/Gosu/TextInput.h +30 -0
  187. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  188. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  189. data/{Gosu → include/Gosu}/Utility.hpp +15 -4
  190. data/{Gosu → include/Gosu}/Version.hpp +3 -3
  191. data/include/Gosu/Window.h +63 -0
  192. data/{Gosu → include/Gosu}/Window.hpp +23 -25
  193. data/lib/OpenAL32.dll +0 -0
  194. data/lib/SDL2.dll +0 -0
  195. data/lib/gosu.rb +0 -3
  196. data/lib/gosu/compat.rb +9 -4
  197. data/lib/gosu/patches.rb +8 -11
  198. data/lib/gosu/swig_patches.rb +13 -6
  199. data/lib64/OpenAL32.dll +0 -0
  200. data/lib64/SDL2.dll +0 -0
  201. data/rdoc/gosu.rb +114 -21
  202. data/src/Audio.cpp +50 -224
  203. data/src/AudioFile.hpp +20 -37
  204. data/src/AudioFileAudioToolbox.cpp +237 -0
  205. data/src/AudioFileSDLSound.cpp +147 -0
  206. data/src/AudioImpl.cpp +3 -12
  207. data/src/AudioImpl.hpp +3 -1
  208. data/src/Bitmap.cpp +85 -83
  209. data/src/BitmapIO.cpp +52 -58
  210. data/src/ChannelWrapper.cpp +50 -0
  211. data/src/ColorWrapper.cpp +126 -0
  212. data/src/Constants.cpp +338 -0
  213. data/src/Font.cpp +4 -1
  214. data/src/FontWrapper.cpp +74 -0
  215. data/src/GosuWrapper.cpp +251 -0
  216. data/src/Graphics.cpp +11 -5
  217. data/src/GraphicsImpl.hpp +0 -1
  218. data/src/Image.cpp +13 -16
  219. data/src/ImageWrapper.cpp +168 -0
  220. data/src/Input.cpp +412 -164
  221. data/src/LargeImageData.cpp +2 -1
  222. data/src/MarkupParser.cpp +13 -4
  223. data/src/RubyGosu.cxx +502 -219
  224. data/src/RubyGosu.h +4 -2
  225. data/src/SampleWrapper.cpp +30 -0
  226. data/src/SongWrapper.cpp +52 -0
  227. data/src/TexChunk.cpp +29 -19
  228. data/src/Text.cpp +2 -0
  229. data/src/TextBuilder.cpp +6 -4
  230. data/src/TextInputWrapper.cpp +101 -0
  231. data/src/Texture.cpp +1 -1
  232. data/src/TrueTypeFont.cpp +2 -1
  233. data/src/Utility.cpp +11 -7
  234. data/src/Window.cpp +30 -39
  235. data/src/WindowWrapper.cpp +317 -0
  236. metadata +212 -42
  237. data/Gosu/AutoLink.hpp +0 -14
  238. data/Gosu/Bitmap.hpp +0 -113
  239. data/src/AudioToolboxFile.hpp +0 -210
  240. data/src/OggFile.hpp +0 -92
  241. data/src/SndFile.hpp +0 -174
  242. data/src/WinMain.cpp +0 -64
@@ -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
+