root/as2/SoundManager/src/jp/sygnas/sound/BGMManager.as

リビジョン 101, 16.2 kB (コミッタ: sygnas, コミット時期: 1 年 前)

--

Line 
1 /*
2 * Copyright 2007 dada
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*////////////////////////////////////////////////
18 * jp.sygnas.sound.BGMManager
19 *
20 * BGM管理クラス
21 *
22 * @version              0.99
23 * @author               dada
24 * @url                  http://sygnas.jp/
25 *
26 * ライブラリからの呼び出しおよび、外部MP3に対応。
27 * 外部MP3呼び出しの場合ストリーミングは行わない。
28 *
29 * ////////////////////////////////////////////////
30 * @usage
31 *       var myBGM:BGMManager = new BGMManager(this,100);
32 *       myBGM.addBGM( "bgm1","bgm1.mp3","LOAD",50 );
33 *       myBGM.fadein( "bgm1", 2 );
34 *
35 * ////////////////////////////////////////////////
36 * ■履歴
37 * 2007/11/01    ストリーミングパラメータ「_streaming:Boolean」を追加。
38 *                               ストリーミング再生時は fadein()、crossfade()をしてもフェードまでに再生が始まらない可能性があります。
39 *                               ストリーミング再生時は、ループ指定がききません。onSoundComplete を受け取って play() を実行してください。
40 *                               ストリーミング再生時は、即座にイベントonSoundPlay が呼び出されます。
41 *
42 * 2007/10/30    フェードイン時にもイベント「onSoundPlay」を発生するようにした。
43 *                               STOP時に pause() を実行すると、play() を実行するように変更。
44 *
45 *
46 * ////////////////////////////////////////////////
47 * ■イベント
48 * onSoundPlay( bgmManager:BGMManager )
49 *       再生開始した
50 *
51 * onSoundComplete( bgmManager:BGMManager )
52 *       再生完了した
53 *
54 * onSoundStop( bgmManager:BGMManager )
55 *       停止した
56 *
57 * onSoundPause( bgmManager:BGMManager, bool:Boolean )
58 *       一時停止した。「bool」は一時停止状態なら「true」、再生再開なら「false」
59 *
60 * onFadeInComp( bgmManager:BGMManager )
61 *       フェードイン完了
62 *
63 * onFadeOutComp( bgmManager:BGMManager )
64 *       フェードアウト完了
65 *
66 * onCrossFadeComp( bgmManager:BGMManager )
67 *       クロスフェード完了
68 *
69 * onVolume( bgmManager:BGMManager )
70 *       ボリュームが変わった
71 *
72 * onTitle( bgmManager:BGMManager )
73 *       再生する曲が変わった
74 *
75 * onError( bgmManager:BGMManager, msg:String )
76 *       エラー発生。メッセージは後述の「エラーについて」参照。     
77 *
78 * onEnabled( bgmManager:BGMManager, bool:Boolean )
79 *       再生の有効、無効が変わった
80 *       
81 *
82 * ////////////////////////////////////////////////
83 * ■エラーについて
84 * 再生失敗すると onError( obj:BGMManager, message:String ) を呼びます。
85 * LOAD_ERROR    外部MP3の読み込み失敗
86 * NO_ADDED              指定された識別子は登録されていない
87 *
88 */
89
90
91 import mx.utils.Delegate;
92
93 class jp.sygnas.sound.BGMManager{
94
95
96         public static var INTERVAL:Number       = 50;           // フェードアウト時の間隔(ms)
97         public static var VERSION:String        = "0.99";       // バージョン
98        
99         public var _sound1:Sound;                               // サウンドオブジェクト
100         public var _sound2:Sound;                               // サウンドオブジェクト。クロスフェード用
101         public var _loop:Number;                                // ループ回数
102         public var _streaming:Boolean;                  // ストリーミング再生をする。
103        
104         private var $bgmList:Object;                    // 曲のファイル名リスト { 識別子:{file:ファイル名, type:種別, vol:ボリューム }
105         private var $total:Number;                              // 全曲数
106         private var $nowTitle:String;                   // 現在再生している曲の識別子
107         private var $gVolume:Number;                    // 全体の音量
108         private var $interval:Number;                   // インターバルID
109         private var $mode:String;                               // モード。PLAY / STOP / FADE_IN / FADE_OUT / CROSS_FADE など
110         private var $target:MovieClip;                  // 配置する場所
111         private var $enabled:Boolean;                   // 再生が認められているか
112         private var $pausePos:Number;                   // 一時停止した時間
113         private var $targetVolume:Number;               // フェードイン時の目標音量
114         private var $fadeVolume1:Number;                // フェード中のボリューム
115         private var $fadeVolume2:Number;                // フェード中のボリューム。クロスフェード用
116         private var $fade1:Number;                              // フェードイン・アウト時の増減値
117         private var $fade2:Number;                              // フェードイン・アウト時の増減値。クロスフェード用
118
119         // イベント
120         private var $onSoundComplete:Function;  // 再生完了した
121         private var $onSoundPlay:Function;              // 再生開始した
122         private var $onSoundStop:Function;              // 停止した
123         private var $onSoundPause:Function;             // 一時停止した
124         private var $onFadeInComp:Function;             // フェードイン完了時
125         private var $onFadeOutComp:Function;    // フェードアウト完了時
126         private var $onCrossFadeComp:Function;  // フェードアウト完了時
127         private var $onVolume:Function;                 // ボリュームが変更された
128         private var $onTitle:Function;                  // 再生曲が変わった
129         private var $onError:Function;                  // 指定された曲がないなどのエラー
130         private var $onEnabled:Function;                // 有効無効切り替え時
131        
132        
133         /* /////////////////////////////////////////
134         * プロパティ
135         */
136        
137         /*
138         * 全体のボリューム
139         * 0~100の範囲で与える。
140         * 曲登録時の基準ボリュームを100として考える。
141         * 50で登録した曲を、50で再生していたら「100」を返す。
142         */
143         public function get volume():Number{ return $gVolume; }
144         public function set volume( vol:Number ){ ___setVolume( vol ); $onVolume( this ); }
145         /*
146         * 現在のモード
147         * PLAY                  再生中
148         * STOP                  停止
149         * PAUSE                 一時停止
150         * FADE_IN               フェードイン
151         * FADE_OUT              フェードアウト
152         * CROSS_FADE    クロスフェード
153         */
154         public function get mode():String{ return $mode; }
155
156         // 再生中の曲
157         public function get title():String{ return $nowTitle; }
158        
159         // 総曲数
160         public function get total():Number{ return $total; }
161
162         // 有効・無効
163         public function get enabled():Boolean{ return $enabled; }
164         public function set enabled( mode:Boolean ){ ___setEnabled( mode ); }
165
166         // イベント
167         public function set onSoundComplete( func:Function ){ $onSoundComplete = func; }
168         public function set onSoundPlay( func:Function ){ $onSoundPlay = func; }
169         public function set onSoundStop( func:Function ){ $onSoundStop = func; }
170         public function set onSoundPause( func:Function ){ $onSoundPause = func; }
171         public function set onFadeInComp( func:Function ){ $onFadeInComp = func; }
172         public function set onFadeOutComp( func:Function ){ $onFadeOutComp = func; }
173         public function set onCrossFadeComp( func:Function ){ $onCrossFadeComp = func; }
174         public function set onVolume( func:Function ){ $onVolume = func; }
175         public function set onTitle( func:Function ){ $onTitle = func; }
176         public function set onError( func:Function ){ $onError = func; }
177         public function set onEnabled( func:Function ){ $onEnabled = func; }
178
179        
180         /* /////////////////////////////////////////
181         * メソッド
182         */
183        
184         /******************************
185         * コストラクタ
186         * target        soundオブジェクトを割り当てる場所
187         * vol           スタート時のボリューム。指定がなければ「50」
188         */
189         public function BGMManager( target:MovieClip, vol:Number ){
190                 $target = target;
191                 $gVolume = vol ? vol : 50;
192
193                 $total = 0;
194                 $bgmList = new Object();
195                 $mode = "STOP";
196                 $nowTitle = "";
197                 $enabled = true;
198                 _loop = 99999;
199                 _streaming = false;
200
201                 _sound1 = ___soundInit();
202                 _sound2 = ___soundInit();
203         }
204        
205         /******************************
206         * 曲を追加
207         * name          識別子
208         * file          外部MP3ならURL、ライブラリならリンケージ名
209         * type          外部MP3なら「LOAD」、ライブラリなら「LIB」
210         * vol           基準ボリューム。指定がなければ「100」になる
211         */
212         public function addBGM( name:String, file:String, type:String, vol:Number ){
213                 $bgmList[name] = { file:file, type:type, vol:vol?vol:100 };
214                 $total ++;
215         }
216        
217         /******************************
218         * 指定された曲を再生
219         * name          識別子
220         */
221         public function play( name:String ){
222                 if( !$enabled ) return;
223                 $mode = "PLAY";
224                 ___soundReady( name );
225         }
226
227         /******************************
228         * 曲を停止
229         */
230         public function stop(){
231                 if( $mode=="STOP" ) return;
232                 clearInterval( $interval );
233                 $mode = "STOP";
234                 _sound1.stop();
235                 $onSoundStop( this );
236         }
237        
238         /******************************
239         * 曲を一時停止
240         */
241         public function pause(){
242                 if( !$enabled ) return;
243                
244                 if( $mode == "STOP" ){
245                         this.play( $nowTitle );
246                 }else{
247                         ___pause();
248                 }
249         }
250        
251         /******************************
252         * フェードイン
253         * name          曲識別子
254         * sec           フェードインにかける時間(秒)
255         */
256         public function fadein( name:String, sec:Number ){
257                 if( !$enabled ){ return; }
258                 $mode = "FADE_IN";
259                 ___fadeReady( sec, name );
260         }
261        
262         /******************************
263         * フェードアウト
264         * sec           フェードアウトにかける時間(秒)
265         */
266         public function fadeout( sec:Number ){
267                 $mode = "FADE_OUT";
268                 ___fadeReady( sec );
269         }
270
271         /******************************
272         * クロスフェード
273         * name          曲識別子
274         * sec           クロスフェードにかける時間(秒)
275         */
276         public function crossfade( name:String, sec:Number ){
277                 if( !$enabled ){ return; }
278                 $mode = "CROSS_FADE";
279                 ___fadeReady( sec, name );
280         }
281        
282         /******************************
283         * 曲単体の最大音量を変更
284         * 演奏中の音量は変わらない
285         * mame          曲識別子
286         * vol           音量(0-100)
287         */
288         public function setVolumeMax( name:String, vol:Number ){
289                 $bgmList[name]['vol'] = Math.max( 0, Math.min( vol, 100 ));
290         }
291        
292         /******************************
293         * 曲単体の最大音量を取得
294         * 演奏中の音量は変わらない
295         * mame          曲識別子
296         * vol           音量(0-100)
297         */
298         public function getVolumeMax( name:String ):Number{
299                 return $bgmList[name]['vol'];
300         }
301        
302         /******************************
303         * 破棄する
304         */
305         public function dispose(){
306                 delete _sound1;
307                 if( _sound2 ) delete _sound2;
308                 delete $bgmList;
309                 delete this;
310         }
311        
312        
313         /* /////////////////////////////////////////
314         * プライベートメソッド
315         */
316
317        
318        
319        
320         /******************************
321         * フェードインアウトの準備
322         */
323         private function ___fadeReady( sec:Number, name:String ){
324                 // 登録されていなければエラー
325                 if( $mode=="FADE_IN" || $mode=="CROSS_FADE" ){
326                         if( !___checkExists(name) ) return;
327                 }
328                
329                 clearInterval( $interval );
330                
331                 // 指定秒数かかるまでの回数と、1回あたりの調音率
332                 var titleVol:Number;
333                 var step:Number = sec * 1000 / INTERVAL;
334                 name = name ? name : $nowTitle;
335
336                 switch( mode ){
337                         case "FADE_IN":
338                                 titleVol = $bgmList[name]['vol'];
339                                 $targetVolume = ___convRealVolume(titleVol);
340                                 $fade1 = $targetVolume / step;
341                                 $fadeVolume1 = 0;
342                                 break;
343                                
344                         case "FADE_OUT":
345                                 $fade1 = _sound1.getVolume() / step * -1;
346                                 $fadeVolume1 = _sound1.getVolume();
347                                 break;
348                                
349                         case "CROSS_FADE":
350                                 // 現在再生しているものを sound2。これから再生するものを sound1 にする
351                                 var tmp:Sound = _sound2;
352                                 _sound2 = _sound1;
353                                 _sound1 = tmp;
354                                
355                                 titleVol = $bgmList[name]['vol'];
356                                 $targetVolume = ___convRealVolume(titleVol);
357                                 $fade1 = $targetVolume / step;
358                                 $fade2 = _sound2.getVolume() / step * -1;
359                                 $fadeVolume1 = 0;
360                                 $fadeVolume2 = _sound2.getVolume();
361                                 break;
362                 }
363
364                 if( $mode == "FADE_OUT" ){
365                         $interval = setInterval( this, "___fadeInOut", INTERVAL );
366                 }else{
367                         ___soundReady( name );
368                 }
369         }
370
371         /******************************
372         * 指定された曲の再生準備
373         */
374         private function ___soundReady( name:String ){
375                 // 登録されていなければエラー
376                 if( !___checkExists(name) ) return;
377                
378                 var type:String = $bgmList[name]['type'];
379                 var file:String = $bgmList[name]['file'];
380        
381                 clearInterval( $interval );
382                 $nowTitle = name;
383                 $onTitle( this );
384                
385                 if( type == "LOAD" ){
386                         // ストリーミング指定されていたらすぐ再生に
387                         _sound1.loadSound( file, _streaming );
388                         if( _streaming ) ___startSound();
389                 }else{
390                         _sound1.attachSound( file );
391                         ___startSound();
392                 }
393         }
394        
395         /******************************
396         * サウンド読み込み完了したら再生
397         */
398         private function ___loadSound( success:Boolean ){
399                 trace("___loadSound");
400                 if(success){
401                         if( !_streaming ) ___startSound();
402                 }else{
403                         $mode = "STOP";
404                         $onError( this, "LOAD_ERROR" );
405                 }
406         }
407
408         /******************************
409         * 再生開始
410         * pos           再生開始時間
411         */
412         private function ___startSound( pos:Number ){
413                 pos = pos ? pos : 0;
414                 _sound1.start(pos,_loop);
415                
416                 // フェードインが設定されている場合はインターバルでボリューム上げていく
417                 if( $mode=="FADE_IN" || $mode=="CROSS_FADE"){
418                         _sound1.setVolume(0);
419                         $interval = setInterval( this, "___fadeInOut", INTERVAL );
420                         $onSoundPlay( this );
421                 }else{
422                         ___setVolume( $gVolume );       // ボリュームを再設定
423                         $onSoundPlay( this );
424                 }
425         }
426        
427         /******************************
428         * フェードイン・アウトの調音
429         */
430         private function ___fadeInOut(){
431                 // ボリューム変更
432                 $fadeVolume1 += $fade1;
433                 $fadeVolume2 += $fade2;
434                 _sound1.setVolume( $fadeVolume1 );
435                 _sound2.setVolume( $fadeVolume2 );
436                
437                 switch( $mode ){
438                         case "FADE_IN":
439                                 if( $fadeVolume1 >= $targetVolume ){
440                                         clearInterval( $interval );
441                                         $mode = "PLAY";
442                                         _sound1.setVolume( $targetVolume );
443                                         $onFadeInComp( this );
444                                 }
445                                 break;
446                         case "FADE_OUT":
447                                 if( $fadeVolume1 <= 0 ){
448                                         clearInterval( $interval );
449                                         $mode = "STOP";
450                                         _sound1.stop();
451                                         $onFadeOutComp( this );
452                                 }
453                                 break;
454                         case "CROSS_FADE":
455                                 if( $fadeVolume1 >= $targetVolume ){
456                                         clearInterval( $interval );
457                                         $mode = "PLAY";
458                                         _sound1.setVolume( $targetVolume );
459                                         _sound2.stop();
460                                         $onCrossFadeComp( this );
461                                 }
462                                 break;
463                 }
464         }
465         /******************************
466         * 一時停止
467         */
468         private function ___pause(){
469                 clearInterval( $interval );
470                
471                 if( $mode == "PAUSE" ){
472                         $mode = "PLAY";
473                         $onSoundPause( this, false );
474                         ___startSound( $pausePos );
475                 }else{
476                         $mode = "PAUSE";
477                         $pausePos = _sound1.position /1000;     // 時間を記録しておく
478                         _sound1.stop();
479                         $onSoundPause( this, true );
480                 }
481         }
482
483         /******************************
484         * ボリューム設定
485         */
486         private function ___setVolume( vol:Number ){
487                 $gVolume = vol;
488
489                 if( vol == 0 ){
490                         _sound1.setVolume( 0 );
491                 }else if( $nowTitle ){
492                         // 再生中の曲があれば、曲の基準ボリュームから実際のボリュームを設定
493                         var titlevol:Number = $bgmList[$nowTitle]['vol'];
494                         _sound1.setVolume( ___convRealVolume(titlevol) );
495                 }
496         }
497         /******************************
498         * 実際のボリュームを計算
499         */
500         private function ___convRealVolume( titleVol:Number ):Number{
501                 return titleVol * $gVolume / 100;
502         }
503        
504         /******************************
505         * 有効無効切り替え
506         * 無効なら曲を止める
507         */
508         private function ___setEnabled( mode:Boolean ){
509                 $enabled = mode;
510                 if( !mode ) _sound1.stop();
511                 $onEnabled( this, $enabled );
512         }
513        
514         /******************************
515         * 曲が登録されているか
516         */
517         private function ___checkExists( name ){
518                 if( $bgmList[name] == undefined ){
519                         $onError( this, "NO_ADDED" );
520                         $mode = "STOP";
521                         return false;
522                 }
523                 return true;
524         }
525
526         /******************************
527         * Soundオブジェクト初期化
528         */
529         private function ___soundInit():Sound{
530                 var sound:Sound = new Sound( $target );
531                 sound.setVolume( $gVolume );
532                 sound.onSoundComplete = Delegate.create( this, ___onSoundComplete );
533                 sound.onLoad = Delegate.create( this, ___loadSound );
534                 return sound;
535         }
536
537         /******************************
538         * 再生完了
539         */
540         private function ___onSoundComplete(){
541                 $onSoundComplete( this );
542         }
543 }
544
545
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。