View Javadoc

1   package de.jos.game.music;
2   
3   import ibxm.FastTracker2;
4   import ibxm.IBXM;
5   import ibxm.Module;
6   import ibxm.ProTracker;
7   import ibxm.ScreamTracker3;
8   
9   import java.io.DataInputStream;
10  import java.io.IOException;
11  import java.io.InputStream;
12  
13  import javax.sound.sampled.AudioFormat;
14  import javax.sound.sampled.AudioSystem;
15  import javax.sound.sampled.LineEvent;
16  import javax.sound.sampled.LineListener;
17  import javax.sound.sampled.LineUnavailableException;
18  import javax.sound.sampled.SourceDataLine;
19  
20  /***
21   * 
22   * @author root
23   * 
24   */
25  public class Player implements LineListener {
26  
27    private Module module = null;
28  
29    private BackgroundMusicThread thread = null;
30  
31    public void initPlayer(String fileName) {
32      ClassLoader cl = Player.class.getClassLoader();
33      InputStream inputStream = cl.getResourceAsStream(fileName);
34      DataInputStream dataInputStream = new DataInputStream(inputStream);
35  
36      byte[] s3m_header, mod_header;
37      byte[] xm_header = new byte[60];
38  
39      try {
40        dataInputStream.readFully(xm_header);
41        if (FastTracker2.is_xm(xm_header)) {
42          module = FastTracker2.load_xm(xm_header, dataInputStream);
43        } else {
44          s3m_header = new byte[96];
45          System.arraycopy(xm_header, 0, s3m_header, 0, 60);
46          dataInputStream.readFully(s3m_header, 60, 36);
47          if (ScreamTracker3.is_s3m(s3m_header)) {
48            module = ScreamTracker3.load_s3m(s3m_header, dataInputStream);
49          } else {
50            mod_header = new byte[1084];
51            System.arraycopy(s3m_header, 0, mod_header, 0, 96);
52            dataInputStream.readFully(mod_header, 96, 988);
53            module = ProTracker.load_mod(mod_header, dataInputStream);
54          }
55        }
56        dataInputStream.close();
57      } catch (IOException e) {
58        // TODO Auto-generated catch block
59        e.printStackTrace();
60      }
61    }
62  
63    public void playMusic() {
64      if (thread == null) {
65        thread = new BackgroundMusicThread(module, this);
66        thread.start();
67      }
68    }
69  
70    public void stopMusic() {
71      if (thread != null) {
72        System.out.println("Stopping musing in player");
73        thread.setStopThreadFlag(true);
74      }
75    }
76  
77    /***
78     * Notify the Player when the tune is over !
79     */
80    public void update(LineEvent event) {
81      System.out.println(event.getType());
82      System.out.println(event.getLine());
83    }
84  
85    static final class BackgroundMusicThread extends Thread {
86  
87      private Module module = null;
88  
89      private boolean stopThreadFlag = false;
90      
91      private LineListener listener = null;
92  
93      public BackgroundMusicThread(Module module, LineListener listener) {
94        this.module = module;
95        this.listener = listener;
96      }
97  
98      public void run() {
99        IBXM ibxm = new IBXM(48000);
100       byte[] outputBuffer = null;
101       ibxm.set_module(module);
102       int songDuration = ibxm.calculate_song_duration();
103       AudioFormat outputFormat = new AudioFormat(48000, 16, 2, true, false);
104       SourceDataLine outputLine = null;
105 
106       try {
107         outputLine = AudioSystem.getSourceDataLine(outputFormat);
108         outputBuffer = new byte[1024 * 4];
109         outputLine.open();
110       } catch (LineUnavailableException e) {
111         e.printStackTrace();
112         return;
113       }
114 
115       outputLine.start();
116       outputLine.addLineListener(listener);
117 
118       int frames = 0;
119       while (songDuration > 0 && stopThreadFlag == false) {
120         frames = 1024;
121         if (frames > songDuration) {
122           frames = songDuration;
123         }
124         ibxm.get_audio(outputBuffer, frames);
125         outputLine.write(outputBuffer, 0, frames * 4);
126         songDuration -= frames;
127       }
128       outputLine.drain();
129       outputLine.close();
130       
131       outputLine.removeLineListener(listener);
132     }
133 
134     public void setStopThreadFlag(boolean stopThreadFlag) {
135       this.stopThreadFlag = stopThreadFlag;
136     }
137 
138   }
139 
140 }