2 AudioChannels music don't work at the same time

Started by nightmarer, Wed 24/02/2021 22:54:31

Previous topic - Next topic

nightmarer

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
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
enum SetBGM_Channel {
  ChannelA = 0,  
  ChannelB = 1
};


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


With this function:
Code: ags
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
  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?

Crimson Wizard

#1
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?

nightmarer

#2
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
  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);

Crimson Wizard

#3
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

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

nightmarer

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

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

Crimson Wizard

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.

nightmarer

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.

nightmarer

#7
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
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
SetBGM.Play(aDecadance_disco, ChannelA, 57);


Now these are the results of the script.
Code: ags
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.

Crimson Wizard

#8
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.

Khris

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.

nightmarer


nightmarer

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.

SMF spam blocked by CleanTalk