comparison game/SoundElement.java @ 22:afde253ec705

More work.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 31 Jan 2011 21:28:59 +0200
parents
children 0741dc117808
comparison
equal deleted inserted replaced
21:df494a65bf8c 22:afde253ec705
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