diff --git a/examples/audio_sound_loading.c b/examples/audio_sound_loading.c new file mode 100644 index 0000000..ec5dd66 --- /dev/null +++ b/examples/audio_sound_loading.c @@ -0,0 +1,83 @@ +/******************************************************************************************* +* +* raylib [audio] example - Sound loading and playing +* +* Example originally created with raylib 1.1, last time updated with raylib 3.5 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +void raylib_js_set_entry(void (*entry)(void)); + +Sound fxWav; +Sound fxOgg; + +void GameFrame(void) +{ + // Update + //---------------------------------------------------------------------------------- + if (IsKeyPressed(KEY_SPACE)) PlaySound(fxWav); // Play WAV sound + if (IsKeyPressed(KEY_ENTER)) PlaySound(fxOgg); // Play OGG sound + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, LIGHTGRAY); + DrawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, LIGHTGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- +} + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading and playing"); + + InitAudioDevice(); // Initialize audio device + + fxWav = LoadSound("resources/sound.wav"); // Load WAV audio file + fxOgg = LoadSound("resources/target.ogg"); // Load OGG audio file + + SetTargetFPS(60); // Set desired framerate (frames-per-second) + //-------------------------------------------------------------------------------------- + +#ifdef PLATFORM_WEB + raylib_js_set_entry(GameFrame); +#else + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + GameFrame(); + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadSound(fxWav); // Unload sound data + UnloadSound(fxOgg); // Unload sound data + + CloseAudioDevice(); // Close audio device + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- +#endif + + return 0; +} diff --git a/index.html b/index.html index 960a2cd..c1d6518 100644 --- a/index.html +++ b/index.html @@ -68,6 +68,7 @@ <script> const wasmPaths = { "tsoding": ["tsoding_ball", "tsoding_snake",], + "audio": ["audio_sound_loading"], "core": ["core_basic_window", "core_basic_screen_manager", "core_input_keys", "core_input_mouse_wheel",], "shapes": ["shapes_colors_palette"], "text": ["text_writing_anim"], diff --git a/nob.c b/nob.c index 15ef36d..c02c6c4 100644 --- a/nob.c +++ b/nob.c @@ -8,6 +8,11 @@ typedef struct { } Example; Example examples[] = { + { + .src_path = "./examples/audio_sound_loading.c", + .bin_path = "./build/audio_sound_loading", + .wasm_path = "./wasm/audio_sound_loading.wasm", + }, { .src_path = "./examples/core_basic_window.c", .bin_path = "./build/core_basic_window", diff --git a/raylib.js b/raylib.js index 6e48efd..0aa70a3 100644 --- a/raylib.js +++ b/raylib.js @@ -44,6 +44,7 @@ class RaylibJs { this.currentMousePosition = {x: 0, y: 0}; this.images = []; this.quit = false; + this.audio = []; } constructor() { @@ -353,6 +354,77 @@ class RaylibJs { this.ctx.fillText(text, posX, posY + fontSize); } + // RLAPI void InitAudioDevice(void); // Initialize audio device and context + InitAudioDevice() { + if (!this.audio) { + this.audio = []; + } + } + + // RLAPI void CloseAudioDevice(void); // Close the audio device and context + CloseAudioDevice() { + this.audio = []; + } + + // RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully + IsAudioDeviceReady() { + return this.audio && Array.isArray(this.audio); + } + + // RLAPI Sound LoadSound(const char *fileName); // Load sound from file + LoadSound(result_ptr, fileName_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const filename = cstr_by_ptr(buffer, fileName_ptr); + const sound = new Audio(filename); + this.audio.push(sound); + + const result = new Uint32Array(buffer, result_ptr, 6); + result[0] = this.audio.length; // Sound::AudioStream::buffer + result[1] = 1; // Sound::AudioStream::processor + result[2] = 1; // Sound::AudioStream::sampleRate + result[3] = 1; // Sound::AudioStream::sampleSize + result[4] = 2; // Sound::AudioStream::channels + result[5] = 1; // Sound::frameCount + + return result; + } + + // RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready + IsSoundReady(sound_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [id, processor, sampleRate, sampleSize, channels, frameCount] = new Uint32Array(buffer, sound_ptr, 6); + if (id <= 0 || id > this.audio.length) { + return false; + } + return this.audio[id - 1] != null; + } + + // RLAPI void UnloadSound(Sound sound); // Unload sound + UnloadSound(sound_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [id, processor, sampleRate, sampleSize, channels, frameCount] = new Uint32Array(buffer, sound_ptr, 6); + if (id <= 0 || id > this.audio.length) { + return; + } + this.audio[id - 1] = null; + } + + // RLAPI void PlaySound(Sound sound); // Play a sound + PlaySound(sound_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [id, processor, sampleRate, sampleSize, channels, frameCount] = new Uint32Array(buffer, sound_ptr, 6); + if (id <= 0 || id > this.audio.length) { + return; + } + const audio = this.audio[id - 1]; + if (!audio) { + return; + } + audio.loop = false; + audio.currentTime = 0; + audio.play(); + } + GetRandomValue(min, max) { return min + Math.floor(Math.random()*(max - min + 1)); } diff --git a/resources/sound.wav b/resources/sound.wav new file mode 100644 index 0000000..b5d01c9 Binary files /dev/null and b/resources/sound.wav differ diff --git a/resources/target.ogg b/resources/target.ogg new file mode 100644 index 0000000..2b73e1c Binary files /dev/null and b/resources/target.ogg differ diff --git a/wasm/audio_sound_loading.wasm b/wasm/audio_sound_loading.wasm new file mode 100755 index 0000000..349f8a9 Binary files /dev/null and b/wasm/audio_sound_loading.wasm differ