View Javadoc

1   /*
2    * All Rights Reserved.
3    * Copyright (C) 1999-2005 Tsukuba Bunko.
4    *
5    * Licensed under the BSD License ("the License"); you may not use
6    * this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *       http://www.tsukuba-bunko.org/licenses/LICENSE.txt
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   *
17   * $Id: AudioPlayer.java,v 1.4 2005/09/04 12:36:28 ppoi Exp $
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 }