该类WaveTone
(假设您使用的是我刚刚搜索的其中一个)可能提供了无穷无尽的数据流。如果要将输出限制在特定的持续时间,则需要将特定数量的数据加载到另一个缓冲区/流中,或者修改WaveTone
类以停止生成超过持续时间的数据。
像这样的东西:
class WaveTone : WaveStream
{
readonly WaveFormat Format;
public readonly double Frequency;
public readonly double Amplitude;
public readonly double Duration;
readonly long streamLength;
long pos;
const double timeIncr = 1 / 44100.0;
readonly double sinMult;
public WaveTone(double freq, double amp)
: this(freq, amp, 0)
{ }
public WaveTone(double freq, double amp, double dur)
{
Format = new WaveFormat(44100, 16, 1);
Frequency = freq;
Amplitude = Math.Min(1, Math.Max(0, amp));
Duration = dur;
streamLength = Duration == 0 ? long.MaxValue : (long)(44100 * 2 * Duration);
pos = 0;
sinMult = Math.PI * 2 * Frequency;
}
public override WaveFormat WaveFormat
{
get { return Format; }
}
public override long Length
{
get { return streamLength; }
}
public override long Position
{
get { return pos; }
set { pos = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
if (pos >= streamLength)
return 0;
int nSamples = count / 2;
if ((pos + nSamples * 2) > streamLength)
nSamples = (int)(streamLength - pos) / 2;
double time = pos / (44100 * 2.0);
int rc = 0;
for (int i = 0; i < nSamples; i++, time += timeIncr, ++rc, pos += 2)
{
double val = Amplitude * Math.Sin(sinMult * time);
short sval = (short)(Math.Round(val * (short.MaxValue - 1)));
buffer[offset + i * 2] = (byte)(sval & 0xFF);
buffer[offset + i * 2 + 1] = (byte)((sval >> 8) & 0xFF);
}
return rc * 2;
}
}