More tweaks for spandsp.

This commit is contained in:
Steve Underwood
2012-07-04 23:57:30 +08:00
parent 2b75169c07
commit 4a200ce3a0
17 changed files with 375 additions and 118 deletions

View File

@@ -29,9 +29,11 @@
/* CNG is 0.5s+-15% of 1100+-38Hz, 3s+-15% off, repeating.
CED is 0.2s silence, 3.3+-0.7s of 2100+-15Hz, and 75+-20ms of silence.
Calling tone is 0.5s-0.7s of 1300Hz+-15Hz, 1.5s-2.0s off, repeating.
ANS is 3.3+-0.7s of 2100+-15Hz.
ANS/ is 3.3+-0.7s of 2100+-15Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms.
ANSam/ is 2100+-1Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms, and AM with a sinewave of 15+-0.1Hz.
@@ -92,6 +94,8 @@ SPAN_DECLARE(const char *) modem_connect_tone_to_str(int tone)
return "FAX preamble";
case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE:
return "FAX CED or preamble";
case MODEM_CONNECT_TONES_CALLING_TONE:
return "Calling tone";
}
return "???";
}
@@ -202,6 +206,29 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *
}
s->duration_timer -= len;
break;
case MODEM_CONNECT_TONES_CALLING_TONE:
for ( ; i < len; i++)
{
if (s->duration_timer > ms_to_samples(2000))
{
if ((xlen = i + s->duration_timer - ms_to_samples(2000)) > len)
xlen = len;
s->duration_timer -= (xlen - i);
for ( ; i < xlen; i++)
amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
}
if (s->duration_timer > 0)
{
if ((xlen = i + s->duration_timer) > len)
xlen = len;
s->duration_timer -= (xlen - i);
memset(amp + i, 0, sizeof(int16_t)*(xlen - i));
i = xlen;
}
if (s->duration_timer == 0)
s->duration_timer = ms_to_samples(600 + 2000);
}
break;
}
return len;
}
@@ -274,6 +301,17 @@ SPAN_DECLARE(modem_connect_tones_tx_state_t *) modem_connect_tones_tx_init(modem
s->mod_phase = 0;
s->hop_timer = ms_to_samples(450);
break;
case MODEM_CONNECT_TONES_CALLING_TONE:
/* 0.6s of 1300Hz+-15Hz + 2.0s of silence repeating. */
s->tone_phase_rate = dds_phase_rate(1300.0);
s->level = dds_scaling_dbm0(-11);
s->duration_timer = ms_to_samples(600 + 2000);
s->mod_phase_rate = 0;
s->tone_phase = 0;
s->mod_phase = 0;
s->mod_level = 0;
s->hop_timer = 0;
break;
default:
if (alloced)
free(s);
@@ -402,6 +440,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
famp = amp[i];
/* A Cauer notch at 1100Hz, spread just wide enough to meet our detection bandwidth
criteria. */
/* Poles 0.736618498*exp(+-1047/4000 * PI * j)
Zeroes exp(+-1099.5 * PI * j) */
v1 = 0.792928f*famp + 1.0018744927985f*s->znotch_1 - 0.54196833412465f*s->znotch_2;
famp = v1 - 1.2994747954630f*s->znotch_1 + s->znotch_2;
s->znotch_2 = s->znotch_1;
@@ -446,6 +486,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
{
famp = amp[i];
/* A Cauer bandpass at 15Hz, with which we demodulate the AM signal. */
/* Poles 0.9983989*exp(+-15/4000 * PI * j)
Zeroes exp(0 * PI * j) */
v1 = fabs(famp) + 1.996667f*s->z15hz_1 - 0.9968004f*s->z15hz_2;
filtered = 0.001599787f*(v1 - s->z15hz_2);
s->z15hz_2 = s->z15hz_1;
@@ -454,8 +496,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
//printf("%9.1f %10.4f %9d %9d\n", famp, filtered, s->am_level, s->channel_level);
/* A Cauer notch at 2100Hz, spread just wide enough to meet our detection bandwidth
criteria. */
/* This is actually centred at 2095Hz, but gets the balance we want, due
to the asymmetric walls of the notch */
/* Poles 0.7144255*exp(+-2105.612/4000 * PI * j)
Zeroes exp(+-2099.9 * PI * j) */
v1 = 0.76000f*famp - 0.1183852f*s->znotch_1 - 0.5104039f*s->znotch_2;
famp = v1 + 0.1567596f*s->znotch_1 + s->znotch_2;
s->znotch_2 = s->znotch_1;
@@ -543,6 +585,44 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
}
}
break;
case MODEM_CONNECT_TONES_CALLING_TONE:
for (i = 0; i < len; i++)
{
famp = amp[i];
/* A Cauer notch at 1300Hz, spread just wide enough to meet our detection bandwidth
criteria. */
/* Poles 0.736618498*exp(+-1247/4000 * PI * j)
Zeroes exp(+-1299.5 * PI * j) */
v1 = 0.755582f*famp + 0.820887174515f*s->znotch_1 - 0.541968324778f*s->znotch_2;
famp = v1 - 1.0456667108f*s->znotch_1 + s->znotch_2;
s->znotch_2 = s->znotch_1;
s->znotch_1 = v1;
notched = (int16_t) lfastrintf(famp);
/* Estimate the overall energy in the channel, and the energy in
the notch (i.e. overall channel energy - tone energy => noise).
Use abs instead of multiply for speed (is it really faster?). */
s->channel_level += ((abs(amp[i]) - s->channel_level) >> 5);
s->notch_level += ((abs(notched) - s->notch_level) >> 5);
if (s->channel_level > 70 && s->notch_level*6 < s->channel_level)
{
/* There is adequate energy in the channel, and it is mostly at 1300Hz. */
if (s->tone_present != MODEM_CONNECT_TONES_CALLING_TONE)
{
if (++s->tone_cycle_duration >= ms_to_samples(415))
report_tone_state(s, MODEM_CONNECT_TONES_CALLING_TONE, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
}
}
else
{
/* If the signal looks wrong, even for a moment, we consider this the
end of the tone. */
if (s->tone_present == MODEM_CONNECT_TONES_CALLING_TONE)
report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
s->tone_cycle_duration = 0;
}
}
break;
}
return 0;
}