3

同時に 3 つの外部サウンド カードでサウンドを再生したいのですが、ボタンをクリックすると、3 つのサウンド カードに関連する 3 つのスピーカーからサウンドが聞こえます。私は関数を持っていますが、最初に見つかった1つのデバイスでのみサウンドを再生します。つまり、このコードでは最初のデバイスは番号0であるため、そのデバイスでサウンドを再生しますが、最初にデバイス番号1を書き込むと、その中でサウンドを再生します。結論として、サウンドは1つのデバイスでのみ再生され、同時にすべてのデバイスで機能しません。これはそのコードです:

public void playAllAvailableDevices()
{
//create a new class for each wav file & output etc.
WaveOut waveOut1 = new WaveOut();
WaveFileReader waveReader1 = new WaveFileReader(fileName);
WaveOut waveOut2 = new WaveOut();
WaveFileReader waveReader2 = new WaveFileReader(fileName);
WaveOut waveOut3 = new WaveOut();
WaveFileReader waveReader3 = new WaveFileReader(fileName);

switch (waveOutDevices)
{
case 1: 
waveOut1.Init(waveReader1);
waveOut1.DeviceNumber = 0;
waveOut1.Play();
break;
case 2: 
waveOut1.Init(waveReader1);
waveOut1.DeviceNumber = 0;
waveOut1.Play();

waveOut2.Init(waveReader2);
waveOut2.DeviceNumber = 1;
waveOut2.Play();
break;
case 3:
waveOut1.Init(waveReader1);
waveOut1.DeviceNumber = 0;
waveOut1.Play();

waveOut2.Init(waveReader2);
waveOut2.DeviceNumber = 1;
waveOut2.Play();

waveOut3.Init(waveReader3);
waveOut3.DeviceNumber = 2;
waveOut3.Play();
break;
}}

fileName は、再生したいサウンド ファイルの名前です。私のコードでは、darabase からこの名前を取得します。

private void btnAlarm1_Click(object sender, EventArgs e)
    {

        OdbcConnection cn = new OdbcConnection("DSN=cp1");
        cn.Open();
        OdbcCommand cmd1 = new OdbcCommand("select chemin from alarme where code_alarme=41", cn);
        cmd1.Connection = cn;
        fileName = cmd1.ExecuteScalar().ToString();
        wave = new WaveOut();
        playAllAvailableDevices();
    }

解決策を見つけるのを手伝ってもらえますか???? 前もって感謝します。良い一日。

4

2 に答える 2

7

DeviceNumberを呼び出す前に、WaveOut オブジェクトのプロパティを設定する必要がありますInit。単純な関数を使用して、コードを大幅にクリーンアップできます。

    private void PlaySoundInDevice(int deviceNumber, string fileName)
    {
        if (outputDevices.ContainsKey(deviceNumber))
        {
            outputDevices[deviceNumber].WaveOut.Dispose();
            outputDevices[deviceNumber].WaveStream.Dispose();
        }
        var waveOut = new WaveOut();
        waveOut.DeviceNumber = deviceNumber;
        WaveStream waveReader = new WaveFileReader(fileName);
        // hold onto the WaveOut and  WaveStream so we can dispose them later
        outputDevices[deviceNumber] = new PlaybackSession { WaveOut=waveOut, WaveStream=waveReader };

        waveOut.Init(waveReader);
        waveOut.Play();
    }

    private Dictionary<int, PlaybackSession> outputDevices = new Dictionary<int, PlaybackSession>();

    class PlaybackSession
    {
        public IWavePlayer WaveOut { get; set; }
        public WaveStream WaveStream { get; set; }
    }

ディクショナリは WaveOut を保持するため、再生中にガベージ コレクションが発生せず、適切にクリーンアップできます。アプリケーションを終了する前に、適切にクリーンアップしてください。

    private void DisposeAll()
    {
        foreach (var playbackSession in outputDevices.Values)
        {
            playbackSession.WaveOut.Dispose();
            playbackSession.WaveStream.Dispose();
        }
    }

これで、コードを複製する必要がある switch ステートメントの代わりに for ループを使用して、利用可能なすべてのデバイスで再生できるようになりました。

    public void PlayInAllAvailableDevices(string fileName)
    {
        int waveOutDevices = WaveOut.DeviceCount;
        for (int n = 0; n < waveOutDevices; n++)
        {
            PlaySoundInDevice(n, fileName);
        }
    }
于 2011-05-15T22:02:03.097 に答える
1

あなたが探しているのは BASS オーディオ ライブラリだと思います:

http://www.un4seen.com/

これもうまくいくかもしれません:

http://www.alvas.net/alvas.audio.aspx

上記のようなサードパーティのアドインがなければ、C# がこれを行うように設定されているとは思いません。私より賢い誰かがあなたがそれを機能させるのを手伝うことができるかもしれませんが、そうでない場合は、これらのライブラリがあなたが望む道をたどるのに役立ちます.

于 2011-05-15T22:02:38.090 に答える