Audiochannel Help

Started by Quintaros, Sun 19/04/2015 23:04:41

Previous topic - Next topic

Quintaros

I think I'm missing some fundamental concept when it comes to using the audiochannels.  I have a function that is supposed to play a ambient sound file based on a room custom property that is called from the "Enters Room Before Fade-In".  It seems to work for the very first room but when I go to another room that also calls the function the music stops and won't restart even when I go back to the room that was working before.

Can anyone help me to understand what I'm missing?

Module Header:
Code: ags

enum AmbientSounds{
  eQuiet=0, 
  eBirds=1, 
  eBeach=2
};

import function StartAmbientSound();



Module Script:
Code: ags

function StartAmbientSound(){
  if((AmbientSound==null)||(AmbientSound.IsPlaying==false)){
    int atmosphere=Room.GetProperty("AmbientSound");      
    if(atmosphere==eQuiet){//Don't play a sound      
    }else if(atmosphere==eBirds){
       AmbientSound=aBirds.Play();
    }
  }else{    
    int atmosphere=Room.GetProperty("AmbientSound");          
    if(atmosphere==eQuiet){       
      AmbientSound.Stop();     
    }else if(atmosphere==eBirds){
       AmbientSound=aBirds.Play();
    }
  }
}


Room Script:
Code: ags


function room_Load()
{
  StartAmbientSound();
}

MyEakinBack

#1
removed incorrect statements
completed: Beyond Eternity

Crimson Wizard

#2
Quote from: MyEakinBack on Mon 20/04/2015 00:21:41
I'm not an expert, but I've never had any luck at putting any type of array, struct, enum, etc. at global scope. I think AGS really only allows you to use the global variables tab to do any global variable, so you can only have ints, bools, Strings, etc.
No, no, no, AGS does allow to put either of mentioned item at global scope. This is how we create custom types of data in our scripts.
In fact, I, personally, have never used Global Variables tab at all (just a personal preference, but I note that its absolutely possible).
A lot of custom modules use custom enums and structs in global scope. You may easily check latest custom modules from their forum thread:
http://www.adventuregamestudio.co.uk/forums/index.php?board=10.0

Also, this topic from manual:
http://www.adventuregamestudio.co.uk/wiki/Script_language_keywords#import

Quote from: MyEakinBack on Mon 20/04/2015 00:21:41
My suggestion is to put your enum statement at the top of each and every room, and not in a header.
This is a very bad advice. This would create duplicates of entity instead of using same entity for all scripts.
Imagine you would have 100 rooms and would need to add new ambient sound type. You will be adding it to all 100.
Duplicating code, and even more - duplicating types, - lead to insanity (and errors in your program).



Regarding the problem, do I understand this right, that your ambient sound plays, but music stops?
Please tell, what audio types do those sounds belong, and how many available channels did you set for those types in their properties.


Lastly, your function seem to have a bit of excess repeating checks. It's not a technical mistake, but rather code style problem, which may cause trouble if the number of ambient types grow in future. It could be easier if you would just remember the type of sound you played before. Something like:
Code: ags

function StartAmbientSound(){
    AmbientSounds room_sound=Room.GetProperty("AmbientSound");
    if (room_sound==LastAmbientType)
        return; // no need to do anything

    // Stop current sound
    if(AmbientSound!=null && AmbientSound.IsPlaying)
        AmbientSound.Stop();

    // Play new sound
    if(atmosphere==eQuiet){//Don't play a sound      
    }else if(atmosphere==eBirds){
        AmbientSound=aBirds.Play();
    }
    // etc...
}


Monsieur OUXX

+1 Crimson Wizard

- Global stuff (in modules and global script) is all about "import" (and "export" if needed)
- putting the enum in each room is very bad advice ;) (no offense)
- CW's updated code is probably good (he's no fool (roll)), even though I have no knowledge of what's custom in the code and what's AGS built-in (AmbientSound, LastAmbientSound...)
 

Crimson Wizard

Quote from: Monsieur OUXX on Mon 20/04/2015 09:24:56
- CW's updated code is probably good even though I have no knowledge of what's custom in the code and what's AGS built-in (AmbientSound, LastAmbientSound...)
That's pseudo-code! obviously, I did not show where you declare LastAmbientSound, but it's implicitly suggested to declare it right at the AmbientSound.

BTW, something I forgot to ask, is AmbientSound a global variable, and how precisely it is declared?

Quintaros

#5
Thank you for your detailed help, CW

Quote from: Crimson Wizard on Mon 20/04/2015 09:08:09
Regarding the problem, do I understand this right, that your ambient sound plays, but music stops?
Please tell, what audio types do those sounds belong, and how many available channels did you set for those types in their properties.
IS AmbientSound a global variable, and how precisely it is declared?

No the music continues to play on room changes.
The audio type of the ambientsounds is "Sound" and they are .WAV files.  I'm not sure how many available channels are set.  I didn't do anything with this.
AmbientSound is a global variable declared in the Global Variables tab as *AudioChannel.

I tried modifiying my code based on your suggestions but now its crashing on a "Null pointer reference" on this line:
Code: ags

 if((AmbientSound!=null)||(AmbientSound.IsPlaying)){


I like your inclusion of the LastAmbientSound check, so the ambient sound continues from room to room if they are the same type. But I wasn't sure how to declare it.  You need to be explicit with me at this stage.  I put it as a Global Variable as an int. 

Crimson Wizard

Quote from: Quintaros on Mon 20/04/2015 11:25:34
Quote from: Crimson Wizard on Mon 20/04/2015 09:08:09
Regarding the problem, do I understand this right, that your ambient sound plays, but music stops?
Please tell, what audio types do those sounds belong, and how many available channels did you set for those types in their properties.
IS AmbientSound a global variable, and how precisely it is declared?

No the music continues to play on room changes.
In such case, I do not understand the problem.
Earlier you wrote:

Quote from: Quintaros on Sun 19/04/2015 23:04:41
I have a function that is supposed to play a ambient sound file based on a room custom property that is called from the "Enters Room Before Fade-In".  It seems to work for the very first room but when I go to another room that also calls the function the music stops and won't restart even when I go back to the room that was working before.

Can you elaborate?




Quote from: Quintaros on Mon 20/04/2015 11:25:34
I tried modifiying my code based on your suggestions but now its crashing on a "Null pointer reference" on this line:
Code: ags

 if((AmbientSound!=null)||(AmbientSound.IsPlaying)){

But my code was different:
Code: ags

if(AmbientSound!=null && AmbientSound.IsPlaying)

Notice the AND (&&) sign.


Quote from: Quintaros on Mon 20/04/2015 11:25:34
I like your inclusion of the LastAmbientSound check, so the ambient sound continues from room to room if they are the same type. But I wasn't sure how to declare it.  You need to be explicit with me at this stage.  I put it as a Global Variable as an int. 
Well, that would work.

Quintaros

Shoot.  My initial description was wrong.  It wasn't the music that was stopping on room change.  It was the ambient sound that would stop from the previous room and not restart for the new room.

Ah missed the "&&".  Thanks,  I was getting sloppy trying to test your code before heading to work this morning.

Quintaros

Okay, I finally got a chance to test the code and it's still behaving erratically.  The ambient sound plays in the first room where it is called and continues for adjacent rooms that have same ambientsoundtype.  When I go to a quiet room it successfully stops the ambient sound but when I return to a room where the sound had successfully played before it does not start again.  I inserted a display function at the line before the call to play the soundfile and that line is getting executed even though the sound is not playing.

Code: ags

function StartAmbientSound(){
  int RoomAmbientSoundType=Room.GetProperty("AmbientSoundType");
  if (RoomAmbientSoundType==LastRoomAmbientSoundType){
    return; // no need to do anything
  }
    LastRoomAmbientSoundType=RoomAmbientSoundType;
    
    //Stop Current Sound
    if((AmbientSound!=null)&&(AmbientSound.IsPlaying)){
      AmbientSound.Stop();    
      
    }
    if(RoomAmbientSoundType==eQuiet){
    }else if(RoomAmbientSoundType==eBirds){
        Display("this code is seen");
        AmbientSound=aBirds.Play(eAudioPriorityHigh);
      } 
}



Monsieur OUXX

Please do tell where and how your global variables are declared. (LastRoomAmbientSoundType, RoomAmbientSoundType, AmbientSound, etc.)

 

Crimson Wizard

#10
Quote from: Monsieur OUXX on Tue 21/04/2015 09:03:02
Please do tell where and how your global variables are declared. (LastRoomAmbientSoundType, RoomAmbientSoundType, AmbientSound, etc.)
Quintaros already mentioned that he uses Global Variables pane for AmbientSound and LastRoomAmbientSoundType.
As for RoomAmbientSoundType, it is declared right in the script he posted in previous post.


E: there is some problem with playing new sound; I am trying to remember if I've seen something like this before.

Quintaros

I changed the audio clip property of type from "sound" to "ambient sound" and the code seems to be running perfectly now.  I'm glad that it's working, of course, but I'd really like to understand what is going on here.

Quintaros

I have another audio issue.  I put code in my repeatedly_execute_always function to start and stop a footstep audioclip when the player was walking:
Code: ags

if(player.Moving==true){
    if(Walking==null||Walking.IsPlaying==false){//IsPlaying==false){
      Walking=aFootsteps.Play();
      Walking.SetRoomLocation(Room.Width/2, Room.Height);      
    }     
  }else{
     player.SetWalkSpeed(player.GetProperty("DefaultWalkSpeed"),player.GetProperty("DefaultWalkSpeed"));
     if(Walking!=null)Walking.Stop();    
  }


Where "Walking" is an audiochannel declared in the global variables panel.

Somehow this is interfering with other Sound Effect audioclips from playing when called.  Calls for Music and Ambient-Sound clips still work.

If I move the code from the repeatedly_execute_always function to the regular repeatedly_execute function, the other audioclips work normally but the walking sound clip will not play when the player is moved form a Player.Walk(x,y) call within another script.

Any suggestions?



geork

It makes sense that if your code is moved to repeatedly_execute(), then it won't play whenever a command is executed which "blocks" the script (eBlock). You'd want to keep the audio code in repeatedly_execute_always(), since it always runs regardless.

How many channels do you have going? AGS has a limit of 5 channels, with an additional 1 channel set aside for Music, Ambient Sound and Voice respectively. I've never hit the channel cap, but maybe that's what's causing these issues? That's not to say that you can't HAVE more than 5 Channels, but you can't have more than 5 ACTIVE at any one time.

I know it's not really solving the issue, but you can tie a sound effect to a frame in a character's walk animation instead. In the view for your character, click on the relevant frame (where the foot comes down), then in the menu on the bottom right click on "Sound". You should be able to select a footstep sound to attach to that frame. You can change the sound later on in the script (if you want to change it during runtime) using a ViewFrame *object:
Code: ags
ViewFrame *v = Game.GetViewFrame(int View, int Loop, int Frame);
v.LinkedAudio = aFootsteps;

Quintaros

Quote from: geork on Sat 02/05/2015 16:01:32
It makes sense that if your code is moved to repeatedly_execute(), then it won't play whenever a command is executed which "blocks" the script (eBlock). You'd want to keep the audio code in repeatedly_execute_always(), since it always runs regardless.

Yes, I put it in the repeatedly_execute_always()for this reason but only moved it to test if it was the source of the issue with the other sound files.

Quote from: geork
How many channels do you have going? AGS has a limit of 5 channels, with an additional 1 channel set aside for Music, Ambient Sound and Voice respectively. I've never hit the channel cap, but maybe that's what's causing these issues? That's not to say that you can't HAVE more than 5 Channels, but you can't have more than 5 ACTIVE at any one time.
I don't think I'm hitting the 5 channel limit.  I have the footsteps audioclip occupying a channel and then I can't call even one additional audioclip unless it's a music or Ambient Sound type.



SMF spam blocked by CleanTalk