Share:

Signal Generator In C# | Saatody | Amit Padhiyar

using System;
using System.Diagnostics;

namespace SGDemo
{
/// <summary>
/// Types of signal.
/// </summary>
public enum SignalTypes
{
Sine,
Square,
Triangle,
Sawtooth
}

/// <summary>
/// Directions of signal.
/// </summary>
public enum Directions
{
Forward,
Backward
}

/// <summary>
/// Signal generator.
/// </summary>
public class SignalGenerator
{
/// <summary>
/// Shift signal on y axis. Value can be less than 0 too.
/// </summary>
private float offset = 0f;
public float Offset
{
set
{
offset = value;
}
get
{
return offset;
}
}

/// <summary>
/// Amplitudet or height of signal. Value can be less than 0 too.
/// </summary>
private float amplitude = 0f;
public float Amplitude
{
set
{
amplitude = value;
}
get
{
return amplitude;
}
}

/// <summary>
/// Phase is kind of curve. The signal curve depends on signal type. Value can be less than 0 too.
/// </summary>
private float phase = 0f;
public float Phase
{
set
{
phase = value;
}
get
{
return phase;
}
}

/// <summary>
/// Shift signal on x axis. Value can be less than 0 too.
/// </summary>
private float phaseShifting = 0f;
public float PhaseShifting
{
set
{
phaseShifting = value;
}
get
{
return phaseShifting;
}
}

/// <summary>
/// Cycles per second. It is kind of speed parameter for a signal. Value can be less than 0 too.
/// </summary>
private float frequency = 0f;
public float Frequency
{
set
{
frequency = value;
}
get
{
return frequency;
}
}

/// <summary>
/// Signal type.
/// </summary>
private SignalTypes signalType = SignalTypes.Sine;
public SignalTypes SignalType
{
set
{
signalType = value;
}
get
{
return signalType;
}
}

/// <summary>
/// Invert the signal curve.
/// True means -1f. And,
/// False means 1f.
/// </summary>
// True == -1f
// False == +1f
private float InvertValue = +1f;
private bool invert = false;
public bool Invert
{
set
{
invert = value;
if (invert == true)
{
InvertValue = -1f;
}
else if (invert == false)
{
InvertValue = +1f;
}
}
get
{
return invert;
}
}

/// <summary>
/// Signal direction can be forward or backward.
/// </summary>
// For Forward Direction,
// If Phase Negative, Then DirectionValue Will Be +1f.
// If Phase Positive, Then DirectionValue Will Be -1f.
// For Backward Direction,
// If Phase Negative, Then DirectionValue Will Be -1f.
// If Phase Positive, Then DirectionValue Will Be +1f.
private float DirectionValue = -1f;
private Directions direction = Directions.Forward;
public Directions Direction
{
set
{
direction = value;
if (direction == Directions.Forward)
{
if (Phase < 0)
{
DirectionValue = +1f;
}
else if (Phase >= 0)
{
DirectionValue = -1f;
}
}
else if (direction == Directions.Backward)
{
if (Phase < 0)
{
DirectionValue = -1f;
}
else if (Phase >= 0)
{
DirectionValue = +1f;
}
}
}
get
{
return direction;
}
}

private long StartTime = Stopwatch.GetTimestamp();
private long TicksPerSecond = Stopwatch.Frequency;
private bool IsStopped = true;
private long PreviousStartTime = 0L;
private long StoppedAt = 0L;

/// <summary>
/// Get value by time.
/// </summary>
/// <param name="Time">Format of Time: Stopwatch.GetTimestamp() - Stopwatch.Frequency.</param>
public float GetValue(float Time)
{
float Value = 0f;
float T = Frequency * Time + (Phase * DirectionValue);
switch (SignalType)
{
case SignalTypes.Sine: // sin( 2 * pi * t )
Value = (float)Math.Sin(2f * Math.PI * T);
break;
case SignalTypes.Square: // sign( sin( 2 * pi * t ) )
Value = Math.Sign(Math.Sin(2f * Math.PI * T));
break;
case SignalTypes.Triangle: // 2 * abs( t - 2 * floor( t / 2 ) - 1 ) - 1
Value = 1f - 4f * (float)Math.Abs(Math.Round(T - 0.25f) - (T - 0.25f));
break;
case SignalTypes.Sawtooth: // 2 * ( t/a - floor( t/a + 1/2 ) )
Value = 2f * (T - (float)Math.Floor(T + 0.5f));
break;
}

return (InvertValue * Amplitude * Value + Offset);
}

/// <summary>
/// Get value by time. Time will auto generate by inner stopwatch.
/// </summary>
public float GetValue()
{
float Time = 0.0f;
if (IsStopped == true)
{
Time = (float)(PreviousStartTime - StartTime) / TicksPerSecond;
StoppedAt = PreviousStartTime;
}
else
{
PreviousStartTime = Stopwatch.GetTimestamp();
if (StoppedAt != 0)
{
StartTime += (PreviousStartTime - StoppedAt);
StoppedAt = 0;

}
Time = (float)(PreviousStartTime - StartTime) / TicksPerSecond;
}

return GetValue(Time);
}

/// <summary>
/// Start or play signal generator. This will work with GetValue() only.
/// </summary>
public void Start()
{
IsStopped = false;
}

/// <summary>
/// Stop or pause signal generator. This will work with GetValue() only.
/// </summary>
public void Stop()
{
IsStopped = true;
}

/// <summary>
/// Reset signal generator. This will work with GetValue() only.
/// </summary>
public void Reset()
{
StartTime = Stopwatch.GetTimestamp();
PreviousStartTime = StartTime;
}

/// <summary>
/// Synchronize this signal generator with other signal generator.
/// </summary>
/// <param name="Instance">Another signal generator.</param>
public void Synchronize(SignalGenerator Instance)
{
StartTime = Instance.StartTime;
TicksPerSecond = Instance.TicksPerSecond;
}
}
}

Comments

Popular posts from this blog

Get Color From Pixel C# WPF | Saatody | Amit Padhiyar

Basic Audio Operations With MP3 And Wave Files Using NAudio C#

Create Drag And Drop Operation Between DevExpress GridControl And Custom WPF UI | Saatody | Amit Padhiyar