このWaveTone
クラス (私がググったばかりのものの 1 つを使用していると仮定します) は、おそらく無限のデータ ストリームを提供します。出力を特定の期間に制限する場合は、特定の量のデータを別のバッファー/ストリームにロードするか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;
}
}