motorsep@Posted: Thu Aug 30, 2012 6:47 pm :
I don't see any section dedicated for sound/music modding in Doom 3, so I am posting it here :)

Is there a way to make dynamic music in Doom 3? Like fading in/out a track and mixing it with another track (or rather simply overlapping tracks while fading in/out happening) via SDK code based on triggers / conditional statements ?

Thanks.



Sikkpin@Posted: Thu Aug 30, 2012 7:08 pm :
Yes.



=FF=Sturm@Posted: Thu Aug 30, 2012 7:08 pm :
Yes.



chimueloeldragon2011@Posted: Thu Aug 30, 2012 7:14 pm :
Fading sounds can be done through scripts. What exactly are you looking for?
Do you want, for example, when fighting or when in action parts set a specific music to play, and once everything is calm another more relaxing track to fade in?
Anyway, this is a cheap line of code that will allow you to fade sounds in or out (Actually you can set the volume of the fade)

Code:
void sriptname() {
      $speakername.fadeSound ( SND_CHANNEL_ANY, -80, 10 ); -> volume, time in seconds
}


Hope this helped a bit



motorsep@Posted: Thu Aug 30, 2012 8:24 pm :
Imagine you are wondering around a level, nothing is going on and ambient music fills in the background. The you venture into an area where danger lurks, so ambient music fades out and "danger" music fades in and plays while you are in that area (a trigger probably would initiate it). As you go deeper, and monsters begin popping in, "danger" music fades out and "combat" music fades in and plays until either monsters are all dead or w/e (most likely have a head count in the area and have a time out for combat music so while you are not done with all of the enemies, but simply either reloading / catching breath, "combat" will fade into "danger" again, and back upon a new encounter; all that until all enemies in the danger zone are dead; then music goes back to ambient even though the player is still in the former danger zone).

Something like that is what I am after :)



Sikkpin@Posted: Thu Aug 30, 2012 9:05 pm :
You can use !enemyList.IsListEmpty() in GPL code to tell whether you are in a "danger zone" or not.



=FF=Sturm@Posted: Thu Aug 30, 2012 9:07 pm :
I remember that music code was implemented back with classic doom, Right?



motorsep@Posted: Thu Aug 30, 2012 9:20 pm :
I gotta play Classic Doom :P I don't know what it has.



Deadite4@Posted: Fri Aug 31, 2012 1:48 am :
All we had in cdoom was the ability to adjust music independently of everything else. The code actually initially came from our friends at LMS.



Tron@Posted: Fri Aug 31, 2012 9:28 am :
motorsep wrote:

Something like that is what I am after :)


Knock it up and show us how cool it can be!



Sebultura@Posted: Fri Aug 31, 2012 7:06 pm :
If it interest you, I still have the code for the Dynamic Music System I made back at the time I was working on the Requiem mod: only things is that it's for Quake 4 (not sure if it can be ported to Doom 3) and I just need to put the code out from the rest to post it here ?

Edit: it's made from the SDK.



7318@Posted: Fri Aug 31, 2012 7:56 pm :
dynamic music would be great!

i guess dynamic music could be made with some kind of AI in the player script to define the player "emotional" state, this should be doable directly form the player script.

but a dynamic music system form the c++ code should bring way more possibilities.

like emotional sates for the player affecting the gameplay. describing the perception from the pov of view of the player of it's surroundings and other dangers arround him.



motorsep@Posted: Fri Aug 31, 2012 8:00 pm :
Well, I don't see why would dynamic music required SDK code (maybe just to control its volume separately).

The rest is definitely needs to be done in scripts.



Sebultura@Posted: Fri Aug 31, 2012 10:04 pm :
You'll understand why once I'll finish the tutorial (big one :wink: ).

It will be posted in a new topic in the Quake 4 section, then I'll post a link right here once it's done.



7318@Posted: Sat Sep 01, 2012 1:13 am :
because when you use way too much threads in scripting the game can get a big hit, in the end this would be better suited to the coding.

of course this depends on the complexity of this "dynamic music", also there is the mechanism by which ths dynamic music gets riggered and changed, this mechanism could be really complex.



Sebultura@Posted: Sun Nov 25, 2012 9:28 am :
Sorry for the huge delay, but I have problems with the Q4 SDK and my current Visual Studio install: what was working well with past versions seems to be broken now :(
It seems that the precompiled header is broken, I think that the project conversion didn't gone well.

So either I find the time and figure out how to make it all work again and I put the whole changes on the forums, either by the lack of time, I'll only post new code and not the "glue" that tied it to the existing SDK :(

Edit: see the code next by BloodRayne, so I consider it's ok.

The only differences with my version was that the DMS was tied to the event system, then there was a special added trigger to handle the DMS from the map (or from the scripts is needed).



BloodRayne@Posted: Sun Nov 25, 2012 9:56 am :
In the spirit of sharing, here's the complete code for Dynamic music. I don't want to post all the loose ends of this, so I'm assuming you have knowledge on how to program the SDK. This is dynamic music as in: play track 1 when no monsters, play track 2 when monsters. For fading tracks based on triggers you don't need anything, that's regular mapping stuff and there's entities to do all that.

The 'idea':
- Service both 'normal' music (one music speaker) and dynamic music. So when the map says it wants dynamic music it will use it, otherwise it will just use one regular music channel.
- When HasEnemies() returns true, play exciting music.
- When HasEnemies() returns false, play ambient music.
- This worked like a charm. But the switches were to quick so I've added a delay as well.
- After starting combat music, don't check for 12 seconds (make sure it plays at least 12 secs).
- After starting ambient music, don't check for 24 seconds (make sure it plays at least 24 secs).

This is the 'heart' of the code, you'll need to do some stuff on your own.
Just some steps to follow:
- You'll need to make sure that there are two speakers in the world: $music_combat & $music_suspense, you can also create these dynamically in player_init() but I've opted not to do that so mappers have more control.
- This code uses a cvar called s_musicVolumeDB, create it.
- Call the code 'updateDynamicMusic' from the think() function in player.cpp.
- This code crashed at random times before, because I did not store the reference to both speakers in the savegame. I had opted first to simply make a new reference when (!music_suspense) but there were some timing issues meaning that sometimes the reference broke while the object was still made (result>crash). So make sure to save all variables in the savegame(!)
- Make sure that the 'world' has a spawnArg that says 'use_combat_music' set to 1 if you want to use the dynamic music, or take that variable out.
- For some more background info and to see the issues that I ran into while creating this you can look here: viewtopic.php?f=89&t=26032 (You can also find a scripted version of this solution there).
- Add valid declarations to player.h

player.h
Code:
   // grimm -->
   //dynamic music
   void               UpdateDynamicMusic( void );
   idEntity             *music_suspense;
   idEntity             *music_combat;
   float               old_music_volume;
   float               new_music_volume;
   bool               use_combat_music;
   bool               combat_musicon;
   float               music_waittime;


Save/restore part. Make sure to add in the right places in player.cpp {idPlayer::Save & idPlayer::Restore}
Code:

   // grimm -->  save
   savefile->WriteBool( combat_musicon );
   savefile->WriteBool( use_combat_music );
   savefile->WriteFloat( music_waittime );
   savefile->WriteObject( music_suspense );
   savefile->WriteObject( music_combat );
   // <-- grimm


   // grimm --> restore
   savefile->ReadBool( combat_musicon );
   savefile->ReadBool( use_combat_music );
   savefile->ReadFloat( music_waittime );
   savefile->ReadObject( reinterpret_cast<idClass *&>( music_suspense ) );   
   savefile->ReadObject( reinterpret_cast<idClass *&>( music_combat ) );
   // <-- grimm


In player.cpp
Code:
/* grimm -->
=================
idPlayer::UpdateDynamicMusic
=================
*/
void idPlayer::UpdateDynamicMusic( void ) {

//grimm --> this gave random crashes after loading a game so I've opted to save the reference in the savegame file.
//grimm --> I'm still hoping to re-enable this at some point, because I want to make saveGame files SMALLER, not LARGER.
//grimm --> autosave checkpoints are slow enough as it is.
   //if (!music_suspense) {
   //   music_suspense         = gameLocal.FindEntity("music_suspense");
   //   music_combat         = gameLocal.FindEntity("music_combat");
   //}

//there is either no combat music playing, or we're not using combat music at all, the music volume has changed.
//change the volume just once for the ambient channel.
   if (music_suspense) {
      new_music_volume = s_musicvolume_DB.GetFloat();
      if ( (!use_combat_music || !combat_musicon) && old_music_volume != new_music_volume ) {
         old_music_volume = new_music_volume;
         music_suspense->FadeSound( new_music_volume, 0.1f );
      }

//combat music is playing and the user has changed the volume, act on this.
      if ( combat_musicon  && old_music_volume != new_music_volume ) {
         old_music_volume = new_music_volume;
         music_combat->FadeSound( new_music_volume, 0.1f );
      }

//we're using combat music, the player has enemies, the combat music is not turned on yet and we're not waiting anymore since the last change.
//turn off the ambient music and start the combat music
      if ( use_combat_music && HasEnemies() && !combat_musicon && music_waittime < gameLocal.GetTime() ) {
         music_waittime = gameLocal.GetTime() + SEC2MS(12.0f);
         combat_musicon = true;

         music_suspense->FadeSound( -60, 3.0f );
         music_combat->FadeSound( new_music_volume, 3.0f );
      }

//we're using combat music, the player has NO enemies, the combat music is turned on we're not waiting anymore since the last change.
// turn off the combat music and start the ambient music.
      if ( use_combat_music && !HasEnemies() && combat_musicon && music_waittime < gameLocal.GetTime() ) {
         music_waittime = gameLocal.GetTime() + SEC2MS(24.0f);
         combat_musicon = false;

         music_suspense->FadeSound( new_music_volume, 3.0f );
         music_combat->FadeSound( -60, 3.0f );
      }
   }
}

//<-- grimm


You can see the code calls a 'FadeSound' routine.
I've added this routine to entity:

entity.h
Code:
   //grimm -->
   void               FadeSound( float volume, float length);
   //<-- grimm


entity.cpp
Code:
/* grimm -->
================
idEntity::FadeSound
================
*/
void idEntity::FadeSound( float volume, float length ) {
   refSound.referenceSound->FadeSound(0,volume,length);
}

//<-- grimm



motorsep@Posted: Mon Jan 21, 2013 4:18 am :
Thanks Grimm. It seems that Doom 3 doesn't have any stock function to fade sounds. Is it correct assumption?



motorsep@Posted: Thu Aug 30, 2012 6:47 pm :
I don't see any section dedicated for sound/music modding in Doom 3, so I am posting it here :)

Is there a way to make dynamic music in Doom 3? Like fading in/out a track and mixing it with another track (or rather simply overlapping tracks while fading in/out happening) via SDK code based on triggers / conditional statements ?

Thanks.



Sikkpin@Posted: Thu Aug 30, 2012 7:08 pm :
Yes.



=FF=Sturm@Posted: Thu Aug 30, 2012 7:08 pm :
Yes.



chimueloeldragon2011@Posted: Thu Aug 30, 2012 7:14 pm :
Fading sounds can be done through scripts. What exactly are you looking for?
Do you want, for example, when fighting or when in action parts set a specific music to play, and once everything is calm another more relaxing track to fade in?
Anyway, this is a cheap line of code that will allow you to fade sounds in or out (Actually you can set the volume of the fade)

Code:
void sriptname() {
      $speakername.fadeSound ( SND_CHANNEL_ANY, -80, 10 ); -> volume, time in seconds
}


Hope this helped a bit



motorsep@Posted: Thu Aug 30, 2012 8:24 pm :
Imagine you are wondering around a level, nothing is going on and ambient music fills in the background. The you venture into an area where danger lurks, so ambient music fades out and "danger" music fades in and plays while you are in that area (a trigger probably would initiate it). As you go deeper, and monsters begin popping in, "danger" music fades out and "combat" music fades in and plays until either monsters are all dead or w/e (most likely have a head count in the area and have a time out for combat music so while you are not done with all of the enemies, but simply either reloading / catching breath, "combat" will fade into "danger" again, and back upon a new encounter; all that until all enemies in the danger zone are dead; then music goes back to ambient even though the player is still in the former danger zone).

Something like that is what I am after :)



Sikkpin@Posted: Thu Aug 30, 2012 9:05 pm :
You can use !enemyList.IsListEmpty() in GPL code to tell whether you are in a "danger zone" or not.



=FF=Sturm@Posted: Thu Aug 30, 2012 9:07 pm :
I remember that music code was implemented back with classic doom, Right?



motorsep@Posted: Thu Aug 30, 2012 9:20 pm :
I gotta play Classic Doom :P I don't know what it has.



Deadite4@Posted: Fri Aug 31, 2012 1:48 am :
All we had in cdoom was the ability to adjust music independently of everything else. The code actually initially came from our friends at LMS.



Tron@Posted: Fri Aug 31, 2012 9:28 am :
motorsep wrote:

Something like that is what I am after :)


Knock it up and show us how cool it can be!



Sebultura@Posted: Fri Aug 31, 2012 7:06 pm :
If it interest you, I still have the code for the Dynamic Music System I made back at the time I was working on the Requiem mod: only things is that it's for Quake 4 (not sure if it can be ported to Doom 3) and I just need to put the code out from the rest to post it here ?

Edit: it's made from the SDK.



7318@Posted: Fri Aug 31, 2012 7:56 pm :
dynamic music would be great!

i guess dynamic music could be made with some kind of AI in the player script to define the player "emotional" state, this should be doable directly form the player script.

but a dynamic music system form the c++ code should bring way more possibilities.

like emotional sates for the player affecting the gameplay. describing the perception from the pov of view of the player of it's surroundings and other dangers arround him.



motorsep@Posted: Fri Aug 31, 2012 8:00 pm :
Well, I don't see why would dynamic music required SDK code (maybe just to control its volume separately).

The rest is definitely needs to be done in scripts.



Sebultura@Posted: Fri Aug 31, 2012 10:04 pm :
You'll understand why once I'll finish the tutorial (big one :wink: ).

It will be posted in a new topic in the Quake 4 section, then I'll post a link right here once it's done.



7318@Posted: Sat Sep 01, 2012 1:13 am :
because when you use way too much threads in scripting the game can get a big hit, in the end this would be better suited to the coding.

of course this depends on the complexity of this "dynamic music", also there is the mechanism by which ths dynamic music gets riggered and changed, this mechanism could be really complex.



Sebultura@Posted: Sun Nov 25, 2012 9:28 am :
Sorry for the huge delay, but I have problems with the Q4 SDK and my current Visual Studio install: what was working well with past versions seems to be broken now :(
It seems that the precompiled header is broken, I think that the project conversion didn't gone well.

So either I find the time and figure out how to make it all work again and I put the whole changes on the forums, either by the lack of time, I'll only post new code and not the "glue" that tied it to the existing SDK :(

Edit: see the code next by BloodRayne, so I consider it's ok.

The only differences with my version was that the DMS was tied to the event system, then there was a special added trigger to handle the DMS from the map (or from the scripts is needed).



BloodRayne@Posted: Sun Nov 25, 2012 9:56 am :
In the spirit of sharing, here's the complete code for Dynamic music. I don't want to post all the loose ends of this, so I'm assuming you have knowledge on how to program the SDK. This is dynamic music as in: play track 1 when no monsters, play track 2 when monsters. For fading tracks based on triggers you don't need anything, that's regular mapping stuff and there's entities to do all that.

The 'idea':
- Service both 'normal' music (one music speaker) and dynamic music. So when the map says it wants dynamic music it will use it, otherwise it will just use one regular music channel.
- When HasEnemies() returns true, play exciting music.
- When HasEnemies() returns false, play ambient music.
- This worked like a charm. But the switches were to quick so I've added a delay as well.
- After starting combat music, don't check for 12 seconds (make sure it plays at least 12 secs).
- After starting ambient music, don't check for 24 seconds (make sure it plays at least 24 secs).

This is the 'heart' of the code, you'll need to do some stuff on your own.
Just some steps to follow:
- You'll need to make sure that there are two speakers in the world: $music_combat & $music_suspense, you can also create these dynamically in player_init() but I've opted not to do that so mappers have more control.
- This code uses a cvar called s_musicVolumeDB, create it.
- Call the code 'updateDynamicMusic' from the think() function in player.cpp.
- This code crashed at random times before, because I did not store the reference to both speakers in the savegame. I had opted first to simply make a new reference when (!music_suspense) but there were some timing issues meaning that sometimes the reference broke while the object was still made (result>crash). So make sure to save all variables in the savegame(!)
- Make sure that the 'world' has a spawnArg that says 'use_combat_music' set to 1 if you want to use the dynamic music, or take that variable out.
- For some more background info and to see the issues that I ran into while creating this you can look here: viewtopic.php?f=89&t=26032 (You can also find a scripted version of this solution there).
- Add valid declarations to player.h

player.h
Code:
   // grimm -->
   //dynamic music
   void               UpdateDynamicMusic( void );
   idEntity             *music_suspense;
   idEntity             *music_combat;
   float               old_music_volume;
   float               new_music_volume;
   bool               use_combat_music;
   bool               combat_musicon;
   float               music_waittime;


Save/restore part. Make sure to add in the right places in player.cpp {idPlayer::Save & idPlayer::Restore}
Code:

   // grimm -->  save
   savefile->WriteBool( combat_musicon );
   savefile->WriteBool( use_combat_music );
   savefile->WriteFloat( music_waittime );
   savefile->WriteObject( music_suspense );
   savefile->WriteObject( music_combat );
   // <-- grimm


   // grimm --> restore
   savefile->ReadBool( combat_musicon );
   savefile->ReadBool( use_combat_music );
   savefile->ReadFloat( music_waittime );
   savefile->ReadObject( reinterpret_cast<idClass *&>( music_suspense ) );   
   savefile->ReadObject( reinterpret_cast<idClass *&>( music_combat ) );
   // <-- grimm


In player.cpp
Code:
/* grimm -->
=================
idPlayer::UpdateDynamicMusic
=================
*/
void idPlayer::UpdateDynamicMusic( void ) {

//grimm --> this gave random crashes after loading a game so I've opted to save the reference in the savegame file.
//grimm --> I'm still hoping to re-enable this at some point, because I want to make saveGame files SMALLER, not LARGER.
//grimm --> autosave checkpoints are slow enough as it is.
   //if (!music_suspense) {
   //   music_suspense         = gameLocal.FindEntity("music_suspense");
   //   music_combat         = gameLocal.FindEntity("music_combat");
   //}

//there is either no combat music playing, or we're not using combat music at all, the music volume has changed.
//change the volume just once for the ambient channel.
   if (music_suspense) {
      new_music_volume = s_musicvolume_DB.GetFloat();
      if ( (!use_combat_music || !combat_musicon) && old_music_volume != new_music_volume ) {
         old_music_volume = new_music_volume;
         music_suspense->FadeSound( new_music_volume, 0.1f );
      }

//combat music is playing and the user has changed the volume, act on this.
      if ( combat_musicon  && old_music_volume != new_music_volume ) {
         old_music_volume = new_music_volume;
         music_combat->FadeSound( new_music_volume, 0.1f );
      }

//we're using combat music, the player has enemies, the combat music is not turned on yet and we're not waiting anymore since the last change.
//turn off the ambient music and start the combat music
      if ( use_combat_music && HasEnemies() && !combat_musicon && music_waittime < gameLocal.GetTime() ) {
         music_waittime = gameLocal.GetTime() + SEC2MS(12.0f);
         combat_musicon = true;

         music_suspense->FadeSound( -60, 3.0f );
         music_combat->FadeSound( new_music_volume, 3.0f );
      }

//we're using combat music, the player has NO enemies, the combat music is turned on we're not waiting anymore since the last change.
// turn off the combat music and start the ambient music.
      if ( use_combat_music && !HasEnemies() && combat_musicon && music_waittime < gameLocal.GetTime() ) {
         music_waittime = gameLocal.GetTime() + SEC2MS(24.0f);
         combat_musicon = false;

         music_suspense->FadeSound( new_music_volume, 3.0f );
         music_combat->FadeSound( -60, 3.0f );
      }
   }
}

//<-- grimm


You can see the code calls a 'FadeSound' routine.
I've added this routine to entity:

entity.h
Code:
   //grimm -->
   void               FadeSound( float volume, float length);
   //<-- grimm


entity.cpp
Code:
/* grimm -->
================
idEntity::FadeSound
================
*/
void idEntity::FadeSound( float volume, float length ) {
   refSound.referenceSound->FadeSound(0,volume,length);
}

//<-- grimm



motorsep@Posted: Mon Jan 21, 2013 4:18 am :
Thanks Grimm. It seems that Doom 3 doesn't have any stock function to fade sounds. Is it correct assumption?



motorsep@Posted: Thu Aug 30, 2012 6:47 pm :
I don't see any section dedicated for sound/music modding in Doom 3, so I am posting it here :)

Is there a way to make dynamic music in Doom 3? Like fading in/out a track and mixing it with another track (or rather simply overlapping tracks while fading in/out happening) via SDK code based on triggers / conditional statements ?

Thanks.



Sikkpin@Posted: Thu Aug 30, 2012 7:08 pm :
Yes.



=FF=Sturm@Posted: Thu Aug 30, 2012 7:08 pm :
Yes.



chimueloeldragon2011@Posted: Thu Aug 30, 2012 7:14 pm :
Fading sounds can be done through scripts. What exactly are you looking for?
Do you want, for example, when fighting or when in action parts set a specific music to play, and once everything is calm another more relaxing track to fade in?
Anyway, this is a cheap line of code that will allow you to fade sounds in or out (Actually you can set the volume of the fade)

Code:
void sriptname() {
      $speakername.fadeSound ( SND_CHANNEL_ANY, -80, 10 ); -> volume, time in seconds
}


Hope this helped a bit



motorsep@Posted: Thu Aug 30, 2012 8:24 pm :
Imagine you are wondering around a level, nothing is going on and ambient music fills in the background. The you venture into an area where danger lurks, so ambient music fades out and "danger" music fades in and plays while you are in that area (a trigger probably would initiate it). As you go deeper, and monsters begin popping in, "danger" music fades out and "combat" music fades in and plays until either monsters are all dead or w/e (most likely have a head count in the area and have a time out for combat music so while you are not done with all of the enemies, but simply either reloading / catching breath, "combat" will fade into "danger" again, and back upon a new encounter; all that until all enemies in the danger zone are dead; then music goes back to ambient even though the player is still in the former danger zone).

Something like that is what I am after :)



Sikkpin@Posted: Thu Aug 30, 2012 9:05 pm :
You can use !enemyList.IsListEmpty() in GPL code to tell whether you are in a "danger zone" or not.



=FF=Sturm@Posted: Thu Aug 30, 2012 9:07 pm :
I remember that music code was implemented back with classic doom, Right?



motorsep@Posted: Thu Aug 30, 2012 9:20 pm :
I gotta play Classic Doom :P I don't know what it has.



Deadite4@Posted: Fri Aug 31, 2012 1:48 am :
All we had in cdoom was the ability to adjust music independently of everything else. The code actually initially came from our friends at LMS.



Tron@Posted: Fri Aug 31, 2012 9:28 am :
motorsep wrote:

Something like that is what I am after :)


Knock it up and show us how cool it can be!



Sebultura@Posted: Fri Aug 31, 2012 7:06 pm :
If it interest you, I still have the code for the Dynamic Music System I made back at the time I was working on the Requiem mod: only things is that it's for Quake 4 (not sure if it can be ported to Doom 3) and I just need to put the code out from the rest to post it here ?

Edit: it's made from the SDK.



7318@Posted: Fri Aug 31, 2012 7:56 pm :
dynamic music would be great!

i guess dynamic music could be made with some kind of AI in the player script to define the player "emotional" state, this should be doable directly form the player script.

but a dynamic music system form the c++ code should bring way more possibilities.

like emotional sates for the player affecting the gameplay. describing the perception from the pov of view of the player of it's surroundings and other dangers arround him.



motorsep@Posted: Fri Aug 31, 2012 8:00 pm :
Well, I don't see why would dynamic music required SDK code (maybe just to control its volume separately).

The rest is definitely needs to be done in scripts.



Sebultura@Posted: Fri Aug 31, 2012 10:04 pm :
You'll understand why once I'll finish the tutorial (big one :wink: ).

It will be posted in a new topic in the Quake 4 section, then I'll post a link right here once it's done.



7318@Posted: Sat Sep 01, 2012 1:13 am :
because when you use way too much threads in scripting the game can get a big hit, in the end this would be better suited to the coding.

of course this depends on the complexity of this "dynamic music", also there is the mechanism by which ths dynamic music gets riggered and changed, this mechanism could be really complex.



Sebultura@Posted: Sun Nov 25, 2012 9:28 am :
Sorry for the huge delay, but I have problems with the Q4 SDK and my current Visual Studio install: what was working well with past versions seems to be broken now :(
It seems that the precompiled header is broken, I think that the project conversion didn't gone well.

So either I find the time and figure out how to make it all work again and I put the whole changes on the forums, either by the lack of time, I'll only post new code and not the "glue" that tied it to the existing SDK :(

Edit: see the code next by BloodRayne, so I consider it's ok.

The only differences with my version was that the DMS was tied to the event system, then there was a special added trigger to handle the DMS from the map (or from the scripts is needed).



BloodRayne@Posted: Sun Nov 25, 2012 9:56 am :
In the spirit of sharing, here's the complete code for Dynamic music. I don't want to post all the loose ends of this, so I'm assuming you have knowledge on how to program the SDK. This is dynamic music as in: play track 1 when no monsters, play track 2 when monsters. For fading tracks based on triggers you don't need anything, that's regular mapping stuff and there's entities to do all that.

The 'idea':
- Service both 'normal' music (one music speaker) and dynamic music. So when the map says it wants dynamic music it will use it, otherwise it will just use one regular music channel.
- When HasEnemies() returns true, play exciting music.
- When HasEnemies() returns false, play ambient music.
- This worked like a charm. But the switches were to quick so I've added a delay as well.
- After starting combat music, don't check for 12 seconds (make sure it plays at least 12 secs).
- After starting ambient music, don't check for 24 seconds (make sure it plays at least 24 secs).

This is the 'heart' of the code, you'll need to do some stuff on your own.
Just some steps to follow:
- You'll need to make sure that there are two speakers in the world: $music_combat & $music_suspense, you can also create these dynamically in player_init() but I've opted not to do that so mappers have more control.
- This code uses a cvar called s_musicVolumeDB, create it.
- Call the code 'updateDynamicMusic' from the think() function in player.cpp.
- This code crashed at random times before, because I did not store the reference to both speakers in the savegame. I had opted first to simply make a new reference when (!music_suspense) but there were some timing issues meaning that sometimes the reference broke while the object was still made (result>crash). So make sure to save all variables in the savegame(!)
- Make sure that the 'world' has a spawnArg that says 'use_combat_music' set to 1 if you want to use the dynamic music, or take that variable out.
- For some more background info and to see the issues that I ran into while creating this you can look here: viewtopic.php?f=89&t=26032 (You can also find a scripted version of this solution there).
- Add valid declarations to player.h

player.h
Code:
   // grimm -->
   //dynamic music
   void               UpdateDynamicMusic( void );
   idEntity             *music_suspense;
   idEntity             *music_combat;
   float               old_music_volume;
   float               new_music_volume;
   bool               use_combat_music;
   bool               combat_musicon;
   float               music_waittime;


Save/restore part. Make sure to add in the right places in player.cpp {idPlayer::Save & idPlayer::Restore}
Code:

   // grimm -->  save
   savefile->WriteBool( combat_musicon );
   savefile->WriteBool( use_combat_music );
   savefile->WriteFloat( music_waittime );
   savefile->WriteObject( music_suspense );
   savefile->WriteObject( music_combat );
   // <-- grimm


   // grimm --> restore
   savefile->ReadBool( combat_musicon );
   savefile->ReadBool( use_combat_music );
   savefile->ReadFloat( music_waittime );
   savefile->ReadObject( reinterpret_cast<idClass *&>( music_suspense ) );   
   savefile->ReadObject( reinterpret_cast<idClass *&>( music_combat ) );
   // <-- grimm


In player.cpp
Code:
/* grimm -->
=================
idPlayer::UpdateDynamicMusic
=================
*/
void idPlayer::UpdateDynamicMusic( void ) {

//grimm --> this gave random crashes after loading a game so I've opted to save the reference in the savegame file.
//grimm --> I'm still hoping to re-enable this at some point, because I want to make saveGame files SMALLER, not LARGER.
//grimm --> autosave checkpoints are slow enough as it is.
   //if (!music_suspense) {
   //   music_suspense         = gameLocal.FindEntity("music_suspense");
   //   music_combat         = gameLocal.FindEntity("music_combat");
   //}

//there is either no combat music playing, or we're not using combat music at all, the music volume has changed.
//change the volume just once for the ambient channel.
   if (music_suspense) {
      new_music_volume = s_musicvolume_DB.GetFloat();
      if ( (!use_combat_music || !combat_musicon) && old_music_volume != new_music_volume ) {
         old_music_volume = new_music_volume;
         music_suspense->FadeSound( new_music_volume, 0.1f );
      }

//combat music is playing and the user has changed the volume, act on this.
      if ( combat_musicon  && old_music_volume != new_music_volume ) {
         old_music_volume = new_music_volume;
         music_combat->FadeSound( new_music_volume, 0.1f );
      }

//we're using combat music, the player has enemies, the combat music is not turned on yet and we're not waiting anymore since the last change.
//turn off the ambient music and start the combat music
      if ( use_combat_music && HasEnemies() && !combat_musicon && music_waittime < gameLocal.GetTime() ) {
         music_waittime = gameLocal.GetTime() + SEC2MS(12.0f);
         combat_musicon = true;

         music_suspense->FadeSound( -60, 3.0f );
         music_combat->FadeSound( new_music_volume, 3.0f );
      }

//we're using combat music, the player has NO enemies, the combat music is turned on we're not waiting anymore since the last change.
// turn off the combat music and start the ambient music.
      if ( use_combat_music && !HasEnemies() && combat_musicon && music_waittime < gameLocal.GetTime() ) {
         music_waittime = gameLocal.GetTime() + SEC2MS(24.0f);
         combat_musicon = false;

         music_suspense->FadeSound( new_music_volume, 3.0f );
         music_combat->FadeSound( -60, 3.0f );
      }
   }
}

//<-- grimm


You can see the code calls a 'FadeSound' routine.
I've added this routine to entity:

entity.h
Code:
   //grimm -->
   void               FadeSound( float volume, float length);
   //<-- grimm


entity.cpp
Code:
/* grimm -->
================
idEntity::FadeSound
================
*/
void idEntity::FadeSound( float volume, float length ) {
   refSound.referenceSound->FadeSound(0,volume,length);
}

//<-- grimm



motorsep@Posted: Mon Jan 21, 2013 4:18 am :
Thanks Grimm. It seems that Doom 3 doesn't have any stock function to fade sounds. Is it correct assumption?