Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Stopping sounds when switching out of my app.

Credits go to Audric and Richard Phipps for helping out!
This thread is locked; no one can reply to it. rss feed Print
Stopping sounds when switching out of my app.
Andrei Ellman
Member #3,434
April 2003

Hi,

Whenever I switch out of my program (Allegro 4.2.2, Windows 2000) using ALT-TAB the sound-buffer is looped continuously so the currently playing collection of samples stutters until I switch back to the program. This happens in both windowed and fullscreen modes. This also happens when I focus another window. As well as my app, it happens in the Allegro demo-game too. Midis however do manage to silence themselves when switched out - it's just the samples that keep looping.

I tried writing a switch-out callback that loops through all my samples and stop_sample()'s them, but this does not work when switching out. However, when I call the function for doing so from within the main context of the program it successfully stops all sounds. I also placed a TRACE-message in my switch-out handler, and the message is printed in the debug-window before the app is switched out. This means that both the code for stopping the samples and the switch-out callback appear to be working.

Here's the code I use for stopping the sound

void
chStopAllSounds(void)
{
  int nI;
  int nNumSounds = _chGetNumSamples();
  
  for(nI=0;nI<nNumSounds;nI++)
  {
    ChSFXDatum *sfxdp = &(g_sfxdaTheSoundEffects[nI]);
    stop_sample(sfxdp->splTheSample);
  }
}

Here's the switch-out callback:

void 
aeSwitchOutCallback(void)
{
  /* Stop all sounds */
  chStopAllSounds();

  TRACE(TPREFIX_I "A display switch-out message was recieved.\n");

}

And finally, the code for setting up the switch-out callback

1AERETVAL
2aeSetDisplaySwitchCallbacksIfNeeded(void)
3{
4 ASSERT(!g_bRemoveSwitchInCallback);
5 ASSERT(!g_bRemoveSwitchOutCallback);
6 
7 
8 /* Set up a callback for when the app is switched back in. */
9 if(set_display_switch_callback(SWITCH_IN, aeSwitchInCallback))
10 {
11 TRACE(TPREFIX_E "No SWITCH_IN callback was set.\n");
12 return AERVAL_AIEEE;
13 }
14 
15 g_bRemoveSwitchInCallback = TRUE;
16 
17 
18 
19 /* Set up a callback for when the app is switched out. */
20 if(set_display_switch_callback(SWITCH_OUT, aeSwitchOutCallback))
21 {
22 TRACE(TPREFIX_E "No SWITCH_OUT callback was set.\n");
23 return AERVAL_AIEEE;
24 }
25 
26 g_bRemoveSwitchOutCallback = TRUE;
27 
28 
29 
30 return AERVAL_YOOPY;
31}

And finally, the code for initialising the Allegro sound-engine

  if(install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL))
  {
    TRACE(TPREFIX_E "Error Initialising Sound: %s\n", allegro_error);
    return AERVAL_AIEEE;  // Sound-related error-message instead?
  }

The Allegro sound-driver used is AXA and the MIDI driver is W32M

Anyone know how to make the sound stop playing when I switch out?

AE.

[EDIT: PS. My soundcard is a "SB Live! Value"]

--
Don't let the illegitimates turn you into carbon.

Elverion
Member #6,239
September 2005
avatar

Is there any reason you can't use set_display_switch_mode(SWITCH_BACKGROUND)? Then you wouldn't have to worry about stopping the sounds.

--
SolarStrike Software - MicroMacro home - Automation software.

bamccaig
Member #7,536
July 2006
avatar

The sound shouldn't necessarily stop playing when you switch out. I know that Counter-Strike: Source's sounds continue even after you switch out. However, if the sounds are looping erroneously or something that would be a problem.

Otherwise, I wouldn't worry about silencing the game when you switch. Games are generally not intended to be running unless the user is playing them. If they are playing them they probably want the sound (unless they don't in which case they can either mute the system or mute your game (if that functionality exists).

Audric
Member #907
January 2001

What you experience is not the normal behavior.
I tested with the Allegro demo (which doesn't call any specific set_display_switch_callback() nor set_display_switch_mode()), and Allegro suspends MIDI, and cuts all sounds short. Sounds do not resume on return.
Win98, though.

Andrei Ellman
Member #3,434
April 2003

Elverion said:

Is there any reason you can't use set_display_switch_mode(SWITCH_BACKGROUND)? Then you wouldn't have to worry about stopping the sounds.

What if I'm running fullscreen and I don't want the action to continue while my game is minimised? I could of course set a flag in my switch out callback that pauses the game and resumes it on switch-in, but would prefer just to make the sounds stop.

bamccaig said:

However, if the sounds are looping erroneously or something that would be a problem.

That's what they're doing. The sound-buffer just keeps looping continuously until I return to my game.

bamccaig said:

Otherwise, I wouldn't worry about silencing the game when you switch. Games are generally not intended to be running unless the user is playing them.

But the point is that the stuttering sound-buffer is annoying and should be silenced automatically.

Audric said:

Win98, though.

I'll try it the next time I boot up in Win98. Only tried Win2K so far.

AE.

--
Don't let the illegitimates turn you into carbon.

Richard Phipps
Member #1,632
November 2001
avatar

I've had this myself. I can't remember of the top of my head how I solved it, but I think the switch out callback gets called twice, so I ended up making that function only set a variable and then dealt with that variable to stop/restart sound in the main loop.

Does that help?

Audric
Member #907
January 2001

Ok i checked on the laptop (win 2000) : sound is "stuck" when window loses focus / minimize etc.
The Allegro DLL I have there is 4.2.1
(edit found a 4.2.2 dll and re-tested: same thing)
The problem is even more visible if you use wave-based music, such as DUMB playing a module.
FMOD music doesn't show the problem as far as I know, because it uses its own thread and it continues playing even if the Allegro thread is paused.

Richard Phipps
Member #1,632
November 2001
avatar

Ah! I found this old Neon Wars (OpenLayer version) code. Hope it helps:

1// This function is called with out switch in callback so this is executed when the user
2// alt-tabs back into our program. It just sets a flag.
3void switch_in(void)
4{
5 game.switch_in = true;
6}
7 
8// This function is called with out switch out callback so this is executed when the user
9// alt-tabs out of our program. It just sets a flag.
10void switch_out(void)
11{
12 game.switch_out = true;
13}
14 
15// This code is executed from the main loop when the switch in variable has been set.
16// It is done this way so the function is not called from the callback itself.
17void switch_in_code(void)
18{
19 if (!game.switched_out) return;
20 if (option[OPTION_SCREEN].choice != 0 || game.minimized) game.switched_out = false;
21 game.switch_in = false;
22 game.minimized = false;
23
24 write_to_log("Switching back in");
25
26 // If we have a fullscreen screenmode then, restore screen.
27 if (option[OPTION_SCREEN].choice > 0) change_screen_type();
28
29 if (set_display_switch_mode(SWITCH_BACKGROUND) != -1)
30 set_display_switch_mode(SWITCH_BACKAMNESIA);
31
32 // Restore callbacks as set_display_switch_mode removes them..
33 set_display_switch_callback(SWITCH_OUT, switch_out);
34 game.pause_alpha.target = 0.0;
35 game.paused = false;
36
37 // Restore looping shield sound if necessary.
38 if (ply[0].special == SPECIAL_SHIELD)
39 {
40 // Play shield sound in a loop.
41 play_sound(sound[SND_SPECIAL_SHIELD].snd, ply[0].x, ply[0].y, 1000, 1);
42 }
43 
44 if (ply[0].special == SPECIAL_ORBIT)
45 {
46 // Play orbit sound in a loop.
47 play_sound(sound[SND_SPECIAL_ORBIT].snd, ply[0].x, ply[0].y, 1000, 1);
48 }
49
50 reset_timer();
51}
52 
53// This code is executed from the main loop when the switch out variable has been set.
54// It is done this way so the function is not called from the callback itself.
55void switch_out_code(void)
56{
57 game.switch_out = false;
58 write_to_log("Switching out");
59
60 // Lower music volume and pause before switching out..
61 al_duh_set_volume(sound_system.dp, 0);
62 al_pause_duh(sound_system.dp);
63
64 if (ply[0].special == SPECIAL_SHIELD) stop_sample(sound[SND_SPECIAL_SHIELD].snd);
65 if (ply[0].special == SPECIAL_ORBIT) stop_sample(sound[SND_SPECIAL_ORBIT].snd);
66
67 game.switched_out = true;
68
69 if (option[OPTION_SCREEN].choice == 0)
70 {
71 // Windowed.
72 set_display_switch_mode(SWITCH_BACKGROUND);
73 set_display_switch_callback(SWITCH_IN, switch_in);
74 }
75 else
76 {
77 // Fullscreen.
78 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); // Remove our screenmode and restore desktop.
79 set_display_switch_mode(SWITCH_BACKAMNESIA);
80 set_display_switch_callback(SWITCH_IN, switch_in);
81 }
82}

Andrei Ellman
Member #3,434
April 2003

I just tried this on Win98SE (Allegro 4.2.2) and the same problem occurs (even with the Allegro demo game). However, if I minimise, I briefly get a stutter, the sound then plays normally for about 1 second and then starts stuttering again.

This happens in both fullscreen and windowed modes, and in windowed modes, happens regardless of whether I use the DXWN or GDIB graphics drivers. I think this may be a bug in Allegro.

Richard Phipps said:

SWITCH_BACKGROUND

I was hoping to be able to use SWITCH_PAUSE instead as then my game does not take up any CPU time when switched out. Although I suppose your method can be used as a workaround if I place a "rest(1000)" or something in my main loop (plus it has the advantage that I could make my game chartacters have falling-asleep animations when the game is switched out).

Incidentally, does Allegro have the ability to tell the difference between a minimised window and a window switched to the background?

AE.

[EDIT: PS. My soundcard is a "SB Live! Value"]

[EDIT2:]

Audric said:

Allegro suspends MIDI, and cuts all sounds short. Sounds do not resume on return.
Win98, though.

Is that Win98SE or the first Win98 edition?

--
Don't let the illegitimates turn you into carbon.

Audric
Member #907
January 2001

Win98SE, Sound Blaster Live 1024.
I have to say there can be a very brief stutter (or silence) while the focus switches to an other window, but then the sound stabilizes to silence. I have never considered it as abnormal for any game, seeing how the OS might do some swapping at the time.

Now on the Windows 2000 laptop it's a whole different matter, the sound buffer instantly enters an endless loop - very easy to reproduce.

On both platforms, I made almost all my tests in windowed mode (click on other window to switch focus), as in fullscreen Alt-tabbing is slow to register.

Milan Mimica
Member #3,877
September 2003
avatar

Phipps said:

but I think the switch out callback gets called twice

Has been fixed in 4.2.2.

bamccaig
Member #7,536
July 2006
avatar

Richard Phipps
Member #1,632
November 2001
avatar

Hmm.. no idea then!

IMHO there are major issues with sound and window control in Allegro.

Andrei Ellman
Member #3,434
April 2003

Looks like it's a bug in Allegro then. I've notified the devs.

Cookie time.

AE.

--
Don't let the illegitimates turn you into carbon.

Audric
Member #907
January 2001

I made some more serious tests in the default windows background mode :
Allegro 4.2.1 and 4.2.2 give good results under Win98SE.
Allegro 4.2.1 and 4.2.2 give bad results under Win2000.

On either OS and Allegro version, DUMB playback stutters when the window doesn't have the focus - I guess I'll have to call al_pause_duh() and al_resume_duh() when switched out and in.

Go to: