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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.91060 の関連記事表示

<< 0 >>
■91060  WaveStreamのクラス化がうまくいかない
□投稿者/ TOTO -(2019/05/23(Thu) 12:52:17)

    分類:[.NET 全般] 


    https://smdn.jp/programming/netfx/tips/set_volume_of_soundplayer/

    このページに音量を調整可能な
    WaveStreamのクラスのコードが載っています。

    複数の音声を扱うために、
    これを以下のようにクラス化しました。



    Public Class SoundClass

    Public strm As WaveStream

    Public player As System.Media.SoundPlayer = Nothing

    Public Sub Start()

    If player IsNot Nothing Then Exit Sub

    player = New System.Media.SoundPlayer(strm)

    player.PlayLooping()


    End Sub


    Public Sub Stop0()

    If player IsNot Nothing Then
    player.Stop()
    player.Dispose()
    player = Nothing
    End If
    End Sub

    End Class



    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

    Dim myAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
    Dim kkk = New SoundClass With {.strm = New WaveStream(myAssembly.GetManifestResourceStream("WindowsApplication1.test.wav"))}

    kkk.Start()
    Thread.Sleep(1000)
    kkk.Stop0()
    Thread.Sleep(1000)
    kkk.Start() ’←ここでエラーが発生する


      End Class


    しかし、一回目の再生はうまくいくのですが、
    一度、停止してから再度再生しようとすると


    player.PlayLooping()

    WAVEヘッダーが壊れています
    というエラーが出てうまくいきません。


    Public Class SoundClassの中で、


    Dim myAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
    Dim strm As New WaveStream(myAssembly.GetManifestResourceStream("WindowsApplication1.test.wav"))}

    の宣言を行うとなぜかうまくいきます。

    なぜ、このエラーが発生するのでしょうか?
親記事 /過去ログ157より / 関連記事表示
削除チェック/

■91061  Re[1]: WaveStreamのクラス化がうまくいかない
□投稿者/ 魔界の仮面弁士 -(2019/05/23(Thu) 13:20:14)
    No91060 (TOTO さん) に返信
    > Public Class SoundClass
    >  Public strm As WaveStream
    >  Public player As System.Media.SoundPlayer = Nothing

    これらのクラスを内包させるのであれば、SoundClass クラスは
    Components を継承させて作るか、もしくは
    IDisposable インターフェイスを実装することをお奨めします。


    > Thread.Sleep(1000)

    Windows メッセージループを阻害することになるため、
    フォーム上(というか、UI スレッド)上で Sleep メソッドを呼び出すのは厳禁です。



    > kkk.Start() ’←ここでエラーが発生する

    その直前の処理で SoundPlayer を Dispose していますよね。
    肝心のインスタンスが廃棄されていませんか?

    廃棄済みのオブジェクトを操作するのはマズイと思いますよ。
記事No.91060 のレス /過去ログ157より / 関連記事表示
削除チェック/

■91063  Re[2]: WaveStreamのクラス化がうまくいかない
□投稿者/ TOTO -(2019/05/23(Thu) 22:09:20)
    ありがとうございます。

    Components を継承させて作るか、もしくは
    IDisposable インターフェイスを実装することをお奨めします。

    これの方法をお教えいただけないでしょうか?
記事No.91060 のレス /過去ログ157より / 関連記事表示
削除チェック/

■91080  Re[3]: WaveStreamのクラス化がうまくいかない
□投稿者/ キングダム -(2019/05/26(Sun) 19:22:26)
    2019/05/26(Sun) 19:24:03 編集(投稿者)

    No91063 (TOTO さん) に返信

    ●エラーが発生する原因を知るにはどうすればよいか

    仮説を立てましょー

    SoundPlayerにStreamを渡すようになっており
    Streamは一定の方向に進んでいくというものです

    PlayLoopingでStreamが一定の方向に進んでいく
    StopでそれがストップするけれどもStreamの位置はリセットされない

    次にSoundPlayerにStreamを渡したときには
    Streamの読み込み位置が最初とは違っている

    Waveのヘッダはファイルの特定の場所に存在していて
    読み出す位置が違うと正常に読み出せない

    WAVEヘッダーが壊れていますというエラーが投げられる

    という感じじゃないかなと思います

    ●仮説を検証するにはどうすればよいか

    StopのあとにStream.Positionを出力してみる、0ではないはず

    New System.Media.SoundPlayer(strm)の前のところで
    strm.Position = 0を実行してみる、エラーがでないはず

    ということを確認すれば良さそうですね

    ●エラーがでないようにするにはどうすればよいか

    やり方はいくつかありそうですね

    ・PlayごとにStreamのインスタンスを作成する
    ・Streamが変わらない場合はSoundPlayerのコンストラクタを呼ばない
    ・Stream.Position = 0を挿入する

    ●Componentsの継承、IDisposableの実装について

    継承の仕方、インターフェースの実装のしかたは
    プログラミングの一般的な事柄なので↓こういうところを読むのがいんじゃないかと思います

    第4回 継承を使うために知っておくべきこと (1/4):連載 オブジェクト指向プログラミング超入門 - @IT
    https://www.atmarkit.co.jp/ait/articles/0409/25/news010.html

    VB開発者のためのインターフェイス入門(1/2) - @IT
    https://www.atmarkit.co.jp/fdotnet/bookpreview/kisokaravb_0802/kisokaravb_0802_01.html
記事No.91060 のレス /過去ログ157より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -