koffi 2.1.1 → 2.1.2

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 (311) hide show
  1. package/ChangeLog.md +6 -0
  2. package/build/qemu/2.1.2/koffi_darwin_arm64.tar.gz +0 -0
  3. package/build/qemu/2.1.2/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/2.1.2/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/2.1.2/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/2.1.2/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/2.1.2/koffi_linux_arm32hf.tar.gz +0 -0
  8. package/build/qemu/2.1.2/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/2.1.2/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/2.1.2/koffi_linux_riscv64hf64.tar.gz +0 -0
  11. package/build/qemu/2.1.2/koffi_linux_x64.tar.gz +0 -0
  12. package/build/qemu/2.1.2/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/build/qemu/2.1.2/koffi_openbsd_x64.tar.gz +0 -0
  14. package/build/qemu/2.1.2/koffi_win32_arm64.tar.gz +0 -0
  15. package/build/qemu/2.1.2/koffi_win32_ia32.tar.gz +0 -0
  16. package/build/qemu/2.1.2/koffi_win32_x64.tar.gz +0 -0
  17. package/doc/templates/badges.html +3 -0
  18. package/package.json +2 -2
  19. package/src/abi_arm64.cc +35 -1
  20. package/src/abi_x64_win.cc +2 -8
  21. package/src/abi_x86.cc +1 -7
  22. package/src/ffi.hh +1 -1
  23. package/src/util.hh +6 -0
  24. package/test/raylib.js +37 -5
  25. package/vendor/libcc/libcc.cc +430 -196
  26. package/vendor/libcc/libcc.hh +1417 -1283
  27. package/vendor/raylib/BINDINGS.md +87 -70
  28. package/vendor/raylib/CHANGELOG +263 -50
  29. package/vendor/raylib/CMakeLists.txt +12 -0
  30. package/vendor/raylib/CMakeOptions.txt +8 -1
  31. package/vendor/raylib/CONVENTIONS.md +2 -3
  32. package/vendor/raylib/FAQ.md +137 -0
  33. package/vendor/raylib/HISTORY.md +62 -29
  34. package/vendor/raylib/LICENSE +1 -1
  35. package/vendor/raylib/README.md +22 -17
  36. package/vendor/raylib/ROADMAP.md +8 -7
  37. package/vendor/raylib/cmake/CompileDefinitions.cmake +19 -15
  38. package/vendor/raylib/cmake/GlfwImport.cmake +2 -0
  39. package/vendor/raylib/cmake/LibraryConfigurations.cmake +22 -16
  40. package/vendor/raylib/cmake/raylib-config.cmake +52 -49
  41. package/vendor/raylib/examples/CMakeLists.txt +14 -9
  42. package/vendor/raylib/examples/Makefile +112 -125
  43. package/vendor/raylib/examples/Makefile.Android +1 -1
  44. package/vendor/raylib/examples/Makefile.Web +145 -158
  45. package/vendor/raylib/examples/README.md +141 -141
  46. package/vendor/raylib/examples/audio/audio_module_playing.c +9 -4
  47. package/vendor/raylib/examples/audio/audio_multichannel_sound.c +8 -3
  48. package/vendor/raylib/examples/audio/audio_music_stream.c +16 -11
  49. package/vendor/raylib/examples/audio/audio_raw_stream.c +57 -9
  50. package/vendor/raylib/examples/audio/audio_sound_loading.c +8 -3
  51. package/vendor/raylib/examples/audio/audio_stream_effects.c +179 -0
  52. package/vendor/raylib/examples/audio/audio_stream_effects.png +0 -0
  53. package/vendor/raylib/examples/build.zig +17 -6
  54. package/vendor/raylib/examples/core/core_2d_camera.c +8 -4
  55. package/vendor/raylib/examples/core/core_2d_camera_mouse_zoom.c +105 -0
  56. package/vendor/raylib/examples/core/core_2d_camera_mouse_zoom.png +0 -0
  57. package/vendor/raylib/examples/core/core_2d_camera_platformer.c +11 -6
  58. package/vendor/raylib/examples/core/core_3d_camera_first_person.c +9 -4
  59. package/vendor/raylib/examples/core/core_3d_camera_free.c +9 -4
  60. package/vendor/raylib/examples/core/core_3d_camera_mode.c +8 -3
  61. package/vendor/raylib/examples/core/core_3d_picking.c +9 -4
  62. package/vendor/raylib/examples/core/core_basic_screen_manager.c +9 -7
  63. package/vendor/raylib/examples/core/core_basic_window.c +8 -3
  64. package/vendor/raylib/examples/core/core_basic_window_web.c +13 -11
  65. package/vendor/raylib/examples/core/core_custom_frame_control.c +9 -4
  66. package/vendor/raylib/examples/core/core_custom_logging.c +12 -8
  67. package/vendor/raylib/examples/core/core_drop_files.c +20 -12
  68. package/vendor/raylib/examples/core/core_input_gamepad.c +20 -15
  69. package/vendor/raylib/examples/core/core_input_gestures.c +19 -15
  70. package/vendor/raylib/examples/core/core_input_keys.c +8 -3
  71. package/vendor/raylib/examples/core/core_input_mouse.c +8 -3
  72. package/vendor/raylib/examples/core/core_input_mouse_wheel.c +8 -3
  73. package/vendor/raylib/examples/core/core_input_multitouch.c +8 -3
  74. package/vendor/raylib/examples/core/core_loading_thread.c +10 -6
  75. package/vendor/raylib/examples/core/core_random_values.c +8 -3
  76. package/vendor/raylib/examples/core/core_scissor_test.c +8 -3
  77. package/vendor/raylib/examples/core/core_smooth_pixelperfect.c +9 -4
  78. package/vendor/raylib/examples/core/core_split_screen.c +8 -3
  79. package/vendor/raylib/examples/core/core_storage_values.c +109 -3
  80. package/vendor/raylib/examples/core/core_vr_simulator.c +15 -7
  81. package/vendor/raylib/examples/core/core_window_flags.c +8 -3
  82. package/vendor/raylib/examples/core/core_window_letterbox.c +13 -18
  83. package/vendor/raylib/examples/core/core_window_should_close.c +77 -0
  84. package/vendor/raylib/examples/core/core_window_should_close.png +0 -0
  85. package/vendor/raylib/examples/core/core_world_screen.c +9 -4
  86. package/vendor/raylib/examples/examples_template.c +8 -3
  87. package/vendor/raylib/examples/models/models_animation.c +11 -7
  88. package/vendor/raylib/examples/models/models_billboard.c +9 -4
  89. package/vendor/raylib/examples/models/models_box_collisions.c +8 -3
  90. package/vendor/raylib/examples/models/models_cubicmap.c +9 -4
  91. package/vendor/raylib/examples/models/models_first_person_maze.c +9 -4
  92. package/vendor/raylib/examples/models/models_geometric_shapes.c +8 -3
  93. package/vendor/raylib/examples/models/models_heightmap.c +9 -4
  94. package/vendor/raylib/examples/models/models_loading.c +21 -17
  95. package/vendor/raylib/examples/models/models_loading_gltf.c +15 -41
  96. package/vendor/raylib/examples/models/models_loading_vox.c +9 -4
  97. package/vendor/raylib/examples/models/models_mesh_generation.c +71 -58
  98. package/vendor/raylib/examples/models/models_mesh_picking.c +25 -7
  99. package/vendor/raylib/examples/models/models_orthographic_projection.c +8 -5
  100. package/vendor/raylib/examples/models/models_rlgl_solar_system.c +6 -4
  101. package/vendor/raylib/examples/models/models_skybox.c +16 -12
  102. package/vendor/raylib/examples/models/models_waving_cubes.c +9 -4
  103. package/vendor/raylib/examples/models/models_yaw_pitch_roll.c +12 -7
  104. package/vendor/raylib/examples/models/resources/LICENSE.md +9 -10
  105. package/vendor/raylib/examples/models/resources/models/gltf/LICENSE +2 -23
  106. package/vendor/raylib/examples/models/resources/models/gltf/{raylib_32x32.glb → raylib_logo_3d.glb} +0 -0
  107. package/vendor/raylib/examples/models/resources/models/gltf/robot.blend +0 -0
  108. package/vendor/raylib/examples/models/resources/models/gltf/robot.glb +0 -0
  109. package/vendor/raylib/examples/others/easings_testbed.c +10 -8
  110. package/vendor/raylib/examples/others/easings_testbed.png +0 -0
  111. package/vendor/raylib/examples/others/embedded_files_loading.c +10 -5
  112. package/vendor/raylib/examples/others/embedded_files_loading.png +0 -0
  113. package/vendor/raylib/examples/others/raylib_opengl_interop.c +10 -6
  114. package/vendor/raylib/{src/extras/easings.h → examples/others/reasings.h} +38 -38
  115. package/vendor/raylib/examples/others/rlgl_compute_shader.c +21 -20
  116. package/vendor/raylib/examples/others/rlgl_compute_shader.png +0 -0
  117. package/vendor/raylib/examples/others/rlgl_standalone.c +4 -4
  118. package/vendor/raylib/examples/others/rlgl_standalone.png +0 -0
  119. package/vendor/raylib/examples/raylib_compile_execute.bat +2 -2
  120. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs +1 -1
  121. package/vendor/raylib/examples/shaders/resources/shaders/glsl330/{base_lighting_instanced.vs → lighting_instancing.vs} +2 -2
  122. package/vendor/raylib/examples/shaders/rlights.h +14 -27
  123. package/vendor/raylib/examples/shaders/shaders_basic_lighting.c +24 -26
  124. package/vendor/raylib/examples/shaders/shaders_custom_uniform.c +10 -5
  125. package/vendor/raylib/examples/shaders/shaders_eratosthenes.c +13 -8
  126. package/vendor/raylib/examples/shaders/shaders_fog.c +8 -12
  127. package/vendor/raylib/examples/shaders/shaders_hot_reloading.c +10 -5
  128. package/vendor/raylib/examples/shaders/shaders_julia_set.c +9 -4
  129. package/vendor/raylib/examples/shaders/shaders_mesh_instancing.c +45 -119
  130. package/vendor/raylib/examples/shaders/shaders_model_shader.c +10 -5
  131. package/vendor/raylib/examples/shaders/shaders_multi_sample2d.c +8 -3
  132. package/vendor/raylib/examples/shaders/shaders_palette_switch.c +8 -3
  133. package/vendor/raylib/examples/shaders/shaders_postprocessing.c +9 -4
  134. package/vendor/raylib/examples/shaders/shaders_raymarching.c +14 -11
  135. package/vendor/raylib/examples/shaders/shaders_shapes_textures.c +8 -3
  136. package/vendor/raylib/examples/shaders/shaders_simple_mask.c +10 -5
  137. package/vendor/raylib/examples/shaders/shaders_spotlight.c +10 -6
  138. package/vendor/raylib/examples/shaders/shaders_texture_drawing.c +9 -4
  139. package/vendor/raylib/examples/shaders/shaders_texture_outline.c +8 -3
  140. package/vendor/raylib/examples/shaders/shaders_texture_waves.c +8 -3
  141. package/vendor/raylib/{src/extras → examples/shapes}/raygui.h +1290 -1141
  142. package/vendor/raylib/examples/{others/easings.h → shapes/reasings.h} +40 -40
  143. package/vendor/raylib/examples/shapes/shapes_basic_shapes.c +8 -3
  144. package/vendor/raylib/examples/shapes/shapes_bouncing_ball.c +8 -3
  145. package/vendor/raylib/examples/shapes/shapes_collision_area.c +10 -4
  146. package/vendor/raylib/examples/shapes/shapes_colors_palette.c +8 -3
  147. package/vendor/raylib/examples/shapes/shapes_draw_circle_sector.c +9 -4
  148. package/vendor/raylib/examples/shapes/shapes_draw_rectangle_rounded.c +9 -4
  149. package/vendor/raylib/examples/shapes/shapes_draw_ring.c +10 -6
  150. package/vendor/raylib/examples/shapes/shapes_easings_ball_anim.c +9 -4
  151. package/vendor/raylib/examples/shapes/shapes_easings_box_anim.c +9 -4
  152. package/vendor/raylib/examples/shapes/shapes_easings_rectangle_array.c +9 -4
  153. package/vendor/raylib/examples/shapes/shapes_following_eyes.c +8 -3
  154. package/vendor/raylib/examples/shapes/shapes_lines_bezier.c +8 -3
  155. package/vendor/raylib/examples/shapes/shapes_logo_raylib.c +8 -3
  156. package/vendor/raylib/examples/shapes/shapes_logo_raylib_anim.c +8 -3
  157. package/vendor/raylib/examples/shapes/shapes_rectangle_scaling.c +14 -5
  158. package/vendor/raylib/examples/shapes/shapes_top_down_lights.c +355 -0
  159. package/vendor/raylib/examples/shapes/shapes_top_down_lights.png +0 -0
  160. package/vendor/raylib/examples/text/resources/DotGothic16-Regular.ttf +0 -0
  161. package/vendor/raylib/examples/text/resources/DotGothic16-Regular_OFL.txt +93 -0
  162. package/vendor/raylib/examples/text/resources/LICENSE.md +1 -1
  163. package/vendor/raylib/examples/text/text_codepoints_loading.c +138 -0
  164. package/vendor/raylib/examples/text/text_codepoints_loading.png +0 -0
  165. package/vendor/raylib/examples/text/text_draw_3d.c +42 -33
  166. package/vendor/raylib/examples/text/text_font_filters.c +14 -11
  167. package/vendor/raylib/examples/text/text_font_loading.c +9 -4
  168. package/vendor/raylib/examples/text/text_font_sdf.c +9 -4
  169. package/vendor/raylib/examples/text/text_font_spritefont.c +12 -6
  170. package/vendor/raylib/examples/text/text_format_text.c +8 -3
  171. package/vendor/raylib/examples/text/text_input_box.c +8 -3
  172. package/vendor/raylib/examples/text/text_raylib_fonts.c +9 -4
  173. package/vendor/raylib/examples/text/text_rectangle_bounds.c +9 -5
  174. package/vendor/raylib/examples/text/text_unicode.c +9 -7
  175. package/vendor/raylib/examples/text/text_writing_anim.c +8 -3
  176. package/vendor/raylib/examples/textures/resources/scarfy_run.gif +0 -0
  177. package/vendor/raylib/examples/textures/textures_background_scrolling.c +8 -3
  178. package/vendor/raylib/examples/textures/textures_blend_modes.c +8 -3
  179. package/vendor/raylib/examples/textures/textures_bunnymark.c +8 -3
  180. package/vendor/raylib/examples/textures/textures_draw_tiled.c +14 -10
  181. package/vendor/raylib/examples/textures/textures_fog_of_war.c +154 -0
  182. package/vendor/raylib/examples/textures/textures_fog_of_war.png +0 -0
  183. package/vendor/raylib/examples/textures/textures_gif_player.c +121 -0
  184. package/vendor/raylib/examples/textures/textures_gif_player.png +0 -0
  185. package/vendor/raylib/examples/textures/textures_image_drawing.c +8 -3
  186. package/vendor/raylib/examples/textures/textures_image_generation.c +8 -3
  187. package/vendor/raylib/examples/textures/textures_image_loading.c +8 -3
  188. package/vendor/raylib/examples/textures/textures_image_processing.c +8 -3
  189. package/vendor/raylib/examples/textures/textures_image_text.c +8 -3
  190. package/vendor/raylib/examples/textures/textures_logo_raylib.c +8 -3
  191. package/vendor/raylib/examples/textures/textures_mouse_painting.c +9 -4
  192. package/vendor/raylib/examples/textures/textures_npatch_drawing.c +8 -3
  193. package/vendor/raylib/examples/textures/textures_particles_blending.c +8 -3
  194. package/vendor/raylib/examples/textures/textures_polygon.c +9 -5
  195. package/vendor/raylib/examples/textures/textures_raw_data.c +8 -3
  196. package/vendor/raylib/examples/textures/{textures_rectangle.c → textures_sprite_anim.c} +11 -5
  197. package/vendor/raylib/examples/textures/{textures_rectangle.png → textures_sprite_anim.png} +0 -0
  198. package/vendor/raylib/examples/textures/textures_sprite_button.c +8 -3
  199. package/vendor/raylib/examples/textures/textures_sprite_explosion.c +8 -3
  200. package/vendor/raylib/examples/textures/textures_srcrec_dstrec.c +8 -3
  201. package/vendor/raylib/examples/textures/textures_to_image.c +8 -3
  202. package/vendor/raylib/parser/LICENSE +1 -1
  203. package/vendor/raylib/parser/Makefile +28 -0
  204. package/vendor/raylib/parser/README.md +49 -5
  205. package/vendor/raylib/parser/output/raylib_api.json +10717 -0
  206. package/vendor/raylib/parser/output/raylib_api.lua +7435 -0
  207. package/vendor/raylib/parser/{raylib_api.txt → output/raylib_api.txt} +1371 -824
  208. package/vendor/raylib/parser/{raylib_api.xml → output/raylib_api.xml} +827 -595
  209. package/vendor/raylib/parser/raylib_parser.c +1174 -196
  210. package/vendor/raylib/projects/4coder/Makefile +2 -4
  211. package/vendor/raylib/projects/4coder/main.c +0 -1
  212. package/vendor/raylib/projects/CMake/CMakeLists.txt +13 -16
  213. package/vendor/raylib/projects/CMake/README.md +27 -0
  214. package/vendor/raylib/projects/CMake/core_basic_window.c +52 -31
  215. package/vendor/raylib/projects/CodeBlocks/README.md +4 -4
  216. package/vendor/raylib/projects/Geany/core_basic_window.c +1 -1
  217. package/vendor/raylib/projects/Notepad++/c_raylib.xml +168 -128
  218. package/vendor/raylib/projects/Notepad++/npes_saved_tcc.txt +0 -0
  219. package/vendor/raylib/projects/Notepad++/npes_saved_w64devkit.txt +0 -0
  220. package/vendor/raylib/projects/Notepad++/npes_saved_zig.txt +0 -0
  221. package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +168 -84
  222. package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +67 -51
  223. package/vendor/raylib/projects/README.md +1 -1
  224. package/vendor/raylib/projects/VSCode/.vscode/c_cpp_properties.json +1 -1
  225. package/vendor/raylib/projects/VSCode/Makefile +8 -11
  226. package/vendor/raylib/projects/VSCode/main.c +53 -26
  227. package/vendor/raylib/projects/VSCode/resources/LICENSE +1 -0
  228. package/vendor/raylib/projects/scripts/build-linux.sh +6 -6
  229. package/vendor/raylib/projects/scripts/build-osx.sh +6 -6
  230. package/vendor/raylib/projects/scripts/build-rpi.sh +6 -6
  231. package/vendor/raylib/projects/scripts/build-windows.bat +2 -2
  232. package/vendor/raylib/src/CMakeLists.txt +6 -7
  233. package/vendor/raylib/src/Makefile +209 -103
  234. package/vendor/raylib/src/build.zig +56 -20
  235. package/vendor/raylib/src/config.h +32 -27
  236. package/vendor/raylib/src/external/cgltf.h +342 -104
  237. package/vendor/raylib/src/external/dr_wav.h +487 -225
  238. package/vendor/raylib/src/external/glfw/src/posix_time.c +1 -3
  239. package/vendor/raylib/src/external/glfw/src/wl_init.c +1 -3
  240. package/vendor/raylib/src/external/jar_xm.h +2 -1
  241. package/vendor/raylib/src/external/miniaudio.h +62251 -42061
  242. package/vendor/raylib/src/external/qoi.h +671 -0
  243. package/vendor/raylib/src/external/stb_vorbis.h +1 -1
  244. package/vendor/raylib/src/external/vox_loader.h +30 -25
  245. package/vendor/raylib/src/minshell.html +82 -0
  246. package/vendor/raylib/src/raudio.c +359 -201
  247. package/vendor/raylib/src/raylib.dll.rc +5 -5
  248. package/vendor/raylib/src/raylib.dll.rc.data +0 -0
  249. package/vendor/raylib/src/raylib.h +95 -63
  250. package/vendor/raylib/src/raylib.rc +5 -5
  251. package/vendor/raylib/src/raylib.rc.data +0 -0
  252. package/vendor/raylib/src/raymath.h +391 -133
  253. package/vendor/raylib/src/rcamera.h +32 -41
  254. package/vendor/raylib/src/rcore.c +775 -471
  255. package/vendor/raylib/src/rgestures.h +5 -5
  256. package/vendor/raylib/src/rglfw.c +3 -3
  257. package/vendor/raylib/src/rlgl.h +184 -144
  258. package/vendor/raylib/src/rmodels.c +207 -144
  259. package/vendor/raylib/src/rshapes.c +105 -47
  260. package/vendor/raylib/src/rtext.c +255 -38
  261. package/vendor/raylib/src/rtextures.c +167 -71
  262. package/vendor/raylib/src/shell.html +63 -63
  263. package/vendor/raylib/src/utils.c +49 -3
  264. package/vendor/raylib/src/utils.h +3 -3
  265. package/build/qemu/2.1.1/koffi_darwin_arm64.tar.gz +0 -0
  266. package/build/qemu/2.1.1/koffi_darwin_x64.tar.gz +0 -0
  267. package/build/qemu/2.1.1/koffi_freebsd_arm64.tar.gz +0 -0
  268. package/build/qemu/2.1.1/koffi_freebsd_ia32.tar.gz +0 -0
  269. package/build/qemu/2.1.1/koffi_freebsd_x64.tar.gz +0 -0
  270. package/build/qemu/2.1.1/koffi_linux_arm32hf.tar.gz +0 -0
  271. package/build/qemu/2.1.1/koffi_linux_arm64.tar.gz +0 -0
  272. package/build/qemu/2.1.1/koffi_linux_ia32.tar.gz +0 -0
  273. package/build/qemu/2.1.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  274. package/build/qemu/2.1.1/koffi_linux_x64.tar.gz +0 -0
  275. package/build/qemu/2.1.1/koffi_openbsd_ia32.tar.gz +0 -0
  276. package/build/qemu/2.1.1/koffi_openbsd_x64.tar.gz +0 -0
  277. package/build/qemu/2.1.1/koffi_win32_arm64.tar.gz +0 -0
  278. package/build/qemu/2.1.1/koffi_win32_ia32.tar.gz +0 -0
  279. package/build/qemu/2.1.1/koffi_win32_x64.tar.gz +0 -0
  280. package/vendor/raylib/CONTRIBUTORS.md +0 -63
  281. package/vendor/raylib/SPONSORS.md +0 -68
  282. package/vendor/raylib/examples/core/core_quat_conversion.c +0 -132
  283. package/vendor/raylib/examples/core/core_quat_conversion.png +0 -0
  284. package/vendor/raylib/examples/models/resources/models/gltf/AnimatedMorphCube.glb +0 -0
  285. package/vendor/raylib/examples/models/resources/models/gltf/AnimatedTriangle.gltf +0 -118
  286. package/vendor/raylib/examples/models/resources/models/gltf/BoxAnimated.glb +0 -0
  287. package/vendor/raylib/examples/models/resources/models/gltf/girl.glb +0 -0
  288. package/vendor/raylib/examples/models/resources/models/gltf/rigged_figure.glb +0 -0
  289. package/vendor/raylib/examples/models/resources/models/gltf/vertex_colored_object.glb +0 -0
  290. package/vendor/raylib/examples/models/resources/models/iqm/vertex_colored_object.iqm +0 -0
  291. package/vendor/raylib/examples/models/rlights.h +0 -183
  292. package/vendor/raylib/examples/others/raudio_standalone.c +0 -152
  293. package/vendor/raylib/examples/others/resources/audio/country.mp3 +0 -0
  294. package/vendor/raylib/examples/others/resources/audio/target.ogg +0 -0
  295. package/vendor/raylib/examples/others/resources/audio/weird.wav +0 -0
  296. package/vendor/raylib/examples/physics/physics_demo.c +0 -128
  297. package/vendor/raylib/examples/physics/physics_demo.png +0 -0
  298. package/vendor/raylib/examples/physics/physics_friction.c +0 -142
  299. package/vendor/raylib/examples/physics/physics_friction.png +0 -0
  300. package/vendor/raylib/examples/physics/physics_movement.c +0 -128
  301. package/vendor/raylib/examples/physics/physics_movement.png +0 -0
  302. package/vendor/raylib/examples/physics/physics_restitution.c +0 -129
  303. package/vendor/raylib/examples/physics/physics_restitution.png +0 -0
  304. package/vendor/raylib/examples/physics/physics_shatter.c +0 -111
  305. package/vendor/raylib/examples/physics/physics_shatter.png +0 -0
  306. package/vendor/raylib/parser/raylib_api.json +0 -6668
  307. package/vendor/raylib/projects/VS2019/raylib/raylib.rc +0 -0
  308. package/vendor/raylib/projects/VS2019/raylib/resource.h +0 -14
  309. package/vendor/raylib/src/extras/physac.h +0 -1977
  310. package/vendor/raylib/src/extras/rmem.h +0 -751
  311. package/vendor/raylib/src/raudio.h +0 -198
@@ -1,6 +1,6 @@
1
1
  /**********************************************************************************************
2
2
  *
3
- * raudio v1.0 - A simple and easy-to-use audio library based on miniaudio
3
+ * raudio v1.1 - A simple and easy-to-use audio library based on miniaudio
4
4
  *
5
5
  * FEATURES:
6
6
  * - Manage audio device (init/close)
@@ -12,6 +12,9 @@
12
12
  *
13
13
  * CONFIGURATION:
14
14
  *
15
+ * #define SUPPORT_MODULE_RAUDIO
16
+ * raudio module is included in the build
17
+ *
15
18
  * #define RAUDIO_STANDALONE
16
19
  * Define to use the module as standalone library (independently of raylib).
17
20
  * Required types and functions are defined in the same module.
@@ -47,7 +50,7 @@
47
50
  *
48
51
  * LICENSE: zlib/libpng
49
52
  *
50
- * Copyright (c) 2013-2021 Ramon Santamaria (@raysan5)
53
+ * Copyright (c) 2013-2022 Ramon Santamaria (@raysan5)
51
54
  *
52
55
  * This software is provided "as-is", without any express or implied warranty. In no event
53
56
  * will the authors be held liable for any damages arising from the use of this software.
@@ -68,9 +71,9 @@
68
71
 
69
72
  #if defined(RAUDIO_STANDALONE)
70
73
  #include "raudio.h"
71
- #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
72
74
  #else
73
75
  #include "raylib.h" // Declares module functions
76
+
74
77
  // Check if config flags have been externally provided on compilation line
75
78
  #if !defined(EXTERNAL_CONFIG_FLAGS)
76
79
  #include "config.h" // Defines module configuration flags
@@ -78,6 +81,8 @@
78
81
  #include "utils.h" // Required for: fopen() Android mapping
79
82
  #endif
80
83
 
84
+ #if defined(SUPPORT_MODULE_RAUDIO)
85
+
81
86
  #if defined(_WIN32)
82
87
  // To avoid conflicting windows.h symbols with raylib, some flags are defined
83
88
  // WARNING: Those flags avoid inclusion of some Win32 headers that could be required
@@ -169,26 +174,25 @@ typedef struct tagBITMAPINFOHEADER {
169
174
 
170
175
  #include <stdlib.h> // Required for: malloc(), free()
171
176
  #include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
177
+ #include <string.h> // Required for: strcmp() [Used in IsFileExtension(), LoadWaveFromMemory(), LoadMusicStreamFromMemory()]
172
178
 
173
179
  #if defined(RAUDIO_STANDALONE)
174
- #include <string.h> // Required for: strcmp() [Used in IsFileExtension()]
175
-
176
180
  #ifndef TRACELOG
177
- #define TRACELOG(level, ...) (void)0
181
+ #define TRACELOG(level, ...) printf(__VA_ARGS__)
178
182
  #endif
179
183
 
180
184
  // Allow custom memory allocators
181
185
  #ifndef RL_MALLOC
182
- #define RL_MALLOC(sz) malloc(sz)
186
+ #define RL_MALLOC(sz) malloc(sz)
183
187
  #endif
184
188
  #ifndef RL_CALLOC
185
- #define RL_CALLOC(n,sz) calloc(n,sz)
189
+ #define RL_CALLOC(n,sz) calloc(n,sz)
186
190
  #endif
187
191
  #ifndef RL_REALLOC
188
- #define RL_REALLOC(ptr,sz) realloc(ptr,sz)
192
+ #define RL_REALLOC(ptr,sz) realloc(ptr,sz)
189
193
  #endif
190
194
  #ifndef RL_FREE
191
- #define RL_FREE(ptr) free(ptr)
195
+ #define RL_FREE(ptr) free(ptr)
192
196
  #endif
193
197
  #endif
194
198
 
@@ -243,10 +247,6 @@ typedef struct tagBITMAPINFOHEADER {
243
247
  #include "external/dr_flac.h" // FLAC loading functions
244
248
  #endif
245
249
 
246
- #if defined(_MSC_VER)
247
- #undef bool
248
- #endif
249
-
250
250
  //----------------------------------------------------------------------------------
251
251
  // Defines and Macros
252
252
  //----------------------------------------------------------------------------------
@@ -263,10 +263,6 @@ typedef struct tagBITMAPINFOHEADER {
263
263
  #ifndef MAX_AUDIO_BUFFER_POOL_CHANNELS
264
264
  #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Audio pool channels
265
265
  #endif
266
- #ifndef DEFAULT_AUDIO_BUFFER_SIZE
267
- #define DEFAULT_AUDIO_BUFFER_SIZE 4096 // Default audio buffer size
268
- #endif
269
-
270
266
 
271
267
  //----------------------------------------------------------------------------------
272
268
  // Types and Structures Definition
@@ -307,16 +303,20 @@ typedef enum {
307
303
  AUDIO_BUFFER_USAGE_STREAM
308
304
  } AudioBufferUsage;
309
305
 
310
- // Audio buffer structure
306
+ // Audio buffer struct
311
307
  struct rAudioBuffer {
312
308
  ma_data_converter converter; // Audio data converter
313
309
 
310
+ AudioCallback callback; // Audio buffer callback for buffer filling on audio threads
311
+ rAudioProcessor *processor; // Audio processor
312
+
314
313
  float volume; // Audio buffer volume
315
314
  float pitch; // Audio buffer pitch
315
+ float pan; // Audio buffer pan (0.0f to 1.0f)
316
316
 
317
317
  bool playing; // Audio buffer state: AUDIO_PLAYING
318
318
  bool paused; // Audio buffer state: AUDIO_PAUSED
319
- bool looping; // Audio buffer looping, always true for AudioStreams
319
+ bool looping; // Audio buffer looping, default to true for AudioStreams
320
320
  int usage; // Audio buffer usage mode: STATIC or STREAM
321
321
 
322
322
  bool isSubBufferProcessed[2]; // SubBuffer processed (virtual double buffer)
@@ -330,6 +330,14 @@ struct rAudioBuffer {
330
330
  rAudioBuffer *prev; // Previous audio buffer on the list
331
331
  };
332
332
 
333
+ // Audio processor struct
334
+ // NOTE: Useful to apply effects to an AudioBuffer
335
+ struct rAudioProcessor {
336
+ AudioCallback process; // Processor callback function
337
+ rAudioProcessor *next; // Next audio processor on the list
338
+ rAudioProcessor *prev; // Previous audio processor on the list
339
+ };
340
+
333
341
  #define AudioBuffer rAudioBuffer // HACK: To avoid CoreAudio (macOS) symbol collision
334
342
 
335
343
  // Audio data context
@@ -339,6 +347,8 @@ typedef struct AudioData {
339
347
  ma_device device; // miniaudio device
340
348
  ma_mutex lock; // miniaudio mutex lock
341
349
  bool isReady; // Check if audio device is ready
350
+ size_t pcmBufferSize; // Pre-allocated buffer size
351
+ void *pcmBuffer; // Pre-allocated buffer to read audio data from file/memory
342
352
  } System;
343
353
  struct {
344
354
  AudioBuffer *first; // Pointer to first AudioBuffer in the list
@@ -367,15 +377,13 @@ static AudioData AUDIO = { // Global AUDIO context
367
377
  //----------------------------------------------------------------------------------
368
378
  // Module specific Functions Declaration
369
379
  //----------------------------------------------------------------------------------
370
- static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message);
380
+ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage);
371
381
  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);
382
+ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer);
373
383
 
374
384
  #if defined(RAUDIO_STANDALONE)
375
385
  static bool IsFileExtension(const char *fileName, const char *ext); // Check file extension
376
386
  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
387
 
380
388
  static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
381
389
  static bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write)
@@ -396,6 +404,7 @@ void PauseAudioBuffer(AudioBuffer *buffer);
396
404
  void ResumeAudioBuffer(AudioBuffer *buffer);
397
405
  void SetAudioBufferVolume(AudioBuffer *buffer, float volume);
398
406
  void SetAudioBufferPitch(AudioBuffer *buffer, float pitch);
407
+ void SetAudioBufferPan(AudioBuffer *buffer, float pan);
399
408
  void TrackAudioBuffer(AudioBuffer *buffer);
400
409
  void UntrackAudioBuffer(AudioBuffer *buffer);
401
410
 
@@ -407,7 +416,7 @@ void InitAudioDevice(void)
407
416
  {
408
417
  // Init audio context
409
418
  ma_context_config ctxConfig = ma_context_config_init();
410
- ctxConfig.logCallback = OnLog;
419
+ ma_log_callback_init(OnLog, NULL);
411
420
 
412
421
  ma_result result = ma_context_init(NULL, 0, &ctxConfig, &AUDIO.System.context);
413
422
  if (result != MA_SUCCESS)
@@ -461,8 +470,7 @@ void InitAudioDevice(void)
461
470
  // Init dummy audio buffers pool for multichannel sound playing
462
471
  for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
463
472
  {
464
- // WARNING: An empty audio buffer is created (data = 0)
465
- // AudioBuffer data just points to loaded sound data
473
+ // WARNING: An empty audio buffer is created (data = 0) and added to list, AudioBuffer data is filled on PlaySoundMulti()
466
474
  AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
467
475
  }
468
476
 
@@ -488,7 +496,7 @@ void CloseAudioDevice(void)
488
496
  //UnloadAudioBuffer(AUDIO.MultiChannel.pool[i]);
489
497
  if (AUDIO.MultiChannel.pool[i] != NULL)
490
498
  {
491
- ma_data_converter_uninit(&AUDIO.MultiChannel.pool[i]->converter);
499
+ ma_data_converter_uninit(&AUDIO.MultiChannel.pool[i]->converter, NULL);
492
500
  UntrackAudioBuffer(AUDIO.MultiChannel.pool[i]);
493
501
  //RL_FREE(buffer->data); // Already unloaded by UnloadSound()
494
502
  RL_FREE(AUDIO.MultiChannel.pool[i]);
@@ -500,6 +508,7 @@ void CloseAudioDevice(void)
500
508
  ma_context_uninit(&AUDIO.System.context);
501
509
 
502
510
  AUDIO.System.isReady = false;
511
+ RL_FREE(AUDIO.System.pcmBuffer);
503
512
 
504
513
  TRACELOG(LOG_INFO, "AUDIO: Device closed successfully");
505
514
  }
@@ -537,9 +546,9 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
537
546
 
538
547
  // Audio data runs through a format converter
539
548
  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
549
+ converterConfig.allowDynamicSampleRate = true;
541
550
 
542
- ma_result result = ma_data_converter_init(&converterConfig, &audioBuffer->converter);
551
+ ma_result result = ma_data_converter_init(&converterConfig, NULL, &audioBuffer->converter);
543
552
 
544
553
  if (result != MA_SUCCESS)
545
554
  {
@@ -551,9 +560,15 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
551
560
  // Init audio buffer values
552
561
  audioBuffer->volume = 1.0f;
553
562
  audioBuffer->pitch = 1.0f;
563
+ audioBuffer->pan = 0.5f;
564
+
565
+ audioBuffer->callback = NULL;
566
+ audioBuffer->processor = NULL;
567
+
554
568
  audioBuffer->playing = false;
555
569
  audioBuffer->paused = false;
556
570
  audioBuffer->looping = false;
571
+
557
572
  audioBuffer->usage = usage;
558
573
  audioBuffer->frameCursorPos = 0;
559
574
  audioBuffer->sizeInFrames = sizeInFrames;
@@ -574,7 +589,7 @@ void UnloadAudioBuffer(AudioBuffer *buffer)
574
589
  {
575
590
  if (buffer != NULL)
576
591
  {
577
- ma_data_converter_uninit(&buffer->converter);
592
+ ma_data_converter_uninit(&buffer->converter, NULL);
578
593
  UntrackAudioBuffer(buffer);
579
594
  RL_FREE(buffer->data);
580
595
  RL_FREE(buffer);
@@ -648,13 +663,22 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
648
663
  // Note that this changes the duration of the sound:
649
664
  // - higher pitches will make the sound faster
650
665
  // - 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);
666
+ ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.sampleRateOut/pitch);
667
+ ma_data_converter_set_rate(&buffer->converter, buffer->converter.sampleRateIn, outputSampleRate);
653
668
 
654
669
  buffer->pitch = pitch;
655
670
  }
656
671
  }
657
672
 
673
+ // Set pan for an audio buffer
674
+ void SetAudioBufferPan(AudioBuffer *buffer, float pan)
675
+ {
676
+ if (pan < 0.0f) pan = 0.0f;
677
+ else if (pan > 1.0f) pan = 1.0f;
678
+
679
+ if (buffer != NULL) buffer->pan = pan;
680
+ }
681
+
658
682
  // Track audio buffer to linked list next position
659
683
  void TrackAudioBuffer(AudioBuffer *buffer)
660
684
  {
@@ -711,16 +735,14 @@ Wave LoadWave(const char *fileName)
711
735
  }
712
736
 
713
737
  // Load wave from memory buffer, fileType refers to extension: i.e. ".wav"
738
+ // WARNING: File extension must be provided in lower-case
714
739
  Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize)
715
740
  {
716
741
  Wave wave = { 0 };
717
742
 
718
- char fileExtLower[16] = { 0 };
719
- strcpy(fileExtLower, TextToLower(fileType));
720
-
721
743
  if (false) { }
722
744
  #if defined(SUPPORT_FILEFORMAT_WAV)
723
- else if (TextIsEqual(fileExtLower, ".wav"))
745
+ else if (strcmp(fileType, ".wav") == 0)
724
746
  {
725
747
  drwav wav = { 0 };
726
748
  bool success = drwav_init_memory(&wav, fileData, dataSize, NULL);
@@ -742,7 +764,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
742
764
  }
743
765
  #endif
744
766
  #if defined(SUPPORT_FILEFORMAT_OGG)
745
- else if (TextIsEqual(fileExtLower, ".ogg"))
767
+ else if (strcmp(fileType, ".ogg") == 0)
746
768
  {
747
769
  stb_vorbis *oggData = stb_vorbis_open_memory((unsigned char *)fileData, dataSize, NULL, NULL);
748
770
 
@@ -764,7 +786,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
764
786
  }
765
787
  #endif
766
788
  #if defined(SUPPORT_FILEFORMAT_FLAC)
767
- else if (TextIsEqual(fileExtLower, ".flac"))
789
+ else if (strcmp(fileType, ".flac") == 0)
768
790
  {
769
791
  unsigned long long int totalFrameCount = 0;
770
792
 
@@ -777,7 +799,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
777
799
  }
778
800
  #endif
779
801
  #if defined(SUPPORT_FILEFORMAT_MP3)
780
- else if (TextIsEqual(fileExtLower, ".mp3"))
802
+ else if (strcmp(fileType, ".mp3") == 0)
781
803
  {
782
804
  drmp3_config config = { 0 };
783
805
  unsigned long long int totalFrameCount = 0;
@@ -862,17 +884,15 @@ Sound LoadSoundFromWave(Wave wave)
862
884
  // Unload wave data
863
885
  void UnloadWave(Wave wave)
864
886
  {
865
- if (wave.data != NULL) RL_FREE(wave.data);
866
-
867
- TRACELOG(LOG_INFO, "WAVE: Unloaded wave data from RAM");
887
+ RL_FREE(wave.data);
888
+ //TRACELOG(LOG_INFO, "WAVE: Unloaded wave data from RAM");
868
889
  }
869
890
 
870
891
  // Unload sound
871
892
  void UnloadSound(Sound sound)
872
893
  {
873
894
  UnloadAudioBuffer(sound.stream.buffer);
874
-
875
- TRACELOG(LOG_INFO, "WAVE: Unloaded sound data from RAM");
895
+ //TRACELOG(LOG_INFO, "SOUND: Unloaded sound data from RAM");
876
896
  }
877
897
 
878
898
  // Update sound buffer with new data
@@ -883,7 +903,7 @@ void UpdateSound(Sound sound, const void *data, int sampleCount)
883
903
  StopAudioBuffer(sound.stream.buffer);
884
904
 
885
905
  // 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));
906
+ memcpy(sound.stream.buffer->data, data, sampleCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.formatIn, sound.stream.buffer->converter.channelsIn));
887
907
  }
888
908
  }
889
909
 
@@ -899,7 +919,8 @@ bool ExportWave(Wave wave, const char *fileName)
899
919
  drwav wav = { 0 };
900
920
  drwav_data_format format = { 0 };
901
921
  format.container = drwav_container_riff;
902
- format.format = DR_WAVE_FORMAT_PCM;
922
+ if (wave.sampleSize == 32) format.format = DR_WAVE_FORMAT_IEEE_FLOAT;
923
+ else format.format = DR_WAVE_FORMAT_PCM;
903
924
  format.channels = wave.channels;
904
925
  format.sampleRate = wave.sampleRate;
905
926
  format.bitsPerSample = wave.sampleSize;
@@ -946,42 +967,50 @@ bool ExportWaveAsCode(Wave wave, const char *fileName)
946
967
  int byteCount = 0;
947
968
  byteCount += sprintf(txtData + byteCount, "\n//////////////////////////////////////////////////////////////////////////////////\n");
948
969
  byteCount += sprintf(txtData + byteCount, "// //\n");
949
- byteCount += sprintf(txtData + byteCount, "// WaveAsCode exporter v1.0 - Wave data exported as an array of bytes //\n");
970
+ byteCount += sprintf(txtData + byteCount, "// WaveAsCode exporter v1.1 - Wave data exported as an array of bytes //\n");
950
971
  byteCount += sprintf(txtData + byteCount, "// //\n");
951
972
  byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
952
973
  byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
953
974
  byteCount += sprintf(txtData + byteCount, "// //\n");
954
- byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2021 Ramon Santamaria (@raysan5) //\n");
975
+ byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2022 Ramon Santamaria (@raysan5) //\n");
955
976
  byteCount += sprintf(txtData + byteCount, "// //\n");
956
977
  byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n");
957
978
 
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
979
+ char fileNameLower[256] = { 0 };
980
+ char fileNameUpper[256] = { 0 };
981
+ for (int i = 0; fileName[i] != '.'; i++) { fileNameLower[i] = fileName[i]; } // Get filename without extension
982
+ for (int i = 0; fileNameLower[i] != '\0'; i++) if (fileNameLower[i] >= 'a' && fileNameLower[i] <= 'z') { fileNameUpper[i] = fileNameLower[i] - 32; }
966
983
 
967
984
  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]);
985
+ byteCount += sprintf(txtData + byteCount, "#define %s_FRAME_COUNT %u\n", fileNameUpper, wave.frameCount);
986
+ byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_RATE %u\n", fileNameUpper, wave.sampleRate);
987
+ byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_SIZE %u\n", fileNameUpper, wave.sampleSize);
988
+ byteCount += sprintf(txtData + byteCount, "#define %s_CHANNELS %u\n\n", fileNameUpper, wave.channels);
989
+
990
+ // Write wave data as an array of values
991
+ // Wave data is exported as byte array for 8/16bit and float array for 32bit float data
992
+ // NOTE: Frame data exported is channel-interlaced: frame01[sampleChannel1, sampleChannel2, ...], frame02[], frame03[]
993
+ if (wave.sampleSize == 32)
994
+ {
995
+ byteCount += sprintf(txtData + byteCount, "static float %sData[%i] = {\n", fileNameLower, waveDataSize/4);
996
+ for (int i = 1; i < waveDataSize/4; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.4ff,\n " : "%.4ff, "), ((float *)wave.data)[i - 1]);
997
+ byteCount += sprintf(txtData + byteCount, "%.4ff };\n", ((float *)wave.data)[waveDataSize/4 - 1]);
998
+ }
999
+ else
1000
+ {
1001
+ byteCount += sprintf(txtData + byteCount, "static unsigned char %sData[%i] = { ", fileNameLower, waveDataSize);
1002
+ for (int i = 1; i < waveDataSize; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n " : "0x%x, "), ((unsigned char *)wave.data)[i - 1]);
1003
+ byteCount += sprintf(txtData + byteCount, "0x%x };\n", ((unsigned char *)wave.data)[waveDataSize - 1]);
1004
+ }
979
1005
 
980
1006
  // NOTE: Text data length exported is determined by '\0' (NULL) character
981
1007
  success = SaveFileText(fileName, txtData);
982
1008
 
983
1009
  RL_FREE(txtData);
984
1010
 
1011
+ if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave as code exported successfully", fileName);
1012
+ else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave as code", fileName);
1013
+
985
1014
  return success;
986
1015
  }
987
1016
 
@@ -1039,14 +1068,17 @@ void PlaySoundMulti(Sound sound)
1039
1068
  AUDIO.MultiChannel.channels[index] = AUDIO.MultiChannel.poolCounter;
1040
1069
  AUDIO.MultiChannel.poolCounter++;
1041
1070
 
1042
- AUDIO.MultiChannel.pool[index]->volume = sound.stream.buffer->volume;
1043
- AUDIO.MultiChannel.pool[index]->pitch = sound.stream.buffer->pitch;
1071
+ SetAudioBufferVolume(AUDIO.MultiChannel.pool[index], sound.stream.buffer->volume);
1072
+ SetAudioBufferPitch(AUDIO.MultiChannel.pool[index], sound.stream.buffer->pitch);
1073
+ SetAudioBufferPan(AUDIO.MultiChannel.pool[index], sound.stream.buffer->pan);
1074
+
1044
1075
  AUDIO.MultiChannel.pool[index]->looping = sound.stream.buffer->looping;
1045
1076
  AUDIO.MultiChannel.pool[index]->usage = sound.stream.buffer->usage;
1046
1077
  AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[0] = false;
1047
1078
  AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[1] = false;
1048
1079
  AUDIO.MultiChannel.pool[index]->sizeInFrames = sound.stream.buffer->sizeInFrames;
1049
- AUDIO.MultiChannel.pool[index]->data = sound.stream.buffer->data;
1080
+
1081
+ AUDIO.MultiChannel.pool[index]->data = sound.stream.buffer->data; // Fill dummy track with data for playing
1050
1082
 
1051
1083
  PlayAudioBuffer(AUDIO.MultiChannel.pool[index]);
1052
1084
  }
@@ -1106,6 +1138,12 @@ void SetSoundPitch(Sound sound, float pitch)
1106
1138
  SetAudioBufferPitch(sound.stream.buffer, pitch);
1107
1139
  }
1108
1140
 
1141
+ // Set pan for a sound
1142
+ void SetSoundPan(Sound sound, float pan)
1143
+ {
1144
+ SetAudioBufferPan(sound.stream.buffer, pan);
1145
+ }
1146
+
1109
1147
  // Convert wave data to desired format
1110
1148
  void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
1111
1149
  {
@@ -1113,8 +1151,8 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
1113
1151
  ma_format formatOut = ((sampleSize == 8)? ma_format_u8 : ((sampleSize == 16)? ma_format_s16 : ma_format_f32));
1114
1152
 
1115
1153
  ma_uint32 frameCountIn = wave->frameCount;
1116
-
1117
1154
  ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, 0, formatOut, channels, sampleRate, NULL, frameCountIn, formatIn, wave->channels, wave->sampleRate);
1155
+
1118
1156
  if (frameCount == 0)
1119
1157
  {
1120
1158
  TRACELOG(LOG_WARNING, "WAVE: Failed to get frame count for format conversion");
@@ -1134,6 +1172,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
1134
1172
  wave->sampleSize = sampleSize;
1135
1173
  wave->sampleRate = sampleRate;
1136
1174
  wave->channels = channels;
1175
+
1137
1176
  RL_FREE(wave->data);
1138
1177
  wave->data = data;
1139
1178
  }
@@ -1163,8 +1202,7 @@ Wave WaveCopy(Wave wave)
1163
1202
  // NOTE: Security check in case of out-of-range
1164
1203
  void WaveCrop(Wave *wave, int initSample, int finalSample)
1165
1204
  {
1166
- if ((initSample >= 0) && (initSample < finalSample) &&
1167
- (finalSample > 0) && ((unsigned int)finalSample < (wave->frameCount*wave->channels)))
1205
+ if ((initSample >= 0) && (initSample < finalSample) && ((unsigned int)finalSample < (wave->frameCount*wave->channels)))
1168
1206
  {
1169
1207
  int sampleCount = finalSample - initSample;
1170
1208
 
@@ -1377,18 +1415,16 @@ Music LoadMusicStream(const char *fileName)
1377
1415
  return music;
1378
1416
  }
1379
1417
 
1380
- // extension including period ".mod"
1381
- Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int dataSize)
1418
+ // Load music stream from memory buffer, fileType refers to extension: i.e. ".wav"
1419
+ // WARNING: File extension must be provided in lower-case
1420
+ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize)
1382
1421
  {
1383
1422
  Music music = { 0 };
1384
1423
  bool musicLoaded = false;
1385
1424
 
1386
- char fileExtLower[16] = { 0 };
1387
- strcpy(fileExtLower, TextToLower(fileType));
1388
-
1389
1425
  if (false) { }
1390
1426
  #if defined(SUPPORT_FILEFORMAT_WAV)
1391
- else if (TextIsEqual(fileExtLower, ".wav"))
1427
+ else if (strcmp(fileType, ".wav") == 0)
1392
1428
  {
1393
1429
  drwav *ctxWav = RL_CALLOC(1, sizeof(drwav));
1394
1430
 
@@ -1410,7 +1446,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
1410
1446
  }
1411
1447
  #endif
1412
1448
  #if defined(SUPPORT_FILEFORMAT_FLAC)
1413
- else if (TextIsEqual(fileExtLower, ".flac"))
1449
+ else if (strcmp(fileType, ".flac") == 0)
1414
1450
  {
1415
1451
  music.ctxType = MUSIC_AUDIO_FLAC;
1416
1452
  music.ctxData = drflac_open_memory((const void*)data, dataSize, NULL);
@@ -1427,7 +1463,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
1427
1463
  }
1428
1464
  #endif
1429
1465
  #if defined(SUPPORT_FILEFORMAT_MP3)
1430
- else if (TextIsEqual(fileExtLower, ".mp3"))
1466
+ else if (strcmp(fileType, ".mp3") == 0)
1431
1467
  {
1432
1468
  drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3));
1433
1469
  int success = drmp3_init_memory(ctxMp3, (const void*)data, dataSize, NULL);
@@ -1445,7 +1481,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
1445
1481
  }
1446
1482
  #endif
1447
1483
  #if defined(SUPPORT_FILEFORMAT_OGG)
1448
- else if (TextIsEqual(fileExtLower, ".ogg"))
1484
+ else if (strcmp(fileType, ".ogg") == 0)
1449
1485
  {
1450
1486
  // Open ogg audio stream
1451
1487
  music.ctxType = MUSIC_AUDIO_OGG;
@@ -1467,7 +1503,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
1467
1503
  }
1468
1504
  #endif
1469
1505
  #if defined(SUPPORT_FILEFORMAT_XM)
1470
- else if (TextIsEqual(fileExtLower, ".xm"))
1506
+ else if (strcmp(fileType, ".xm") == 0)
1471
1507
  {
1472
1508
  jar_xm_context_t *ctxXm = NULL;
1473
1509
  int result = jar_xm_create_context_safe(&ctxXm, (const char *)data, dataSize, AUDIO.System.device.sampleRate);
@@ -1477,16 +1513,14 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
1477
1513
  jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops
1478
1514
 
1479
1515
  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;
1516
+ if (AUDIO_DEVICE_FORMAT == ma_format_s16) bits = 16;
1517
+ else if (AUDIO_DEVICE_FORMAT == ma_format_u8) bits = 8;
1484
1518
 
1485
1519
  // NOTE: Only stereo is supported for XM
1486
1520
  music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, 2);
1487
1521
  music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo)
1488
1522
  music.looping = true; // Looping enabled by default
1489
- jar_xm_reset(ctxXm); // make sure we start at the beginning of the song
1523
+ jar_xm_reset(ctxXm); // make sure we start at the beginning of the song
1490
1524
 
1491
1525
  music.ctxData = ctxXm;
1492
1526
  musicLoaded = true;
@@ -1494,7 +1528,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
1494
1528
  }
1495
1529
  #endif
1496
1530
  #if defined(SUPPORT_FILEFORMAT_MOD)
1497
- else if (TextIsEqual(fileExtLower, ".mod"))
1531
+ else if (strcmp(fileType, ".mod") == 0)
1498
1532
  {
1499
1533
  jar_mod_context_t *ctxMod = (jar_mod_context_t *)RL_MALLOC(sizeof(jar_mod_context_t));
1500
1534
  int result = 0;
@@ -1507,7 +1541,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
1507
1541
  for (int i = 0; i < it; i++) newData[i] = data[i];
1508
1542
 
1509
1543
  // Memory loaded version for jar_mod_load_file()
1510
- if (dataSize && dataSize < 32*1024*1024)
1544
+ if (dataSize && (dataSize < 32*1024*1024))
1511
1545
  {
1512
1546
  ctxMod->modfilesize = dataSize;
1513
1547
  ctxMod->modfile = newData;
@@ -1587,7 +1621,7 @@ void UnloadMusicStream(Music music)
1587
1621
  else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL);
1588
1622
  #endif
1589
1623
  #if defined(SUPPORT_FILEFORMAT_MP3)
1590
- else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); }
1624
+ else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); }
1591
1625
  #endif
1592
1626
  #if defined(SUPPORT_FILEFORMAT_XM)
1593
1627
  else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
@@ -1633,16 +1667,16 @@ void StopMusicStream(Music music)
1633
1667
  switch (music.ctxType)
1634
1668
  {
1635
1669
  #if defined(SUPPORT_FILEFORMAT_WAV)
1636
- case MUSIC_AUDIO_WAV: drwav_seek_to_pcm_frame((drwav *)music.ctxData, 0); break;
1670
+ case MUSIC_AUDIO_WAV: drwav_seek_to_first_pcm_frame((drwav *)music.ctxData); break;
1637
1671
  #endif
1638
1672
  #if defined(SUPPORT_FILEFORMAT_OGG)
1639
1673
  case MUSIC_AUDIO_OGG: stb_vorbis_seek_start((stb_vorbis *)music.ctxData); break;
1640
1674
  #endif
1641
1675
  #if defined(SUPPORT_FILEFORMAT_FLAC)
1642
- case MUSIC_AUDIO_FLAC: drflac_seek_to_pcm_frame((drflac *)music.ctxData, 0); break;
1676
+ case MUSIC_AUDIO_FLAC: drflac__seek_to_first_frame((drflac *)music.ctxData); break;
1643
1677
  #endif
1644
1678
  #if defined(SUPPORT_FILEFORMAT_MP3)
1645
- case MUSIC_AUDIO_MP3: drmp3_seek_to_pcm_frame((drmp3 *)music.ctxData, 0); break;
1679
+ case MUSIC_AUDIO_MP3: drmp3_seek_to_start_of_stream((drmp3 *)music.ctxData); break;
1646
1680
  #endif
1647
1681
  #if defined(SUPPORT_FILEFORMAT_XM)
1648
1682
  case MUSIC_MODULE_XM: jar_xm_reset((jar_xm_context_t *)music.ctxData); break;
@@ -1687,64 +1721,107 @@ void UpdateMusicStream(Music music)
1687
1721
  {
1688
1722
  if (music.stream.buffer == NULL) return;
1689
1723
 
1690
- bool streamEnding = false;
1691
1724
  unsigned int subBufferSizeInFrames = music.stream.buffer->sizeInFrames/2;
1692
1725
 
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;
1726
+ // On first call of this function we lazily pre-allocated a temp buffer to read audio files/memory data in
1727
+ int frameSize = music.stream.channels*music.stream.sampleSize/8;
1728
+ unsigned int pcmSize = subBufferSizeInFrames*frameSize;
1729
+ if (AUDIO.System.pcmBufferSize < pcmSize)
1730
+ {
1731
+ RL_FREE(AUDIO.System.pcmBuffer);
1732
+ AUDIO.System.pcmBuffer = RL_CALLOC(1, pcmSize);
1733
+ AUDIO.System.pcmBufferSize = pcmSize;
1734
+ }
1701
1735
 
1702
- while (IsAudioStreamProcessed(music.stream))
1736
+ // Check both sub-buffers to check if they require refilling
1737
+ for (int i = 0; i < 2; i++)
1703
1738
  {
1704
- if (framesLeft >= subBufferSizeInFrames) frameCountToStream = subBufferSizeInFrames;
1705
- else frameCountToStream = framesLeft;
1739
+ if ((music.stream.buffer != NULL) && !music.stream.buffer->isSubBufferProcessed[i]) continue; // No refilling required, move to next sub-buffer
1706
1740
 
1741
+ unsigned int framesLeft = music.frameCount - music.stream.buffer->framesProcessed; // Frames left to be processed
1742
+ unsigned int framesToStream = 0; // Total frames to be streamed
1743
+ if ((framesLeft >= subBufferSizeInFrames) || music.looping) framesToStream = subBufferSizeInFrames;
1744
+ else framesToStream = framesLeft;
1745
+
1746
+ int frameCountStillNeeded = framesToStream;
1747
+ int frameCountRedTotal = 0;
1707
1748
  switch (music.ctxType)
1708
1749
  {
1709
1750
  #if defined(SUPPORT_FILEFORMAT_WAV)
1710
1751
  case MUSIC_AUDIO_WAV:
1711
1752
  {
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
-
1753
+ if (music.stream.sampleSize == 16)
1754
+ {
1755
+ while (true)
1756
+ {
1757
+ int frameCountRed = drwav_read_pcm_frames_s16((drwav *)music.ctxData, frameCountStillNeeded, (short *)((char *)AUDIO.System.pcmBuffer + frameCountRedTotal*frameSize));
1758
+ frameCountRedTotal += frameCountRed;
1759
+ frameCountStillNeeded -= frameCountRed;
1760
+ if (frameCountStillNeeded == 0) break;
1761
+ else drwav_seek_to_first_pcm_frame((drwav *)music.ctxData);
1762
+ }
1763
+ }
1764
+ else if (music.stream.sampleSize == 32)
1765
+ {
1766
+ while (true)
1767
+ {
1768
+ int frameCountRed = drwav_read_pcm_frames_f32((drwav *)music.ctxData, frameCountStillNeeded, (float *)((char *)AUDIO.System.pcmBuffer + frameCountRedTotal*frameSize));
1769
+ frameCountRedTotal += frameCountRed;
1770
+ frameCountStillNeeded -= frameCountRed;
1771
+ if (frameCountStillNeeded == 0) break;
1772
+ else drwav_seek_to_first_pcm_frame((drwav *)music.ctxData);
1773
+ }
1774
+ }
1716
1775
  } break;
1717
1776
  #endif
1718
1777
  #if defined(SUPPORT_FILEFORMAT_OGG)
1719
1778
  case MUSIC_AUDIO_OGG:
1720
1779
  {
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
-
1780
+ while (true)
1781
+ {
1782
+ int frameCountRed = stb_vorbis_get_samples_short_interleaved((stb_vorbis *)music.ctxData, music.stream.channels, (short *)((char *)AUDIO.System.pcmBuffer + frameCountRedTotal*frameSize), frameCountStillNeeded*music.stream.channels);
1783
+ frameCountRedTotal += frameCountRed;
1784
+ frameCountStillNeeded -= frameCountRed;
1785
+ if (frameCountStillNeeded == 0) break;
1786
+ else stb_vorbis_seek_start((stb_vorbis *)music.ctxData);
1787
+ }
1724
1788
  } break;
1725
1789
  #endif
1726
1790
  #if defined(SUPPORT_FILEFORMAT_FLAC)
1727
1791
  case MUSIC_AUDIO_FLAC:
1728
1792
  {
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
-
1793
+ while (true)
1794
+ {
1795
+ int frameCountRed = drflac_read_pcm_frames_s16((drflac *)music.ctxData, frameCountStillNeeded, (short *)((char *)AUDIO.System.pcmBuffer + frameCountRedTotal*frameSize));
1796
+ frameCountRedTotal += frameCountRed;
1797
+ frameCountStillNeeded -= frameCountRed;
1798
+ if (frameCountStillNeeded == 0) break;
1799
+ else drflac__seek_to_first_frame((drflac *)music.ctxData);
1800
+ }
1732
1801
  } break;
1733
1802
  #endif
1734
1803
  #if defined(SUPPORT_FILEFORMAT_MP3)
1735
1804
  case MUSIC_AUDIO_MP3:
1736
1805
  {
1737
- drmp3_read_pcm_frames_f32((drmp3 *)music.ctxData, frameCountToStream, (float *)pcm);
1738
-
1806
+ while (true)
1807
+ {
1808
+ int frameCountRed = drmp3_read_pcm_frames_f32((drmp3 *)music.ctxData, frameCountStillNeeded, (float *)((char *)AUDIO.System.pcmBuffer + frameCountRedTotal*frameSize));
1809
+ frameCountRedTotal += frameCountRed;
1810
+ frameCountStillNeeded -= frameCountRed;
1811
+ if (frameCountStillNeeded == 0) break;
1812
+ else drmp3_seek_to_start_of_stream((drmp3 *)music.ctxData);
1813
+ }
1739
1814
  } break;
1740
1815
  #endif
1741
1816
  #if defined(SUPPORT_FILEFORMAT_XM)
1742
1817
  case MUSIC_MODULE_XM:
1743
1818
  {
1744
1819
  // 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);
1820
+ if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples((jar_xm_context_t *)music.ctxData, (float *)AUDIO.System.pcmBuffer, framesToStream);
1821
+ else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t *)music.ctxData, (short *)AUDIO.System.pcmBuffer, framesToStream);
1822
+ else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t *)music.ctxData, (char *)AUDIO.System.pcmBuffer, framesToStream);
1823
+
1824
+ //jar_xm_reset((jar_xm_context_t *)music.ctxData);
1748
1825
 
1749
1826
  } break;
1750
1827
  #endif
@@ -1752,38 +1829,33 @@ void UpdateMusicStream(Music music)
1752
1829
  case MUSIC_MODULE_MOD:
1753
1830
  {
1754
1831
  // 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);
1832
+ jar_mod_fillbuffer((jar_mod_context_t *)music.ctxData, (short *)AUDIO.System.pcmBuffer, framesToStream, 0);
1833
+
1834
+ //jar_mod_seek_start((jar_mod_context_t *)music.ctxData);
1835
+
1756
1836
  } break;
1757
1837
  #endif
1758
1838
  default: break;
1759
1839
  }
1760
1840
 
1761
- UpdateAudioStream(music.stream, pcm, frameCountToStream);
1841
+ UpdateAudioStream(music.stream, AUDIO.System.pcmBuffer, framesToStream);
1762
1842
 
1763
- framesLeft -= frameCountToStream;
1843
+ music.stream.buffer->framesProcessed = music.stream.buffer->framesProcessed%music.frameCount;
1764
1844
 
1765
- if (framesLeft <= 0)
1845
+ if (framesLeft <= subBufferSizeInFrames)
1766
1846
  {
1767
- streamEnding = true;
1768
- break;
1847
+ if (!music.looping)
1848
+ {
1849
+ // Streaming is ending, we filled latest frames from input
1850
+ StopMusicStream(music);
1851
+ return;
1852
+ }
1769
1853
  }
1770
1854
  }
1771
1855
 
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
- }
1856
+ // NOTE: In case window is minimized, music stream is stopped,
1857
+ // just make sure to play again on window restore
1858
+ if (IsMusicStreamPlaying(music)) PlayMusicStream(music);
1787
1859
  }
1788
1860
 
1789
1861
  // Check if any music is playing
@@ -1804,6 +1876,12 @@ void SetMusicPitch(Music music, float pitch)
1804
1876
  SetAudioBufferPitch(music.stream.buffer, pitch);
1805
1877
  }
1806
1878
 
1879
+ // Set pan for a music
1880
+ void SetMusicPan(Music music, float pan)
1881
+ {
1882
+ SetAudioBufferPan(music.stream.buffer, pan);
1883
+ }
1884
+
1807
1885
  // Get music time length (in seconds)
1808
1886
  float GetMusicTimeLength(Music music)
1809
1887
  {
@@ -1832,7 +1910,13 @@ float GetMusicTimePlayed(Music music)
1832
1910
  #endif
1833
1911
  {
1834
1912
  //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;
1913
+ int framesProcessed = (int)music.stream.buffer->framesProcessed;
1914
+ int subBufferSize = (int)music.stream.buffer->sizeInFrames/2;
1915
+ int framesInFirstBuffer = music.stream.buffer->isSubBufferProcessed[0]? 0 : subBufferSize;
1916
+ int framesInSecondBuffer = music.stream.buffer->isSubBufferProcessed[1]? 0 : subBufferSize;
1917
+ int framesSentToMix = music.stream.buffer->frameCursorPos%subBufferSize;
1918
+ int framesPlayed = (framesProcessed - framesInFirstBuffer - framesInSecondBuffer + framesSentToMix)%(int)music.frameCount;
1919
+ if (framesPlayed < 0) framesPlayed += music.frameCount;
1836
1920
  secondsPlayed = (float)framesPlayed/music.stream.sampleRate;
1837
1921
  }
1838
1922
  }
@@ -1907,16 +1991,14 @@ void UpdateAudioStream(AudioStream stream, const void *data, int frameCount)
1907
1991
  ma_uint32 subBufferSizeInFrames = stream.buffer->sizeInFrames/2;
1908
1992
  unsigned char *subBuffer = stream.buffer->data + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate);
1909
1993
 
1910
- // TODO: Get total frames processed on this buffer... DOES NOT WORK.
1994
+ // Total frames processed in buffer is always the complete size, filled with 0 if required
1911
1995
  stream.buffer->framesProcessed += subBufferSizeInFrames;
1912
1996
 
1913
1997
  // Does this API expect a whole buffer to be updated in one go?
1914
1998
  // Assuming so, but if not will need to change this logic.
1915
1999
  if (subBufferSizeInFrames >= (ma_uint32)frameCount)
1916
2000
  {
1917
- ma_uint32 framesToWrite = subBufferSizeInFrames;
1918
-
1919
- if (framesToWrite > (ma_uint32)frameCount) framesToWrite = (ma_uint32)frameCount;
2001
+ ma_uint32 framesToWrite = (ma_uint32)frameCount;
1920
2002
 
1921
2003
  ma_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8);
1922
2004
  memcpy(subBuffer, data, bytesToWrite);
@@ -1984,28 +2066,98 @@ void SetAudioStreamPitch(AudioStream stream, float pitch)
1984
2066
  SetAudioBufferPitch(stream.buffer, pitch);
1985
2067
  }
1986
2068
 
2069
+ // Set pan for audio stream
2070
+ void SetAudioStreamPan(AudioStream stream, float pan)
2071
+ {
2072
+ SetAudioBufferPan(stream.buffer, pan);
2073
+ }
2074
+
1987
2075
  // Default size for new audio streams
1988
2076
  void SetAudioStreamBufferSizeDefault(int size)
1989
2077
  {
1990
2078
  AUDIO.Buffer.defaultSize = size;
1991
2079
  }
1992
2080
 
2081
+ // Audio thread callback to request new data
2082
+ void SetAudioStreamCallback(AudioStream stream, AudioCallback callback)
2083
+ {
2084
+ if (stream.buffer != NULL) stream.buffer->callback = callback;
2085
+ }
2086
+
2087
+ // Add processor to audio stream. Contrary to buffers, the order of processors is important.
2088
+ // The new processor must be added at the end. As there aren't supposed to be a lot of processors attached to
2089
+ // a given stream, we iterate through the list to find the end. That way we don't need a pointer to the last element.
2090
+ void AttachAudioStreamProcessor(AudioStream stream, AudioCallback process)
2091
+ {
2092
+ ma_mutex_lock(&AUDIO.System.lock);
2093
+
2094
+ rAudioProcessor *processor = (rAudioProcessor *)RL_CALLOC(1, sizeof(rAudioProcessor));
2095
+ processor->process = process;
2096
+
2097
+ rAudioProcessor *last = stream.buffer->processor;
2098
+
2099
+ while (last && last->next)
2100
+ {
2101
+ last = last->next;
2102
+ }
2103
+ if (last)
2104
+ {
2105
+ processor->prev = last;
2106
+ last->next = processor;
2107
+ }
2108
+ else stream.buffer->processor = processor;
2109
+
2110
+ ma_mutex_unlock(&AUDIO.System.lock);
2111
+ }
2112
+
2113
+ void DetachAudioStreamProcessor(AudioStream stream, AudioCallback process)
2114
+ {
2115
+ ma_mutex_lock(&AUDIO.System.lock);
2116
+
2117
+ rAudioProcessor *processor = stream.buffer->processor;
2118
+
2119
+ while (processor)
2120
+ {
2121
+ rAudioProcessor *next = processor->next;
2122
+ rAudioProcessor *prev = processor->prev;
2123
+
2124
+ if (processor->process == process)
2125
+ {
2126
+ if (stream.buffer->processor == processor) stream.buffer->processor = next;
2127
+ if (prev) prev->next = next;
2128
+ if (next) next->prev = prev;
2129
+
2130
+ RL_FREE(processor);
2131
+ }
2132
+
2133
+ processor = next;
2134
+ }
2135
+
2136
+ ma_mutex_unlock(&AUDIO.System.lock);
2137
+ }
2138
+
1993
2139
  //----------------------------------------------------------------------------------
1994
2140
  // Module specific Functions Definition
1995
2141
  //----------------------------------------------------------------------------------
1996
2142
 
1997
2143
  // Log callback function
1998
- static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message)
2144
+ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage)
1999
2145
  {
2000
- (void)pContext;
2001
- (void)pDevice;
2002
-
2003
- TRACELOG(LOG_WARNING, "miniaudio: %s", message); // All log messages from miniaudio are errors
2146
+ TRACELOG(LOG_WARNING, "miniaudio: %s", pMessage); // All log messages from miniaudio are errors
2004
2147
  }
2005
2148
 
2006
2149
  // Reads audio data from an AudioBuffer object in internal format.
2007
2150
  static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount)
2008
2151
  {
2152
+ // Using audio buffer callback
2153
+ if (audioBuffer->callback)
2154
+ {
2155
+ audioBuffer->callback(framesOut, frameCount);
2156
+ audioBuffer->framesProcessed += frameCount;
2157
+
2158
+ return frameCount;
2159
+ }
2160
+
2009
2161
  ma_uint32 subBufferSizeInFrames = (audioBuffer->sizeInFrames > 1)? audioBuffer->sizeInFrames/2 : audioBuffer->sizeInFrames;
2010
2162
  ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
2011
2163
 
@@ -2013,11 +2165,11 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
2013
2165
 
2014
2166
  // Another thread can update the processed state of buffers so
2015
2167
  // we just take a copy here to try and avoid potential synchronization problems
2016
- bool isSubBufferProcessed[2];
2168
+ bool isSubBufferProcessed[2] = { 0 };
2017
2169
  isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
2018
2170
  isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
2019
2171
 
2020
- ma_uint32 frameSizeInBytes = ma_get_bytes_per_frame(audioBuffer->converter.config.formatIn, audioBuffer->converter.config.channelsIn);
2172
+ ma_uint32 frameSizeInBytes = ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
2021
2173
 
2022
2174
  // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0
2023
2175
  ma_uint32 framesRead = 0;
@@ -2096,21 +2248,22 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
2096
2248
  // should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important
2097
2249
  // 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
2250
  // 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);
2251
+ ma_uint8 inputBuffer[4096] = { 0 };
2252
+ ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
2101
2253
 
2102
2254
  ma_uint32 totalOutputFramesProcessed = 0;
2103
2255
  while (totalOutputFramesProcessed < frameCount)
2104
2256
  {
2105
2257
  ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed;
2258
+ ma_uint64 inputFramesToProcessThisIteration = 0;
2106
2259
 
2107
- ma_uint64 inputFramesToProcessThisIteration = ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration);
2260
+ (void)ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration, &inputFramesToProcessThisIteration);
2108
2261
  if (inputFramesToProcessThisIteration > inputBufferFrameCap)
2109
2262
  {
2110
2263
  inputFramesToProcessThisIteration = inputBufferFrameCap;
2111
2264
  }
2112
2265
 
2113
- float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.config.channelsOut);
2266
+ float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut);
2114
2267
 
2115
2268
  /* At this point we can convert the data to our mixing format. */
2116
2269
  ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */
@@ -2165,7 +2318,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
2165
2318
 
2166
2319
  while (framesToRead > 0)
2167
2320
  {
2168
- float tempBuffer[1024]; // 512 frames for stereo
2321
+ float tempBuffer[1024] = { 0 }; // Frames for stereo
2169
2322
 
2170
2323
  ma_uint32 framesToReadRightNow = framesToRead;
2171
2324
  if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/AUDIO_DEVICE_CHANNELS)
@@ -2179,7 +2332,15 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
2179
2332
  float *framesOut = (float *)pFramesOut + (framesRead*AUDIO.System.device.playback.channels);
2180
2333
  float *framesIn = tempBuffer;
2181
2334
 
2182
- MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
2335
+ // Apply processors chain if defined
2336
+ rAudioProcessor *processor = audioBuffer->processor;
2337
+ while (processor)
2338
+ {
2339
+ processor->process(framesIn, framesJustRead);
2340
+ processor = processor->next;
2341
+ }
2342
+
2343
+ MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer);
2183
2344
 
2184
2345
  framesToRead -= framesJustRead;
2185
2346
  framesRead += framesJustRead;
@@ -2219,18 +2380,45 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
2219
2380
  ma_mutex_unlock(&AUDIO.System.lock);
2220
2381
  }
2221
2382
 
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)
2383
+ // Main mixing function, pretty simple in this project, just an accumulation
2384
+ // NOTE: framesOut is both an input and an output, it is initially filled with zeros outside of this function
2385
+ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer)
2225
2386
  {
2226
- for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
2387
+ const float localVolume = buffer->volume;
2388
+ const ma_uint32 channels = AUDIO.System.device.playback.channels;
2389
+
2390
+ if (channels == 2) // We consider panning
2227
2391
  {
2228
- for (ma_uint32 iChannel = 0; iChannel < AUDIO.System.device.playback.channels; ++iChannel)
2392
+ const float left = buffer->pan;
2393
+ const float right = 1.0f - left;
2394
+
2395
+ // Fast sine approximation in [0..1] for pan law: y = 0.5f*x*(3 - x*x);
2396
+ const float levels[2] = { localVolume*0.5f*left*(3.0f - left*left), localVolume*0.5f*right*(3.0f - right*right) };
2397
+
2398
+ float *frameOut = framesOut;
2399
+ const float *frameIn = framesIn;
2400
+
2401
+ for (ma_uint32 frame = 0; frame < frameCount; frame++)
2229
2402
  {
2230
- float *frameOut = framesOut + (iFrame*AUDIO.System.device.playback.channels);
2231
- const float *frameIn = framesIn + (iFrame*AUDIO.System.device.playback.channels);
2403
+ frameOut[0] += (frameIn[0]*levels[0]);
2404
+ frameOut[1] += (frameIn[1]*levels[1]);
2405
+
2406
+ frameOut += 2;
2407
+ frameIn += 2;
2408
+ }
2409
+ }
2410
+ else // We do not consider panning
2411
+ {
2412
+ for (ma_uint32 frame = 0; frame < frameCount; frame++)
2413
+ {
2414
+ for (ma_uint32 c = 0; c < channels; c++)
2415
+ {
2416
+ float *frameOut = framesOut + (frame*channels);
2417
+ const float *frameIn = framesIn + (frame*channels);
2232
2418
 
2233
- frameOut[iChannel] += (frameIn[iChannel]*localVolume);
2419
+ // Output accumulates input multiplied by volume to provided output (usually 0)
2420
+ frameOut[c] += (frameIn[c]*localVolume);
2421
+ }
2234
2422
  }
2235
2423
  }
2236
2424
  }
@@ -2261,38 +2449,6 @@ static const char *GetFileExtension(const char *fileName)
2261
2449
  return dot;
2262
2450
  }
2263
2451
 
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
2452
  // Load data from file into a buffer
2297
2453
  static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead)
2298
2454
  {
@@ -2378,3 +2534,5 @@ static bool SaveFileText(const char *fileName, char *text)
2378
2534
  #endif
2379
2535
 
2380
2536
  #undef AudioBuffer
2537
+
2538
+ #endif // SUPPORT_MODULE_RAUDIO