将音频静音一段时间

本文关键字:一段时间 音频 | 更新日期: 2023-09-27 18:28:36

我想将我的音频静音一段时间,比如说,从开始到播放持续时间的4秒后,即2秒。

我想为50种不同的音频做这件事,它们有不同的静音开始和停止时间。目前,我正在使用两个System.Timer类的对象,第一个对象是开始时间,第二个对象是静音的停止时间,我有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)的东西?

将音频静音一段时间

您可以编写自己的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();