1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-04-29 02:43:59 -04:00

Merge pull request #2621 from srcejon/inmarsat

Inmarsat: Improve frequency offset estimation and fix address coordinates
This commit is contained in:
Edouard Griffiths 2026-01-23 20:46:41 +01:00 committed by GitHub
commit cb3bc174c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 15 deletions

View File

@ -506,8 +506,8 @@ QString MultipartMessage::decodeAddress(QString serviceCode, QString addressHex,
if (coordinates)
{
int lat1Deg = west ? -latDeg : latDeg;
int lon1Deg = south ? -lonDeg : lonDeg;
int lat1Deg = south ? -latDeg : latDeg;
int lon1Deg = west ? -lonDeg : lonDeg;
int lat2Deg = lat1Deg + latExtentEast;
int lon2Deg = lon1Deg + latExtentNorth;
*latitude = lat1Deg + lat2Deg / 2;
@ -545,8 +545,8 @@ QString MultipartMessage::decodeAddress(QString serviceCode, QString addressHex,
if (coordinates)
{
int lat1Deg = west ? -latDeg : latDeg;
int lon1Deg = south ? -lonDeg : lonDeg;
int lat1Deg = south ? -latDeg : latDeg;
int lon1Deg = west ? -lonDeg : lonDeg;
QGeoCoordinate centre(lat1Deg, lon1Deg);
*latitude = lat1Deg;

View File

@ -65,7 +65,7 @@ FrequencyOffsetEstimate::FrequencyOffsetEstimate() :
FFTFactory *fftFactory = DSPEngine::instance()->getFFTFactory();
m_fftSequence = fftFactory->getEngine(m_fftSize, false, &m_fft);
m_fftCounter = 0;
m_fftWindow.create(FFTWindow::Rectangle, m_fftSize);
m_fftWindow.create(FFTWindow::Hanning, m_fftSize);
}
FrequencyOffsetEstimate::~FrequencyOffsetEstimate()
@ -108,16 +108,32 @@ void FrequencyOffsetEstimate::processOneSample(Complex& iq, bool locked)
}
}
Real idx = maxIdx;
if (maxIdx > m_fftSize / 2) {
idx -= m_fftSize; // Negative freqs are in second half
}
// Calculate power for current peak bin and frequency we're locked too
m_currentFreqMagSq = magSq(maxIdx);
m_freqMagSq = magSq(m_freqOffsetBin);
Real hzPerBin = InmarsatDemodSettings::CHANNEL_SAMPLE_RATE / (Real) m_fftSize;
int idx = maxIdx;
if (maxIdx > m_fftSize / 2) {
idx -= m_fftSize; // Negative freqs are in second half
// Quadratic interpolation using two bins either side of peak
if ((maxIdx != m_fftSize / 2) && (maxIdx != m_fftSize / 2 - 1))
{
int alphaIdx = maxIdx == 0 ? m_fftSize - 1 : maxIdx - 1;
int gammaIdx = maxIdx == m_fftSize - 1 ? 0 : maxIdx + 1;
Real alpha = sqrt(magSq(alphaIdx));
Real beta = sqrt(m_currentFreqMagSq);
Real gamma = sqrt(magSq(gammaIdx));
Real p = 0.5f * (alpha - gamma) / (alpha - 2.0f * beta + gamma);
Real b = beta - 0.25f * (alpha - gamma) * p;
m_currentFreqMagSq = b * b; // Interpolated power
idx = idx + p; // Interpolated fractional bin
}
m_currentFreqOffsetHz = ((idx * hzPerBin) / 2); // Divide by two, as the squaring operation doubles the freq
const Real hzPerBin = InmarsatDemodSettings::CHANNEL_SAMPLE_RATE / (Real) m_fftSize;
m_currentFreqOffsetHz = (idx * hzPerBin) / 2.0f; // Divide by two, as the squaring operation doubles the freq
Real magRatio = sqrt(m_currentFreqMagSq) / sqrt(m_freqMagSq);
@ -325,7 +341,6 @@ InmarsatDemodSink::InmarsatDemodSink(InmarsatDemod *stdCDemod) :
m_adjustedSPS = MAX_SAMPLES_PER_SYMBOL;
m_adjustment = 0;
m_totalSampleCount = 0;
m_error = 0;
m_errorSum = 0;
m_mu = 0.0;
@ -481,7 +496,6 @@ void InmarsatDemodSink::processOneSample(Complex &ci)
// Symbol synchronizer
m_totalSampleCount++;
m_filteredSamples.enqueue(rrc);
while (m_filteredSamples.size() > MAX_SAMPLES_PER_SYMBOL)
{
@ -512,7 +526,6 @@ void InmarsatDemodSink::processOneSample(Complex &ci)
m_adjustedSPS = SAMPLES_PER_SYMBOL - m_adjustment; // Positve mu indicates late, so reduce time to next sample
m_adjustment = adjustment;
m_prevTotalSampleCount = m_totalSampleCount;
// Costas loop for fine phase/freq correction - runs at symbol rate

View File

@ -232,8 +232,6 @@ private:
Real m_mu;
int m_adjustedSPS;
int m_adjustment;
qint64 m_totalSampleCount;
qint64 m_prevTotalSampleCount;
int m_bit;
uint8_t m_bits[DEMODULATOR_SYMBOLSPERCHUNK];
int m_bitCount;