Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: nightmarer on Wed 24/02/2021 22:54:31

Title: 2 AudioChannels music don't work at the same time
Post by: nightmarer on Wed 24/02/2021 22:54:31
Good evening all.

I am continuing this thread I changed the name as now the issue is another.
https://www.adventuregamestudio.co.uk/forums/index.php?topic=58871.0 (https://www.adventuregamestudio.co.uk/forums/index.php?topic=58871.0)
First I wanted to make the script work but seems that AGS doesn't like to play two tracks at the same time in this way.

In this enum:
Code (ags) Select
enum SetBGM_Channel {
  ChannelA = 0, 
  ChannelB = 1
};


With these array of pointers:
Code (ags) Select
AudioChannel *bgm[2];

With this function:
Code (ags) Select
static void SetBGM::Play(AudioClip *music, SetBGM_Channel index, int initialvol) {
  if (bgm[index] == null || bgm[index].PlayingClip != music) {
   bgm[index] = music.Play();
   bgm[index].Volume=initialvol;
   Display("index = %d", index);
   Display("Initial volumen = %d", initialvol);
  }
  else if(music == null) {
    music.Stop();
  }
}


If I enter this code.
Code (ags) Select
  SetBGM.Play(track1, ChannelA);
  SetBGM.Play(track2, ChannelB);


The second line seems to overwrite the same pointer in spite it is using different index in the array.
So this way of doing it doesn't work.
Is there any other way to do it?
Title: Re: 2 AudioChannels music don't work at the same time
Post by: Crimson Wizard on Wed 24/02/2021 23:03:50
Quote from: nightmarer on Wed 24/02/2021 22:54:31
The second line seems to overwrite the same pointer in spite it is using different index in the array.

How do you test that it overwrites same pointer? Does it actually overwrite wrong element in array, or you just noticed that playing second music stops the first one?
How many channels are there reserved for music audio type?
Title: Re: 2 AudioChannels music don't work at the same time
Post by: nightmarer on Wed 24/02/2021 23:14:55
Quote from: Crimson Wizard on Wed 24/02/2021 23:03:50
Quote from: nightmarer on Wed 24/02/2021 22:54:31
The second line seems to overwrite the same pointer in spite it is using different index in the array.

How do you test that it overwrites same pointer? Does it actually overwrite wrong element in array, or you just noticed that playing second music stops the first one?
How many channels are there reserved for music audio type?
Can you see the Display text added in the code?
This is the way I tested it.
I hear the same song in both channels. Maybe it is the same channel?
I used these different testes to check it.
Code (ags) Select
  SetBGM.SetVolumen(ChannelB, 0);
  Display("B to 0");
  SetBGM.SetVolumen(ChannelB, 100);
  Display("B to 100);
  SetBGM.SetVolumen(ChannelA, 0);
  Display("A  to 0");
  SetBGM.SetVolumen(ChannelA, 100);
  Display("A to 100");
  SetBGM.SetVolumen(ChannelB, 0);
  Display("B to 0 again");
  SetBGM.SetVolumen(ChannelB, 100);
  Display("Be to 100 again);
Title: Re: 2 AudioChannels music don't work at the same time
Post by: Crimson Wizard on Wed 24/02/2021 23:17:27
Quote from: nightmarer on Wed 24/02/2021 23:14:55
Can you see the Display text added in the code?
This is the way I tested it.

Yes, but what did these displays show? Was the index correct, or same all the time regardless of what you pass?

Quote from: nightmarer on Wed 24/02/2021 23:14:55
I hear the same song in both channels. Maybe it is the same channel?

You can test what the channel is by doing so:
Code (ags) Select

Display("channel ID = %d", bgm[index].ID);
Title: Re: 2 AudioChannels music don't work at the same time
Post by: nightmarer on Wed 24/02/2021 23:39:09
Quote from: Crimson Wizard on Wed 24/02/2021 23:17:27
Quote from: nightmarer on Wed 24/02/2021 23:14:55
Can you see the Display text added in the code?
This is the way I tested it.

Yes, but what did these displays show? Was the index correct, or same all the time regardless of what you pass?

Quote from: nightmarer on Wed 24/02/2021 23:14:55
I hear the same song in both channels. Maybe it is the same channel?

You can test what the channel is by doing so:
Code (ags) Select

Display("channel ID = %d", bgm[index].ID);


I've added your line and it shows the same for both indexes. ID = 1.
https://ibb.co/VxGXWRh (https://ibb.co/VxGXWRh)
Title: Re: 2 AudioChannels music don't work at the same time
Post by: Crimson Wizard on Wed 24/02/2021 23:45:18
So, how many channels are reserved for music audio type? I have a feeling there's MaxChannels set to 1. If it is, you just need to increase it to 2.

This is done by going to Audio -> Types -> Music in the project tree.
Title: Re: 2 AudioChannels music don't work at the same time
Post by: nightmarer on Wed 24/02/2021 23:53:19
Quote from: Crimson Wizard on Wed 24/02/2021 23:45:18
So, how many channels are reserved for music audio type? I have a feeling there's MaxChannels set to 1. If it is, you just need to increase it to 2.

This is done by going to Audio -> Types -> Music in the project tree.

Ohh! That was the error. So maybe this should be moved to the beginners questions.
Thank you again for your help.
Title: Re: 2 AudioChannels music don't work at the same time
Post by: nightmarer on Thu 25/02/2021 12:21:17
Good morning all.

Let me continue this thopic as I found something really weird.

As usual there are one array with two indexes pointing 2 different AudioChannels

Code (ags) Select
AudioChannel *bgm[2];

Everything is fine untill I play a new track in any of the two channels. Untill the stack is not finish it will copy the same values in volume for both indexes.
Also I must mention that the AdioChannel ID is changing. Is that normal?

I'm going to put in the comments the result of the Displays.

This is the instruction for running the script.
Code (ags) Select
SetBGM.Play(aDecadance_disco, ChannelA, 57);

Now these are the results of the script.
Code (ags) Select
static void SetBGM::Play(AudioClip *music, SetBGM_Channel index, int initialvol) {
  if (bgm[index] == null || bgm[index].PlayingClip != music) {
   if (bgm[1] != null) {
     bgm[0].Volume = 41;
     bgm[1].Volume = 42;
     Display("Channel ID of A = %d", bgm[0].ID); //Channel ID of A = 2
     Display("Channel A before playing track = %d", bgm[0].Volume); //Channel A before playing track = 41
     Display("Channel ID of B = %d", bgm[1].ID); //Channel ID of B = 1
     Display("Channel B before playing track = %d", bgm[1].Volume); //Channel B before playing track = 42
   } //So far so good
   bgm[index] = music.Play(); //Music is played and now the issue begins
   if (bgm[1] != null) {
     Display("Channel ID of A = %d", bgm[0].ID); //Channel ID of A = 1    ---Why now does it have another ID?
     Display("Channel A after playing track = %d", bgm[0].Volume); //Channel A after playing track = 100
     Display("Channel ID of B = %d", bgm[1].ID); //Channel ID of B = 1    ---Now both arrays are pointing the same index
     Display("Channel B after playing track = %d", bgm[1].Volume); //Channel B after playing track = 100
   }
   bgm[index].Volume=initialvol; //initial vol is 0;
   bgm[0].Volume=57;
   if (bgm[1] != null) {
     bgm[1].Volume=59;
     Display("Channel ID of A = %d", bgm[0].ID); //Channel ID of A = 1
     Display("Channel A now = %d", bgm[0].Volume); //Channel A now = 59
     Display("Channel ID of B = %d", bgm[1].ID); //Channel ID of B = 1
     Display("Channel B now = %d", bgm[1].Volume); //Channel A now = 59
   }
  }
  else if(music == null) {
    music.Stop();
  }
}


If I enter a new change out of this script everything goes fine, but I don't now why the function Play() is temporally pointing both index to the same AudioChannel ID.
Title: Re: 2 AudioChannels music don't work at the same time
Post by: Crimson Wizard on Thu 25/02/2021 12:37:52
I already mentioned this before in previous thread, that you dont really control which channel next music will be played on. Engine selects the channel.
If you call your function with ChannelA that won't necessarily mean that engine will play it on channel 1. This depends on combination of factors: how many channels are reserved, which channels are free, clip's priority.
This is why this script is quite questionable.

Perhaps you need a different approach to this task, but unfortunately I don't have much spare time right now to think this over. This seem to be a rather common thing, so maybe someone else could help.
Title: Re: 2 AudioChannels music don't work at the same time
Post by: Khris on Thu 25/02/2021 13:28:19
nightmarer, it seems to me like there's a central assumption you're working off: the assumption that as long as you have two pointers, that they will point to two separate audio channels.
This assumption however is wrong, and any code you write that is based on that assumption is broken by definition and will give unexpected results.

The whole issue with pointers is that they can absolutely point to the same object, in which case if you have pointerA and pointerB, setting pointerA.someProperty to a new value will also set pointerB.someProperty to that new value, because pointerA == pointerB.

Since you cannot force the channel AGS will use when you .Play() something, any channel index based code you use must read back the returned AudioChannel pointer's .ID to determine which channel AGS has used and go from there.
You cannot circumvent that fact by trying to force your own IDs into the process.
Title: Re: 2 AudioChannels music don't work at the same time
Post by: nightmarer on Thu 25/02/2021 13:53:48
Thanks for your answers, both of you.
Title: Re: 2 AudioChannels music don't work at the same time
Post by: nightmarer on Thu 25/02/2021 16:24:42
Anyway, let me let you know that finally I made it possible.
Out of the script I can set the volume to the pointers without having this issue.
So I just needed to make different methods for that and call them in the next line.

Regards.