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

Author Topic: [System] SoundTools  (Read 5611 times)

  • Awesome Global Code Moderator
  • Recognized User
  • Rookie - level 2
  • *
  • Posts: 83
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • Reputation: 516
  • vJass Incarnate
    • View Profile
[System] SoundTools
« on: July 09, 2012, 01:43:19 PM »
This system allows you to play a sound immediately after creating it (Which is impossible inside Warcraft III)

Basically, all what it does is start a timer and play the sound.
It also recycles these sounds to decrease the amount of RAM used up.

Code: jass  [Select]
  1. /***********************************************
  2. *
  3. *   SoundTools
  4. *   v2.3.0.0
  5. *   By Magtheridon96
  6. *
  7. *   (Special Thanks to Rising_Dusk for SoundUtils)
  8. *
  9. *   - Allows you to play sounds immediately after creating them.
  10. *   - Uses a sound recycler to increase efficiency and save RAM.
  11. *
  12. *   API:
  13. *   ----
  14. *
  15. *
  16. *       constant boolean DEFAULT_SOUND_STOPS_ON_LEAVE_RANGE
  17. *       constant integer DEFAULT_SOUND_FADE_IN_RATE
  18. *       constant integer DEFAULT_SOUND_FADE_OUT_RATE
  19. *       constant string  DEFAULT_SOUND_EAX_SETTINGS
  20. *       constant integer DEFAULT_SOUND_VOLUME
  21. *       constant integer DEFAULT_SOUND_PITCH
  22. *
  23. *
  24. *       struct Sound extends array
  25. *
  26. *           readonly string file
  27. *           readonly integer duration
  28. *           readonly boolean looping
  29. *           readonly boolean is3D
  30. *           readonly boolean stopOnLeaveRange
  31. *           readonly integer fadeIn
  32. *           readonly integer fadeOut
  33. *           readonly string eaxSetting
  34. *
  35. *           static method create takes string fileName, integer duration, boolean looping, boolean is3D returns thistype
  36. *               - Creates a sound struct given the filepath, the duration in milliseconds, whether it is looping or not, and whether it is 3D or not.
  37. *           static method createEx takes string fileName, integer duration, boolean looping, boolean is3D, boolean stopOnExitRange, integer fadeIn, integer fadeOut, string eaxSetting returns thistype
  38. *               - In addition to static method create, this allows you to specificy whether the sound stops when the player leaves range, the fadeIn/fadeOut rates and the EAX Setting.
  39. *           static method release takes sound s returns boolean
  40. *               - Releases a sound and throws it into the recycler. Also stops the sound.
  41. *
  42. *           static method getTotalInstances takes nothing returns integer
  43. *               - Determines the total number of sounds playing.
  44. *           method getInstances takes nothing returns integer
  45. *               - Determines the total number of sounds of a certain type that are running.
  46. *
  47. *           method run takes nothing returns sound
  48. *               - Plays the sound.
  49. *           method runEx takes integer volume, real pitch returns sound
  50. *               - Plays the sound. This function allows you to pass in extra arguments.
  51. *
  52. *           method runUnit takes unit whichUnit returns sound
  53. *               - Plays the sound on a unit.
  54. *           method runPoint takes real x, real y, real z returns sound
  55. *               - Plays the sound at a point.
  56. *           method runPlayer takes player whichPlayer returns sound
  57. *               - Plays the sound for a player.
  58. *
  59. *           method runUnitEx takes unit whichUnit, integer volume, real pitch returns sound
  60. *               - Plays the sound on a unit. This function allows you to pass in extra arguments.
  61. *           method runPointEx takes real x, real y, real z, integer volume, real pitch returns sound
  62. *               - Plays the sound at a point. This function allows you to pass in extra arguments.
  63. *           method runPlayerEx takes player whichPlayer, integer volume, real pitch returns sound
  64. *               - Plays the sound for a player. This function allows you to pass in extra arguments.
  65. *
  66. *       function NewSound takes string fileName, integer duration, boolean looping, boolean is3D returns Sound
  67. *           - Creates a sound struct given the filepath, the duration in milliseconds, whether it is looping or not, and whether it is 3D or not.
  68. *       function NewSoundEx takes string fileName, integer duration, boolean looping, boolean is3D, boolean stop, integer fadeInRate, integer fadeOutRate, string eax returns Sound
  69. *           - In addition to static method create, this allows you to specificy whether the sound stops when the player leaves range, the fadeIn/fadeOut rates and the EAX Setting.
  70. *       function GetTotalSoundInstances takes nothing returns integer
  71. *           - Determines the total number of sounds playing.
  72. *       function GetSoundInstances takes Sound this returns integer
  73. *           - Determines the total number of sounds of a certain type that are running.
  74. *       function ReleaseSound takes sound s returns boolean
  75. *           - Releases a sound and throws it into the recycler. Also stops the sound.
  76. *       function RunSound takes Sound this returns sound
  77. *           - Plays the sound.
  78. *       function RunSoundEx takes Sound this, integer volume, real pitch returns sound
  79. *           - Plays the sound. This function allows you to pass in extra arguments.
  80. *       function RunSoundOnUnit takes Sound this, unit whichUnit returns sound
  81. *           - Plays the sound on a unit.
  82. *       function RunSoundAtPoint takes Sound this, real x, real y, real z returns sound
  83. *           - Plays the sound at a point.
  84. *       function RunSoundForPlayer takes Sound this, player p returns sound
  85. *           - Plays the sound for a player.
  86. *       function RunSoundOnUnitEx takes Sound this, unit whichUnit, integer volume, real pitch returns sound
  87. *           - Plays the sound on a unit. This function allows you to pass in extra arguments.
  88. *       function RunSoundAtPointEx takes Sound this, real x, real y, real z, integer volume, real pitch returns sound
  89. *           - Plays the sound at a point. This function allows you to pass in extra arguments.
  90. *       function RunSoundForPlayerEx takes Sound this, player p, integer volume, real pitch returns sound
  91. *           - Plays the sound for a player. This function allows you to pass in extra arguments.
  92. *
  93. ***********************************************/
  94. library SoundTools requires Table, TimerUtils
  95.    
  96.     /*
  97.     *   Configuration.
  98.     */
  99.    
  100.     globals
  101.         constant boolean DEFAULT_SOUND_STOPS_ON_LEAVE_RANGE = true
  102.         constant integer DEFAULT_SOUND_FADE_IN_RATE = 10
  103.         constant integer DEFAULT_SOUND_FADE_OUT_RATE = 10
  104.         constant string  DEFAULT_SOUND_EAX_SETTINGS = "CombatSoundsEAX"
  105.         constant integer DEFAULT_SOUND_VOLUME = 127
  106.         constant integer DEFAULT_SOUND_PITCH = 1
  107.     endglobals
  108.    
  109.     globals
  110.         private constant integer SOUND_CHANNEL = 5
  111.         private constant integer SOUND_MIN_DIST = 600
  112.         private constant integer SOUND_MAX_DIST = 10000
  113.         private constant integer SOUND_DIST_CUT = 3000
  114.     endglobals
  115.    
  116.     /*
  117.     *   Configuration Ends here.
  118.     */
  119.    
  120.     struct Sound extends array
  121.         private static key tbK
  122.         private static key ptK
  123.         private static Table tb = tbK
  124.         private static Table pt = ptK
  125.         private static integer index = 1
  126.        
  127.         private static Table array stack
  128.         private static integer array count
  129.         private static integer array playing
  130.         private static sound snd = null
  131.         private static integer totalPlaying = 0
  132.        
  133.         readonly string file
  134.         readonly integer duration
  135.         readonly boolean looping
  136.         readonly boolean is3D
  137.         readonly boolean stopOnLeaveRange
  138.         readonly integer fadeIn
  139.         readonly integer fadeOut
  140.         readonly string eaxSetting
  141.        
  142.         static method createEx takes string fileName, integer dur, boolean loopng, boolean isTD, boolean stop, integer fadeInRate, integer fadeOutRate, string eax returns thistype
  143.             local thistype this = index
  144.             set index = index + 1
  145.            
  146.             set this.file               = fileName
  147.             set this.duration           = dur
  148.             set this.looping            = loopng
  149.             set this.is3D               = isTD
  150.             set this.stopOnLeaveRange   = stop
  151.             set this.fadeIn             = fadeInRate
  152.             set this.fadeOut            = fadeOutRate
  153.             set this.eaxSetting         = eax
  154.            
  155.             set stack[this] = Table.create()
  156.             return this
  157.         endmethod
  158.        
  159.         static method create takes string fileName, integer dur, boolean loopng, boolean isTD returns thistype
  160.             return createEx(fileName, dur, loopng, isTD, DEFAULT_SOUND_STOPS_ON_LEAVE_RANGE, DEFAULT_SOUND_FADE_IN_RATE, DEFAULT_SOUND_FADE_OUT_RATE, DEFAULT_SOUND_EAX_SETTINGS)
  161.         endmethod
  162.        
  163.         static method getTotalInstances takes nothing returns integer
  164.             return totalPlaying
  165.         endmethod
  166.        
  167.         method getInstances takes nothing returns integer
  168.             return playing[this]
  169.         endmethod
  170.        
  171.         private static method recycle takes nothing returns nothing
  172.             local timer t = GetExpiredTimer()
  173.             local sound s = tb.sound[GetHandleId(t)]
  174.             local integer this = GetTimerData(t)
  175.            
  176.             /*
  177.             *   Stop the sound and push it to the stack.
  178.             */
  179.             call StopSound(s, false, true)
  180.             set stack[this].sound[count[this]] = s
  181.             set count[this] = count[this] + 1
  182.            
  183.             set totalPlaying = totalPlaying - 1
  184.             set playing[this] = playing[this] - 1
  185.            
  186.             /*
  187.             *   Null locals and release timer.
  188.             */
  189.             call ReleaseTimer(t)
  190.             set t = null
  191.             set s = null
  192.         endmethod
  193.        
  194.         private static integer array next
  195.         private static sound array media
  196.        
  197.         private static method runSounds takes nothing returns nothing
  198.             local thistype this = next[0]
  199.             local timer t
  200.            
  201.             call ReleaseTimer(GetExpiredTimer())
  202.            
  203.             loop
  204.                 exitwhen this == 0
  205.                
  206.                 /*
  207.                 *   Play the sound
  208.                 */
  209.                 call StartSound(media[this])
  210.                
  211.                 /*
  212.                 *   If the sound is not looping, we recycle
  213.                 *   it and push it into the stack after it
  214.                 *   finishes playing.
  215.                 */
  216.                 if not this.looping then
  217.                     set t = NewTimerEx(this)
  218.                     set tb.sound[GetHandleId(t)] = media[this]
  219.                     call TimerStart(t, this.duration * 0.001, false, function thistype.recycle)
  220.                 endif
  221.                
  222.                 set media[this] = null
  223.                 set this = next[this]
  224.             endloop
  225.            
  226.             /*
  227.             *   Fast stack destruction.
  228.             */
  229.             set next[0] = 0
  230.            
  231.             set t = null
  232.         endmethod
  233.        
  234.         private method play takes nothing returns sound
  235.             /*
  236.             *   If the run-stack is empty, we start the run-timer.
  237.             */
  238.             if next[0] == 0 then
  239.                 call TimerStart(NewTimer(), 0, false, function thistype.runSounds)
  240.             endif
  241.            
  242.             /*
  243.             *   This prevents sounds of the same type from being
  244.             *   played in the same thread. This is good for
  245.             *   performance because playing the same sound-type
  246.             *   twice at the same time will make no difference.
  247.             */
  248.             if media[this] == null then
  249.                 /*
  250.                 *   Push instance to run-stack.
  251.                 */
  252.                 set next[this] = next[0]
  253.                 set next[0] = this
  254.                
  255.                 /*
  256.                 *   Increase the number of sounds playing.
  257.                 */
  258.                 set totalPlaying = totalPlaying + 1
  259.                 set playing[this] = playing[this] + 1
  260.                
  261.                 /*
  262.                 *   We check if the stack is empty.
  263.                 */
  264.                 if count[this] == 0 then
  265.                     /*
  266.                     *   Create a new sound and point it to the struct instance
  267.                     */
  268.                     set media[this] = CreateSound(this.file, this.looping, this.is3D, this.stopOnLeaveRange, this.fadeIn, this.fadeOut, this.eaxSetting)
  269.                     set pt[GetHandleId(media[this])] = this
  270.                    
  271.                     /*
  272.                     *   Set the duration of the sound and the channel
  273.                     */
  274.                     call SetSoundDuration(media[this], this.duration)
  275.                     call SetSoundChannel(snd, SOUND_CHANNEL)
  276.                    
  277.                     /*
  278.                     *   If the sound is 3D, we configure it some more.
  279.                     */
  280.                     if this.is3D then
  281.                         call SetSoundDistances(media[this], SOUND_MIN_DIST, SOUND_MAX_DIST)
  282.                         call SetSoundDistanceCutoff(media[this], SOUND_DIST_CUT)
  283.                         call SetSoundConeOrientation(media[this], 0, 0, 0)
  284.                     endif
  285.                 else
  286.                     /*
  287.                     *   We have a sound in our stack, so we pop it.
  288.                     */
  289.                     set count[this] = count[this] - 1
  290.                     return stack[this].sound[count[this]]
  291.                 endif
  292.             debug else
  293.                 debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[SoundTools]Warning: Attempted to run the same sound twice.")
  294.             endif
  295.            
  296.             return media[this]
  297.         endmethod
  298.        
  299.         method run takes nothing returns sound
  300.             set snd = this.play()
  301.            
  302.             /*
  303.             *   Configure volume and pitch to default values.
  304.             */
  305.             call SetSoundVolume(snd, DEFAULT_SOUND_VOLUME)
  306.             call SetSoundPitch(snd, DEFAULT_SOUND_PITCH)
  307.            
  308.             /*
  309.             *   If the sound is 3D, we configure the cone angle volume.
  310.             */
  311.             if this.is3D then
  312.                 call SetSoundConeAngles(snd, 0, 0, DEFAULT_SOUND_VOLUME)
  313.             endif
  314.            
  315.             return snd
  316.         endmethod
  317.        
  318.         method runEx takes integer volume, real pitch returns sound
  319.             set snd = this.play()
  320.            
  321.             /*
  322.             *   Configure volume and pitch.
  323.             */
  324.             call SetSoundVolume(snd, volume)
  325.             call SetSoundPitch(snd, pitch)
  326.            
  327.             /*
  328.             *   If the sound is 3D, we configure the cone angle volume.
  329.             */
  330.             if this.is3D then
  331.                 call SetSoundConeAngles(snd, 0, 0, volume)
  332.             endif
  333.            
  334.             return snd
  335.         endmethod
  336.        
  337.         static method release takes sound s returns boolean
  338.             local integer id = GetHandleId(s)
  339.             local integer this = pt[id]
  340.            
  341.             if s == null then
  342.                 debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[SoundTools]Error: Attempted to release a null sound.")
  343.                 return false
  344.             elseif this == 0 then
  345.                 debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[SoundTools]Error: Attempted to release a sound not allocated by RunSound.")
  346.                 return false
  347.             endif
  348.            
  349.             /*
  350.             *   Stop the sound and push it to the stack.
  351.             */
  352.             call StopSound(s, false, true)
  353.             set stack[this].sound[count[this]] = s
  354.             set count[this] = count[this] + 1
  355.            
  356.             set totalPlaying = totalPlaying - 1
  357.             set playing[this] = playing[this] - 1
  358.            
  359.             return true
  360.         endmethod
  361.        
  362.         method runUnit takes unit whichUnit returns sound
  363.             set snd = this.run()
  364.             call AttachSoundToUnit(snd, whichUnit)
  365.             return snd
  366.         endmethod
  367.        
  368.         method runPoint takes real x, real y, real z returns sound
  369.             set snd = this.run()
  370.             call SetSoundPosition(snd, x, y, z)
  371.             return snd
  372.         endmethod
  373.        
  374.         method runPlayer takes player p returns sound
  375.             set snd = this.run()
  376.             if GetLocalPlayer() != p then
  377.                 call SetSoundVolume(snd, 0)
  378.             endif
  379.             return snd
  380.         endmethod
  381.        
  382.         method runUnitEx takes unit whichUnit, integer volume, real pitch returns sound
  383.             set snd = this.runEx(volume, pitch)
  384.             call AttachSoundToUnit(snd, whichUnit)
  385.             return snd
  386.         endmethod
  387.        
  388.         method runPointEx takes real x, real y, real z, integer volume, real pitch returns sound
  389.             set snd = this.runEx(volume, pitch)
  390.             call SetSoundPosition(snd, x, y, z)
  391.             return snd
  392.         endmethod
  393.        
  394.         method runPlayerEx takes player p, integer volume, real pitch returns sound
  395.             set snd = this.runEx(volume, pitch)
  396.             if GetLocalPlayer() != p then
  397.                 call SetSoundVolume(snd, 0)
  398.             endif
  399.             return snd
  400.         endmethod
  401.        
  402.     endstruct
  403.    
  404.     function NewSoundEx takes string fileName, integer duration, boolean looping, boolean is3D, boolean stop, integer fadeInRate, integer fadeOutRate, string eax returns Sound
  405.         return Sound.createEx(fileName, duration, looping, is3D, stop, fadeInRate, fadeOutRate, eax)
  406.     endfunction
  407.    
  408.     function NewSound takes string fileName, integer duration, boolean looping, boolean is3D returns Sound
  409.         return Sound.create(fileName, duration, looping, is3D)
  410.     endfunction
  411.    
  412.     function GetTotalSoundInstances takes nothing returns integer
  413.         return Sound.getTotalInstances()
  414.     endfunction
  415.    
  416.     function GetSoundInstances takes Sound this returns integer
  417.         return this.getInstances()
  418.     endfunction
  419.    
  420.     function RunSound takes Sound this returns sound
  421.         return this.run()
  422.     endfunction
  423.    
  424.     function RunSoundEx takes Sound this, integer volume, real pitch returns sound
  425.         return this.runEx(volume, pitch)
  426.     endfunction
  427.    
  428.     function ReleaseSound takes sound s returns boolean
  429.         return Sound.release(s)
  430.     endfunction
  431.    
  432.     function RunSoundOnUnit takes Sound this, unit whichUnit returns sound
  433.         return this.runUnit(whichUnit)
  434.     endfunction
  435.    
  436.     function RunSoundAtPoint takes Sound this, real x, real y, real z returns sound
  437.         return this.runPoint(x, y, z)
  438.     endfunction
  439.    
  440.     function RunSoundForPlayer takes Sound this, player p returns sound
  441.         return this.runPlayer(p)
  442.     endfunction
  443.    
  444.     function RunSoundOnUnitEx takes Sound this, unit whichUnit, integer volume, real pitch returns sound
  445.         return this.runUnitEx(whichUnit, volume, pitch)
  446.     endfunction
  447.    
  448.     function RunSoundAtPointEx takes Sound this, real x, real y, real z, integer volume, real pitch returns sound
  449.         return this.runPointEx(x, y, z, volume, pitch)
  450.     endfunction
  451.    
  452.     function RunSoundForPlayerEx takes Sound this, player p, integer volume, real pitch returns sound
  453.         return this.runPlayerEx(p, volume, pitch)
  454.     endfunction
  455.    
  456. endlibrary

Rising_Dusk's SoundUtils is the original version of this.
This is a more optimal and cleaner version that's easier to read and understand.

Feel free to comment.

 

New Hero Selection System for version 1.6!!!

Started by SonofJayBoard General Information

Replies: 3
Views: 5674
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: 13097
Last post September 06, 2012, 09:54:35 PM
by moyack
[System] Simulate 3D Sound

Started by PurgeandfireBoard Codes & Snippets

Replies: 7
Views: 14304
Last post July 15, 2013, 12:36:35 AM
by Purgeandfire
Advanced Streak System v4.3.0.0

Started by Magtheridon96Board Warcraft III Spells and Systems

Replies: 2
Views: 7134
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: 4037
Last post April 02, 2015, 06:36:41 PM
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!!