1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package tsukuba_bunko.peko.canvas.stage;
20
21 import java.io.Serializable;
22
23 import java.net.URL;
24
25 import java.util.Map;
26
27 import tsukuba_bunko.peko.Logger;
28
29 import tsukuba_bunko.peko.resource.ResourceManager;
30
31 import tsukuba_bunko.peko.canvas.stage.audio.SampledAudioClip;
32
33
34 /***
35 * 音楽クリップの再生を行います。
36 * @author $Author: ppoi $
37 * @version $Revision: 1.4 $ $Date: 2005/09/04 12:36:28 $
38 */
39 public class AudioPlayer implements Serializable {
40
41 /***
42 * serial version UID
43 */
44 private static final long serialVersionUID = 7799979848147586424L;
45
46
47 /***
48 * 停止モード:即停止
49 */
50 public static final int STOP_IMMEDIATELY = 0;
51
52 /***
53 * 停止モード:フェードアウト(同期)
54 */
55 public static final int STOP_WITH_SYNC_FADEOUT = 1;
56
57 /***
58 * 停止モード:フェードアウト(非同期)
59 */
60 public static final int STOP_WITH_ASYNC_FADEOUT = 2;
61
62
63 /***
64 * クリップマップ
65 */
66 transient private Map _clips = new java.util.HashMap( 17 );
67
68 /***
69 * BGM registry
70 */
71 private Map _bgmRegistry = new java.util.HashMap( 17 );
72
73 /***
74 * SE registry
75 */
76 private Map _seRegistry = new java.util.HashMap( 17 );
77
78
79 /***
80 * <code>AudioPlayer</code> のインスタンスを作成します。
81 */
82 public AudioPlayer()
83 {
84 super();
85 }
86
87
88 /***
89 * BGM を再生します。
90 * @param id BGM ID
91 * @param clipName クリップ名
92 * @param loop ループ再生する場合 <code>true</code>、しない場合 <code>false</code>
93 */
94 public void playBGM( String id, String clipName, boolean loop )
95 {
96 ResourceManager resources = ResourceManager.getInstance();
97 try {
98 if( _clips.containsKey(id) ) {
99 Logger.error( "[canvas.stage] specified bgm clip id was already used. :" + id );
100 return;
101 }
102 _bgmRegistry.put( id, new Object[]{clipName, (loop?Boolean.TRUE:Boolean.FALSE)} );
103 URL clipURL = new URL( resources.getLocationResources().getSoundsDirecotryURL(), clipName );
104 playClip( id, clipURL, loop );
105 }
106 catch( Exception e ) {
107 Logger.error( "[canvas.stage] fail to play bgm :" + clipName, e );
108 }
109 }
110
111 /***
112 * SE(Sound Effect) を再生します。
113 * @param id BGM ID
114 * @param clipName クリップ名
115 * @param loop ループ再生する場合 <code>true</code>、しない場合 <code>false</code>
116 */
117 public void playSE( String id, String clipName, boolean loop )
118 {
119 ResourceManager resources = ResourceManager.getInstance();
120 try {
121 if( _seRegistry.containsKey(id) ) {
122 Object[] info = (Object[])_seRegistry.get( id );
123 if( info[1] == Boolean.FALSE ) {
124 stop( id, AudioPlayer.STOP_IMMEDIATELY );
125 }
126 else {
127 Logger.error( "[canvas.stage] specified se clip id was already used. :" + id );
128 return;
129 }
130 }
131 _seRegistry.put( id, new Object[]{clipName, (loop?Boolean.TRUE:Boolean.FALSE)} );
132 URL clipURL = new URL( resources.getLocationResources().getSoundsDirecotryURL(), clipName );
133 playClip( id, clipURL, loop );
134 }
135 catch( Exception e ) {
136 Logger.error( "[canvas.stage] fail to play bgm :" + clipName, e );
137 }
138 }
139
140 /***
141 * クリップを再生します。
142 * @param id クリップ ID
143 * @param clipURL クリップの URL
144 * @param loop ループ再生する場合 <code>true</code>、しない場合 <code>false</code>
145 */
146 protected void playClip( String id, URL clipURL, boolean loop )
147 {
148 try {
149 AudioClip clip = getAudioClip( id, clipURL );
150 if( clip != null ) {
151 register( clip );
152 clip.play( loop );
153 }
154 }
155 catch( Exception e ) {
156 Logger.error( "[canvas.stage] fail to play clip. :" + clipURL, e );
157 }
158 }
159
160 /***
161 * クリップを登録します。
162 * @param clip 登録するクリップ
163 */
164 protected void register( AudioClip clip )
165 {
166 clip.setAudioPlayer( this );
167 _clips.put( clip.getID(), clip );
168 Logger.debug( "[canvas.stage] registered clip :" + clip.getID() );
169 }
170
171 /***
172 * クリップの登録を解除します。
173 * @param clip 登録解除するクリップ
174 */
175 protected void unregister( AudioClip clip )
176 {
177 _clips.remove( clip.getID() );
178 _bgmRegistry.remove( clip.getID() );
179 _seRegistry.remove( clip.getID() );
180 Logger.debug( "[canvas.stage] unregistered clip :" + clip.getID() );
181 }
182
183 /***
184 * 指定されたクリップの再生を停止します。
185 * @param id クリップ ID
186 */
187 public void stop( String id )
188 {
189 stop( id, AudioPlayer.STOP_WITH_ASYNC_FADEOUT );
190 }
191
192 /***
193 * 指定されたクリップの再生を停止します。
194 * @param id クリップ ID
195 * @param mode 停止モード
196 */
197 public void stop( String id, int mode )
198 {
199 AudioClip clip = (AudioClip)_clips.get( id );
200 if( clip != null ) {
201 clip.stop( mode );
202 }
203 }
204
205 /***
206 * 全クリップの再生を停止します。
207 */
208 public void stopAll()
209 {
210 AudioClip[] clips = (AudioClip[])_clips.values().toArray( new AudioClip[_clips.size()] );
211 for( int i = 0; i < clips.length; ++i ) {
212 clips[i].stop();
213 }
214 }
215
216 /***
217 * クリップを再生する AudioClip のインスタンスを作成します。
218 * @param id クリップ ID
219 * @param clipURL クリップの URL
220 */
221 protected AudioClip getAudioClip( String id, URL clipURL )
222 {
223 String clipName = clipURL.getFile().toLowerCase();
224 if( clipName.endsWith(".mid") || clipName.equals(".smf") ) {
225 Logger.error( "[canvas.stage] unsupported format :" + clipURL );
226 return null;
227 }
228 else if( clipName.endsWith( "mp3") || clipName.endsWith(".wav") || clipName.endsWith(".au") ) {
229 return new SampledAudioClip( id, clipURL );
230 }
231 else {
232 Logger.error( "[canvas.stage] unsupported format :" + clipURL );
233 return null;
234 }
235 }
236
237
238 /***
239 * 再生の準備を実行します。
240 */
241 public void prepare()
242 {
243 if( _clips == null ) {
244 Logger.debug( "[cavnas.stage] initialize clips." );
245 _clips = new java.util.HashMap( 17 );
246 }
247
248 String[] id = null;
249 Object[] clip = null;
250
251 Map registry = _bgmRegistry;
252 if( registry.size() > 0 ) {
253 id = (String[])registry.keySet().toArray( new String[registry.size()] );
254 for( int i = 0; i < id.length; ++i ) {
255 clip = (Object[])registry.get( id[i] );
256 playBGM( id[i], (String)clip[0], ((Boolean)clip[1]).booleanValue() );
257 }
258 }
259
260 registry = _seRegistry;
261 if( registry.size() > 0 ) {
262 id = (String[])registry.keySet().toArray( new String[registry.size()] );
263 for( int i = 0; i < id.length; ++i ) {
264 clip = (Object[])registry.get( id[i] );
265 playSE( id[i], (String)clip[0], ((Boolean)clip[1]).booleanValue() );
266 }
267 }
268 }
269 }