/src/away3d/audio/SoundTransform3D.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 169 lines · 104 code · 32 blank · 33 comment · 6 complexity · 9c3e1646a9fe454e3de92254b446ca70 MD5 · raw file

  1. package away3d.audio
  2. {
  3. import away3d.containers.ObjectContainer3D;
  4. import flash.geom.Matrix3D;
  5. import flash.geom.Vector3D;
  6. import flash.media.SoundTransform;
  7. /**
  8. * SoundTransform3D is a convinience class that helps adjust a Soundtransform's volume and pan according
  9. * position and distance of a listener and emitter object. See SimplePanVolumeDriver for the limitations
  10. * of this method.
  11. */
  12. public class SoundTransform3D
  13. {
  14. private var _scale:Number;
  15. private var _volume:Number;
  16. private var _soundTransform:SoundTransform;
  17. private var _emitter:ObjectContainer3D;
  18. private var _listener:ObjectContainer3D;
  19. private var _refv:Vector3D;
  20. private var _inv_ref_mtx:Matrix3D;
  21. private var _r:Number;
  22. private var _r2:Number;
  23. private var _azimuth:Number;
  24. /**
  25. * Creates a new SoundTransform3D.
  26. * @param emitter the ObjectContainer3D from which the sound originates.
  27. * @param listener the ObjectContainer3D considered to be to position of the listener (usually, the camera)
  28. * @param volume the maximum volume used.
  29. * @param scale the distance that the sound covers.
  30. *
  31. */
  32. public function SoundTransform3D(emitter:ObjectContainer3D = null, listener:ObjectContainer3D = null, volume:Number = 1, scale:Number = 1000)
  33. {
  34. _emitter = emitter;
  35. _listener = listener;
  36. _volume = volume;
  37. _scale = scale;
  38. _inv_ref_mtx = new Matrix3D();
  39. _refv = new Vector3D();
  40. _soundTransform = new SoundTransform(volume);
  41. _r = 0;
  42. _r2 = 0;
  43. _azimuth = 0;
  44. }
  45. /**
  46. * updates the SoundTransform based on the emitter and listener.
  47. */
  48. public function update():void
  49. {
  50. if (_emitter && _listener) {
  51. _inv_ref_mtx.rawData = _listener.sceneTransform.rawData;
  52. _inv_ref_mtx.invert();
  53. _refv = _inv_ref_mtx.deltaTransformVector(_listener.position);
  54. _refv = _emitter.scenePosition.subtract(_refv);
  55. }
  56. updateFromVector3D(_refv);
  57. }
  58. /**
  59. * udpates the SoundTransform based on the vector representing the distance and
  60. * angle between the emitter and listener.
  61. *
  62. * @param v Vector3D
  63. *
  64. */
  65. public function updateFromVector3D(v:Vector3D):void
  66. {
  67. _azimuth = Math.atan2(v.x, v.z);
  68. if (_azimuth < -1.5707963)
  69. _azimuth = -(1.5707963 + (_azimuth%1.5707963));
  70. else if (_azimuth > 1.5707963)
  71. _azimuth = 1.5707963 - (_azimuth%1.5707963);
  72. // Divide by a number larger than pi/2, to make sure
  73. // that pan is never full +/-1.0, muting one channel
  74. // completely, which feels very unnatural.
  75. _soundTransform.pan = (_azimuth/1.7);
  76. // Offset radius so that max value for volume curve is 1,
  77. // (i.e. y~=1 for r=0.) Also scale according to configured
  78. // driver scale value.
  79. _r = (v.length/_scale) + 0.28209479;
  80. _r2 = _r*_r;
  81. // Volume is calculated according to the formula for
  82. // sound intensity, I = P / (4 * pi * r^2)
  83. // Avoid division by zero.
  84. if (_r2 > 0)
  85. _soundTransform.volume = (1/(12.566*_r2)); // 1 / 4pi * r^2
  86. else
  87. _soundTransform.volume = 1;
  88. // Alter according to user-specified volume
  89. _soundTransform.volume *= _volume;
  90. }
  91. public function get soundTransform():SoundTransform
  92. {
  93. return _soundTransform;
  94. }
  95. public function set soundTransform(value:SoundTransform):void
  96. {
  97. _soundTransform = value;
  98. update();
  99. }
  100. public function get scale():Number
  101. {
  102. return _scale;
  103. }
  104. public function set scale(value:Number):void
  105. {
  106. _scale = value;
  107. update();
  108. }
  109. public function get volume():Number
  110. {
  111. return _volume;
  112. }
  113. public function set volume(value:Number):void
  114. {
  115. _volume = value;
  116. update();
  117. }
  118. public function get emitter():ObjectContainer3D
  119. {
  120. return _emitter;
  121. }
  122. public function set emitter(value:ObjectContainer3D):void
  123. {
  124. _emitter = value;
  125. update();
  126. }
  127. public function get listener():ObjectContainer3D
  128. {
  129. return _listener;
  130. }
  131. public function set listener(value:ObjectContainer3D):void
  132. {
  133. _listener = value;
  134. update();
  135. }
  136. }
  137. }