AudioChannels, music clips, Stop() and weirdness.

Started by UnusualCadence, Sun 12/06/2016 14:22:03

Previous topic - Next topic

UnusualCadence

Hello! Hopefully someone here can help with a slight engine conundrum!

I'm messing around with the audio system attempting to implement some smart music looping/sequencing setup, that allows me to set loop points in a music track and jump between them. Using an internal bar and beat tracker, this works really well when Seeking in one music track - however, I also want to add in a short crossfade to make this jump seamless. I thought I could do this by adding an extra AudioChannel, loading the same clip in to both and doing a custom fade-in/fade-out on the individual channels, but unfortunately it seems that when I call "AudioChannel[].Stop();", this stops the clip on both channels. I'm hoping this is just a bug, as it's possible to do AudioChannel.PlayFrom() on the same channel over and over and have the music track play again and again until you run out of voices (hence the need for Stopping!)

If this is not a bug and intended behavior, can anyone think of a way around this that doesn't involve having a duplicate of every music clip?

morganw

#1
I think you may have confused AudioClip and AudioChannel. Calling AudioClip.Stop will stop all instances of an AudioClip, playing on any AudioChannel. AudioChannel.Stop will only stop the channel you are referencing. Plus, there is no such method as AudioChannel.PlayFrom.
Quote from: UnusualCadence on Sun 12/06/2016 14:22:03
AudioChannel[].Stop()
As far as I know, this isn't valid and wouldn't compile. Are you using an array of AudioChannel pointers?

UnusualCadence

#2
No confusion (other than creating some in my post!), I'm just using lazy psudeo-code in my post :)

Yes, I'm using an array of AudioChannels (which I've named 'mainmus' in my prototype script):
Code: ags

mainmus[musicChannel] = aTest.PlayFrom(22050 * FloatToInt(music_PositionDelta,  eRoundDown),  eOnce);

...to start a track, and then later,

Code: ags

mainmus[stopChannel].Stop();

To end it, which stops all clips that are named 'aTest' regadless of which channel they're playing on.

I've tried it alternating between the original aTest clip and a duplicate called aTest1 and it works as I'd expect with the tracks looping seamlessly with a nice little crossfade, so I'm hoping that this is a bug in the system that can be easily squashed :)

morganw

Do musicChannel and stopChannel have the same value? Otherwise it looks like you are referencing two different channels.
Also, do aTest and aTest1 have the same Type, and what do you have configured for channel reservations? The default reservation for music is only a single channel.


Crimson Wizard

#4
First of all, which version of AGS are you using?

I tried to reproduce your problem, but it worked well for me.
My script (works, assuming you have at least 2 channels assigned for Music audio type):
Code: ags

AudioChannel *ch[2];
function on_key_press(eKeyCode keycode) 
{
  if (keycode == eKey1)
    ch[0] = aClip.Play();
  if (keycode == eKey2)
    ch[1] = aClip.PlayFrom(2000);
  if (keycode == eKey3)
  {
    if (ch[0] != null && ch[0].IsPlaying)
      ch[0].Stop();
    ch[0] = null;
  }
}


I start both instances of the clip pressing 1 and 2 with short delay, then press 3 and only one instance is stopped.

There is probably some specific condition that causes the error. If you have a large script, I recommend trying to create a simpliest possible test project that demonstrates the issue.

EDIT:
BTW, I remember there was an interesting bug, that if you keep AudioChannel reference for prolonged time, you may end up having different clip playing on it, even if you don't explicitly assign your variable to AudioClip.Play. AFAIK this is because the AudioChannel script pointer does not refer to a temporary channel object, but to constantly existing channel, which may later be assigned to play another clip.

What I mean, for example:
Code: ags

AudioChannel *mychan; // a global variable

mychan = aClip1.Play();
//
// time passes, and Clip1 stops on its own here
//
aClip2.Play();
//
// much later
mychan.Stop(); // <-- this may stop aClip2


In other words, if you are keeping a reference to AudioChannel for a long time, then you must keep track of clip state, or you may end up using it to access different instance of a clip (or completely another clip).

I suppose it is quite possible that similar thing is occuring to you.

UnusualCadence

#5
How curious! I've set up a totally fresh script to trigger and stop the music clips using keys, as you are doing in your example - but when I call the Stop() function on either mainmus[0] or mainmus[1] when both clips are playing, both channels will be stopped.  I'm using the latest 3.4.0.7 beta, incidentally!

Edit: OK, this bug seems to be specific to using .wav files. As soon as I imported an .ogg file, the issue went away, hooray! However, I was hoping to use wav as the Seek and Position functions are sample accurate with that file format, unlike the compressed formats.

Crimson Wizard

Hmm... does anyone else experience this?

UnusualCadence, could you send me your project for testing?

morganw

This sounds more like it's hitting a limit for channel reservations, so I think we need to check that there were definitely two AudioClips playing before Stop was called (what is the Type of these AudioClips, and how have channels been reserved).

Crimson Wizard

#8
Quote from: UnusualCadence on Sun 12/06/2016 17:20:17
Edit: OK, this bug seems to be specific to using .wav files.

When I test WAV files, I cannot make multiple clips play at the same time at all...

Another strange thing I found: if I play WAV, and then start OGG, the WAV stops. But if I start OGG first, then start WAV, they both continue to play.

The manual mentions that AGS cannot play two MIDI files at the same time, but nothing about WAV restriction.

E: Also, AudioChannel.IsPlaying returns false all the time for WAV file I was testing...

UnusualCadence

Aha, thanks for confirming! I guess there's something up with wav playback in AGS. I've switched over to ogg now, and everything is working perfectly!

SMF spam blocked by CleanTalk