C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[11]: waveファイルの再生キャンセル方法


(過去ログ 53 を表示中)

[トピック内 16 記事 (1 - 16 表示)]  << 0 >>

■29726 / inTopicNo.1)  waveファイルの再生キャンセル方法
  
□投稿者/ taku (1回)-(2008/12/12(Fri) 19:39:31)

分類:[C#] 

いつも参考にさせていただいてます。
現在waveファイルを再生するソフトを作っているのですが、
ボタン1つで再生・停止ができずに悩んでいます。
DOBON.NETさんのsoundPlayerのplayメソッドを使う方法だと、処理の完了が確認できないため、
再生が完了しても1度soundPlayerをnullにしなければならず
(再生キャンセルしない場合次の再生のときに1度余分にボタンを押さないといけない)、
BackgroundWorkerによる別スレッド中でplaysyncを使う方法だと、
ループ処理がないのでCancellationPendingのチェックができず、キャンセルできません。

ボタンを2つに分けるしか方法はないのでしょうか?
よい方法がありましたら教えてください。よろしくお願いします。
引用返信 編集キー/
■29727 / inTopicNo.2)  Re[1]: waveファイルの再生キャンセル方法
□投稿者/ .SHO (399回)-(2008/12/12(Fri) 19:52:31)
No29726 (taku さん) に返信

試してないので想像ですが
ボタンを押された時に、再生する前にnullにすればいいのではないですか?
引用返信 編集キー/
■29728 / inTopicNo.3)  Re[2]: waveファイルの再生キャンセル方法
□投稿者/ .SHO (400回)-(2008/12/12(Fri) 20:10:31)
それにしても変な話だと思い試してみましたが
何の問題もなく再生できました。

どこかにバグがあるとしかわかりません。

現象が再現する最小のソースを掲示して頂いた方が早そうです。
引用返信 編集キー/
■29729 / inTopicNo.4)  Re[2]: waveファイルの再生キャンセル方法
□投稿者/ taku (2回)-(2008/12/12(Fri) 20:23:03)
> 試してないので想像ですが
> ボタンを押された時に、再生する前にnullにすればいいのではないですか?
すばやい返答ありがとうございます。
残念ながらそれでは私の実装したい処理にはならないと思います。
私がしたい処理は
ボタン1を押す
→何も再生されていなければ再生
→何か再生されていれば停止(そこから新しいものを再生するわけではない)
と言うものですので(再生前にnullにすると停止できない)。説明不足で申し訳ありませんでした。

引用返信 編集キー/
■29730 / inTopicNo.5)  Re[3]: waveファイルの再生キャンセル方法
□投稿者/ .SHO (401回)-(2008/12/12(Fri) 20:31:20)
No29729 (taku さん) に返信

> ボタン1を押す
> →何も再生されていなければ再生
> →何か再生されていれば停止(そこから新しいものを再生するわけではない)

そういうことですか。
BackgroundWorkerによる別スレッド中でplaysyncを使って
playsyncから戻ったらnullにすればいいのではないですか?

CancellationPendingは関係ないですよね。
引用返信 編集キー/
■29731 / inTopicNo.6)  Re[3]: waveファイルの再生キャンセル方法
□投稿者/ taku (3回)-(2008/12/12(Fri) 20:32:58)
現在こんな感じです。
hoge.wavの再生中にbutton1を押す分には正常に停止処理をしてくれますが、
再生が人間視点で完全に終わったあとでもう1度再生しようとbutton1を押すと、
プログラム視点では再生が終わっていないため、停止処理が行われてしまいます(人間視点では何もおこっていない)。
   private SoundPlayer wavePlayer = null;   

   private void button1_Click(object sender, EventArgs e)
   {
       if (wavePlayer != null)
       {
           wavePlayer.Stop();
           wavePlayer.Dispose();
           wavePlayer = null;
       }
       else
       {
           wavePlayer = new SoundPlayer("hoge.wav");
           wavePlayer.Play();
       }
   }

引用返信 編集キー/
■29732 / inTopicNo.7)  Re[4]: waveファイルの再生キャンセル方法
□投稿者/ .SHO (402回)-(2008/12/12(Fri) 20:36:55)
2008/12/12(Fri) 20:37:25 編集(投稿者)
No29731 (taku さん) に返信

> hoge.wavの再生中にbutton1を押す分には正常に停止処理をしてくれますが、
> 再生が人間視点で完全に終わったあとでもう1度再生しようとbutton1を押すと、
> プログラム視点では再生が終わっていないため、停止処理が行われてしまいます(人間視点では何もおこっていない)。

いや、だから PlaySyncを使って戻ったらnullにしてはダメですか?

>    private SoundPlayer wavePlayer = null;   
> 
>    private void button1_Click(object sender, EventArgs e)
>    {
>        if (wavePlayer != null)
>        {
>            wavePlayer.Stop();
>            wavePlayer.Dispose();
>            wavePlayer = null;
>        }
>        else
>        {
>            wavePlayer = new SoundPlayer("hoge.wav");
>            wavePlayer.Play();

ここを
             wavePlayer.PlaySync();
             wavePlayer = null;
にする。

>        }
>    }

引用返信 編集キー/
■29733 / inTopicNo.8)  Re[4]: waveファイルの再生キャンセル方法
□投稿者/ taku (4回)-(2008/12/12(Fri) 20:37:01)
>playsyncから戻ったら
戻ったら、ということは再生がすべて終了しているわけですよね?
それでは再生を中断するという処理はできないのではないでしょうか?

#申し訳ないですがしばらく席をはずします。
引用返信 編集キー/
■29734 / inTopicNo.9)  Re[5]: waveファイルの再生キャンセル方法
□投稿者/ .SHO (403回)-(2008/12/12(Fri) 20:39:12)
No29733 (taku さん) に返信

> >playsyncから戻ったら
> 戻ったら、ということは再生がすべて終了しているわけですよね?
> それでは再生を中断するという処理はできないのではないでしょうか?

だから、それをBackgroundWorkerの中でやっておけば
再生が終わった時はnullになってるので、ボタン押されたら再生するし
再生が終わってなければ止めるのでは?
引用返信 編集キー/
■29735 / inTopicNo.10)  Re[5]: waveファイルの再生キャンセル方法
□投稿者/ taku (5回)-(2008/12/12(Fri) 20:42:35)
書き込み時間のせいで食い違いがありましたね。すみません。
再生直後にnullをはさむと
if (wavePlayer != null)
という処理をしているためにもう1度押したときは停止ではなくそこから新しくhoge.wavの再生が始まってしまいます。
引用返信 編集キー/
■29736 / inTopicNo.11)  Re[6]: waveファイルの再生キャンセル方法
□投稿者/ .SHO (404回)-(2008/12/12(Fri) 21:19:41)
No29735 (taku さん) に返信

ダメだ。
実際にやってみたけど確かにPlaySyncだと途中で止められませんでした。

あとは、ちょっと強引だけど PlaySync で再生時間測っといて
その時間で制御するとか…
(当然、誤差が出てきますが)
引用返信 編集キー/
■29738 / inTopicNo.12)  Re[7]: waveファイルの再生キャンセル方法
□投稿者/ taku (6回)-(2008/12/12(Fri) 22:13:11)
わざわざ再現してくれたのですね・・・ありがとうございます。
んーやっぱり無理ですか。今回のソフトは複数のwavファイルを結合して、それから再生するものなので
再生時間測ると言うのも無理そうですね・・・
再生と停止で2つボタン作ることにします。ありがとうございました。
#ボタン2つ重ねてvisible操作すればそれっぽくなる、なんてことも考えたり・・・
解決済み
引用返信 編集キー/
■29739 / inTopicNo.13)  Re[8]: waveファイルの再生キャンセル方法
□投稿者/ taku (7回)-(2008/12/12(Fri) 22:26:50)
2008/12/12(Fri) 22:31:29 編集(投稿者)

ってボタン重ねたら意味ないのか;重ねなくても停止ボタンのEnabledとか操作できないし。
なんで「今再生されているか」のプロパティとかないんだろう・・・
引用返信 編集キー/
■29757 / inTopicNo.14)  Re[9]: waveファイルの再生キャンセル方法
□投稿者/ よねKEN (229回)-(2008/12/13(Sat) 17:03:19)
2008/12/13(Sat) 17:03:46 編集(投稿者)

> なんで「今再生されているか」のプロパティとかないんだろう・・・

SoundPlayerはWindows APIのPlaySoundをラッピングしたものなので、
あまり凝ったことには使えません。

WindowsAPIのmciSendString関数などのmci系の関数を使うようにしてはいかがでしょう。
こちらの場合、再生が終わったかどうかの通知も機能として持っているので、
たぶん実現できるのではないかと思います。
(とはいえ、mci系のAPIを使って再生完了通知を扱うような実装をしたことがないので、
 今のところ具体的なアドバイスはできませんが)

引用返信 編集キー/
■29759 / inTopicNo.15)  Re[10]: waveファイルの再生キャンセル方法
□投稿者/ .SHO (407回)-(2008/12/13(Sat) 17:44:29)
なんだかいろいろ言って申し訳ないので、mciSendString API を使用した
MySoundPlayer クラス作りました。このままで望みどおりに動くと思います。
後は、煮るなり焼くなり好きにして頂いて結構です。

using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class MySoundPlayer {
    [DllImport("winmm.dll")]
    extern static int mciSendString( string s, StringBuilder t, int i, int j );
    private string fname;
    public MySoundPlayer( string f ) { fname = f; }
    public void Play() {
        mciSendString( "close s", null, 0, 0 );
        mciSendString( "open \"" + fname + "\" alias s", null, 0, 0 );
        mciSendString( "play s", null, 0, 0 );
    }
    public void Stop() {
        mciSendString( "close s", null, 0, 0 );
    }
    public bool Status {
        get {
            StringBuilder sb = new StringBuilder( 32 );
            mciSendString( "status s mode", sb, sb.Capacity, 0 );
            return sb.ToString() == "playing";
        }
    }
}

// 使用例
    MySoundPlayer player = new MySoundPlayer( "サウンド.wav" );

    private void Button1_Click( object sender, EventArgs e ) {
        if ( player.Status )
            player.Stop();
        else
            player.Play();
    }

解決済み
引用返信 編集キー/
■29784 / inTopicNo.16)  Re[11]: waveファイルの再生キャンセル方法
□投稿者/ taku (8回)-(2008/12/14(Sun) 20:39:47)
遅くなりましたがお礼です。
No29759 (よねKEN) に返信
>SoundPlayerはWindows APIのPlaySoundをラッピングしたものなので、
>あまり凝ったことには使えません。
なるほど・・・やはり楽に使えるものはそれなりなんですね・・・
No29759 (.SHO さん) に返信
> なんだかいろいろ言って申し訳ないので、mciSendString API を使用した
> MySoundPlayer クラス作りました。このままで望みどおりに動くと思います。
> 後は、煮るなり焼くなり好きにして頂いて結構です。
全く望みどおりに動いてくれたので恥ずかしながらそのまま使用させていただきます(クラスの内容は理解したつもりです)。
とても助かります。本当にありがとうございました。

しかしAPIは便利ですね。これから勉強してみます。
また機会があればそのときはよろしくお願いします。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -