播放每圈 NAudio 较低的波形
Playing waveform with NAudio lower for each turn
我正在尝试使用 NAudio 播放字节缓冲区。我为这个任务创建了一个 winforms 应用程序。
但是当我随后播放声音(使用 Math.sin 创建)时,每次播放的音量都会越来越低。为什么?
using System;
using System.Windows.Forms;
using NAudio.Wave;
namespace beeper
{
public partial class Form1 : Form
{
byte[] bytes;
const int sampling_freq = 44100;
public Form1()
{
InitializeComponent();
double freq = 1000;
var seconds = 0.5;
var length = (int)(seconds * sampling_freq);
bytes = new byte[length];
for (var i = 0; i < length; i++)
{
var offset = 80 * Math.Sin(i * freq / sampling_freq * Math.PI * 2);
bytes[i] = (byte)(128 + offset);
}
}
private void btnBeep_Click(object sender, EventArgs e)
{
var format = new WaveFormat(sampling_freq, 8, 1);
var provider = new BufferedWaveProvider(format);
provider.AddSamples(bytes, 0, bytes.Length);
var wo = new WaveOut();
wo.Init(provider);
wo.Play();
}
}
}
大胆录制
难怪当看到这个以某种奇怪的方式偏移和扭曲的波形时,它听起来就像是这样。我正在寻找一种模式,但我真的找不到。
将 button1_Click
事件正确更改为 WaveOut
的 Dispose
和 using
并等待声音结束似乎工作正常。否则我认为你需要使用一个全局 WaveOut
.
public Form1()
{
InitializeComponent();
double freq = 1000;
var length = (int)(seconds * sampling_freq);
bytes = new byte[length];
for (var i = 0; i < length; i++)
{
var offset = 80 * Math.Sin(i * freq / sampling_freq * Math.PI * 2);
bytes[i] = (byte)(128 + offset);
}
}
private void btnBeep_Click(object sender, EventArgs e)
{
var format = new WaveFormat(sampling_freq, 8, 1);
var provider = new BufferedWaveProvider(format);
provider.AddSamples(bytes, 0, bytes.Length);
using var wo = new WaveOut();
wo.Init(provider);
wo.Play();
Thread.Sleep((int)Math.Ceiling(1000*seconds) + 100);
}
每次单击播放按钮时,您都会添加一个全新的播放频道。如果您不关闭这些通道,那么它们将继续播放静音,因此您最终会得到多个静音通道与一个活跃声音混合的结果,从而得到您所看到的结果。按下按钮的次数越多,输出就越安静。
您需要在提示音结束后关闭频道(使用计时器或类似工具)或创建一个频道并重新使用它:
private BufferedWaveProvider provider;
private WaveOut waveOut;
private void btnBeep_Click(object sender, EventArgs e)
{
if (waveOut == null)
{
var format = new WaveFormat(sampling_freq, 8, 1);
provider = new BufferedWaveProvider(format);
waveOut = new WaveOut();
waveOut.Init(provider);
waveOut.Play();
}
provider.ClearBuffer();
provider.AddSamples(bytes, 0, bytes.Length);
}
调用 ClearBuffer
会删除任何剩余的缓冲样本,因此反复点击按钮不会只是排队整个输出堆栈。如果你想播放多个重叠的音调,你需要做多个通道或自己处理混音。
如果您确实想要重叠,我建议您查看 MixingWaveProvider32
。目前它有点受限,但您应该能够按原样使用它(使用适当的转换示例提供程序)。
我正在尝试使用 NAudio 播放字节缓冲区。我为这个任务创建了一个 winforms 应用程序。
但是当我随后播放声音(使用 Math.sin 创建)时,每次播放的音量都会越来越低。为什么?
using System;
using System.Windows.Forms;
using NAudio.Wave;
namespace beeper
{
public partial class Form1 : Form
{
byte[] bytes;
const int sampling_freq = 44100;
public Form1()
{
InitializeComponent();
double freq = 1000;
var seconds = 0.5;
var length = (int)(seconds * sampling_freq);
bytes = new byte[length];
for (var i = 0; i < length; i++)
{
var offset = 80 * Math.Sin(i * freq / sampling_freq * Math.PI * 2);
bytes[i] = (byte)(128 + offset);
}
}
private void btnBeep_Click(object sender, EventArgs e)
{
var format = new WaveFormat(sampling_freq, 8, 1);
var provider = new BufferedWaveProvider(format);
provider.AddSamples(bytes, 0, bytes.Length);
var wo = new WaveOut();
wo.Init(provider);
wo.Play();
}
}
}
大胆录制
难怪当看到这个以某种奇怪的方式偏移和扭曲的波形时,它听起来就像是这样。我正在寻找一种模式,但我真的找不到。
将 button1_Click
事件正确更改为 WaveOut
的 Dispose
和 using
并等待声音结束似乎工作正常。否则我认为你需要使用一个全局 WaveOut
.
public Form1()
{
InitializeComponent();
double freq = 1000;
var length = (int)(seconds * sampling_freq);
bytes = new byte[length];
for (var i = 0; i < length; i++)
{
var offset = 80 * Math.Sin(i * freq / sampling_freq * Math.PI * 2);
bytes[i] = (byte)(128 + offset);
}
}
private void btnBeep_Click(object sender, EventArgs e)
{
var format = new WaveFormat(sampling_freq, 8, 1);
var provider = new BufferedWaveProvider(format);
provider.AddSamples(bytes, 0, bytes.Length);
using var wo = new WaveOut();
wo.Init(provider);
wo.Play();
Thread.Sleep((int)Math.Ceiling(1000*seconds) + 100);
}
每次单击播放按钮时,您都会添加一个全新的播放频道。如果您不关闭这些通道,那么它们将继续播放静音,因此您最终会得到多个静音通道与一个活跃声音混合的结果,从而得到您所看到的结果。按下按钮的次数越多,输出就越安静。
您需要在提示音结束后关闭频道(使用计时器或类似工具)或创建一个频道并重新使用它:
private BufferedWaveProvider provider;
private WaveOut waveOut;
private void btnBeep_Click(object sender, EventArgs e)
{
if (waveOut == null)
{
var format = new WaveFormat(sampling_freq, 8, 1);
provider = new BufferedWaveProvider(format);
waveOut = new WaveOut();
waveOut.Init(provider);
waveOut.Play();
}
provider.ClearBuffer();
provider.AddSamples(bytes, 0, bytes.Length);
}
调用 ClearBuffer
会删除任何剩余的缓冲样本,因此反复点击按钮不会只是排队整个输出堆栈。如果你想播放多个重叠的音调,你需要做多个通道或自己处理混音。
如果您确实想要重叠,我建议您查看 MixingWaveProvider32
。目前它有点受限,但您应该能够按原样使用它(使用适当的转换示例提供程序)。