Search code examples
actionscript-3flashaudioadobeflash-cs3

How to Adjust Volume in an Audio loop?


How would someone change sound levels of a music playing in a loop? For example, I'm making a game and at a certain frame I want the music level (music.wav) to be decreased to half of its volume.

How could someone do this in AS3?


Solution

  • You are using the word "loop" in a confusing way. In programming, a loop usually refers to one of the "for" loops that looks like this:

    for (var i:int = 0; i < 10; i++)
    {
       //do stuff 10 times
    }
    

    I surmise that this is not what you mean by loop, but rather that you would like a MovieClip or the main timeline to decrease the volume of a Sound object at the end of n frames. Or do you just mean the music itself is looping? Hopefully you see the value of asking well written questions. That being said..

    Mind you, I haven't tried this, but according to my reference book (ActionScript 3.0 Cookbook by Lott, Schall & Peters) you need to use a SoundTransform object which specifies the volume at which you want the sound to be set. Try this:

    var _sound:Sound = new Sound(music.wav); // creates a Sound object which has no internal volume control
    var channel:SoundChannel = _sound.play(); // creates a SoundChannel which has a soundTransform property
    var transform:SoundTransform = new SoundTransform(); // SoundTransform objects have a property called "volume". This is what you need to change volume.
    

    Now in your loop (or on the frame event that you are using) do this:

    transform.volume *= 0.9; // or whatever factor you want to have it decrease
    //transform.volume /= 1.1; // or this if you prefer.
    channel.soundTransform = transform; //
    

    So anytime you want the volume to decrease by this incremental amount, run this bit of code. Of course, you need to make sure that any variables you set are accessible in the code that is referencing them. One way that comes to mind to do this is with a function.

    private function soundDiminish(st:SoundTransform, c:SoundChannel, factor:Number = 0.9):void
    {
        st.volume *= factor;
        c.soundTransform = st;
    }
    

    Now, whenever you want to diminish the volume just call the soundDiminish function.

    Maybe your frame event looks like this:

    function onLoadFrame(fe:Event):void
    {
        soundDiminish(transform, channel); // 3rd parameter optional
    }
    

    If you only want this function to be called every 20 frames then:

    function onLoadFrame(fe:Event):void
    {
        // this is a counter that will count up each time this frame event happens
        frameCount ++;
        if (frameCount >= 20)
        {
            soundDiminish(transform, channel); // 3rd parameter optional
            frameCount = 0; // reset the frame counter
        }
    }