22
|
1 /*
|
|
2 * Ristipolku Game Engine
|
|
3 * (C) Copyright 2011 Matti 'ccr' Hämäläinen <ccr@tnsp.org>
|
|
4 */
|
|
5 package game;
|
|
6
|
|
7 import java.util.*;
|
|
8 import java.io.*;
|
|
9 import game.*;
|
|
10 import javax.sound.sampled.*;
|
|
11
|
|
12
|
|
13 class SoundElement implements Runnable
|
|
14 {
|
|
15 private final String name;
|
|
16
|
|
17 private AudioInputStream stream;
|
|
18 private AudioFormat format;
|
|
19 private SourceDataLine line;
|
|
20 private Thread playThread;
|
|
21 private int loopCount;
|
|
22 private boolean playing, streaming;
|
|
23 private int volume = 100;
|
|
24
|
|
25 byte[] buffer;
|
|
26 int length;
|
|
27
|
|
28
|
|
29 SoundElement(String filename, boolean streaming) throws IOException
|
|
30 {
|
|
31 this.name = filename;
|
|
32 this.streaming = streaming;
|
|
33
|
|
34 ResourceLoader res = new ResourceLoader(name);
|
|
35 if (res == null || res.getStream() == null)
|
|
36 {
|
|
37 throw new IOException("Could not load audio resource '"+name+"'.\n");
|
|
38 }
|
|
39
|
|
40
|
|
41 try {
|
|
42 stream = AudioSystem.getAudioInputStream(res.getStream());
|
|
43 format = stream.getFormat();
|
|
44 }
|
|
45 catch (UnsupportedAudioFileException e) {
|
|
46 throw new IOException("Unsupported audio file format for '"+name+"'.\n");
|
|
47 }
|
|
48 catch (IOException e)
|
|
49 {
|
|
50 throw new IOException("Could not load audio resource '"+name+"'.\n");
|
|
51 }
|
|
52
|
|
53
|
|
54 if (streaming) {
|
|
55 System.out.print("Loading '"+name+"' as a clip\n");
|
|
56 try {
|
|
57 clip = AudioSystem.getClip();
|
|
58 clip.open(stream);
|
|
59 }
|
|
60 catch (LineUnavailableException e)
|
|
61 {
|
|
62 throw new IOException("Line unavailable for '"+name+"'.\n");
|
|
63 }
|
|
64 finally {
|
|
65 stream.close();
|
|
66 }
|
|
67 }
|
|
68 else
|
|
69 {
|
|
70 clip = null;
|
|
71 System.out.print("Loading '"+name+"' as stream\n");
|
|
72
|
|
73 try {
|
|
74 SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
|
|
75 System.out.print("info: "+stream.getFrameLength() + ", " + format.getFrameSize() + "\n");
|
|
76 line = (SourceDataLine) AudioSystem.getLine(info);
|
|
77 line.open(format);
|
|
78 }
|
|
79 catch (LineUnavailableException e) {
|
|
80 throw new IOException("Line unavailable for '"+name+"'.\n");
|
|
81 }
|
|
82 }
|
|
83 }
|
|
84
|
|
85 public void play()
|
|
86 {
|
|
87 System.out.print("Sound("+name+").play()\n");
|
|
88 if (streaming)
|
|
89 {
|
|
90 clip.setFramePosition(0);
|
|
91 clip.start();
|
|
92 }
|
|
93 else
|
|
94 {
|
|
95 if (playThread == null)
|
|
96 {
|
|
97 doPlay = true;
|
|
98 loopCount = 1;
|
|
99 playThread = new Thread(this);
|
|
100 playThread.start();
|
|
101 }
|
|
102 }
|
|
103 }
|
|
104
|
|
105 public void loop(int n)
|
|
106 {
|
|
107 System.out.print("Sound("+name+").loop("+n+")\n");
|
|
108 if (isClip())
|
|
109 {
|
|
110 clip.setFramePosition(0);
|
|
111 if (n < 0)
|
|
112 clip.loop(Clip.LOOP_CONTINUOUSLY);
|
|
113 else
|
|
114 clip.loop(n);
|
|
115 }
|
|
116 else
|
|
117 {
|
|
118 if (playThread == null)
|
|
119 {
|
|
120 doPlay = true;
|
|
121 loopCount = n;
|
|
122 playThread = new Thread(this);
|
|
123 playThread.start();
|
|
124 }
|
|
125 }
|
|
126 }
|
|
127
|
|
128 public void stop()
|
|
129 {
|
|
130 if (isClip())
|
|
131 {
|
|
132 if (clip.isRunning())
|
|
133 clip.stop();
|
|
134 }
|
|
135 else
|
|
136 {
|
|
137 if (playThread != null)
|
|
138 {
|
|
139 playThread.interrupt();
|
|
140 doPlay = false;
|
|
141 playThread = null;
|
|
142 }
|
|
143 }
|
|
144 }
|
|
145
|
|
146 public boolean isPlaying()
|
|
147 {
|
|
148 if (isClip())
|
|
149 return clip.isRunning();
|
|
150 else
|
|
151 return (playThread != null && line.isRunning());
|
|
152 }
|
|
153
|
|
154 public void run()
|
|
155 {
|
|
156 line.start();
|
|
157 byte[] buf = new byte[line.getBufferSize()];
|
|
158
|
|
159 while (doPlay && (loopCount > 0 || loopCount == -1))
|
|
160 {
|
|
161 try {
|
|
162 int numRead = 0;
|
|
163 while ((numRead = stream.read(buf, 0, buf.length)) >= 0 && doPlay)
|
|
164 {
|
|
165 int offset = 0;
|
|
166 while (offset < numRead)
|
|
167 {
|
|
168 System.out.print("audioThread: offs="+offset+", numread="+numRead+"\n");
|
|
169 offset += line.write(buf, offset, numRead - offset);
|
|
170 }
|
|
171 }
|
|
172 line.drain();
|
|
173
|
|
174 System.out.print("audioThread: stream.reset()\n");
|
|
175 stream.reset();
|
|
176 }
|
|
177 catch (IOException e) {
|
|
178 }
|
|
179
|
|
180 if (loopCount > 0)
|
|
181 loopCount--;
|
|
182 }
|
|
183
|
|
184 line.stop();
|
|
185 doPlay = false;
|
|
186 }
|
|
187 }
|
|
188
|
|
189
|