3

我想同时在三个外部声卡中播放声音,我的意思是当我点击一个按钮时,我可以听到三个与我的三个声卡相关的扬声器的声音。我有一个功能,但它只在一个设备中播放声音,它找到的第一个设备,我的意思是在这段代码中第一个设备是数字 0,所以它在其中播放声音,但是如果你首先写设备号 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();
        }
    }

现在您可以使用 for 循环而不是需要您复制代码的 switch 语句在所有可用设备中播放:

    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 回答