【问题标题】:Play a sound in a specific device with C#使用 C# 在特定设备中播放声音
【发布时间】:2011-05-03 11:45:19
【问题描述】:

我的问题是,如果我想创建 3 个按钮并且我有 3 个声卡,并且每个按钮都与声卡相关(例如 button1 与声卡1...),当我点击 button1 时,我想听到与声卡1相关的扬声器发出的声音(按钮2和按钮3相同。

我的朋友给了我两个代码:第一次使用 Naudio 它可以工作,但我仍然无法在三个声卡中播放声音。我的意思是当我安装三个声卡时只有一个声卡工作。就像程序总是从三个外置声卡中选择一个默认声卡一样。

第二个使用 DirectX,它适用于我,但我不明白他如何调用设备号。我的意思是在使用 NAudio 的代码中有“例如 devicenumber= 1”。我需要知道如何,因为我将为每个按钮指定一个设备(例如,当我单击按钮 1 时,声音将在声卡 1 中播放)?

我想知道如何更正这两个代码之一,以及如何在第二个代码中指定“设备”。

这是 Form2 的代码(来自使用 NAudio 的项目),您可以注意到它如何为每个按钮指定一个设备,但不幸的是它导致了上述问题:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NAudio.Wave;
using NAudio.CoreAudioApi;
namespace AudioWithNAudio
{
    public partial class Form2 : Form
    {
        string fileName = null;
        WaveOut wave = null;
        private NAudio.Wave.WaveFileReader waveReader = null;
        private NAudio.Wave.DirectSoundOut output = null;
       
        public Form2()
        {
            InitializeComponent();
        }
        private void Form2_Load(object sender, EventArgs e)
        {
            hideButtons();
             fileName = ("alarm.wav");
             detectDevices();          
             
        }
        public void hideButtons()
        {
        
            bttnAudioDevice1.Visible = false;
            bttnAudioDevice2.Visible = false;
            bttnAudioDevice3.Visible = false;
            bttnAudioDevice4.Visible = false;
            bttnAudioDevice5.Visible = false;
        }
        public void detectDevices()
        {
            int waveOutDevices = WaveOut.DeviceCount;
            switch (waveOutDevices)
            {
                case 1:
                    bttnAudioDevice1.Visible = true;
                    break;
                case 2:
                    bttnAudioDevice2.Visible = true;
                    bttnAudioDevice1.Visible = true;
                    break;
                case 3:
                      bttnAudioDevice2.Visible = true;
                    bttnAudioDevice1.Visible = true;
                    bttnAudioDevice3.Visible = true;
                    break;
                case 4:
                         bttnAudioDevice2.Visible = true;
                    bttnAudioDevice1.Visible = true;
                    bttnAudioDevice3.Visible = true;
                    bttnAudioDevice4.Visible = true;
                    break;
                case 5:
                            bttnAudioDevice2.Visible = true;
                    bttnAudioDevice1.Visible = true;
                    bttnAudioDevice3.Visible = true;
                    bttnAudioDevice4.Visible = true;
                    bttnAudioDevice5.Visible = true;
                    break;
            }
        }
        private void bttnAudioDevice1_Click(object sender, EventArgs e)
        {
            wave = new WaveOut();
            wave.DeviceNumber = 0;
            playSound();
        }
        private void bttnAudioDevice2_Click(object sender, EventArgs e)
        {
            wave = new WaveOut();
            wave.DeviceNumber = 1;
            playSound();
        }
        private void bttnAudioDevice3_Click(object sender, EventArgs e)
        {
            wave.DeviceNumber = 2;
            playSound();
        }
        private void bttnAudioDevice4_Click(object sender, EventArgs e)
        {
            wave.DeviceNumber = 3;
            playSound();
        }
        private void bttnAudioDevice5_Click(object sender, EventArgs e)
        {
            wave.DeviceNumber = 4;
            playSound();
        }
        public void playSound()
        {
            disposeWave();// stop previous sounds before starting
            waveReader = new NAudio.Wave.WaveFileReader(fileName);
            output = new NAudio.Wave.DirectSoundOut();
           
            output.Init(new NAudio.Wave.WaveChannel32(waveReader));
            output.Play();
        }
        public void disposeWave()
        {
            if (output != null)
            {
                if (output.PlaybackState == NAudio.Wave.PlaybackState.Playing)
                {
                    output.Stop();
                    output.Dispose();
                    output = null;
                }
            }
            if (wave != null)
            {
                wave.Dispose();
                wave = null;
            }
        }
        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            disposeWave();
        }
        private void bttnStop_Click(object sender, EventArgs e)
        {
            if (output != null)
            {
                if (output.PlaybackState == NAudio.Wave.PlaybackState.Playing)
                {
                    output.Stop();
                 
                }
            }
        }
    }
}

这是 Form1 的代码(来自使用 DirectX 的项目):

using System;
using System.Windows.Forms;
using Microsoft.DirectX.DirectSound;
using DirectSound = Microsoft.DirectX.DirectSound;
namespace DirectSoundPlay
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            ReSizeControls();
        }
        private void playToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listBox2.SelectedItems.Count == 0)
                return;
            if (listBox2.SelectedItems.Count > 1)
            {
                MessageBox.Show("Too many SelectedItems");
                return;
            }
            ClassAudioDevice ad = listBox2.SelectedItem as ClassAudioDevice;
            if (ad == null)
            {
                MessageBox.Show("SelectedItem is not a ClassAudioDevice");
                return;
            }
            DirectSound.Device Device = new DirectSound.Device(ad.DriverGuid);
            Device.SetCooperativeLevel(this.Handle, DirectSound.CooperativeLevel.Priority);
            DirectSound.Buffer AudioBuffer = new DirectSound.Buffer("C:\\Windows\\Media\\notify.wav", Device);
            AudioBuffer.Play(0, BufferPlayFlags.Default);
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            ReSizeControls();
        }
        private void ReSizeControls()
        {
            int w = ClientSize.Width >> 1;
            listBox1.Width = w - 1;
            listBox2.Width = w - 1;
            listBox1.Height = ClientSize.Height;
            listBox2.Height = ClientSize.Height;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            DirectSound.DevicesCollection DevicesList = new DirectSound.DevicesCollection();
            DirectSound.CaptureDevicesCollection CaptureDevicesList = new DirectSound.CaptureDevicesCollection();
            ClassAudioDevice ad;
            //
            foreach (DirectSound.DeviceInformation di in CaptureDevicesList)
            {
                ad = new ClassAudioDevice();
                ad.Description = di.Description;
                ad.DriverGuid = di.DriverGuid;
                listBox1.Items.Add(ad);
            }
            foreach (DirectSound.DeviceInformation di in DevicesList)
            {
                ad = new ClassAudioDevice();
                ad.Description = di.Description;
                ad.DriverGuid = di.DriverGuid;
                listBox2.Items.Add(ad);
            }
        }
    }
}
 

这是 ClassAudioDevice 的代码(来自同一个项目):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace DirectSoundPlay
{
    class ClassAudioDevice
    {
        public string Description = "";
 
        public Guid DriverGuid = new Guid();
 
        public override string ToString()
        {
            return Description;
        }
    }
}

【问题讨论】:

    标签: c#


    【解决方案1】:

    在您的按钮单击处理程序中,您正在创建一个 WaveOut 设备,设置其设备编号,然后您的 playSound 函数使用完全不同的 IWavePlayer(DirectSoundOut 的一个实例)播放声音。您的代码存在几个问题(尤其是并发播放时),但我会先将设备编号传递给 playSound 函数。

    public void playSound(int deviceNumber)
    {
        disposeWave();// stop previous sounds before starting
        waveReader = new NAudio.Wave.WaveFileReader(fileName);
        var waveOut = new NAudio.Wave.WaveOut();
        waveOut.DeviceNumber = deviceNumber;
        waveOut.Init(waveReader);
        waveOut.Play();
    }
    

    【讨论】:

    • @Mark Heath:非常感谢 Mark 它可以工作了,现在我可以听到三个扬声器的声音了。
    【解决方案2】:

    我有一个类似的问题,我需要能够控制在哪个声音设备上播放声音,我找到了一个不错的库 (irrKlang),它让这一切变得非常容易。对于任何感兴趣的人,这是链接:http://www.ambiera.com/irrklang/downloads.html。有了这个库,只需几行代码就可以选择所需的声音设备并用它播放声音。

    //Get the list of installed sound devices. 
    sdl = new IrrKlang.ISoundDeviceList(IrrKlang.SoundDeviceListType.PlaybackDevice);
    
    //Add each device to a combo box.
    for(int i = 0; i < sdl.DeviceCount; i++)
    {
        comboBox1.Items.Add(sdl.getDeviceDescription(i) + "\n");
    }
    
    
    //Place this code in your play sound event handler.
    //Create a sound engine for the selected device (uses the ComboBox index to 
    //get device ID).
    irrKlangEngine = new IrrKlang.ISoundEngine(IrrKlang.SoundOutputDriver.AutoDetect,
                    IrrKlang.SoundEngineOptionFlag.DefaultOptions, 
                    sdl.getDeviceID(comboBox1.SelectedIndex));
    
    //Play the selected file
    playSelectedFile(fileName);
    

    我希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 2021-01-31
      • 1970-01-01
      相关资源
      最近更新 更多