Записи не радиолюбительского обмена, но в любительском диапазоне (тема про QRM с Питерского форума).
Код демодулятора привожу, просто достаточное соотношение сигнал/шум.
Код:
omega2ftw_k1 = POWF(2, NCOFTWBITS);
...
#define OMEGA2FTWI(angle) ((ncoftwi_t) ((FLOAT_t) (angle) * omega2ftw_k1 / (FLOAT_t) M_TWOPI)) // angle in radians -pi..+pi to signed version of ftw_t
...
// Демодуляция FM
static RAMFUNC ncoftwi_t demodulator_FM(
FLOAT32P_t vp1,
const uint_fast8_t rxi // 0/1: main_RX/sub_RX
)
{
// Здесь, имея квадратурные сигналы vp1.IV и vp1.QV, начинаем демодуляции
//
// tnx Vladimir Vassilevsky
// http://www.dsprelated.com/showmessage/71491/2.php
//
static ncoftwi_t prev_fi [NTRX] = { 0, };
if (vp1.IV == 0 && vp1.QV == 0)
vp1.QV = 1;
const ncoftwi_t fi = OMEGA2FTWI(ATAN2F(vp1.QV, vp1.IV)); // returns a value in the range –pi to pi radians, using the signs of both parameters to determine the quadrant of the return value.
const ncoftwi_t d_fi = (ncoftwi_t) (fi - prev_fi [rxi]);
prev_fi [rxi] = fi;
return d_fi;
}
...
{
// Демодуляция NBFM
/*const FLOAT_t gain = */agc_forvard_float(dspmode, vp0f, rxi); // для отображения S-метра
saved_delta_fi [rxi] = demodulator_FM(vp0f, rxi); // погрешность настройки - требуется фильтровать ФНЧ
//const int fdelta10 = ((int64_t) saved_delta_fi [rxi] * ARMSAIRATE * 10) >> 32; // Отклнение частоты в 0.1 герц единицах
// значение для прослушивания
// 0.707 == M_SQRT1_2
const FLOAT_t sample = saved_delta_fi [rxi] * (FLOAT_t) M_SQRT1_2;
BEGIN_STAMP2();
r = sample * rxoutdenom; // масштабирование к разрядности аудио-кодека 1_31 -> 1_15
END_STAMP2();
if (glob_nb_off == 0)
{
// "шумодав"
testholdmax3(iir_nfmnbbpf(sample));
const int nbopen = getholdmax3() < nbfence;
r = (nbopen != 0) ? r : (r / 16);
}
}