Code archives/Audio/Area Sound

This code has been declared by its author to be Public Domain code.

Download source code

Area Sound by BMA2006
This extension lets you control the volume of a specific sound according to the position of two entities aka. listener and emitter.
For looped sounds place 'AreaSound_update' into your main loop...
; ************************************************************************************************************
; AreaSound - BMA 2006
; ************************************************************************************************************

Type tAreaSound
  Field emitter%
  Field listener%
  Field sound%
  Field emitVolume#
  Field range#
  Field channel%
  Field volume#
End Type


Function AreaSound_create(emitter%, listener%, sound%, range#=10.0, emitVolume#=1.0, loop%=False, play%=True)
  Local s.tAreaSound  = New tAreaSound
  s\emitter     = emitter
  s\listener      = listener
  s\range       = range
  s\emitVolume    = emitVolume
  s\sound       = sound%
  If loop Then LoopSound(s\sound)
  If play Then s\channel = PlaySound(s\sound)
  AreaSound_calc(s)
  If Not loop Then Delete s
  Return Handle(s)
End Function

;call this method in your game loop, when using looped sounds
Function AreaSound_update()
  For s.tAreaSound = Each tAreaSound
    AreaSound_calc(s)
  Next
End Function

Function AreaSound_getCurrentVolume#(soundID%)
  s.tAreaSound = Object.tAreaSound(soundID)
  Return s\volume
End Function

Function AreaSound_setEmitVolume(soundID%, volume#)
  s.tAreaSound = Object.tAreaSound(soundID)
  s\emitVolume = volume
  AreaSound_calc(s)
End Function

Function AreaSound_setEmitterRange(soundID%, range#)
  s.tAreaSound = Object.tAreaSound(soundID)
  s\range = range
  AreaSound_calc(s)
End Function

Function AreaSound_play(soundID%, loop%=False)
  s.tAreaSound = Object.tAreaSound(soundID)
  If loop Then LoopSound(s\sound)
  s\channel = PlaySound(s\sound)
  AreaSound_calc(s)
End Function

Function AreaSound_stop(soundID%)
  s.tAreaSound = Object.tAreaSound(soundID)
  StopChannel(s\sound)
End Function

Function AreaSound_cleanUp()
  Delete Each tAreaSound 
End Function

; ************************************************************************************************************
; Private Method
; ************************************************************************************************************

Function AreaSound_calc(s.tAreaSound)
  d# = EntityDistance(s\listener, s\emitter)
  If d < s\range Then
    s\volume = s\emitVolume - d * s\emitVolume / (s\range)
    ChannelVolume s\channel, s\volume
  Else
    s\volume = 0.0
    ChannelVolume s\channel, 0.0
  EndIf
End Function




; ************************************************************************************************************
; ************************************************************************************************************
; Test Stuff
; ************************************************************************************************************
; ************************************************************************************************************

Graphics3D 640,480,32,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()

camera=CreateCamera()
PositionEntity camera,0,20,-10

light=CreateLight()
RotateEntity light,90,0,0

listener  = CreateCube()
EntityColor listener,255,0,0

emitter   = CreateCube()
range   = CreateSphere(32,emitter)

EntityColor emitter,255,255,0
EntityColor range,0,255,255
EntityAlpha range,0.2

PointEntity camera,listener

PositionEntity listener,0,1,0
PositionEntity emitter,Rand(-10,10),1,Rand(-10,10)

;define emitter range
r# = 8.0

soundFile% = LoadSound("your_sound_here.mp3")

aSound% = AreaSound_create(emitter, listener, soundFile, r, 1.0, True)

While Not KeyHit(1)
   If KeyDown(205) Then TurnEntity listener,0,-1,0
   If KeyDown(203) Then TurnEntity listener,0,1,0
   If KeyDown(208) Then MoveEntity listener,0,0,-0.1
   If KeyDown(200) Then MoveEntity listener,0,0,0.1
   
   If KeyDown(49) Then
      r = r -0.05
      AreaSound_setEmitterRange(aSound, r)
   EndIf
   If KeyDown(50) Then
      r# = r# +0.05
      AreaSound_setEmitterRange(aSound, r)
   EndIf
   
   Xscale#  = ((100/1)  * r) / 100.0
   Yscale#  = ((100/1)  * r) / 100.0
   Zscale#  = ((100/1)  * r) / 100.0

   ScaleEntity range,Xscale#,Yscale#,Zscale#
   
   ;update looped sounds
   AreaSound_update()
   
   RenderWorld
   Text 0,0,"Move Listener with Cursor-Keys"
   Text 0,20,"Set Emitter Range with 'N' and 'M' Keys - Range: "+r
   Text 0,40,"Emitter Sound Volume: "+AreaSound_getCurrentVolume(aSound)
   Flip
Wend
End

Comments

_PJ_2008
I hear nothing.... :S


Mikorians2014
Here's an update that makes it a TRUE REPLACEMENT:




Code Archives Forum