Creating Sine or Square Wave in C#

Creating sine or square wave in C#

You can use NAudio and create a derived WaveStream that outputs sine or square waves which you could output to the soundcard or write to a WAV file. If you used 32-bit floating point samples you could write the values directly out of the sin function without having to scale as it already goes between -1 and 1.

As for accuracy, do you mean exactly the right frequency, or exactly the right wave shape? There is no such thing as a true square wave, and even the sine wave will likely have a few very quiet artifacts at other frequencies. If it's accuracy of frequency that matters, you are reliant on the stability and accuracy of the clock in your sound card. Having said that, I would imagine that the accuracy would be good enough for most uses.

Here's some example code that makes a 1 kHz sample at a 8 kHz sample rate and with 16 bit samples (that is, not floating point):

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));
}

How to generate a square wave using C#?

The easiest way I can think of is to set y to be sign of a sine wave, making allowances for when it equals zero. I don't know if C# has the triple-operator, but something like this might work:

y[k] = Math.Sin(freq * k)>=0?A:-1*A;

How do I automatically calculate the values of a sine wave for a given number of positions?

A sine wave equation is y = sin x (for the "unit" sine wave).

What you need to do is divide your x axis into the number of positions that you want to display, then display those x values.

Since your x max is 1, use:
NOTE: Since a sine wave doesn't end at 1 on the x-axis, I am assuming that you want it to be bound to those values, as such the x-axis will be scaled so that 1.0 = 2*Pi

double xStep = 1.0/NumberOfPositions;

then do:

for(double x = 0.0; x < 1.0; x += xStep)
{
double yValue = Math.Sin(x*2*Math.PI); // Since you want 2*PI to be at 1
}

OR:

double xStep = 1.0/NumberOfPositions;
double[] yValues = new double[NumberOfPositions+1];
double[] xValues = new double[NumberOfPositions+1];
for (int i = 0; i < NumberOfPositions+1; i++)
{
xValues[i] = i * xStep;
yValues[i] = Math.Sin(xValues[i]*2*Math.PI); // Since you want 2*PI to be @ 1
}

Draw Sine Wave in WPF

Draw lines between points which you calculate with Math.Sin function. You'll have to decide how many points per cycle to use, a compromise between drawing speed and accuracy. Presumably you'll also need to scale the amplitude to suit the area on the screen, since Sin function will return a value between +1 and -1.



Related Topics



Leave a reply



Submit