sound positioning
There is no browser build of this example yet.
Is it the same as C?
- Desktop:verified The Zig version renders a final frame that is byte-identical to the C example.
- Browser:not checked yet The browser comparison does not cover this example yet.
//! raylib [audio] example - sound positioning
//!
//! Zig-API translation of examples/audio/audio_sound_positioning.c (raylib 6.2).
//! Example contributed by Le Juez Victor (@Bigfoot71) and reviewed by Ramon Santamaria (@raysan5)
//! Example licensed under an unmodified zlib/libpng license.
//! Copyright (c) 2025 Le Juez Victor (@Bigfoot71)
const rl = @import("raylib");
const rm = rl.math;
pub fn main() !void {
// Initialization
const screen_width = 800;
const screen_height = 450;
rl.initWindow(screen_width, screen_height, "raylib [audio] example - sound positioning");
defer rl.closeWindow(); // Close window and OpenGL context
rl.initAudioDevice();
defer rl.closeAudioDevice(); // Close audio device
const sound = try rl.loadSound("resources/coin.wav");
defer rl.unloadSound(sound);
var camera: rl.Camera = .{
.position = .{ .x = 0, .y = 5, .z = 5 },
.target = .{ .x = 0, .y = 0, .z = 0 },
.up = .{ .x = 0, .y = 1, .z = 0 },
.fovy = 60,
.projection = .perspective,
};
rl.disableCursor();
rl.setTargetFPS(60);
// Main game loop
while (!rl.windowShouldClose()) {
// Update
rl.updateCamera(&camera, .free);
const th: f32 = @floatCast(rl.getTime());
const sphere_pos: rl.Vector3 = .{
.x = 5.0 * @cos(th),
.y = 0.0,
.z = 5.0 * @sin(th),
};
setSoundPosition(camera, sound, sphere_pos, 1.0);
if (!rl.isSoundPlaying(sound)) rl.playSound(sound);
// Draw
rl.beginDrawing();
defer rl.endDrawing();
rl.clearBackground(.ray_white);
rl.beginMode3D(camera);
rl.drawGrid(10, 2);
rl.drawSphere(sphere_pos, 0.5, .red);
rl.endMode3D();
}
}
/// Set sound 3d position
fn setSoundPosition(listener: rl.Camera, sound: rl.Sound, position: rl.Vector3, max_dist: f32) void {
// Calculate direction vector and distance between listener and sound source
const direction = rm.vector3Subtract(position, listener.position);
const distance = rm.vector3Length(direction);
// Apply logarithmic distance attenuation and clamp between 0-1
var attenuation = 1.0 / (1.0 + (distance / max_dist));
attenuation = rm.clamp(attenuation, 0.0, 1.0);
// Calculate normalized vectors for spatial positioning
const normalized_direction = rm.vector3Normalize(direction);
const forward = rm.vector3Normalize(rm.vector3Subtract(listener.target, listener.position));
const right = rm.vector3Normalize(rm.vector3CrossProduct(forward, listener.up));
// Reduce volume for sounds behind the listener
const dot_product = rm.vector3DotProduct(forward, normalized_direction);
if (dot_product < 0.0) attenuation *= (1.0 + dot_product * 0.5);
// Set stereo panning based on sound position relative to listener
const pan = rm.vector3DotProduct(normalized_direction, right);
// Apply final sound properties
rl.setSoundVolume(sound, attenuation);
rl.setSoundPan(sound, pan);
}/*******************************************************************************************
*
* raylib [audio] example - sound positioning
*
* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 6.0
*
* 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"
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static void SetSoundPosition(Camera listener, Sound sound, Vector3 position, float maxDist);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound positioning");
InitAudioDevice();
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,
.projection = CAMERA_PERSPECTIVE
};
DisableCursor();
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera, CAMERA_FREE);
float th = (float)GetTime();
Vector3 spherePos = {
.x = 5.0f*cosf(th),
.y = 0.0f,
.z = 5.0f*sinf(th)
};
SetSoundPosition(camera, sound, spherePos, 1.0f);
if (!IsSoundPlaying(sound)) PlaySound(sound);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawGrid(10, 2);
DrawSphere(spherePos, 0.5f, RED);
EndMode3D();
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadSound(sound);
CloseAudioDevice(); // Close audio device
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Set sound 3d position
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 = Vector3DotProduct(normalizedDirection, right);
// Apply final sound properties
SetSoundVolume(sound, attenuation);
SetSoundPan(sound, pan);
}From raylib 6.2. The original on GitHub.