|
'******************************************************************************
|
'* ChirpGenerator *
|
'* *
|
'* This class implements a custom control to generate a chirp signal *
|
'* The user can modify the frequency,output power and decay in real time. *
|
'* *
|
'* We calculate the minimum samples of the tone that we need to generate a *
|
'* continous signal with the given sampling and output frequency. *
|
'* Then, each time the caller want to have a new fragment of the signal, we *
|
'* repeat the calculated samples as many times as we need to fill the output *
|
'* buffer. *
|
'* *
|
'* EQUITEL - C.V. February 2007 ALMDI *
|
'******************************************************************************
|
|
Imports System.ComponentModel
|
Imports System.Math
|
|
Public Class ChirpGenerator
|
Private mInternalBuffer As Short()
|
Private mBufSize As Integer
|
Private mSamplingFrequency As Integer = 8000
|
Private mFrequency As Integer = 1000
|
Private mPower As Double = -0
|
Private mSignalIsGenerated As Boolean = False
|
Private mDecayTime As Integer
|
Private mPeriodSamples As Integer = 160
|
|
|
|
|
#Region "Propiedades"
|
|
<Category("Signal"), DefaultValue(GetType(Integer), "8000"), _
|
Description("Sampling frequency of the desired signal")> _
|
Public Property SamplingFrequency() As Integer
|
Get
|
Return mSamplingFrequency
|
End Get
|
Set(ByVal value As Integer)
|
If value >= 8000 AndAlso value <= 96000 Then
|
mSamplingFrequency = value
|
End If
|
End Set
|
End Property
|
|
<Category("Signal"), DefaultValue(GetType(Integer), "1000"), _
|
Description("Frequency of the desired signal")> _
|
Public Property Frequency() As Integer
|
Get
|
Return mFrequency
|
End Get
|
Set(ByVal value As Integer)
|
If value >= 100 AndAlso value <= mSamplingFrequency / 2 Then
|
mFrequency = value
|
CtrlFrequency.Value = value
|
lblFrequency.Text = Format(mFrequency / 1000, "0.0 kHz")
|
CalculateSignal()
|
End If
|
End Set
|
End Property
|
|
<Category("Signal"), DefaultValue(GetType(Integer), "-100"), _
|
Description("Relative output level of the signal in decibels")> _
|
Public Property Power() As Double
|
Get
|
Return mPower
|
End Get
|
Set(ByVal value As Double)
|
If value >= -100 AndAlso value <= 0 Then
|
mPower = value
|
CtrlPower.Value = value
|
lblPower.Text = Format(value, "0 dB")
|
CalculateSignal()
|
End If
|
End Set
|
End Property
|
|
|
<Category("Signal"), DefaultValue(GetType(Integer), "10"), _
|
Description("Time the signal takes to fall to the 10% of amplitude (in ms)")> _
|
Public Property T_Decay() As Double
|
Get
|
If mDecayTime < 1 Then mDecayTime = 1
|
Return mDecayTime
|
End Get
|
Set(ByVal value As Double)
|
If value <= 100 AndAlso value > 1 Then
|
mDecayTime = value
|
CtrlDecay.Value = value
|
LblDecay.Text = Format(value, "000 ms")
|
CalculateSignal()
|
End If
|
End Set
|
End Property
|
|
|
|
|
<Category("Signal"), DefaultValue(GetType(Integer), "20"), _
|
Description("Period of the Chirp (in ms)")> _
|
Public Property ChirpPeriod() As Integer
|
Get
|
Return (mPeriodSamples * 1000) / mSamplingFrequency
|
End Get
|
Set(ByVal value As Integer)
|
If value <= 1000 AndAlso value > 1 Then
|
mPeriodSamples = value * (mSamplingFrequency / 1000)
|
LblPeriod.Text = Format(value, "000 ms")
|
CalculateSignal()
|
End If
|
End Set
|
End Property
|
|
|
#End Region
|
|
|
Private Sub CalculateSignal()
|
Dim i As Integer
|
Dim t As Double
|
Dim W As Double
|
Dim Factor As Double
|
Dim Vmax As Integer
|
|
|
ReDim mInternalBuffer(mPeriodSamples - 1)
|
mBufSize = mPeriodSamples
|
W = 2 * 3.141592659 * mFrequency
|
Factor = 20 ^ (mPower / (10 * 3))
|
Vmax = Int(32767 * Factor)
|
For i = 0 To mPeriodSamples - 1
|
t = i * (1 / mSamplingFrequency)
|
Try
|
mInternalBuffer(i) = Vmax * Sin(W * t) * Exp(-t / (T_Decay / 2302))
|
Catch e As Exception
|
MsgBox("Chirp signal generation error", MsgBoxStyle.Critical)
|
End Try
|
Next
|
mSignalIsGenerated = True
|
End Sub
|
|
Private Sub Power_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CtrlPower.Scroll
|
Power = CtrlPower.Value
|
End Sub
|
|
Private Sub Frequency_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CtrlFrequency.Scroll
|
CtrlFrequency.Value = Int(CtrlFrequency.Value / 100) * 100
|
Frequency = CtrlFrequency.Value
|
End Sub
|
|
Private Sub CtrlDecay_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CtrlDecay.Scroll
|
T_Decay = CtrlDecay.Value
|
End Sub
|
|
Private Sub CtrlPeriod_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CtrlPeriod.Scroll
|
ChirpPeriod = CtrlPeriod.Value
|
End Sub
|
|
Public Sub OutputPacket(ByRef Buffer As Short(), ByVal NumSamples As Integer)
|
Dim i As Integer
|
Static mInternalBufferPointer As Integer = 0
|
|
If Not mSignalIsGenerated Then CalculateSignal()
|
For i = 0 To NumSamples - 1
|
Buffer(i) = mInternalBuffer(mInternalBufferPointer)
|
mInternalBufferPointer += 1
|
If mInternalBufferPointer = mBufSize Then
|
mInternalBufferPointer = 0
|
End If
|
Next
|
End Sub
|
|
End Class
|