トップページ > 過去ログ > 記事閲覧
音楽再生周りの挙動について
名前:DG 日時: 2010/04/10 10:24

お世話になってます。 音楽再生周りの挙動が想定通りに行かなかったので ちょっとテストしてみたところ、 以下のような挙動を確認しましたので報告します。 ちょっと長いですが・・・ DXライブラリバージョン 3.02b OS:WindowsXP SP3 ●テスト1 テストに使用した音声ファイル 煉獄庭園様 ttp://www.rengoku-teien.com/rengoku_mp3/polp.mp3 (再生時間189秒 44100Hz stereo) 【SetSoundCurrentTime、SetCurrentPositionSoundMem、SetSoundCurrentPositionについて】 (1)再生位置を0秒〜21秒までにした場合  ・再生位置は正常に設定される  ・GetSoundCurrentTime、GetCurrentPositionSoundMem、GetSoundCurrentPositionで取得した値が   6秒先の値にずれることがある。   指定した開始位置の秒数によって、頻繁に起きたり、あまり起きなかったりする。  ・上記のズレが発生した場合、音声ファイルを最後まで再生したとき   GetSoundCurrentTimeは最大再生時間までくると、実際の再生が終わってなくても止まるが   GetCurrentPositionSoundMem、GetSoundCurrentPositionは実際の再生が終わるまでカウントし続ける   (同じ用途の関数の挙動が一致しない) (2)再生位置を22秒以降にした場合  ・指定した再生位置が設定されない(PlaySoundMemの第3引数がfalseなら前回停止位置から再生される) 以下の3つのロードタイプ全てで、上記挙動を確認しました  DX_SOUNDDATATYPE_MEMPRESS  DX_SOUNDDATATYPE_MEMNOPRESS  DX_SOUNDDATATYPE_FILE ●テスト2 テストに使用した音声ファイル ザ・マッチメイカァズ様 ttp://osabisi.sakura.ne.jp/m2/tm4/se/tm2_traffic001.wav (再生時間15秒 44100Hz stereo) を、ビットレード256(CBR)でmp3にエンコードしたもの 上記ファイルだと、別の挙動が確認出来ました(再生時間が関係?別の35秒ほどのmp3ファイルでも確認) (1)DX_SOUNDDATATYPE_MEMNOPRESS の場合  ・再生回数が3の倍数の時のみ、GetCurrentPositionSoundMem、GetSoundCurrentPositionが正常に動く  ・SetCurrentPositionSoundMem、SetSoundCurrentPositionも同様に3の倍数回目の再生開始で正常に動作する  ・SetSoundCurrentTime、GetSoundCurrentTimeは正常に動作  ・テスト1のような、ずれの発生は確認できなかった  ・テスト1のような、再生位置が指定できない値は無かった。指定した位置に再生位置が移動した   (ただし、最大再生時間を越えるを指定すると、前回停止位置からの再生) (2)DX_SOUNDDATATYPE_MEMPRESS、DX_SOUNDDATATYPE_FILE の場合  ・テスト1と同じ挙動(ただし、再生開始時間指定が有効なのは0〜2秒) ●上記テストに付随して発生したエラー (1)ファイルを最後まで再生させ、自然に止まらせる。 (2)再生位置を再生時間より大きい数値にして再生実行 (3)ProcessMessage()でエラー発生。異常終了 ※ただし、テスト2(1)の場合は最後まで再生した時、再生位置が0にリセットされるので  上記のエラーは発生しない。

Page: 1 |

Re: 音楽再生周りの挙動について ( No.1 )
名前:DG 日時:2010/04/10 10:30

以下、テストで使ったソースです。 ↑↓キーで再生開始位置の移動 Pキーで再生・停止です。 #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode(TRUE); /* ウィンドウモード */ if( DxLib_Init() == -1 ) return -1; // エラーが起きたら直ちに終了 if( SetDrawScreen( DX_SCREEN_BACK ) != 0 ) return -1; /* 裏画面化 */ SetCreateSoundDataType( DX_SOUNDDATATYPE_MEMPRESS ); // SetCreateSoundDataType( DX_SOUNDDATATYPE_MEMNOPRESS ); // SetCreateSoundDataType( DX_SOUNDDATATYPE_FILE ); // int bgm_handle = LoadSoundMem( "./data/polp.mp3" ); // int bgm_handle = LoadSoundMem( "./data/polp.wav" ); // int bgm_handle = LoadSoundMem( "./data/tm2_traffic001.wav" ); int bgm_handle = LoadSoundMem( "./data/tm2_traffic001.mp3" ); int hit_p = 0; int second = 0; int bgm_pos = 0; while( true ){ if( ProcessMessage() ) break; /* メッセージ処理 */ if( ClearDrawScreen() ) break; /* 画面をクリア */ if( CheckHitKey(KEY_INPUT_ESCAPE) ) break; /* ESCで終了 */ if( CheckHitKey(KEY_INPUT_P) ){ hit_p++; }else{ hit_p = 0; } if( CheckHitKey(KEY_INPUT_UP) ) second += 1; if( CheckHitKey(KEY_INPUT_DOWN) ) second -= (second==0)?(0):(1); if( hit_p == 1 ){ if( CheckSoundMem( bgm_handle ) == 1 ){ StopSoundMem( bgm_handle ); } else if( CheckSoundMem( bgm_handle ) == 0 ){ bgm_pos = (second*1000); // BGMの現在の位置を設定(ミリ秒) // bgm_pos = (second*44100); // BGMの現在の位置を設定(サンプル数) // bgm_pos = (second*44100*4); // BGMの現在の位置を設定(バイト数) SetSoundCurrentTime( bgm_pos, bgm_handle ); // BGMの現在位置をセット(ミリ秒) // SetCurrentPositionSoundMem( bgm_pos, bgm_handle ); // BGMの現在位置をセット(サンプル数) // SetSoundCurrentPosition( bgm_pos, bgm_handle ); // BGMの現在位置をセット(バイト数) PlaySoundMem( bgm_handle, DX_PLAYTYPE_BACK, false ); } else { printfDx( "BGM ERROR\n" ); } } DrawFormatString( 0, 0, 0x00FFFFFF, "GetCurrentPositionSoundMem:%d" , GetCurrentPositionSoundMem(bgm_handle) ); /* サンプル数で位置を表示 */ DrawFormatString( 0, 20, 0x00FFFFFF, "GetSoundCurrentPosition :%d" , GetSoundCurrentPosition(bgm_handle)); /* バイト数で位置を表示 */ DrawFormatString( 0, 40, 0x00FFFFFF, "GetSoundCurrentTime :%d" , GetSoundCurrentTime(bgm_handle)); /* ミリ秒で位置を表示 */ DrawFormatString( 0, 60, 0x00FFFFFF, "CheckSoundMem:%d", CheckSoundMem( bgm_handle ) ); /* 再生状態 */ DrawFormatString( 0, 80, 0x00FFFFFF, "SECOND:%d", second ); /* 設定秒数 */ ScreenFlip(); } DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 }
Re: 音楽再生周りの挙動について ( No.2 )
名前:sy(サイ) 日時:2010/04/10 11:03

mp3形式では仕方ないです。oggなら動作が約束されます。
Re: 音楽再生周りの挙動について ( No.3 )
名前:DG 日時:2010/04/10 15:58

syさんのレスを受けて、oggでもテストしてみましたが ほぼ、mp3の場合と同様の挙動をしました。 違ったところは、「テスト1(2)」のように再生位置の上限がなく 任意の指定位置に移動することが出来た点です。 ただ、Getの数値のズレ、3回に1回だけGetやSetが成功するなどの 挙動は変わりませんでした。 wavについてもざっとテストしましたが、 こちらは全て想定内の正常動作をしてくれました。 私の環境に依存してるんでしょうか・・・。 oggのデータは ttp://music.edolfzoku.com/free01.ogg を使用させていただきました。
Re: 音楽再生周りの挙動について ( No.4 )
名前:管理人 日時:2010/04/19 00:57

詳細な不具合のご報告ありがとうございます > ●テスト1 > (2)再生位置を22秒以降にした場合 > > ●上記テストに付随して発生したエラー を私の環境でも確認することができました、他のエラーは直接確認することはできませんでしたが、 上記エラーの原因にその他のエラーが発生する要因となりそうな点がありましたので、 直っている可能性が高いと思います よろしければこちらの修正バージョンをお試しになってみてください m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
Re: 音楽再生周りの挙動について ( No.5 )
名前:DG 日時:2010/04/20 19:39

お忙しい中、対応ありがとうございますm(_ _)m 早速、修正バージョンをDLして 同じテストファイル、コードで再テストしましたところ いくつかまだ想定外の動作がありましたのでご報告します。 @ttp://www.rengoku-teien.com/rengoku_mp3/polp.mp3  DX_SOUNDDATATYPE_MEMNOPRESS  DX_SOUNDDATATYPE_MEMPRESS  DX_SOUNDDATATYPE_FILE   全てで想定通りの動作を確認しました。 Attp://osabisi.sakura.ne.jp/m2/tm4/se/tm2_traffic001.wav  DX_SOUNDDATATYPE_MEMNOPRESS   サンプル数・バイト数指定時に以下の想定外の挙動    ・3の倍数回目の再生位置指定のみ有効になる  DX_SOUNDDATATYPE_MEMPRESS  DX_SOUNDDATATYPE_FILE   全てで想定内の動作を確認しました。 BAのwavを256kbps(CBR)でmp3(Lame)にエンコードしたもの  Aと同様の結果(polp.mp3をwavにしたものではこの挙動はないので再生時間に依存??) Cttp://music.edolfzoku.com/free01.ogg  DX_SOUNDDATATYPE_MEMNOPRESS   AのDX_SOUNDDATATYPE_MEMNOPRESSと同様の挙動  DX_SOUNDDATATYPE_MEMPRESS  DX_SOUNDDATATYPE_FILE   31秒未満の音声ファイルだが31秒指定時に再生位置指定が有効になる模様(32秒以上だと大丈夫)   ミリ秒のGet値は31557で止まるが、サンプル数、バイト数はカウントされ続ける   再生位置自体は実際には設定されておらず、前回停止位置からの模様 あと、今回のテストでいくつか気になった挙動がありましたので そちらもご報告します。 1.時々、再生終端に来た時サンプル数・バイト数より、ミリ秒取得の表示の方がわずかに早く止まる  (取得した再生位置が0.2秒程ミリ秒の方が進んで表示される。終端辺りに再生位置を指定したときに起こり易い?) 2.mp3の再生位置が1分を超えた辺りから、停止→再生にタイムラグがある(3分当たりだと1秒くらいでした)  wavではこの現象は起こりませんでした。 以上です。
Re: 音楽再生周りの挙動について ( No.6 )
名前:管理人 日時:2010/04/25 23:51

ご報告ありがとうございます 修正したバージョンをアップしましたので、よろしければお試し下さい m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい) > Attp://osabisi.sakura.ne.jp/m2/tm4/se/tm2_traffic001.wav >  DX_SOUNDDATATYPE_MEMNOPRESS >   サンプル数・バイト数指定時に以下の想定外の挙動 >    ・3の倍数回目の再生位置指定のみ有効になる > Cttp://music.edolfzoku.com/free01.ogg >  DX_SOUNDDATATYPE_MEMNOPRESS >   AのDX_SOUNDDATATYPE_MEMNOPRESSと同様の挙動  すいません、前回直したバグと同タイプのバグがまだ残っていました 修正しました m(_ _;m > BAのwavを256kbps(CBR)でmp3(Lame)にエンコードしたもの >  Aと同様の結果(polp.mp3をwavにしたものではこの挙動はないので再生時間に依存??)  こちらは DX_SOUNDDATATYPE_MEMNOPRESS の指定で読み込んでも読み込んだサウンドデータが 大きいと自動的に DX_SOUNDDATATYPE_MEMPRESS と同じ処理をする、という仕様が原因で polp.mp3 を wav にしたものだけ DX_SOUNDDATATYPE_MEMPRESS と同じ処理が行われたために バグが発生しなかったということで、上記バグと原因は同じでした > Cttp://music.edolfzoku.com/free01.ogg >  DX_SOUNDDATATYPE_MEMPRESS >  DX_SOUNDDATATYPE_FILE >   31秒未満の音声ファイルだが31秒指定時に再生位置指定が有効になる模様(32秒以上だと大丈夫) >   ミリ秒のGet値は31557で止まるが、サンプル数、バイト数はカウントされ続ける >   再生位置自体は実際には設定されておらず、前回停止位置からの模様  確認しました、ご報告ありがとうございます 修正しました > 1.時々、再生終端に来た時サンプル数・バイト数より、ミリ秒取得の表示の方がわずかに早く止まる >  (取得した再生位置が0.2秒程ミリ秒の方が進んで表示される。終端辺りに再生位置を指定したときに起こり易い?)  確認はできませんでしたが、ミリ秒で取得する関数だけ得られた現在時間と「読み込み時に取得した サウンドデータの総時間」を比較して、前者の方が後者の値より大きくなっていたら後者の値を戻り値とする、 という処理が加わっているのが原因だと思います  原因は分からないのですが、MP3やOGGはそれぞれのデコード機能の「総時間を取得する」という 関数で得られる値と、実際にデコードしたときに得られる生PCMデータの総時間に違いがあることがあります 他の時間取得関数はそのままデコードして得られた再生時間を返しますが、ミリ秒で時間を取得する関数だけ 「総時間を取得する」機能で得られた値でクランプしています  因みにデコーダの「総時間を取得する」という機能を使わずに、実際に全データをデコードをすれば正しい 総時間が得られるので読み込み時に圧縮データを一通りデコードしてしまえば正しい総時間を得ることができますが、 そうすると DX_SOUNDDATATYPE_MEMPRESS を指定しても DX_SOUNDDATATYPE_MEMNOPRESS 並に読込時間が 長くなってしまうので、妥協してデコーダの「総時間を取得する」機能を使用しています・・・ > 2.mp3の再生位置が1分を超えた辺りから、停止→再生にタイムラグがある(3分当たりだと1秒くらいでした) >  wavではこの現象は起こりませんでした。  MP3の再生に使用している機能にはシーク機能がないので( 仕様的にはあるのですが、正しく動作しません ) 再生位置が変更されたときは、今までの再生位置より先に設定された場合は今の位置からその位置までの MP3データをデコードして、今の位置より前の位置を指定された場合はMP3データの最初から指定された位置まで デコードをし直します  なので、長いMP3データの後半を再生位置として指定した場合はそれだけデコードしなければならないデータの量が 増えるので、再生位置の指定処理に掛かる時間も長くなります
Re: 音楽再生周りの挙動について ( No.7 )
名前:DG 日時:2010/04/26 19:47

管理人様、対応ありがとうございますm(_ _)m 気になっていた挙動の理由も理解できました。 さて、同ファイル・同コードで再テストを行い、修正を確認しましたが 新たにちょっとよく分からない障害が発生してしまいました(;_;) 以下のようなものです。 テストコードで 「DX_SOUNDDATATYPE_MEMNOPRESS」の時 ttp://music.edolfzoku.com/free01.ogg ttp://osabisi.sakura.ne.jp/m2/tm4/se/tm2_traffic001.wav(mp3にエンコードしたものも) を一度再生→停止してからESCで終了させようとすると、 処理が固まる。 ※一度も再生しない状態でESCを押すと正常に終了しました。 ※ttp://www.rengoku-teien.com/rengoku_mp3/polp.mp3だと起こりませんでした ステップ実行したところ、DxLib_End()のところで固まったので。 「あ、DeleteSoundMemを入れるの忘れてた。コレが原因かな?」と思ってDxLib_End()の直前に DeleteSoundMemを入れたら、今度はDeleteSoundMemのとこで固りました 領域の開放処理でなにか障害が発生してしまってる感じです また、現在作っているプログラムをバージョン3.02cでリビルドしたところ LoadSoundMemで固まるようになってしまいました。 こちらはDX_SOUNDDATATYPE_MEMNOPRESSでもDX_SOUNDDATATYPE_MEMPRESSでも関係なく 発生します。 ご確認よろしくお願いします。
Re: 音楽再生周りの挙動について ( No.8 )
名前:管理人 日時:2010/05/01 17:32

ご報告ありがとうございます DX_SOUNDDATATYPE_MEMNOPRESS を指定して作成したサウンドハンドルを DeleteSoundMem に渡すと 必ずそこで処理が停止してしまう致命的なバグがありました 修正しましたので、何度もお手数で申し訳ありませんがよろしければこちらをお試し下さい m(_ _;m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
Re: 音楽再生周りの挙動について ( No.9 )
名前:DG(解決) 日時:2010/05/01 22:09

管理人様 修正点の再テストを行い、修正を確認しました。 対応ありがとうございましたm(_ _)m

Page: 1 |