Changing Audio Voulme in the Script

Started by GoToHellDave, Fri 01/02/2013 14:57:25

Previous topic - Next topic

GoToHellDave

I've searched high and low and I can't seem to find any information on this, despite it being what would appear to be a fairly rudimentary function. I'm aware that the audio side of the engine recently received an overhaul, but again, I'm struggling to find any info on it anywhere.

Basically, what I'm attempting to do is have two pieces of music playing simultaneously and be able to change the volume of the two of them in the script, at will, in order to create what's known as a wet/dry mix. This will enable me to give the player the impression of hearing the music clearly whilst inside a nightclub and having the higher frequencies drop out once the player leaves the night club.

Does anybody know how I can do this or would anybody be so kind as to link me to where the relevant information is?

Your help is greatly appreciated as always.

Ben.

Crimson Wizard

You should store the pointer to audio channel, which plays your music. Then use it to change volume.

Basic example:
Code: ags

AudioChannel *channel = MyMusic1.Play();
channel.Volume = 20;

GoToHellDave

Thanks Crimson Wizard. I'd completely overlooked the use of audio channels.

GoToHellDave

OK. I'm trying to implement what you have suggested but I don't think I fully understand how audio channels work. I've created two audio channels (one to be turned up whilst the player is inside the club and the other to be turned up when he goes outside the club.) Here is my issue:

In the room_firstload function, if I arrange the script like this:

Code: AGS

AudioChannel *OutsideClub = aMusic4.Play();
OutsideClub.Volume = 0;
AudioChannel *InsideClub = aMusic3.Play();
InsideClub.Volume = 100;


then the music plays when the room loads up.

However, if I arrange the script like this:

Code: AGS

AudioChannel *InsideClub = aMusic3.Play();
InsideClub.Volume = 100;
AudioChannel *OutsideClub = aMusic4.Play();
OutsideClub.Volume = 0;  


then the room is silent when it loads up.

Obviously I don't fully understand how audio channels work. Is this happening because I'm trying to make two channels which both have music on them? When I try to change the volume of the various channels in the 'room_LeaveLeft' function I get an error telling me that 'InsideClub' is an unidentified token.

Is there an FAQ or tutorial anywhere for this sort of thing? I can't seem to find any concrete info on audio anywhere and what I do find seems to be out of date.

Thanks for helping.

Ben.

Crimson Wizard

#4
New audio system is explained in the manual which comes with AGS Editor.
Specifically:
- "Other features"->"Music and sound";
- "Scripting" -> "AudioChannel functions and properties";
- "Scripting" -> "AudioClip functions and properties";

Quote from the "Music and sound" article:
Quote
AGS currently has an 8-channel audio system, which means that up to 8 sounds can be playing at the same time. With the default Audio Types settings, one channel is reserved for speech, one for music and one for ambient sounds; thus leaving 5 available for sound effects.
In your example music does not play because you start TWO audio clips at once. By default music has only one channel, that's why only the last-started music plays. In your second case you lower down second clip's volume, thats why you dont hear anything.
If you do not need more than one music channel, simply start new music, and it will stop any music that currently plays.

E: If you DO need more than one music channel, you should probably save the channel as global pointer for future use.
Just some silly example:
Code: ags

// Declare channel pointers in global script
AudioChannel music_channels[2];

// In room scripts --

function WhenEnteringClub()
{
  if (music_channel[0])
    music_channel[0].Volume = 20; // lower down outside music volume
  if (!music_channel[1])
    music_channel[1] = aClubMusic.Play();
  music_channel[1].Volume = 100;
}

function WhenExitingClub()
{
  if (music_channel[1])
    music_channel[1].Volume = 20; // lower down club music volume
  if (!music_channel[0])
    music_channel[0] = aOutsideMusic.Play();
  music_channel[0].Volume = 100;
}

// In this case two musics will play simultaneously, but with different volumes

Also, increase number of channels for music. In your project tree select "Audio"->"Types"->"Music" and change MaxChannels property.

GoToHellDave

Thanks again Crimson Wizard. I'll try this out now.

GoToHellDave

I've tried to implement what you suggested but it keeps throwing up an error that music_channel is an undefined symbol. I figured it might need to be imported from the global script but that doesn't seem to work either.

Crimson Wizard

My apologizes. It should be
Code: ags
AudioChannel* music_channels[2];

a pointer-to-channel array, not just channel array.

GoToHellDave

I'm afraid I still get the same error (undefined symbol 'music_channel'.) Is there something I'm not doing? It won't let me import music_channels because it isn't a variable or a function.

monkey0506

Arrays (including arrays of pointers) in AGS have to be exported from the script in order to be imported in the header. The proper syntax for this is:

Code: ags
// Script.asc

AudioChannel *music_channels[2];
export music_channels;

// Script.ash

import AudioChannel *music_channels[2];


Also, CW very sensibly named the array "music_channels" but then very foolishly omitted the s throughout the rest of his example code, which you've clearly just copied and pasted. You can name the array whatever you want, but you'll have to access it by the same name (meaning, either rename the array and the import, or change the usages in room and other scripts).


Khris

Also, while if (some_pointer) ... does the same as if (some_pointer != null) ..., using if (!some_pointer) ... will throw a compilation error. You have to use if (some_pointer == null) ..

GoToHellDave

Thanks Khris. As it happens, I didn't simply copy and paste the code. Naturally when the error was thrown up my first instinct was that of the missing 's'. Thanks for your advice, I'll have a go at implementing it now.

SMF spam blocked by CleanTalk