在特定设备中播放声音

时间:2011-05-11 12:21:13

标签: c#

我是Csharp的初学者,我正在尝试使用NAudio开发。我在NAudio网站上找到了一个代码,它让我可以播​​放声音。 在我的情况下,我将创建三个按钮,每个按钮与外部声卡相关,当我点击按钮时,我想听到与我的声卡相关的扬声器的声音(按钮1与声卡1相关, ...)。因此每个功能“回放”应该在特定设备中播放声音。对于性能问题,为每个按钮创建“回放”功能并不是很普遍(因此对于每个声卡)并且我的声音允许我只在声卡中播放声音,请你帮我纠正代码???????这对我来说非常重要。

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using NAudio.Wave;
using NAudio.CoreAudioApi;
namespace PaGa
{
public partial class PlaybackForm : Form
{
    IWavePlayer waveOut;
    string fileName = null;
    WaveStream mainOutputStream;
    WaveChannel32 volumeStream;
    public PlaybackForm()
    {
        InitializeComponent();
    }
    private void buttonPlay_Click(object sender, EventArgs e)
    {
        if (waveOut != null)
        {
            if (waveOut.PlaybackState == PlaybackState.Playing)
            {
                return;
            }
            else if (waveOut.PlaybackState == PlaybackState.Paused)
            {
                waveOut.Play();
                return;
            }
        }
        // we are in a stopped state
        // TODO: only re-initialise if necessary
        if (String.IsNullOrEmpty(fileName))
        {
            toolStripButtonOpenFile_Click(sender, e);
        }
        if (String.IsNullOrEmpty(fileName))
        {
            return;
        }
        try
        {
            CreateWaveOut();
        }
        catch (Exception driverCreateException)
        {
            MessageBox.Show(String.Format("{0}", driverCreateException.Message));
            return;
        }
        mainOutputStream = CreateInputStream(fileName);
        trackBarPosition.Maximum = (int)mainOutputStream.TotalTime.TotalSeconds;
        labelTotalTime.Text = String.Format("{0:00}:{1:00}",   (int)mainOutputStream.TotalTime.TotalMinutes,
            mainOutputStream.TotalTime.Seconds);
        trackBarPosition.TickFrequency = trackBarPosition.Maximum / 30;
        try
        {
            waveOut.Init(mainOutputStream);
        }
        catch (Exception initException)
        {
            MessageBox.Show(String.Format("{0}", initException.Message), "Error Initializing Output");
            return;
        }
        // not doing Volume on IWavePlayer any more
        volumeStream.Volume = volumeSlider1.Volume;
        waveOut.Play();
    }
    private WaveStream CreateInputStream(string fileName)
    {
        WaveChannel32 inputStream;
        if (fileName.EndsWith(".wav"))
        {
            WaveStream readerStream = new WaveFileReader(fileName);
            if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm)
            {
                readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
                readerStream = new BlockAlignReductionStream(readerStream);
            }
            if (readerStream.WaveFormat.BitsPerSample != 16)
            {
                var format = new WaveFormat(readerStream.WaveFormat.SampleRate,
                    16, readerStream.WaveFormat.Channels);
                readerStream = new WaveFormatConversionStream(format, readerStream);
            }
            inputStream = new WaveChannel32(readerStream);
        }
        else if (fileName.EndsWith(".mp3"))
        {
            WaveStream mp3Reader = new Mp3FileReader(fileName);
            WaveStream pcmStream = WaveFormatConversionStream.CreatePcmStream(mp3Reader);
            WaveStream blockAlignedStream = new BlockAlignReductionStream(pcmStream);
            inputStream = new WaveChannel32(blockAlignedStream);
        }
        else
        {
            throw new InvalidOperationException("Unsupported extension");
        }
        // we are not going into a mixer so we don't need to zero pad
        //((WaveChannel32)inputStream).PadWithZeroes = false;
        volumeStream = inputStream;
        var meteringStream = new MeteringStream(inputStream, inputStream.WaveFormat.SampleRate / 10);
        meteringStream.StreamVolume += new EventHandler<StreamVolumeEventArgs>(meteringStream_StreamVolume);
        return meteringStream;
    }
    void meteringStream_StreamVolume(object sender, StreamVolumeEventArgs e)
    {
        volumeMeter1.Amplitude = e.MaxSampleValues[0];
        waveformPainter1.AddMax(e.MaxSampleValues[0]);
        if (e.MaxSampleValues.Length > 1)
        {
            volumeMeter2.Amplitude = e.MaxSampleValues[1];
            waveformPainter2.AddMax(e.MaxSampleValues[1]);
        }
    }
    private void CreateWaveOut()
    {
        CloseWaveOut();
        int latency = (int)comboBoxLatency.SelectedItem;
        //if (radioButtonWaveOut.Checked)
        {
            //WaveCallbackInfo callbackInfo = checkBoxWaveOutWindow.Checked ?
            WaveCallbackInfo callbackInfo = WaveCallbackInfo.FunctionCallback();
            // WaveCallbackInfo callbackInfo = WaveCallbackInfo.FunctionCallback();
            // WaveCallbackInfo.NewWindow(): WaveCallbackInfo.FunctionCallback();
            WaveOut outputDevice = new WaveOut(callbackInfo);
            outputDevice.DesiredLatency = latency;
            waveOut = outputDevice;
        }
    }
    private void CloseWaveOut()
    {
        if (waveOut != null)
        {
            waveOut.Stop();
        }
        if (mainOutputStream != null)
        {
            // this one really closes the file and ACM conversion
            volumeStream.Close();
            volumeStream = null;
            // this one does the metering stream
            mainOutputStream.Close();
            mainOutputStream = null;
        }
        if (waveOut != null)
        {
            waveOut.Dispose();
            waveOut = null;
        }
    }
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        CloseWaveOut();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        comboBoxLatency.Items.Add(25);
        comboBoxLatency.Items.Add(50);
        comboBoxLatency.Items.Add(100);
        comboBoxLatency.Items.Add(150);
        comboBoxLatency.Items.Add(200);
        comboBoxLatency.Items.Add(300);
        comboBoxLatency.Items.Add(400);
        comboBoxLatency.Items.Add(500);
        comboBoxLatency.SelectedIndex = 5;
    }
    private void buttonPause_Click(object sender, EventArgs e)
    {
        if (waveOut != null)
        {
            if (waveOut.PlaybackState == PlaybackState.Playing)
            {
                waveOut.Pause();
            }
        }
    }
    private void volumeSlider1_VolumeChanged(object sender, EventArgs e)
    {
        if (mainOutputStream != null)
        {
            volumeStream.Volume = volumeSlider1.Volume;
        }
    }
    private void buttonControlPanel_Click(object sender, EventArgs e)
    {
        AsioOut asio = waveOut as AsioOut;
        if (asio != null)
        {
            asio.ShowControlPanel();
        }
    }
    private void buttonStop_Click(object sender, EventArgs e)
    {
        if (waveOut != null)
        {
            waveOut.Stop();
            trackBarPosition.Value = 0;
        }
    }
    private void timer1_Tick(object sender, EventArgs e)
    {
        if (waveOut != null)
        {
            if (mainOutputStream.Position >= mainOutputStream.Length)
            {
                buttonStop_Click(sender, e);
            }
            else
            {
                TimeSpan currentTime = mainOutputStream.CurrentTime;
                trackBarPosition.Value = (int)currentTime.TotalSeconds;
                labelCurrentTime.Text = String.Format("{0:00}:{1:00}", (int)currentTime.TotalMinutes,
                    currentTime.Seconds);
            }
        }
    }
    private void trackBarPosition_Scroll(object sender, EventArgs e)
    {
        if (waveOut != null)
        {
            mainOutputStream.CurrentTime = TimeSpan.FromSeconds(trackBarPosition.Value);
        }
    }
    private void toolStripButtonOpenFile_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Filter = "All Supported Files (*.wav, *.mp3)|*.wav;*.mp3|All Files (*.*)|*.*";
        openFileDialog.FilterIndex = 1;
        if (openFileDialog.ShowDialog() == DialogResult.OK)
        {
            fileName = openFileDialog.FileName;
        }
       }

       }
       }

提前谢谢你。 美好的一天。

1 个答案:

答案 0 :(得分:0)

我使用了NAudio,这就是我如何设置设备:

waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()) {DeviceNumber = OUTdeviceID };  

基本上WaveOut有一个属性DeviceNumer,默认为-1(默认为Windows) 所以你需要做的是获取声音设备的ID并将它们传递给waveOut