Recent

Author Topic: Quick Spatial Sound(raylib)  (Read 291 times)

Guva

  • Full Member
  • ***
  • Posts: 197
  • 🌈 ZX-Spectrum !!!
Quick Spatial Sound(raylib)
« on: April 12, 2025, 03:40:01 am »
Saw a spatial sound example from @Bigfoot71 hanging in pr. My curiosity got the better of me and I rewrote it in Pascal.

Code: Pascal  [Select][+][-]
  1. program audio_spatial_sound;
  2.  
  3. uses
  4.   {$IFDEF LINUX} cthreads,{$ENDIF} raylib, raymath, math;
  5.  
  6. //------------------------------------------------------------------------------------
  7. // Sound positioning procedure
  8. //------------------------------------------------------------------------------------
  9. procedure SetSoundPosition(listener: TCamera; sound: TSound; position: TVector3; maxDist: Single);
  10. var
  11.   direction, normalizedDirection, forward, right: TVector3;
  12.   distance, attenuation, dotProduct, pan: Single;
  13. begin
  14.   // Calculate direction vector and distance between listener and sound source
  15.   direction := Vector3Subtract(position, listener.position);
  16.   distance := Vector3Length(direction);
  17.  
  18.   // Apply logarithmic distance attenuation and clamp between 0-1
  19.   attenuation := 1.0 / (1.0 + (distance / maxDist));
  20.   attenuation := Clamp(attenuation, 0.0, 1.0);
  21.  
  22.   // Calculate normalized vectors for spatial positioning
  23.   if distance > 0 then
  24.     normalizedDirection := Vector3Normalize(direction)
  25.   else
  26.     normalizedDirection := Vector3Create(0, 0, 0);
  27.  
  28.   forward := Vector3Normalize(Vector3Subtract(listener.target, listener.position));
  29.   right := Vector3Normalize(Vector3CrossProduct(forward, listener.up));
  30.  
  31.   // Reduce volume for sounds behind the listener
  32.   dotProduct := Vector3DotProduct(forward, normalizedDirection);
  33.   if dotProduct < 0.0 then
  34.     attenuation := attenuation * (1.0 + dotProduct * 0.5);
  35.  
  36.   // Set stereo panning based on sound position relative to listener
  37.   pan := 0.5 + 0.5 * Vector3DotProduct(normalizedDirection, right);
  38.  
  39.   // Apply final sound properties
  40.   SetSoundVolume(sound, attenuation);
  41.   SetSoundPan(sound, pan);
  42. end;
  43.  
  44. //------------------------------------------------------------------------------------
  45. // Program main entry point
  46. //------------------------------------------------------------------------------------
  47. var
  48.   sound: TSound;
  49.   camera: TCamera;
  50.   th: Single;
  51.   spherePos: TVector3;
  52. begin
  53.   // Initialization
  54.   //--------------------------------------------------------------------------------------
  55.   InitWindow(800, 600, 'Quick Spatial Sound');
  56.   InitAudioDevice();
  57.  
  58.   SetTargetFPS(60);
  59.   DisableCursor();
  60.  
  61.   sound := LoadSound('resources/coin.wav');
  62.  
  63.   camera.position := Vector3Create(0, 5, 5);
  64.   camera.target := Vector3Create(0, 0, 0);
  65.   camera.up := Vector3Create(0, 1, 0);
  66.   camera.fovy := 60;
  67.   camera.projection := CAMERA_PERSPECTIVE;
  68.   //--------------------------------------------------------------------------------------
  69.  
  70.   // Main game loop
  71.   while not WindowShouldClose() do
  72.   begin
  73.     // Update
  74.     //----------------------------------------------------------------------------------
  75.     UpdateCamera(@camera, CAMERA_FREE);
  76.  
  77.     th := GetTime();
  78.  
  79.     spherePos.x := 5.0 * Cos(th);
  80.     spherePos.y := 0.0;
  81.     spherePos.z := 5.0 * Sin(th);
  82.  
  83.     SetSoundPosition(camera, sound, spherePos, 20.0);
  84.     if not IsSoundPlaying(sound) then PlaySound(sound);
  85.     //----------------------------------------------------------------------------------
  86.  
  87.     // Draw
  88.     //----------------------------------------------------------------------------------
  89.     BeginDrawing();
  90.       ClearBackground(BLACK);
  91.  
  92.       BeginMode3D(camera);
  93.         DrawGrid(10, 2);
  94.         DrawSphere(spherePos, 0.5, RED);
  95.       EndMode3D();
  96.     EndDrawing();
  97.     //----------------------------------------------------------------------------------
  98.   end;
  99.  
  100.   // De-Initialization
  101.   //--------------------------------------------------------------------------------------
  102.   UnloadSound(sound);
  103.   CloseAudioDevice();
  104.   CloseWindow();
  105. end.
  106.  

 

TinyPortal © 2005-2018