Author Topic: MODULE: Pause and Resume all Audio  (Read 198 times)

MODULE: Pause and Resume all Audio
« on: 22 Feb 2021, 20:46 »
Baffled by the lack of a "pause audio" function in AGS and the lack of any modules addressing this (as far as I know), I've decided to make a very simple module that provides pause and resume functionality for all currently playing audio, for example in case you want to pause everything that's playing when your Options/Pause menu comes up, and maybe play a different music piece while the menu is up, or whatever.

You can download it from here.

Usage is extremely simple, just use PauseAudio() to pause and ResumeAudio() to resume.

The only catch is that you need to set AudioPriority and RepeatStyle for each clip in the editor. So if for example you have a clip that you sometimes want to play looped and sometimes as a one-off, you'll need to import two copies of the same clip and set different attributes for each instance. Same if you want to change the priority of an audio clip.

I'm working on a more "robust" version that can actually store AudioPriority and RepeatStyle, for which you can find the (untested) code below, BUT the trade-off in this case would be that in order to play audio, you would have to use an extender function, CustomPlay, rather than the built-in Play function. Feel free to check out the code below if you want. If I find time to test it properly and it works, I could provide another variant of the module, or replace the previous one entirely.

Thanks a lot to Crimson Wizard for his infinite patience helping me figure this out!

Spoiler: ShowHide

Code: Adventure Game Studio
  1. struct ChannelAttributes {
  2.     int channelvolume;
  3.     int channelpanning;
  4.     AudioClip * channelclip;
  5.     int channelposition;
  6.     int channelprio;
  7.     int channelrepeat;
  8.     int channelspeed;
  9. };
  11. ChannelAttributes runningchannel[8];  // if the maximum number of channels changes in the future, this will need to be updated

We also need a global bool:

Code: Adventure Game Studio
  1. bool isthisframeaudio = false;

This would be the extender/wrapping function that replaces the regular Play:

Code: Adventure Game Studio
  1. function CustomPlay(this AudioClip*, AudioPriority prio, RepeatStyle repeat)
  2. {
  3.     this.Play(prio, repeat);
  4.     for (int i = 0; i < System.AudioChannelCount; i++) {
  5.         AudioChannel* tempchannel = System.Audiochannels[i];
  6.         if (tempchannel != null && tempchannel.PlayingClip == this) {
  7.             runningchannel[i].channelprio = prio;
  8.             runningchannel[i].channelrepeat = repeat;
  9.             runningchannel[i].channelclip = this;
  10.         }
  11.     }
  12. }

Pause and resume functions proper:

Code: Adventure Game Studio
  1. function PauseAudio()
  2. {
  3.     for (int i = 0; i < System.AudioChannelCount; i++) {
  4.         AudioChannel* tempchannel = System.Audiochannels[i];
  5.         if (tempchannel != null && tempchannel.IsPlaying) {
  6.           runningchannel[i].channelvolume = tempchannel.Volume;
  7.           runningchannel[i].channelpanning = tempchannel.Panning;
  8.           runningchannel[i].channelposition = tempchannel.Position;
  9.           runningchannel[i].channelspeed = tempchannel.Speed;
  10.          // here we check if the clip that is playing is the same one we played manually; if it's not, it's frame-linked audio
  11.           if (tempchannel.PlayingClip != runningchannel[i].channelclip) isthisframeaudio = true;
  12.           else isthisframeaudio = false;
  13.           runningchannel[i].channelclip = tempchannel.PlayingClip;
  14.           tempchannel.Stop();
  15.         }
  16.     }
  17. }

Code: Adventure Game Studio
  1. function ResumeAudio()
  2. {
  3.     for (int i = 0; i < System.AudioChannelCount; i++) {
  4.         AudioChannel* tempchannel = System.Audiochannels[i];
  5.         if (tempchannel != null) {
  6.           AudioClip* tempclip = runningchannel[i].channelclip;
  7.           // if the clip playing is frame-linked audio, we use the Play command with no attributes so the AudioPriority and RepeatStyle values set in the editor are used
  8.           if (tempclip != null) {
  9.             if (isthisframeaudio) tempchannel = tempclip.Play();
  10.             else tempchannel = tempclip.Play(runningchannel[i].channelprio, runningchannel[i].channelrepeat);
  11.           }
  12.           tempchannel.Volume = runningchannel[i].channelvolume;
  13.           tempchannel.Panning = runningchannel[i].channelpanning;
  14.           tempchannel.Speed = runningchannel[i].channelspeed;
  15.           tempchannel.Seek(runningchannel[i].channelposition);
  16.         }
  17.     }
  18. }

« Last Edit: 12 Mar 2021, 10:01 by Laura Hunt »


Re: MODULE: Pause and Resume all Audio
« Reply #1 on: 23 Feb 2021, 00:33 »
That is something useful to have! Hey, if you have the time, place the code somewhere in GitHub, because I saw a bunch of these file storages die through the life of this forum - GitHub has been more resilient so far.

Re: MODULE: Pause and Resume all Audio
« Reply #2 on: 23 Feb 2021, 08:47 »
I will! I simply have never used Github, so I need to find a moment to create an account, tinker around, and see how it works. But I will definitely upload it there at some point :)
« Last Edit: 23 Feb 2021, 08:52 by Laura Hunt »