1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-15 12:51:49 -05:00

ATV demod: fixed AM demodulator. Fixes issue #459

This commit is contained in:
f4exb 2020-06-29 08:46:09 +02:00
parent 587a8b4e1e
commit 9c05329bb3
2 changed files with 51 additions and 51 deletions

View File

@ -42,11 +42,11 @@ ATVDemodSink::ATVDemodSink() :
m_verticalSynchroDetected(false), m_verticalSynchroDetected(false),
m_ampLineSum(0.0f), m_ampLineSum(0.0f),
m_ampLineAvg(0.0f), m_ampLineAvg(0.0f),
m_effMin(2000000.0f), m_effMin(2.0f),
m_effMax(-2000000.0f), m_effMax(-2.0f),
m_ampMin(0.0f), m_ampMin(-1.0f),
m_ampMax(0.3f), m_ampMax(1.0f),
m_ampDelta(0.3f), m_ampDelta(2.0f),
m_ampSample(0.0f), m_ampSample(0.0f),
m_colIndex(0), m_colIndex(0),
m_sampleIndex(0), m_sampleIndex(0),
@ -170,7 +170,7 @@ void ATVDemodSink::demod(Complex& c)
{ {
//Amplitude FM //Amplitude FM
magSq = fltI*fltI + fltQ*fltQ; magSq = fltI*fltI + fltQ*fltQ;
m_objMagSqAverage(magSq); m_magSqAverage(magSq);
sampleNorm = sqrt(magSq); sampleNorm = sqrt(magSq);
sampleNormI = fltI/sampleNorm; sampleNormI = fltI/sampleNorm;
sampleNormQ = fltQ/sampleNorm; sampleNormQ = fltQ/sampleNorm;
@ -225,14 +225,14 @@ void ATVDemodSink::demod(Complex& c)
{ {
//Amplitude AM //Amplitude AM
magSq = fltI*fltI + fltQ*fltQ; magSq = fltI*fltI + fltQ*fltQ;
m_objMagSqAverage(magSq); m_magSqAverage(magSq);
sampleNorm = sqrt(magSq); sampleNorm = sqrt(magSq);
sample = sampleNorm / SDR_RX_SCALEF; sample = 2.0 * (sampleNorm / SDR_RX_SCALEF) - 1.0;
} }
else if ((m_settings.m_atvModulation == ATVDemodSettings::ATV_USB) || (m_settings.m_atvModulation == ATVDemodSettings::ATV_LSB)) else if ((m_settings.m_atvModulation == ATVDemodSettings::ATV_USB) || (m_settings.m_atvModulation == ATVDemodSettings::ATV_LSB))
{ {
magSq = fltI*fltI + fltQ*fltQ; magSq = fltI*fltI + fltQ*fltQ;
m_objMagSqAverage(magSq); m_magSqAverage(magSq);
sampleNorm = sqrt(magSq); sampleNorm = sqrt(magSq);
Real bfoValues[2]; Real bfoValues[2];
@ -254,13 +254,13 @@ void ATVDemodSink::demod(Complex& c)
{ {
float rawDeviation; float rawDeviation;
sample = m_objPhaseDiscri.phaseDiscriminatorDelta(c, magSq, rawDeviation) + 0.5f; sample = m_objPhaseDiscri.phaseDiscriminatorDelta(c, magSq, rawDeviation) + 0.5f;
m_objMagSqAverage(magSq); m_magSqAverage(magSq);
sampleNorm = sqrt(magSq); sampleNorm = sqrt(magSq);
} }
else else
{ {
magSq = fltI*fltI + fltQ*fltQ; magSq = fltI*fltI + fltQ*fltQ;
m_objMagSqAverage(magSq); m_magSqAverage(magSq);
sampleNorm = sqrt(magSq); sampleNorm = sqrt(magSq);
sample = 0.0f; sample = 0.0f;
} }
@ -281,7 +281,7 @@ void ATVDemodSink::demod(Complex& c)
m_effMax = sample; m_effMax = sample;
} }
if (m_amSampleIndex < m_samplesPerLine * m_settings.m_nbLines) // do not extend estimation period past a full image if (m_amSampleIndex < m_samplesPerLine * m_settings.m_nbLines * m_settings.m_fps * 5) // calculate on 5s
{ {
m_amSampleIndex++; m_amSampleIndex++;
} }
@ -290,25 +290,25 @@ void ATVDemodSink::demod(Complex& c)
// scale signal based on extrema on the estimation period // scale signal based on extrema on the estimation period
m_ampMin = m_effMin; m_ampMin = m_effMin;
m_ampMax = m_effMax; m_ampMax = m_effMax;
m_ampDelta = (m_ampMax - m_ampMin) * 0.3f; m_ampDelta = (m_ampMax - m_ampMin);
m_ampSample = 0.3f; // allow passing to fine scale estimation m_ampSample = 0.3f; // allow passing to fine scale estimation
if (m_ampDelta <= 0.0) { if (m_ampDelta <= 0.0) {
m_ampDelta = 0.3f; m_ampDelta = 1.0f;
} }
qDebug("ATVDemod::demod: m_ampMin: %f m_ampMax: %f m_ampDelta: %f", m_ampMin, m_ampMax, m_ampDelta); qDebug("ATVDemod::demod: m_ampMin: %f m_ampMax: %f m_ampDelta: %f", m_ampMin, m_ampMax, m_ampDelta);
//Reset extrema //Reset extrema
m_effMin = 2000000.0f; m_effMin = 2.0f;
m_effMax = -2000000.0; m_effMax = -2.0f;
m_amSampleIndex = 0; m_amSampleIndex = 0;
} }
//Normalisation of current sample //Normalisation of current sample
sample -= m_ampMin; sample -= m_ampMin;
sample /= (m_ampDelta * 3.1f); sample /= (m_ampDelta*0.9);
} }
sample = m_settings.m_invertVideo ? 1.0f - sample : sample; sample = m_settings.m_invertVideo ? 1.0f - sample : sample;

View File

@ -45,7 +45,7 @@ public:
void setScopeSink(BasebandSampleSink* scopeSink) { m_scopeSink = scopeSink; } void setScopeSink(BasebandSampleSink* scopeSink) { m_scopeSink = scopeSink; }
void setTVScreen(TVScreen *tvScreen) { m_registeredTVScreen = tvScreen; } //!< set by the GUI void setTVScreen(TVScreen *tvScreen) { m_registeredTVScreen = tvScreen; } //!< set by the GUI
double getMagSq() const { return m_objMagSqAverage; } //!< Beware this is scaled to 2^30 double getMagSq() const { return m_magSqAverage; } //!< Beware this is scaled to 2^30
bool getBFOLocked(); bool getBFOLocked();
void setVideoTabIndex(int videoTabIndex) { m_videoTabIndex = videoTabIndex; } void setVideoTabIndex(int videoTabIndex) { m_videoTabIndex = videoTabIndex; }
@ -147,7 +147,7 @@ private:
int m_colIndex; int m_colIndex;
int m_sampleIndex; int m_sampleIndex;
unsigned int m_amSampleIndex; int m_amSampleIndex;
int m_rowIndex; int m_rowIndex;
int m_lineIndex; int m_lineIndex;
@ -158,7 +158,7 @@ private:
//*************** RF *************** //*************** RF ***************
MovingAverageUtil<double, double, 32> m_objMagSqAverage; MovingAverageUtil<double, double, 32> m_magSqAverage;
NCO m_nco; NCO m_nco;
SimplePhaseLock m_bfoPLL; SimplePhaseLock m_bfoPLL;
@ -194,12 +194,12 @@ private:
// Floor Detection (0.1 nominal) // Floor Detection (0.1 nominal)
if (sample < m_settings.m_levelSynchroTop) if (sample < m_settings.m_levelSynchroTop)
{ {
if (m_synchroSamples == 0) // AM scale reset on transition if within range // if (m_synchroSamples == 0) // AM scale reset on transition if within range
{ // {
m_effMin = 2000000.0f; // m_effMin = 2000000.0f;
m_effMax = -2000000.0f; // m_effMax = -2000000.0f;
m_amSampleIndex = 0; // m_amSampleIndex = 0;
} // }
m_synchroSamples++; m_synchroSamples++;
} }
@ -209,16 +209,16 @@ private:
} }
// Refine AM scale estimation on HSync pulse sequence // Refine AM scale estimation on HSync pulse sequence
if (m_amSampleIndex == (3*m_numberSamplesPerHTop)/2) // if (m_amSampleIndex == (3*m_numberSamplesPerHTop)/2)
{ // {
m_ampMin = m_effMin; // m_ampMin = m_effMin;
m_ampMax = m_effMax; // m_ampMax = m_effMax;
m_ampDelta = (m_ampMax - m_ampMin); // m_ampDelta = (m_ampMax - m_ampMin);
if (m_ampDelta <= 0.0) { // if (m_ampDelta <= 0.0) {
m_ampDelta = 0.3f; // m_ampDelta = 0.3f;
} // }
} // }
// H sync pulse // H sync pulse
m_horizontalSynchroDetected = (m_synchroSamples == m_numberSamplesPerHTop); m_horizontalSynchroDetected = (m_synchroSamples == m_numberSamplesPerHTop);
@ -285,12 +285,12 @@ private:
// Floor Detection 0 // Floor Detection 0
if (sample < m_settings.m_levelSynchroTop) if (sample < m_settings.m_levelSynchroTop)
{ {
if ((m_synchroSamples == 0) && (m_ampSample > 0.25f) && (m_ampSample < 0.35f)) // AM scale reset on transition // if ((m_synchroSamples == 0) && (m_ampSample > 0.25f) && (m_ampSample < 0.35f)) // AM scale reset on transition
{ // {
m_effMin = 2000000.0f;; // m_effMin = 2000000.0f;;
m_effMax = -2000000.0f;; // m_effMax = -2000000.0f;;
m_amSampleIndex = 0; // m_amSampleIndex = 0;
} // }
m_synchroSamples++; m_synchroSamples++;
} }
@ -300,17 +300,17 @@ private:
} }
// Refine AM scale estimation on HSync pulse sequence // Refine AM scale estimation on HSync pulse sequence
if ((m_amSampleIndex == (3*m_numberSamplesPerHTop)/2) && (sample > 0.25f) && (sample < 0.35f)) // if ((m_amSampleIndex == (3*m_numberSamplesPerHTop)/2) && (sample > 0.25f) && (sample < 0.35f))
{ // {
m_ampSample = sample; // m_ampSample = sample;
m_ampMin = m_effMin; // m_ampMin = m_effMin;
m_ampMax = m_effMax; // m_ampMax = m_effMax;
m_ampDelta = (m_ampMax - m_ampMin); // m_ampDelta = (m_ampMax - m_ampMin);
if (m_ampDelta <= 0.0) { // if (m_ampDelta <= 0.0) {
m_ampDelta = 0.3f; // m_ampDelta = 0.3f;
} // }
} // }
// H sync pulse // H sync pulse
m_horizontalSynchroDetected = (m_synchroSamples == m_numberSamplesPerHTop) && (m_sampleIndex > (m_samplesPerLine/2) + m_numberSamplesPerLineSignals); m_horizontalSynchroDetected = (m_synchroSamples == m_numberSamplesPerHTop) && (m_sampleIndex > (m_samplesPerLine/2) + m_numberSamplesPerLineSignals);