将音频静音一段时间
本文关键字:一段时间 音频 | 更新日期: 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();