将音频静音一定时间

时间:2014-10-31 04:57:38

标签: c# naudio mute

我希望将音频静音一段时间,让我们说它从2秒开始直到4秒的播放持续时间,即2秒钟。

我想为50个不同的Audios执行此操作,其中Muting具有不同的开始和停止时间。目前,我正在使用两个System.Timer类的对象,其间隔为第一个为开始时间,第二个为停止时间为Muting,我有50个if子句来检查50个音频和设置他们的启动和停止计时器就像这样:

    //50 checks

    AudioFileReader ar;
    Timer start_timer = new Timer(),stop_timer=new Timer();

    public Form1()
    {
        InitializeComponent();
        ar = new AudioFileReader(@"D:\SampleDegradedSpeech.wav");

        var a = new WaveOut();

        a.Init(ar);

        a.Play();

        start_timer.Interval = //start time;
        stop_timer.Interval = //stop time;

        start_timer.Tick += t1_Tick;
        start_timer.Start();

        stop_timer.Tick+=t2_Tick;
        stop_timer.Start();
    }

    private void t2_Tick(object sender, EventArgs e)
    {
        ar.Volume = 1;
        stop_timer.Stop();
    }

    private void t1_Tick(object sender, EventArgs e)
    {
        ar.Volume = 0;
        start_timer.Stop();
    }

还有其他/更好的方法吗? 两个计时器的任何替换? 像ar.mute(start,stop)

这样的东西

1 个答案:

答案 0 :(得分:0)

当底层流到达该时间点时,您可以编写自己的IWaveProvider实现,它包裹您的WaveSource以将Read方法中的样本字节设置为0。到达静音期结束时,您将停止更改字节数组。

这是MutingReader的简单实现:

private class MutingReader : IWaveProvider
{
    private TimeSpan _start;
    private TimeSpan _end;
    private WaveStream _stream;

    // constructor
    public MutingReader(WaveStream stream, TimeSpan start, TimeSpan end)
    {
        _stream = stream;
        _start = start;
        _end = end;
    }  

    // gets called each time the WaveOut needs more bytes
    public int Read(byte[] array, int offset, int count)
    {
        Debug.WriteLine(_stream.CurrentTime);
        var samples = _stream.Read(array, offset, count);
        // if we are between our Start and End Time stamps
        if (_stream.CurrentTime > _start &&
            _stream.CurrentTime < _end)
        {
            // silence by only returning zeroes in the array
            for (int i = 0; i < count; i++)
            {
                array[i + offset] = 0;
            }
        }
        return samples;
    }

    #region IWaveProvider Members
    public WaveFormat WaveFormat
    {
        get { return _stream.WaveFormat; }
    }
    #endregion
}

您可以按如下方式使用上述实现:

var wo = new NAudio.Wave.WaveOutEvent();
var reader = new MutingReader(
        new WaveFileReader( @"v1.wav"),
        new TimeSpan(0,0,2),  // mute after 2 seconds
        new TimeSpan(0,0,4)); // unmute after 4 seconds
wo.Init(reader);
wo.Play();