Making a fading MusicSystem

Hi, I have tried to create a Crossfader for my MusicSystem the whole day, but have not anytjhing acomplished.



Basically what I try to archieve



//Pseudo code

static private float fadetime = X;
static public enum type {Loading,Battle,Peace} // The type of music I want to play!

static private ArrayList<ArrayList<AudioTrack>> musiccache = new ArrayList<ArrayList<AudioTrack>>(); //The first contains with the ordinals of the enum the AudioTrack Objects coresspondenting to it. It is possible that there are none, however the ArrayList does exist for sure;

public void Play(type typ){
curtype = typ; //Files, look below for sense;
//Fade out a possible running old AudioTrack
//Get a random AudioTrack for the typ (no problems here)
//Fade the new Audiotrack in, after the old stopped Playing(Faded out)
}

//The playing Audiotrack should call Play(curtype) when the time left for playing is less than the fadetime(So that another Audiotrack of the same type can continue it's work, it might be possible that the next AudioTrack is the same as the old one)



If anyone ca point me in the right direction or has some other hints for me, it would be kinda great.

I ask just in case… sometimes people overlook the obvious - have you checked the code in the testpackage? By modifying it just a bit, I can easily get simple crossfade with:



         AudioTrack track1 = AudioSystem.getSystem().createAudioTrack(
               TestMusicQueue.class.getClassLoader().getResource(
                     "jmetest/data/sound/test.ogg"), true);
         AudioTrack track2 = AudioSystem.getSystem().createAudioTrack(
               TestMusicQueue.class.getClassLoader().getResource(
                     "jmetest/data/sound/track2.ogg"), true);
         MusicTrackQueue queue = AudioSystem.getSystem().getMusicQueue();
         queue.setCrossfadeoutTime(10);
         queue.setCrossfadeinTime(10);
         queue.setRepeatType(RepeatType.ALL);
         queue.addTrack(track1);
         queue.addTrack(track2);
         queue.play();



That code just crossfaded from one song to the next. And there are other convenience methods that you can use.. Check:


queue.fadeOutAndClear(fadeTime)
track.getCurrentTime()
track.fadeIn(time, maxVolume)
track.fadeOut(time)



Or perhaps I am not quite understanding the problem you are facing...?

Well my problem is, that the whole stuff I tried does not work as expected :confused:



This is my dirty testcode I wrote, however despite what I do, it won't work correctly



package Engine.Musicmanager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;

import com.jmex.audio.AudioSystem;
import com.jmex.audio.AudioTrack;
import com.jmex.audio.AudioTrack.TrackType;

import Engine.MassiveSpaceEngine;
import Interface.Console;
import Interface.MusicTypeConfig;
import Interface.Settings;
import Interface.util.MusicFileFilter;
public class MusicManager {
   static private AudioTrack Currentplaying;
   static private AudioTrack Nextplaying;
   static private type curtype;
   
   final private static float fadeperupd = 0.1f;
   static private ArrayList<ArrayList<AudioTrack>> musiccache = new ArrayList<ArrayList<AudioTrack>>();
   static private ArrayList<AudioTrack> toupdate = new ArrayList<AudioTrack>();
   
   static private File Musicfolder = new File(MassiveSpaceEngine.GetSettingsFolder() +"/Music/") ;
   static private Random generator = new Random();
   static public enum type {Loading,InGame}
   
   public static File GetMusicfolder(){
      return Musicfolder;
   }
   
   public static void AddFile(File file,MusicManager.type type){ //For the config Menu!
      File thistypefolder = new File(Musicfolder.getAbsoluteFile() + "/" + type.name());
      thistypefolder.mkdirs();
      File out = new File(thistypefolder.getAbsoluteFile() + "/" + file.getName());
      try {
         copyFile(file,out);
      } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }   
   }
   
   public static void copyFile(File in, File out) throws Exception {
       FileInputStream fis  = new FileInputStream(in);
       FileOutputStream fos = new FileOutputStream(out);
       try {
           byte[] buf = new byte[1024];
           int i = 0;
           while ((i = fis.read(buf)) != -1) {
               fos.write(buf, 0, i);
           }
       }
       catch (Exception e) {
           throw e;
       }
       finally {
           if (fis != null) fis.close();
           if (fos != null) fos.close();
       }
     }
   
   public static void create(){ //creates the ingame play thread!, only call after start of engine!
      //Loading all the Files!!!
      LoadMusicIntoBuffer();
   }
   
   private static void LoadMusicIntoBuffer() {
      type[] type = MusicManager.type.values();
      int index = 0;
      while (index < type.length){
         type curtype = type[index];
         LoadFolder(curtype);
         index++;
      }      
   }

   private static void LoadFolder(type curtype) {
      System.out.println("Loading " + curtype.name());
      int typeint = curtype.ordinal();
      ArrayList<AudioTrack> thistypecache = new ArrayList<AudioTrack>();
      musiccache.add(typeint, thistypecache);
      //Populate the List!
      File curfolder = new File (MusicManager.GetMusicfolder() + "/" + curtype.name());
      File[] allfiles = curfolder.listFiles();
      int fileamount = allfiles.length;
      int curentindex = 0;
      while(curentindex < fileamount){
         File currentfile = allfiles[curentindex];
         try {
            
            System.out.println(currentfile.getName());
            AudioTrack thisfile = getMusic(currentfile);
            thistypecache.add(thisfile);
         } catch (Exception e) {
            System.out.println("Deleting File " + currentfile.getAbsolutePath());
            currentfile.delete();
            e.printStackTrace();
         }
         curentindex++;
      }
      if(thistypecache.size()<1){
         try {
            throw new Exception();
         } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
         }
      }
      
   }

   private static AudioTrack getMusic(File resource) throws Exception {
        // Use streaming to save ram !.
        AudioTrack sound;
      sound = AudioSystem.getSystem().createAudioTrack(resource.toURI().toURL(), true);
      sound.setType(TrackType.MUSIC);
      sound.setRelative(true);
      sound.setLooping(false);
      toupdate.add(sound);
        return sound;
    }
   
   public static void Play(type typ){
      curtype = typ;
      //Get a track for this type!
      ArrayList<AudioTrack> possiblefiles = musiccache.get(typ.ordinal());   
      int amount = possiblefiles.size();
      int toplay = generator.nextInt(amount);
      Nextplaying = possiblefiles.get(toplay);
   }
   
   public static void Update(float updt){
      System.out.print("au");
      float targetvolume = Settings.GetSettings().getMusicvolume()/(float)100;
      ListIterator<AudioTrack> iter = toupdate.listIterator();
      while(iter.hasNext()){
         iter.next().update(20);//Running at a fixed updaterate of 50/second, when i dont call this manually they don't change their colume at all.
      }
      
      if(Currentplaying == null){
         if(Nextplaying != null){
            Currentplaying = Nextplaying;
            Currentplaying.play();
            Currentplaying.setVolume(0);
            Currentplaying.setTargetVolume(targetvolume);
            System.out.println("Initial play");
            return;
         }
         return;
      }
      //Check if the enxt file is enqued!
      if(Nextplaying != Currentplaying){
         System.out.println("Changing Track " + Currentplaying.getVolume());
         //Is the Current file Volume not 0?
         if (Currentplaying.getVolume() > 0){
            Currentplaying.setTargetVolume(0);
         }
         else{
            System.out.println("Start next Track");
            Currentplaying.stop();
            Currentplaying = Nextplaying;
            Currentplaying.setVolume(0.1f);
            Currentplaying.play();
            System.out.println("Starting play");
         }
      }
      else{
               //is out file already faded in?
         if(Currentplaying.getVolume() < targetvolume){
            System.out.println("Fadein Track" + Currentplaying.getVolume() + "- "+ Currentplaying.getCurrentTime());
            Currentplaying.setTargetVolume(targetvolume);
         }
      }
      
      //Check if currentfile reaches it's end and its nto already fading!
      if(Nextplaying == Currentplaying && Currentplaying.getCurrentTime() > Currentplaying.getTotalTime() -2f ){
         System.out.println("Reached Endof Track");
         Play(curtype);
      }
   }
}