• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[System] SoundTools

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.

JASS:
/***********************************************
*
*   SoundTools
*   v3.0.0.2
*   By Magtheridon96
*
*   (Special Thanks to Rising_Dusk)
*
*   - Allows you to play sounds immediately after creating them.
*   - Uses a sound recycler to increase efficiency and save RAM.
*
*   Requirements:
*   -------------
*
*       - Table by Bribe
*           - hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
*       - TimerUtils by Vexorian
*           - wc3c.net/showthread.php?t=101322
*
*   API:
*   ----
*
*       constant boolean DEFAULT_SOUND_STOPS_ON_LEAVE_RANGE
*       constant integer DEFAULT_SOUND_FADE_IN_RATE
*       constant integer DEFAULT_SOUND_FADE_OUT_RATE
*       constant string  DEFAULT_SOUND_EAX_SETTINGS
*       constant integer DEFAULT_SOUND_VOLUME
*       constant integer DEFAULT_SOUND_PITCH
*
*       struct Sound extends array
*
*           readonly string file
*           readonly integer duration
*           readonly boolean looping
*           readonly boolean is3D
*           readonly boolean stopOnLeaveRange
*           readonly integer fadeIn
*           readonly integer fadeOut
*           readonly string eaxSetting
*
*           static method create takes string fileName, integer duration, boolean looping, boolean is3D returns thistype
*               - Creates a sound struct given the filepath, the duration in milliseconds, whether it is looping or not, and whether it is 3D or not.
*           static method createEx takes string fileName, integer duration, boolean looping, boolean is3D, boolean stopOnExitRange, integer fadeIn, integer fadeOut, string eaxSetting returns thistype
*               - 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.
*           static method release takes sound s returns boolean
*               - Releases a sound and throws it into the recycler. Also stops the sound.
*
*           method run takes nothing returns sound
*               - Plays the sound.
*           method runUnit takes unit whichUnit returns sound
*               - Plays the sound on a unit.
*           method runPoint takes real x, real y, real z returns sound
*               - Plays the sound at a point.
*           method runPlayer takes player whichPlayer returns sound
*               - Plays the sound for a player.
*
*           method runEx takes integer volume, integer pitch returns sound
*               - Plays the sound. This function allows you to pass in extra arguments.
*           method runUnitEx takes unit whichUnit, integer volume, integer pitch returns sound
*               - Plays the sound on a unit. This function allows you to pass in extra arguments.
*           method runPointEx takes real x, real y, real z, integer volume, integer pitch returns sound
*               - Plays the sound at a point. This function allows you to pass in extra arguments.
*           method runPlayerEx takes player whichPlayer, integer volume, integer pitch returns sound
*               - Plays the sound for a player. This function allows you to pass in extra arguments.
*
*       function NewSound takes string fileName, integer duration, boolean looping, boolean is3D returns Sound
*           - Creates a sound struct given the filepath, the duration in milliseconds, whether it is looping or not, and whether it is 3D or not.
*       function NewSoundEx takes string fileName, integer duration, boolean looping, boolean is3D, boolean stop, integer fadeInRate, integer fadeOutRate, string eax returns Sound
*           - 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.
*       function ReleaseSound takes sound s returns boolean
*           - Releases a sound and throws it into the recycler. Also stops the sound.
*       function RunSound takes Sound this returns sound
*           - Plays the sound.
*       function RunSoundEx takes Sound this, integer volume, integer pitch returns sound
*           - Plays the sound. This function allows you to pass in extra arguments.
*       function RunSoundOnUnit takes Sound this, unit whichUnit returns sound
*           - Plays the sound on a unit.
*       function RunSoundAtPoint takes Sound this, real x, real y, real z returns sound
*           - Plays the sound at a point.
*       function RunSoundForPlayer takes Sound this, player p returns sound
*           - Plays the sound for a player.
*       function RunSoundOnUnitEx takes Sound this, unit whichUnit, integer volume, real pitch returns sound
*           - Plays the sound on a unit. This function allows you to pass in extra arguments.
*       function RunSoundAtPointEx takes Sound this, real x, real y, real z, integer volume, real pitch returns sound
*           - Plays the sound at a point. This function allows you to pass in extra arguments.
*       function RunSoundForPlayerEx takes Sound this, player p, integer volume, real pitch returns sound
*           - Plays the sound for a player. This function allows you to pass in extra arguments.
*
*   Credits:
*   --------
*
*       - Rising_Dusk (The original system)
*       - Zwiebelchen (Research - He found a ton of Wc3 sound bugs and ways to fix them)
*
***********************************************/
library SoundTools requires Table, TimerUtils
    
    /*
    *   Configuration
    */
    
    globals
        constant boolean DEFAULT_SOUND_STOPS_ON_LEAVE_RANGE = true
        constant integer DEFAULT_SOUND_FADE_IN_RATE = 10
        constant integer DEFAULT_SOUND_FADE_OUT_RATE = 10
        constant string  DEFAULT_SOUND_EAX_SETTINGS = "CombatSoundsEAX"
        constant integer DEFAULT_SOUND_VOLUME = 127
        constant integer DEFAULT_SOUND_PITCH = 1
    endglobals
    
    globals
        private constant integer SOUND_CHANNEL = 5
        private constant integer SOUND_MIN_DIST = 600
        private constant integer SOUND_MAX_DIST = 10000
        private constant integer SOUND_DIST_CUT = 3000
    endglobals
    
    /*
    *   End of Configuration
    */
    
    struct Sound extends array
        private static key tk
        private static key pk
        private static Table tb = tk
        private static Table pt = pk
        private static integer index = 1
        
        private static Table array stack
        private static integer array count
        
        readonly string file
        readonly integer duration
        readonly boolean looping
        readonly boolean is3D
        readonly boolean stopOnLeaveRange
        readonly integer fadeIn
        readonly integer fadeOut
        readonly string eaxSetting
        
        private real pitch
        
        static method createEx takes string fileName, integer dur, boolean loopng, boolean isTD, boolean stop, integer fadeInRate, integer fadeOutRate, string eax returns thistype
            local thistype this = index
            set index = index + 1
            
            set this.file = fileName
            set this.duration = dur
            set this.looping = loopng
            set this.is3D = isTD
            set this.stopOnLeaveRange = stop
            set this.fadeIn = fadeInRate
            set this.fadeOut = fadeOutRate
            set this.eaxSetting = eax
            set this.pitch = 1
            
            set stack[this] = Table.create()
            
            return this
        endmethod
        
        static method create takes string fileName, integer dur, boolean loopng, boolean isTD returns thistype
            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)
        endmethod
        
        // Credits to Zwiebelchen for this function
        // He discovered a bug with sound pitches and this function was written to fix that.
        method setSoundPitch takes sound s, real newPitch returns nothing
            if GetSoundIsPlaying(s) or GetSoundIsLoading(s) then
                call SetSoundPitch(s, 1/this.pitch)
                call SetSoundPitch(s, newPitch)
                set this.pitch = newPitch
            elseif newPitch == 1 then
                call SetSoundPitch(s, 1.0001)
                set this.pitch = 1.0001
            else
                call SetSoundPitch(s, newPitch)
                set this.pitch = newPitch
            endif
        endmethod
        
        private static sound snd
        
        private method get takes nothing returns sound
            if count[this] == 0 then
            
                /*
                *   Create new sound and point it to
                *   Sound struct instance.
                */
                set snd = CreateSound(this.file, this.looping, this.is3D, this.stopOnLeaveRange, this.fadeIn, this.fadeOut, this.eaxSetting)
                set pt[GetHandleId(snd)] = this
                
                /*
                *   Configure sound
                */
                call SetSoundDuration(snd, this.duration)
                call SetSoundChannel(snd, SOUND_CHANNEL)
                call SetSoundVolume(snd, DEFAULT_SOUND_VOLUME)
                call this.setSoundPitch(snd, DEFAULT_SOUND_PITCH)
                
                /*
                *   Proper 3D sound configuration
                */
                if this.is3D then
                    call SetSoundDistances(snd, SOUND_MIN_DIST, SOUND_MAX_DIST)
                    call SetSoundDistanceCutoff(snd, SOUND_DIST_CUT)
                    call SetSoundConeAngles(snd, 0, 0, DEFAULT_SOUND_VOLUME)
                    call SetSoundConeOrientation(snd, 0, 0, 0)
                endif
                
                return snd
            endif
            
            /*
            *   Pop out of sound stack.
            */
            set count[this] = count[this] - 1
            return stack[this].sound[count[this]]
        endmethod
        
        private method push takes sound s returns nothing
            set stack[this].sound[count[this]] = s
            set count[this] = count[this] + 1
        endmethod
        
        private static method recycle takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local sound s = tb.sound[GetHandleId(t)]
            
            /*
            *   Stop sound and push to the
            *   stack.
            */
            call StopSound(s, false, true)
            call thistype(GetTimerData(t)).push(s)
            call ReleaseTimer(t)
            
            set t = null
            set s = null
        endmethod
        
        private static integer array next
        private static sound array media
        
        private static method runSounds takes nothing returns nothing
            local thistype this = next[0]
            local timer t
            
            call ReleaseTimer(GetExpiredTimer())
            
            loop
                exitwhen this == 0
                
                /*
                *   Play the sound.
                */
                call StartSound(media[this])
                
                /*
                *   If it is not looping,
                *   we can recycle it when 
                *   it finishes playing.
                */
                if not this.looping then
                    set t = NewTimerEx(this)
                    set tb.sound[GetHandleId(t)] = media[this]
                    call TimerStart(t, this.duration * 0.001, false, function thistype.recycle)
                endif
                
                set media[this] = null
                set this = next[this]
            endloop
            
            set next[0] = 0
            
            set t = null
        endmethod
        
        method run takes nothing returns sound
            debug if this == 0 then
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[SoundTools]Error: Attempted to play null sound.")
                debug return null
            debug endif
            
            if next[0] == 0 then
                call TimerStart(NewTimer(), 0, false, function thistype.runSounds)
            endif
            
            if media[this] == null then
                set next[this] = next[0]
                set next[0] = this
                set media[this] = this.get()
            debug else
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[SoundTools]Warning: Attempted to run the same sound twice.")
            endif
            
            return media[this]
        endmethod
        
        method runEx takes integer volume, integer newPitch returns sound
            set snd = this.run()
            call SetSoundVolume(snd, volume)
            call this.setSoundPitch(snd, newPitch)
            return snd
        endmethod
        
        static method release takes sound s returns boolean
            local integer id = GetHandleId(s)
            
            if s == null then
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[SoundTools]Error: Attempted to release a null sound.")
                return false
            elseif pt[id] == 0 then
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[SoundTools]Error: Attempted to release a sound not allocated by RunSound.")
                return false
            endif
            
            /*
            *   Stop the sound and push it
            *   to the stack.
            */
            call StopSound(s, false, true)
            call thistype(pt[id]).push(s)
            
            return true
        endmethod
        
        method runUnit takes unit whichUnit returns sound
            set snd = this.run()
            call AttachSoundToUnit(snd, whichUnit)
            return snd
        endmethod
        
        method runUnitEx takes unit whichUnit, integer volume, integer newPitch returns sound
            set snd = this.runUnit(whichUnit)
            call SetSoundVolume(snd, volume)
            call this.setSoundPitch(snd, newPitch)
            return snd
        endmethod
        
        method runPoint takes real x, real y, real z returns sound
            set snd = this.run()
            call SetSoundPosition(snd, x, y, z)
            return snd
        endmethod
        
        method runPointEx takes real x, real y, real z, integer volume, integer newPitch returns sound
            set snd = this.runPoint(x, y, z)
            call SetSoundVolume(snd, volume)
            call this.setSoundPitch(snd, newPitch)
            return snd
        endmethod
        
        method runPlayer takes player p returns sound
            set snd = this.run()
            if GetLocalPlayer() != p then
                call SetSoundVolume(snd, 0)
            endif
            return snd
        endmethod
        
        method runPlayerEx takes player p, integer volume, integer newPitch returns sound
            set snd = this.runPlayer(p)
            call SetSoundVolume(snd, volume)
            call this.setSoundPitch(snd, newPitch)
            return snd
        endmethod
    endstruct
    
    function NewSoundEx takes string fileName, integer duration, boolean looping, boolean is3D, boolean stop, integer fadeInRate, integer fadeOutRate, string eax returns Sound
        return Sound.createEx(fileName, duration, looping, is3D, stop, fadeInRate, fadeOutRate, eax)
    endfunction
    
    function NewSound takes string fileName, integer duration, boolean looping, boolean is3D returns Sound
        return Sound.create(fileName, duration, looping, is3D)
    endfunction
    
    function RunSound takes Sound this returns sound
        return this.run()
    endfunction
    
    function RunSoundEx takes Sound this, integer volume, integer pitch returns sound
        return this.runEx(volume, pitch)
    endfunction
    
    function ReleaseSound takes sound s returns boolean
        return Sound.release(s)
    endfunction
    
    function RunSoundOnUnit takes Sound this, unit whichUnit returns sound
        return this.runUnit(whichUnit)
    endfunction
    
    function RunSoundOnUnitEx takes Sound this, unit whichUnit, integer volume, integer pitch returns sound
        return this.runUnitEx(whichUnit, volume, pitch)
    endfunction
    
    function RunSoundAtPoint takes Sound this, real x, real y, real z returns sound
        return this.runPoint(x, y, z)
    endfunction
    
    function RunSoundAtPointEx takes Sound this, real x, real y, real z, integer volume, integer pitch returns sound
        return this.runPointEx(x, y, z, volume, pitch)
    endfunction
    
    function RunSoundForPlayer takes Sound this, player p returns sound
        return this.runPlayer(p)
    endfunction
    
    function RunSoundForPlayerEx takes Sound this, player p, integer volume, integer pitch returns sound
        return this.runPlayerEx(p, volume, pitch)
    endfunction
    
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, and it addresses the sound pitch bug C:

Feel free to comment.
 
Last edited:
Level 6
Joined
Jun 20, 2011
Messages
249
f1rst

No rly, what's this?
JASS:
set tb.sound[GetHandleId(t)] = s
call TimerStart(t, 0.001, false, function thistype.runProxy)
Instead use a stack, pile up sounds being fired up in a stack and after the timer (which should be 0 and not 0.001) run all of them
JASS:
static method runProxy takes nothing returns nothing
    call DestroyTimer(GetExpiredTimer())
    loop
        exitwhen stack[0]==0
        //do stuff using stack[0] as this
        set stack[0]=stack[stack[0]]
    endloop
endmethod

method run takes nothing returns nothing
    if stack[0]==0 then
        call TimerStart(CreateTimer(),0,false,function thistype.runProxy)
    endif
    set stack[this]=stack[0]
    set stack[0]=this
endmethod
 
Level 7
Joined
Oct 11, 2008
Messages
304
Finally you release it :D

JASS:
        method runPoint takes real x, real y, real z returns sound
            local sound s = this.run() // leak?
            call SetSoundPosition(s, x, y, z)
            return s
        endmethod

//>>

        method runPoint takes real x, real y, real z returns sound
            call SetSoundPosition(this.run(), x, y, z)
            return this.run() // will fail :/ another timer... ignore this example.
        endmethod

// or >>

        private static sound TSound

        method runPoint takes real x, real y, real z returns sound
            set TSound = this.run()
            call SetSoundPosition(TSound, x, y, z)
            return TSound
        endmethod

// or >>

        method position takes sound s, real x, real y, real z returns sound
            call SetSoundPosition(s, x, y, z)
            return s
        endmethod

        method runPoint takes real x, real y, real z returns sound
            return this.position(this.run(), x, y, z)
        endmethod
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
JASS:
              call SetSoundChannel(s, 5)
                call SetSoundVolume(s, 127)
                call SetSoundPitch(s, 1)
                
                // Proper 3D Sound Configuration
                if is3D[this] then
                    call SetSoundDistances(s, 600, 10000)
                    call SetSoundDistanceCutoff(s, 3000)
                    call SetSoundConeAngles(s, 0, 0, 127)

The 5, 127, 600, 10000, 3000, 127 should be configurable via constants.
 
Level 7
Joined
Oct 11, 2008
Messages
304
:)
JASS:
        private static sound TSound

        method runPoint takes real x, real y, real z returns sound
            set TSound = this.run()
            call SetSoundPosition(TSound, x, y, z)
            return TSound
        endmethod

// or >>

        method position takes sound s, real x, real y, real z returns sound
            call SetSoundPosition(s, x, y, z)
            return s
        endmethod

        method runPoint takes real x, real y, real z returns sound
            return this.position(this.run(), x, y, z)
        endmethod
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Since you use it here, maybe you can tell what
native SetSoundConeAngles takes sound soundHandle, real inside, real outside, integer outsideVolume returns nothing
and
native SetSoundConeOrientation takes sound soundHandle, real x, real y, real z returns nothing
do exactly?
 
Since you use it here, maybe you can tell what
native SetSoundConeAngles takes sound soundHandle, real inside, real outside, integer outsideVolume returns nothing
and
native SetSoundConeOrientation takes sound soundHandle, real x, real y, real z returns nothing
do exactly?

I actually got the idea of how those natives work by playing some DotA :p
The closer you are to the ground, the louder the 3D sound.
Basically, those natives manipulate the 'cone' in which the sounds are played.
By setting the cone angles to 0, I'm removing some wierd effects that occur while you move the camera around the position of the sound. By default, the x,y coordinates are 0. The first controls the angles of this cone.
The second is pretty much like SetSoundPosition, but it actually does something to configure the cone.

@Laiev:
Yeah, but I don't want to increase code-size :eek:

@Bribe:
I'll fix that leak and I'll make most of those values configurable.

@Luorax:

:cgrin:

@Dirac:

It might not work with the 0-second timer, but I'll test that. (The GetSoundIsLoading native brings me to surmise that a sound can't play when it's created because it's loading)

The stack is a good idea though :)
Less timers, moar /win/ :D
 
Last edited:
I just realized something about that stack. It will fail to play the same sound twice... Wait- what the hell am I talking about? That's a good thing :D
More performance ^_^

I LOVE YOU DIRAC ! :D

edit
Man, that thing is more epic than I thought. It's a stack that destroys itself DURING iteration :D
Dude, you're awesome :D

edit
Updated. Good news: GetSoundIsLoading is useless.
 
Last edited:
Level 7
Joined
Oct 11, 2008
Messages
304
SoundUtils?

The name is not SoundTools?
E107.png
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
Ah, "NewSound"... I had to change like 50 function calls in 50-100 triggers... meh.

EDIT: did you even test it? Because there're no sounds at all. No spells do work with this that worked perfectly before, and it likes causing super lags on my tri-core 3200 Ghz, 4 Gbyte DDR3 RAM PC (not that good, I know, I'm not trying to brag with it; I'm trying to tell that it's not supposed to freeze down because of a couple of sounds)

Also, Table should be on the requirement list.

EDIT2: okay, switching Advent 3.0 back to 2.0 removed all the lags (both was implemented together). But my spells still DO lack sounds (most likely because SoundTools has nothing to do with Advent)
 
Last edited:
Level 16
Joined
Aug 7, 2009
Messages
1,403
Oh well, I figured out what's wrong, you'll find it strange, just like me.

The in-game sounds did appear, I was just trying a "bad" hero, its sound effects are not that loud and got overlayed by other sounds. But the hero selection sound is a different story.

SoundUtils had an interesting bug: after initializing the click sound I had to play it, like I had to preload it, or it was randomly not played. It looked like this:

JASS:
private function init takes nothing returns nothing
    set ClickSound=NewSound("Sound\\Interface\\MouseClick1.wav",239,false,false)
    call RunSoundForPlayer(ClickSound,Player(12))

If I don't play it immediately after initializing it, it works perfectly. Interesting.

Whatever, it's working, don't waste any more of your time on it. I'll stick to this from now, and gj ;)
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
For first I thought the same, but then that little glitch with SoundUtils came to my mind. And I was right about that (however I have to rewrite my hero selection system, because it's an ancient, function orientated slow bs)

(EDIT: Firefox 9.0 lolwut?)
 
Level 6
Joined
Oct 23, 2011
Messages
182
does the sound have to be initialized for runPlayer? this keeps bugging for some reason

*EDIT

improved API with demo map would be nice as well.
How am I supposed to use release? I thought i was supposed to use it like .snd.release().. what am I supposed to recycle?

Sound.release(this.snd.runPoint(0, 0, 0))...?
 
Last edited:
Level 17
Joined
Feb 11, 2011
Messages
1,860
When I try saving the map after installing the system, it gives the following error:

"sound is not a member of Table__GTable"

The line that has this error is:

"return stack[this].sound[count[this]]"

I do have the TimerUtils and Table libraries. What's wrong?
 
Usually, I'd expect the user to know how to use it given the API :/
But, just for you, here:
  • Init
    • Events
      • Map Initialization
    • Conditions
    • Actions
      • ---------- The file path of your sound. If it's imported, use the one given in the Import Editor ("war3imported/...") ----------
      • Set SoundPath = ""
      • ---------- The duration of the sound in MILLISECONDS. Meaning, you should take the duration of the sound in seconds and multiply it by 1000. ----------
      • Set SoundDuration = 0
      • ---------- Is the sound a looping sound? Note: Looping sounds have to stopped manually ----------
      • Set SoundLooping = False
      • ---------- Is the sound going to be played in 3D? ----------
      • Set Sound3D = False
      • ---------- Now, we get down to business and create our sound ----------
      • Custom script: set udg_MySound = NewSound(udg_SoundPath, udg_SoundDuration, udg_SoundLooping, udg_Sound3D)
SoundPath is a string variable
SoundDuration is an integer variable
SoundLooping is a boolean variable
Sound3D is a boolean variable
MySound is an integer variable

NO sound variables are needed ever ;)
EXCEPT when you have a looping sound.

If the sound is looping, you need to store the sound variable whenever you run it and release the sound variable when you want it to stop looping.

To Play the sound:
  • Play
    • Events
    • Conditions
    • Actions
      • Custom script: call RunSound(udg_MySound)
It's that simple :)

To run the sound for a player:
  • Play for Player
    • Events
    • Conditions
    • Actions
      • Set udg_MyPlayer = (Player 1)
      • Custom script: call RunSoundForPlayer(udg_MySound, udg_MyPlayer)
To play it on a unit:
  • Play on unit
    • Events
    • Conditions
    • Actions
      • Set udg_MyUnit = (Triggering unit)
      • Custom script: call RunSoundOnUnit(udg_MySound, udg_MyUnit)
To play the sound at a point or location:
  • Play at location
    • Events
    • Conditions
    • Actions
      • Set MyLoc = (Position of (Triggering unit))
      • Custom script: call RunSoundAtPoint(udg_MySound, GetLocationX(udg_MyLoc), GetLocationY(udg_MyLoc), GetLocationZ(udg_MyLoc))
      • Custom script: call RemoveLocation(udg_MyLoc)
If the sound is a looping sound, just replace the "call" before the RunSoundxxxx functions, with a "set udg_THE_NAME_OF_YOUR_SOUND_VARIABLE_HERE = " (Excluding the quotation marks of course)

And when you want to stop the looping sound:
  • Custom script: call ReleaseSound(udg_THE_NAME_OF_YOUR_SOUND_VARIABLE_HERE)
It's that easy ;)
I hope this helps.

edit
Hey, if you're a GUIer, you shouldn't be using this, you could simply use the Sound Editor and GUI actions to play sounds >:O
 
Level 6
Joined
Mar 9, 2009
Messages
175
hey , can I put - A unit is attacked then play the multiple of sound effect on the attacking unit ??


Edited*

The first trigger "Init" is require right ?
 
Yes you can:

  • Trigger
    • Events
      • Unit - A unit is attacked
    • Conditions
    • Actions
      • Set Unit = (Attacking unit)
      • Custom script: call RunSoundOnUnit(udg_MySound1, udg_Unit)
      • Custom script: call RunSoundOnUnit(udg_MySound2, udg_Unit)
And the init trigger is required because it actually creates the sound.
Without it, the sounds wouldn't play :c
 
Level 6
Joined
Mar 9, 2009
Messages
175
why the Custom script: set udg_MySound = NewSound(udg_SoundPath, udg_SoundDuration, udg_SoundLooping, udg_Sound3D) looks like have undeclared function ??
 
Level 6
Joined
Mar 9, 2009
Messages
175
If the sound is a looping sound, just replace the "call" before the RunSoundxxxx functions, with a "set udg_THE_NAME_OF_YOUR_SOUND_VARIABLE_HERE = " (Excluding the quotation marks of course)

And when you want to stop the looping sound:
  • Custom script: call ReleaseSound(udg_THE_NAME_OF_YOUR_SOUND_VARIABLE_HERE)


The name of my sound variable is from Sound Editor or Import Manager (war3mapImported\skill_explo_128.wav) ??

Hey sorry i really not good in doing this >.<

Can you give me a complete triggers >.< I not very understand whether how to do this .


Edited * the NewSound is a variables?
 
Last edited:
NewSound is a function, not a variable :X

Listen, if you're using the Sound Editor, there's no point in using this resource :/

This was made for handling sounds for people who use Jass because only these people are going to run into problems and inconveniences while managing sounds :/

In GUI, it's really simple.

You just have to import the sound, use it as a sound in the Sound Editor, and play it in the world editor.

Simple as that.

In Jass, you have to create a trigger in GUI and use the sound just for the World Editor to generate something like gg_snd_xxxxxxx

Also, this provides a recycler for sounds so that you wont run into problems when wanting to play a sound twice at very close times (about 0.3 or 0.7 seconds apart for example)

BUT, if you really wanna use this and be what I like to call a Linux-user, you would have to do this:

Do this on map initialization:
  • Custom script: set udg_MY_INTEGER_VARIABLE = NewSound("war3mapImported\\skill_explo_128.wav", DURATION_OF_THE_SOUND_IN_MILLISECONDS, false, false)
So for example, if your sound is 3.872 seconds, you would have to replace DURATION_OF_THE_SOUND_IN_MILLISECONDS with 3872.

Do this to play the sound:
  • Custom script: call RunSound(udg_MY_INTEGER_VARIABLE)
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
I want to use this lib to create a music library:
http://www.hiveworkshop.com/forums/triggers-scripts-269/


However, in order to do so, can you please make volume, pitch settings and sound channel parameters of the sound struct?
I need them to be configurable for each sound, not just all sounds together. Them being constants is weird, if you ask me.

Also, can I use this lib to run the same sound twice at the same time? Let's say I want both sounds to overlap each other, will it work? if so, will the first sound stop or will it continue until the end of its duration when the second playing is fired?
 
Top