Вы можете использовать NAudio и создать производный WaveStream, который выводит синусоидальные или прямоугольные волны, которые можно вывести на звуковую карту или записать в файл WAV . Если вы использовали 32-битные выборки с плавающей запятой, вы могли бы записать значения непосредственно из функции sin без необходимости масштабирования, поскольку она уже находится между -1 и 1.
Что касается точности, вы имеете в виду именно правильную частоту или точно правильную форму волны? Нет такой вещи как истинная прямоугольная волна, и даже синусоида, вероятно, будет иметь несколько очень тихих артефактов на других частотах. Если важна точность частоты, вы полагаетесь на стабильность и точность часов в вашей звуковой карте. Сказав это, я предположил бы, что точность будет достаточно хорошей для большинства применений.
Вот пример кода, который делает выборку 1 кГц с частотой выборки 8 кГц и 16-битными выборками (то есть не с плавающей запятой):
int sampleRate = 8000;
short[] buffer = new short[8000];
double amplitude = 0.25 * short.MaxValue;
double frequency = 1000;
for (int n = 0; n < buffer.Length; n++)
{
buffer[n] = (short)(amplitude * Math.Sin((2 * Math.PI * n * frequency) / sampleRate));
}