Fixed issue with duplicate decodes based on the ring buffer after tx cycles completed when it lined up with a decode cycle.
This commit is contained in:
parent
f4ae642cec
commit
720bd6b22a
@ -48,7 +48,11 @@ void Detector::clear ()
|
|||||||
qint64 now (DriftingDateTime::currentMSecsSinceEpoch ());
|
qint64 now (DriftingDateTime::currentMSecsSinceEpoch ());
|
||||||
unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000));
|
unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000));
|
||||||
dec_data.params.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (dec_data.d2) / sizeof (dec_data.d2[0])));
|
dec_data.params.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (dec_data.d2) / sizeof (dec_data.d2[0])));
|
||||||
m_bufferPos = 0;
|
m_bufferPos = m_samplesPerFFT;
|
||||||
|
|
||||||
|
// erase everything after kin.
|
||||||
|
memset(dec_data.d2 + dec_data.params.kin, 0, sizeof(dec_data.d2) - (sizeof(dec_data.d2[0]) * dec_data.params.kin));
|
||||||
|
|
||||||
qDebug() << "advancing detector buffer to" << dec_data.params.kin;
|
qDebug() << "advancing detector buffer to" << dec_data.params.kin;
|
||||||
#else
|
#else
|
||||||
dec_data.params.kin = 0;
|
dec_data.params.kin = 0;
|
||||||
|
@ -7,9 +7,8 @@
|
|||||||
#define RX_SAMPLE_RATE 12000
|
#define RX_SAMPLE_RATE 12000
|
||||||
|
|
||||||
#define JS8_USE_REFSPEC 1 // compute the signal refspec
|
#define JS8_USE_REFSPEC 1 // compute the signal refspec
|
||||||
#define JS8_USE_IHSYM 1 // compute ihsym manually instead of from symspec
|
#define JS8_USE_IHSYM 0 // compute ihsym manually instead of from symspec
|
||||||
#define JS8_RING_BUFFER 1 // use a ring buffer instead of clearing the decode frames
|
#define JS8_RING_BUFFER 1 // use a ring buffer instead of clearing the decode frames
|
||||||
#define JS8_DECODER_ONE 1 // decode only one mode at a time
|
|
||||||
#define JS8_DECODER_E2S 0 // decode every 2 seconds instead of at the half symbol stop
|
#define JS8_DECODER_E2S 0 // decode every 2 seconds instead of at the half symbol stop
|
||||||
|
|
||||||
#define JS8_NUM_SYMBOLS 79
|
#define JS8_NUM_SYMBOLS 79
|
||||||
|
14
lib/jt9.f90
14
lib/jt9.f90
@ -1,7 +1,7 @@
|
|||||||
program jt9
|
program jt9
|
||||||
|
|
||||||
! Decoder for JT9. Can run stand-alone, reading data from *.wav files;
|
! Decoder for js8. Can run stand-alone, reading data from *.wav files;
|
||||||
! or as the back end of wsjt-x, with data placed in a shared memory region.
|
! or as the back end of js8call, with data placed in a shared memory region.
|
||||||
|
|
||||||
use options
|
use options
|
||||||
use prog_args
|
use prog_args
|
||||||
@ -15,7 +15,6 @@ program jt9
|
|||||||
|
|
||||||
integer(C_INT) iret
|
integer(C_INT) iret
|
||||||
type(wav_header) wav
|
type(wav_header) wav
|
||||||
real*4 s(NSMAX)
|
|
||||||
character c
|
character c
|
||||||
character(len=500) optarg, infile
|
character(len=500) optarg, infile
|
||||||
character wisfile*80
|
character wisfile*80
|
||||||
@ -234,15 +233,6 @@ program jt9
|
|||||||
4 call timer('read_wav',1)
|
4 call timer('read_wav',1)
|
||||||
nhsym=(k-2048)/kstep
|
nhsym=(k-2048)/kstep
|
||||||
if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then
|
if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then
|
||||||
if(mode.eq.9 .or. mode.eq.74) then
|
|
||||||
! Compute rough symbol spectra for the JT9 decoder
|
|
||||||
ingain=0
|
|
||||||
call timer('symspec ',0)
|
|
||||||
nminw=1
|
|
||||||
call symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb, &
|
|
||||||
s,df3,ihsym,npts8,pxdbmax)
|
|
||||||
call timer('symspec ',1)
|
|
||||||
endif
|
|
||||||
nhsym0=nhsym
|
nhsym0=nhsym
|
||||||
if(nhsym.ge.181) exit
|
if(nhsym.ge.181) exit
|
||||||
endif
|
endif
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb,s, &
|
subroutine symspec(shared_data,k,k0,ntrperiod,nsps,ingain,nminw,pxdb,s, &
|
||||||
df3,ihsym,npts8,pxdbmax)
|
df3,ihsym,npts8,pxdbmax)
|
||||||
|
|
||||||
! Input:
|
! Input:
|
||||||
! shared_data pointer to the most recent new data
|
! shared_data pointer to the most recent new data
|
||||||
! k frames in that data
|
! k frames in that data
|
||||||
|
! k0 the last k observed
|
||||||
! ntrperiod T/R sequence length, minutes
|
! ntrperiod T/R sequence length, minutes
|
||||||
! nsps samples per symbol, at 12000 Hz
|
! nsps samples per symbol, at 12000 Hz
|
||||||
! ndiskdat 0/1 to indicate if data from disk
|
! ndiskdat 0/1 to indicate if data from disk
|
||||||
@ -32,7 +33,7 @@ subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb,s, &
|
|||||||
integer nch(7)
|
integer nch(7)
|
||||||
|
|
||||||
common/spectra/syellow(NSMAX),ref(0:3456),filter(0:3456)
|
common/spectra/syellow(NSMAX),ref(0:3456),filter(0:3456)
|
||||||
data k0/99999999/,nfft3z/0/
|
data nfft3z/0/
|
||||||
data nch/1,2,4,9,18,36,72/
|
data nch/1,2,4,9,18,36,72/
|
||||||
equivalence (xc,cx)
|
equivalence (xc,cx)
|
||||||
save
|
save
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
//----------------------------------------------------- C and Fortran routines
|
//----------------------------------------------------- C and Fortran routines
|
||||||
void symspec_(struct dec_data *, int* k, int* ntrperiod, int* nsps, int* ingain,
|
void symspec_(struct dec_data *, int* k, int* k0, int* ntrperiod, int* nsps, int* ingain,
|
||||||
int* minw, float* px, float s[], float* df3, int* nhsym, int* npts8,
|
int* minw, float* px, float s[], float* df3, int* nhsym, int* npts8,
|
||||||
float *m_pxmax);
|
float *m_pxmax);
|
||||||
|
|
||||||
@ -2542,11 +2542,16 @@ int MainWindow::computeFramesNeededForDecode(int submode, int period){
|
|||||||
//-------------------------------------------------------------- dataSink()
|
//-------------------------------------------------------------- dataSink()
|
||||||
void MainWindow::dataSink(qint64 frames)
|
void MainWindow::dataSink(qint64 frames)
|
||||||
{
|
{
|
||||||
static int k0 = 0;
|
static int k0 = 999999999;
|
||||||
static float s[NSMAX];
|
static float s[NSMAX];
|
||||||
char line[80];
|
char line[80];
|
||||||
|
|
||||||
int k (frames);
|
int k (frames);
|
||||||
|
if(k0 == 999999999){
|
||||||
|
m_ihsym = int((float)frames/(float)m_nsps)*2;
|
||||||
|
k0 = k;
|
||||||
|
}
|
||||||
|
|
||||||
QString fname {QDir::toNativeSeparators(m_config.writeable_data_dir ().absoluteFilePath ("refspec.dat"))};
|
QString fname {QDir::toNativeSeparators(m_config.writeable_data_dir ().absoluteFilePath ("refspec.dat"))};
|
||||||
QByteArray bafname = fname.toLatin1();
|
QByteArray bafname = fname.toLatin1();
|
||||||
const char *c_fname = bafname.data();
|
const char *c_fname = bafname.data();
|
||||||
@ -2588,25 +2593,37 @@ void MainWindow::dataSink(qint64 frames)
|
|||||||
}
|
}
|
||||||
k0 = k;
|
k0 = k;
|
||||||
int ihs = m_ihsym;
|
int ihs = m_ihsym;
|
||||||
symspec_(&dec_data,&k,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&ihs,&m_npts8,&m_pxmax);
|
dec_data.params.kpos = computeCycleStartForDecode(computeCurrentCycle(m_TRperiod), m_TRperiod);
|
||||||
|
symspec_(&dec_data,&k,&k0,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&ihs,&m_npts8,&m_pxmax);
|
||||||
// 3) if symspec wants ihs to be 0, set it.
|
// 3) if symspec wants ihs to be 0, set it.
|
||||||
if(ihs == 0){
|
if(ihs == 0){
|
||||||
m_ihsym = ihs;
|
m_ihsym = ihs;
|
||||||
} else {
|
} else {
|
||||||
m_ihsym += 1;
|
m_ihsym += 1;
|
||||||
}
|
}
|
||||||
qDebug() << "dataSink" << k << "ihsym" << m_ihsym << "ihs" << ihs;
|
|
||||||
|
// make ihsym similar to how it was...relative to the tr period
|
||||||
|
m_ihsym = m_ihsym % (m_TRperiod*RX_SAMPLE_RATE/m_nsps*2);
|
||||||
|
|
||||||
|
/// qDebug() << "dataSink" << k << "ihsym" << m_ihsym << "ihs" << ihs;
|
||||||
|
/// QVector<float> sss;
|
||||||
|
/// for(int i = 0; i < 10; i++){
|
||||||
|
/// sss << s[i];
|
||||||
|
/// }
|
||||||
|
/// qDebug() << "-->" << sss;
|
||||||
|
|
||||||
/// END IHSYM
|
/// END IHSYM
|
||||||
#else
|
#else
|
||||||
symspec_(&dec_data,&k,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&m_ihsym,&m_npts8,&m_pxmax);
|
m_ihsym=m_ihsym%(m_TRperiod*RX_SAMPLE_RATE/m_nsps*2);
|
||||||
|
qDebug() << "k" << k << "k0" << k0 << "ihsym" << m_ihsym;
|
||||||
|
symspec_(&dec_data,&k,&k0,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&m_ihsym,&m_npts8,&m_pxmax);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(m_ihsym <= 0) return;
|
if(m_ihsym <= 0) return;
|
||||||
|
|
||||||
if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer
|
if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer
|
||||||
if(m_monitoring || m_diskData) {
|
if(m_monitoring || m_diskData) {
|
||||||
m_wideGraph->dataSink2(s,m_df3,m_ihsym,m_diskData);
|
m_wideGraph->dataSink2(s, m_df3, m_ihsym, m_diskData);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixStop();
|
fixStop();
|
||||||
@ -4140,6 +4157,31 @@ bool MainWindow::decodeReady(int submode, int period, int *pSubmode, int *pPerio
|
|||||||
strncpy(dec_data.params.hiscall,(hisCall + " ").toLatin1 ().constData (), 12);
|
strncpy(dec_data.params.hiscall,(hisCall + " ").toLatin1 ().constData (), 12);
|
||||||
strncpy(dec_data.params.hisgrid,(hisGrid + " ").toLatin1 ().constData (), 6);
|
strncpy(dec_data.params.hisgrid,(hisGrid + " ").toLatin1 ().constData (), 6);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// for waterfall computation
|
||||||
|
memset(dec_data.d1, 0, sizeof(dec_data.d1));
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
int frames = 0;
|
||||||
|
if(m_nSubMode == Varicode::JS8CallNormal){
|
||||||
|
start = dec_data.params.kposA;
|
||||||
|
frames = dec_data.params.kszA;
|
||||||
|
}
|
||||||
|
else if(m_nSubMode == Varicode::JS8CallFast){
|
||||||
|
start = dec_data.params.kposB;
|
||||||
|
frames = dec_data.params.kszB;
|
||||||
|
}
|
||||||
|
else if(m_nSubMode == Varicode::JS8CallTurbo){
|
||||||
|
start = dec_data.params.kposC;
|
||||||
|
frames = dec_data.params.kszC;
|
||||||
|
}
|
||||||
|
else if(m_nSubMode == Varicode::JS8CallUltra){
|
||||||
|
start = dec_data.params.kposD;
|
||||||
|
frames = dec_data.params.kszD;
|
||||||
|
}
|
||||||
|
memcpy(dec_data.d1, dec_data.d2 + start, sizeof(dec_data.d2[0]) * frames);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if JS8_TWO_BUFFERS
|
#if JS8_TWO_BUFFERS
|
||||||
#if JS8_RING_BUFFER
|
#if JS8_RING_BUFFER
|
||||||
// clear out d1
|
// clear out d1
|
||||||
@ -7190,12 +7232,13 @@ void MainWindow::on_actionJS8_triggered()
|
|||||||
m_TRperiod = computeSubmodePeriod(m_nSubMode);
|
m_TRperiod = computeSubmodePeriod(m_nSubMode);
|
||||||
m_wideGraph->show();
|
m_wideGraph->show();
|
||||||
ui->decodedTextLabel2->setText(" UTC dB DT Freq Message");
|
ui->decodedTextLabel2->setText(" UTC dB DT Freq Message");
|
||||||
m_wideGraph->setPeriod(m_TRperiod, m_nsps);
|
|
||||||
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
#if JS8_RING_BUFFER
|
#if JS8_RING_BUFFER
|
||||||
Q_ASSERT(NTMAX == 60);
|
Q_ASSERT(NTMAX == 60);
|
||||||
|
m_wideGraph->setPeriod(m_TRperiod, m_nsps);
|
||||||
m_detector->setTRPeriod(NTMAX / 2); // TODO - not thread safe
|
m_detector->setTRPeriod(NTMAX / 2); // TODO - not thread safe
|
||||||
#else
|
#else
|
||||||
|
m_wideGraph->setPeriod(m_TRperiod, m_nsps);
|
||||||
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
#endif
|
#endif
|
||||||
ui->label_7->setText("Rx Frequency");
|
ui->label_7->setText("Rx Frequency");
|
||||||
|
Loading…
Reference in New Issue
Block a user