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 }