• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:2つの音のボリューム制御)

2つの音のボリューム制御

このQ&Aのポイント
  • Flashで2つの音を鳴らす方法について質問です。タイムラインとスクリプト制御で音を別々に鳴らしたいのですが、setVolumeでのボリューム制御がうまくいきません。
  • タイムライン用の音のボリュームを30に、スクリプト制御用の音のボリュームを80に設定したいのですが、最後に指定したsetVolumeのボリュームが2つの音に適用されてしまいます。
  • Flash MX 2004とWindows XPを使用しています。解決方法をご存知の方がいらっしゃいましたら、教えていただけると助かります。

質問者が選んだベストアンサー

  • ベストアンサー
  • DPE
  • ベストアンサー率85% (666/776)
回答No.2

タイムラインに挿入したサウンドの「同期」を「イベント」か「スタート」にした場合、例えば挿入したのがフレーム1であれば、フレーム1に”○○というサウンドを再生する”という命令だけが書き込まれます。 そのため、フレーム2から再生すると、再生の命令が実行されず、また、それぞれのフレームで再生すべきサウンドのデータも何もないので、音は鳴りません。 また、何らかの理由で描画が遅れたり、サウンドの読み込みが失敗・遅れた場合などは、画面と音がズレることもありえます。 しかし、サウンドを何度もループさせたり、他のフレームで再利用する場合でも、書き出すサウンドのデータは1ループ分で済み、特に、容量を小さくしなければならないネットでの公開では有利になります。 一方「ストリーミング」は、各フレームで再生するべきサウンドのデータが逐一書き出されます。 「ストリーミング」では、マシンの能力不足などの理由で描画が間に合わない時は、描画を間引いてでも、音と画面との同期を最優先にします。再生するマシンの能力がない場合は、コマ落ち・引きつり等の、いわゆる”処理落ち”が発生することがありますが、画面と音との同期は保たれます。 こんな芸当ができるのは、各フレームに、そのフレームで再生するべきサウンドのデータが全て書き込まれているおかげです。 「イベント」または「スタート」にした場合、編集画面でタイムラインの再生ヘッドを動かしても音は出ませんが、「ストリーミング」では音が出ますので、各フレームで鳴る音を確認しながらムービーを編集できます。 ただし、「ストリーミング」サウンドを繰り返しまたはループさせると、ループした分だけサウンドのデータが書き出されることになり、ファイルが大きくなります。 ファイルが大きいということは、それだけメモリを占有し、再生するマシンにも多大な負担をかけることになります。 なお、「ストリーミング」サウンドを繰り返し・ループにしていても、タイムラインには1ループ分の波形しか表示されません。 しかし、ループの場合、例えばサウンドを置いたレイヤーのフレーム10で波形が終わっていても、その先にまだフレームが存在している場合は、その分、ストリーミング再生は続行されます。 「ストリーミング」サウンドは繰り返し・ループさせないことがベストですが、どうしても繰り返さなければならない場合は、「繰り返し」を「1」にし、1ループごとにキーフレームを作り、波形を確認しながら画像を配置してはいかがでしょう。 「ストリーミング」サウンドにして、音を確認しながら画像を配置していれば、普通はズレたりはしないはずです。 しかし、フレームレートが極端に大きい・画像やサウンドデータが多く、ムービーの容量や処理が重い場合は、画面の動きが遅くなったり、画面と音がズレる・ビットマップ画像が赤い四角で表示されるといった、予期せぬ現象が起こることもあるようです。 Flash でも動画形式に書き出したり、プロジェクタ形式で書き出してCDで配布することはできますが、Flash の本業は、ネットでも公開できるアニメ・商業用コンテンツの作成です。容量の軽さと、その少ない容量の割に高度な作品を作れることをセールスポイントにしています。 本格的な動画の編集や、処理の重さとファイルの容量に糸目を付けず、とにかく質の高さを追求する作品の作成には不向きです。 容量や処理が重い場合は、  ・フレームレートを下げる(標準は 12 、多少細かい作品を作る場合でも 15 ~ 18 を限度とする)  ・ビットマップ系画像とサウンドデータを少なくする  ・ムービーを分割し、必要に応じて loadMovie などで読み込む  ・2回以上使うものはシンボルにする  ・トゥイーンを利用し、キーフレームを少なくする などで、ムービーのスリム化を図ってみてください。 タイムラインの波形と画像が合っていないことと、ムービーが重過ぎる以外の原因でズレるようでしたら、あとはちょっと心当たりがありませんが、、、

hide_momiji
質問者

お礼

ありがとうございます。 目的がCD-ROM配布で、動画もふんだんに使用している、 コンテンツで、当初は1ムービーで200MBこえていました。 しかもフレームレートが20でしたので、ずれるのは当然 ということですね。 フレームレートは落とせなかったので、loadMovieで読み 込む形で同期をとりました。 すべて解決しました。本当にありがとうございました。

その他の回答 (1)

  • DPE
  • ベストアンサー率85% (666/776)
回答No.1

同時に鳴らす2つの音を個別に制御するには、別々のムービークリップで鳴らし、それぞれを違う Sound オブジェクトで管理する必要があります。 Sound オブジェクトを生成する際、new Sound の引数にターゲット名を渡すと、そのムービークリップの音を管理するオブジェクトが生成されます。省略した場合は、ムービー全体の音を管理するオブジェクトになります。 ご質問文のスクリプトですと、snd も bgmsnd も、ともにムービー全体の音を管理するオブジェクトになっているようです。 そのため、最後に実行される _root.bgmsnd.setVolume(80); だけが有効になり、ムービー全体の音量が 80 に統一されているのだと思われます。 bgmsnd で鳴らしている音は、おそらくBGMだと思います。 これは、ダミーのムービークリップを作り、そちらで鳴らすようにしてはいかがでしょう。 ダミーのムービークリップは、ムービークリップを何か1つ、非表示にしてステージに配置しておいてもいいのですが、空のムービークリップを作る createEmptyMovieClip を使うと、タイムラインを使うことなくダミーのムービークリップを配置できます。 タイムラインのフレーム1に、次のようなスクリプトを設定してみてください。  //BGM用のダミーのムービークリップを作る  _root.createEmptyMovieClip( "bgm_clip" , 0 );  //BGM用サウンドオブジェクトの生成  bgmsnd = new Sound( bgm_clip );  //BGMの設定と再生  bgmsnd.attachSound( "bgm" );  bgmsnd.setVolume( 80 );  bgmsnd.start();  bgmsnd.onSoundComplete = function()  {   //再生終了時、自動的にループ   this.start();  }; (↑このスクリプトをコピーして利用する場合は、各行頭の全角のスペースを、全て半角のタブかスペースに置き換えてください。このまま使うとシンタックスエラーになります) createEmptyMovieClip で、” bgm_clip ”というインスタンス名を持つ、空のムービークリップを作ります。 Sound オブジェクト bgmsnd では、このムービークリップの音を制御します。 onSoundComplete はサウンドの再生終了時に発生するイベントで、イベント発生時に呼び出す関数を定義できます。 よって、onSoundComplete イベント発生時にサウンドの最初から再生するように定義しておくと、無限ループ再生になります。 タイムラインに挿入しているのは効果音で、おそらくですが、効果音の再生終了を待って次のフレームに進みたい、といった処理ではないでしょうか。 タイムラインに挿入した音は、ムービー全体の音を管理する Sound オブジェクトでなければ制御できません。となると、せっかくムービークリップを作って鳴らしているBGMも、効果音と同じボリュームに設定されてしまいます。 効果音もダミーのムービークリップで鳴らすと、BGMとは別のボリュームに設定できます。 フレーム1のスクリプトに、次のようなスクリプトを追加してください。  //効果音の再生終了フラグ  //再生終了時true、それ以外はfalse  se_flg = false;  //効果音用のダミーのムービークリップを作る  _root.createEmptyMovieClip( "se_clip" , 1 );  //効果音用サウンドオブジェクトの生成  snd = new Sound( se_clip );  //効果音の設定  snd.attachSound( "menu1" );  snd.setVolume( 30 );  snd.onSoundComplete = function()  {   //再生終了を知らせる   _root.se_flg = true;  }; BGMの時と同様に、ダミーのムービークリップを作り、これで鳴らす音を snd で管理します。 1度 attachSound で挿入したサウンドは、start メソッドで何度でも再生できます。 あとは、効果音を鳴らしたいフレームで  snd.start(); を実行すれば、効果音が鳴ります。 しかし、タイムラインの方では、効果音の再生が終わったかどうかは分かりません。 そこで、変数と先の onSoundComplete を利用して、再生終了を検出することにします。 se_flg という変数は、最初は false が入っています。効果音の再生終了後、この変数の中身は true に変わります。 タイムラインではフレーム間をループして、この変数を監視し、true になるのを待つ、つまり効果音の再生が終わるまで待ってから先に進むようにしてください。 ちなみに、attachSound と start で鳴らす音は「イベント」サウンドです。 「イベント」サウンドでは、画面との同期は保証されません。 もし、音に合わせて画面を動かしたいとのご希望でしたら、タイムラインにサウンドを挿入し、「プロパティ」の同期のリストから「ストリーミング」を選択してください。 ただし、メインのタイムラインを使って鳴らす音にすると、先述の通り、BGMと別のボリュームを設定することはできなくなります。 この場合は、メインのタイムラインに組んである内容をムービークリップにし、ムービークリップのタイムラインで「ストリーミング」サウンドを利用する、などの工夫が必要になるかと思います。 長くなってすみませんでした。 不明な点がありましたら、補足してください。

hide_momiji
質問者

補足

すばらしい回答でした。 ボリュームの問題だけでなく、 無限ループ再生の仕方まで解決しました。 start()メソッドでの無限ループはあきらめて いたので、助かりました。 >音に合わせて画面を動かしたいとのご希望でしたら、 >「プロパティ」の同期のリストから「ストリーミン >グ」を選択してください。 音の同期についても、大変参考になりました。 音の同期は、ストリーミングサウンドにする、と、 解説書にもあることですが、フレームのタイミング に関わらず、サウンドがストリーミングされて、ど んどん次へ次へと再生されてしまう、という現象に 悩まされています。 今回の質問とはずれてしまいますが、ストリーミング サウンドの扱いで、この現象を回避する方法はないの でしょうか?もしご存知であれば教えてください。