0

gui スレッドで wav ファイルを同期的に再生したいのですが、PlaySync への呼び出しが早期に返されます (再生が途中で停止します)。wav ファイルは 2 ~ 3 分です。

私のコードは次のようになります。

        //in gui code (event handler)
        //play first audio file
        JE_SP.playSound("example1.wav");

        //do a few other statements
        doSomethingUnrelated();

        //play another audio file
        JE_SP.playSound("example2.wav");

    //library method written by me, called in gui code, but located in another assembly
    public static int playSound(string wavFile, bool synchronous = true,
        bool debug = true, string logFile = "", int loadTimeout = FIVE_MINUTES_IN_MS)
    {
        SoundPlayer sp = new SoundPlayer();
        sp.LoadTimeout = loadTimeout;
        sp.SoundLocation = wavFile;
        sp.Load();

        switch (synchronous)
        {
            case true:
                sp.PlaySync();
                break;
            case false:
                sp.Play();
                break;
        }

        if (debug)
        {
            string writeMe = "JE_SP: \r\n\tSoundLocation = " + sp.SoundLocation
                + "\r\n\t" + "Synchronous = " + synchronous.ToString();
            JE_Log.logMessage(writeMe);
        }

        sp.Dispose();
        sp = null;

        return 0;
    }

私が考えたいくつかのことは、ロードタイムアウト、および別のスレッドでオーディオを再生し、その後、GUI スレッドをサウンドファイルの持続時間まで強制的に待機させることにより、GUI を手動で「フリーズ」することです。ロードタイムアウトを長くしようとしましたが、何もしませんでした。

私/マイクロソフト以外の誰かによって書かれたコードを使用せずに wav ファイルの長さを取得する最善の方法が何であるかはよくわかりません。ファイル サイズがわかっているため、これは計算できると思います。すべてのエンコーディング プロパティ (ビットレート、サンプル レート、サンプル サイズなど) は、再生するすべてのファイルで一貫しています。この情報を使用して wav ファイルの長さを計算する方法を誰か詳しく説明できますか? つまり、PlaySync が早期に復帰する理由について誰も考えていない場合です。

編集:

注: 少し前に VB 6 で同様の問題が発生しましたが、これはタイムアウトが原因であり、ここでは問題ではないと思われます。短い (< 1 分) ファイルは正常に再生されるように見えるので、長いファイルを手動で編集してから、複数の呼び出しで個別に再生することにするかもしれません。

追加情報: 同じファイルが一貫して同時に停止することに気付きました。ファイルは Audacity を使用して作成されました。PlaySync が、私が Audacity に作成させたものとは異なるファイルの特定のエンコーディングを期待している可能性はありますか?

4

1 に答える 1

0

他の誰かが大きな wav ファイルを同期的に再生する際に問題に遭遇した場合に備えて、代わりに WMP を使用する方法を以下に示します。

public static int playSoundWMP(string soundFile, bool synchronous = true)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        wmp.URL = soundFile;
        wmp.controls.play();

        Thread.Yield();

        while (wmp.playState == WMPLib.WMPPlayState.wmppsTransitioning)
        {
            Application.DoEvents();
            Thread.Yield();
        }

        int duration = Convert.ToInt32(wmp.currentMedia.duration * 1000);
        double waitTime = wmp.currentMedia.duration;

        if (synchronous)
        {
            Thread.Sleep(duration);
        }

        long elapsed = sw.ElapsedMilliseconds;
        sw.Stop();
        sw = null;

        return (int) wmp.currentMedia.duration * 1000;
    }

このメソッドは、SoundPlayer クラスの代わりに WMP を使用してオーディオ ファイルを再生するため、より大きな wav ファイルをより確実に再生できます...

于 2011-01-31T20:40:13.593 に答える