Merge pull request #4881 from Bigfoot71/raylib-sound-positioning
[examples] Add 3D sound spatialization example
This commit is contained in:
commit
ab901c58bb
5 changed files with 124 additions and 6 deletions
|
@ -653,6 +653,7 @@ AUDIO = \
|
||||||
audio/audio_raw_stream \
|
audio/audio_raw_stream \
|
||||||
audio/audio_sound_loading \
|
audio/audio_sound_loading \
|
||||||
audio/audio_sound_multi \
|
audio/audio_sound_multi \
|
||||||
|
audio/audio_sound_positioning \
|
||||||
audio/audio_stream_effects
|
audio/audio_stream_effects
|
||||||
|
|
||||||
OTHERS = \
|
OTHERS = \
|
||||||
|
|
|
@ -535,6 +535,7 @@ AUDIO = \
|
||||||
audio/audio_raw_stream \
|
audio/audio_raw_stream \
|
||||||
audio/audio_sound_loading \
|
audio/audio_sound_loading \
|
||||||
audio/audio_sound_multi \
|
audio/audio_sound_multi \
|
||||||
|
audio/audio_sound_positioning \
|
||||||
audio/audio_stream_effects
|
audio/audio_stream_effects
|
||||||
|
|
||||||
OTHERS = \
|
OTHERS = \
|
||||||
|
|
|
@ -216,6 +216,7 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
||||||
| 146 | [audio_mixed_processor](audio/audio_mixed_processor.c) | <img src="audio/audio_mixed_processor.png" alt="audio_mixed_processor" width="80"> | ⭐️⭐️⭐️⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
|
| 146 | [audio_mixed_processor](audio/audio_mixed_processor.c) | <img src="audio/audio_mixed_processor.png" alt="audio_mixed_processor" width="80"> | ⭐️⭐️⭐️⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
|
||||||
| 147 | [audio_stream_effects](audio/audio_stream_effects.c) | <img src="audio/audio_stream_effects.png" alt="audio_stream_effects" width="80"> | ⭐️⭐️⭐️⭐️ | 4.2 | 5.0 | [Ray](https://github.com/raysan5) |
|
| 147 | [audio_stream_effects](audio/audio_stream_effects.c) | <img src="audio/audio_stream_effects.png" alt="audio_stream_effects" width="80"> | ⭐️⭐️⭐️⭐️ | 4.2 | 5.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 148 | [audio_sound_multi](audio/audio_sound_multi.c) | <img src="audio/audio_sound_multi.png" alt="audio_sound_multi" width="80"> | ⭐️⭐️☆☆ | 4.6 | 4.6 | [Jeffery Myers](https://github.com/JeffM2501) |
|
| 148 | [audio_sound_multi](audio/audio_sound_multi.c) | <img src="audio/audio_sound_multi.png" alt="audio_sound_multi" width="80"> | ⭐️⭐️☆☆ | 4.6 | 4.6 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
|
| 149 | [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐️⭐️☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
|
||||||
|
|
||||||
### category: others
|
### category: others
|
||||||
|
|
||||||
|
@ -223,11 +224,11 @@ Examples showing raylib misc functionality that does not fit in other categories
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
| 149 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | 4.0 | [Ray](https://github.com/raysan5) |
|
| 150 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | 4.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 150 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
|
| 151 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
|
||||||
| 151 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
| 152 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||||
| 152 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | 3.8 | 4.0 | [Stephan Soller](https://github.com/arkanis) |
|
| 153 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | 3.8 | 4.0 | [Stephan Soller](https://github.com/arkanis) |
|
||||||
| 153 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.0 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
| 154 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.0 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
||||||
| 154 | [raymath_vector_angle](others/raymath_vector_angle.c) | <img src="others/raymath_vector_angle.png" alt="raymath_vector_angle" width="80"> | ⭐️⭐️☆☆ | 1.0 | 4.6 | [Ray](https://github.com/raysan5) |
|
| 155 | [raymath_vector_angle](others/raymath_vector_angle.c) | <img src="others/raymath_vector_angle.png" alt="raymath_vector_angle" width="80"> | ⭐️⭐️☆☆ | 1.0 | 4.6 | [Ray](https://github.com/raysan5) |
|
||||||
|
|
||||||
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
|
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
|
||||||
|
|
115
examples/audio/audio_sound_positioning.c
Normal file
115
examples/audio/audio_sound_positioning.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [audio] example - Playing spatialized 3D sound
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||||
|
*
|
||||||
|
* Example contributed by Le Juez Victor (@Bigfoot71) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* 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) 2025 Le Juez Victor (@Bigfoot71)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <raymath.h>
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Sound positioning function
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static void SetSoundPosition(Camera listener, Sound sound, Vector3 position, float maxDist)
|
||||||
|
{
|
||||||
|
// Calculate direction vector and distance between listener and sound source
|
||||||
|
Vector3 direction = Vector3Subtract(position, listener.position);
|
||||||
|
float distance = Vector3Length(direction);
|
||||||
|
|
||||||
|
// Apply logarithmic distance attenuation and clamp between 0-1
|
||||||
|
float attenuation = 1.0f / (1.0f + (distance / maxDist));
|
||||||
|
attenuation = Clamp(attenuation, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Calculate normalized vectors for spatial positioning
|
||||||
|
Vector3 normalizedDirection = Vector3Normalize(direction);
|
||||||
|
Vector3 forward = Vector3Normalize(Vector3Subtract(listener.target, listener.position));
|
||||||
|
Vector3 right = Vector3Normalize(Vector3CrossProduct(forward, listener.up));
|
||||||
|
|
||||||
|
// Reduce volume for sounds behind the listener
|
||||||
|
float dotProduct = Vector3DotProduct(forward, normalizedDirection);
|
||||||
|
if (dotProduct < 0.0f) {
|
||||||
|
attenuation *= (1.0f + dotProduct * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set stereo panning based on sound position relative to listener
|
||||||
|
float pan = 0.5f + 0.5f * Vector3DotProduct(normalizedDirection, right);
|
||||||
|
|
||||||
|
// Apply final sound properties
|
||||||
|
SetSoundVolume(sound, attenuation);
|
||||||
|
SetSoundPan(sound, pan);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
InitWindow(800, 600, "Quick Spatial Sound");
|
||||||
|
InitAudioDevice();
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
DisableCursor();
|
||||||
|
|
||||||
|
Sound sound = LoadSound("resources/coin.wav");
|
||||||
|
|
||||||
|
Camera camera = {
|
||||||
|
.position = (Vector3) { 0, 5, 5 },
|
||||||
|
.target = (Vector3) { 0, 0, 0 },
|
||||||
|
.up = (Vector3) { 0, 1, 0 },
|
||||||
|
.fovy = 60,
|
||||||
|
};
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose())
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
UpdateCamera(&camera, CAMERA_FREE);
|
||||||
|
|
||||||
|
float th = GetTime();
|
||||||
|
|
||||||
|
Vector3 spherePos = {
|
||||||
|
.x = 5.0f * cosf(th),
|
||||||
|
.y = 0.0f,
|
||||||
|
.z = 5.0f * sinf(th)
|
||||||
|
};
|
||||||
|
|
||||||
|
SetSoundPosition(camera, sound, spherePos, 20.0f);
|
||||||
|
if (!IsSoundPlaying(sound)) PlaySound(sound);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
{
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
DrawGrid(10, 2);
|
||||||
|
DrawSphere(spherePos, 0.5f, RED);
|
||||||
|
EndMode3D();
|
||||||
|
}
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadSound(sound);
|
||||||
|
CloseAudioDevice();
|
||||||
|
CloseWindow();
|
||||||
|
}
|
BIN
examples/audio/audio_sound_positioning.png
Normal file
BIN
examples/audio/audio_sound_positioning.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Loading…
Add table
Add a link
Reference in a new issue