[bb] Area Sound by BMA [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:43

Previous topic - Next topic

BlitzBot

Title : Area Sound
Author : BMA
Posted : 1+ years ago

Description : 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...


Code :
Code (blitzbasic) Select
; ************************************************************************************************************
; 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
  semitter     = emitter
  slistener      = listener
  sange       = range
  semitVolume    = emitVolume
  ssound       = sound%
  If loop Then LoopSound(ssound)
  If play Then schannel = PlaySound(ssound)
  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 svolume
End Function

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

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

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

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

Function AreaSound_cleanUp()
  Delete Each tAreaSound
End Function

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

Function AreaSound_calc(s.tAreaSound)
  d# = EntityDistance(slistener, semitter)
  If d < sange Then
    svolume = semitVolume - d * semitVolume / (sange)
    ChannelVolume schannel, svolume
  Else
    svolume = 0.0
    ChannelVolume schannel, 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_(Posted 1+ years ago)

 I hear nothing.... :S


Mikorians(Posted 1+ years ago)

 Here's an update that makes it a TRUE REPLACEMENT:
; UPDATED FOR 3D RELATIVE PANNING by Mikorians 2014
; ID: 1759
; Author: BMA
; Date: 2006-07-22 12:29:29
; Title: Area Sound
; Description: Alternative to BB's 3DSound Functions

; ************************************************************************************************************
; AreaSound - BMA 2006
; ************************************************************************************************************

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


Function AreaSound_create(emitter%, listener%, sound%, range#=10.0, emitVolume#=1.0, loop%=False, play%=True)
  Local s.tAreaSound  = New tAreaSound
  semitter     = emitter
  slistener    = listener
  sange       = range
  semitVolume  = emitVolume
  ssound       = sound%
span = 0.0
  If loop Then LoopSound(ssound)
  If play Then schannel = PlaySound(ssound)
  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 svolume
End Function

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

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

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

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

Function AreaSound_cleanUp()
  Delete Each tAreaSound
End Function

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

Function AreaSound_calc(s.tAreaSound)
  d# = EntityDistance(slistener, semitter)
  If d < sange Then
    svolume = semitVolume - d * semitVolume / (sange)
    ChannelVolume schannel, svolume
q#=rec2pol#(EntityX#(slistener,True),EntityZ#(slistener,True),EntityX#(semitter,True),EntityZ#(semitter,True)) ;The angle betwixt the two
q#=q#+angtrm#(EntityYaw#(slistener,True)) ;Add the listener's rotation (ear direction)
span=-Sgn((q#-180) Mod 180)*(1-(Abs(90-(q# Mod 180))/90)) ;This works.
ChannelPan schannel,span
  Else
span=0
    svolume = 0.0
    ChannelVolume schannel, 0.0
ChannelPan schannel,span
  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("C:WINDOWSMediaSnore.wav")

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

Function Rec2Pol#(X1#,Y1#,X2#,Y2#)
C# = 3.141592654 / 180
OX# = X2# - X1#: OY# = Y2# - Y1#:R# = Sqr((OX# ^ 2) + (OY# ^ 2))
If Sgn(OX#)=0 And Sgn(OY#)=0 Then Ret#=0:Goto XitR
If OX<0 And OY<0 Then QT=180
If OX<0 And OY>0 Then QT=180
If OX=0 And OY>0 Then Ret#=0:Goto XitR
If OX>0 And OY=0 Then Ret#=90:Goto XitR
If OX=0 And OY<0 Then Ret#=180:Goto XitR
If OX<0 And OY=0 Then Ret#=270:Goto XitR
Ret# = 90-ATan((OY / R#) / (OX# / R#))+QT
.XitR
Return Ret#
End Function

Function AngTrm#(Ang#)
Return (360.0+(Ang# Mod 360)) Mod 360.0
End Function