由于我的程序(C#,NAudio)正在播放音频文件,如果它遇到1分钟的沉默,我想跳过它
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了由于我的程序(C#,NAudio)正在播放音频文件,如果它遇到1分钟的沉默,我想跳过它相关的知识,希望对你有一定的参考价值。
我的应用播放音频文件。当它播放时,我想检查下一分钟将播放的内容,看看它是否全部都是沉默;如果是这样,我想跳过沉默。
我试图找到一种方法来查看流之前传递给WaveOutEvent。我正在链接AudioFileReader,SampleChannel和OffsetSampleProvider。我还没有找到一种方法可以让我简单地“窥视”即将到来的数据。我看过Mark Heath的PluralSight课程和NAudio源代码。
//此代码基于Mark Health在PluralSight上的NAudo课程的示例。
...
private string fileName;
private IWavePlayer waveOut;
ISampleProvider sampleProvider;
private ISampleProvider CreateInputStream(string fileName)
{
audioFileReader = new AudioFileReader(fileName);
var sampleChannel = new SampleChannel(audioFileReader, true);
var offsetSampleProvider = new OffsetSampleProvider(sampleChannel);
return offsetSampleProvider;
}
private void Play()
{
...
if (waveOut != null)
{
if (waveOut.PlaybackState == PlaybackState.Playing)
{
return;
}
else if (waveOut.PlaybackState == PlaybackState.Paused)
{
waveOut.Play();
return;
}
}
if (string.IsNullOrEmpty(fileName)) GetFileName();
if (string.IsNullOrEmpty(fileName)) return;
try
{
CreateWaveOut();
}
catch (Exception driverCreateException)
{
MessageBox.Show(String.Format("{0}", driverCreateException.Message));
return;
}
try
{
sampleProvider = CreateInputStream(fileName);
}
catch (Exception createException)
{
MessageBox.Show(String.Format("{0}", createException.Message), "Error Loading File");
return;
}
...
try
{
waveOut.Init(sampleProvider);
}
catch (Exception initException)
{
MessageBox.Show(String.Format("{0}", initException.Message), "Error Initializing Output");
return;
}
SetVolume();
waveOut.Play();
}
private void CreateWaveOut()
{
CloseWaveOut();
waveOut = new WaveOutEvent();
waveOut.PlaybackStopped += OnPlaybackStopped;
}
private void OnPlaybackStopped(object sender, StoppedEventArgs e)
{
if (e.Exception != null) MessageBox.Show(e.Exception.Message, "Playback Device Error");
if (audioFileReader != null) audioFileReader.Position = 0;
}
private AudioFileReader audioFileReader;
private void CloseWaveOut()
{
if (waveOut != null) waveOut.Stop();
if (audioFileReader != null)
{
audioFileReader.Dispose();
audioFileReader = null;
}
if (waveOut != null)
{
waveOut.Dispose();
waveOut = null;
}
}
...
private void playToolStripButton_Click(object sender, EventArgs e)
{
Play();
}
...
private void stopToolStripButton_Click(object sender, EventArgs e)
{
if (waveOut != null) waveOut.Stop();
}
private void openToolStripButton_Click(object sender, EventArgs e)
{
GetFileName();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (waveOut != null && audioFileReader != null)
{
TimeSpan currentTime = (waveOut.PlaybackState == PlaybackState.Stopped) ? TimeSpan.Zero : audioFileReader.CurrentTime;
trackBar1.Value = Math.Min(trackBar1.Maximum, (int)(100 * currentTime.TotalSeconds / audioFileReader.TotalTime.TotalSeconds));
currentTimeStripLabel.Text = String.Format("{0:00}:{1:00}", (int)currentTime.TotalMinutes, currentTime.Seconds);
}
else
{
trackBar1.Value = 0;
}
}
private void pauseToolStripButton_Click(object sender, EventArgs e)
{
if (waveOut != null)
{
if (waveOut.PlaybackState == PlaybackState.Playing) waveOut.Pause();
}
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
if (waveOut != null)
{
audioFileReader.CurrentTime = TimeSpan.FromSeconds(audioFileReader.TotalTime.TotalSeconds * trackBar1.Value / 100.0);
}
}
}
}
当用户听到听写时,跳过大于1分钟的静音。
---这是关于我的问题的其他信息---
我观看了PluralSight中有关如何实现ISampleProvider的部分。很简单,谢谢!这就是我所拥有的。 (见下文。)但不知道如何创建你所谈论的内存缓冲区。我使用BufferedWaveProvider吗?
公共类SkipSilenceSampleProvider:ISampleProvider {public WaveFormat WaveFormat {get {return sourceProvider.WaveFormat; }}
private readonly ISampleProvider sourceProvider;
public SkipSilenceSampleProvider(ISampleProvider sourceProvider)
{
this.sourceProvider = sourceProvider;
}
public int Read(float[] buffer, int offset, int count)
{
// Extract samples for the next minute and determine if the whole range is silence.
int readCount = sourceProvider.Read(buffer, offset, count);
return readCount;
}
}
你可以通过实现包装你的ISampleProvider
的自定义AudioFileReader
来实现这一点。在Read
方法中,您需要从源AudioFileReader
中提前阅读,以确定是否存在需要跳过的静音。所以你需要一个包含一分钟音频的内存缓冲区。然后Read
方法应该返回下一个非静默样本。除非您已到达源文件的末尾,否则Read
应始终返回所请求的样本数。
以上是关于由于我的程序(C#,NAudio)正在播放音频文件,如果它遇到1分钟的沉默,我想跳过它的主要内容,如果未能解决你的问题,请参考以下文章