Skip to content

Commit 93ff076

Browse files
committed
Fix downsampler producing incorrect output when ratio 0.5 < x < 1.0
Add I/Q support to timing error detector Fix PSK/QAM generator not applying constant doppler effects properly Replace Integrator.Preload() with Integrator.SetValue(), as they do the same thing
1 parent 094d9fa commit 93ff076

File tree

5 files changed

+153
-96
lines changed

5 files changed

+153
-96
lines changed

SignalTest/AGC.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public AGC(float targetAmplitude, float maxGain)
6969
_isAdaptAllowed = true;
7070

7171
_gainIntegrator = new Integrator(1f, (1f / 44100f) * 1500f);
72-
_gainIntegrator.Preload(1.0f);
72+
_gainIntegrator.SetValue(1.0f);
7373
_gain = 1.0f;
7474
}
7575

SignalTest/Downsampler.cs

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,87 +14,48 @@ public class Downsampler
1414
private float _invRatio;
1515
private float _lastSample;
1616
private float _sampleCounter;
17-
private bool _needsMoreInput;
1817

1918

2019
public Downsampler(double inputSampleRate)
2120
{
2221
_inputSampleRate = inputSampleRate;
2322
_firBuffer = new float[9];
2423

25-
_needsMoreInput = true;
26-
2724
_sampleCounter = 0f;
2825
SetRatio(1f);
2926
}
3027

3128

3229
public void SupplyInput(float sample)
3330
{
34-
if (!_needsMoreInput)
35-
return;
36-
3731
ShiftArrayLeft(_firBuffer, sample);
38-
_needsMoreInput = false;
3932
}
4033

4134
public bool Next()
4235
{
43-
if (_needsMoreInput)
44-
return false;
45-
4636
bool returnVal = false;
4737
if (_ratio <= 1f)
4838
{
49-
//Console.WriteLine("{0:F4}", _sampleCounter);
50-
5139
if (_sampleCounter < 1f)
5240
{
5341
float result = 0f;
54-
//for (int i = 0; i < _firBuffer.Length; i++)
55-
//{
56-
// result += (float)(Sinc((i - (_firBuffer.Length / 2)) - (_sampleCounter - (int)_sampleCounter), 1.0) * _firBuffer[i]);
57-
//}
58-
59-
// Linear decimation seems to perform better than the sinc-based decimation from above
60-
float dist = (_sampleCounter - (int)_sampleCounter);
61-
result = (_firBuffer[_firBuffer.Length - 2] * (1f - dist)) + (_firBuffer[_firBuffer.Length - 1] * dist);
42+
for (int i = 0; i < _firBuffer.Length; i++)
43+
{
44+
result += (float)(Sinc((i - (_firBuffer.Length / 2)) - (_sampleCounter - (int)_sampleCounter), 1.0) * _firBuffer[i]);
45+
}
6246

6347
_lastSample = result;
6448

6549
_sampleCounter += _invRatio;
6650
returnVal = true;
6751
}
68-
//else
69-
{
70-
_sampleCounter--;
71-
}
72-
73-
74-
75-
//// If the counter is 0 < x < 1, we need more input
76-
//if (_sampleCounter == 0f || _sampleCounter >= 1f)
77-
//{
78-
// _sampleCounter -= (int)_sampleCounter;
79-
// returnVal = true;
80-
//}
81-
////else
82-
83-
//{
84-
// if (_sampleCounter == -1)
85-
// _sampleCounter = 0f;
86-
// else
87-
// _sampleCounter += _ratio;
88-
//}
52+
_sampleCounter--;
8953
}
9054
else
9155
{
9256
throw new NotImplementedException("Raising the sampling rate is currently not supported");
9357
}
9458

95-
_needsMoreInput = !returnVal;
96-
//Console.WriteLine(returnVal);
97-
9859
return returnVal;
9960
}
10061

SignalTest/Gardner.cs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,65 @@ namespace SignalTest
99
class Gardner
1010
{
1111
private bool _flipFlop;
12-
private float _prevSample;
13-
private float _currentSample;
14-
private float _middleSample;
12+
private float _prevSampleI;
13+
private float _prevSampleQ;
14+
private float _currentSampleI;
15+
private float _currentSampleQ;
16+
private float _middleSampleI;
17+
private float _middleSampleQ;
1518

1619

17-
public Gardner(float baudRate)
20+
public Gardner()
1821
{
1922
}
2023

2124

2225
public float Process(float sample)
26+
{
27+
return Process(sample, 0);
28+
}
29+
30+
public float Process(float sampleI, float sampleQ)
2331
{
2432
// Shift symbol samples over
25-
_prevSample = _middleSample;
26-
_middleSample = _currentSample;
27-
_currentSample = sample;
33+
_prevSampleI = _middleSampleI;
34+
_prevSampleQ = _middleSampleQ;
35+
_middleSampleI = _currentSampleI;
36+
_middleSampleQ = _currentSampleQ;
37+
_currentSampleI = sampleI;
38+
_currentSampleQ = sampleQ;
2839

2940
if ((_flipFlop ^= true))
3041
{
3142
// Every other sample, calculate error, but only if there is a transition
3243
// using Jonti's (modified gardner) method for M-QAM and M-PAM timing recovery
3344
// This method also works for QPSK and BPSK, and 2-PAM as well
34-
if (Math.Sign(_prevSample) != Math.Sign(_currentSample))
45+
float error = 0f;
46+
47+
// Calculate for I
48+
if (Math.Sign(_prevSampleI) != Math.Sign(_currentSampleI))
49+
{
50+
float localError = 0.5f * (_currentSampleI + _prevSampleI) - _middleSampleI;
51+
if (_currentSampleI > _prevSampleI)
52+
{
53+
localError = -localError;
54+
}
55+
56+
error += localError;
57+
}
58+
59+
// Calculate for Q
60+
if (Math.Sign(_prevSampleQ) != Math.Sign(_currentSampleQ))
3561
{
36-
float error = 0.5f * (_currentSample + _prevSample) - _middleSample;
37-
if (_currentSample > _prevSample)
62+
float localError = 0.5f * (_currentSampleQ + _prevSampleQ) - _middleSampleQ;
63+
if (_currentSampleQ > _prevSampleQ)
3864
{
39-
error = -error;
65+
localError = -localError;
4066
}
4167

42-
return error;
68+
error += localError;
4369
}
70+
return error;
4471
}
4572

4673
return 0;

SignalTest/Integrator.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public Integrator(float pGain, float iGain, float preloadValue)
4242
{
4343
_iGain = iGain;
4444
_pGain = pGain;
45-
Preload(preloadValue);
45+
SetValue(preloadValue);
4646
}
4747

4848

@@ -54,10 +54,6 @@ public float Process(float sample)
5454
return _lastValue = (pTerm + (_iState * _iGain));
5555
}
5656

57-
public void Preload(float value)
58-
{
59-
_iState = (value / _iGain);
60-
}
6157

6258
public float GetValue()
6359
{
@@ -73,5 +69,10 @@ public void SetValue(float value)
7369
{
7470
_iState = (value / _iGain);
7571
}
72+
73+
public void Reset()
74+
{
75+
_iState = 0f;
76+
}
7677
}
7778
}

0 commit comments

Comments
 (0)