Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Dave Gilbert on Wed 17/04/2013 21:16:56

Title: Trying to fadein/fadeout music using tweening module
Post by: Dave Gilbert on Wed 17/04/2013 21:16:56
This is one of those occasions I really hate the new AGS sound system. You used to just be able to play a new tune and it would automatically fadein and fadeout, but no longer. :( :-\

Anyway, enough griping!

I discovered that Edmundo's lovely tweening module can tween the volume of audio channels, WITHOUT blocking. This is ideal, since I can fadein/fadeout between music and ambient sound without stopping the action.

I have three audio channels: MusicChannel, MusicChannelb and MusicChannelActive.

How it works is I start playing music on MusicChannel, then switch over to MusicChannelb (using the tween module to fade up the volume of one while fading down the volume of the other) and then setting MusicChannelActive to the new channel. I also have a silent music clip called aSilence that I use when I want to turn off the sound.

Here's the function declaration:

Code (AGS) Select

import function MusicChange(AudioClip*thisclip, int vol=50, int time=500,  bool repeat=true);

And here's the juicy code:

Code (AGS) Select

function MusicChange(AudioClip*thisClip, int vol, int time, bool repeat)
{
  float ftime=IntToFloat(time);
  ftime=ftime/1000.0;
  if (MusicChannelActive.PlayingClip != thisClip) //check to see if the active channel is already playing the requested clip
  {
      if (MusicChannelActive==MusicChannel) //switch to musicChannelB
      {
        if (repeat==true)
          MusicChannelb = thisClip.Play(eAudioPriorityVeryHigh, eRepeat);
        else
          MusicChannelb = thisClip.Play(eAudioPriorityVeryHigh, eOnce);
        MusicChannelb.Volume=0;
        MusicChannelb.TweenVolume(ftime, vol, eLinearTween, eNoBlockTween);
        MusicChannel.TweenVolume(ftime, 0, eLinearTween, eNoBlockTween);
        MusicChannelActive=MusicChannelb;
      }
      else if (MusicChannelActive==MusicChannelb) //switch to music channel A
      {
        if (repeat==true)
          MusicChannel = thisClip.Play(eAudioPriorityVeryHigh, eRepeat);
        else
          MusicChannel = thisClip.Play(eAudioPriorityVeryHigh, eOnce);
        MusicChannel.Volume=0;
        MusicChannel.TweenVolume(ftime, vol, eLinearTween, eNoBlockTween);
        MusicChannelb.TweenVolume(ftime, 0, eLinearTween, eNoBlockTween);
        MusicChannelActive=MusicChannel;
      }
  }
}

function repeatedly_execute_always()
{
  if (MusicChannelActive == MusicChannel && MusicChannelb.Volume==0)
    MusicChannelb.Stop();
  if (MusicChannelActive == MusicChannelb && MusicChannel.Volume==0)
    MusicChannel.Stop();
}


At game_start, everything is set to these values:

Code (AGS) Select

  MusicChannel = aSilence.Play(eAudioPriorityNormal, eRepeat);
  MusicChannelb = aSilence.Play(eAudioPriorityNormal, eRepeat);
  MusicChannel.Volume=100;
  MusicChannelb.Volume=0;
  MusicChannelActive=MusicChannel;


The result of all this nonsense? It works... half the time. Half the time, the music doesn't change at all. Once in a while, the music doesn't even begin at the start of the game. It seems totally arbitrary and I have been spending ages trying to sort out why. So... help? What am I doing wrong? Or is there a much better way of doing this entirely?

Thanks in advance!

-Dave
Title: Re: Trying to fadein/fadeout music using tweening module
Post by: Crimson Wizard on Wed 17/04/2013 21:38:51
I apologize if all this is already known to you, but I would like to note something very important prior to anything else.

The AudioChannel* is a pointer, not persistent object. When you say "I have three channels" this should be read as "I have three references to audio channels".
What do they reference? They may reference absolutely nothing, for instance. Or same channel. Or different channels every other time.
The actual channel objects are inside the AGS, and you do not have direct access to them, you may only control how many of them are there.
You do this by setting "MaxChannels" in the sound type object (Project Tree -> Audio -> Types -> any type, e.g. Music -> MaxChannels).

So, first thing I'd like to ask: what did you set the MaxChannels to?
Also, check "Crossfade tracks" option, maybe you could use that one instead of manually crossfading music?

Then, just something that I noticed:
Code (ags) Select

function MusicChange(AudioClip*thisClip, int vol, int time, bool repeat)
{
  float ftime=IntToFloat(time);
  ftime=ftime/1000.0;
  if (MusicChannelActive.PlayingClip != thisClip) //check to see if the active channel is already playing the requested clip

This will crash the game, if MusicChannelActive was not assigned prior to the function call. I don't know all your program logic, but I'd add "MusicChannelActive != null" check.
Title: Re: Trying to fadein/fadeout music using tweening module
Post by: selmiak on Wed 17/04/2013 22:21:31
I ran into the same thing and khris wrote a nice working audio fading script (http://www.adventuregamestudio.co.uk/forums/index.php?topic=47261.msg634937#msg634937). It has no ease in, ease out, but it works, i hope this helps.
Title: Re: Trying to fadein/fadeout music using tweening module
Post by: Crimson Wizard on Wed 17/04/2013 22:48:48
Actually, I just made a quick test to see how AGS auto crossfading work. That may be my ears, or the music, but I really don't see (hear) any problems when music is changing. It sometimes act a bit weird when music starts in silence though (it plays in low volume first, then suddenly gets louder).
Unfortunately there's no way to set up precise crossfade duration in AGS (something worth of a feature request maybe).
Title: Re: Trying to fadein/fadeout music using tweening module
Post by: Dave Gilbert on Sat 20/04/2013 13:26:59
You know... you're right. Setting the music channel property to play a maximum of ONE piece of music at a time, and then just playing another tune does the crossfade automatically. I don't know why I never tried doing that. So much for my giant function of death. Cheers!