using NAudio.Wave;
namespace TravelEar.Helper;
/// Continuous sine tone for --tone: lets the OBS capture spike run with no game.
internal sealed class ToneWaveProvider : IWaveProvider
{
private readonly int _channels;
private readonly float _amplitude;
private readonly double _phaseStep;
private double _phase;
public WaveFormat WaveFormat { get; }
public ToneWaveProvider(int sampleRate, int channels, float frequencyHz, float amplitude)
{
_channels = channels;
_amplitude = amplitude;
_phaseStep = 2 * Math.PI * frequencyHz / sampleRate;
WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels);
}
public int Read(byte[] buffer, int offset, int count)
{
var frames = count / (sizeof(float) * _channels);
var floats = System.Runtime.InteropServices.MemoryMarshal.Cast(buffer.AsSpan(offset, frames * _channels * sizeof(float)));
for (var f = 0; f < frames; f++)
{
var s = (float)(Math.Sin(_phase) * _amplitude);
_phase += _phaseStep;
if (_phase > 2 * Math.PI) _phase -= 2 * Math.PI;
for (var c = 0; c < _channels; c++) floats[f * _channels + c] = s;
}
return frames * _channels * sizeof(float);
}
}