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.
- package/ChangeLog.md +6 -0
- package/build/qemu/2.1.2/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.1.2/koffi_win32_x64.tar.gz +0 -0
- package/doc/templates/badges.html +3 -0
- package/package.json +2 -2
- package/src/abi_arm64.cc +35 -1
- package/src/abi_x64_win.cc +2 -8
- package/src/abi_x86.cc +1 -7
- package/src/ffi.hh +1 -1
- package/src/util.hh +6 -0
- package/test/raylib.js +37 -5
- package/vendor/libcc/libcc.cc +430 -196
- package/vendor/libcc/libcc.hh +1417 -1283
- package/vendor/raylib/BINDINGS.md +87 -70
- package/vendor/raylib/CHANGELOG +263 -50
- package/vendor/raylib/CMakeLists.txt +12 -0
- package/vendor/raylib/CMakeOptions.txt +8 -1
- package/vendor/raylib/CONVENTIONS.md +2 -3
- package/vendor/raylib/FAQ.md +137 -0
- package/vendor/raylib/HISTORY.md +62 -29
- package/vendor/raylib/LICENSE +1 -1
- package/vendor/raylib/README.md +22 -17
- package/vendor/raylib/ROADMAP.md +8 -7
- package/vendor/raylib/cmake/CompileDefinitions.cmake +19 -15
- package/vendor/raylib/cmake/GlfwImport.cmake +2 -0
- package/vendor/raylib/cmake/LibraryConfigurations.cmake +22 -16
- package/vendor/raylib/cmake/raylib-config.cmake +52 -49
- package/vendor/raylib/examples/CMakeLists.txt +14 -9
- package/vendor/raylib/examples/Makefile +112 -125
- package/vendor/raylib/examples/Makefile.Android +1 -1
- package/vendor/raylib/examples/Makefile.Web +145 -158
- package/vendor/raylib/examples/README.md +141 -141
- package/vendor/raylib/examples/audio/audio_module_playing.c +9 -4
- package/vendor/raylib/examples/audio/audio_multichannel_sound.c +8 -3
- package/vendor/raylib/examples/audio/audio_music_stream.c +16 -11
- package/vendor/raylib/examples/audio/audio_raw_stream.c +57 -9
- package/vendor/raylib/examples/audio/audio_sound_loading.c +8 -3
- package/vendor/raylib/examples/audio/audio_stream_effects.c +179 -0
- package/vendor/raylib/examples/audio/audio_stream_effects.png +0 -0
- package/vendor/raylib/examples/build.zig +17 -6
- package/vendor/raylib/examples/core/core_2d_camera.c +8 -4
- package/vendor/raylib/examples/core/core_2d_camera_mouse_zoom.c +105 -0
- package/vendor/raylib/examples/core/core_2d_camera_mouse_zoom.png +0 -0
- package/vendor/raylib/examples/core/core_2d_camera_platformer.c +11 -6
- package/vendor/raylib/examples/core/core_3d_camera_first_person.c +9 -4
- package/vendor/raylib/examples/core/core_3d_camera_free.c +9 -4
- package/vendor/raylib/examples/core/core_3d_camera_mode.c +8 -3
- package/vendor/raylib/examples/core/core_3d_picking.c +9 -4
- package/vendor/raylib/examples/core/core_basic_screen_manager.c +9 -7
- package/vendor/raylib/examples/core/core_basic_window.c +8 -3
- package/vendor/raylib/examples/core/core_basic_window_web.c +13 -11
- package/vendor/raylib/examples/core/core_custom_frame_control.c +9 -4
- package/vendor/raylib/examples/core/core_custom_logging.c +12 -8
- package/vendor/raylib/examples/core/core_drop_files.c +20 -12
- package/vendor/raylib/examples/core/core_input_gamepad.c +20 -15
- package/vendor/raylib/examples/core/core_input_gestures.c +19 -15
- package/vendor/raylib/examples/core/core_input_keys.c +8 -3
- package/vendor/raylib/examples/core/core_input_mouse.c +8 -3
- package/vendor/raylib/examples/core/core_input_mouse_wheel.c +8 -3
- package/vendor/raylib/examples/core/core_input_multitouch.c +8 -3
- package/vendor/raylib/examples/core/core_loading_thread.c +10 -6
- package/vendor/raylib/examples/core/core_random_values.c +8 -3
- package/vendor/raylib/examples/core/core_scissor_test.c +8 -3
- package/vendor/raylib/examples/core/core_smooth_pixelperfect.c +9 -4
- package/vendor/raylib/examples/core/core_split_screen.c +8 -3
- package/vendor/raylib/examples/core/core_storage_values.c +109 -3
- package/vendor/raylib/examples/core/core_vr_simulator.c +15 -7
- package/vendor/raylib/examples/core/core_window_flags.c +8 -3
- package/vendor/raylib/examples/core/core_window_letterbox.c +13 -18
- package/vendor/raylib/examples/core/core_window_should_close.c +77 -0
- package/vendor/raylib/examples/core/core_window_should_close.png +0 -0
- package/vendor/raylib/examples/core/core_world_screen.c +9 -4
- package/vendor/raylib/examples/examples_template.c +8 -3
- package/vendor/raylib/examples/models/models_animation.c +11 -7
- package/vendor/raylib/examples/models/models_billboard.c +9 -4
- package/vendor/raylib/examples/models/models_box_collisions.c +8 -3
- package/vendor/raylib/examples/models/models_cubicmap.c +9 -4
- package/vendor/raylib/examples/models/models_first_person_maze.c +9 -4
- package/vendor/raylib/examples/models/models_geometric_shapes.c +8 -3
- package/vendor/raylib/examples/models/models_heightmap.c +9 -4
- package/vendor/raylib/examples/models/models_loading.c +21 -17
- package/vendor/raylib/examples/models/models_loading_gltf.c +15 -41
- package/vendor/raylib/examples/models/models_loading_vox.c +9 -4
- package/vendor/raylib/examples/models/models_mesh_generation.c +71 -58
- package/vendor/raylib/examples/models/models_mesh_picking.c +25 -7
- package/vendor/raylib/examples/models/models_orthographic_projection.c +8 -5
- package/vendor/raylib/examples/models/models_rlgl_solar_system.c +6 -4
- package/vendor/raylib/examples/models/models_skybox.c +16 -12
- package/vendor/raylib/examples/models/models_waving_cubes.c +9 -4
- package/vendor/raylib/examples/models/models_yaw_pitch_roll.c +12 -7
- package/vendor/raylib/examples/models/resources/LICENSE.md +9 -10
- package/vendor/raylib/examples/models/resources/models/gltf/LICENSE +2 -23
- package/vendor/raylib/examples/models/resources/models/gltf/{raylib_32x32.glb → raylib_logo_3d.glb} +0 -0
- package/vendor/raylib/examples/models/resources/models/gltf/robot.blend +0 -0
- package/vendor/raylib/examples/models/resources/models/gltf/robot.glb +0 -0
- package/vendor/raylib/examples/others/easings_testbed.c +10 -8
- package/vendor/raylib/examples/others/easings_testbed.png +0 -0
- package/vendor/raylib/examples/others/embedded_files_loading.c +10 -5
- package/vendor/raylib/examples/others/embedded_files_loading.png +0 -0
- package/vendor/raylib/examples/others/raylib_opengl_interop.c +10 -6
- package/vendor/raylib/{src/extras/easings.h → examples/others/reasings.h} +38 -38
- package/vendor/raylib/examples/others/rlgl_compute_shader.c +21 -20
- package/vendor/raylib/examples/others/rlgl_compute_shader.png +0 -0
- package/vendor/raylib/examples/others/rlgl_standalone.c +4 -4
- package/vendor/raylib/examples/others/rlgl_standalone.png +0 -0
- package/vendor/raylib/examples/raylib_compile_execute.bat +2 -2
- package/vendor/raylib/examples/shaders/resources/shaders/glsl330/lighting.fs +1 -1
- package/vendor/raylib/examples/shaders/resources/shaders/glsl330/{base_lighting_instanced.vs → lighting_instancing.vs} +2 -2
- package/vendor/raylib/examples/shaders/rlights.h +14 -27
- package/vendor/raylib/examples/shaders/shaders_basic_lighting.c +24 -26
- package/vendor/raylib/examples/shaders/shaders_custom_uniform.c +10 -5
- package/vendor/raylib/examples/shaders/shaders_eratosthenes.c +13 -8
- package/vendor/raylib/examples/shaders/shaders_fog.c +8 -12
- package/vendor/raylib/examples/shaders/shaders_hot_reloading.c +10 -5
- package/vendor/raylib/examples/shaders/shaders_julia_set.c +9 -4
- package/vendor/raylib/examples/shaders/shaders_mesh_instancing.c +45 -119
- package/vendor/raylib/examples/shaders/shaders_model_shader.c +10 -5
- package/vendor/raylib/examples/shaders/shaders_multi_sample2d.c +8 -3
- package/vendor/raylib/examples/shaders/shaders_palette_switch.c +8 -3
- package/vendor/raylib/examples/shaders/shaders_postprocessing.c +9 -4
- package/vendor/raylib/examples/shaders/shaders_raymarching.c +14 -11
- package/vendor/raylib/examples/shaders/shaders_shapes_textures.c +8 -3
- package/vendor/raylib/examples/shaders/shaders_simple_mask.c +10 -5
- package/vendor/raylib/examples/shaders/shaders_spotlight.c +10 -6
- package/vendor/raylib/examples/shaders/shaders_texture_drawing.c +9 -4
- package/vendor/raylib/examples/shaders/shaders_texture_outline.c +8 -3
- package/vendor/raylib/examples/shaders/shaders_texture_waves.c +8 -3
- package/vendor/raylib/{src/extras → examples/shapes}/raygui.h +1290 -1141
- package/vendor/raylib/examples/{others/easings.h → shapes/reasings.h} +40 -40
- package/vendor/raylib/examples/shapes/shapes_basic_shapes.c +8 -3
- package/vendor/raylib/examples/shapes/shapes_bouncing_ball.c +8 -3
- package/vendor/raylib/examples/shapes/shapes_collision_area.c +10 -4
- package/vendor/raylib/examples/shapes/shapes_colors_palette.c +8 -3
- package/vendor/raylib/examples/shapes/shapes_draw_circle_sector.c +9 -4
- package/vendor/raylib/examples/shapes/shapes_draw_rectangle_rounded.c +9 -4
- package/vendor/raylib/examples/shapes/shapes_draw_ring.c +10 -6
- package/vendor/raylib/examples/shapes/shapes_easings_ball_anim.c +9 -4
- package/vendor/raylib/examples/shapes/shapes_easings_box_anim.c +9 -4
- package/vendor/raylib/examples/shapes/shapes_easings_rectangle_array.c +9 -4
- package/vendor/raylib/examples/shapes/shapes_following_eyes.c +8 -3
- package/vendor/raylib/examples/shapes/shapes_lines_bezier.c +8 -3
- package/vendor/raylib/examples/shapes/shapes_logo_raylib.c +8 -3
- package/vendor/raylib/examples/shapes/shapes_logo_raylib_anim.c +8 -3
- package/vendor/raylib/examples/shapes/shapes_rectangle_scaling.c +14 -5
- package/vendor/raylib/examples/shapes/shapes_top_down_lights.c +355 -0
- package/vendor/raylib/examples/shapes/shapes_top_down_lights.png +0 -0
- package/vendor/raylib/examples/text/resources/DotGothic16-Regular.ttf +0 -0
- package/vendor/raylib/examples/text/resources/DotGothic16-Regular_OFL.txt +93 -0
- package/vendor/raylib/examples/text/resources/LICENSE.md +1 -1
- package/vendor/raylib/examples/text/text_codepoints_loading.c +138 -0
- package/vendor/raylib/examples/text/text_codepoints_loading.png +0 -0
- package/vendor/raylib/examples/text/text_draw_3d.c +42 -33
- package/vendor/raylib/examples/text/text_font_filters.c +14 -11
- package/vendor/raylib/examples/text/text_font_loading.c +9 -4
- package/vendor/raylib/examples/text/text_font_sdf.c +9 -4
- package/vendor/raylib/examples/text/text_font_spritefont.c +12 -6
- package/vendor/raylib/examples/text/text_format_text.c +8 -3
- package/vendor/raylib/examples/text/text_input_box.c +8 -3
- package/vendor/raylib/examples/text/text_raylib_fonts.c +9 -4
- package/vendor/raylib/examples/text/text_rectangle_bounds.c +9 -5
- package/vendor/raylib/examples/text/text_unicode.c +9 -7
- package/vendor/raylib/examples/text/text_writing_anim.c +8 -3
- package/vendor/raylib/examples/textures/resources/scarfy_run.gif +0 -0
- package/vendor/raylib/examples/textures/textures_background_scrolling.c +8 -3
- package/vendor/raylib/examples/textures/textures_blend_modes.c +8 -3
- package/vendor/raylib/examples/textures/textures_bunnymark.c +8 -3
- package/vendor/raylib/examples/textures/textures_draw_tiled.c +14 -10
- package/vendor/raylib/examples/textures/textures_fog_of_war.c +154 -0
- package/vendor/raylib/examples/textures/textures_fog_of_war.png +0 -0
- package/vendor/raylib/examples/textures/textures_gif_player.c +121 -0
- package/vendor/raylib/examples/textures/textures_gif_player.png +0 -0
- package/vendor/raylib/examples/textures/textures_image_drawing.c +8 -3
- package/vendor/raylib/examples/textures/textures_image_generation.c +8 -3
- package/vendor/raylib/examples/textures/textures_image_loading.c +8 -3
- package/vendor/raylib/examples/textures/textures_image_processing.c +8 -3
- package/vendor/raylib/examples/textures/textures_image_text.c +8 -3
- package/vendor/raylib/examples/textures/textures_logo_raylib.c +8 -3
- package/vendor/raylib/examples/textures/textures_mouse_painting.c +9 -4
- package/vendor/raylib/examples/textures/textures_npatch_drawing.c +8 -3
- package/vendor/raylib/examples/textures/textures_particles_blending.c +8 -3
- package/vendor/raylib/examples/textures/textures_polygon.c +9 -5
- package/vendor/raylib/examples/textures/textures_raw_data.c +8 -3
- package/vendor/raylib/examples/textures/{textures_rectangle.c → textures_sprite_anim.c} +11 -5
- package/vendor/raylib/examples/textures/{textures_rectangle.png → textures_sprite_anim.png} +0 -0
- package/vendor/raylib/examples/textures/textures_sprite_button.c +8 -3
- package/vendor/raylib/examples/textures/textures_sprite_explosion.c +8 -3
- package/vendor/raylib/examples/textures/textures_srcrec_dstrec.c +8 -3
- package/vendor/raylib/examples/textures/textures_to_image.c +8 -3
- package/vendor/raylib/parser/LICENSE +1 -1
- package/vendor/raylib/parser/Makefile +28 -0
- package/vendor/raylib/parser/README.md +49 -5
- package/vendor/raylib/parser/output/raylib_api.json +10717 -0
- package/vendor/raylib/parser/output/raylib_api.lua +7435 -0
- package/vendor/raylib/parser/{raylib_api.txt → output/raylib_api.txt} +1371 -824
- package/vendor/raylib/parser/{raylib_api.xml → output/raylib_api.xml} +827 -595
- package/vendor/raylib/parser/raylib_parser.c +1174 -196
- package/vendor/raylib/projects/4coder/Makefile +2 -4
- package/vendor/raylib/projects/4coder/main.c +0 -1
- package/vendor/raylib/projects/CMake/CMakeLists.txt +13 -16
- package/vendor/raylib/projects/CMake/README.md +27 -0
- package/vendor/raylib/projects/CMake/core_basic_window.c +52 -31
- package/vendor/raylib/projects/CodeBlocks/README.md +4 -4
- package/vendor/raylib/projects/Geany/core_basic_window.c +1 -1
- package/vendor/raylib/projects/Notepad++/c_raylib.xml +168 -128
- package/vendor/raylib/projects/Notepad++/npes_saved_tcc.txt +0 -0
- package/vendor/raylib/projects/Notepad++/npes_saved_w64devkit.txt +0 -0
- package/vendor/raylib/projects/Notepad++/npes_saved_zig.txt +0 -0
- package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +168 -84
- package/vendor/raylib/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +67 -51
- package/vendor/raylib/projects/README.md +1 -1
- package/vendor/raylib/projects/VSCode/.vscode/c_cpp_properties.json +1 -1
- package/vendor/raylib/projects/VSCode/Makefile +8 -11
- package/vendor/raylib/projects/VSCode/main.c +53 -26
- package/vendor/raylib/projects/VSCode/resources/LICENSE +1 -0
- package/vendor/raylib/projects/scripts/build-linux.sh +6 -6
- package/vendor/raylib/projects/scripts/build-osx.sh +6 -6
- package/vendor/raylib/projects/scripts/build-rpi.sh +6 -6
- package/vendor/raylib/projects/scripts/build-windows.bat +2 -2
- package/vendor/raylib/src/CMakeLists.txt +6 -7
- package/vendor/raylib/src/Makefile +209 -103
- package/vendor/raylib/src/build.zig +56 -20
- package/vendor/raylib/src/config.h +32 -27
- package/vendor/raylib/src/external/cgltf.h +342 -104
- package/vendor/raylib/src/external/dr_wav.h +487 -225
- package/vendor/raylib/src/external/glfw/src/posix_time.c +1 -3
- package/vendor/raylib/src/external/glfw/src/wl_init.c +1 -3
- package/vendor/raylib/src/external/jar_xm.h +2 -1
- package/vendor/raylib/src/external/miniaudio.h +62251 -42061
- package/vendor/raylib/src/external/qoi.h +671 -0
- package/vendor/raylib/src/external/stb_vorbis.h +1 -1
- package/vendor/raylib/src/external/vox_loader.h +30 -25
- package/vendor/raylib/src/minshell.html +82 -0
- package/vendor/raylib/src/raudio.c +359 -201
- package/vendor/raylib/src/raylib.dll.rc +5 -5
- package/vendor/raylib/src/raylib.dll.rc.data +0 -0
- package/vendor/raylib/src/raylib.h +95 -63
- package/vendor/raylib/src/raylib.rc +5 -5
- package/vendor/raylib/src/raylib.rc.data +0 -0
- package/vendor/raylib/src/raymath.h +391 -133
- package/vendor/raylib/src/rcamera.h +32 -41
- package/vendor/raylib/src/rcore.c +775 -471
- package/vendor/raylib/src/rgestures.h +5 -5
- package/vendor/raylib/src/rglfw.c +3 -3
- package/vendor/raylib/src/rlgl.h +184 -144
- package/vendor/raylib/src/rmodels.c +207 -144
- package/vendor/raylib/src/rshapes.c +105 -47
- package/vendor/raylib/src/rtext.c +255 -38
- package/vendor/raylib/src/rtextures.c +167 -71
- package/vendor/raylib/src/shell.html +63 -63
- package/vendor/raylib/src/utils.c +49 -3
- package/vendor/raylib/src/utils.h +3 -3
- package/build/qemu/2.1.1/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.1.1/koffi_win32_x64.tar.gz +0 -0
- package/vendor/raylib/CONTRIBUTORS.md +0 -63
- package/vendor/raylib/SPONSORS.md +0 -68
- package/vendor/raylib/examples/core/core_quat_conversion.c +0 -132
- package/vendor/raylib/examples/core/core_quat_conversion.png +0 -0
- package/vendor/raylib/examples/models/resources/models/gltf/AnimatedMorphCube.glb +0 -0
- package/vendor/raylib/examples/models/resources/models/gltf/AnimatedTriangle.gltf +0 -118
- package/vendor/raylib/examples/models/resources/models/gltf/BoxAnimated.glb +0 -0
- package/vendor/raylib/examples/models/resources/models/gltf/girl.glb +0 -0
- package/vendor/raylib/examples/models/resources/models/gltf/rigged_figure.glb +0 -0
- package/vendor/raylib/examples/models/resources/models/gltf/vertex_colored_object.glb +0 -0
- package/vendor/raylib/examples/models/resources/models/iqm/vertex_colored_object.iqm +0 -0
- package/vendor/raylib/examples/models/rlights.h +0 -183
- package/vendor/raylib/examples/others/raudio_standalone.c +0 -152
- package/vendor/raylib/examples/others/resources/audio/country.mp3 +0 -0
- package/vendor/raylib/examples/others/resources/audio/target.ogg +0 -0
- package/vendor/raylib/examples/others/resources/audio/weird.wav +0 -0
- package/vendor/raylib/examples/physics/physics_demo.c +0 -128
- package/vendor/raylib/examples/physics/physics_demo.png +0 -0
- package/vendor/raylib/examples/physics/physics_friction.c +0 -142
- package/vendor/raylib/examples/physics/physics_friction.png +0 -0
- package/vendor/raylib/examples/physics/physics_movement.c +0 -128
- package/vendor/raylib/examples/physics/physics_movement.png +0 -0
- package/vendor/raylib/examples/physics/physics_restitution.c +0 -129
- package/vendor/raylib/examples/physics/physics_restitution.png +0 -0
- package/vendor/raylib/examples/physics/physics_shatter.c +0 -111
- package/vendor/raylib/examples/physics/physics_shatter.png +0 -0
- package/vendor/raylib/parser/raylib_api.json +0 -6668
- package/vendor/raylib/projects/VS2019/raylib/raylib.rc +0 -0
- package/vendor/raylib/projects/VS2019/raylib/resource.h +0 -14
- package/vendor/raylib/src/extras/physac.h +0 -1977
- package/vendor/raylib/src/extras/rmem.h +0 -751
- package/vendor/raylib/src/raudio.h +0 -198
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**********************************************************************************************
|
|
2
2
|
*
|
|
3
|
-
* raudio v1.
|
|
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-
|
|
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, ...)
|
|
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)
|
|
186
|
+
#define RL_MALLOC(sz) malloc(sz)
|
|
183
187
|
#endif
|
|
184
188
|
#ifndef RL_CALLOC
|
|
185
|
-
#define RL_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)
|
|
192
|
+
#define RL_REALLOC(ptr,sz) realloc(ptr,sz)
|
|
189
193
|
#endif
|
|
190
194
|
#ifndef RL_FREE
|
|
191
|
-
#define RL_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
|
|
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,
|
|
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(
|
|
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,
|
|
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
|
-
|
|
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.
|
|
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.
|
|
652
|
-
ma_data_converter_set_rate(&buffer->converter, buffer->converter.
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
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.
|
|
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-
|
|
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
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
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",
|
|
969
|
-
byteCount += sprintf(txtData + byteCount, "#define %
|
|
970
|
-
byteCount += sprintf(txtData + byteCount, "#define %
|
|
971
|
-
byteCount += sprintf(txtData + byteCount, "#define %
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
//
|
|
975
|
-
// NOTE: Frame data exported is interlaced:
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
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]
|
|
1043
|
-
AUDIO.MultiChannel.pool[index]
|
|
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
|
-
|
|
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
|
|
1381
|
-
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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);
|
|
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 (
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
//
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
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
|
-
|
|
1736
|
+
// Check both sub-buffers to check if they require refilling
|
|
1737
|
+
for (int i = 0; i < 2; i++)
|
|
1703
1738
|
{
|
|
1704
|
-
if (
|
|
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
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
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
|
-
|
|
1722
|
-
|
|
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
|
-
|
|
1730
|
-
|
|
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
|
-
|
|
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 *)
|
|
1746
|
-
else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t *)music.ctxData, (short *)
|
|
1747
|
-
else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t *)music.ctxData, (char *)
|
|
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 *)
|
|
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,
|
|
1841
|
+
UpdateAudioStream(music.stream, AUDIO.System.pcmBuffer, framesToStream);
|
|
1762
1842
|
|
|
1763
|
-
|
|
1843
|
+
music.stream.buffer->framesProcessed = music.stream.buffer->framesProcessed%music.frameCount;
|
|
1764
1844
|
|
|
1765
|
-
if (framesLeft <=
|
|
1845
|
+
if (framesLeft <= subBufferSizeInFrames)
|
|
1766
1846
|
{
|
|
1767
|
-
|
|
1768
|
-
|
|
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
|
-
//
|
|
1773
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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 =
|
|
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(
|
|
2144
|
+
static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage)
|
|
1999
2145
|
{
|
|
2000
|
-
(
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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]; //
|
|
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
|
-
|
|
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
|
-
//
|
|
2223
|
-
// NOTE: framesOut is both an input and an output
|
|
2224
|
-
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2231
|
-
|
|
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
|
-
|
|
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
|