IsPlaying giving a null pointer error

Started by Andail, Sun 11/11/2012 14:46:07

Previous topic - Next topic

Andail

Okay, I might have been sitting for too long with AGS today, but I can't wrap my head around this issue.

I have a sound playing in one room. I'm using a global variable audio channel (bells) to play the clip in.
In the next room, I want the volume to go down, so I've got this:

if (bells.IsPlaying == true){
    bells.Volume = 50;
}

Now, this works perfectly if the bells clip is playing, but if it isn't, AGS gives me a null pointer referenced error and shuts down. I can't for my life see why. If the bells sound isn't playing, surely it would just return false?

Crimson Wizard

#1
Where do you declare 'bells' variable? Is it global or local?

Ah, pardon, I somehow missed that line about bells being global var.

Andail

#2
How does that make a difference? How do I go about checking whether the sound clip is playing?
Btw, I should mention that I need to check this for other purposes, not just to lower the volume.

PS:
Ok I found in the manual that I have to first check that the soundclip != null before. Feels a bit strange, but ok.

Crimson Wizard

#3
Regarding the AudioChannel pointer being null. Can you show how you set that pointer in your script?

Regarding difference between AudioChannel and AudioClip. Problem is that AudioChannel is not bound to certain AudioClip all the time. If game used the channel A for the first time, it may use channel B next time.
Quote from the manual:
Quote from: AGS Manual
AudioChannel* AudioClip.Play
<...>
This command searches through all the available audio channels to find one that is available for this type of audio. If no spare channels are found, it will try to find one that is playing a clip with a lower or equal priority, and interrupt it to replace it with this new sound.

If all audio channels are busy playing higher priority sounds, then this new audio clip will not be played.

This command returns the AudioChannel instance that the new sound is playing on, or null if it did not play for any reason.
Check the last line BTW.


How to test if certain AudioClip is playing. I used this function:
Code: ags

AudioChannel * GetPlayingInstance(this AudioClip*)
{
  int i = 0;
  AudioChannel *ac;
  
  while (i < System.AudioChannelCount)
  {
    ac = System.AudioChannels[i];
    
    if (ac.PlayingClip == this)
    {
      return System.AudioChannels[i];
    }
    i++;
  }
  
  return null;
}

It returns channel that is playing given clip at the moment, or null pointer if the clip is not being played at all.

Kumpel

Sorry to necropost, but this is my exact problem, I just don't get the solution.

I want to play a sound if the cursor is over a hotspot. Of course it should only play once while on the Hotspot, so I need to check if it is already playing.

First I did this

Code: ags
 
if (!MenuSounds.IsPlaying)
  MenuSounds = aEngineStart.Play(eAudioPriorityNormal);


But it gave me that weird null pointer reference error at the first line.

Now with trying the thing you guys mentioned in this thread and checking if MenuSounds != null before the first "if",
the clip won't play at all. But why? Does this mean the audiochannel MenuSounds (a global variable) is always null if not played? ???

Crimson Wizard

#5
Quote from: Kumpel on Wed 15/06/2016 17:34:47
Now with trying the thing you guys mentioned in this thread and checking if MenuSounds != null before the first "if",
the clip won't play at all. But why? Does this mean the audiochannel MenuSounds (a global variable) is always null if not played? ???

The thing is that
a) you must check (MenuSounds != null) before checking IsPlaying, but also
b) you may need to call Play even if (MenuSounds == null).
In other words, you may need to change your condition logic:
Code: ags

if (MenuSounds == null || (MenuSounds != null && !MenuSounds.IsPlaying))
  MenuSounds = aEngineStart.Play(eAudioPriorityNormal);

or, to simplify:
Code: ags

if (MenuSounds == null || !MenuSounds.IsPlaying)
  MenuSounds = aEngineStart.Play(eAudioPriorityNormal);


Regarding latter example, according to the rule of calculating boolean expressions, MenuSounds.IsPlaying won't be called if MenuSounds == null, because in that case the first check will be enough to know the result of this logical expression.


Quote from: Kumpel on Wed 15/06/2016 17:34:47Does this mean the audiochannel MenuSounds (a global variable) is always null if not played? ???
Well for starters, it will be null initially, before playing anything.

Also, I really recommend you to not keep AudioChannel pointer saved in your variable for a long time, because of the bug, described in the second part of following post (after EDIT):
http://www.adventuregamestudio.co.uk/forums/index.php?topic=53645.msg636537469#msg636537469

Kumpel

#6
Oh yes! Thanks for clarifying that for me! Now it makes perfect sense.
Maybe you should add in the manual, that this statement addendum is necessary for checking if a channel is playing. Just writing at help article AudioClip.play: "This command returns the AudioChannel instance that the new sound is playing on, or null if it did not play for any reason." without linking the importance of this sentence for "IsPlaying-statements wasn't very helpful on it's own for me. But maybe I am just not a programming crack 8-0 (As if I didn't know that...(laugh))

SMF spam blocked by CleanTalk