koffi 0.9.4 → 0.9.7

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 (823) hide show
  1. package/LICENSE.txt +661 -0
  2. package/README.md +50 -8
  3. package/package.json +24 -6
  4. package/src/call.hh +2 -1
  5. package/src/call_arm32.cc +498 -0
  6. package/src/call_arm32_fwd.S +108 -0
  7. package/src/call_arm64.cc +57 -57
  8. package/src/call_arm64_fwd.S +24 -29
  9. package/src/call_x64_sysv.cc +29 -43
  10. package/src/call_x64_win.cc +37 -40
  11. package/src/call_x86.cc +46 -59
  12. package/src/ffi.cc +29 -27
  13. package/src/ffi.hh +19 -12
  14. package/src/util.cc +58 -24
  15. package/src/util.hh +103 -19
  16. package/test/qemu/.gitkeep +0 -0
  17. package/test/registry/machines.json +112 -0
  18. package/test/registry/sha256sum.txt +21 -0
  19. package/test/test.js +493 -0
  20. package/vendor/dragonbox/CMakeLists.txt +122 -122
  21. package/vendor/dragonbox/LICENSE-Apache2-LLVM +218 -218
  22. package/vendor/dragonbox/LICENSE-Boost +23 -23
  23. package/vendor/dragonbox/README.md +277 -277
  24. package/vendor/dragonbox/cmake/dragonboxConfig.cmake +1 -1
  25. package/vendor/dragonbox/include/dragonbox/dragonbox.h +6 -2
  26. package/vendor/dragonbox/include/dragonbox/dragonbox_to_chars.h +108 -108
  27. package/vendor/dragonbox/other_files/Dragonbox.pdf +0 -0
  28. package/vendor/dragonbox/other_files/unknown_win64_vc2019.html +539 -539
  29. package/vendor/dragonbox/source/dragonbox_to_chars.cpp +303 -303
  30. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/CMakeLists.txt +23 -23
  31. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.cpp +238 -238
  32. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.h +95 -95
  33. package/vendor/dragonbox/subproject/3rdparty/grisu_exact/grisu_exact.h +2666 -2666
  34. package/vendor/dragonbox/subproject/3rdparty/ryu/CMakeLists.txt +16 -16
  35. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/common.h +114 -114
  36. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s.c +509 -509
  37. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_full_table.h +367 -367
  38. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_intrinsics.h +357 -357
  39. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/digit_table.h +35 -35
  40. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s.c +345 -345
  41. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_full_table.h +55 -55
  42. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_intrinsics.h +128 -128
  43. package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/ryu.h +46 -46
  44. package/vendor/dragonbox/subproject/3rdparty/schubfach/CMakeLists.txt +21 -21
  45. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.cc +699 -699
  46. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.h +31 -31
  47. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.cc +1354 -1354
  48. package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.h +31 -31
  49. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/example_shaded_plots.m +68 -68
  50. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/license.txt +25 -25
  51. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution.m +92 -92
  52. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution_prctile.m +121 -121
  53. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_histogram_shaded.m +99 -99
  54. package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_shaded.m +93 -93
  55. package/vendor/dragonbox/subproject/benchmark/CMakeLists.txt +64 -64
  56. package/vendor/dragonbox/subproject/benchmark/include/benchmark.h +40 -40
  57. package/vendor/dragonbox/subproject/benchmark/matlab/plot_benchmarks.m +21 -21
  58. package/vendor/dragonbox/subproject/benchmark/matlab/plot_digit_benchmark.m +78 -78
  59. package/vendor/dragonbox/subproject/benchmark/matlab/plot_uniform_benchmark.m +95 -95
  60. package/vendor/dragonbox/subproject/benchmark/source/benchmark.cpp +237 -237
  61. package/vendor/dragonbox/subproject/benchmark/source/dragonbox.cpp +30 -30
  62. package/vendor/dragonbox/subproject/benchmark/source/grisu_exact.cpp +36 -36
  63. package/vendor/dragonbox/subproject/benchmark/source/ryu.cpp +27 -27
  64. package/vendor/dragonbox/subproject/benchmark/source/schubfach.cpp +31 -31
  65. package/vendor/dragonbox/subproject/common/CMakeLists.txt +41 -41
  66. package/vendor/dragonbox/subproject/common/include/best_rational_approx.h +96 -96
  67. package/vendor/dragonbox/subproject/common/include/big_uint.h +217 -217
  68. package/vendor/dragonbox/subproject/common/include/continued_fractions.h +173 -173
  69. package/vendor/dragonbox/subproject/common/include/good_rational_approx.h +266 -266
  70. package/vendor/dragonbox/subproject/common/include/random_float.h +182 -182
  71. package/vendor/dragonbox/subproject/common/include/rational_continued_fractions.h +56 -56
  72. package/vendor/dragonbox/subproject/common/source/big_uint.cpp +601 -601
  73. package/vendor/dragonbox/subproject/meta/CMakeLists.txt +40 -40
  74. package/vendor/dragonbox/subproject/meta/results/binary32_generated_cache.txt +81 -81
  75. package/vendor/dragonbox/subproject/meta/results/binary64_compressed_cache_error_table.txt +9 -9
  76. package/vendor/dragonbox/subproject/meta/results/binary64_generated_cache.txt +622 -622
  77. package/vendor/dragonbox/subproject/meta/source/generate_cache.cpp +126 -126
  78. package/vendor/dragonbox/subproject/meta/source/live_test.cpp +81 -81
  79. package/vendor/dragonbox/subproject/meta/source/perf_test.cpp +104 -104
  80. package/vendor/dragonbox/subproject/meta/source/sandbox.cpp +20 -20
  81. package/vendor/dragonbox/subproject/test/CMakeLists.txt +69 -69
  82. package/vendor/dragonbox/subproject/test/results/plot_required_bits.m +17 -17
  83. package/vendor/dragonbox/subproject/test/source/test_all_shorter_interval_cases.cpp +88 -88
  84. package/vendor/dragonbox/subproject/test/source/uniform_random_test.cpp +95 -95
  85. package/vendor/dragonbox/subproject/test/source/verify_cache_precision.cpp +337 -337
  86. package/vendor/dragonbox/subproject/test/source/verify_compressed_cache.cpp +154 -154
  87. package/vendor/dragonbox/subproject/test/source/verify_fast_multiplication.cpp +168 -168
  88. package/vendor/dragonbox/subproject/test/source/verify_log_computation.cpp +251 -251
  89. package/vendor/dragonbox/subproject/test/source/verify_magic_division.cpp +113 -113
  90. package/vendor/libcc/libcc.cc +36 -18
  91. package/vendor/libcc/libcc.hh +23 -1
  92. package/vendor/raylib/BINDINGS.md +123 -0
  93. package/vendor/raylib/CHANGELOG +1495 -0
  94. package/vendor/raylib/CMakeLists.txt +33 -0
  95. package/vendor/raylib/CMakeOptions.txt +87 -0
  96. package/vendor/raylib/CONTRIBUTING.md +76 -0
  97. package/vendor/raylib/CONTRIBUTORS.md +63 -0
  98. package/vendor/raylib/CONVENTIONS.md +95 -0
  99. package/vendor/raylib/HISTORY.md +364 -0
  100. package/vendor/raylib/LICENSE +16 -0
  101. package/vendor/raylib/README.md +141 -0
  102. package/vendor/raylib/ROADMAP.md +76 -0
  103. package/vendor/raylib/SPONSORS.md +68 -0
  104. package/vendor/raylib/cmake/AddIfFlagCompiles.cmake +12 -0
  105. package/vendor/raylib/cmake/BuildOptions.cmake +18 -0
  106. package/vendor/raylib/cmake/CompileDefinitions.cmake +110 -0
  107. package/vendor/raylib/cmake/CompilerFlags.cmake +79 -0
  108. package/vendor/raylib/cmake/EnumOption.cmake +9 -0
  109. package/vendor/raylib/cmake/GlfwImport.cmake +34 -0
  110. package/vendor/raylib/cmake/InstallConfigurations.cmake +29 -0
  111. package/vendor/raylib/cmake/JoinPaths.cmake +26 -0
  112. package/vendor/raylib/cmake/LibraryConfigurations.cmake +108 -0
  113. package/vendor/raylib/cmake/LibraryPathToLinkerFlags.cmake +24 -0
  114. package/vendor/raylib/cmake/PackConfigurations.cmake +13 -0
  115. package/vendor/raylib/cmake/PopulateConfigVariablesLocally.cmake +11 -0
  116. package/vendor/raylib/cmake/raylib-config-version.cmake +21 -0
  117. package/vendor/raylib/cmake/raylib-config.cmake +76 -0
  118. package/vendor/raylib/examples/CMakeLists.txt +139 -0
  119. package/vendor/raylib/examples/Makefile +565 -0
  120. package/vendor/raylib/examples/Makefile.Android +405 -0
  121. package/vendor/raylib/examples/Makefile.Web +1053 -0
  122. package/vendor/raylib/examples/README.md +203 -0
  123. package/vendor/raylib/examples/audio/audio_module_playing.c +146 -0
  124. package/vendor/raylib/examples/audio/audio_module_playing.png +0 -0
  125. package/vendor/raylib/examples/audio/audio_multichannel_sound.c +73 -0
  126. package/vendor/raylib/examples/audio/audio_multichannel_sound.png +0 -0
  127. package/vendor/raylib/examples/audio/audio_music_stream.c +93 -0
  128. package/vendor/raylib/examples/audio/audio_music_stream.png +0 -0
  129. package/vendor/raylib/examples/audio/audio_raw_stream.c +167 -0
  130. package/vendor/raylib/examples/audio/audio_raw_stream.png +0 -0
  131. package/vendor/raylib/examples/audio/audio_sound_loading.c +64 -0
  132. package/vendor/raylib/examples/audio/audio_sound_loading.png +0 -0
  133. package/vendor/raylib/examples/audio/resources/LICENSE.md +10 -0
  134. package/vendor/raylib/examples/audio/resources/coin.wav +0 -0
  135. package/vendor/raylib/examples/audio/resources/country.mp3 +0 -0
  136. package/vendor/raylib/examples/audio/resources/mini1111.xm +0 -0
  137. package/vendor/raylib/examples/audio/resources/sound.wav +0 -0
  138. package/vendor/raylib/examples/audio/resources/spring.wav +0 -0
  139. package/vendor/raylib/examples/audio/resources/target.flac +0 -0
  140. package/vendor/raylib/examples/audio/resources/target.ogg +0 -0
  141. package/vendor/raylib/examples/audio/resources/weird.wav +0 -0
  142. package/vendor/raylib/examples/build.zig +86 -0
  143. package/vendor/raylib/examples/core/core_2d_camera.c +132 -0
  144. package/vendor/raylib/examples/core/core_2d_camera.png +0 -0
  145. package/vendor/raylib/examples/core/core_2d_camera_platformer.c +293 -0
  146. package/vendor/raylib/examples/core/core_2d_camera_platformer.png +0 -0
  147. package/vendor/raylib/examples/core/core_2d_camera_smooth_pixelperfect.png +0 -0
  148. package/vendor/raylib/examples/core/core_3d_camera_first_person.c +97 -0
  149. package/vendor/raylib/examples/core/core_3d_camera_first_person.png +0 -0
  150. package/vendor/raylib/examples/core/core_3d_camera_free.c +83 -0
  151. package/vendor/raylib/examples/core/core_3d_camera_free.png +0 -0
  152. package/vendor/raylib/examples/core/core_3d_camera_mode.c +73 -0
  153. package/vendor/raylib/examples/core/core_3d_camera_mode.png +0 -0
  154. package/vendor/raylib/examples/core/core_3d_picking.c +107 -0
  155. package/vendor/raylib/examples/core/core_3d_picking.png +0 -0
  156. package/vendor/raylib/examples/core/core_basic_screen_manager.c +150 -0
  157. package/vendor/raylib/examples/core/core_basic_screen_manager.png +0 -0
  158. package/vendor/raylib/examples/core/core_basic_window.c +62 -0
  159. package/vendor/raylib/examples/core/core_basic_window.png +0 -0
  160. package/vendor/raylib/examples/core/core_basic_window_web.c +85 -0
  161. package/vendor/raylib/examples/core/core_custom_frame_control.c +125 -0
  162. package/vendor/raylib/examples/core/core_custom_frame_control.png +0 -0
  163. package/vendor/raylib/examples/core/core_custom_logging.c +84 -0
  164. package/vendor/raylib/examples/core/core_custom_logging.png +0 -0
  165. package/vendor/raylib/examples/core/core_drop_files.c +76 -0
  166. package/vendor/raylib/examples/core/core_drop_files.png +0 -0
  167. package/vendor/raylib/examples/core/core_input_gamepad.c +195 -0
  168. package/vendor/raylib/examples/core/core_input_gamepad.png +0 -0
  169. package/vendor/raylib/examples/core/core_input_gestures.c +115 -0
  170. package/vendor/raylib/examples/core/core_input_gestures.png +0 -0
  171. package/vendor/raylib/examples/core/core_input_keys.c +59 -0
  172. package/vendor/raylib/examples/core/core_input_keys.png +0 -0
  173. package/vendor/raylib/examples/core/core_input_mouse.c +65 -0
  174. package/vendor/raylib/examples/core/core_input_mouse.png +0 -0
  175. package/vendor/raylib/examples/core/core_input_mouse_wheel.c +58 -0
  176. package/vendor/raylib/examples/core/core_input_mouse_wheel.png +0 -0
  177. package/vendor/raylib/examples/core/core_input_multitouch.c +70 -0
  178. package/vendor/raylib/examples/core/core_input_multitouch.png +0 -0
  179. package/vendor/raylib/examples/core/core_loading_thread.c +147 -0
  180. package/vendor/raylib/examples/core/core_loading_thread.png +0 -0
  181. package/vendor/raylib/examples/core/core_quat_conversion.c +132 -0
  182. package/vendor/raylib/examples/core/core_quat_conversion.png +0 -0
  183. package/vendor/raylib/examples/core/core_random_values.c +67 -0
  184. package/vendor/raylib/examples/core/core_random_values.png +0 -0
  185. package/vendor/raylib/examples/core/core_scissor_test.c +71 -0
  186. package/vendor/raylib/examples/core/core_scissor_test.png +0 -0
  187. package/vendor/raylib/examples/core/core_smooth_pixelperfect.c +117 -0
  188. package/vendor/raylib/examples/core/core_smooth_pixelperfect.png +0 -0
  189. package/vendor/raylib/examples/core/core_split_screen.c +155 -0
  190. package/vendor/raylib/examples/core/core_split_screen.png +0 -0
  191. package/vendor/raylib/examples/core/core_storage_values.c +87 -0
  192. package/vendor/raylib/examples/core/core_storage_values.png +0 -0
  193. package/vendor/raylib/examples/core/core_vr_simulator.c +143 -0
  194. package/vendor/raylib/examples/core/core_vr_simulator.png +0 -0
  195. package/vendor/raylib/examples/core/core_window_flags.c +191 -0
  196. package/vendor/raylib/examples/core/core_window_flags.png +0 -0
  197. package/vendor/raylib/examples/core/core_window_letterbox.c +112 -0
  198. package/vendor/raylib/examples/core/core_window_letterbox.png +0 -0
  199. package/vendor/raylib/examples/core/core_world_screen.c +78 -0
  200. package/vendor/raylib/examples/core/core_world_screen.png +0 -0
  201. package/vendor/raylib/examples/core/resources/LICENSE.md +4 -0
  202. package/vendor/raylib/examples/core/resources/distortion100.fs +52 -0
  203. package/vendor/raylib/examples/core/resources/distortion330.fs +53 -0
  204. package/vendor/raylib/examples/core/resources/ps3.png +0 -0
  205. package/vendor/raylib/examples/core/resources/xbox.png +0 -0
  206. package/vendor/raylib/examples/examples_template.c +100 -0
  207. package/vendor/raylib/examples/models/models_animation.c +114 -0
  208. package/vendor/raylib/examples/models/models_animation.png +0 -0
  209. package/vendor/raylib/examples/models/models_billboard.c +75 -0
  210. package/vendor/raylib/examples/models/models_billboard.png +0 -0
  211. package/vendor/raylib/examples/models/models_box_collisions.c +121 -0
  212. package/vendor/raylib/examples/models/models_box_collisions.png +0 -0
  213. package/vendor/raylib/examples/models/models_cubicmap.c +87 -0
  214. package/vendor/raylib/examples/models/models_cubicmap.png +0 -0
  215. package/vendor/raylib/examples/models/models_first_person_maze.c +122 -0
  216. package/vendor/raylib/examples/models/models_first_person_maze.png +0 -0
  217. package/vendor/raylib/examples/models/models_geometric_shapes.c +80 -0
  218. package/vendor/raylib/examples/models/models_geometric_shapes.png +0 -0
  219. package/vendor/raylib/examples/models/models_heightmap.c +82 -0
  220. package/vendor/raylib/examples/models/models_heightmap.png +0 -0
  221. package/vendor/raylib/examples/models/models_loading.c +146 -0
  222. package/vendor/raylib/examples/models/models_loading.png +0 -0
  223. package/vendor/raylib/examples/models/models_loading_gltf.c +105 -0
  224. package/vendor/raylib/examples/models/models_loading_gltf.png +0 -0
  225. package/vendor/raylib/examples/models/models_loading_vox.c +130 -0
  226. package/vendor/raylib/examples/models/models_loading_vox.png +0 -0
  227. package/vendor/raylib/examples/models/models_mesh_generation.c +179 -0
  228. package/vendor/raylib/examples/models/models_mesh_generation.png +0 -0
  229. package/vendor/raylib/examples/models/models_mesh_picking.c +223 -0
  230. package/vendor/raylib/examples/models/models_mesh_picking.png +0 -0
  231. package/vendor/raylib/examples/models/models_orthographic_projection.c +99 -0
  232. package/vendor/raylib/examples/models/models_orthographic_projection.png +0 -0
  233. package/vendor/raylib/examples/models/models_rlgl_solar_system.c +172 -0
  234. package/vendor/raylib/examples/models/models_rlgl_solar_system.png +0 -0
  235. package/vendor/raylib/examples/models/models_skybox.c +262 -0
  236. package/vendor/raylib/examples/models/models_skybox.png +0 -0
  237. package/vendor/raylib/examples/models/models_waving_cubes.c +112 -0
  238. package/vendor/raylib/examples/models/models_waving_cubes.png +0 -0
  239. package/vendor/raylib/examples/models/models_yaw_pitch_roll.c +117 -0
  240. package/vendor/raylib/examples/models/models_yaw_pitch_roll.png +0 -0
  241. package/vendor/raylib/examples/models/resources/LICENSE.md +23 -0
  242. package/vendor/raylib/examples/models/resources/billboard.png +0 -0
  243. package/vendor/raylib/examples/models/resources/cubicmap.png +0 -0
  244. package/vendor/raylib/examples/models/resources/cubicmap_atlas.png +0 -0
  245. package/vendor/raylib/examples/models/resources/dresden_square_1k.hdr +0 -0
  246. package/vendor/raylib/examples/models/resources/dresden_square_2k.hdr +0 -0
  247. package/vendor/raylib/examples/models/resources/heightmap.png +0 -0
  248. package/vendor/raylib/examples/models/resources/models/gltf/AnimatedMorphCube.glb +0 -0
  249. package/vendor/raylib/examples/models/resources/models/gltf/AnimatedTriangle.gltf +118 -0
  250. package/vendor/raylib/examples/models/resources/models/gltf/BoxAnimated.glb +0 -0
  251. package/vendor/raylib/examples/models/resources/models/gltf/LICENSE +23 -0
  252. package/vendor/raylib/examples/models/resources/models/gltf/girl.glb +0 -0
  253. package/vendor/raylib/examples/models/resources/models/gltf/raylib_32x32.glb +0 -0
  254. package/vendor/raylib/examples/models/resources/models/gltf/rigged_figure.glb +0 -0
  255. package/vendor/raylib/examples/models/resources/models/gltf/vertex_colored_object.glb +0 -0
  256. package/vendor/raylib/examples/models/resources/models/iqm/guy.blend +0 -0
  257. package/vendor/raylib/examples/models/resources/models/iqm/guy.iqm +0 -0
  258. package/vendor/raylib/examples/models/resources/models/iqm/guyanim.iqm +0 -0
  259. package/vendor/raylib/examples/models/resources/models/iqm/guytex.png +0 -0
  260. package/vendor/raylib/examples/models/resources/models/iqm/vertex_colored_object.iqm +0 -0
  261. package/vendor/raylib/examples/models/resources/models/obj/bridge.obj +1725 -0
  262. package/vendor/raylib/examples/models/resources/models/obj/bridge_diffuse.png +0 -0
  263. package/vendor/raylib/examples/models/resources/models/obj/castle.obj +12919 -0
  264. package/vendor/raylib/examples/models/resources/models/obj/castle_diffuse.png +0 -0
  265. package/vendor/raylib/examples/models/resources/models/obj/cube.obj +68 -0
  266. package/vendor/raylib/examples/models/resources/models/obj/cube_diffuse.png +0 -0
  267. package/vendor/raylib/examples/models/resources/models/obj/house.obj +4564 -0
  268. package/vendor/raylib/examples/models/resources/models/obj/house_diffuse.png +0 -0
  269. package/vendor/raylib/examples/models/resources/models/obj/market.obj +7301 -0
  270. package/vendor/raylib/examples/models/resources/models/obj/market_diffuse.png +0 -0
  271. package/vendor/raylib/examples/models/resources/models/obj/plane.obj +10858 -0
  272. package/vendor/raylib/examples/models/resources/models/obj/plane_diffuse.png +0 -0
  273. package/vendor/raylib/examples/models/resources/models/obj/turret.obj +1888 -0
  274. package/vendor/raylib/examples/models/resources/models/obj/turret_diffuse.png +0 -0
  275. package/vendor/raylib/examples/models/resources/models/obj/well.obj +1030 -0
  276. package/vendor/raylib/examples/models/resources/models/obj/well_diffuse.png +0 -0
  277. package/vendor/raylib/examples/models/resources/models/vox/LICENSE +9 -0
  278. package/vendor/raylib/examples/models/resources/models/vox/chr_knight.vox +0 -0
  279. package/vendor/raylib/examples/models/resources/models/vox/chr_sword.vox +0 -0
  280. package/vendor/raylib/examples/models/resources/models/vox/monu9.vox +0 -0
  281. package/vendor/raylib/examples/models/resources/shaders/glsl100/cubemap.fs +29 -0
  282. package/vendor/raylib/examples/models/resources/shaders/glsl100/cubemap.vs +20 -0
  283. package/vendor/raylib/examples/models/resources/shaders/glsl100/skybox.fs +31 -0
  284. package/vendor/raylib/examples/models/resources/shaders/glsl100/skybox.vs +24 -0
  285. package/vendor/raylib/examples/models/resources/shaders/glsl330/cubemap.fs +30 -0
  286. package/vendor/raylib/examples/models/resources/shaders/glsl330/cubemap.vs +20 -0
  287. package/vendor/raylib/examples/models/resources/shaders/glsl330/skybox.fs +30 -0
  288. package/vendor/raylib/examples/models/resources/shaders/glsl330/skybox.vs +24 -0
  289. package/vendor/raylib/examples/models/resources/skybox.png +0 -0
  290. package/vendor/raylib/examples/models/rlights.h +183 -0
  291. package/vendor/raylib/examples/others/easings.h +263 -0
  292. package/vendor/raylib/examples/others/easings_testbed.c +227 -0
  293. package/vendor/raylib/examples/others/embedded_files_loading.c +103 -0
  294. package/vendor/raylib/examples/others/external/include/GLFW/glfw3.h +5538 -0
  295. package/vendor/raylib/examples/others/external/include/GLFW/glfw3native.h +572 -0
  296. package/vendor/raylib/examples/others/external/include/glad.h +5466 -0
  297. package/vendor/raylib/examples/others/external/lib/libglfw3.a +0 -0
  298. package/vendor/raylib/examples/others/raudio_standalone.c +152 -0
  299. package/vendor/raylib/examples/others/raylib_opengl_interop.c +152 -0
  300. package/vendor/raylib/examples/others/raylib_opengl_interop.png +0 -0
  301. package/vendor/raylib/examples/others/resources/audio/country.mp3 +0 -0
  302. package/vendor/raylib/examples/others/resources/audio/target.ogg +0 -0
  303. package/vendor/raylib/examples/others/resources/audio/weird.wav +0 -0
  304. package/vendor/raylib/examples/others/resources/audio_data.h +4893 -0
  305. package/vendor/raylib/examples/others/resources/image_data.h +9848 -0
  306. package/vendor/raylib/examples/others/resources/shaders/glsl100/point_particle.fs +16 -0
  307. package/vendor/raylib/examples/others/resources/shaders/glsl100/point_particle.vs +24 -0
  308. package/vendor/raylib/examples/others/resources/shaders/glsl330/point_particle.fs +17 -0
  309. package/vendor/raylib/examples/others/resources/shaders/glsl330/point_particle.vs +24 -0
  310. package/vendor/raylib/examples/others/resources/shaders/glsl430/gol.glsl +41 -0
  311. package/vendor/raylib/examples/others/resources/shaders/glsl430/gol_render.glsl +29 -0
  312. package/vendor/raylib/examples/others/resources/shaders/glsl430/gol_transfert.glsl +51 -0
  313. package/vendor/raylib/examples/others/rlgl_compute_shader.c +173 -0
  314. package/vendor/raylib/examples/others/rlgl_standalone.c +469 -0
  315. package/vendor/raylib/examples/physics/physics_demo.c +128 -0
  316. package/vendor/raylib/examples/physics/physics_demo.png +0 -0
  317. package/vendor/raylib/examples/physics/physics_friction.c +142 -0
  318. package/vendor/raylib/examples/physics/physics_friction.png +0 -0
  319. package/vendor/raylib/examples/physics/physics_movement.c +128 -0
  320. package/vendor/raylib/examples/physics/physics_movement.png +0 -0
  321. package/vendor/raylib/examples/physics/physics_restitution.c +129 -0
  322. package/vendor/raylib/examples/physics/physics_restitution.png +0 -0
  323. package/vendor/raylib/examples/physics/physics_shatter.c +111 -0
  324. package/vendor/raylib/examples/physics/physics_shatter.png +0 -0
  325. package/vendor/raylib/examples/raylib_compile_execute.bat +32 -0
  326. package/vendor/raylib/examples/raylib_makefile_example.bat +27 -0
  327. package/vendor/raylib/examples/shaders/resources/LICENSE.md +11 -0
  328. package/vendor/raylib/examples/shaders/resources/fudesumi.png +0 -0
  329. package/vendor/raylib/examples/shaders/resources/mask.png +0 -0
  330. package/vendor/raylib/examples/shaders/resources/models/barracks.obj +22251 -0
  331. package/vendor/raylib/examples/shaders/resources/models/barracks_diffuse.png +0 -0
  332. package/vendor/raylib/examples/shaders/resources/models/church.obj +5116 -0
  333. package/vendor/raylib/examples/shaders/resources/models/church_diffuse.png +0 -0
  334. package/vendor/raylib/examples/shaders/resources/models/watermill.obj +5316 -0
  335. package/vendor/raylib/examples/shaders/resources/models/watermill_diffuse.png +0 -0
  336. package/vendor/raylib/examples/shaders/resources/plasma.png +0 -0
  337. package/vendor/raylib/examples/shaders/resources/raysan.png +0 -0
  338. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/base.fs +23 -0
  339. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/base.vs +26 -0
  340. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/base_lighting.vs +59 -0
  341. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/base_lighting_instanced.vs +36 -0
  342. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/bloom.fs +39 -0
  343. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/blur.fs +34 -0
  344. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/color_mix.fs +26 -0
  345. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/cross_hatching.fs +47 -0
  346. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/cross_stitching.fs +57 -0
  347. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/cubes_panning.fs +60 -0
  348. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/depth.fs +26 -0
  349. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/distortion.fs +54 -0
  350. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/dream_vision.fs +37 -0
  351. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/eratosthenes.fs +60 -0
  352. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/fisheye.fs +43 -0
  353. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/fog.fs +94 -0
  354. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/grayscale.fs +25 -0
  355. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/julia_set.fs +83 -0
  356. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/lighting.fs +81 -0
  357. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/mask.fs +24 -0
  358. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/outline.fs +34 -0
  359. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/palette_switch.fs +41 -0
  360. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/pixelizer.fs +32 -0
  361. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/posterization.fs +29 -0
  362. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/predator.fs +31 -0
  363. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/raymarching.fs +431 -0
  364. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/reload.fs +39 -0
  365. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/scanlines.fs +44 -0
  366. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/sobel.fs +40 -0
  367. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/spotlight.fs +77 -0
  368. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/swirl.fs +46 -0
  369. package/vendor/raylib/examples/shaders/resources/shaders/glsl100/wave.fs +36 -0
  370. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/base.fs +22 -0
  371. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/base.vs +26 -0
  372. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/base_lighting.vs +59 -0
  373. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/bloom.fs +37 -0
  374. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/blur.fs +32 -0
  375. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/cross_hatching.fs +45 -0
  376. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/cross_stitching.fs +55 -0
  377. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/distortion.fs +52 -0
  378. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/dream_vision.fs +35 -0
  379. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/fisheye.fs +41 -0
  380. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/fog.fs +92 -0
  381. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/grayscale.fs +23 -0
  382. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/palette_switch.fs +27 -0
  383. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/pixelizer.fs +30 -0
  384. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/posterization.fs +27 -0
  385. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/predator.fs +29 -0
  386. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/scanlines.fs +42 -0
  387. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/sobel.fs +38 -0
  388. package/vendor/raylib/examples/shaders/resources/shaders/glsl120/swirl.fs +44 -0
  389. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/base.fs +25 -0
  390. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/base.vs +26 -0
  391. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/base_lighting.vs +32 -0
  392. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/base_lighting_instanced.vs +36 -0
  393. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/bloom.fs +40 -0
  394. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/blur.fs +35 -0
  395. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/color_mix.fs +27 -0
  396. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/cross_hatching.fs +48 -0
  397. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/cross_stitching.fs +59 -0
  398. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/cubes_panning.fs +61 -0
  399. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/depth.fs +27 -0
  400. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/distortion.fs +56 -0
  401. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/dream_vision.fs +34 -0
  402. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/eratosthenes.fs +59 -0
  403. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/fisheye.fs +40 -0
  404. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/fog.fs +95 -0
  405. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/grayscale.fs +26 -0
  406. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/julia_set.fs +81 -0
  407. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs +82 -0
  408. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/mask.fs +22 -0
  409. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/outline.fs +35 -0
  410. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/overdraw.fs +26 -0
  411. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/palette_switch.fs +30 -0
  412. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/pixelizer.fs +33 -0
  413. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/posterization.fs +31 -0
  414. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/predator.fs +32 -0
  415. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/raymarching.fs +430 -0
  416. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/reload.fs +40 -0
  417. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/scanlines.fs +49 -0
  418. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/sobel.fs +41 -0
  419. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/spotlight.fs +65 -0
  420. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/swirl.fs +47 -0
  421. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/wave.fs +37 -0
  422. package/vendor/raylib/examples/shaders/resources/space.png +0 -0
  423. package/vendor/raylib/examples/shaders/resources/texel_checker.png +0 -0
  424. package/vendor/raylib/examples/shaders/rlights.h +183 -0
  425. package/vendor/raylib/examples/shaders/shaders_basic_lighting.c +152 -0
  426. package/vendor/raylib/examples/shaders/shaders_basic_lighting.png +0 -0
  427. package/vendor/raylib/examples/shaders/shaders_custom_uniform.c +127 -0
  428. package/vendor/raylib/examples/shaders/shaders_custom_uniform.png +0 -0
  429. package/vendor/raylib/examples/shaders/shaders_eratosthenes.c +92 -0
  430. package/vendor/raylib/examples/shaders/shaders_eratosthenes.png +0 -0
  431. package/vendor/raylib/examples/shaders/shaders_fog.c +160 -0
  432. package/vendor/raylib/examples/shaders/shaders_fog.png +0 -0
  433. package/vendor/raylib/examples/shaders/shaders_hot_reloading.c +130 -0
  434. package/vendor/raylib/examples/shaders/shaders_hot_reloading.png +0 -0
  435. package/vendor/raylib/examples/shaders/shaders_julia_set.c +191 -0
  436. package/vendor/raylib/examples/shaders/shaders_julia_set.png +0 -0
  437. package/vendor/raylib/examples/shaders/shaders_mesh_instancing.c +224 -0
  438. package/vendor/raylib/examples/shaders/shaders_mesh_instancing.png +0 -0
  439. package/vendor/raylib/examples/shaders/shaders_model_shader.c +103 -0
  440. package/vendor/raylib/examples/shaders/shaders_model_shader.png +0 -0
  441. package/vendor/raylib/examples/shaders/shaders_multi_sample2d.c +105 -0
  442. package/vendor/raylib/examples/shaders/shaders_multi_sample2d.png +0 -0
  443. package/vendor/raylib/examples/shaders/shaders_palette_switch.c +147 -0
  444. package/vendor/raylib/examples/shaders/shaders_palette_switch.png +0 -0
  445. package/vendor/raylib/examples/shaders/shaders_postprocessing.c +170 -0
  446. package/vendor/raylib/examples/shaders/shaders_postprocessing.png +0 -0
  447. package/vendor/raylib/examples/shaders/shaders_raymarching.c +113 -0
  448. package/vendor/raylib/examples/shaders/shaders_raymarching.png +0 -0
  449. package/vendor/raylib/examples/shaders/shaders_shapes_textures.c +116 -0
  450. package/vendor/raylib/examples/shaders/shaders_shapes_textures.png +0 -0
  451. package/vendor/raylib/examples/shaders/shaders_simple_mask.c +144 -0
  452. package/vendor/raylib/examples/shaders/shaders_simple_mask.png +0 -0
  453. package/vendor/raylib/examples/shaders/shaders_spotlight.c +254 -0
  454. package/vendor/raylib/examples/shaders/shaders_spotlight.png +0 -0
  455. package/vendor/raylib/examples/shaders/shaders_texture_drawing.c +80 -0
  456. package/vendor/raylib/examples/shaders/shaders_texture_drawing.png +0 -0
  457. package/vendor/raylib/examples/shaders/shaders_texture_outline.c +97 -0
  458. package/vendor/raylib/examples/shaders/shaders_texture_outline.png +0 -0
  459. package/vendor/raylib/examples/shaders/shaders_texture_waves.c +110 -0
  460. package/vendor/raylib/examples/shaders/shaders_texture_waves.png +0 -0
  461. package/vendor/raylib/examples/shapes/shapes_basic_shapes.c +78 -0
  462. package/vendor/raylib/examples/shapes/shapes_basic_shapes.png +0 -0
  463. package/vendor/raylib/examples/shapes/shapes_bouncing_ball.c +76 -0
  464. package/vendor/raylib/examples/shapes/shapes_bouncing_ball.png +0 -0
  465. package/vendor/raylib/examples/shapes/shapes_collision_area.c +108 -0
  466. package/vendor/raylib/examples/shapes/shapes_collision_area.png +0 -0
  467. package/vendor/raylib/examples/shapes/shapes_colors_palette.c +99 -0
  468. package/vendor/raylib/examples/shapes/shapes_colors_palette.png +0 -0
  469. package/vendor/raylib/examples/shapes/shapes_draw_circle_sector.c +83 -0
  470. package/vendor/raylib/examples/shapes/shapes_draw_circle_sector.png +0 -0
  471. package/vendor/raylib/examples/shapes/shapes_draw_rectangle_rounded.c +89 -0
  472. package/vendor/raylib/examples/shapes/shapes_draw_rectangle_rounded.png +0 -0
  473. package/vendor/raylib/examples/shapes/shapes_draw_ring.c +96 -0
  474. package/vendor/raylib/examples/shapes/shapes_draw_ring.png +0 -0
  475. package/vendor/raylib/examples/shapes/shapes_easings_ball_anim.c +110 -0
  476. package/vendor/raylib/examples/shapes/shapes_easings_ball_anim.png +0 -0
  477. package/vendor/raylib/examples/shapes/shapes_easings_box_anim.c +136 -0
  478. package/vendor/raylib/examples/shapes/shapes_easings_box_anim.png +0 -0
  479. package/vendor/raylib/examples/shapes/shapes_easings_rectangle_array.c +118 -0
  480. package/vendor/raylib/examples/shapes/shapes_easings_rectangle_array.png +0 -0
  481. package/vendor/raylib/examples/shapes/shapes_following_eyes.c +104 -0
  482. package/vendor/raylib/examples/shapes/shapes_following_eyes.png +0 -0
  483. package/vendor/raylib/examples/shapes/shapes_lines_bezier.c +59 -0
  484. package/vendor/raylib/examples/shapes/shapes_lines_bezier.png +0 -0
  485. package/vendor/raylib/examples/shapes/shapes_logo_raylib.c +56 -0
  486. package/vendor/raylib/examples/shapes/shapes_logo_raylib.png +0 -0
  487. package/vendor/raylib/examples/shapes/shapes_logo_raylib_anim.c +160 -0
  488. package/vendor/raylib/examples/shapes/shapes_logo_raylib_anim.png +0 -0
  489. package/vendor/raylib/examples/shapes/shapes_rectangle_scaling.c +94 -0
  490. package/vendor/raylib/examples/shapes/shapes_rectangle_scaling.png +0 -0
  491. package/vendor/raylib/examples/text/resources/KAISG.ttf +0 -0
  492. package/vendor/raylib/examples/text/resources/LICENSE.md +20 -0
  493. package/vendor/raylib/examples/text/resources/anonymous_pro_bold.ttf +0 -0
  494. package/vendor/raylib/examples/text/resources/custom_alagard.png +0 -0
  495. package/vendor/raylib/examples/text/resources/custom_jupiter_crash.png +0 -0
  496. package/vendor/raylib/examples/text/resources/custom_mecha.png +0 -0
  497. package/vendor/raylib/examples/text/resources/dejavu.fnt +1115 -0
  498. package/vendor/raylib/examples/text/resources/dejavu.png +0 -0
  499. package/vendor/raylib/examples/text/resources/fonts/alagard.png +0 -0
  500. package/vendor/raylib/examples/text/resources/fonts/alpha_beta.png +0 -0
  501. package/vendor/raylib/examples/text/resources/fonts/jupiter_crash.png +0 -0
  502. package/vendor/raylib/examples/text/resources/fonts/mecha.png +0 -0
  503. package/vendor/raylib/examples/text/resources/fonts/pixantiqua.png +0 -0
  504. package/vendor/raylib/examples/text/resources/fonts/pixelplay.png +0 -0
  505. package/vendor/raylib/examples/text/resources/fonts/romulus.png +0 -0
  506. package/vendor/raylib/examples/text/resources/fonts/setback.png +0 -0
  507. package/vendor/raylib/examples/text/resources/noto_cjk.fnt +580 -0
  508. package/vendor/raylib/examples/text/resources/noto_cjk.png +0 -0
  509. package/vendor/raylib/examples/text/resources/pixantiqua.fnt +188 -0
  510. package/vendor/raylib/examples/text/resources/pixantiqua.png +0 -0
  511. package/vendor/raylib/examples/text/resources/pixantiqua.ttf +0 -0
  512. package/vendor/raylib/examples/text/resources/shaders/glsl100/alpha_discard.fs +20 -0
  513. package/vendor/raylib/examples/text/resources/shaders/glsl100/sdf.fs +25 -0
  514. package/vendor/raylib/examples/text/resources/shaders/glsl330/alpha_discard.fs +19 -0
  515. package/vendor/raylib/examples/text/resources/shaders/glsl330/sdf.fs +26 -0
  516. package/vendor/raylib/examples/text/resources/symbola.fnt +191 -0
  517. package/vendor/raylib/examples/text/resources/symbola.png +0 -0
  518. package/vendor/raylib/examples/text/text_draw_3d.c +739 -0
  519. package/vendor/raylib/examples/text/text_draw_3d.png +0 -0
  520. package/vendor/raylib/examples/text/text_font_filters.c +134 -0
  521. package/vendor/raylib/examples/text/text_font_filters.png +0 -0
  522. package/vendor/raylib/examples/text/text_font_loading.c +91 -0
  523. package/vendor/raylib/examples/text/text_font_loading.png +0 -0
  524. package/vendor/raylib/examples/text/text_font_sdf.c +141 -0
  525. package/vendor/raylib/examples/text/text_font_sdf.png +0 -0
  526. package/vendor/raylib/examples/text/text_font_spritefont.c +85 -0
  527. package/vendor/raylib/examples/text/text_font_spritefont.png +0 -0
  528. package/vendor/raylib/examples/text/text_format_text.c +62 -0
  529. package/vendor/raylib/examples/text/text_format_text.png +0 -0
  530. package/vendor/raylib/examples/text/text_input_box.c +127 -0
  531. package/vendor/raylib/examples/text/text_input_box.png +0 -0
  532. package/vendor/raylib/examples/text/text_raylib_fonts.c +105 -0
  533. package/vendor/raylib/examples/text/text_raylib_fonts.png +0 -0
  534. package/vendor/raylib/examples/text/text_rectangle_bounds.c +264 -0
  535. package/vendor/raylib/examples/text/text_rectangle_bounds.png +0 -0
  536. package/vendor/raylib/examples/text/text_unicode.c +465 -0
  537. package/vendor/raylib/examples/text/text_unicode.png +0 -0
  538. package/vendor/raylib/examples/text/text_writing_anim.c +62 -0
  539. package/vendor/raylib/examples/text/text_writing_anim.png +0 -0
  540. package/vendor/raylib/examples/textures/resources/KAISG.ttf +0 -0
  541. package/vendor/raylib/examples/textures/resources/LICENSE.md +18 -0
  542. package/vendor/raylib/examples/textures/resources/boom.wav +0 -0
  543. package/vendor/raylib/examples/textures/resources/button.png +0 -0
  544. package/vendor/raylib/examples/textures/resources/buttonfx.wav +0 -0
  545. package/vendor/raylib/examples/textures/resources/cat.png +0 -0
  546. package/vendor/raylib/examples/textures/resources/custom_jupiter_crash.png +0 -0
  547. package/vendor/raylib/examples/textures/resources/cyberpunk_street_background.png +0 -0
  548. package/vendor/raylib/examples/textures/resources/cyberpunk_street_foreground.png +0 -0
  549. package/vendor/raylib/examples/textures/resources/cyberpunk_street_midground.png +0 -0
  550. package/vendor/raylib/examples/textures/resources/explosion.png +0 -0
  551. package/vendor/raylib/examples/textures/resources/fudesumi.png +0 -0
  552. package/vendor/raylib/examples/textures/resources/fudesumi.raw +0 -0
  553. package/vendor/raylib/examples/textures/resources/ninepatch_button.png +0 -0
  554. package/vendor/raylib/examples/textures/resources/parrots.png +0 -0
  555. package/vendor/raylib/examples/textures/resources/patterns.png +0 -0
  556. package/vendor/raylib/examples/textures/resources/raylib_logo.png +0 -0
  557. package/vendor/raylib/examples/textures/resources/scarfy.png +0 -0
  558. package/vendor/raylib/examples/textures/resources/spark_flame.png +0 -0
  559. package/vendor/raylib/examples/textures/resources/wabbit_alpha.png +0 -0
  560. package/vendor/raylib/examples/textures/textures_background_scrolling.c +87 -0
  561. package/vendor/raylib/examples/textures/textures_background_scrolling.png +0 -0
  562. package/vendor/raylib/examples/textures/textures_blend_modes.c +93 -0
  563. package/vendor/raylib/examples/textures/textures_blend_modes.png +0 -0
  564. package/vendor/raylib/examples/textures/textures_bunnymark.c +120 -0
  565. package/vendor/raylib/examples/textures/textures_bunnymark.png +0 -0
  566. package/vendor/raylib/examples/textures/textures_draw_tiled.c +165 -0
  567. package/vendor/raylib/examples/textures/textures_draw_tiled.png +0 -0
  568. package/vendor/raylib/examples/textures/textures_image_drawing.c +91 -0
  569. package/vendor/raylib/examples/textures/textures_image_drawing.png +0 -0
  570. package/vendor/raylib/examples/textures/textures_image_generation.c +102 -0
  571. package/vendor/raylib/examples/textures/textures_image_generation.png +0 -0
  572. package/vendor/raylib/examples/textures/textures_image_loading.c +64 -0
  573. package/vendor/raylib/examples/textures/textures_image_loading.png +0 -0
  574. package/vendor/raylib/examples/textures/textures_image_processing.c +169 -0
  575. package/vendor/raylib/examples/textures/textures_image_processing.png +0 -0
  576. package/vendor/raylib/examples/textures/textures_image_text.c +83 -0
  577. package/vendor/raylib/examples/textures/textures_image_text.png +0 -0
  578. package/vendor/raylib/examples/textures/textures_logo_raylib.c +57 -0
  579. package/vendor/raylib/examples/textures/textures_logo_raylib.png +0 -0
  580. package/vendor/raylib/examples/textures/textures_mouse_painting.c +221 -0
  581. package/vendor/raylib/examples/textures/textures_mouse_painting.png +0 -0
  582. package/vendor/raylib/examples/textures/textures_npatch_drawing.c +109 -0
  583. package/vendor/raylib/examples/textures/textures_npatch_drawing.png +0 -0
  584. package/vendor/raylib/examples/textures/textures_particles_blending.c +135 -0
  585. package/vendor/raylib/examples/textures/textures_particles_blending.png +0 -0
  586. package/vendor/raylib/examples/textures/textures_polygon.c +100 -0
  587. package/vendor/raylib/examples/textures/textures_polygon.png +0 -0
  588. package/vendor/raylib/examples/textures/textures_raw_data.c +99 -0
  589. package/vendor/raylib/examples/textures/textures_raw_data.png +0 -0
  590. package/vendor/raylib/examples/textures/textures_rectangle.c +99 -0
  591. package/vendor/raylib/examples/textures/textures_rectangle.png +0 -0
  592. package/vendor/raylib/examples/textures/textures_sprite_button.c +97 -0
  593. package/vendor/raylib/examples/textures/textures_sprite_button.png +0 -0
  594. package/vendor/raylib/examples/textures/textures_sprite_explosion.c +120 -0
  595. package/vendor/raylib/examples/textures/textures_sprite_explosion.png +0 -0
  596. package/vendor/raylib/examples/textures/textures_srcrec_dstrec.c +82 -0
  597. package/vendor/raylib/examples/textures/textures_srcrec_dstrec.png +0 -0
  598. package/vendor/raylib/examples/textures/textures_to_image.c +68 -0
  599. package/vendor/raylib/examples/textures/textures_to_image.png +0 -0
  600. package/vendor/raylib/logo/raylib.ico +0 -0
  601. package/vendor/raylib/logo/raylib_128x128.png +0 -0
  602. package/vendor/raylib/logo/raylib_144x144.png +0 -0
  603. package/vendor/raylib/logo/raylib_16x16.png +0 -0
  604. package/vendor/raylib/logo/raylib_180x180.png +0 -0
  605. package/vendor/raylib/logo/raylib_24x24.png +0 -0
  606. package/vendor/raylib/logo/raylib_256x256.png +0 -0
  607. package/vendor/raylib/logo/raylib_32x32.png +0 -0
  608. package/vendor/raylib/logo/raylib_36x36.png +0 -0
  609. package/vendor/raylib/logo/raylib_48x48.png +0 -0
  610. package/vendor/raylib/logo/raylib_512x512.png +0 -0
  611. package/vendor/raylib/logo/raylib_64x64.png +0 -0
  612. package/vendor/raylib/logo/raylib_72x72.png +0 -0
  613. package/vendor/raylib/logo/raylib_96x96.png +0 -0
  614. package/vendor/raylib/logo/raylib_logo_animation.gif +0 -0
  615. package/vendor/raylib/parser/LICENSE +16 -0
  616. package/vendor/raylib/parser/README.md +63 -0
  617. package/vendor/raylib/parser/raylib_api.json +6668 -0
  618. package/vendor/raylib/parser/raylib_api.txt +3568 -0
  619. package/vendor/raylib/parser/raylib_api.xml +2509 -0
  620. package/vendor/raylib/parser/raylib_parser.c +1003 -0
  621. package/vendor/raylib/projects/4coder/Makefile +401 -0
  622. package/vendor/raylib/projects/4coder/Makefile.Android +300 -0
  623. package/vendor/raylib/projects/4coder/main.c +39 -0
  624. package/vendor/raylib/projects/4coder/project.4coder +54 -0
  625. package/vendor/raylib/projects/Builder/README.md +24 -0
  626. package/vendor/raylib/projects/Builder/examples/README.md +1 -0
  627. package/vendor/raylib/projects/Builder/examples/meson.build +25 -0
  628. package/vendor/raylib/projects/Builder/meson.build +25 -0
  629. package/vendor/raylib/projects/CMake/CMakeLists.txt +44 -0
  630. package/vendor/raylib/projects/CMake/core_basic_window.c +62 -0
  631. package/vendor/raylib/projects/CodeBlocks/README.md +22 -0
  632. package/vendor/raylib/projects/CodeBlocks/compiler_settings.png +0 -0
  633. package/vendor/raylib/projects/CodeBlocks/core_basic_window.c +58 -0
  634. package/vendor/raylib/projects/CodeBlocks/core_basic_window.cbp +137 -0
  635. package/vendor/raylib/projects/Geany/core_basic_window.c +52 -0
  636. package/vendor/raylib/projects/Geany/raylib.c.tags +452 -0
  637. package/vendor/raylib/projects/Geany/raylib_compile_execute.bat +21 -0
  638. package/vendor/raylib/projects/Geany/raylib_compile_sources.bat +42 -0
  639. package/vendor/raylib/projects/Geany/raylib_project.geany +41 -0
  640. package/vendor/raylib/projects/Notepad++/README.md +19 -0
  641. package/vendor/raylib/projects/Notepad++/c_raylib.xml +3104 -0
  642. package/vendor/raylib/projects/Notepad++/npes_saved_mingw.txt +0 -0
  643. package/vendor/raylib/projects/Notepad++/npes_saved_tcc.txt +0 -0
  644. package/vendor/raylib/projects/Notepad++/npes_saved_w64devkit.txt +0 -0
  645. package/vendor/raylib/projects/Notepad++/npes_saved_zig.txt +0 -0
  646. package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +3060 -0
  647. package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp_parser.c +150 -0
  648. package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +631 -0
  649. package/vendor/raylib/projects/README.md +18 -0
  650. package/vendor/raylib/projects/SublimeText/README.md +13 -0
  651. package/vendor/raylib/projects/SublimeText/raylib.sublime-build +13 -0
  652. package/vendor/raylib/projects/SublimeText/raylib.sublime-project +8 -0
  653. package/vendor/raylib/projects/VS2019/raylib/raylib.rc +0 -0
  654. package/vendor/raylib/projects/VS2019/raylib/resource.h +14 -0
  655. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.NativeActivity/android_native_app_glue.c +437 -0
  656. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.NativeActivity/android_native_app_glue.h +344 -0
  657. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.NativeActivity/main.c +64 -0
  658. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.Packaging/AndroidManifest.xml +22 -0
  659. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.Packaging/build.xml +90 -0
  660. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.Packaging/project.properties +3 -0
  661. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.Packaging/raylib_android.Packaging.androidproj +134 -0
  662. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.Packaging/res/values/strings.xml +4 -0
  663. package/vendor/raylib/projects/VSCode/.vscode/c_cpp_properties.json +63 -0
  664. package/vendor/raylib/projects/VSCode/.vscode/launch.json +60 -0
  665. package/vendor/raylib/projects/VSCode/.vscode/settings.json +11 -0
  666. package/vendor/raylib/projects/VSCode/.vscode/tasks.json +71 -0
  667. package/vendor/raylib/projects/VSCode/Makefile +408 -0
  668. package/vendor/raylib/projects/VSCode/Makefile.Android +300 -0
  669. package/vendor/raylib/projects/VSCode/main.c +83 -0
  670. package/vendor/raylib/projects/VSCode/main.code-workspace +16 -0
  671. package/vendor/raylib/projects/scripts/README.md +68 -0
  672. package/vendor/raylib/projects/scripts/build-linux.sh +169 -0
  673. package/vendor/raylib/projects/scripts/build-osx.sh +171 -0
  674. package/vendor/raylib/projects/scripts/build-rpi.sh +169 -0
  675. package/vendor/raylib/projects/scripts/build-windows.bat +219 -0
  676. package/vendor/raylib/projects/scripts/core_basic_window.c +61 -0
  677. package/vendor/raylib/raylib.pc.in +13 -0
  678. package/vendor/raylib/src/CMakeLists.txt +121 -0
  679. package/vendor/raylib/src/Makefile +696 -0
  680. package/vendor/raylib/src/build.zig +60 -0
  681. package/vendor/raylib/src/config.h +230 -0
  682. package/vendor/raylib/src/external/cgltf.h +6501 -0
  683. package/vendor/raylib/src/external/dirent.h +183 -0
  684. package/vendor/raylib/src/external/dr_flac.h +12269 -0
  685. package/vendor/raylib/src/external/dr_mp3.h +4787 -0
  686. package/vendor/raylib/src/external/dr_wav.h +8019 -0
  687. package/vendor/raylib/src/external/glad.h +8640 -0
  688. package/vendor/raylib/src/external/glfw/.mailmap +10 -0
  689. package/vendor/raylib/src/external/glfw/CMake/GenerateMappings.cmake +33 -0
  690. package/vendor/raylib/src/external/glfw/CMake/Info.plist.in +38 -0
  691. package/vendor/raylib/src/external/glfw/CMake/MacOSXBundleInfo.plist.in +38 -0
  692. package/vendor/raylib/src/external/glfw/CMake/cmake_uninstall.cmake.in +29 -0
  693. package/vendor/raylib/src/external/glfw/CMake/glfw3.pc.in +13 -0
  694. package/vendor/raylib/src/external/glfw/CMake/glfw3Config.cmake.in +3 -0
  695. package/vendor/raylib/src/external/glfw/CMake/i686-w64-mingw32-clang.cmake +13 -0
  696. package/vendor/raylib/src/external/glfw/CMake/i686-w64-mingw32.cmake +13 -0
  697. package/vendor/raylib/src/external/glfw/CMake/modules/FindEpollShim.cmake +17 -0
  698. package/vendor/raylib/src/external/glfw/CMake/modules/FindOSMesa.cmake +18 -0
  699. package/vendor/raylib/src/external/glfw/CMake/modules/FindWaylandProtocols.cmake +26 -0
  700. package/vendor/raylib/src/external/glfw/CMake/modules/FindXKBCommon.cmake +34 -0
  701. package/vendor/raylib/src/external/glfw/CMake/x86_64-w64-mingw32-clang.cmake +13 -0
  702. package/vendor/raylib/src/external/glfw/CMake/x86_64-w64-mingw32.cmake +13 -0
  703. package/vendor/raylib/src/external/glfw/CMakeLists.txt +323 -0
  704. package/vendor/raylib/src/external/glfw/LICENSE.md +23 -0
  705. package/vendor/raylib/src/external/glfw/README.md +477 -0
  706. package/vendor/raylib/src/external/glfw/deps/getopt.c +230 -0
  707. package/vendor/raylib/src/external/glfw/deps/getopt.h +57 -0
  708. package/vendor/raylib/src/external/glfw/deps/glad/gl.h +3840 -0
  709. package/vendor/raylib/src/external/glfw/deps/glad/khrplatform.h +282 -0
  710. package/vendor/raylib/src/external/glfw/deps/glad/vk_platform.h +92 -0
  711. package/vendor/raylib/src/external/glfw/deps/glad/vulkan.h +3480 -0
  712. package/vendor/raylib/src/external/glfw/deps/glad_gl.c +1791 -0
  713. package/vendor/raylib/src/external/glfw/deps/glad_vulkan.c +593 -0
  714. package/vendor/raylib/src/external/glfw/deps/mingw/_mingw_dxhelper.h +117 -0
  715. package/vendor/raylib/src/external/glfw/deps/mingw/dinput.h +2467 -0
  716. package/vendor/raylib/src/external/glfw/deps/mingw/xinput.h +239 -0
  717. package/vendor/raylib/src/external/glfw/deps/vs2008/stdint.h +247 -0
  718. package/vendor/raylib/src/external/glfw/include/GLFW/glfw3.h +6075 -0
  719. package/vendor/raylib/src/external/glfw/include/GLFW/glfw3native.h +530 -0
  720. package/vendor/raylib/src/external/glfw/src/CMakeLists.txt +246 -0
  721. package/vendor/raylib/src/external/glfw/src/cocoa_init.m +620 -0
  722. package/vendor/raylib/src/external/glfw/src/cocoa_joystick.h +46 -0
  723. package/vendor/raylib/src/external/glfw/src/cocoa_joystick.m +483 -0
  724. package/vendor/raylib/src/external/glfw/src/cocoa_monitor.m +631 -0
  725. package/vendor/raylib/src/external/glfw/src/cocoa_platform.h +206 -0
  726. package/vendor/raylib/src/external/glfw/src/cocoa_time.c +62 -0
  727. package/vendor/raylib/src/external/glfw/src/cocoa_window.m +1923 -0
  728. package/vendor/raylib/src/external/glfw/src/context.c +756 -0
  729. package/vendor/raylib/src/external/glfw/src/egl_context.c +846 -0
  730. package/vendor/raylib/src/external/glfw/src/egl_context.h +229 -0
  731. package/vendor/raylib/src/external/glfw/src/glfw.rc.in +30 -0
  732. package/vendor/raylib/src/external/glfw/src/glfw_config.h.in +58 -0
  733. package/vendor/raylib/src/external/glfw/src/glx_context.c +699 -0
  734. package/vendor/raylib/src/external/glfw/src/glx_context.h +181 -0
  735. package/vendor/raylib/src/external/glfw/src/init.c +357 -0
  736. package/vendor/raylib/src/external/glfw/src/input.c +1406 -0
  737. package/vendor/raylib/src/external/glfw/src/internal.h +799 -0
  738. package/vendor/raylib/src/external/glfw/src/linux_joystick.c +428 -0
  739. package/vendor/raylib/src/external/glfw/src/linux_joystick.h +59 -0
  740. package/vendor/raylib/src/external/glfw/src/mappings.h +1550 -0
  741. package/vendor/raylib/src/external/glfw/src/mappings.h.in +73 -0
  742. package/vendor/raylib/src/external/glfw/src/monitor.c +542 -0
  743. package/vendor/raylib/src/external/glfw/src/nsgl_context.h +66 -0
  744. package/vendor/raylib/src/external/glfw/src/nsgl_context.m +369 -0
  745. package/vendor/raylib/src/external/glfw/src/null_init.c +57 -0
  746. package/vendor/raylib/src/external/glfw/src/null_joystick.c +53 -0
  747. package/vendor/raylib/src/external/glfw/src/null_joystick.h +31 -0
  748. package/vendor/raylib/src/external/glfw/src/null_monitor.c +159 -0
  749. package/vendor/raylib/src/external/glfw/src/null_platform.h +89 -0
  750. package/vendor/raylib/src/external/glfw/src/null_window.c +670 -0
  751. package/vendor/raylib/src/external/glfw/src/osmesa_context.c +372 -0
  752. package/vendor/raylib/src/external/glfw/src/osmesa_context.h +90 -0
  753. package/vendor/raylib/src/external/glfw/src/posix_thread.c +105 -0
  754. package/vendor/raylib/src/external/glfw/src/posix_thread.h +51 -0
  755. package/vendor/raylib/src/external/glfw/src/posix_time.c +90 -0
  756. package/vendor/raylib/src/external/glfw/src/posix_time.h +44 -0
  757. package/vendor/raylib/src/external/glfw/src/vulkan.c +332 -0
  758. package/vendor/raylib/src/external/glfw/src/wgl_context.c +798 -0
  759. package/vendor/raylib/src/external/glfw/src/wgl_context.h +160 -0
  760. package/vendor/raylib/src/external/glfw/src/win32_init.c +636 -0
  761. package/vendor/raylib/src/external/glfw/src/win32_joystick.c +753 -0
  762. package/vendor/raylib/src/external/glfw/src/win32_joystick.h +53 -0
  763. package/vendor/raylib/src/external/glfw/src/win32_monitor.c +537 -0
  764. package/vendor/raylib/src/external/glfw/src/win32_platform.h +462 -0
  765. package/vendor/raylib/src/external/glfw/src/win32_thread.c +99 -0
  766. package/vendor/raylib/src/external/glfw/src/win32_time.c +76 -0
  767. package/vendor/raylib/src/external/glfw/src/win32_window.c +2405 -0
  768. package/vendor/raylib/src/external/glfw/src/window.c +1114 -0
  769. package/vendor/raylib/src/external/glfw/src/wl_init.c +1310 -0
  770. package/vendor/raylib/src/external/glfw/src/wl_monitor.c +231 -0
  771. package/vendor/raylib/src/external/glfw/src/wl_platform.h +352 -0
  772. package/vendor/raylib/src/external/glfw/src/wl_window.c +1814 -0
  773. package/vendor/raylib/src/external/glfw/src/x11_init.c +1500 -0
  774. package/vendor/raylib/src/external/glfw/src/x11_monitor.c +614 -0
  775. package/vendor/raylib/src/external/glfw/src/x11_platform.h +798 -0
  776. package/vendor/raylib/src/external/glfw/src/x11_window.c +3310 -0
  777. package/vendor/raylib/src/external/glfw/src/xkb_unicode.c +942 -0
  778. package/vendor/raylib/src/external/glfw/src/xkb_unicode.h +28 -0
  779. package/vendor/raylib/src/external/jar_mod.h +1596 -0
  780. package/vendor/raylib/src/external/jar_xm.h +2470 -0
  781. package/vendor/raylib/src/external/miniaudio.h +70273 -0
  782. package/vendor/raylib/src/external/msf_gif.h +717 -0
  783. package/vendor/raylib/src/external/par_shapes.h +2155 -0
  784. package/vendor/raylib/src/external/sdefl.h +696 -0
  785. package/vendor/raylib/src/external/sinfl.h +584 -0
  786. package/vendor/raylib/src/external/stb_image.h +7897 -0
  787. package/vendor/raylib/src/external/stb_image_resize.h +2634 -0
  788. package/vendor/raylib/src/external/stb_image_write.h +1724 -0
  789. package/vendor/raylib/src/external/stb_rect_pack.h +623 -0
  790. package/vendor/raylib/src/external/stb_truetype.h +5077 -0
  791. package/vendor/raylib/src/external/stb_vorbis.h +5475 -0
  792. package/vendor/raylib/src/external/tinyobj_loader_c.h +1589 -0
  793. package/vendor/raylib/src/external/vox_loader.h +710 -0
  794. package/vendor/raylib/src/extras/easings.h +263 -0
  795. package/vendor/raylib/src/extras/physac.h +1977 -0
  796. package/vendor/raylib/src/extras/raygui.h +4342 -0
  797. package/vendor/raylib/src/extras/rmem.h +751 -0
  798. package/vendor/raylib/src/raudio.c +2380 -0
  799. package/vendor/raylib/src/raudio.h +198 -0
  800. package/vendor/raylib/src/raylib.dll.rc +27 -0
  801. package/vendor/raylib/src/raylib.dll.rc.data +0 -0
  802. package/vendor/raylib/src/raylib.h +1536 -0
  803. package/vendor/raylib/src/raylib.ico +0 -0
  804. package/vendor/raylib/src/raylib.rc +27 -0
  805. package/vendor/raylib/src/raylib.rc.data +0 -0
  806. package/vendor/raylib/src/raymath.h +1853 -0
  807. package/vendor/raylib/src/rcamera.h +567 -0
  808. package/vendor/raylib/src/rcore.c +6772 -0
  809. package/vendor/raylib/src/rgestures.h +566 -0
  810. package/vendor/raylib/src/rglfw.c +126 -0
  811. package/vendor/raylib/src/rlgl.h +4677 -0
  812. package/vendor/raylib/src/rmodels.c +5041 -0
  813. package/vendor/raylib/src/rshapes.c +1759 -0
  814. package/vendor/raylib/src/rtext.c +1790 -0
  815. package/vendor/raylib/src/rtextures.c +4761 -0
  816. package/vendor/raylib/src/shell.html +328 -0
  817. package/vendor/raylib/src/utils.c +433 -0
  818. package/vendor/raylib/src/utils.h +81 -0
  819. package/vendor/sqlite3/shell.c +23487 -0
  820. package/vendor/sqlite3/sqlite3.c +239246 -0
  821. package/vendor/sqlite3/sqlite3.h +12802 -0
  822. package/vendor/sqlite3/sqlite3ext.h +689 -0
  823. package/CMakeLists.txt +0 -60
@@ -0,0 +1,2380 @@
1
+ /**********************************************************************************************
2
+ *
3
+ * raudio v1.0 - A simple and easy-to-use audio library based on miniaudio
4
+ *
5
+ * FEATURES:
6
+ * - Manage audio device (init/close)
7
+ * - Manage raw audio context
8
+ * - Manage mixing channels
9
+ * - Load and unload audio files
10
+ * - Format wave data (sample rate, size, channels)
11
+ * - Play/Stop/Pause/Resume loaded audio
12
+ *
13
+ * CONFIGURATION:
14
+ *
15
+ * #define RAUDIO_STANDALONE
16
+ * Define to use the module as standalone library (independently of raylib).
17
+ * Required types and functions are defined in the same module.
18
+ *
19
+ * #define SUPPORT_FILEFORMAT_WAV
20
+ * #define SUPPORT_FILEFORMAT_OGG
21
+ * #define SUPPORT_FILEFORMAT_XM
22
+ * #define SUPPORT_FILEFORMAT_MOD
23
+ * #define SUPPORT_FILEFORMAT_FLAC
24
+ * #define SUPPORT_FILEFORMAT_MP3
25
+ * Selected desired fileformats to be supported for loading. Some of those formats are
26
+ * supported by default, to remove support, just comment unrequired #define in this module
27
+ *
28
+ * DEPENDENCIES:
29
+ * miniaudio.h - Audio device management lib (https://github.com/mackron/miniaudio)
30
+ * stb_vorbis.h - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
31
+ * dr_wav.h - WAV audio files loading (http://github.com/mackron/dr_libs)
32
+ * dr_mp3.h - MP3 audio file loading (https://github.com/mackron/dr_libs)
33
+ * dr_flac.h - FLAC audio file loading (https://github.com/mackron/dr_libs)
34
+ * jar_xm.h - XM module file loading
35
+ * jar_mod.h - MOD audio file loading
36
+ *
37
+ * CONTRIBUTORS:
38
+ * David Reid (github: @mackron) (Nov. 2017):
39
+ * - Complete port to miniaudio library
40
+ *
41
+ * Joshua Reisenauer (github: @kd7tck) (2015)
42
+ * - XM audio module support (jar_xm)
43
+ * - MOD audio module support (jar_mod)
44
+ * - Mixing channels support
45
+ * - Raw audio context support
46
+ *
47
+ *
48
+ * LICENSE: zlib/libpng
49
+ *
50
+ * Copyright (c) 2013-2021 Ramon Santamaria (@raysan5)
51
+ *
52
+ * This software is provided "as-is", without any express or implied warranty. In no event
53
+ * will the authors be held liable for any damages arising from the use of this software.
54
+ *
55
+ * Permission is granted to anyone to use this software for any purpose, including commercial
56
+ * applications, and to alter it and redistribute it freely, subject to the following restrictions:
57
+ *
58
+ * 1. The origin of this software must not be misrepresented; you must not claim that you
59
+ * wrote the original software. If you use this software in a product, an acknowledgment
60
+ * in the product documentation would be appreciated but is not required.
61
+ *
62
+ * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
63
+ * as being the original software.
64
+ *
65
+ * 3. This notice may not be removed or altered from any source distribution.
66
+ *
67
+ **********************************************************************************************/
68
+
69
+ #if defined(RAUDIO_STANDALONE)
70
+ #include "raudio.h"
71
+ #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
72
+ #else
73
+ #include "raylib.h" // Declares module functions
74
+ // Check if config flags have been externally provided on compilation line
75
+ #if !defined(EXTERNAL_CONFIG_FLAGS)
76
+ #include "config.h" // Defines module configuration flags
77
+ #endif
78
+ #include "utils.h" // Required for: fopen() Android mapping
79
+ #endif
80
+
81
+ #if defined(_WIN32)
82
+ // To avoid conflicting windows.h symbols with raylib, some flags are defined
83
+ // WARNING: Those flags avoid inclusion of some Win32 headers that could be required
84
+ // by user at some point and won't be included...
85
+ //-------------------------------------------------------------------------------------
86
+
87
+ // If defined, the following flags inhibit definition of the indicated items.
88
+ #define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
89
+ #define NOVIRTUALKEYCODES // VK_*
90
+ #define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_*
91
+ #define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
92
+ #define NOSYSMETRICS // SM_*
93
+ #define NOMENUS // MF_*
94
+ #define NOICONS // IDI_*
95
+ #define NOKEYSTATES // MK_*
96
+ #define NOSYSCOMMANDS // SC_*
97
+ #define NORASTEROPS // Binary and Tertiary raster ops
98
+ #define NOSHOWWINDOW // SW_*
99
+ #define OEMRESOURCE // OEM Resource values
100
+ #define NOATOM // Atom Manager routines
101
+ #define NOCLIPBOARD // Clipboard routines
102
+ #define NOCOLOR // Screen colors
103
+ #define NOCTLMGR // Control and Dialog routines
104
+ #define NODRAWTEXT // DrawText() and DT_*
105
+ #define NOGDI // All GDI defines and routines
106
+ #define NOKERNEL // All KERNEL defines and routines
107
+ #define NOUSER // All USER defines and routines
108
+ //#define NONLS // All NLS defines and routines
109
+ #define NOMB // MB_* and MessageBox()
110
+ #define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines
111
+ #define NOMETAFILE // typedef METAFILEPICT
112
+ #define NOMINMAX // Macros min(a,b) and max(a,b)
113
+ #define NOMSG // typedef MSG and associated routines
114
+ #define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
115
+ #define NOSCROLL // SB_* and scrolling routines
116
+ #define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc.
117
+ #define NOSOUND // Sound driver routines
118
+ #define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines
119
+ #define NOWH // SetWindowsHook and WH_*
120
+ #define NOWINOFFSETS // GWL_*, GCL_*, associated routines
121
+ #define NOCOMM // COMM driver routines
122
+ #define NOKANJI // Kanji support stuff.
123
+ #define NOHELP // Help engine interface.
124
+ #define NOPROFILER // Profiler interface.
125
+ #define NODEFERWINDOWPOS // DeferWindowPos routines
126
+ #define NOMCX // Modem Configuration Extensions
127
+
128
+ // Type required before windows.h inclusion
129
+ typedef struct tagMSG *LPMSG;
130
+
131
+ #include <windows.h> // Windows functionality (miniaudio)
132
+
133
+ // Type required by some unused function...
134
+ typedef struct tagBITMAPINFOHEADER {
135
+ DWORD biSize;
136
+ LONG biWidth;
137
+ LONG biHeight;
138
+ WORD biPlanes;
139
+ WORD biBitCount;
140
+ DWORD biCompression;
141
+ DWORD biSizeImage;
142
+ LONG biXPelsPerMeter;
143
+ LONG biYPelsPerMeter;
144
+ DWORD biClrUsed;
145
+ DWORD biClrImportant;
146
+ } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
147
+
148
+ #include <objbase.h> // Component Object Model (COM) header
149
+ #include <mmreg.h> // Windows Multimedia, defines some WAVE structs
150
+ #include <mmsystem.h> // Windows Multimedia, used by Windows GDI, defines DIBINDEX macro
151
+
152
+ // Some required types defined for MSVC/TinyC compiler
153
+ #if defined(_MSC_VER) || defined(__TINYC__)
154
+ #include "propidl.h"
155
+ #endif
156
+ #endif
157
+
158
+ #define MA_MALLOC RL_MALLOC
159
+ #define MA_FREE RL_FREE
160
+
161
+ #define MA_NO_JACK
162
+ #define MA_NO_WAV
163
+ #define MA_NO_FLAC
164
+ #define MA_NO_MP3
165
+ #define MINIAUDIO_IMPLEMENTATION
166
+ //#define MA_DEBUG_OUTPUT
167
+ #include "external/miniaudio.h" // Audio device initialization and management
168
+ #undef PlaySound // Win32 API: windows.h > mmsystem.h defines PlaySound macro
169
+
170
+ #include <stdlib.h> // Required for: malloc(), free()
171
+ #include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
172
+
173
+ #if defined(RAUDIO_STANDALONE)
174
+ #include <string.h> // Required for: strcmp() [Used in IsFileExtension()]
175
+
176
+ #ifndef TRACELOG
177
+ #define TRACELOG(level, ...) (void)0
178
+ #endif
179
+
180
+ // Allow custom memory allocators
181
+ #ifndef RL_MALLOC
182
+ #define RL_MALLOC(sz) malloc(sz)
183
+ #endif
184
+ #ifndef RL_CALLOC
185
+ #define RL_CALLOC(n,sz) calloc(n,sz)
186
+ #endif
187
+ #ifndef RL_REALLOC
188
+ #define RL_REALLOC(ptr,sz) realloc(ptr,sz)
189
+ #endif
190
+ #ifndef RL_FREE
191
+ #define RL_FREE(ptr) free(ptr)
192
+ #endif
193
+ #endif
194
+
195
+ #if defined(SUPPORT_FILEFORMAT_OGG)
196
+ // TODO: Remap stb_vorbis malloc()/free() calls to RL_MALLOC/RL_FREE
197
+
198
+ #define STB_VORBIS_IMPLEMENTATION
199
+ #include "external/stb_vorbis.h" // OGG loading functions
200
+ #endif
201
+
202
+ #if defined(SUPPORT_FILEFORMAT_XM)
203
+ #define JARXM_MALLOC RL_MALLOC
204
+ #define JARXM_FREE RL_FREE
205
+
206
+ #define JAR_XM_IMPLEMENTATION
207
+ #include "external/jar_xm.h" // XM loading functions
208
+ #endif
209
+
210
+ #if defined(SUPPORT_FILEFORMAT_MOD)
211
+ #define JARMOD_MALLOC RL_MALLOC
212
+ #define JARMOD_FREE RL_FREE
213
+
214
+ #define JAR_MOD_IMPLEMENTATION
215
+ #include "external/jar_mod.h" // MOD loading functions
216
+ #endif
217
+
218
+ #if defined(SUPPORT_FILEFORMAT_WAV)
219
+ #define DRWAV_MALLOC RL_MALLOC
220
+ #define DRWAV_REALLOC RL_REALLOC
221
+ #define DRWAV_FREE RL_FREE
222
+
223
+ #define DR_WAV_IMPLEMENTATION
224
+ #include "external/dr_wav.h" // WAV loading functions
225
+ #endif
226
+
227
+ #if defined(SUPPORT_FILEFORMAT_MP3)
228
+ #define DRMP3_MALLOC RL_MALLOC
229
+ #define DRMP3_REALLOC RL_REALLOC
230
+ #define DRMP3_FREE RL_FREE
231
+
232
+ #define DR_MP3_IMPLEMENTATION
233
+ #include "external/dr_mp3.h" // MP3 loading functions
234
+ #endif
235
+
236
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
237
+ #define DRFLAC_MALLOC RL_MALLOC
238
+ #define DRFLAC_REALLOC RL_REALLOC
239
+ #define DRFLAC_FREE RL_FREE
240
+
241
+ #define DR_FLAC_IMPLEMENTATION
242
+ #define DR_FLAC_NO_WIN32_IO
243
+ #include "external/dr_flac.h" // FLAC loading functions
244
+ #endif
245
+
246
+ #if defined(_MSC_VER)
247
+ #undef bool
248
+ #endif
249
+
250
+ //----------------------------------------------------------------------------------
251
+ // Defines and Macros
252
+ //----------------------------------------------------------------------------------
253
+ #ifndef AUDIO_DEVICE_FORMAT
254
+ #define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (float-32bit)
255
+ #endif
256
+ #ifndef AUDIO_DEVICE_CHANNELS
257
+ #define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo
258
+ #endif
259
+ #ifndef AUDIO_DEVICE_SAMPLE_RATE
260
+ #define AUDIO_DEVICE_SAMPLE_RATE 0 // Device output sample rate
261
+ #endif
262
+
263
+ #ifndef MAX_AUDIO_BUFFER_POOL_CHANNELS
264
+ #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Audio pool channels
265
+ #endif
266
+ #ifndef DEFAULT_AUDIO_BUFFER_SIZE
267
+ #define DEFAULT_AUDIO_BUFFER_SIZE 4096 // Default audio buffer size
268
+ #endif
269
+
270
+
271
+ //----------------------------------------------------------------------------------
272
+ // Types and Structures Definition
273
+ //----------------------------------------------------------------------------------
274
+
275
+ // Music context type
276
+ // NOTE: Depends on data structure provided by the library
277
+ // in charge of reading the different file types
278
+ typedef enum {
279
+ MUSIC_AUDIO_NONE = 0, // No audio context loaded
280
+ MUSIC_AUDIO_WAV, // WAV audio context
281
+ MUSIC_AUDIO_OGG, // OGG audio context
282
+ MUSIC_AUDIO_FLAC, // FLAC audio context
283
+ MUSIC_AUDIO_MP3, // MP3 audio context
284
+ MUSIC_MODULE_XM, // XM module audio context
285
+ MUSIC_MODULE_MOD // MOD module audio context
286
+ } MusicContextType;
287
+
288
+ #if defined(RAUDIO_STANDALONE)
289
+ // Trace log level
290
+ // NOTE: Organized by priority level
291
+ typedef enum {
292
+ LOG_ALL = 0, // Display all logs
293
+ LOG_TRACE, // Trace logging, intended for internal use only
294
+ LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds
295
+ LOG_INFO, // Info logging, used for program execution info
296
+ LOG_WARNING, // Warning logging, used on recoverable failures
297
+ LOG_ERROR, // Error logging, used on unrecoverable failures
298
+ LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE)
299
+ LOG_NONE // Disable logging
300
+ } TraceLogLevel;
301
+ #endif
302
+
303
+ // NOTE: Different logic is used when feeding data to the playback device
304
+ // depending on whether or not data is streamed (Music vs Sound)
305
+ typedef enum {
306
+ AUDIO_BUFFER_USAGE_STATIC = 0,
307
+ AUDIO_BUFFER_USAGE_STREAM
308
+ } AudioBufferUsage;
309
+
310
+ // Audio buffer structure
311
+ struct rAudioBuffer {
312
+ ma_data_converter converter; // Audio data converter
313
+
314
+ float volume; // Audio buffer volume
315
+ float pitch; // Audio buffer pitch
316
+
317
+ bool playing; // Audio buffer state: AUDIO_PLAYING
318
+ bool paused; // Audio buffer state: AUDIO_PAUSED
319
+ bool looping; // Audio buffer looping, always true for AudioStreams
320
+ int usage; // Audio buffer usage mode: STATIC or STREAM
321
+
322
+ bool isSubBufferProcessed[2]; // SubBuffer processed (virtual double buffer)
323
+ unsigned int sizeInFrames; // Total buffer size in frames
324
+ unsigned int frameCursorPos; // Frame cursor position
325
+ unsigned int framesProcessed; // Total frames processed in this buffer (required for play timing)
326
+
327
+ unsigned char *data; // Data buffer, on music stream keeps filling
328
+
329
+ rAudioBuffer *next; // Next audio buffer on the list
330
+ rAudioBuffer *prev; // Previous audio buffer on the list
331
+ };
332
+
333
+ #define AudioBuffer rAudioBuffer // HACK: To avoid CoreAudio (macOS) symbol collision
334
+
335
+ // Audio data context
336
+ typedef struct AudioData {
337
+ struct {
338
+ ma_context context; // miniaudio context data
339
+ ma_device device; // miniaudio device
340
+ ma_mutex lock; // miniaudio mutex lock
341
+ bool isReady; // Check if audio device is ready
342
+ } System;
343
+ struct {
344
+ AudioBuffer *first; // Pointer to first AudioBuffer in the list
345
+ AudioBuffer *last; // Pointer to last AudioBuffer in the list
346
+ int defaultSize; // Default audio buffer size for audio streams
347
+ } Buffer;
348
+ struct {
349
+ unsigned int poolCounter; // AudioBuffer pointers pool counter
350
+ AudioBuffer *pool[MAX_AUDIO_BUFFER_POOL_CHANNELS]; // Multichannel AudioBuffer pointers pool
351
+ unsigned int channels[MAX_AUDIO_BUFFER_POOL_CHANNELS]; // AudioBuffer pool channels
352
+ } MultiChannel;
353
+ } AudioData;
354
+
355
+ //----------------------------------------------------------------------------------
356
+ // Global Variables Definition
357
+ //----------------------------------------------------------------------------------
358
+ static AudioData AUDIO = { // Global AUDIO context
359
+
360
+ // NOTE: Music buffer size is defined by number of samples, independent of sample size and channels number
361
+ // After some math, considering a sampleRate of 48000, a buffer refill rate of 1/60 seconds and a
362
+ // standard double-buffering system, a 4096 samples buffer has been chosen, it should be enough
363
+ // In case of music-stalls, just increase this number
364
+ .Buffer.defaultSize = 0
365
+ };
366
+
367
+ //----------------------------------------------------------------------------------
368
+ // Module specific Functions Declaration
369
+ //----------------------------------------------------------------------------------
370
+ static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message);
371
+ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount);
372
+ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, float localVolume);
373
+
374
+ #if defined(RAUDIO_STANDALONE)
375
+ static bool IsFileExtension(const char *fileName, const char *ext); // Check file extension
376
+ static const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes the dot: .png)
377
+ static bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
378
+ static const char *TextToLower(const char *text); // Get lower case version of provided string
379
+
380
+ static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
381
+ static bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write)
382
+ static bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated
383
+ #endif
384
+
385
+ //----------------------------------------------------------------------------------
386
+ // AudioBuffer management functions declaration
387
+ // NOTE: Those functions are not exposed by raylib... for the moment
388
+ //----------------------------------------------------------------------------------
389
+ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 sizeInFrames, int usage);
390
+ void UnloadAudioBuffer(AudioBuffer *buffer);
391
+
392
+ bool IsAudioBufferPlaying(AudioBuffer *buffer);
393
+ void PlayAudioBuffer(AudioBuffer *buffer);
394
+ void StopAudioBuffer(AudioBuffer *buffer);
395
+ void PauseAudioBuffer(AudioBuffer *buffer);
396
+ void ResumeAudioBuffer(AudioBuffer *buffer);
397
+ void SetAudioBufferVolume(AudioBuffer *buffer, float volume);
398
+ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch);
399
+ void TrackAudioBuffer(AudioBuffer *buffer);
400
+ void UntrackAudioBuffer(AudioBuffer *buffer);
401
+
402
+ //----------------------------------------------------------------------------------
403
+ // Module Functions Definition - Audio Device initialization and Closing
404
+ //----------------------------------------------------------------------------------
405
+ // Initialize audio device
406
+ void InitAudioDevice(void)
407
+ {
408
+ // Init audio context
409
+ ma_context_config ctxConfig = ma_context_config_init();
410
+ ctxConfig.logCallback = OnLog;
411
+
412
+ ma_result result = ma_context_init(NULL, 0, &ctxConfig, &AUDIO.System.context);
413
+ if (result != MA_SUCCESS)
414
+ {
415
+ TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize context");
416
+ return;
417
+ }
418
+
419
+ // Init audio device
420
+ // NOTE: Using the default device. Format is floating point because it simplifies mixing.
421
+ ma_device_config config = ma_device_config_init(ma_device_type_playback);
422
+ config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device.
423
+ config.playback.format = AUDIO_DEVICE_FORMAT;
424
+ config.playback.channels = AUDIO_DEVICE_CHANNELS;
425
+ config.capture.pDeviceID = NULL; // NULL for the default capture AUDIO.System.device.
426
+ config.capture.format = ma_format_s16;
427
+ config.capture.channels = 1;
428
+ config.sampleRate = AUDIO_DEVICE_SAMPLE_RATE;
429
+ config.dataCallback = OnSendAudioDataToDevice;
430
+ config.pUserData = NULL;
431
+
432
+ result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device);
433
+ if (result != MA_SUCCESS)
434
+ {
435
+ TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize playback device");
436
+ ma_context_uninit(&AUDIO.System.context);
437
+ return;
438
+ }
439
+
440
+ // Keep the device running the whole time. May want to consider doing something a bit smarter and only have the device running
441
+ // while there's at least one sound being played.
442
+ result = ma_device_start(&AUDIO.System.device);
443
+ if (result != MA_SUCCESS)
444
+ {
445
+ TRACELOG(LOG_WARNING, "AUDIO: Failed to start playback device");
446
+ ma_device_uninit(&AUDIO.System.device);
447
+ ma_context_uninit(&AUDIO.System.context);
448
+ return;
449
+ }
450
+
451
+ // Mixing happens on a seperate thread which means we need to synchronize. I'm using a mutex here to make things simple, but may
452
+ // want to look at something a bit smarter later on to keep everything real-time, if that's necessary.
453
+ if (ma_mutex_init(&AUDIO.System.lock) != MA_SUCCESS)
454
+ {
455
+ TRACELOG(LOG_WARNING, "AUDIO: Failed to create mutex for mixing");
456
+ ma_device_uninit(&AUDIO.System.device);
457
+ ma_context_uninit(&AUDIO.System.context);
458
+ return;
459
+ }
460
+
461
+ // Init dummy audio buffers pool for multichannel sound playing
462
+ for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
463
+ {
464
+ // WARNING: An empty audio buffer is created (data = 0)
465
+ // AudioBuffer data just points to loaded sound data
466
+ AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
467
+ }
468
+
469
+ TRACELOG(LOG_INFO, "AUDIO: Device initialized successfully");
470
+ TRACELOG(LOG_INFO, " > Backend: miniaudio / %s", ma_get_backend_name(AUDIO.System.context.backend));
471
+ TRACELOG(LOG_INFO, " > Format: %s -> %s", ma_get_format_name(AUDIO.System.device.playback.format), ma_get_format_name(AUDIO.System.device.playback.internalFormat));
472
+ TRACELOG(LOG_INFO, " > Channels: %d -> %d", AUDIO.System.device.playback.channels, AUDIO.System.device.playback.internalChannels);
473
+ TRACELOG(LOG_INFO, " > Sample rate: %d -> %d", AUDIO.System.device.sampleRate, AUDIO.System.device.playback.internalSampleRate);
474
+ TRACELOG(LOG_INFO, " > Periods size: %d", AUDIO.System.device.playback.internalPeriodSizeInFrames*AUDIO.System.device.playback.internalPeriods);
475
+
476
+ AUDIO.System.isReady = true;
477
+ }
478
+
479
+ // Close the audio device for all contexts
480
+ void CloseAudioDevice(void)
481
+ {
482
+ if (AUDIO.System.isReady)
483
+ {
484
+ // Unload dummy audio buffers pool
485
+ // WARNING: They can be pointing to already unloaded data
486
+ for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
487
+ {
488
+ //UnloadAudioBuffer(AUDIO.MultiChannel.pool[i]);
489
+ if (AUDIO.MultiChannel.pool[i] != NULL)
490
+ {
491
+ ma_data_converter_uninit(&AUDIO.MultiChannel.pool[i]->converter);
492
+ UntrackAudioBuffer(AUDIO.MultiChannel.pool[i]);
493
+ //RL_FREE(buffer->data); // Already unloaded by UnloadSound()
494
+ RL_FREE(AUDIO.MultiChannel.pool[i]);
495
+ }
496
+ }
497
+
498
+ ma_mutex_uninit(&AUDIO.System.lock);
499
+ ma_device_uninit(&AUDIO.System.device);
500
+ ma_context_uninit(&AUDIO.System.context);
501
+
502
+ AUDIO.System.isReady = false;
503
+
504
+ TRACELOG(LOG_INFO, "AUDIO: Device closed successfully");
505
+ }
506
+ else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized");
507
+ }
508
+
509
+ // Check if device has been initialized successfully
510
+ bool IsAudioDeviceReady(void)
511
+ {
512
+ return AUDIO.System.isReady;
513
+ }
514
+
515
+ // Set master volume (listener)
516
+ void SetMasterVolume(float volume)
517
+ {
518
+ ma_device_set_master_volume(&AUDIO.System.device, volume);
519
+ }
520
+
521
+ //----------------------------------------------------------------------------------
522
+ // Module Functions Definition - Audio Buffer management
523
+ //----------------------------------------------------------------------------------
524
+
525
+ // Initialize a new audio buffer (filled with silence)
526
+ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 sizeInFrames, int usage)
527
+ {
528
+ AudioBuffer *audioBuffer = (AudioBuffer *)RL_CALLOC(1, sizeof(AudioBuffer));
529
+
530
+ if (audioBuffer == NULL)
531
+ {
532
+ TRACELOG(LOG_WARNING, "AUDIO: Failed to allocate memory for buffer");
533
+ return NULL;
534
+ }
535
+
536
+ if (sizeInFrames > 0) audioBuffer->data = RL_CALLOC(sizeInFrames*channels*ma_get_bytes_per_sample(format), 1);
537
+
538
+ // Audio data runs through a format converter
539
+ ma_data_converter_config converterConfig = ma_data_converter_config_init(format, AUDIO_DEVICE_FORMAT, channels, AUDIO_DEVICE_CHANNELS, sampleRate, AUDIO.System.device.sampleRate);
540
+ converterConfig.resampling.allowDynamicSampleRate = true; // Pitch shifting
541
+
542
+ ma_result result = ma_data_converter_init(&converterConfig, &audioBuffer->converter);
543
+
544
+ if (result != MA_SUCCESS)
545
+ {
546
+ TRACELOG(LOG_WARNING, "AUDIO: Failed to create data conversion pipeline");
547
+ RL_FREE(audioBuffer);
548
+ return NULL;
549
+ }
550
+
551
+ // Init audio buffer values
552
+ audioBuffer->volume = 1.0f;
553
+ audioBuffer->pitch = 1.0f;
554
+ audioBuffer->playing = false;
555
+ audioBuffer->paused = false;
556
+ audioBuffer->looping = false;
557
+ audioBuffer->usage = usage;
558
+ audioBuffer->frameCursorPos = 0;
559
+ audioBuffer->sizeInFrames = sizeInFrames;
560
+
561
+ // Buffers should be marked as processed by default so that a call to
562
+ // UpdateAudioStream() immediately after initialization works correctly
563
+ audioBuffer->isSubBufferProcessed[0] = true;
564
+ audioBuffer->isSubBufferProcessed[1] = true;
565
+
566
+ // Track audio buffer to linked list next position
567
+ TrackAudioBuffer(audioBuffer);
568
+
569
+ return audioBuffer;
570
+ }
571
+
572
+ // Delete an audio buffer
573
+ void UnloadAudioBuffer(AudioBuffer *buffer)
574
+ {
575
+ if (buffer != NULL)
576
+ {
577
+ ma_data_converter_uninit(&buffer->converter);
578
+ UntrackAudioBuffer(buffer);
579
+ RL_FREE(buffer->data);
580
+ RL_FREE(buffer);
581
+ }
582
+ }
583
+
584
+ // Check if an audio buffer is playing
585
+ bool IsAudioBufferPlaying(AudioBuffer *buffer)
586
+ {
587
+ bool result = false;
588
+
589
+ if (buffer != NULL) result = (buffer->playing && !buffer->paused);
590
+
591
+ return result;
592
+ }
593
+
594
+ // Play an audio buffer
595
+ // NOTE: Buffer is restarted to the start.
596
+ // Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained.
597
+ void PlayAudioBuffer(AudioBuffer *buffer)
598
+ {
599
+ if (buffer != NULL)
600
+ {
601
+ buffer->playing = true;
602
+ buffer->paused = false;
603
+ buffer->frameCursorPos = 0;
604
+ }
605
+ }
606
+
607
+ // Stop an audio buffer
608
+ void StopAudioBuffer(AudioBuffer *buffer)
609
+ {
610
+ if (buffer != NULL)
611
+ {
612
+ if (IsAudioBufferPlaying(buffer))
613
+ {
614
+ buffer->playing = false;
615
+ buffer->paused = false;
616
+ buffer->frameCursorPos = 0;
617
+ buffer->framesProcessed = 0;
618
+ buffer->isSubBufferProcessed[0] = true;
619
+ buffer->isSubBufferProcessed[1] = true;
620
+ }
621
+ }
622
+ }
623
+
624
+ // Pause an audio buffer
625
+ void PauseAudioBuffer(AudioBuffer *buffer)
626
+ {
627
+ if (buffer != NULL) buffer->paused = true;
628
+ }
629
+
630
+ // Resume an audio buffer
631
+ void ResumeAudioBuffer(AudioBuffer *buffer)
632
+ {
633
+ if (buffer != NULL) buffer->paused = false;
634
+ }
635
+
636
+ // Set volume for an audio buffer
637
+ void SetAudioBufferVolume(AudioBuffer *buffer, float volume)
638
+ {
639
+ if (buffer != NULL) buffer->volume = volume;
640
+ }
641
+
642
+ // Set pitch for an audio buffer
643
+ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
644
+ {
645
+ if ((buffer != NULL) && (pitch > 0.0f))
646
+ {
647
+ // Pitching is just an adjustment of the sample rate.
648
+ // Note that this changes the duration of the sound:
649
+ // - higher pitches will make the sound faster
650
+ // - lower pitches make it slower
651
+ ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.config.sampleRateOut/pitch);
652
+ ma_data_converter_set_rate(&buffer->converter, buffer->converter.config.sampleRateIn, outputSampleRate);
653
+
654
+ buffer->pitch = pitch;
655
+ }
656
+ }
657
+
658
+ // Track audio buffer to linked list next position
659
+ void TrackAudioBuffer(AudioBuffer *buffer)
660
+ {
661
+ ma_mutex_lock(&AUDIO.System.lock);
662
+ {
663
+ if (AUDIO.Buffer.first == NULL) AUDIO.Buffer.first = buffer;
664
+ else
665
+ {
666
+ AUDIO.Buffer.last->next = buffer;
667
+ buffer->prev = AUDIO.Buffer.last;
668
+ }
669
+
670
+ AUDIO.Buffer.last = buffer;
671
+ }
672
+ ma_mutex_unlock(&AUDIO.System.lock);
673
+ }
674
+
675
+ // Untrack audio buffer from linked list
676
+ void UntrackAudioBuffer(AudioBuffer *buffer)
677
+ {
678
+ ma_mutex_lock(&AUDIO.System.lock);
679
+ {
680
+ if (buffer->prev == NULL) AUDIO.Buffer.first = buffer->next;
681
+ else buffer->prev->next = buffer->next;
682
+
683
+ if (buffer->next == NULL) AUDIO.Buffer.last = buffer->prev;
684
+ else buffer->next->prev = buffer->prev;
685
+
686
+ buffer->prev = NULL;
687
+ buffer->next = NULL;
688
+ }
689
+ ma_mutex_unlock(&AUDIO.System.lock);
690
+ }
691
+
692
+ //----------------------------------------------------------------------------------
693
+ // Module Functions Definition - Sounds loading and playing (.WAV)
694
+ //----------------------------------------------------------------------------------
695
+
696
+ // Load wave data from file
697
+ Wave LoadWave(const char *fileName)
698
+ {
699
+ Wave wave = { 0 };
700
+
701
+ // Loading file to memory
702
+ unsigned int fileSize = 0;
703
+ unsigned char *fileData = LoadFileData(fileName, &fileSize);
704
+
705
+ // Loading wave from memory data
706
+ if (fileData != NULL) wave = LoadWaveFromMemory(GetFileExtension(fileName), fileData, fileSize);
707
+
708
+ RL_FREE(fileData);
709
+
710
+ return wave;
711
+ }
712
+
713
+ // Load wave from memory buffer, fileType refers to extension: i.e. ".wav"
714
+ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize)
715
+ {
716
+ Wave wave = { 0 };
717
+
718
+ char fileExtLower[16] = { 0 };
719
+ strcpy(fileExtLower, TextToLower(fileType));
720
+
721
+ if (false) { }
722
+ #if defined(SUPPORT_FILEFORMAT_WAV)
723
+ else if (TextIsEqual(fileExtLower, ".wav"))
724
+ {
725
+ drwav wav = { 0 };
726
+ bool success = drwav_init_memory(&wav, fileData, dataSize, NULL);
727
+
728
+ if (success)
729
+ {
730
+ wave.frameCount = (unsigned int)wav.totalPCMFrameCount;
731
+ wave.sampleRate = wav.sampleRate;
732
+ wave.sampleSize = 16;
733
+ wave.channels = wav.channels;
734
+ wave.data = (short *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(short));
735
+
736
+ // NOTE: We are forcing conversion to 16bit sample size on reading
737
+ drwav_read_pcm_frames_s16(&wav, wav.totalPCMFrameCount, wave.data);
738
+ }
739
+ else TRACELOG(LOG_WARNING, "WAVE: Failed to load WAV data");
740
+
741
+ drwav_uninit(&wav);
742
+ }
743
+ #endif
744
+ #if defined(SUPPORT_FILEFORMAT_OGG)
745
+ else if (TextIsEqual(fileExtLower, ".ogg"))
746
+ {
747
+ stb_vorbis *oggData = stb_vorbis_open_memory((unsigned char *)fileData, dataSize, NULL, NULL);
748
+
749
+ if (oggData != NULL)
750
+ {
751
+ stb_vorbis_info info = stb_vorbis_get_info(oggData);
752
+
753
+ wave.sampleRate = info.sample_rate;
754
+ wave.sampleSize = 16; // By default, ogg data is 16 bit per sample (short)
755
+ wave.channels = info.channels;
756
+ wave.frameCount = (unsigned int)stb_vorbis_stream_length_in_samples(oggData); // NOTE: It returns frames!
757
+ wave.data = (short *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(short));
758
+
759
+ // NOTE: Get the number of samples to process (be careful! we ask for number of shorts, not bytes!)
760
+ stb_vorbis_get_samples_short_interleaved(oggData, info.channels, (short *)wave.data, wave.frameCount*wave.channels);
761
+ stb_vorbis_close(oggData);
762
+ }
763
+ else TRACELOG(LOG_WARNING, "WAVE: Failed to load OGG data");
764
+ }
765
+ #endif
766
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
767
+ else if (TextIsEqual(fileExtLower, ".flac"))
768
+ {
769
+ unsigned long long int totalFrameCount = 0;
770
+
771
+ // NOTE: We are forcing conversion to 16bit sample size on reading
772
+ wave.data = drflac_open_memory_and_read_pcm_frames_s16(fileData, dataSize, &wave.channels, &wave.sampleRate, &totalFrameCount, NULL);
773
+ wave.sampleSize = 16;
774
+
775
+ if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount;
776
+ else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data");
777
+ }
778
+ #endif
779
+ #if defined(SUPPORT_FILEFORMAT_MP3)
780
+ else if (TextIsEqual(fileExtLower, ".mp3"))
781
+ {
782
+ drmp3_config config = { 0 };
783
+ unsigned long long int totalFrameCount = 0;
784
+
785
+ // NOTE: We are forcing conversion to 32bit float sample size on reading
786
+ wave.data = drmp3_open_memory_and_read_pcm_frames_f32(fileData, dataSize, &config, &totalFrameCount, NULL);
787
+ wave.sampleSize = 32;
788
+
789
+ if (wave.data != NULL)
790
+ {
791
+ wave.channels = config.channels;
792
+ wave.sampleRate = config.sampleRate;
793
+ wave.frameCount = (int)totalFrameCount;
794
+ }
795
+ else TRACELOG(LOG_WARNING, "WAVE: Failed to load MP3 data");
796
+
797
+ }
798
+ #endif
799
+ else TRACELOG(LOG_WARNING, "WAVE: Data format not supported");
800
+
801
+ TRACELOG(LOG_INFO, "WAVE: Data loaded successfully (%i Hz, %i bit, %i channels)", wave.sampleRate, wave.sampleSize, wave.channels);
802
+
803
+ return wave;
804
+ }
805
+
806
+ // Load sound from file
807
+ // NOTE: The entire file is loaded to memory to be played (no-streaming)
808
+ Sound LoadSound(const char *fileName)
809
+ {
810
+ Wave wave = LoadWave(fileName);
811
+
812
+ Sound sound = LoadSoundFromWave(wave);
813
+
814
+ UnloadWave(wave); // Sound is loaded, we can unload wave
815
+
816
+ return sound;
817
+ }
818
+
819
+ // Load sound from wave data
820
+ // NOTE: Wave data must be unallocated manually
821
+ Sound LoadSoundFromWave(Wave wave)
822
+ {
823
+ Sound sound = { 0 };
824
+
825
+ if (wave.data != NULL)
826
+ {
827
+ // When using miniaudio we need to do our own mixing.
828
+ // To simplify this we need convert the format of each sound to be consistent with
829
+ // the format used to open the playback AUDIO.System.device. We can do this two ways:
830
+ //
831
+ // 1) Convert the whole sound in one go at load time (here).
832
+ // 2) Convert the audio data in chunks at mixing time.
833
+ //
834
+ // First option has been selected, format conversion is done on the loading stage.
835
+ // The downside is that it uses more memory if the original sound is u8 or s16.
836
+ ma_format formatIn = ((wave.sampleSize == 8)? ma_format_u8 : ((wave.sampleSize == 16)? ma_format_s16 : ma_format_f32));
837
+ ma_uint32 frameCountIn = wave.frameCount;
838
+
839
+ ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, 0, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, NULL, frameCountIn, formatIn, wave.channels, wave.sampleRate);
840
+ if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed to get frame count for format conversion");
841
+
842
+ AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, frameCount, AUDIO_BUFFER_USAGE_STATIC);
843
+ if (audioBuffer == NULL)
844
+ {
845
+ TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer");
846
+ return sound; // early return to avoid dereferencing the audioBuffer null pointer
847
+ }
848
+
849
+ frameCount = (ma_uint32)ma_convert_frames(audioBuffer->data, frameCount, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, wave.data, frameCountIn, formatIn, wave.channels, wave.sampleRate);
850
+ if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed format conversion");
851
+
852
+ sound.frameCount = frameCount;
853
+ sound.stream.sampleRate = AUDIO.System.device.sampleRate;
854
+ sound.stream.sampleSize = 32;
855
+ sound.stream.channels = AUDIO_DEVICE_CHANNELS;
856
+ sound.stream.buffer = audioBuffer;
857
+ }
858
+
859
+ return sound;
860
+ }
861
+
862
+ // Unload wave data
863
+ void UnloadWave(Wave wave)
864
+ {
865
+ if (wave.data != NULL) RL_FREE(wave.data);
866
+
867
+ TRACELOG(LOG_INFO, "WAVE: Unloaded wave data from RAM");
868
+ }
869
+
870
+ // Unload sound
871
+ void UnloadSound(Sound sound)
872
+ {
873
+ UnloadAudioBuffer(sound.stream.buffer);
874
+
875
+ TRACELOG(LOG_INFO, "WAVE: Unloaded sound data from RAM");
876
+ }
877
+
878
+ // Update sound buffer with new data
879
+ void UpdateSound(Sound sound, const void *data, int sampleCount)
880
+ {
881
+ if (sound.stream.buffer != NULL)
882
+ {
883
+ StopAudioBuffer(sound.stream.buffer);
884
+
885
+ // TODO: May want to lock/unlock this since this data buffer is read at mixing time
886
+ memcpy(sound.stream.buffer->data, data, sampleCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.config.formatIn, sound.stream.buffer->converter.config.channelsIn));
887
+ }
888
+ }
889
+
890
+ // Export wave data to file
891
+ bool ExportWave(Wave wave, const char *fileName)
892
+ {
893
+ bool success = false;
894
+
895
+ if (false) { }
896
+ #if defined(SUPPORT_FILEFORMAT_WAV)
897
+ else if (IsFileExtension(fileName, ".wav"))
898
+ {
899
+ drwav wav = { 0 };
900
+ drwav_data_format format = { 0 };
901
+ format.container = drwav_container_riff;
902
+ format.format = DR_WAVE_FORMAT_PCM;
903
+ format.channels = wave.channels;
904
+ format.sampleRate = wave.sampleRate;
905
+ format.bitsPerSample = wave.sampleSize;
906
+
907
+ void *fileData = NULL;
908
+ size_t fileDataSize = 0;
909
+ success = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL);
910
+ if (success) success = (int)drwav_write_pcm_frames(&wav, wave.frameCount, wave.data);
911
+ drwav_result result = drwav_uninit(&wav);
912
+
913
+ if (result == DRWAV_SUCCESS) success = SaveFileData(fileName, (unsigned char *)fileData, (unsigned int)fileDataSize);
914
+
915
+ drwav_free(fileData, NULL);
916
+ }
917
+ #endif
918
+ else if (IsFileExtension(fileName, ".raw"))
919
+ {
920
+ // Export raw sample data (without header)
921
+ // NOTE: It's up to the user to track wave parameters
922
+ success = SaveFileData(fileName, wave.data, wave.frameCount*wave.channels*wave.sampleSize/8);
923
+ }
924
+
925
+ if (success) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave data exported successfully", fileName);
926
+ else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave data", fileName);
927
+
928
+ return success;
929
+ }
930
+
931
+ // Export wave sample data to code (.h)
932
+ bool ExportWaveAsCode(Wave wave, const char *fileName)
933
+ {
934
+ bool success = false;
935
+
936
+ #ifndef TEXT_BYTES_PER_LINE
937
+ #define TEXT_BYTES_PER_LINE 20
938
+ #endif
939
+
940
+ int waveDataSize = wave.frameCount*wave.channels*wave.sampleSize/8;
941
+
942
+ // NOTE: Text data buffer size is estimated considering wave data size in bytes
943
+ // and requiring 6 char bytes for every byte: "0x00, "
944
+ char *txtData = (char *)RL_CALLOC(waveDataSize*6 + 2000, sizeof(char));
945
+
946
+ int byteCount = 0;
947
+ byteCount += sprintf(txtData + byteCount, "\n//////////////////////////////////////////////////////////////////////////////////\n");
948
+ byteCount += sprintf(txtData + byteCount, "// //\n");
949
+ byteCount += sprintf(txtData + byteCount, "// WaveAsCode exporter v1.0 - Wave data exported as an array of bytes //\n");
950
+ byteCount += sprintf(txtData + byteCount, "// //\n");
951
+ byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
952
+ byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
953
+ byteCount += sprintf(txtData + byteCount, "// //\n");
954
+ byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2021 Ramon Santamaria (@raysan5) //\n");
955
+ byteCount += sprintf(txtData + byteCount, "// //\n");
956
+ byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n");
957
+
958
+ char varFileName[256] = { 0 };
959
+ #if !defined(RAUDIO_STANDALONE)
960
+ // Get file name from path and convert variable name to uppercase
961
+ strcpy(varFileName, GetFileNameWithoutExt(fileName));
962
+ for (int i = 0; varFileName[i] != '\0'; i++) if (varFileName[i] >= 'a' && varFileName[i] <= 'z') { varFileName[i] = varFileName[i] - 32; }
963
+ #else
964
+ strcpy(varFileName, fileName);
965
+ #endif
966
+
967
+ byteCount += sprintf(txtData + byteCount, "// Wave data information\n");
968
+ byteCount += sprintf(txtData + byteCount, "#define %s_FRAME_COUNT %u\n", varFileName, wave.frameCount);
969
+ byteCount += sprintf(txtData + byteCount, "#define %s_FRAME_COUNT %u\n", varFileName, wave.frameCount);
970
+ byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_RATE %u\n", varFileName, wave.sampleRate);
971
+ byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_SIZE %u\n", varFileName, wave.sampleSize);
972
+ byteCount += sprintf(txtData + byteCount, "#define %s_CHANNELS %u\n\n", varFileName, wave.channels);
973
+
974
+ // Write byte data as hexadecimal text
975
+ // NOTE: Frame data exported is interlaced: Frame01[Sample-Channel01, Sample-Channel02, ...], Frame02[], Frame03[]
976
+ byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%i] = { ", varFileName, waveDataSize);
977
+ for (int i = 0; i < waveDataSize - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), ((unsigned char *)wave.data)[i]);
978
+ byteCount += sprintf(txtData + byteCount, "0x%x };\n", ((unsigned char *)wave.data)[waveDataSize - 1]);
979
+
980
+ // NOTE: Text data length exported is determined by '\0' (NULL) character
981
+ success = SaveFileText(fileName, txtData);
982
+
983
+ RL_FREE(txtData);
984
+
985
+ return success;
986
+ }
987
+
988
+ // Play a sound
989
+ void PlaySound(Sound sound)
990
+ {
991
+ PlayAudioBuffer(sound.stream.buffer);
992
+ }
993
+
994
+ // Play a sound in the multichannel buffer pool
995
+ void PlaySoundMulti(Sound sound)
996
+ {
997
+ int index = -1;
998
+ unsigned int oldAge = 0;
999
+ int oldIndex = -1;
1000
+
1001
+ // find the first non playing pool entry
1002
+ for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
1003
+ {
1004
+ if (AUDIO.MultiChannel.channels[i] > oldAge)
1005
+ {
1006
+ oldAge = AUDIO.MultiChannel.channels[i];
1007
+ oldIndex = i;
1008
+ }
1009
+
1010
+ if (!IsAudioBufferPlaying(AUDIO.MultiChannel.pool[i]))
1011
+ {
1012
+ index = i;
1013
+ break;
1014
+ }
1015
+ }
1016
+
1017
+ // If no none playing pool members can be index choose the oldest
1018
+ if (index == -1)
1019
+ {
1020
+ TRACELOG(LOG_WARNING, "SOUND: Buffer pool is already full, count: %i", AUDIO.MultiChannel.poolCounter);
1021
+
1022
+ if (oldIndex == -1)
1023
+ {
1024
+ // Shouldn't be able to get here... but just in case something odd happens!
1025
+ TRACELOG(LOG_WARNING, "SOUND: Buffer pool could not determine oldest buffer not playing sound");
1026
+ return;
1027
+ }
1028
+
1029
+ index = oldIndex;
1030
+
1031
+ // Just in case...
1032
+ StopAudioBuffer(AUDIO.MultiChannel.pool[index]);
1033
+ }
1034
+
1035
+ // Experimentally mutex lock doesn't seem to be needed this makes sense
1036
+ // as pool[index] isn't playing and the only stuff we're copying
1037
+ // shouldn't be changing...
1038
+
1039
+ AUDIO.MultiChannel.channels[index] = AUDIO.MultiChannel.poolCounter;
1040
+ AUDIO.MultiChannel.poolCounter++;
1041
+
1042
+ AUDIO.MultiChannel.pool[index]->volume = sound.stream.buffer->volume;
1043
+ AUDIO.MultiChannel.pool[index]->pitch = sound.stream.buffer->pitch;
1044
+ AUDIO.MultiChannel.pool[index]->looping = sound.stream.buffer->looping;
1045
+ AUDIO.MultiChannel.pool[index]->usage = sound.stream.buffer->usage;
1046
+ AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[0] = false;
1047
+ AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[1] = false;
1048
+ AUDIO.MultiChannel.pool[index]->sizeInFrames = sound.stream.buffer->sizeInFrames;
1049
+ AUDIO.MultiChannel.pool[index]->data = sound.stream.buffer->data;
1050
+
1051
+ PlayAudioBuffer(AUDIO.MultiChannel.pool[index]);
1052
+ }
1053
+
1054
+ // Stop any sound played with PlaySoundMulti()
1055
+ void StopSoundMulti(void)
1056
+ {
1057
+ for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) StopAudioBuffer(AUDIO.MultiChannel.pool[i]);
1058
+ }
1059
+
1060
+ // Get number of sounds playing in the multichannel buffer pool
1061
+ int GetSoundsPlaying(void)
1062
+ {
1063
+ int counter = 0;
1064
+
1065
+ for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
1066
+ {
1067
+ if (IsAudioBufferPlaying(AUDIO.MultiChannel.pool[i])) counter++;
1068
+ }
1069
+
1070
+ return counter;
1071
+ }
1072
+
1073
+ // Pause a sound
1074
+ void PauseSound(Sound sound)
1075
+ {
1076
+ PauseAudioBuffer(sound.stream.buffer);
1077
+ }
1078
+
1079
+ // Resume a paused sound
1080
+ void ResumeSound(Sound sound)
1081
+ {
1082
+ ResumeAudioBuffer(sound.stream.buffer);
1083
+ }
1084
+
1085
+ // Stop reproducing a sound
1086
+ void StopSound(Sound sound)
1087
+ {
1088
+ StopAudioBuffer(sound.stream.buffer);
1089
+ }
1090
+
1091
+ // Check if a sound is playing
1092
+ bool IsSoundPlaying(Sound sound)
1093
+ {
1094
+ return IsAudioBufferPlaying(sound.stream.buffer);
1095
+ }
1096
+
1097
+ // Set volume for a sound
1098
+ void SetSoundVolume(Sound sound, float volume)
1099
+ {
1100
+ SetAudioBufferVolume(sound.stream.buffer, volume);
1101
+ }
1102
+
1103
+ // Set pitch for a sound
1104
+ void SetSoundPitch(Sound sound, float pitch)
1105
+ {
1106
+ SetAudioBufferPitch(sound.stream.buffer, pitch);
1107
+ }
1108
+
1109
+ // Convert wave data to desired format
1110
+ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
1111
+ {
1112
+ ma_format formatIn = ((wave->sampleSize == 8)? ma_format_u8 : ((wave->sampleSize == 16)? ma_format_s16 : ma_format_f32));
1113
+ ma_format formatOut = ((sampleSize == 8)? ma_format_u8 : ((sampleSize == 16)? ma_format_s16 : ma_format_f32));
1114
+
1115
+ ma_uint32 frameCountIn = wave->frameCount;
1116
+
1117
+ ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, 0, formatOut, channels, sampleRate, NULL, frameCountIn, formatIn, wave->channels, wave->sampleRate);
1118
+ if (frameCount == 0)
1119
+ {
1120
+ TRACELOG(LOG_WARNING, "WAVE: Failed to get frame count for format conversion");
1121
+ return;
1122
+ }
1123
+
1124
+ void *data = RL_MALLOC(frameCount*channels*(sampleSize/8));
1125
+
1126
+ frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate);
1127
+ if (frameCount == 0)
1128
+ {
1129
+ TRACELOG(LOG_WARNING, "WAVE: Failed format conversion");
1130
+ return;
1131
+ }
1132
+
1133
+ wave->frameCount = frameCount;
1134
+ wave->sampleSize = sampleSize;
1135
+ wave->sampleRate = sampleRate;
1136
+ wave->channels = channels;
1137
+ RL_FREE(wave->data);
1138
+ wave->data = data;
1139
+ }
1140
+
1141
+ // Copy a wave to a new wave
1142
+ Wave WaveCopy(Wave wave)
1143
+ {
1144
+ Wave newWave = { 0 };
1145
+
1146
+ newWave.data = RL_MALLOC(wave.frameCount*wave.channels*wave.sampleSize/8);
1147
+
1148
+ if (newWave.data != NULL)
1149
+ {
1150
+ // NOTE: Size must be provided in bytes
1151
+ memcpy(newWave.data, wave.data, wave.frameCount*wave.channels*wave.sampleSize/8);
1152
+
1153
+ newWave.frameCount = wave.frameCount;
1154
+ newWave.sampleRate = wave.sampleRate;
1155
+ newWave.sampleSize = wave.sampleSize;
1156
+ newWave.channels = wave.channels;
1157
+ }
1158
+
1159
+ return newWave;
1160
+ }
1161
+
1162
+ // Crop a wave to defined samples range
1163
+ // NOTE: Security check in case of out-of-range
1164
+ void WaveCrop(Wave *wave, int initSample, int finalSample)
1165
+ {
1166
+ if ((initSample >= 0) && (initSample < finalSample) &&
1167
+ (finalSample > 0) && ((unsigned int)finalSample < (wave->frameCount*wave->channels)))
1168
+ {
1169
+ int sampleCount = finalSample - initSample;
1170
+
1171
+ void *data = RL_MALLOC(sampleCount*wave->sampleSize/8);
1172
+
1173
+ memcpy(data, (unsigned char *)wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->sampleSize/8);
1174
+
1175
+ RL_FREE(wave->data);
1176
+ wave->data = data;
1177
+ }
1178
+ else TRACELOG(LOG_WARNING, "WAVE: Crop range out of bounds");
1179
+ }
1180
+
1181
+ // Load samples data from wave as a floats array
1182
+ // NOTE 1: Returned sample values are normalized to range [-1..1]
1183
+ // NOTE 2: Sample data allocated should be freed with UnloadWaveSamples()
1184
+ float *LoadWaveSamples(Wave wave)
1185
+ {
1186
+ float *samples = (float *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(float));
1187
+
1188
+ // NOTE: sampleCount is the total number of interlaced samples (including channels)
1189
+
1190
+ for (unsigned int i = 0; i < wave.frameCount*wave.channels; i++)
1191
+ {
1192
+ if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 127)/256.0f;
1193
+ else if (wave.sampleSize == 16) samples[i] = (float)(((short *)wave.data)[i])/32767.0f;
1194
+ else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i];
1195
+ }
1196
+
1197
+ return samples;
1198
+ }
1199
+
1200
+ // Unload samples data loaded with LoadWaveSamples()
1201
+ void UnloadWaveSamples(float *samples)
1202
+ {
1203
+ RL_FREE(samples);
1204
+ }
1205
+
1206
+ //----------------------------------------------------------------------------------
1207
+ // Module Functions Definition - Music loading and stream playing (.OGG)
1208
+ //----------------------------------------------------------------------------------
1209
+
1210
+ // Load music stream from file
1211
+ Music LoadMusicStream(const char *fileName)
1212
+ {
1213
+ Music music = { 0 };
1214
+ bool musicLoaded = false;
1215
+
1216
+ if (false) { }
1217
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1218
+ else if (IsFileExtension(fileName, ".wav"))
1219
+ {
1220
+ drwav *ctxWav = RL_CALLOC(1, sizeof(drwav));
1221
+ bool success = drwav_init_file(ctxWav, fileName, NULL);
1222
+
1223
+ music.ctxType = MUSIC_AUDIO_WAV;
1224
+ music.ctxData = ctxWav;
1225
+
1226
+ if (success)
1227
+ {
1228
+ int sampleSize = ctxWav->bitsPerSample;
1229
+ if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream()
1230
+
1231
+ music.stream = LoadAudioStream(ctxWav->sampleRate, sampleSize, ctxWav->channels);
1232
+ music.frameCount = (unsigned int)ctxWav->totalPCMFrameCount;
1233
+ music.looping = true; // Looping enabled by default
1234
+ musicLoaded = true;
1235
+ }
1236
+ }
1237
+ #endif
1238
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1239
+ else if (IsFileExtension(fileName, ".ogg"))
1240
+ {
1241
+ // Open ogg audio stream
1242
+ music.ctxType = MUSIC_AUDIO_OGG;
1243
+ music.ctxData = stb_vorbis_open_filename(fileName, NULL, NULL);
1244
+
1245
+ if (music.ctxData != NULL)
1246
+ {
1247
+ stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)music.ctxData); // Get Ogg file info
1248
+
1249
+ // OGG bit rate defaults to 16 bit, it's enough for compressed format
1250
+ music.stream = LoadAudioStream(info.sample_rate, 16, info.channels);
1251
+
1252
+ // WARNING: It seems this function returns length in frames, not samples, so we multiply by channels
1253
+ music.frameCount = (unsigned int)stb_vorbis_stream_length_in_samples((stb_vorbis *)music.ctxData);
1254
+ music.looping = true; // Looping enabled by default
1255
+ musicLoaded = true;
1256
+ }
1257
+ }
1258
+ #endif
1259
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1260
+ else if (IsFileExtension(fileName, ".flac"))
1261
+ {
1262
+ music.ctxType = MUSIC_AUDIO_FLAC;
1263
+ music.ctxData = drflac_open_file(fileName, NULL);
1264
+
1265
+ if (music.ctxData != NULL)
1266
+ {
1267
+ drflac *ctxFlac = (drflac *)music.ctxData;
1268
+
1269
+ music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels);
1270
+ music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount;
1271
+ music.looping = true; // Looping enabled by default
1272
+ musicLoaded = true;
1273
+ }
1274
+ }
1275
+ #endif
1276
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1277
+ else if (IsFileExtension(fileName, ".mp3"))
1278
+ {
1279
+ drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3));
1280
+ int result = drmp3_init_file(ctxMp3, fileName, NULL);
1281
+
1282
+ music.ctxType = MUSIC_AUDIO_MP3;
1283
+ music.ctxData = ctxMp3;
1284
+
1285
+ if (result > 0)
1286
+ {
1287
+ music.stream = LoadAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels);
1288
+ music.frameCount = (unsigned int)drmp3_get_pcm_frame_count(ctxMp3);
1289
+ music.looping = true; // Looping enabled by default
1290
+ musicLoaded = true;
1291
+ }
1292
+ }
1293
+ #endif
1294
+ #if defined(SUPPORT_FILEFORMAT_XM)
1295
+ else if (IsFileExtension(fileName, ".xm"))
1296
+ {
1297
+ jar_xm_context_t *ctxXm = NULL;
1298
+ int result = jar_xm_create_context_from_file(&ctxXm, AUDIO.System.device.sampleRate, fileName);
1299
+
1300
+ music.ctxType = MUSIC_MODULE_XM;
1301
+ music.ctxData = ctxXm;
1302
+
1303
+ if (result == 0) // XM AUDIO.System.context created successfully
1304
+ {
1305
+ jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops
1306
+
1307
+ unsigned int bits = 32;
1308
+ if (AUDIO_DEVICE_FORMAT == ma_format_s16) bits = 16;
1309
+ else if (AUDIO_DEVICE_FORMAT == ma_format_u8) bits = 8;
1310
+
1311
+ // NOTE: Only stereo is supported for XM
1312
+ music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, AUDIO_DEVICE_CHANNELS);
1313
+ music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo)
1314
+ music.looping = true; // Looping enabled by default
1315
+ jar_xm_reset(ctxXm); // make sure we start at the beginning of the song
1316
+ musicLoaded = true;
1317
+ }
1318
+ }
1319
+ #endif
1320
+ #if defined(SUPPORT_FILEFORMAT_MOD)
1321
+ else if (IsFileExtension(fileName, ".mod"))
1322
+ {
1323
+ jar_mod_context_t *ctxMod = RL_CALLOC(1, sizeof(jar_mod_context_t));
1324
+ jar_mod_init(ctxMod);
1325
+ int result = jar_mod_load_file(ctxMod, fileName);
1326
+
1327
+ music.ctxType = MUSIC_MODULE_MOD;
1328
+ music.ctxData = ctxMod;
1329
+
1330
+ if (result > 0)
1331
+ {
1332
+ // NOTE: Only stereo is supported for MOD
1333
+ music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, 16, AUDIO_DEVICE_CHANNELS);
1334
+ music.frameCount = (unsigned int)jar_mod_max_samples(ctxMod); // NOTE: Always 2 channels (stereo)
1335
+ music.looping = true; // Looping enabled by default
1336
+ musicLoaded = true;
1337
+ }
1338
+ }
1339
+ #endif
1340
+ else TRACELOG(LOG_WARNING, "STREAM: [%s] File format not supported", fileName);
1341
+
1342
+ if (!musicLoaded)
1343
+ {
1344
+ if (false) { }
1345
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1346
+ else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData);
1347
+ #endif
1348
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1349
+ else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData);
1350
+ #endif
1351
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1352
+ else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL);
1353
+ #endif
1354
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1355
+ else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); }
1356
+ #endif
1357
+ #if defined(SUPPORT_FILEFORMAT_XM)
1358
+ else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
1359
+ #endif
1360
+ #if defined(SUPPORT_FILEFORMAT_MOD)
1361
+ else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); }
1362
+ #endif
1363
+
1364
+ music.ctxData = NULL;
1365
+ TRACELOG(LOG_WARNING, "FILEIO: [%s] Music file could not be opened", fileName);
1366
+ }
1367
+ else
1368
+ {
1369
+ // Show some music stream info
1370
+ TRACELOG(LOG_INFO, "FILEIO: [%s] Music file loaded successfully", fileName);
1371
+ TRACELOG(LOG_INFO, " > Sample rate: %i Hz", music.stream.sampleRate);
1372
+ TRACELOG(LOG_INFO, " > Sample size: %i bits", music.stream.sampleSize);
1373
+ TRACELOG(LOG_INFO, " > Channels: %i (%s)", music.stream.channels, (music.stream.channels == 1)? "Mono" : (music.stream.channels == 2)? "Stereo" : "Multi");
1374
+ TRACELOG(LOG_INFO, " > Total frames: %i", music.frameCount);
1375
+ }
1376
+
1377
+ return music;
1378
+ }
1379
+
1380
+ // extension including period ".mod"
1381
+ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int dataSize)
1382
+ {
1383
+ Music music = { 0 };
1384
+ bool musicLoaded = false;
1385
+
1386
+ char fileExtLower[16] = { 0 };
1387
+ strcpy(fileExtLower, TextToLower(fileType));
1388
+
1389
+ if (false) { }
1390
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1391
+ else if (TextIsEqual(fileExtLower, ".wav"))
1392
+ {
1393
+ drwav *ctxWav = RL_CALLOC(1, sizeof(drwav));
1394
+
1395
+ bool success = drwav_init_memory(ctxWav, (const void *)data, dataSize, NULL);
1396
+
1397
+ music.ctxType = MUSIC_AUDIO_WAV;
1398
+ music.ctxData = ctxWav;
1399
+
1400
+ if (success)
1401
+ {
1402
+ int sampleSize = ctxWav->bitsPerSample;
1403
+ if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream()
1404
+
1405
+ music.stream = LoadAudioStream(ctxWav->sampleRate, sampleSize, ctxWav->channels);
1406
+ music.frameCount = (unsigned int)ctxWav->totalPCMFrameCount;
1407
+ music.looping = true; // Looping enabled by default
1408
+ musicLoaded = true;
1409
+ }
1410
+ }
1411
+ #endif
1412
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1413
+ else if (TextIsEqual(fileExtLower, ".flac"))
1414
+ {
1415
+ music.ctxType = MUSIC_AUDIO_FLAC;
1416
+ music.ctxData = drflac_open_memory((const void*)data, dataSize, NULL);
1417
+
1418
+ if (music.ctxData != NULL)
1419
+ {
1420
+ drflac *ctxFlac = (drflac *)music.ctxData;
1421
+
1422
+ music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels);
1423
+ music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount;
1424
+ music.looping = true; // Looping enabled by default
1425
+ musicLoaded = true;
1426
+ }
1427
+ }
1428
+ #endif
1429
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1430
+ else if (TextIsEqual(fileExtLower, ".mp3"))
1431
+ {
1432
+ drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3));
1433
+ int success = drmp3_init_memory(ctxMp3, (const void*)data, dataSize, NULL);
1434
+
1435
+ music.ctxType = MUSIC_AUDIO_MP3;
1436
+ music.ctxData = ctxMp3;
1437
+
1438
+ if (success)
1439
+ {
1440
+ music.stream = LoadAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels);
1441
+ music.frameCount = (unsigned int)drmp3_get_pcm_frame_count(ctxMp3);
1442
+ music.looping = true; // Looping enabled by default
1443
+ musicLoaded = true;
1444
+ }
1445
+ }
1446
+ #endif
1447
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1448
+ else if (TextIsEqual(fileExtLower, ".ogg"))
1449
+ {
1450
+ // Open ogg audio stream
1451
+ music.ctxType = MUSIC_AUDIO_OGG;
1452
+ //music.ctxData = stb_vorbis_open_filename(fileName, NULL, NULL);
1453
+ music.ctxData = stb_vorbis_open_memory((const unsigned char *)data, dataSize, NULL, NULL);
1454
+
1455
+ if (music.ctxData != NULL)
1456
+ {
1457
+ stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)music.ctxData); // Get Ogg file info
1458
+
1459
+ // OGG bit rate defaults to 16 bit, it's enough for compressed format
1460
+ music.stream = LoadAudioStream(info.sample_rate, 16, info.channels);
1461
+
1462
+ // WARNING: It seems this function returns length in frames, not samples, so we multiply by channels
1463
+ music.frameCount = (unsigned int)stb_vorbis_stream_length_in_samples((stb_vorbis *)music.ctxData);
1464
+ music.looping = true; // Looping enabled by default
1465
+ musicLoaded = true;
1466
+ }
1467
+ }
1468
+ #endif
1469
+ #if defined(SUPPORT_FILEFORMAT_XM)
1470
+ else if (TextIsEqual(fileExtLower, ".xm"))
1471
+ {
1472
+ jar_xm_context_t *ctxXm = NULL;
1473
+ int result = jar_xm_create_context_safe(&ctxXm, (const char *)data, dataSize, AUDIO.System.device.sampleRate);
1474
+ if (result == 0) // XM AUDIO.System.context created successfully
1475
+ {
1476
+ music.ctxType = MUSIC_MODULE_XM;
1477
+ jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops
1478
+
1479
+ unsigned int bits = 32;
1480
+ if (AUDIO_DEVICE_FORMAT == ma_format_s16)
1481
+ bits = 16;
1482
+ else if (AUDIO_DEVICE_FORMAT == ma_format_u8)
1483
+ bits = 8;
1484
+
1485
+ // NOTE: Only stereo is supported for XM
1486
+ music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, 2);
1487
+ music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo)
1488
+ music.looping = true; // Looping enabled by default
1489
+ jar_xm_reset(ctxXm); // make sure we start at the beginning of the song
1490
+
1491
+ music.ctxData = ctxXm;
1492
+ musicLoaded = true;
1493
+ }
1494
+ }
1495
+ #endif
1496
+ #if defined(SUPPORT_FILEFORMAT_MOD)
1497
+ else if (TextIsEqual(fileExtLower, ".mod"))
1498
+ {
1499
+ jar_mod_context_t *ctxMod = (jar_mod_context_t *)RL_MALLOC(sizeof(jar_mod_context_t));
1500
+ int result = 0;
1501
+
1502
+ jar_mod_init(ctxMod);
1503
+
1504
+ // Copy data to allocated memory for default UnloadMusicStream
1505
+ unsigned char *newData = (unsigned char *)RL_MALLOC(dataSize);
1506
+ int it = dataSize/sizeof(unsigned char);
1507
+ for (int i = 0; i < it; i++) newData[i] = data[i];
1508
+
1509
+ // Memory loaded version for jar_mod_load_file()
1510
+ if (dataSize && dataSize < 32*1024*1024)
1511
+ {
1512
+ ctxMod->modfilesize = dataSize;
1513
+ ctxMod->modfile = newData;
1514
+ if (jar_mod_load(ctxMod, (void *)ctxMod->modfile, dataSize)) result = dataSize;
1515
+ }
1516
+
1517
+ if (result > 0)
1518
+ {
1519
+ music.ctxType = MUSIC_MODULE_MOD;
1520
+
1521
+ // NOTE: Only stereo is supported for MOD
1522
+ music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, 16, 2);
1523
+ music.frameCount = (unsigned int)jar_mod_max_samples(ctxMod); // NOTE: Always 2 channels (stereo)
1524
+ music.looping = true; // Looping enabled by default
1525
+ musicLoaded = true;
1526
+
1527
+ music.ctxData = ctxMod;
1528
+ musicLoaded = true;
1529
+ }
1530
+ }
1531
+ #endif
1532
+ else TRACELOG(LOG_WARNING, "STREAM: Data format not supported");
1533
+
1534
+ if (!musicLoaded)
1535
+ {
1536
+ if (false) { }
1537
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1538
+ else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData);
1539
+ #endif
1540
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1541
+ else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL);
1542
+ #endif
1543
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1544
+ else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); }
1545
+ #endif
1546
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1547
+ else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData);
1548
+ #endif
1549
+ #if defined(SUPPORT_FILEFORMAT_XM)
1550
+ else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
1551
+ #endif
1552
+ #if defined(SUPPORT_FILEFORMAT_MOD)
1553
+ else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); }
1554
+ #endif
1555
+
1556
+ music.ctxData = NULL;
1557
+ TRACELOG(LOG_WARNING, "FILEIO: Music data could not be loaded");
1558
+ }
1559
+ else
1560
+ {
1561
+ // Show some music stream info
1562
+ TRACELOG(LOG_INFO, "FILEIO: Music data loaded successfully");
1563
+ TRACELOG(LOG_INFO, " > Sample rate: %i Hz", music.stream.sampleRate);
1564
+ TRACELOG(LOG_INFO, " > Sample size: %i bits", music.stream.sampleSize);
1565
+ TRACELOG(LOG_INFO, " > Channels: %i (%s)", music.stream.channels, (music.stream.channels == 1)? "Mono" : (music.stream.channels == 2)? "Stereo" : "Multi");
1566
+ TRACELOG(LOG_INFO, " > Total frames: %i", music.frameCount);
1567
+ }
1568
+
1569
+ return music;
1570
+ }
1571
+
1572
+ // Unload music stream
1573
+ void UnloadMusicStream(Music music)
1574
+ {
1575
+ UnloadAudioStream(music.stream);
1576
+
1577
+ if (music.ctxData != NULL)
1578
+ {
1579
+ if (false) { }
1580
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1581
+ else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData);
1582
+ #endif
1583
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1584
+ else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData);
1585
+ #endif
1586
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1587
+ else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL);
1588
+ #endif
1589
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1590
+ else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); }
1591
+ #endif
1592
+ #if defined(SUPPORT_FILEFORMAT_XM)
1593
+ else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
1594
+ #endif
1595
+ #if defined(SUPPORT_FILEFORMAT_MOD)
1596
+ else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); }
1597
+ #endif
1598
+ }
1599
+ }
1600
+
1601
+ // Start music playing (open stream)
1602
+ void PlayMusicStream(Music music)
1603
+ {
1604
+ if (music.stream.buffer != NULL)
1605
+ {
1606
+ // For music streams, we need to make sure we maintain the frame cursor position
1607
+ // This is a hack for this section of code in UpdateMusicStream()
1608
+ // NOTE: In case window is minimized, music stream is stopped, just make sure to
1609
+ // play again on window restore: if (IsMusicStreamPlaying(music)) PlayMusicStream(music);
1610
+ ma_uint32 frameCursorPos = music.stream.buffer->frameCursorPos;
1611
+ PlayAudioStream(music.stream); // WARNING: This resets the cursor position.
1612
+ music.stream.buffer->frameCursorPos = frameCursorPos;
1613
+ }
1614
+ }
1615
+
1616
+ // Pause music playing
1617
+ void PauseMusicStream(Music music)
1618
+ {
1619
+ PauseAudioStream(music.stream);
1620
+ }
1621
+
1622
+ // Resume music playing
1623
+ void ResumeMusicStream(Music music)
1624
+ {
1625
+ ResumeAudioStream(music.stream);
1626
+ }
1627
+
1628
+ // Stop music playing (close stream)
1629
+ void StopMusicStream(Music music)
1630
+ {
1631
+ StopAudioStream(music.stream);
1632
+
1633
+ switch (music.ctxType)
1634
+ {
1635
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1636
+ case MUSIC_AUDIO_WAV: drwav_seek_to_pcm_frame((drwav *)music.ctxData, 0); break;
1637
+ #endif
1638
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1639
+ case MUSIC_AUDIO_OGG: stb_vorbis_seek_start((stb_vorbis *)music.ctxData); break;
1640
+ #endif
1641
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1642
+ case MUSIC_AUDIO_FLAC: drflac_seek_to_pcm_frame((drflac *)music.ctxData, 0); break;
1643
+ #endif
1644
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1645
+ case MUSIC_AUDIO_MP3: drmp3_seek_to_pcm_frame((drmp3 *)music.ctxData, 0); break;
1646
+ #endif
1647
+ #if defined(SUPPORT_FILEFORMAT_XM)
1648
+ case MUSIC_MODULE_XM: jar_xm_reset((jar_xm_context_t *)music.ctxData); break;
1649
+ #endif
1650
+ #if defined(SUPPORT_FILEFORMAT_MOD)
1651
+ case MUSIC_MODULE_MOD: jar_mod_seek_start((jar_mod_context_t *)music.ctxData); break;
1652
+ #endif
1653
+ default: break;
1654
+ }
1655
+ }
1656
+
1657
+ // Seek music to a certain position (in seconds)
1658
+ void SeekMusicStream(Music music, float position)
1659
+ {
1660
+ // Seeking is not supported in module formats
1661
+ if ((music.ctxType == MUSIC_MODULE_XM) || (music.ctxType == MUSIC_MODULE_MOD)) return;
1662
+
1663
+ unsigned int positionInFrames = (unsigned int)(position*music.stream.sampleRate);
1664
+
1665
+ switch (music.ctxType)
1666
+ {
1667
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1668
+ case MUSIC_AUDIO_WAV: drwav_seek_to_pcm_frame((drwav *)music.ctxData, positionInFrames); break;
1669
+ #endif
1670
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1671
+ case MUSIC_AUDIO_OGG: stb_vorbis_seek_frame((stb_vorbis *)music.ctxData, positionInFrames); break;
1672
+ #endif
1673
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1674
+ case MUSIC_AUDIO_FLAC: drflac_seek_to_pcm_frame((drflac *)music.ctxData, positionInFrames); break;
1675
+ #endif
1676
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1677
+ case MUSIC_AUDIO_MP3: drmp3_seek_to_pcm_frame((drmp3 *)music.ctxData, positionInFrames); break;
1678
+ #endif
1679
+ default: break;
1680
+ }
1681
+
1682
+ music.stream.buffer->framesProcessed = positionInFrames;
1683
+ }
1684
+
1685
+ // Update (re-fill) music buffers if data already processed
1686
+ void UpdateMusicStream(Music music)
1687
+ {
1688
+ if (music.stream.buffer == NULL) return;
1689
+
1690
+ bool streamEnding = false;
1691
+ unsigned int subBufferSizeInFrames = music.stream.buffer->sizeInFrames/2;
1692
+
1693
+ // NOTE: Using dynamic allocation because it could require more than 16KB
1694
+ void *pcm = RL_CALLOC(subBufferSizeInFrames*music.stream.channels*music.stream.sampleSize/8, 1);
1695
+
1696
+ int frameCountToStream = 0; // Total size of data in frames to be streamed
1697
+
1698
+ // TODO: Get the framesLeft using framesProcessed... but first, get total frames processed correctly...
1699
+ //ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(music.stream.buffer->dsp.formatConverterIn.config.formatIn)*music.stream.buffer->dsp.formatConverterIn.config.channels;
1700
+ unsigned int framesLeft = music.frameCount - music.stream.buffer->framesProcessed;
1701
+
1702
+ while (IsAudioStreamProcessed(music.stream))
1703
+ {
1704
+ if (framesLeft >= subBufferSizeInFrames) frameCountToStream = subBufferSizeInFrames;
1705
+ else frameCountToStream = framesLeft;
1706
+
1707
+ switch (music.ctxType)
1708
+ {
1709
+ #if defined(SUPPORT_FILEFORMAT_WAV)
1710
+ case MUSIC_AUDIO_WAV:
1711
+ {
1712
+ // NOTE: Returns the number of samples to process (not required)
1713
+ if (music.stream.sampleSize == 16) drwav_read_pcm_frames_s16((drwav *)music.ctxData, frameCountToStream, (short *)pcm);
1714
+ else if (music.stream.sampleSize == 32) drwav_read_pcm_frames_f32((drwav *)music.ctxData, frameCountToStream, (float *)pcm);
1715
+
1716
+ } break;
1717
+ #endif
1718
+ #if defined(SUPPORT_FILEFORMAT_OGG)
1719
+ case MUSIC_AUDIO_OGG:
1720
+ {
1721
+ // NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!)
1722
+ stb_vorbis_get_samples_short_interleaved((stb_vorbis *)music.ctxData, music.stream.channels, (short *)pcm, frameCountToStream*music.stream.channels);
1723
+
1724
+ } break;
1725
+ #endif
1726
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
1727
+ case MUSIC_AUDIO_FLAC:
1728
+ {
1729
+ // NOTE: Returns the number of samples to process (not required)
1730
+ drflac_read_pcm_frames_s16((drflac *)music.ctxData, frameCountToStream*music.stream.channels, (short *)pcm);
1731
+
1732
+ } break;
1733
+ #endif
1734
+ #if defined(SUPPORT_FILEFORMAT_MP3)
1735
+ case MUSIC_AUDIO_MP3:
1736
+ {
1737
+ drmp3_read_pcm_frames_f32((drmp3 *)music.ctxData, frameCountToStream, (float *)pcm);
1738
+
1739
+ } break;
1740
+ #endif
1741
+ #if defined(SUPPORT_FILEFORMAT_XM)
1742
+ case MUSIC_MODULE_XM:
1743
+ {
1744
+ // NOTE: Internally we consider 2 channels generation, so sampleCount/2
1745
+ if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples((jar_xm_context_t *)music.ctxData, (float *)pcm, frameCountToStream);
1746
+ else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t *)music.ctxData, (short *)pcm, frameCountToStream);
1747
+ else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t *)music.ctxData, (char *)pcm, frameCountToStream);
1748
+
1749
+ } break;
1750
+ #endif
1751
+ #if defined(SUPPORT_FILEFORMAT_MOD)
1752
+ case MUSIC_MODULE_MOD:
1753
+ {
1754
+ // NOTE: 3rd parameter (nbsample) specify the number of stereo 16bits samples you want, so sampleCount/2
1755
+ jar_mod_fillbuffer((jar_mod_context_t *)music.ctxData, (short *)pcm, frameCountToStream, 0);
1756
+ } break;
1757
+ #endif
1758
+ default: break;
1759
+ }
1760
+
1761
+ UpdateAudioStream(music.stream, pcm, frameCountToStream);
1762
+
1763
+ framesLeft -= frameCountToStream;
1764
+
1765
+ if (framesLeft <= 0)
1766
+ {
1767
+ streamEnding = true;
1768
+ break;
1769
+ }
1770
+ }
1771
+
1772
+ // Free allocated pcm data
1773
+ RL_FREE(pcm);
1774
+
1775
+ // Reset audio stream for looping
1776
+ if (streamEnding)
1777
+ {
1778
+ StopMusicStream(music); // Stop music (and reset)
1779
+ if (music.looping) PlayMusicStream(music); // Play again
1780
+ }
1781
+ else
1782
+ {
1783
+ // NOTE: In case window is minimized, music stream is stopped,
1784
+ // just make sure to play again on window restore
1785
+ if (IsMusicStreamPlaying(music)) PlayMusicStream(music);
1786
+ }
1787
+ }
1788
+
1789
+ // Check if any music is playing
1790
+ bool IsMusicStreamPlaying(Music music)
1791
+ {
1792
+ return IsAudioStreamPlaying(music.stream);
1793
+ }
1794
+
1795
+ // Set volume for music
1796
+ void SetMusicVolume(Music music, float volume)
1797
+ {
1798
+ SetAudioStreamVolume(music.stream, volume);
1799
+ }
1800
+
1801
+ // Set pitch for music
1802
+ void SetMusicPitch(Music music, float pitch)
1803
+ {
1804
+ SetAudioBufferPitch(music.stream.buffer, pitch);
1805
+ }
1806
+
1807
+ // Get music time length (in seconds)
1808
+ float GetMusicTimeLength(Music music)
1809
+ {
1810
+ float totalSeconds = 0.0f;
1811
+
1812
+ totalSeconds = (float)music.frameCount/music.stream.sampleRate;
1813
+
1814
+ return totalSeconds;
1815
+ }
1816
+
1817
+ // Get current music time played (in seconds)
1818
+ float GetMusicTimePlayed(Music music)
1819
+ {
1820
+ float secondsPlayed = 0.0f;
1821
+ if (music.stream.buffer != NULL)
1822
+ {
1823
+ #if defined(SUPPORT_FILEFORMAT_XM)
1824
+ if (music.ctxType == MUSIC_MODULE_XM)
1825
+ {
1826
+ uint64_t framesPlayed = 0;
1827
+
1828
+ jar_xm_get_position(music.ctxData, NULL, NULL, NULL, &framesPlayed);
1829
+ secondsPlayed = (float)framesPlayed/music.stream.sampleRate;
1830
+ }
1831
+ else
1832
+ #endif
1833
+ {
1834
+ //ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(music.stream.buffer->dsp.formatConverterIn.config.formatIn)*music.stream.buffer->dsp.formatConverterIn.config.channels;
1835
+ unsigned int framesPlayed = music.stream.buffer->framesProcessed;
1836
+ secondsPlayed = (float)framesPlayed/music.stream.sampleRate;
1837
+ }
1838
+ }
1839
+
1840
+ return secondsPlayed;
1841
+ }
1842
+
1843
+ // Load audio stream (to stream audio pcm data)
1844
+ AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels)
1845
+ {
1846
+ AudioStream stream = { 0 };
1847
+
1848
+ stream.sampleRate = sampleRate;
1849
+ stream.sampleSize = sampleSize;
1850
+ stream.channels = channels;
1851
+
1852
+ ma_format formatIn = ((stream.sampleSize == 8)? ma_format_u8 : ((stream.sampleSize == 16)? ma_format_s16 : ma_format_f32));
1853
+
1854
+ // The size of a streaming buffer must be at least double the size of a period
1855
+ unsigned int periodSize = AUDIO.System.device.playback.internalPeriodSizeInFrames;
1856
+
1857
+ // If the buffer is not set, compute one that would give us a buffer good enough for a decent frame rate
1858
+ unsigned int subBufferSize = (AUDIO.Buffer.defaultSize == 0)? AUDIO.System.device.sampleRate/30 : AUDIO.Buffer.defaultSize;
1859
+
1860
+ if (subBufferSize < periodSize) subBufferSize = periodSize;
1861
+
1862
+ // Create a double audio buffer of defined size
1863
+ stream.buffer = LoadAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM);
1864
+
1865
+ if (stream.buffer != NULL)
1866
+ {
1867
+ stream.buffer->looping = true; // Always loop for streaming buffers
1868
+ TRACELOG(LOG_INFO, "STREAM: Initialized successfully (%i Hz, %i bit, %s)", stream.sampleRate, stream.sampleSize, (stream.channels == 1)? "Mono" : "Stereo");
1869
+ }
1870
+ else TRACELOG(LOG_WARNING, "STREAM: Failed to load audio buffer, stream could not be created");
1871
+
1872
+ return stream;
1873
+ }
1874
+
1875
+ // Unload audio stream and free memory
1876
+ void UnloadAudioStream(AudioStream stream)
1877
+ {
1878
+ UnloadAudioBuffer(stream.buffer);
1879
+
1880
+ TRACELOG(LOG_INFO, "STREAM: Unloaded audio stream data from RAM");
1881
+ }
1882
+
1883
+ // Update audio stream buffers with data
1884
+ // NOTE 1: Only updates one buffer of the stream source: unqueue -> update -> queue
1885
+ // NOTE 2: To unqueue a buffer it needs to be processed: IsAudioStreamProcessed()
1886
+ void UpdateAudioStream(AudioStream stream, const void *data, int frameCount)
1887
+ {
1888
+ if (stream.buffer != NULL)
1889
+ {
1890
+ if (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1])
1891
+ {
1892
+ ma_uint32 subBufferToUpdate = 0;
1893
+
1894
+ if (stream.buffer->isSubBufferProcessed[0] && stream.buffer->isSubBufferProcessed[1])
1895
+ {
1896
+ // Both buffers are available for updating.
1897
+ // Update the first one and make sure the cursor is moved back to the front.
1898
+ subBufferToUpdate = 0;
1899
+ stream.buffer->frameCursorPos = 0;
1900
+ }
1901
+ else
1902
+ {
1903
+ // Just update whichever sub-buffer is processed.
1904
+ subBufferToUpdate = (stream.buffer->isSubBufferProcessed[0])? 0 : 1;
1905
+ }
1906
+
1907
+ ma_uint32 subBufferSizeInFrames = stream.buffer->sizeInFrames/2;
1908
+ unsigned char *subBuffer = stream.buffer->data + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate);
1909
+
1910
+ // TODO: Get total frames processed on this buffer... DOES NOT WORK.
1911
+ stream.buffer->framesProcessed += subBufferSizeInFrames;
1912
+
1913
+ // Does this API expect a whole buffer to be updated in one go?
1914
+ // Assuming so, but if not will need to change this logic.
1915
+ if (subBufferSizeInFrames >= (ma_uint32)frameCount)
1916
+ {
1917
+ ma_uint32 framesToWrite = subBufferSizeInFrames;
1918
+
1919
+ if (framesToWrite > (ma_uint32)frameCount) framesToWrite = (ma_uint32)frameCount;
1920
+
1921
+ ma_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8);
1922
+ memcpy(subBuffer, data, bytesToWrite);
1923
+
1924
+ // Any leftover frames should be filled with zeros.
1925
+ ma_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite;
1926
+
1927
+ if (leftoverFrameCount > 0) memset(subBuffer + bytesToWrite, 0, leftoverFrameCount*stream.channels*(stream.sampleSize/8));
1928
+
1929
+ stream.buffer->isSubBufferProcessed[subBufferToUpdate] = false;
1930
+ }
1931
+ else TRACELOG(LOG_WARNING, "STREAM: Attempting to write too many frames to buffer");
1932
+ }
1933
+ else TRACELOG(LOG_WARNING, "STREAM: Buffer not available for updating");
1934
+ }
1935
+ }
1936
+
1937
+ // Check if any audio stream buffers requires refill
1938
+ bool IsAudioStreamProcessed(AudioStream stream)
1939
+ {
1940
+ if (stream.buffer == NULL) return false;
1941
+
1942
+ return (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1]);
1943
+ }
1944
+
1945
+ // Play audio stream
1946
+ void PlayAudioStream(AudioStream stream)
1947
+ {
1948
+ PlayAudioBuffer(stream.buffer);
1949
+ }
1950
+
1951
+ // Play audio stream
1952
+ void PauseAudioStream(AudioStream stream)
1953
+ {
1954
+ PauseAudioBuffer(stream.buffer);
1955
+ }
1956
+
1957
+ // Resume audio stream playing
1958
+ void ResumeAudioStream(AudioStream stream)
1959
+ {
1960
+ ResumeAudioBuffer(stream.buffer);
1961
+ }
1962
+
1963
+ // Check if audio stream is playing.
1964
+ bool IsAudioStreamPlaying(AudioStream stream)
1965
+ {
1966
+ return IsAudioBufferPlaying(stream.buffer);
1967
+ }
1968
+
1969
+ // Stop audio stream
1970
+ void StopAudioStream(AudioStream stream)
1971
+ {
1972
+ StopAudioBuffer(stream.buffer);
1973
+ }
1974
+
1975
+ // Set volume for audio stream (1.0 is max level)
1976
+ void SetAudioStreamVolume(AudioStream stream, float volume)
1977
+ {
1978
+ SetAudioBufferVolume(stream.buffer, volume);
1979
+ }
1980
+
1981
+ // Set pitch for audio stream (1.0 is base level)
1982
+ void SetAudioStreamPitch(AudioStream stream, float pitch)
1983
+ {
1984
+ SetAudioBufferPitch(stream.buffer, pitch);
1985
+ }
1986
+
1987
+ // Default size for new audio streams
1988
+ void SetAudioStreamBufferSizeDefault(int size)
1989
+ {
1990
+ AUDIO.Buffer.defaultSize = size;
1991
+ }
1992
+
1993
+ //----------------------------------------------------------------------------------
1994
+ // Module specific Functions Definition
1995
+ //----------------------------------------------------------------------------------
1996
+
1997
+ // Log callback function
1998
+ static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message)
1999
+ {
2000
+ (void)pContext;
2001
+ (void)pDevice;
2002
+
2003
+ TRACELOG(LOG_WARNING, "miniaudio: %s", message); // All log messages from miniaudio are errors
2004
+ }
2005
+
2006
+ // Reads audio data from an AudioBuffer object in internal format.
2007
+ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount)
2008
+ {
2009
+ ma_uint32 subBufferSizeInFrames = (audioBuffer->sizeInFrames > 1)? audioBuffer->sizeInFrames/2 : audioBuffer->sizeInFrames;
2010
+ ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
2011
+
2012
+ if (currentSubBufferIndex > 1) return 0;
2013
+
2014
+ // Another thread can update the processed state of buffers so
2015
+ // we just take a copy here to try and avoid potential synchronization problems
2016
+ bool isSubBufferProcessed[2];
2017
+ isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
2018
+ isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
2019
+
2020
+ ma_uint32 frameSizeInBytes = ma_get_bytes_per_frame(audioBuffer->converter.config.formatIn, audioBuffer->converter.config.channelsIn);
2021
+
2022
+ // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0
2023
+ ma_uint32 framesRead = 0;
2024
+ while (1)
2025
+ {
2026
+ // We break from this loop differently depending on the buffer's usage
2027
+ // - For static buffers, we simply fill as much data as we can
2028
+ // - For streaming buffers we only fill the halves of the buffer that are processed
2029
+ // Unprocessed halves must keep their audio data in-tact
2030
+ if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
2031
+ {
2032
+ if (framesRead >= frameCount) break;
2033
+ }
2034
+ else
2035
+ {
2036
+ if (isSubBufferProcessed[currentSubBufferIndex]) break;
2037
+ }
2038
+
2039
+ ma_uint32 totalFramesRemaining = (frameCount - framesRead);
2040
+ if (totalFramesRemaining == 0) break;
2041
+
2042
+ ma_uint32 framesRemainingInOutputBuffer;
2043
+ if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
2044
+ {
2045
+ framesRemainingInOutputBuffer = audioBuffer->sizeInFrames - audioBuffer->frameCursorPos;
2046
+ }
2047
+ else
2048
+ {
2049
+ ma_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames*currentSubBufferIndex;
2050
+ framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer);
2051
+ }
2052
+
2053
+ ma_uint32 framesToRead = totalFramesRemaining;
2054
+ if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer;
2055
+
2056
+ memcpy((unsigned char *)framesOut + (framesRead*frameSizeInBytes), audioBuffer->data + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes);
2057
+ audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead)%audioBuffer->sizeInFrames;
2058
+ framesRead += framesToRead;
2059
+
2060
+ // If we've read to the end of the buffer, mark it as processed
2061
+ if (framesToRead == framesRemainingInOutputBuffer)
2062
+ {
2063
+ audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true;
2064
+ isSubBufferProcessed[currentSubBufferIndex] = true;
2065
+
2066
+ currentSubBufferIndex = (currentSubBufferIndex + 1)%2;
2067
+
2068
+ // We need to break from this loop if we're not looping
2069
+ if (!audioBuffer->looping)
2070
+ {
2071
+ StopAudioBuffer(audioBuffer);
2072
+ break;
2073
+ }
2074
+ }
2075
+ }
2076
+
2077
+ // Zero-fill excess
2078
+ ma_uint32 totalFramesRemaining = (frameCount - framesRead);
2079
+ if (totalFramesRemaining > 0)
2080
+ {
2081
+ memset((unsigned char *)framesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes);
2082
+
2083
+ // For static buffers we can fill the remaining frames with silence for safety, but we don't want
2084
+ // to report those frames as "read". The reason for this is that the caller uses the return value
2085
+ // to know whether or not a non-looping sound has finished playback.
2086
+ if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining;
2087
+ }
2088
+
2089
+ return framesRead;
2090
+ }
2091
+
2092
+ // Reads audio data from an AudioBuffer object in device format. Returned data will be in a format appropriate for mixing.
2093
+ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount)
2094
+ {
2095
+ // What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which
2096
+ // should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important
2097
+ // detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output
2098
+ // frames. This can be achieved with ma_data_converter_get_required_input_frame_count().
2099
+ ma_uint8 inputBuffer[4096];
2100
+ ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.config.formatIn, audioBuffer->converter.config.channelsIn);
2101
+
2102
+ ma_uint32 totalOutputFramesProcessed = 0;
2103
+ while (totalOutputFramesProcessed < frameCount)
2104
+ {
2105
+ ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed;
2106
+
2107
+ ma_uint64 inputFramesToProcessThisIteration = ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration);
2108
+ if (inputFramesToProcessThisIteration > inputBufferFrameCap)
2109
+ {
2110
+ inputFramesToProcessThisIteration = inputBufferFrameCap;
2111
+ }
2112
+
2113
+ float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.config.channelsOut);
2114
+
2115
+ /* At this point we can convert the data to our mixing format. */
2116
+ ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */
2117
+ ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
2118
+ ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
2119
+
2120
+ totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; /* Safe cast. */
2121
+
2122
+ if (inputFramesProcessedThisIteration < inputFramesToProcessThisIteration)
2123
+ {
2124
+ break; /* Ran out of input data. */
2125
+ }
2126
+
2127
+ /* This should never be hit, but will add it here for safety. Ensures we get out of the loop when no input nor output frames are processed. */
2128
+ if (inputFramesProcessedThisIteration == 0 && outputFramesProcessedThisIteration == 0)
2129
+ {
2130
+ break;
2131
+ }
2132
+ }
2133
+
2134
+ return totalOutputFramesProcessed;
2135
+ }
2136
+
2137
+
2138
+ // Sending audio data to device callback function
2139
+ // This function will be called when miniaudio needs more data
2140
+ // NOTE: All the mixing takes place here
2141
+ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount)
2142
+ {
2143
+ (void)pDevice;
2144
+
2145
+ // Mixing is basically just an accumulation, we need to initialize the output buffer to 0
2146
+ memset(pFramesOut, 0, frameCount*pDevice->playback.channels*ma_get_bytes_per_sample(pDevice->playback.format));
2147
+
2148
+ // Using a mutex here for thread-safety which makes things not real-time
2149
+ // This is unlikely to be necessary for this project, but may want to consider how you might want to avoid this
2150
+ ma_mutex_lock(&AUDIO.System.lock);
2151
+ {
2152
+ for (AudioBuffer *audioBuffer = AUDIO.Buffer.first; audioBuffer != NULL; audioBuffer = audioBuffer->next)
2153
+ {
2154
+ // Ignore stopped or paused sounds
2155
+ if (!audioBuffer->playing || audioBuffer->paused) continue;
2156
+
2157
+ ma_uint32 framesRead = 0;
2158
+
2159
+ while (1)
2160
+ {
2161
+ if (framesRead >= frameCount) break;
2162
+
2163
+ // Just read as much data as we can from the stream
2164
+ ma_uint32 framesToRead = (frameCount - framesRead);
2165
+
2166
+ while (framesToRead > 0)
2167
+ {
2168
+ float tempBuffer[1024]; // 512 frames for stereo
2169
+
2170
+ ma_uint32 framesToReadRightNow = framesToRead;
2171
+ if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/AUDIO_DEVICE_CHANNELS)
2172
+ {
2173
+ framesToReadRightNow = sizeof(tempBuffer)/sizeof(tempBuffer[0])/AUDIO_DEVICE_CHANNELS;
2174
+ }
2175
+
2176
+ ma_uint32 framesJustRead = ReadAudioBufferFramesInMixingFormat(audioBuffer, tempBuffer, framesToReadRightNow);
2177
+ if (framesJustRead > 0)
2178
+ {
2179
+ float *framesOut = (float *)pFramesOut + (framesRead*AUDIO.System.device.playback.channels);
2180
+ float *framesIn = tempBuffer;
2181
+
2182
+ MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
2183
+
2184
+ framesToRead -= framesJustRead;
2185
+ framesRead += framesJustRead;
2186
+ }
2187
+
2188
+ if (!audioBuffer->playing)
2189
+ {
2190
+ framesRead = frameCount;
2191
+ break;
2192
+ }
2193
+
2194
+ // If we weren't able to read all the frames we requested, break
2195
+ if (framesJustRead < framesToReadRightNow)
2196
+ {
2197
+ if (!audioBuffer->looping)
2198
+ {
2199
+ StopAudioBuffer(audioBuffer);
2200
+ break;
2201
+ }
2202
+ else
2203
+ {
2204
+ // Should never get here, but just for safety,
2205
+ // move the cursor position back to the start and continue the loop
2206
+ audioBuffer->frameCursorPos = 0;
2207
+ continue;
2208
+ }
2209
+ }
2210
+ }
2211
+
2212
+ // If for some reason we weren't able to read every frame we'll need to break from the loop
2213
+ // Not doing this could theoretically put us into an infinite loop
2214
+ if (framesToRead > 0) break;
2215
+ }
2216
+ }
2217
+ }
2218
+
2219
+ ma_mutex_unlock(&AUDIO.System.lock);
2220
+ }
2221
+
2222
+ // This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
2223
+ // NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
2224
+ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, float localVolume)
2225
+ {
2226
+ for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
2227
+ {
2228
+ for (ma_uint32 iChannel = 0; iChannel < AUDIO.System.device.playback.channels; ++iChannel)
2229
+ {
2230
+ float *frameOut = framesOut + (iFrame*AUDIO.System.device.playback.channels);
2231
+ const float *frameIn = framesIn + (iFrame*AUDIO.System.device.playback.channels);
2232
+
2233
+ frameOut[iChannel] += (frameIn[iChannel]*localVolume);
2234
+ }
2235
+ }
2236
+ }
2237
+
2238
+ // Some required functions for audio standalone module version
2239
+ #if defined(RAUDIO_STANDALONE)
2240
+ // Check file extension
2241
+ static bool IsFileExtension(const char *fileName, const char *ext)
2242
+ {
2243
+ bool result = false;
2244
+ const char *fileExt;
2245
+
2246
+ if ((fileExt = strrchr(fileName, '.')) != NULL)
2247
+ {
2248
+ if (strcmp(fileExt, ext) == 0) result = true;
2249
+ }
2250
+
2251
+ return result;
2252
+ }
2253
+
2254
+ // Get pointer to extension for a filename string (includes the dot: .png)
2255
+ static const char *GetFileExtension(const char *fileName)
2256
+ {
2257
+ const char *dot = strrchr(fileName, '.');
2258
+
2259
+ if (!dot || dot == fileName) return NULL;
2260
+
2261
+ return dot;
2262
+ }
2263
+
2264
+ // Check if two text string are equal
2265
+ // REQUIRES: strcmp()
2266
+ static bool TextIsEqual(const char *text1, const char *text2)
2267
+ {
2268
+ bool result = false;
2269
+
2270
+ if (strcmp(text1, text2) == 0) result = true;
2271
+
2272
+ return result;
2273
+ }
2274
+
2275
+ // Get lower case version of provided string
2276
+ // REQUIRES: tolower()
2277
+ static const char *TextToLower(const char *text)
2278
+ {
2279
+ #define MAX_TEXT_BUFFER_LENGTH 1024
2280
+
2281
+ static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
2282
+
2283
+ for (int i = 0; i < MAX_TEXT_BUFFER_LENGTH; i++)
2284
+ {
2285
+ if (text[i] != '\0')
2286
+ {
2287
+ buffer[i] = (char)tolower(text[i]);
2288
+ //if ((text[i] >= 'A') && (text[i] <= 'Z')) buffer[i] = text[i] + 32;
2289
+ }
2290
+ else { buffer[i] = '\0'; break; }
2291
+ }
2292
+
2293
+ return buffer;
2294
+ }
2295
+
2296
+ // Load data from file into a buffer
2297
+ static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead)
2298
+ {
2299
+ unsigned char *data = NULL;
2300
+ *bytesRead = 0;
2301
+
2302
+ if (fileName != NULL)
2303
+ {
2304
+ FILE *file = fopen(fileName, "rb");
2305
+
2306
+ if (file != NULL)
2307
+ {
2308
+ // WARNING: On binary streams SEEK_END could not be found,
2309
+ // using fseek() and ftell() could not work in some (rare) cases
2310
+ fseek(file, 0, SEEK_END);
2311
+ int size = ftell(file);
2312
+ fseek(file, 0, SEEK_SET);
2313
+
2314
+ if (size > 0)
2315
+ {
2316
+ data = (unsigned char *)RL_MALLOC(size*sizeof(unsigned char));
2317
+
2318
+ // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements]
2319
+ unsigned int count = (unsigned int)fread(data, sizeof(unsigned char), size, file);
2320
+ *bytesRead = count;
2321
+
2322
+ if (count != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded", fileName);
2323
+ else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName);
2324
+ }
2325
+ else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read file", fileName);
2326
+
2327
+ fclose(file);
2328
+ }
2329
+ else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
2330
+ }
2331
+ else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
2332
+
2333
+ return data;
2334
+ }
2335
+
2336
+ // Save data to file from buffer
2337
+ static bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite)
2338
+ {
2339
+ if (fileName != NULL)
2340
+ {
2341
+ FILE *file = fopen(fileName, "wb");
2342
+
2343
+ if (file != NULL)
2344
+ {
2345
+ unsigned int count = (unsigned int)fwrite(data, sizeof(unsigned char), bytesToWrite, file);
2346
+
2347
+ if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName);
2348
+ else if (count != bytesToWrite) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName);
2349
+ else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName);
2350
+
2351
+ fclose(file);
2352
+ }
2353
+ else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
2354
+ }
2355
+ else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
2356
+ }
2357
+
2358
+ // Save text data to file (write), string must be '\0' terminated
2359
+ static bool SaveFileText(const char *fileName, char *text)
2360
+ {
2361
+ if (fileName != NULL)
2362
+ {
2363
+ FILE *file = fopen(fileName, "wt");
2364
+
2365
+ if (file != NULL)
2366
+ {
2367
+ int count = fprintf(file, "%s", text);
2368
+
2369
+ if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName);
2370
+ else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName);
2371
+
2372
+ fclose(file);
2373
+ }
2374
+ else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
2375
+ }
2376
+ else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
2377
+ }
2378
+ #endif
2379
+
2380
+ #undef AudioBuffer