mirror of
https://git.code.sf.net/p/fldigi/fldigi
synced 2026-08-13 17:47:54 -04:00
NAVTEX abort
* remove abort() statements from navtext afc processing
* fix serious bug which allowed fft filters to be
destroyed during signal processing
This commit is contained in:
parent
96e1f05174
commit
a943ae324e
2 changed files with 51 additions and 38 deletions
|
|
@ -211,6 +211,8 @@
|
|||
|
||||
#include "FL/fl_ask.H"
|
||||
|
||||
pthread_mutex_t navtex_filter_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/// This models a line of the file defining Navtex stations.
|
||||
class NavtexRecord
|
||||
{
|
||||
|
|
@ -968,6 +970,9 @@ private:
|
|||
}
|
||||
|
||||
void configure_filters() {
|
||||
// do not allow filters to be changed during signal processing!
|
||||
guard_lock filter_guard(&navtex_filter_mutex);
|
||||
|
||||
const int filtlen = 512;
|
||||
if (m_mark_lowpass) delete m_mark_lowpass;
|
||||
m_mark_lowpass = new fftfilt(m_baud_rate/m_sample_rate, filtlen);
|
||||
|
|
@ -1363,6 +1368,7 @@ private:
|
|||
static const int bw[][2] = {
|
||||
{ -deviation_f - 10, -deviation_f + 5 },
|
||||
{ deviation_f - 5, deviation_f + 10 } };
|
||||
// find mid frequency of power spectra in mark/space frequency interval
|
||||
double max_carrier = wf->powerDensityMaximum( 2, bw );
|
||||
|
||||
/// Do not change the frequency too quickly if an image is received.
|
||||
|
|
@ -1478,17 +1484,19 @@ private:
|
|||
* an end of emission idle signal alpha for at least 2 seconds. */
|
||||
public:
|
||||
void process_data(const double * data, int nb_samples) {
|
||||
process_afc();
|
||||
process_timeout();
|
||||
for( int i =0; i < nb_samples; ++i ) {
|
||||
int n_out;
|
||||
cmplx z, zmark, zspace, *zp_mark, *zp_space;
|
||||
|
||||
short v = static_cast<short>(32767 * data[i]);
|
||||
process_afc();
|
||||
process_timeout();
|
||||
// prevent user waterfall interaction from changing filters!
|
||||
guard_lock g( &navtex_filter_mutex );
|
||||
|
||||
for( int i =0; i < nb_samples; ++i ) {
|
||||
int n_out;
|
||||
|
||||
m_time_sec = m_sample_count / m_sample_rate ;
|
||||
|
||||
double dv = v;
|
||||
double dv = 32767 * data[i];
|
||||
z = cmplx(dv, dv);
|
||||
|
||||
zmark = mixer(m_mark_phase, m_mark_f, z);
|
||||
|
|
|
|||
|
|
@ -441,55 +441,60 @@ int WFdisp::peakFreq(int f0, int delta)
|
|||
|
||||
double WFdisp::powerDensity(double f0, double bw)
|
||||
{
|
||||
guard_lock waterfall_lock(&waterfall_mutex);
|
||||
|
||||
double pwrdensity = 0.0;
|
||||
int flower = (int)((f0 - bw/2)),
|
||||
fupper = (int)((f0 + bw/2));
|
||||
if (flower < 0 || fupper > IMAGE_WIDTH)
|
||||
return 0.0;
|
||||
for (int i = flower; i <= fupper; i++)
|
||||
pwrdensity += pwr[i];
|
||||
{
|
||||
guard_lock waterfall_lock(&waterfall_mutex);
|
||||
for (int i = flower; i <= fupper; i++)
|
||||
pwrdensity += pwr[i];
|
||||
}
|
||||
return pwrdensity/(bw+1);
|
||||
}
|
||||
|
||||
/// Frequency of the maximum power for a given bandwidth. Used for AFC.
|
||||
double WFdisp::powerDensityMaximum(int bw_nb, const int (*bw)[2]) const
|
||||
{
|
||||
guard_lock waterfall_lock(&waterfall_mutex);
|
||||
if (bw_nb < 1) return carrierfreq;
|
||||
|
||||
double max_pwr = 0 ;
|
||||
int f_lowest = bw[0][0];
|
||||
int f_highest = bw[bw_nb-1][1];
|
||||
if( f_lowest > f_highest ) abort();
|
||||
|
||||
for( int i = 0 ; i < bw_nb; ++i )
|
||||
{
|
||||
const int * p_bw = bw[i];
|
||||
if( p_bw[0] > p_bw[1] ) abort();
|
||||
for( int j = p_bw[0] ; j <= p_bw[1]; ++j )
|
||||
{
|
||||
max_pwr += pwr[ j - f_lowest ];
|
||||
}
|
||||
int fmax[bw_nb];
|
||||
double pnbw[bw_nb];
|
||||
int f_lowest = carrierfreq;
|
||||
int f_highest = carrierfreq;
|
||||
double max_pwr = 0;
|
||||
for (int i = 0; i < bw_nb; i++) {
|
||||
fmax[i] = carrierfreq;
|
||||
pnbw[i] = 0;
|
||||
}
|
||||
|
||||
double curr_pwr = max_pwr ;
|
||||
int max_idx = -1 ;
|
||||
/// Single pass to compute the maximum on this bandwidth.
|
||||
for( int f = -f_lowest ; f < IMAGE_WIDTH - f_highest; ++f )
|
||||
{
|
||||
/// Difference with previous power.
|
||||
for( int i = 0 ; i < bw_nb; ++i )
|
||||
{
|
||||
const int * p_bw = bw[i];
|
||||
curr_pwr += pwr[ f + p_bw[1] ] - pwr[ f + p_bw[0] ];
|
||||
}
|
||||
if( curr_pwr > max_pwr ) {
|
||||
max_idx = f ;
|
||||
max_pwr = curr_pwr ;
|
||||
guard_lock waterfall_lock(&waterfall_mutex);
|
||||
for (int i = 0; i < bw_nb; i++) {
|
||||
f_lowest = carrierfreq + bw[i][0];
|
||||
if (f_lowest <= 0) f_lowest = 0;
|
||||
f_highest = carrierfreq + bw[i][1];
|
||||
if (f_highest > IMAGE_WIDTH) f_highest = IMAGE_WIDTH;
|
||||
max_pwr = 0;
|
||||
pnbw[i] = 0;
|
||||
for (int n = f_lowest; n < f_highest; n++) {
|
||||
if (pwr[n] > max_pwr) {
|
||||
max_pwr = pwr[n];
|
||||
fmax[i] = n;
|
||||
}
|
||||
pnbw[i] += pwr[n];
|
||||
}
|
||||
if (pnbw[i] == 0) return carrierfreq;
|
||||
}
|
||||
}
|
||||
return max_idx ;
|
||||
int fmid = 0;
|
||||
double total_pwr = 0;
|
||||
for (int i = 0; i < bw_nb; i++) total_pwr += pnbw[i];
|
||||
|
||||
for (int i = 0; i < bw_nb; i++) fmid += fmax[i] * pnbw[i] / total_pwr;
|
||||
|
||||
return fmid;
|
||||
}
|
||||
|
||||
void WFdisp::setPrefilter(int v)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue