From 6f111cdb73cc943d1a5c8f035632e786c0ebb8cb Mon Sep 17 00:00:00 2001 From: Jordan Sherer Date: Sat, 5 Oct 2019 14:55:15 -0400 Subject: [PATCH] Fixed jumping frequency by better signal frequency tweaking after sync --- lib/js8/baselinejs8.f90 | 2 +- lib/js8/genjs8.f90 | 2 +- lib/js8/js8dec.f90 | 2 +- lib/js8/syncjs8d.f90 | 2 +- mainwindow.cpp | 56 ++++++++++++++++++++++++++++++----------- mainwindow.h | 2 ++ 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/lib/js8/baselinejs8.f90 b/lib/js8/baselinejs8.f90 index 79f4003..dd43e1c 100644 --- a/lib/js8/baselinejs8.f90 +++ b/lib/js8/baselinejs8.f90 @@ -1,6 +1,6 @@ subroutine baselinejs8(s,nfa,nfb,sbase) -! Fit baseline to spectrum (for FT8) +! Fit baseline to spectrum (for JS8) ! Input: s(npts) Linear scale in power ! Output: sbase(npts) Baseline diff --git a/lib/js8/genjs8.f90 b/lib/js8/genjs8.f90 index 37bba4b..acf2ad7 100644 --- a/lib/js8/genjs8.f90 +++ b/lib/js8/genjs8.f90 @@ -1,6 +1,6 @@ subroutine genjs8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone) -! Encode an FT8 message, producing array itone(). +! Encode an JS8 message, producing array itone(). use crc use packjt diff --git a/lib/js8/js8dec.f90 b/lib/js8/js8dec.f90 index 36b8f56..33fd051 100644 --- a/lib/js8/js8dec.f90 +++ b/lib/js8/js8dec.f90 @@ -137,7 +137,7 @@ subroutine js8dec(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, & delf=ifr*0.5 dphi=twopi*delf*dt2 phi=0.0 - do i=1,NDOWNSPS + do i=1,(4*NSPS/NDOWN) ctwk(i)=cmplx(cos(phi),sin(phi)) phi=mod(phi+dphi,twopi) enddo diff --git a/lib/js8/syncjs8d.f90 b/lib/js8/syncjs8d.f90 index 532e704..2d8bfaf 100644 --- a/lib/js8/syncjs8d.f90 +++ b/lib/js8/syncjs8d.f90 @@ -1,5 +1,5 @@ subroutine syncjs8d(cd0,i0,ctwk,itwk,sync) -! Compute sync power for a complex, downsampled FT8 signal. +! Compute sync power for a complex, downsampled JS8 signal. !include 'js8_params.f90' diff --git a/mainwindow.cpp b/mainwindow.cpp index 86fac0b..efe3a54 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -4127,6 +4127,14 @@ void MainWindow::decodeDone () m_blankLine=true; } +QList generateOffsets(int minOffset, int maxOffset){ + QList offsets; + for(int i = minOffset; i <= maxOffset; i++){ + offsets.append(i); + } + return offsets; +} + void MainWindow::readFromStdout() //readFromStdout { while(proc_js8.canReadLine()) { @@ -4203,12 +4211,11 @@ void MainWindow::readFromStdout() //readFromStdout int offset = decodedtext.frequencyOffset(); if(!m_bandActivity.contains(offset)){ - QList offsets = { - // offset - 60, offset - 61, offset - 62, offset - 63, offset - 64, offset - 65, offset - 66, offset - 67, offset - 68, offset - 69, - // offset + 60, offset + 61, offset + 62, offset + 63, offset + 64, offset + 65, offset + 66, offset + 67, offset + 68, offset + 69, - offset - 1, offset - 2, offset - 3, offset - 4, offset - 5, offset - 6, offset - 7, offset - 8, offset - 9, offset - 10, - offset + 1, offset + 2, offset + 3, offset + 4, offset + 5, offset + 6, offset + 7, offset + 8, offset + 9, offset + 10 - }; + int range = 10; + if(m_nSubMode == Varicode::JS8CallFast){ range = 15; } + if(m_nSubMode == Varicode::JS8CallTurbo){ range = 30; } + QList offsets = generateOffsets(offset-10, offset+10); + foreach(int prevOffset, offsets){ if(!m_bandActivity.contains(prevOffset)){ continue; } m_bandActivity[offset] = m_bandActivity[prevOffset]; @@ -4340,6 +4347,7 @@ void MainWindow::readFromStdout() //readFromStdout logHeardGraph(cmd.from, cmd.to); } + // merge any existing buffer to this frequency hasExistingMessageBuffer(cmd.freq, true, nullptr); if(cmd.to == m_config.my_callsign()){ @@ -4538,12 +4546,12 @@ bool MainWindow::hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffs return true; } - QList offsets = { - //offset - 60, offset - 61, offset - 62, offset - 63, offset - 64, offset - 65, offset - 66, offset - 67, offset - 68, offset - 69, - //offset + 60, offset + 61, offset + 62, offset + 63, offset + 64, offset + 65, offset + 66, offset + 67, offset + 68, offset + 69, - offset - 1, offset - 2, offset - 3, offset - 4, offset - 5, offset - 6, offset - 7, offset - 8, offset - 9, offset - 10, - offset + 1, offset + 2, offset + 3, offset + 4, offset + 5, offset + 6, offset + 7, offset + 8, offset + 9, offset + 10 - }; + int range = 10; + if(m_nSubMode == Varicode::JS8CallFast){ range = 15; } + if(m_nSubMode == Varicode::JS8CallTurbo){ range = 30; } + + QList offsets = generateOffsets(offset-range, offset+range); + foreach(int prevOffset, offsets){ if(!m_messageBuffer.contains(prevOffset)){ continue; } @@ -4559,6 +4567,13 @@ bool MainWindow::hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffs return false; } +bool MainWindow::hasClosedExistingMessageBuffer(int offset){ + int range = 10; + if(m_nSubMode == Varicode::JS8CallFast){ range = 15; } + if(m_nSubMode == Varicode::JS8CallTurbo){ range = 30; } + return offset - range <= m_lastClosedMessageBufferOffset && m_lastClosedMessageBufferOffset <= offset + range; +} + void MainWindow::logCallActivity(CallDetail d, bool spot){ // don't log empty calls if(d.call.trimmed().isEmpty()){ @@ -9953,10 +9968,15 @@ void MainWindow::processRxActivity() { d.utcTimestamp = qMin(d.utcTimestamp, lastCompound.utcTimestamp); } + } else if(hasClosedExistingMessageBuffer(d.freq)){ + // incremental typeahead should just be displayed... + // TODO: should the buffer be reopened? + shouldDisplay = true; } else if(d.isDirected && d.text.contains("<....>")){ // if this is a _partial_ directed message, skip until the complete call comes through. continue; + } else if(d.isDirected && d.text.contains(": HB ")){ // TODO: HEARTBEAT // if this is a heartbeat, process elsewhere... continue; @@ -10135,6 +10155,9 @@ void MainWindow::processCompoundActivity() { m_rxCommandQueue.append(buffer.cmd); m_messageBuffer.remove(freq); + + // TODO: only if to me? + m_lastClosedMessageBufferOffset = freq; } } @@ -10158,20 +10181,24 @@ void MainWindow::processBufferedActivity() { if(!buffer.msgs.isEmpty()){ dt = qMax(dt, buffer.msgs.last().utcTimestamp); } + + // if the buffer has messages older than 1 minute, and we still haven't closed it, let's mark it as the last frame if(dt.secsTo(DriftingDateTime::currentDateTimeUtc()) > 60 && !buffer.msgs.isEmpty()){ - // if the buffer has messages older than 1 minute, and we still haven't closed it, let's just mark it as the last frame buffer.msgs.last().bits |= Varicode::JS8CallLast; } + + // but, if the buffer is older than 1.5 minutes, and we still haven't closed it, just remove it and skip if(dt.secsTo(DriftingDateTime::currentDateTimeUtc()) > 90){ - // but, if the buffer is older than 2 minutes, and we still haven't closed it, just remove it m_messageBuffer.remove(freq); continue; } + // if the buffer has no messages, skip if (buffer.msgs.isEmpty()) { continue; } + // if the buffered message hasn't seen the last message, skip if ((buffer.msgs.last().bits & Varicode::JS8CallLast) != Varicode::JS8CallLast) { continue; } @@ -10220,6 +10247,7 @@ void MainWindow::processBufferedActivity() { // regardless of valid or not, remove the "complete" buffered message from the buffer cache m_messageBuffer.remove(freq); + m_lastClosedMessageBufferOffset = freq; } } diff --git a/mainwindow.h b/mainwindow.h index 8bf560e..8eb104d 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -137,6 +137,7 @@ public slots: void playSoundFile(const QString &path); bool hasExistingMessageBufferToMe(int *pOffset); bool hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffset); + bool hasClosedExistingMessageBuffer(int offset); void logCallActivity(CallDetail d, bool spot=true); void logHeardGraph(QString from, QString to); QString lookupCallInCompoundCache(QString const &call); @@ -843,6 +844,7 @@ private: QMap m_rxFrameBlockNumbers; // freq -> block QMap> m_bandActivity; // freq -> [(text, last timestamp), ...] QMap m_messageBuffer; // freq -> (cmd, [frames, ...]) + int m_lastClosedMessageBufferOffset; QMap m_callActivity; // call -> (last freq, last timestamp) QMap m_aprsCallCache;