Warcraft III: MapsModelsSkinsIconsSpellsToolsTutorials
WC3 JASS: Code SnippetsJASS and vJASS Spells and SystemsJass Tutorials
Chat @Discord

Author Topic: [System] Simulate 3D Sound  (Read 14862 times)

  • Rookie - level 1
  • *
  • Posts: 45
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • Reputation: 13
    • View Profile
[System] Simulate 3D Sound
« on: May 02, 2013, 08:55:38 PM »
This library will allow you to simulate a 3D sound. It will have most of the features of a 3D sound, except for cones and velocity. Most of these are guesstimates, but when I compared it to the regular 3D sounds, they were very similar.

I don't have a 100% concrete grasp on what each field does, so if you have more insight on it, feel free to share. I interpreted it from a lot of testing, but even then there are still a few things I can't account for.

Anyway, why have this system? (1) 3D sounds are incredibly annoying. As far as I can tell, mp3's and 2-channel sounds don't work as them. This will allow you to use it as a regular sound, so you won't have to worry about any of that. (2) If you have a 3D sound, you cannot use SetSoundPlayPosition(...). If your sound is not 3D, you cannot have 3D features (obviously). This system will serve as a compromise, having the sound as non-3D and emulating the features of 3D sounds to get the best aspects of both sides. 

Enjoy.

Code: jass  [Select]
  1. library Simulate3DSound /* v.1.0.1.1
  2. *********************************************************************
  3. *
  4. *   Simulates a 3D Sound using a regular sound. This extends the
  5. *   functionality for regular sounds, allowing you to apply 3D
  6. *   sound effects and positioning. In addition, you can use the
  7. *   sound functions that require the sound to be normal (non-3D).
  8. *
  9. *   This will allow you to use sounds that normally wouldn't work
  10. *   as 3D (for example, 2-channel wav).
  11. *
  12. *********************************************************************
  13. *
  14. *   */uses/*
  15. *  
  16. *       */ TimerUtils /*    [url]http://www.wc3c.net/showthread.php?t=101322[/url]
  17. *
  18. ********************************************************************
  19. *
  20. *   Description of Arguments
  21. *
  22. *       sound s
  23. *
  24. *           - The base sound to be played. The function will play
  25. *             the sound for you. This sound must already exist as
  26. *             an object (you have to create it).
  27. *
  28. *       unit u
  29. *      
  30. *           - The sound will follow this unit around. The closer
  31. *             the camera is to this unit, the louder the sound.
  32. *
  33. *       real x, y
  34. *
  35. *           - The sound will project from this point. The volume
  36. *             is loudest within the point's area.
  37. *
  38. *       real minD (minimum distance)
  39. *
  40. *           - Determines how far the camera can go without attenuating
  41. *             the volume. From the origin to this distance, the sound's
  42. *             volume will be 100%.
  43. *
  44. *       real maxD (maximum distance)
  45. *
  46. *           - Once the camera is past the minimum distance, it will
  47. *             gradually reduce until it hits the maximum distance.
  48. *             Once it is at the maximum distance or beyond, it will
  49. *             no longer lose volume unless it hits the distance cutoff.
  50. *
  51. *       real distCutoff (distance cutoff)
  52. *
  53. *           - The sound will fade to 0% volume once it hits this distance.
  54. *             If the camera is farther than "distCutoff" when the sound
  55. *             is played, the sound will not be heard by that player.
  56. *
  57. ********************************************************************
  58. *
  59. *   Functions
  60. *
  61. *       function BindSoundToUnit takes sound s, unit u, real minD, real maxD, real distCut returns Sim3DSound
  62. *           - Attaches a regular sound to a unit.
  63. *       function BindSoundToPoint takes sound s, real x, real y, real minD, real maxD, real distCut returns Sim3DSound
  64. *           - Attaches a regular sound to a point.
  65. *       function SetSoundUnit takes Sim3DSound s, unit u returns nothing
  66. *           - Allows you to switch the unit the sound is projecting from.
  67. *       function SetSoundCoordinates takes Sim3DSound s, real x, real y returns nothing
  68. *           - Allows you to move the sound to another point.
  69. *       function BindSoundToUnitForPlayer takes player p, sound s, unit u, real minD, real maxD, real distCut returns Sim3DSound
  70. *       function BindSoundToPointForPlayer takes player p, sound s, real x, real y, real minD, real maxD, real distCut returns Sim3DSound
  71. *
  72. ********************************************************************
  73. *
  74. *   Bugs
  75. *
  76. *       This doesn't behave 100% like Warcraft 3 3D sounds. It does
  77. *       not increase volume in relation to zoom (I may add that feature
  78. *       in the future), and the "minimum distance" does not behave
  79. *       exactly like Warcraft 3's. I'm still trying to figure it out.
  80. *       However, it is realistic and works well.
  81. *
  82. ********************************************************************/
  83.  
  84.     globals
  85.         // Determines how often the volume is updated
  86.         private constant real PERIOD = 0.2
  87.     endglobals
  88.  
  89.     private struct Sim3DSound
  90.         private sound snd
  91.         private unit source
  92.         private real sourceX
  93.         private real sourceY
  94.         private boolean adjust
  95.        
  96.         private real initial
  97.         private real factor
  98.         private real dur
  99.         private real maxD
  100.         private real distCut
  101.        
  102.         private static method expire takes nothing returns nothing
  103.             local thistype this = GetTimerData(GetExpiredTimer())
  104.             local real dx  
  105.             local real dy            
  106.             local real dist
  107.             local integer volume = 0
  108.            
  109.             if this.source == null then
  110.                 set dx = this.sourceX - GetCameraTargetPositionX()
  111.                 set dy = this.sourceY - GetCameraTargetPositionY()
  112.             else
  113.                 set dx = GetUnitX(this.source) - GetCameraTargetPositionX()
  114.                 set dy = GetUnitY(this.source) - GetCameraTargetPositionY()
  115.             endif
  116.             set dist = SquareRoot(dx * dx + dy * dy)
  117.            
  118.             if this.adjust then
  119.                 if dist > maxD and dist < distCut then
  120.                     call SetSoundVolume(snd, R2I(this.initial - maxD * this.factor))
  121.                 else
  122.                     set volume = R2I(this.initial - dist * this.factor) // linear reduction
  123.                     if volume < 0 then
  124.                         call SetSoundVolume(snd, 1)
  125.                     else
  126.                         call SetSoundVolume(snd, volume)
  127.                     endif
  128.                 endif
  129.             endif
  130.             if this.dur <= 0 then
  131.                 call ReleaseTimer(GetExpiredTimer())
  132.             endif
  133.             set this.dur = this.dur - PERIOD
  134.         endmethod
  135.        
  136.         method setSoundPosition takes real x, real y returns nothing
  137.             set this.sourceX = x
  138.             set this.sourceY = y
  139.         endmethod
  140.        
  141.         method setSource takes unit u returns nothing
  142.             set this.source = u
  143.         endmethod
  144.        
  145.         static method createOnPoint takes sound s, real x, real y, real minDist, real maxDist, real distCutoff returns thistype
  146.             local thistype this = thistype.create()
  147.             local real dx = x - GetCameraTargetPositionX()
  148.             local real dy = y - GetCameraTargetPositionY()
  149.             local real dist = dx*dx + dy*dy
  150.            
  151.             set this.snd = s
  152.             set this.source = null
  153.             set this.sourceX = x
  154.             set this.sourceY = y
  155.             set this.distCut = distCutoff
  156.             set this.factor = 127 / distCutoff
  157.             set this.initial = 127 + minDist * this.factor
  158.             set this.maxD = maxDist
  159.             set this.dur = GetSoundDuration(s) * 0.001
  160.             set this.adjust = dist < distCutoff * distCutoff
  161.             if not this.adjust then
  162.                 call SetSoundVolume(s, 1)
  163.             endif
  164.            
  165.             call TimerStart(NewTimerEx(this), PERIOD, true, function thistype.expire)
  166.             return this
  167.         endmethod
  168.        
  169.         static method attachToUnit takes sound s, unit u, real minDist, real maxDist, real distCutoff returns thistype
  170.             local thistype this = thistype.create()
  171.             local real dx = GetUnitX(u) - GetCameraTargetPositionX()
  172.             local real dy = GetUnitY(u) - GetCameraTargetPositionY()
  173.             local real dist = dx*dx + dy*dy
  174.            
  175.             set this.snd = s
  176.             set this.source = u
  177.             set this.distCut = distCutoff
  178.             set this.factor = 127 / distCutoff
  179.             set this.initial = 127 + minDist * this.factor
  180.             set this.maxD = maxDist
  181.             set this.dur = GetSoundDuration(s) * 0.001
  182.             set this.adjust = dist < distCutoff * distCutoff
  183.             if not this.adjust then
  184.                 call SetSoundVolume(s, 1)
  185.             endif
  186.            
  187.             call TimerStart(NewTimerEx(this), PERIOD, true, function thistype.expire)
  188.             return this
  189.         endmethod
  190.     endstruct
  191.    
  192.     function BindSoundToUnit takes sound s, unit u, real minD, real maxD, real distCut returns Sim3DSound
  193.         if not GetSoundIsPlaying(s) then
  194.             call StartSound(s)
  195.         endif
  196.         return Sim3DSound.attachToUnit(s, u, minD, maxD, distCut)
  197.     endfunction
  198.    
  199.     function BindSoundToPoint takes sound s, real x, real y, real minD, real maxD, real distCut returns Sim3DSound
  200.         if not GetSoundIsPlaying(s) then
  201.             call StartSound(s)
  202.         endif
  203.         return Sim3DSound.createOnPoint(s, x, y, minD, maxD, distCut)
  204.     endfunction
  205.    
  206.     function SetSoundUnit takes Sim3DSound s, unit u returns nothing
  207.         call s.setSource(u)
  208.     endfunction
  209.    
  210.     function SetSoundCoordinates takes Sim3DSound s, real x, real y returns nothing
  211.         call s.setSoundPosition(x, y)
  212.     endfunction
  213.    
  214.     function BindSoundToUnitForPlayer takes player p, sound s, unit u, real minD, real maxD, real distCut returns Sim3DSound
  215.         if GetLocalPlayer() == p then
  216.             if not GetSoundIsPlaying(s) then
  217.                 call StartSound(s)
  218.             endif
  219.         endif
  220.         return Sim3DSound.attachToUnit(s, u, minD, maxD, distCut)
  221.     endfunction
  222.    
  223.     function BindSoundToPointForPlayer takes player p, sound s, real x, real y, real minD, real maxD, real distCut returns Sim3DSound
  224.         if GetLocalPlayer() == p then
  225.             if not GetSoundIsPlaying(s) then
  226.                 call StartSound(s)
  227.             endif
  228.         endif
  229.         return Sim3DSound.createOnPoint(s, x, y, minD, maxD, distCut)
  230.     endfunction
  231.    
  232. endlibrary

EDIT: Updated with test map and support for SoundTools. (just use call BindSound...(soundObject.run()) or whatever the method is.
« Last Edit: July 15, 2013, 12:35:45 AM by Purgeandfire »

  • Site Owner
  • Administrator
  • Starter - level 4
  • *
  • Posts: 977
  • WC3 Models: 59
  • WC3 Tutorials: 13
  • WC3 Tools: 10
  • WC3 Maps: 12
  • WC3 Skins: 6
  • WC3 Icons: 2
  • WC3 Spells: 6
  • Reputation: 1153
  • Site Admin - I love fix things
    • View Profile
    • Blizzard Modding Information Center
Simulate 3D Sound
« Reply #1 on: May 02, 2013, 10:17:50 PM »
WOAHHH!!! man!!! this is awesome!!! just one thing. I consider to add a test map and with it an example about how to use it.

We can give you full hosting for your projects, a complete page!!

A custom altered melee map where you can play Naga and Demons. Check it out!!
Use Dropbox...

  • Rookie - level 1
  • *
  • Posts: 45
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • Reputation: 13
    • View Profile
Simulate 3D Sound
« Reply #2 on: May 02, 2013, 11:15:50 PM »
I added a test map. Although, I didn't really know what to explain. The test map is really hastily-made though, nothing fancy. You can play the sound, then you can move your camera away and watch the system work its magic. That is about it.

I added one example in GUI-jass and one in vJASS.

  • Site Owner
  • Administrator
  • Starter - level 4
  • *
  • Posts: 977
  • WC3 Models: 59
  • WC3 Tutorials: 13
  • WC3 Tools: 10
  • WC3 Maps: 12
  • WC3 Skins: 6
  • WC3 Icons: 2
  • WC3 Spells: 6
  • Reputation: 1153
  • Site Admin - I love fix things
    • View Profile
    • Blizzard Modding Information Center
Simulate 3D Sound
« Reply #3 on: May 05, 2013, 11:06:27 AM »
Great!!! That's what I call a nice resource. In fact this baby have some nice purpose in a secret project of mine :)

We can give you full hosting for your projects, a complete page!!

A custom altered melee map where you can play Naga and Demons. Check it out!!
Use Dropbox...

  • Awesome Global Code Moderator
  • Recognized User
  • Rookie - level 2
  • *
  • Posts: 84
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • Reputation: 516
  • vJass Incarnate
    • View Profile
Simulate 3D Sound
« Reply #4 on: May 14, 2013, 12:01:52 PM »
This seems like a nice resource.

From what I can see, this should work well in multiplayer since no local factors will lead to any variations in the local handle and string tables.

Approved.

  • Rookie - level 1
  • *
  • Posts: 45
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • Reputation: 13
    • View Profile
[System] Simulate 3D Sound
« Reply #5 on: June 28, 2013, 10:40:51 PM »
These are what the sound fields are supposed to represent:

Min Distance - The sound level at the minimum distance that the sound can be heard.
Max Distance - The sound level at the maximum distance that the sound can be heard.
Distance Cutoff - The distance at which the sound will begin to fade out.

I found it in the readme for the sound editor. Oops. Anyway, I may update this eventually to mimic it more accurately now that I know the proper definitions, but for now this system should come pretty close (or at least, it should be able to offer similar behavior).

  • Newbie - level 3
  • ***
  • Posts: 31
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • Reputation: 1
  • User
    • View Profile
[System] Simulate 3D Sound
« Reply #6 on: June 29, 2013, 05:01:32 PM »
Purgeandfire rank: newbie
wat?
give him epic guy rank (?)

  • Rookie - level 1
  • *
  • Posts: 45
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • Reputation: 13
    • View Profile
[System] Simulate 3D Sound
« Reply #7 on: July 15, 2013, 12:36:35 AM »
Thanks darkly. :)

Bugfix. I was referring to this.source when it was null. Sorry to anyone who had issues with it.

 

New Hero Selection System for version 1.6!!!

Started by SonofJayBoard General Information

Replies: 3
Views: 5781
Last post July 01, 2013, 03:59:31 PM
by Chaosy
Advanced AI system (AKA AMAI 2)

Started by moyackBoard Jass Theory & Questions

Replies: 6
Views: 13612
Last post September 06, 2012, 09:54:35 PM
by moyack
Advanced Streak System v4.3.0.0

Started by Magtheridon96Board Warcraft III Spells and Systems

Replies: 2
Views: 7286
Last post June 25, 2013, 08:54:56 PM
by LembidiZ
What people want in a Custom XP System?

Started by Naoto ShiroganeBoard Triggers & Scripting

Replies: 3
Views: 4172
Last post April 02, 2015, 06:36:41 PM
by moyack
WC3 - New map pool system: PTR 1.29 is coming!!!

Started by moyackBoard Warcraft III News

Replies: 0
Views: 302
Last post August 03, 2017, 08:25:42 AM
by moyack
Blizzard Modding Information Center Starcraft II Modding Information Center Wacraft III Modding Information Center WC3JASS.com - The JASS Vault Chronicles of Darkness - A Warcraft III mod Jetcraft - A Starcraft II mod Troll Smash - A Warcraft III Arena
  Mod DB - Change the Game Power of Corruption - A Warcraft III altered melee map Chaos Realm - The world of Game modders and wc3 addicts Follow us on Facebook!!