version.
/* How far into the first CLEAN interval we are. This is like the route flap initialzation. */
s->link_failure_counter = s->link_failure_interval_ticks - 99 - floor(s->link_failure_interval_ticks*q1050_rand());
s->link_recovery_counter = s->link_failure_duration_ticks;
-
+
s->base_delay = parms->base_regional_delay;
s->max_jitter = parms->max_jitter;
s->prob_packet_loss = parms->prob_packet_loss/100.0;
static void g1050_simulate_chunk(g1050_state_t *s)
{
int i;
-
+
s->base_time += 1.0;
memcpy(&s->segment[0].delays[0], &s->segment[0].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[0].delays[0]));
mo = &g1050_standard_models[model];
memset(s, 0, sizeof(*s));
-
+
s->packet_rate = packet_rate;
s->packet_size = packet_size;
{
g1050_channel_speeds_t *sp;
g1050_model_t *mo;
-
+
sp = &g1050_speed_patterns[speed_pattern - 1];
mo = &g1050_standard_models[model];
}
if (e)
{
- element->next = e->next;
- element->prev = e;
+ element->next = e->next;
+ element->prev = e;
e->next = element;
}
else
if (++p == s->near_filter_len)
p = 0;
s->near_buf_ptr = p;
-
+
/* Apply the filter */
sum = 0.0f;
for (j = 0; j < s->near_filter_len; j++)
if (++p >= s->near_filter_len)
p = 0;
}
-
+
/* Add noise */
sum += awgn(&s->near_noise);
-
+
return sum;
}
/*- End of function --------------------------------------------------------*/
if (++p == s->far_filter_len)
p = 0;
s->far_buf_ptr = p;
-
+
/* Apply the filter */
sum = 0.0f;
for (j = 0; j < s->far_filter_len; j++)
if (++p >= s->far_filter_len)
p = 0;
}
-
+
/* Add noise */
sum += awgn(&s->far_noise);
}
/*- End of function --------------------------------------------------------*/
-SPAN_DECLARE(void) one_way_line_model(one_way_line_model_state_t *s,
+SPAN_DECLARE(void) one_way_line_model(one_way_line_model_state_t *s,
int16_t output[],
const int16_t input[],
int samples)
in = input[i];
/* Near end analogue section */
-
+
/* Line model filters & noise */
out = calc_near_line_filter(s, in);
-
+
/* Long distance digital section */
amp[0] = out;
s->bulk_delay_ptr = 0;
/* Far end analogue section */
-
+
/* Line model filters & noise */
out = calc_far_line_filter(s, out);
-
+
if (s->mains_interference)
{
tone_gen(&s->mains_tone, amp, 1);
}
/*- End of function --------------------------------------------------------*/
-SPAN_DECLARE(void) both_ways_line_model(both_ways_line_model_state_t *s,
+SPAN_DECLARE(void) both_ways_line_model(both_ways_line_model_state_t *s,
int16_t output1[],
const int16_t input1[],
int16_t output2[],
/* Put half the noise in each analogue section */
awgn_init_dbm0(&s->near_noise, 1234567, noise - 3.02f);
awgn_init_dbm0(&s->far_noise, 1234567, noise - 3.02f);
-
+
s->dc_offset = 0.0f;
s->mains_interference = 0;
s->line2.near_co_hybrid_echo = pow(10, echo_level_co2/20.0f);
s->line1.near_cpe_hybrid_echo = pow(10, echo_level_cpe1/20.0f);
s->line2.near_cpe_hybrid_echo = pow(10, echo_level_cpe2/20.0f);
-
+
return s;
}
/*- End of function --------------------------------------------------------*/
/* Tabulated medium range telephone line response
(from p 537, Digital Communication, John G. Proakis */
/*
- amp 1.0 -> 2.15, freq = 3000 Hz -> 3.2, by 0.2 increments
+ amp 1.0 -> 2.15, freq = 3000 Hz -> 3.2, by 0.2 increments
delay = 4 ms -> 2.2
*/
}
//phase = 2.0f*M_PI*f*delay*0.001f;
phase = 0.0f;
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
in[i][0] = amp*cosf(phase);
in[i][1] = amp*sinf(phase);
in[FFT_SIZE - i][0] = in[i][0];
for (i = 0; i < FFT_SIZE; i++)
fprintf(outfile, "%5d %15.5f,%15.5f\n", i, in[i].re, in[i].im);
#endif
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
fftw_execute(p);
#else
fftw_one(p, in, out);
l = FFT_SIZE - (LINE_FILTER_SIZE - 1)/2;
for (i = 0; i < LINE_FILTER_SIZE; i++)
{
-
+
#if defined(HAVE_FFTW3_H)
impulse_responses[filter_sets][i] = out[l][0]/pw;
#else
generate_proakis();
generate_ad_edd();
-
+
fclose(outfile);
-
+
if (argc > 1)
{
for (i = 0; i < LINE_FILTER_SIZE; i++)
memcpy(s->tx_pkt[s->next_pkt], buf, len);
s->tx_pkt_len[s->next_pkt] = len;
s->tx_pkt_seq_no[s->next_pkt] = seq_no;
-
+
/* Construct the redundant packet */
p = buf2;
slot = s->next_pkt;
uint8_t *p;
uint16_t *q;
int redundancy_depth;
-
+
if (s->rx_queued_pkts)
{
/* We have some stuff from the last g1050_get() still to deliver */
/*! 3 seconds of predicted delays for the link */
double delays[3*G1050_TICKS_PER_SEC];
-
+
/*! A count of packets lost on the link. */
uint32_t lost_packets;
/*! An extra debug count of packets lost on the link. */
float far_co_hybrid_echo;
/*! DC offset impairment */
float dc_offset;
-
+
/*! Mains pickup impairment */
int mains_interference;
tone_gen_state_t mains_tone;
one_way_line_model_state_t line1;
one_way_line_model_state_t line2;
float fout1;
- float fout2;
+ float fout2;
} both_ways_line_model_state_t;
#ifdef __cplusplus
SPAN_DECLARE_DATA extern const float *line_models[];
-SPAN_DECLARE(void) both_ways_line_model(both_ways_line_model_state_t *s,
+SPAN_DECLARE(void) both_ways_line_model(both_ways_line_model_state_t *s,
int16_t output1[],
const int16_t input1[],
int16_t output2[],
SPAN_DECLARE(void) both_ways_line_model_set_dc(both_ways_line_model_state_t *s, float dc1, float dc2);
SPAN_DECLARE(void) both_ways_line_model_set_mains_pickup(both_ways_line_model_state_t *s, int f, float level1, float level2);
-
+
SPAN_DECLARE(both_ways_line_model_state_t *) both_ways_line_model_init(int model1,
float noise1,
float echo_level_cpe1,
SPAN_DECLARE(int) both_ways_line_model_release(both_ways_line_model_state_t *s);
-SPAN_DECLARE(void) one_way_line_model(one_way_line_model_state_t *s,
+SPAN_DECLARE(void) one_way_line_model(one_way_line_model_state_t *s,
int16_t output[],
const int16_t input[],
int samples);
SPAN_DECLARE(codec_munge_state_t *) codec_munge_init(int codec, int info)
{
codec_munge_state_t *s;
-
+
if ((s = (codec_munge_state_t *) malloc(sizeof(*s))))
{
switch (codec)
static void sf_close_at_exit(void)
{
int i;
-
+
for (i = 0; i < SF_MAX_HANDLE; i++)
{
if (sf_close_at_exit_list[i])
static int sf_record_handle(SNDFILE *handle)
{
int i;
-
+
for (i = 0; i < SF_MAX_HANDLE; i++)
{
if (sf_close_at_exit_list[i] == NULL)
{
int res;
int i;
-
+
if ((res = sf_close(handle)) == 0)
{
for (i = 0; i < SF_MAX_HANDLE; i++)
{
int bit;
adsi_tx_state_t *s;
-
+
s = (adsi_tx_state_t *) user_data;
/* This is similar to the async. handling code in fsk.c, but a few special
things are needed in the preamble, and postamble of an ADSI message. */
static int adsi_tdd_get_async_byte(void *user_data)
{
adsi_tx_state_t *s;
-
+
s = (adsi_tx_state_t *) user_data;
if (s->byte_no < s->msg_len)
return s->msg[s->byte_no++];
{
if (s->msg_len == 0)
{
- /* A message should start DLE SOH, but let's just check
+ /* A message should start DLE SOH, but let's just check
we are starting with a DLE for now */
if (s->in_progress == (0x80 | DLE))
s->msg[s->msg_len++] = (uint8_t) s->in_progress;
{
adsi_rx_state_t *s;
uint8_t octet;
-
+
s = (adsi_rx_state_t *) user_data;
//printf("Rx bit %x\n", bit);
if (byte < 0)
i += len - 2;
s->msg[i++] = DLE;
s->msg[i++] = ETX;
-
+
/* Set the parity bits */
for (j = 0; j < i; j++)
{
s->msg[len] = (uint8_t) ((-sum) & 0xFF);
s->msg_len = len + 1;
break;
- }
+ }
/* Prepare the bit sequencing */
s->byte_no = 0;
s->bit_pos = 0;
{
async_tx_state_t *s;
int bit;
-
+
s = (async_tx_state_t *) user_data;
if (s->bitpos == 0)
{
s->stop_bits = stop_bits;
if (parity != ASYNC_PARITY_NONE)
s->stop_bits++;
-
+
s->get_byte = get_byte;
s->user_data = user_data;
SPAN_DECLARE(void) at_put_response(at_state_t *s, const char *t)
{
uint8_t buf[3];
-
+
buf[0] = s->p.s_regs[3];
buf[1] = s->p.s_regs[4];
buf[2] = '\0';
{
at_call_id_t *call_id;
at_call_id_t *next;
-
+
for (call_id = s->call_id; call_id; call_id = next)
{
next = call_id->next;
{
snprintf(buf,
sizeof(buf),
- "%s=%s",
+ "%s=%s",
(call_id->id) ? call_id->id : "NULL",
(call_id->value) ? call_id->value : "<NONE>");
at_put_response(s, buf);
static int parse_num(const char **s, int max_value)
{
int i;
-
+
/* The spec. says no digits is valid, and should be treated as zero. */
i = 0;
while (isdigit((int) **s))
static int parse_hex_num(const char **s, int max_value)
{
int i;
-
+
/* The spec. says a hex value is always 2 digits, and the alpha digits are
upper case. */
i = 0;
allowed = "24,48,72,73,74,96,97,98,121,122,145,146";
break;
}
-
+
val = -1;
if (!parse_out(s, t, &val, 255, NULL, allowed))
return TRUE;
/* 0: In-band control service disabled
1: In-band control service enabled, 7-bit codes allowed, and top bit insignificant
2; In-band control service enabled, 7-bit codes allowed, and 8-bit codes available
-
+
Circuits 105, 106, 107, 108, 109, 110, 125, 132, 133, 135, 142 in that order. For each one:
0: disabled
1: enabled
-
+
DCE line connect status reports:
0: disabled
1: enabled */
T3 = entire interval -- N*T2
7: report the first time when <T1> is exceeded, and then each time <T2> is exceeded, and then once
more when the mark idle period ends; T3 = entire mark idle period -- N*T2 - T1
-
+
T1 in units of 10ms
-
+
T2 in units of 10ms */
locations[0] = NULL;
locations[1] = NULL;
4: 7 data 2 stop
5: 7 data 1 parity 1 stop
6: 7 data 1 stop
-
+
Parity
0: Odd
1: Even
static const char *at_cmd_plus_MSC(at_state_t *s, const char *t)
{
/* V.250 6.4.8 - Seamless rate change enable */
- /* 0 Disables V.34 seamless rate change
+ /* 0 Disables V.34 seamless rate change
1 Enables V.34 seamless rate change */
/* TODO: */
t += 4;
paper somewhere. I can't track down where I got the original from,
so that due recognition can be given. The original had no explicit
copyright notice, and I hope nobody objects to its use here.
-
+
Having a reasonable Gaussian noise generator is pretty important for
telephony testing (in fact, pretty much any DSP testing), and this
one seems to have served me OK. Since the generation of Gaussian
noise is only for test purposes, and not a core system component,
I don't intend to worry excessively about copyright issues, unless
someone worries me.
-
+
The non-core nature of this code also explains why it is unlikely
to ever be optimised. */
s->digits_callback = callback;
s->digits_callback_data = user_data;
- s->hits[0] =
+ s->hits[0] =
s->hits[1] =
s->hits[2] =
- s->hits[3] =
+ s->hits[3] =
s->hits[4] = 0;
for (i = 0; i < 6; i++)
best = 1;
second_best = 0;
}
-
+
for (i = 2; i < 6; i++)
{
energy[i] = goertzel_result(&s->out[i]);
s->report_frequency = freq;
s->reporter = reporter;
s->user_data = user_data;
-
+
s->rx.report_countdown = s->report_frequency;
}
/*- End of function --------------------------------------------------------*/
}
s->error_rate = 8;
s->rx.measurement_step = MEASUREMENT_STEP;
-
+
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
span_log_set_protocol(&s->logging, "BERT");
int len;
#if defined(LOG_FAX_AUDIO)
int required_len;
-
+
required_len = max_len;
#endif
len = 0;
{
/* Pad to the requested length with silence */
memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
- len = max_len;
+ len = max_len;
}
break;
}
{
/* Pad to the requested length with silence */
memset(amp, 0, max_len*sizeof(int16_t));
- len = max_len;
+ len = max_len;
}
}
#if defined(LOG_FAX_AUDIO)
void compute_hilbert_transform(double coeffs[], int len);
-
#if defined(__cplusplus)
}
#endif
else if (wd1 > 18432)
wd1 = 18432;
s->band[0].nb = (int16_t) wd1;
-
+
/* Block 3L, SCALEL */
wd1 = (s->band[0].nb >> 6) & 31;
wd2 = 8 - (s->band[0].nb >> 11);
s->band[0].det = (int16_t) (wd3 << 2);
block4(&s->band[0], dlow);
-
+
if (!s->eight_k)
{
/* Block 2H, INVQAH */
else if (wd1 > 22528)
wd1 = 22528;
s->band[1].nb = (int16_t) wd1;
-
+
/* Block 3H, SCALEH */
wd1 = (s->band[1].nb >> 6) & 31;
wd2 = 10 - (s->band[1].nb >> 11);
s->band[0].det = (int16_t) (wd3 << 2);
block4(&s->band[0], dlow);
-
+
if (s->eight_k)
{
/* Just leave the high bits as zero */
int16_t dqsez;
int16_t dq;
int16_t i;
-
+
sezi = predictor_zero(s);
sei = sezi + predictor_pole(s);
se = sei >> 1;
/* Pole prediction difference */
dqsez = sr + (sezi >> 1) - se;
-
+
update(s, y, g726_16_witab[i], g726_16_fitab[i], dq, sr, dqsez);
return (uint8_t) i;
}
int16_t dq;
int16_t i;
int y;
-
+
sezi = predictor_zero(s);
sei = sezi + predictor_pole(s);
se = sei >> 1;
/* Pole prediction difference */
dqsez = sr + (sezi >> 1) - se;
-
+
update(s, y, g726_24_witab[i], g726_24_fitab[i], dq, sr, dqsez);
return (uint8_t) i;
}
int16_t dq;
int16_t i;
int y;
-
+
sezi = predictor_zero(s);
sei = sezi + predictor_pole(s);
se = sei >> 1;
int16_t dq;
int16_t i;
int y;
-
+
sezi = predictor_zero(s);
sei = sezi + predictor_pole(s);
se = sei >> 1;
code &= 0x1F;
sezi = predictor_zero(s);
sei = sezi + predictor_pole(s);
-
+
y = step_size(s);
dq = reconstruct(code & 0x10, g726_40_dqlntab[code], y);
int i;
int j;
int k;
-
+
i = 0;
for (j = 0; j < 8; j++)
s->LARc[j] = c[i++];
/* The RPE-LTD coder works on a frame by frame basis. The length of
the frame is equal to 160 samples. Some computations are done
once per frame to produce at the output of the coder the
- LARc[1..8] parameters which are the coded LAR coefficients and
+ LARc[1..8] parameters which are the coded LAR coefficients and
also to realize the inverse filtering operation for the entire
frame (160 samples of signal d[0..159]). These parts produce at
the output of the coder:
SPAN_DECLARE(int) gsm0610_set_packing(gsm0610_state_t *s, int packing)
{
s->packing = packing;
- return 0;
+ return 0;
}
/*- End of function --------------------------------------------------------*/
int i;
int j;
int k;
-
+
i = 0;
for (j = 0; j < 8; j++)
c[i++] = (uint8_t) s->LARc[j];
{
uint16_t sr;
int i;
-
+
sr = 0;
sr = (sr >> 6) | (s->LARc[0] << 10);
sr = (sr >> 6) | (s->LARc[1] << 10);
/* The number of left shifts needed to normalize the 32 bit
variable x for positive values on the interval
with minimum of
- minimum of 1073741824 (01000000000000000000000000000000) and
+ minimum of 1073741824 (01000000000000000000000000000000) and
maximum of 2147483647 (01111111111111111111111111111111)
and for negative values on the interval with
minimum of -2147483648 (-10000000000000000000000000000000) and
maximum of -1073741824 ( -1000000000000000000000000000000).
-
+
In order to normalize the result, the following
operation must be done: norm_var1 = x << gsm0610_norm(x);
-
+
(That's 'ffs', only from the left, not the right..)
*/
/*
(From p. 46, end of section 4.2.5)
-
+
NOTE: The following lines gives [sic] one correct implementation
of the div(num, denum) arithmetic operation. Compute div
which is the integer division of num by denom: with
" addq $2,%%rdx;\n" /* now edx = top-2 */
" cmpq %%rdx,%%rsi;\n"
" ja 2f;\n"
-
+
" movzwl (%%rsi),%%eax;\n"
" movd %%eax,%%mm0;\n"
" paddsw %%mm2,%%mm0;\n"
" addl $2,%%edx;\n" /* now edx = top-2 */
" cmpl %%edx,%%esi;\n"
" ja 2f;\n"
-
+
" movzwl (%%esi),%%eax;\n"
" movd %%eax,%%mm0;\n"
" paddsw %%mm2,%%mm0;\n"
int16_t *sp;
int16_t sl;
#endif
-
+
/* The goal is to compute the array L_ACF[k]. The signal s[i] must
be scaled in order to avoid an overflow situation. */
/* Rescaling of the array s[0..159] */
if (scalauto > 0)
{
- assert(scalauto <= 4);
+ assert(scalauto <= 4);
for (k = 0; k < GSM0610_FRAME_LEN; k++)
amp[k] <<= scalauto;
/*endfor*/
/*endif*/
assert(*r != INT16_MIN);
if (n == 8)
- return;
+ return;
/*endif*/
/* Schur recursion */
int i;
/* The following scaling for r[..] and LAR[..] has been used:
-
+
r[..] = integer (real_r[..]*32768.); -1 <= real_r < 1.
LAR[..] = integer (real_LAR[..] * 16384);
with -1.625 <= real_LAR <= 1.625
/* This procedure needs four tables; the following equations
give the optimum scaling for the constants:
-
+
A[0..7] = integer(real_A[0..7] * 1024)
B[0..7] = integer(real_B[0..7] * 512)
MAC[0..7] = maximum of the LARc[0..7]
/*
4.2.0 .. 4.2.3 PREPROCESSING SECTION
-
+
After A-law to linear conversion (or directly from the
A to D converter) the following scaling is assumed for
input to the RPE-LTP algorithm:
-
+
in: 0.1.....................12
S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
-
+
Where S is the sign bit, v a valid bit, and * a "don't care" bit.
The original signal is called sop[..]
-
- out: 0.1................... 12
+
+ out: 0.1................... 12
S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
*/
"1:\n"
" movq (%%rcx,%%rsi,2),%%mm0;\n"
" pmaddwd %%mm1,%%mm0;\n"
-
+
" movq 8(%%rcx,%%rsi,2),%%mm4;\n"
" pmaddwd %%mm2,%%mm4;\n"
" paddd %%mm4,%%mm0;\n"
" paddd %%mm5,%%mm0;\n" /* Add for roundoff */
" psrad $13,%%mm0;\n"
- " packssdw %%mm0,%%mm0;\n"
+ " packssdw %%mm0,%%mm0;\n"
" movd %%mm0,%%eax;\n" /* eax has result */
" movw %%ax,(%%rdi,%%rsi,2);\n"
" incq %%rsi;\n"
"1:\n"
" movq (%%ecx,%%esi,2),%%mm0;\n"
" pmaddwd %%mm1,%%mm0;\n"
-
+
" movq 8(%%ecx,%%esi,2),%%mm4;\n"
" pmaddwd %%mm2,%%mm4;\n"
" paddd %%mm4,%%mm0;\n"
" paddd %%mm5,%%mm0;\n" /* Add for roundoff */
" psrad $13,%%mm0;\n"
- " packssdw %%mm0,%%mm0;\n"
+ " packssdw %%mm0,%%mm0;\n"
" movd %%mm0,%%eax;\n" /* eax has result */
" movw %%ax,(%%edi,%%esi,2);\n"
" incl %%esi;\n"
/* The coefficients of the weighting filter are stored in a table
(see table 4.4). The following scaling is used:
-
- H[0..10] = integer(real_H[0..10] * 8192);
+
+ H[0..10] = integer(real_H[0..10] * 8192);
*/
/* Initialization of a temporary working array wt[0...49] */
#define STEP(i,H) (e[k + i] * (int32_t) H)
/* Every one of these multiplications is done twice,
- but I don't see an elegant way to optimize this.
+ but I don't see an elegant way to optimize this.
Do you?
*/
result += STEP( 0, -134);
can be calculated by using the exponent and the mantissa part of
xmaxc (logarithmic table).
So, this method avoids any division and uses only a scaling
- of the RPE samples by a function of the exponent. A direct
+ of the RPE samples by a function of the exponent. A direct
multiplication by the inverse of the mantissa (NRFAC[0..7]
found in table 4.5) gives the 3 bit coded version xMc[0..12]
of the RPE samples.
*/
/* Direct computation of xMc[0..12] using table 4.5 */
assert(exp <= 4096 && exp >= -4096);
- assert(mant >= 0 && mant <= 7);
+ assert(mant >= 0 && mant <= 7);
temp1 = (int16_t) (6 - exp); /* Normalization by the exponent */
temp2 = gsm_NRFAC[mant]; /* Inverse mantissa */
analysis and synthesis filters operate with four different sets of
coefficients, derived from the previous set of decoded LARs(LARpp(j - 1))
and the actual set of decoded LARs (LARpp(j))
-
+
(Initial value: LARpp(j - 1)[1..8] = 0.)
*/
{
if (s->octet_count_report_interval == 0)
return;
-
+
/* If we are not in octet counting mode, we start it.
If we are in octet counting mode, we update it. */
if (s->octet_counting_mode)
{
s->abort_octets = 0;
return 0x7F;
- }
+ }
return s->idle_octet;
}
if (s->len)
static void eval_amdf(float speech[],
int32_t lpita,
- const int32_t tau[],
+ const int32_t tau[],
int32_t ltau,
int32_t maxlag,
float amdf[],
static void eval_highres_amdf(float speech[],
int32_t lpita,
- const int32_t tau[],
+ const int32_t tau[],
int32_t ltau,
float amdf[],
int32_t *minptr,
{
static const int32_t tau[60] =
{
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
- 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 84, 88, 92, 96,
- 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
- 148, 152, 156
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
+ 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 84, 88, 92, 96,
+ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156
};
static const int32_t buflim[4] =
{
{
static const int32_t kexc[25] =
{
- 8, -16, 26, -48, 86, -162, 294, -502, 718, -728, 184,
- 672, -610, -672, 184, 728, 718, 502, 294, 162, 86, 48, 26, 16, 8
+ 8, -16, 26, -48, 86, -162, 294, -502, 718, -728, 184,
+ 672, -610, -672, 184, 728, 718, 502, 294, 162, 86, 48,
+ 26, 16, 8
};
int32_t i;
int32_t j;
/* Synthesize a single pitch epoch */
static int pitsyn(lpc10_decode_state_t *s,
- int voice[],
+ int voice[],
int32_t *pitch,
float *rms,
float *rc,
- int32_t ivuv[],
+ int32_t ivuv[],
int32_t ipiti[],
float *rmsi,
float *rci,
/* If bit 2 of ICORF is set then smooth RMS and RC's, */
if ((icorf & bit[1]) != 0)
{
- if ((float) abs(s->drms[1] - s->drms[0]) >= corth[ixcor + 3]
+ if ((float) abs(s->drms[1] - s->drms[0]) >= corth[ixcor + 3]
&&
(float) abs(s->drms[1] - s->drms[2]) >= corth[ixcor + 3])
{
/* If bit 3 of ICORF is set then smooth pitch */
if ((icorf & bit[2]) != 0)
{
- if ((float) abs(s->dpit[1] - s->dpit[0]) >= corth[ixcor - 1]
+ if ((float) abs(s->dpit[1] - s->dpit[0]) >= corth[ixcor - 1]
&&
(float) abs(s->dpit[1] - s->dpit[2]) >= corth[ixcor - 1])
{
s->dei[i] = 0.0f;
for (i = 0; i < 3; i++)
s->deo[i] = 0.0f;
-
+
return s;
}
/*- End of function --------------------------------------------------------*/
int32_t af,
int32_t vwin[3][2],
int32_t awin[3][2],
- int32_t ewin[3][2],
+ int32_t ewin[3][2],
int32_t lframe,
int32_t maxwin);
void lpc10_placev(int32_t *osbuf,
int32_t *osptr,
- int32_t oslen,
+ int32_t oslen,
int32_t *obound,
int32_t vwin[3][2],
int32_t af,
const int32_t buflim[],
int32_t half,
float *minamd,
- float *maxamd,
+ float *maxamd,
int32_t *mintau,
float *ivrc,
int32_t *obound);
};
static const int32_t entau[60] =
{
- 19, 11, 27, 25, 29, 21, 23, 22, 30, 14, 15, 7, 39, 38, 46,
- 42, 43, 41, 45, 37, 53, 49, 51, 50, 54, 52, 60, 56, 58, 26,
- 90, 88, 92, 84, 86, 82, 83, 81, 85, 69, 77, 73, 75, 74, 78,
- 70, 71, 67, 99, 97, 113, 112, 114, 98, 106, 104, 108, 100,
- 101, 76
+ 19, 11, 27, 25, 29, 21, 23, 22, 30, 14, 15, 7, 39, 38, 46,
+ 42, 43, 41, 45, 37, 53, 49, 51, 50, 54, 52, 60, 56, 58, 26,
+ 90, 88, 92, 84, 86, 82, 83, 81, 85, 69, 77, 73, 75, 74, 78,
+ 70, 71, 67, 99, 97, 113, 112, 114, 98, 106, 104, 108, 100, 101, 76
};
static const int32_t enadd[8] =
{
};
static const int32_t rmst[64] =
{
- 1024, 936, 856, 784, 718, 656, 600, 550, 502,
- 460, 420, 384, 352, 328, 294, 270, 246, 226,
- 206, 188, 172, 158, 144, 132, 120, 110, 102,
- 92, 84, 78, 70, 64, 60, 54, 50,
- 46, 42, 38, 34, 32, 30, 26, 24,
- 22, 20, 18, 17, 16, 15, 14, 13,
- 12, 11, 10, 9, 8, 7, 6, 5, 4,
- 3, 2, 1, 0
+ 1024, 936, 856, 784, 718, 656, 600, 550,
+ 502, 460, 420, 384, 352, 328, 294, 270,
+ 246, 226, 206, 188, 172, 158, 144, 132,
+ 120, 110, 102, 92, 84, 78, 70, 64,
+ 60, 54, 50, 46, 42, 38, 34, 32,
+ 30, 26, 24, 22, 20, 18, 17, 16,
+ 15, 14, 13, 12, 11, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0
};
int32_t idel;
s->z21 = 0.0f;
s->z12 = 0.0f;
s->z22 = 0.0f;
-
+
/* State used by function lpc10_analyse */
for (i = 0; i < 540; i++)
{
/* State used by function lpc10_pack */
s->isync = 0;
-
+
return s;
}
/*- End of function --------------------------------------------------------*/
int32_t af,
int32_t vwin[3][2],
int32_t awin[3][2],
- int32_t ewin[3][2],
+ int32_t ewin[3][2],
int32_t lframe,
int32_t maxwin)
{
int32_t hrange;
int ephase;
int32_t lrange;
-
+
lrange = (af - 2)*lframe + 1;
hrange = af*lframe;
void lpc10_placev(int32_t *osbuf,
int32_t *osptr,
- int32_t oslen,
+ int32_t oslen,
int32_t *obound,
int32_t vwin[3][2],
int32_t af,
int32_t half,
float *dither,
int32_t *mintau,
- int32_t *zc,
+ int32_t *zc,
int32_t *lbe,
int32_t *fbe,
float *qs,
const int32_t buflim[],
int32_t half,
float *minamd,
- float *maxamd,
+ float *maxamd,
int32_t *mintau,
float ivrc[],
int32_t obound[])
int32_t lbe;
float snr2;
-#if (_MSC_VER >= 1400)
+#if (_MSC_VER >= 1400)
__analysis_assume(half >= 0 && half < 2);
#endif
inbuf_offset = 0;
vparms(vwin,
&inbuf[inbuf_offset],
&lpbuf[lpbuf_offset],
- buflim,
+ buflim,
half,
&s->dither,
mintau,
static trie_node_t *trie_node_create(void)
{
trie_node_t *s;
-
+
if ((s = (trie_node_t *) malloc(sizeof(*s))))
{
memset(s, 0, sizeof(*s));
static trie_t *trie_create(void)
{
trie_t *s;
-
+
if ((s = (trie_t *) malloc(sizeof(*s))))
{
memset(s, 0, sizeof(*s));
static void trie_recursive_add_node_numbers(trie_node_t *t)
{
int index;
-
+
if (t)
{
if (t->first <= t->last)
static void trie_recursive_build_packed_trie(trie_node_t *t)
{
int i;
-
+
if (t)
{
if (t->first <= t->last)
{
/* The character in u we are processing... */
index = (unsigned char) u[i];
-
+
/* Is there a child node for this character? */
if (t->child_list[index] == NULL)
{
if (index > t->last)
t->last = index;
}
-
+
/* Move to the new node... and loop */
t = t->child_list[index];
}
{
trie_t *s;
int i;
-
+
s = trie_create();
for (i = 0; wordlist[i]; i++)
/* sRGB to Linear RGB */
r = (r > 0.04045f) ? powf((r + 0.055f)/1.055f, 2.4f) : r/12.92f;
-
+
printf((i < 255) ? " %f,\n" : " %f\n", r);
}
printf("};\n");
-
+
printf("static const uint8_t linear_to_srgb[4096] =\n");
printf("{\n");
for (i = 0; i < 4096; i++)
for (i = 0; i < total_coeffs; i++)
coeffs[i] *= scaling;
}
-
+
/* Churn out the data as a C source code header file, which can be directly included by the
modem code. */
printf("#define TX_PULSESHAPER%s_GAIN %ff\n", tag, gain);
return ((y & 0x8000) | 0x4000);
abs_x = abs(x);
abs_y = abs(y);
-
+
if (abs_y < abs_x)
{
recip = fixed_reciprocal16(abs_x, &shift);
s->last_frame = NULL;
}
return frame;
- }
+ }
return NULL;
}
SPAN_DECLARE(playout_frame_t *) playout_get_unconditional(playout_state_t *s)
{
playout_frame_t *frame;
-
+
if ((frame = queue_get(s, 0x7FFFFFFF)))
{
/* Put it on the free list */
s->state_late += ((((frame->receiver_stamp > s->latest_expected) ? 0x10000000 : 0) - s->state_late) >> 8);
s->state_just_in_time += ((((frame->receiver_stamp > s->latest_expected - frame->sender_len) ? 0x10000000 : 0) - s->state_just_in_time) >> 8);
s->latest_expected += frame->sender_len;
-
+
if (s->state_late > s->dropable_threshold)
{
if (s->since_last_step < 10)
s->state_just_in_time = s->dropable_threshold;
s->state_late = 0;
s->since_last_step = 0;
-
+
s->last_speech_sender_stamp += s->last_speech_sender_len;
}
}
{
/* Rewind last_speech_sender_stamp, since this isn't speech */
s->last_speech_sender_stamp -= s->last_speech_sender_len;
-
+
*frameout = *frame;
/* Put it on the free list */
frame->later = s->free_frames;
s->free_frames = frame;
-
+
s->frames_out++;
return PLAYOUT_OK;
}
/* Find where it should go in the queue */
p = s->last_frame;
- while (sender_stamp < p->sender_stamp && p->earlier)
+ while (sender_stamp < p->sender_stamp && p->earlier)
p = p->earlier;
if (p->earlier)
s->start = TRUE;
s->since_last_step = 0x7FFFFFFF;
/* Start with the minimum buffer length allowed, and work from there */
- s->actual_buffer_length =
+ s->actual_buffer_length =
s->target_buffer_length = (s->max_length - s->min_length)/2;
}
/*- End of function --------------------------------------------------------*/
{
playout_frame_t *frame;
playout_frame_t *next;
-
+
/* Free all the frames in the queue. In most cases these should have been
removed already, so their associated data could be freed. */
for (frame = s->first_frame; frame; frame = next)
if (s)
{
playout_release(s);
- /* Finally, free ourselves! */
+ /* Finally, free ourselves! */
free(s);
}
return 0;
float old_weight;
float new_weight;
float gain;
-
+
if (s->missing_samples)
{
/* Although we have a real signal, we need to smooth it to fit well
SPAN_DECLARE(int) queue_free_space(queue_state_t *s)
{
int len;
-
+
if ((len = s->optr - s->iptr - 1) < 0)
len += s->len;
/*endif*/
SPAN_DECLARE(int) queue_contents(queue_state_t *s)
{
int len;
-
+
if ((len = s->iptr - s->optr) < 0)
len += s->len;
/*endif*/
int to_end;
int iptr;
int optr;
-
+
/* Snapshot the values (although only iptr should be changeable during this processing) */
iptr = s->iptr;
optr = s->optr;
int new_optr;
int iptr;
int optr;
-
+
/* Snapshot the values (although only iptr should be changeable during this processing) */
iptr = s->iptr;
optr = s->optr;
int iptr;
int optr;
int byte;
-
+
/* Snapshot the values (although only iptr should be changeable during this processing) */
iptr = s->iptr;
optr = s->optr;
ADEMCO_CONTACTID_MESSAGE_TYPE_18 = 0x18,
ADEMCO_CONTACTID_MESSAGE_TYPE_98 = 0x98
};
-
+
enum
{
ADEMCO_CONTACTID_QUALIFIER_NEW_EVENT = 1,
- ETSI ETS 300 648, ETS 300 659-1 CLIP (Calling Line Identity Presentation) DTMF standard
variant 1 (Belgium, Brazil, Denmark, Finland, Iceland, India, Netherlands, Saudi Arabia,
Sweden and Uruguay).
-
+
- ETSI ETS 300 648, ETS 300 659-1 CLIP (Calling Line Identity Presentation) DTMF standard
variant 2 (Denmark and Holland).
-
+
- ETSI ETS 300 648, ETS 300 659-1 CLIP (Calling Line Identity Presentation) DTMF standard
variant 3.
-
+
- ETSI ETS 300 648, ETS 300 659-1 CLIP (Calling Line Identity Presentation) DTMF standard
variant 4. (Taiwan and Kuwait).
-
+
- ETSI Caller-ID support in UK (British Telecom), British Telecomm SIN227, SIN242.
- Nippon Telegraph & Telephone Corporation JCLIP (Japanese Calling Line Identity
In other places, where the standard ring tone has much smaller silences,
a line voltage reversal is used to wake up a power saving receiver, then the
message is sent, then the phone begins to ring.
-
+
The message is sent using a Bell 202 FSK modem. The data rate is 1200 bits
per second. The message protocol uses 8-bit data words (bytes), each bounded
by a start bit and a stop bit.
Channel Carrier Message Message Data Checksum
Seizure Signal Type Length Word(s) Word
Signal Word Word
-
+
\section adsi_page_sec_2a1 CHANNEL SEIZURE SIGNAL
The channel seizure is 30 continuous bytes of 55h (01010101), including
the start and stop bits (i.e. 300 bits of alternations in total).
This provides a detectable alternating function to the CPE (i.e. the
modem data pump).
-
+
\section adsi_page_sec_2a2 CARRIER SIGNAL
The carrier signal consists of 180 bits of 1s. This may be reduced to 80
bits of 1s for caller ID on call waiting.
-
+
\section adsi_page_sec_2a3 MESSAGE TYPE WORD
-Various message types are defined. The commonest ones for the US CLASS
+Various message types are defined. The commonest ones for the US CLASS
standard are:
- Type 0x04 (SDMF) - single data message. Simple caller ID (CND)
- Type 0x80 (MDMF) - multiple data message. A more flexible caller ID,
with extra information.
-Other messages support message waiting, for voice mail, and other display features.
+Other messages support message waiting, for voice mail, and other display features.
\section adsi_page_sec_2a4 MESSAGE LENGTH WORD
The message length word specifies the total number of data words
to follow.
-
+
\section adsi_page_sec_2a5 DATA WORDS
The data words contain the actual message.
-
+
\section adsi_page_sec_2a6 CHECKSUM WORD
The Checksum Word contains the twos complement of the modulo 256
sum of the other words in the data message (i.e., message type,
- CPE hangs up on receipt of the caller ID message
- The phone line rings a second time
- The CPE answers a second time, connecting the called party with the caller.
-
+
Timeouts are, obviously, required to ensure this system behaves well when the caller ID message
or the second ring are missing.
*/
angle = 3.1415926f/2.0f - fx*fy/(y*y + 0.28125f*x*x);
else
angle = fy*fx/(x*x + 0.28125f*y*y);
-
+
/* Deal with the quadrants, to bring the final answer to the range +-pi */
if (x < 0.0f)
angle = 3.1415926f - angle;
paper somewhere. I can't track down where I got the original from,
so that due recognition can be given. The original had no explicit
copyright notice, and I hope nobody objects to its use here.
-
+
Having a reasonable Gaussian noise generator is pretty important for
telephony testing (in fact, pretty much any DSP testing), and this
one seems to have served me OK. Since the generation of Gaussian
noise is only for test purposes, and not a core system component,
I don't intend to worry excessively about copyright issues, unless
someone worries me.
-
+
The non-core nature of this code also explains why it is unlikely
to ever be optimised. */
\section awgn_page_sec_1 What does it do?
Adding noise is not the most useful thing in most DSP applications, but it is
-awfully useful for test suites.
+awfully useful for test suites.
\section awgn_page_sec_2 How does it work?
This code is based on some demonstration code in a research paper somewhere. I
can't track down where I got the original from, so that due recognition can be
given. The original had no explicit copyright notice, and I hope nobody objects
-to its use here.
+to its use here.
Having a reasonable Gaussian noise generator is pretty important for telephony
testing (in fact, pretty much any DSP testing), and this one seems to have
served me OK. Since the generation of Gaussian noise is only for test purposes,
and not a core system component, I don't intend to worry excessively about
-copyright issues, unless someone worries me.
+copyright issues, unless someone worries me.
The non-core nature of this code also explains why it is unlikely to ever be
optimised.
/*! \page mfc_r2_tone_generation_page MFC/R2 tone generation
\section mfc_r2_tone_generation_page_sec_1 What does it do?
The MFC/R2 tone generation module provides for the generation of the
-repertoire of 15 dual tones needs for the digital MFC/R2 signalling protocol.
+repertoire of 15 dual tones needs for the digital MFC/R2 signalling protocol.
\section mfc_r2_tone_generation_page_sec_2 How does it work?
*/
/*! \page bell_mf_tone_generation_page Bell MF tone generation
\section bell_mf_tone_generation_page_sec_1 What does it do?
The Bell MF tone generation module provides for the generation of the
-repertoire of 15 dual tones needs for various Bell MF signalling protocols.
+repertoire of 15 dual tones needs for various Bell MF signalling protocols.
\section bell_mf_tone_generation_page_sec_2 How does it work?
Basic Bell MF tone generation specs:
\section mfc_r2_tone_rx_page_sec_1 What does it do?
The MFC/R2 tone receiver module provides for the detection of the
-repertoire of 15 dual tones needs for the digital MFC/R2 signalling protocol.
+repertoire of 15 dual tones needs for the digital MFC/R2 signalling protocol.
It is compliant with ITU-T Q.441D.
\section mfc_r2_tone_rx_page_sec_2 How does it work?
\section bell_mf_tone_rx_page_sec_1 What does it do?
The Bell MF tone receiver module provides for the detection of the
-repertoire of 15 dual tones needs for various Bell MF signalling protocols.
+repertoire of 15 dual tones needs for various Bell MF signalling protocols.
It is compliant with ITU-T Q.320, ITU-T Q.322, ITU-T Q.323B.
\section bell_mf_tone_rx_page_sec_2 How does it work?
\param s The Bell MF generator context.
\param amp The buffer for the generated signal.
\param max_samples The required number of generated samples.
- \return The number of samples actually generated. This may be less than
+ \return The number of samples actually generated. This may be less than
max_samples if the input buffer empties. */
SPAN_DECLARE(int) bell_mf_tx(bell_mf_tx_state_t *s, int16_t amp[], int max_samples);
bq->a2 = a2;
bq->b1 = b1;
bq->b2 = b2;
-
+
bq->z1 = 0;
- bq->z2 = 0;
+ bq->z2 = 0;
#if FIRST_ORDER_NOISE_SHAPING
bq->residue = 0;
{
int32_t y;
int32_t z0;
-
+
z0 = sample*bq->gain + bq->z1*bq->a1 + bq->z2*bq->a2;
y = z0 + bq->z1*bq->b1 + bq->z2*bq->b2;
bq->z2 = bq->z1;
bq->z1 = z0 >> 15;
#if FIRST_ORDER_NOISE_SHAPING
- y += bq->residue;
+ y += bq->residue;
bq->residue = y & 0x7FFF;
#elif SECOND_ORDER_NOISE_SHAPING
y += (2*bq->residue1 - bq->residue2);
static __inline__ int bottom_bit(unsigned int bits)
{
int res;
-
+
#if defined(SPANDSP_USE_86_ASM)
__asm__ (" xorl %[res],%[res];\n"
" decl %[res];\n"
{
-436, -829, -2797, -4208, -17968, -11215, 46150, 34480,
-10427, 9049, -1309, -6320, 390, -8191, -1751, -6051,
- -3796, -4055, -3948, -2557, -3372, -1808, -2259, -1300,
+ -3796, -4055, -3948, -2557, -3372, -1808, -2259, -1300,
-1098, -618, -340, -61, 323, 419, 745, 716,
946, 880, 1014, 976, 1033, 1091, 1053, 1042,
- 794, 831, 899, 716, 390, 313, 304, 304,
+ 794, 831, 899, 716, 390, 313, 304, 304,
73, -119, -109, -176, -359, -407, -512, -580,
- -704, -618, -685, -791, -772, -820, -839, -724
+ -704, -618, -685, -791, -772, -820, -839, -724
};
#define LINE_MODEL_D2_GAIN 1.39E-5f
-4470, 25356, 11458, -19696, -11800, 5766, 789, 6633,
14624, -6975, -17156, -187, 149, 1515, 14907, 4345,
-7128, -2757, -10185, -7083, 6850, 3944, 6969, 8694,
- -4068, -3852, -5793, -9371, 453, 1060, 3965, 9463,
+ -4068, -3852, -5793, -9371, 453, 1060, 3965, 9463,
2393, 2784, -892, -7366, -3376, -5847, -2399, 3011,
1537, 6623, 4205, 1602, 1592, -4752, -3646, -5207,
- -5577, -501, -1174, 4041, 5647, 4628, 7252, 2123,
+ -5577, -501, -1174, 4041, 5647, 4628, 7252, 2123,
2654, -881, -4113, -3244, -7289, -3830, -4600, -2508,
431, -144, 4184, 2372, 4617, 3576, 2382, 2839,
- -404, 539, -1803, -1401, -1705, -2269, -783, -1608,
+ -404, 539, -1803, -1401, -1705, -2269, -783, -1608,
-220, -306, 257, 615, 225, 561, 8, 344,
127, -57, 182, 41, 203, -111, 95, -79,
- 30, 84, -13, -68, -241, -68, -24, 19,
+ 30, 84, -13, -68, -241, -68, -24, 19,
-57, -24, 30, -68, 84, -155, -68, 19
};
#define LINE_MODEL_D5_GAIN 1.77E-5f
-821, -2068, -2236, -4283, -3406, -5022, -4039, -4842,
-4104, -4089, -3582, -2978, -2734, -1805, -1608, -645,
-495, 279, 471, 947, 1186, 1438, 1669, 1640,
- 1901, 1687, 1803, 1543, 1566, 1342, 1163, 963,
+ 1901, 1687, 1803, 1543, 1566, 1342, 1163, 963,
733, 665, 323, 221, -14, -107, -279, -379,
-468, -513, -473, -588, -612, -652, -616, -566,
-515, -485, -404, -344, -290, -202, -180, -123
3946, 4414, 4026, 3005, 3380, 1616, 2007, 158,
388, -1198, -1117, -2134, -2547, -2589, -3310, -2778,
-3427, -2779, -3116, -2502, -2399, -1956, -1539, -1239,
- -570, -377, 251, 331, 964, 1177, 1449, 1564,
+ -570, -377, 251, 331, 964, 1177, 1449, 1564,
1724, 1871, 1767, 1802, 1630, 1632, 1379, 1271,
1063, 856, 711, 482, 289, 54, -137, -321,
-490, -638, -764, -836, -800, -859, -838, -837,
-16854, -3115, 9483, -17799, 7399, -4342, -7415, 7929,
-10726, 6239, -2526, -1317, 5345, -4565, 6868, -2195,
3425, 1969, -109, 3963, -1275, 3087, -892, 1239,
- 2, -427, 596, -1184, 551, -1244, 141, -743,
+ 2, -427, 596, -1184, 551, -1244, 141, -743,
-415, -372, -769, -183, -785, -270, -659, -377,
-523, -325, -245, -255, -60, 35, 218, 149,
340, 233, 365, 303, 251, 230, 209, 179
the first 1" instruction. A little in-line assembler fixes that, and the
conversion routines can be faster than lookup tables, in most real world usage.
A "find the first 1" instruction is available on most modern CPUs, and is a
-much underused feature.
+much underused feature.
If an assembly language method of bit searching is not available, these routines
revert to a method that can be a little slow, so the cache thrashing might not
* segment, but a little inline assembly can fix that on an i386, x86_64 and
* many other modern processors.
*/
-
+
/*
* Mu-law is basically as follows:
*
static __inline__ int16_t ulaw_to_linear(uint8_t ulaw)
{
int t;
-
+
/* Complement to obtain normal u-law value. */
ulaw = ~ulaw;
/*
{
int mask;
int seg;
-
+
if (linear >= 0)
{
/* Sign (bit 7) bit = 1 */
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+
/*! \file */
#if !defined(_SPANDSP_MODEM_CONNECT_TONES_H_)
frequency. This type of detector may seem less intuitive than using a narrow
bandpass filter to isolate the energy at the notch freqency. However, a sharp
bandpass implemented as an IIR filter rings badly. The reciprocal notch filter
-is very well behaved for our purpose.
+is very well behaved for our purpose.
*/
enum
This module aims to cancel electrical echoes (e.g. from 2-4 wire hybrids)
in modem applications. It is not very suitable for speech applications, which
require additional refinements for satisfactory performance. It is, however, more
-efficient and better suited to modem applications.
+efficient and better suited to modem applications.
\section modem_echo_can_page_sec_2 How does it work?
The heart of the echo cancellor is an adaptive FIR filter. This is adapted to
then subtracted from the received signal, and the result should be an estimate
of the signal which originates within the environment being cancelled (people
talking in the room, or the signal from the far end of a telephone line) free
-from the echos of our own transmitted signal.
+from the echos of our own transmitted signal.
The FIR filter is adapted using the least mean squares (LMS) algorithm. This
algorithm is attributed to Widrow and Hoff, and was introduced in 1960. It is
the commonest form of filter adaption used in things like modem line equalisers
and line echo cancellers. It works very well if the signal level is constant,
which is true for a modem signal. To ensure good performa certain conditions must
-be met:
+be met:
- The transmitted signal has weak self-correlation.
- There is no signal being generated within the environment being cancelled.
can go seriously wrong. The reason is there is only one solution for the
adaption on a near random signal. For a repetitive signal, there are a number of
solutions which converge the adaption, and nothing guides the adaption to choose
-the correct one.
+the correct one.
\section modem_echo_can_page_sec_3 How do I use it?
The echo cancellor processes both the transmit and receive streams sample by
sample. The processing function is not declared inline. Unfortunately,
cancellation requires many operations per sample, so the call overhead is only a
-minor burden.
+minor burden.
*/
#include "fir.h"
int tx_digits_len;
/*! \brief The number of consecutive retries. */
int tries;
-
+
int tone_state;
int duration;
int last_hit;
int stop_bits;
/*! */
int baudot_shift;
-
+
/*! */
logging_state_t logging;
};
int msg_len;
/*! */
int baudot_shift;
-
+
/*! A count of the framing errors. */
int framing_errors;
int rx_window;
/*! Value set by +EWIND */
int tx_window;
-
+
int v8bis_signal;
int v8bis_1st_message;
int v8bis_2nd_message;
int ptr;
g722_band_t band[2];
-
+
uint32_t in_buffer;
int in_bits;
uint32_t out_buffer;
int16_t dml;
/*! Linear weighting coefficient of 'yl' and 'yu'. */
int16_t ap;
-
+
/*! Coefficients of pole portion of prediction filter. */
int16_t a[2];
/*! Coefficients of zero portion of prediction filter. */
int16_t sr[2];
/*! Delayed tone detect */
int td;
-
+
/*! \brief The bit stream processing context. */
bitstream_state_t bs;
int16_t v[9];
/*! Decoder postprocessing */
int16_t msr;
-
+
/*! Encoder data */
int16_t e[50];
};
float z12;
/*! \brief ??? */
float z22;
-
+
/* State used by function lpc10_analyse */
/*! \brief ??? */
float inbuf[LPC10_SAMPLES_PER_FRAME*3];
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+
/*! \file */
#if !defined(_SPANDSP_PRIVATE_MODEM_CONNECT_TONES_H_)
int flat_mode_timeout;
/*! \brief ??? */
int notch_insertion_timeout;
-
+
/*! \brief ??? */
int signalling_state;
/*! \brief ??? */
/*! \brief TRUE if behaving as the calling party */
int calling_party;
-
+
/*! \brief Internet aware FAX mode bit mask. */
int iaf;
/*! \brief A bit mask of the currently supported modem types. */
/*! \brief TRUE once the far end FAX entity has been detected. */
int far_end_detected;
-
+
/*! \brief TRUE once the end of procedure condition has been detected. */
int end_of_procedure_detected;
int16_t ecm_len[256];
/*! \brief A bit map of the OK ECM frames, constructed as a PPR frame. */
uint8_t ecm_frame_map[3 + 32];
-
+
/*! \brief The current page number for receiving, in ECM or non-ECM mode. This is reset at the start of a call. */
int rx_page_number;
/*! \brief The current page number for sending, in ECM or non-ECM mode. This is reset at the start of a call. */
/* In a DIS/DTC frame, setting bit 97 to "0" indicates that the called terminal does not have the
capability to accept 300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm
resolutions for colour/gray-scale images or T.44 Mixed Raster Content (MRC) mask layer.
-
+
Setting bit 97 to "1" indicates that the called terminal does have the capability to accept
300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm resolutions for
colour/gray-scale images and MRC mask layer. Bit 97 is valid only when bits 68 and 42 or 43
(300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm) are set to "1".
-
+
In a DCS frame, setting bit 97 to "0" indicates that the calling terminal does not use
300 pels/25.4 mm x 300 lines/25.4 mm or 400 pels/25.4 mm x 400 lines/25.4 mm resolutions
for colour/gray-scale images and mask layer.
-
+
Setting bit 97 to "1" indicates that the calling terminal uses 300 pels/25.4 mm x 300 lines/25.4 mm
or 400 pels/25.4 mm x 400 lines/25.4 mm resolutions for colour/gray-scale images and MRC mask layer.
Bit 97 is valid only when bits 68 and 42 or 43 (300 pels/25.4 mm x 300 lines/25.4 mm and
Method 2: Transfer of TCF is required for use with UDP (UDPTL or RTP).
Method 2 is not recommended for use with TCP. */
int data_rate_management_method;
-
+
/*! \brief The emitting gateway may indicate a preference for either UDP/UDPTL, or
UDP/RTP, or TCP for transport of T.38 IFP Packets. The receiving device
selects the transport protocol. */
int max_buffer_size;
/*! \brief This option indicates the maximum size of a UDPTL packet or the
- maximum size of the payload within an RTP packet that can be accepted
+ maximum size of the payload within an RTP packet that can be accepted
by the remote device. */
int max_datagram_size;
over TCP they are not relevent. */
int check_sequence_numbers;
- /*! \brief The number of times each packet type will be sent (low byte). The
+ /*! \brief The number of times each packet type will be sent (low byte). The
depth of redundancy (2nd byte). Higher numbers may increase reliability
for UDP transmission. Zero is valid for the indicator packet category,
to suppress all indicator packets (typicaly for TCP transmission). */
int y_resolution;
/* "Background" information about the FAX, which can be stored in the image file. */
- /*! \brief The vendor of the machine which produced the file. */
+ /*! \brief The vendor of the machine which produced the file. */
const char *vendor;
- /*! \brief The model of machine which produced the file. */
+ /*! \brief The model of machine which produced the file. */
const char *model;
- /*! \brief The remote end's ident string. */
+ /*! \brief The remote end's ident string. */
const char *far_ident;
- /*! \brief The FAX sub-address. */
+ /*! \brief The FAX sub-address. */
const char *sub_address;
- /*! \brief The FAX DCS information, as an ASCII hex string. */
+ /*! \brief The FAX DCS information, as an ASCII hex string. */
const char *dcs;
} t4_rx_metadata_t;
/*! \brief The type of compression used between the FAX machines. */
int line_encoding;
-
+
/*! \brief The width of the current page, in pixels. */
uint32_t image_width;
in no header line. */
const char *header_info;
/*! \brief The local ident string. This is used with header_info to form a
- page header line. */
+ page header line. */
const char *local_ident;
/*! \brief The page number of current page. The first page is zero. If FAX page
headers are used, the page number in the header will be one more than
/*! \brief The carrier update rate saved for reuse when using short training. */
int32_t carrier_phase_rate_save;
- /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
+ /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
power_meter_t power;
/*! \brief The power meter level at which carrier on is declared. */
int32_t carrier_on_power;
int32_t carrier_phase_rate;
/*! \brief The current fractional phase of the baud timing. */
int baud_phase;
-
+
/*! \brief The current number of data bits per symbol. This does not include
the redundant bit. */
int bits_per_symbol;
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+
#if !defined(_SPANDSP_PRIVATE_V18_H_)
#define _SPANDSP_PRIVATE_V18_H_
routine. */
void *qam_user_data;
- /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
+ /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
power_meter_t rx_power;
/*! \brief The power meter level at which carrier on is declared. */
int32_t carrier_on_power;
int total_baud_timing_correction;
/*! \brief The current fractional phase of the baud timing. */
int baud_phase;
-
+
int sixteen_way_decisions;
int pattern_repeats;
/*! \brief The carrier update rate saved for reuse when using short training. */
int32_t carrier_phase_rate_save;
- /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
+ /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
power_meter_t power;
/*! \brief The power meter level at which carrier on is declared. */
int32_t carrier_on_power;
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
int rrc_filter_step;
-
+
/*! \brief The register for the training and data scrambler. */
uint32_t scramble_reg;
/*! \brief A counter for the number of consecutive bits of repeating pattern through
/*! \brief The carrier update rate saved for reuse when using short training. */
int32_t carrier_phase_rate_save;
- /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
+ /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */
power_meter_t power;
/*! \brief The power meter level at which carrier on is declared. */
int32_t carrier_on_power;
/*! \brief Compression performance metric */
uint16_t compression_performance;
- /*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */
+ /*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */
uint32_t bit_buffer;
- /*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */
+ /*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */
int bit_count;
/*! \brief The output composition buffer */
uint8_t output_buf[V42BIS_MAX_OUTPUT_LENGTH];
- /*! \brief The length of the contents of the output composition buffer */
+ /*! \brief The length of the contents of the output composition buffer */
int output_octet_count;
/*! \brief The current value of the escape code */
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+
#if !defined(_SPANDSP_PRIVATE_V8_H_)
#define _SPANDSP_PRIVATE_V8_H_
int preamble_type;
uint8_t rx_data[64];
int rx_data_ptr;
-
+
/*! \brief a reference copy of the last CM or JM message, used when
testing for matches. */
uint8_t cm_jm_data[64];
The T.30 spec. specifies a number of time-outs. For example, after dialing a number,
a calling fax system should listen for a response for 35 seconds before giving up.
-These time-out periods are as follows:
+These time-out periods are as follows:
- T1 - 35+-5s: the maximum time for which two fax system will attempt to identify each other
- T2 - 6+-1s: a time-out used to start the sequence for changing transmit parameters
calling fax system is supposed to wait for 35 seconds before giving up. If the
answering unit does not answer on the first ring or if a voice answering machine
is connected to the line, or if there are many delays through the network,
-the delay before answer can be much longer than 35 seconds.
+the delay before answer can be much longer than 35 seconds.
Fax units that support error correction mode (ECM) can respond to a post-image
handshake message with a receiver not ready (RNR) message. The calling unit then
message. According to the T.30 standard, this sequence (RR/RNR RR/RNR) can be
repeated for up to the end of T5 (60+-5s). However, many fax systems
ignore the time-out and will continue the sequence indefinitely, unless the user
-manually overrides.
+manually overrides.
All the time-outs are subject to alteration, and sometimes misuse. Good T.30
implementations must do the right thing, and tolerate others doing the wrong thing.
This may be stretched to well over 100ms. If this period is too long, it can interfere with
handshake signal error recovery, should a packet be corrupted on the line. Systems
should ensure they stay within the prescribed T.30 limits, and be tolerant of others
-being out of spec..
+being out of spec..
\subsection t30_page_sec_2d Other timing variations
repetitions, and also in the pauses between the receipt of a handshake command and
the start of a response to that command. In order to reduce the total
transmission time, many fax systems start sending a response message before the
-end of the command has been received.
+end of the command has been received.
\subsection t30_page_sec_2e Other deviations from the T.30 standard
T30_ERR_BADTAG, /*! Incorrect values for TIFF/F tags */
T30_ERR_BADTIFFHDR, /*! Bad TIFF/F header - incorrect values in fields */
T30_ERR_NOMEM, /*! Cannot allocate memory for more pages */
-
+
/* General problems */
T30_ERR_RETRYDCN, /*! Disconnected after permitted retries */
T30_ERR_CALLDROPPED, /*! The call dropped prematurely */
-
+
/* Feature negotiation issues */
T30_ERR_NOPOLL, /*! Poll not accepted */
T30_ERR_IDENT_UNACCEPTABLE, /*! Far end's ident is not acceptable */
\param s The T.31 modem context.
\return The number of bytes of free space. */
SPAN_DECLARE(int) t31_at_rx_free_space(t31_state_t *s);
-
+
SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len);
/*! Process a block of received T.31 modem audio samples.
*/
/*! The buffer length much be a power of two. The chosen length is big enough for
- over 9s of data at the V.17 14,400bps rate. */
+ over 9s of data at the V.17 14,400bps rate. */
#define T38_NON_ECM_TX_BUF_LEN 16384
/*! \brief A flow controlled non-ECM image data buffer, for buffering T.38 to analogue
/*! \page tone_generation_page Tone generation
\section tone_generation_page_sec_1 What does it do?
The tone generation module provides for the generation of cadenced tones,
-suitable for a wide range of telephony applications.
+suitable for a wide range of telephony applications.
\section tone_generation_page_sec_2 How does it work?
Oscillators are a problem. They oscillate due to instability, and yet we need
we are only concerned with telephony applications. It is possible to generate
the tones we need with a very simple efficient scheme. It is also practical to
use an exhaustive test to prove the oscillator is stable under all the
-conditions in which we will use it.
+conditions in which we will use it.
*/
typedef struct tone_gen_tone_descriptor_s tone_gen_tone_descriptor_t;
at data rates of 14400, 12000, 9600 and 7200 bits/second. The audio input is a stream
of 16 bit samples, at 8000 samples/second. The transmit and receive side of V.17
modems operate independantly. V.17 is mostly used for FAX transmission over PSTN
-lines, where it provides the standard 14400 bits/second rate.
+lines, where it provides the standard 14400 bits/second rate.
\section v17rx_page_sec_2 How does it work?
V.17 uses QAM modulation, at 2400 baud, and trellis coding. Constellations with
based on the angular difference between each received constellation position and
its expected position, is sufficient to track the carrier, and maintain phase
alignment. A fast rough approximator for the arc-tangent function is adequate
-for the estimation of the angular error.
+for the estimation of the angular error.
The next phase of the training sequence is a scrambled sequence of two
particular symbols. We train the T/2 adaptive equalizer using this sequence. The
equalizer should be sufficiently well adapted that is can correctly resolve the
full QAM constellation. However, the equalizer continues to adapt throughout
operation of the modem, fine tuning on the more complex data patterns of the
-full QAM constellation.
+full QAM constellation.
In the last phase of the training sequence, the modem enters normal data
operation, with a short defined period of all ones as data. As in most high
operate at data rates of 14400, 12000, 9600 and 7200 bits/second. The audio
output is a stream of 16 bit samples, at 8000 samples/second. The transmit and
receive side of V.17 modems operate independantly. V.17 is mostly used for FAX
-transmission, where it provides the standard 14400 bits/second rate.
+transmission, where it provides the standard 14400 bits/second rate.
\section v17tx_page_sec_2 How does it work?
V.17 uses QAM modulation and trellis coding. The data to be transmitted is
rate which is a multiple of the baud rate. The raw signal is then a series of
complex pulses, each an integer number of samples long. These can be shaped,
using a suitable complex filter, and multiplied by a complex carrier signal
-to produce the final QAM signal for transmission.
+to produce the final QAM signal for transmission.
The pulse shaping filter is only vaguely defined by the V.17 spec. Some of the
other ITU modem specs. fully define the filter, typically specifying a root
started in quadrature, might be more efficient, as it would have less impact on
the processor cache than a table lookup approach. However, the DDS approach
suits the receiver better, so the same signal generator is also used for the
-transmitter.
+transmitter.
*/
/*!
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+
/*! \file */
/*! \page v18_page The V.18 text telephony protocols
at data rates of 4800 and 2400 bits/s. The audio input is a stream of 16 bit samples,
at 8000 samples/second. The transmit and receive side of V.27ter modems operate
independantly. V.27ter is mostly used for FAX transmission, where it provides the
-standard 4800 bits/s rate (the 2400 bits/s mode is not used for FAX).
+standard 4800 bits/s rate (the 2400 bits/s mode is not used for FAX).
\section v27ter_rx_page_sec_2 How does it work?
V.27ter defines two modes of operation. One uses 8-PSK at 1600 baud, giving 4800bps.
can operate at data rates of 4800 and 2400 bits/s. The audio output is a stream
of 16 bit samples, at 8000 samples/second. The transmit and receive side of
V.27ter modems operate independantly. V.27ter is used for FAX transmission,
-where it provides the standard 4800 and 2400 bits/s rates.
+where it provides the standard 4800 and 2400 bits/s rates.
\section v27ter_tx_page_sec_2 How does it work?
V.27ter uses DPSK modulation. A common method of producing a DPSK modulated
signal is to use a sampling rate which is a multiple of the baud rate. The raw
signal is then a series of complex pulses, each an integer number of samples
long. These can be shaped, using a suitable complex filter, and multiplied by a
-complex carrier signal to produce the final DPSK signal for transmission.
+complex carrier signal to produce the final DPSK signal for transmission.
The pulse shaping filter for V.27ter is defined in the spec. It is a root raised
-cosine filter with 50% excess bandwidth.
+cosine filter with 50% excess bandwidth.
The sampling rate for our transmitter is defined by the channel - 8000 samples/s.
This is a multiple of the baud rate at 4800 bits/s (8-PSK at 1600 baud, 5 samples per
bit samples, at 8000 samples/second. The transmit and receive side of V.29
modems operate independantly. V.29 is mostly used for FAX transmission, where it
provides the standard 9600 and 7200 bits/s rates (the 4800 bits/s mode is not
-used for FAX).
+used for FAX).
\section v29rx_page_sec_2 How does it work?
V.29 operates at 2400 baud for all three bit rates. It uses 16-QAM modulation for
based on the angular difference between each received constellation position and
its expected position, is sufficient to track the carrier, and maintain phase
alignment. A fast rough approximator for the arc-tangent function is adequate
-for the estimation of the angular error.
+for the estimation of the angular error.
The next phase of the training sequence is a scrambled sequence of two
particular symbols. We train the T/2 adaptive equalizer using this sequence. The
equalizer should be sufficiently well adapted that is can correctly resolve the
full QAM constellation. However, the equalizer continues to adapt throughout
operation of the modem, fine tuning on the more complex data patterns of the
-full QAM constellation.
+full QAM constellation.
In the last phase of the training sequence, the modem enters normal data
operation, with a short defined period of all ones as data. As in most high
transmit side of some real V.29 modems fail to initialise their scrambler before
sending the ones. This means the first 23 received bits (the length of the
scrambler register) cannot be trusted for the test. The receive modem,
-therefore, only tests that bits starting at bit 24 are really ones.
+therefore, only tests that bits starting at bit 24 are really ones.
*/
#if defined(SPANDSP_USE_FIXED_POINT)
stream of 16 bit samples, at 8000 samples/second. The transmit and receive side
of V.29 modems operate independantly. V.29 is mostly used for FAX transmission,
where it provides the standard 9600 and 7200 bits/s rates (the 4800 bits/s mode
-is not used for FAX).
+is not used for FAX).
\section v29tx_page_sec_2 How does it work?
V.29 uses QAM modulation. The standard method of producing a QAM modulated
signal is to use a sampling rate which is a multiple of the baud rate. The raw
signal is then a series of complex pulses, each an integer number of samples
long. These can be shaped, using a suitable complex filter, and multiplied by a
-complex carrier signal to produce the final QAM signal for transmission.
+complex carrier signal to produce the final QAM signal for transmission.
The pulse shaping filter is only vaguely defined by the V.29 spec. Some of the
other ITU modem specs. fully define the filter, typically specifying a root
started in quadrature, might be more efficient, as it would have less impact on
the processor cache than a table lookup approach. However, the DDS approach
suits the receiver better, so the same signal generator is also used for the
-transmitter.
+transmitter.
The equation defining QAM modulation is:
using the identity
cos(x + y) = cos(x)*cos(y) - sin(x)*sin(y)
-
+
we get
s(n) = A {cos(2*pi*f*n)*cos(phi(n)) - sin(2*pi*f*n)*sin(phi(n))}
-
+
substituting with the constellation positions
I(n) = A*cos(phi(n))
Q(n) = A*sin(phi(n))
-
+
gives
s(n) = I(n)*cos(2*pi*f*n) - Q(n)*sin(2*pi*f*n)
/*! Initialise a V.42 context.
\param s The V.42 context.
\param calling_party TRUE if caller mode, else answerer mode.
- \param detect TRUE to perform the V.42 detection, else go straight into LAP.M
+ \param detect TRUE to perform the V.42 detection, else go straight into LAP.M
\param iframe_get A callback function to handle received frames of data.
\param iframe_put A callback function to get frames of data for transmission.
\param user_data An opaque pointer passed to the frame handler routines.
\param len The length of the data buffer.
\return 0 */
SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t buf[], int len);
-
+
/*! Flush out any data remaining in the decompression buffer.
\param s The V.42bis context.
\return 0 */
static int send_pps_frame(t30_state_t *s)
{
uint8_t frame[7];
-
+
frame[0] = ADDRESS_FIELD;
frame[1] = CONTROL_FIELD_FINAL_FRAME;
frame[2] = (uint8_t) (T30_PPS | s->dis_received);
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_300_300_CAPABLE);
if ((s->supported_resolutions & (T30_SUPPORT_400_400_RESOLUTION | T30_SUPPORT_R16_RESOLUTION)))
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_400_400_CAPABLE);
- /* Metric */
+ /* Metric */
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_METRIC_RESOLUTION_PREFERRED);
/* Superfine minimum scan line time pattern follows fine */
if ((s->supported_t30_features & T30_SUPPORT_SELECTIVE_POLLING))
}
/* Start document reception */
span_log(&s->logging,
- SPAN_LOG_FLOW,
+ SPAN_LOG_FLOW,
"Get document at %dbps, modem %d\n",
fallback_sequence[s->current_fallback].bit_rate,
fallback_sequence[s->current_fallback].modem_type);
s->ecm_len[frame_no] = -1;
}
}
- }
+ }
if (s->ecm_len[frame_no] < 0)
{
s->ecm_frame_map[i + 3] |= (1 << j);
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for PPR bits - %d\n", (len - 3)*8);
/* This frame didn't get corrupted in transit, because its CRC is OK. It was sent bad
and there is little possibility that causing a retransmission will help. It is best
- to just give up. */
+ to just give up. */
t30_set_status(s, T30_ERR_TX_ECMPHD);
disconnect(s);
return;
{
uint8_t fcf;
uint8_t fcf2;
-
+
/* This actually handles 2 states - _DOC_ECM and _POST_DOC_ECM - as they are very similar */
fcf = msg[2] & 0xFE;
switch (fcf)
static void timer_t2_t4_stop(t30_state_t *s)
{
const char *tag;
-
+
switch (s->timer_t2_t4_is)
{
case TIMER_IS_IDLE:
static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt, int len)
{
uint8_t *t;
-
+
if ((t = malloc(len - 1)) == NULL)
return 0;
memcpy(t, pkt + 1, len - 1);
SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
{
t30_state_t *s;
-
+
s = (t30_state_t *) user_data;
switch (status)
char s[10] = ".... ....";
int bit;
uint8_t octet;
-
+
/* Break out the octet and the bit number within it. */
octet = msg[((bit_no - 1) >> 3) + 3];
bit_no = (bit_no - 1) & 7;
int i;
uint8_t octet;
const char *tag;
-
+
/* Break out the octet and the bit number range within it. */
octet = msg[((start - 1) >> 3) + 3];
start = (start - 1) & 7;
span_log(log, SPAN_LOG_FLOW, " Frame is short\n");
return;
}
-
+
span_log(log, SPAN_LOG_FLOW, "%s:\n", t30_frametype(pkt[2]));
if (len <= 3)
{
span_log(log, SPAN_LOG_FLOW, " Frame is short\n");
return;
}
-
+
if (frame_type == T30_DCS)
{
octet_reserved_bit(log, pkt, 9, 0);
int stuffed;
int i;
int j;
-
+
bitstream = 0;
ones = 0;
stuffed = 0;
static int process_rx_missing(t38_core_state_t *t, void *user_data, int rx_seq_no, int expected_seq_no)
{
t31_state_t *s;
-
+
s = (t31_state_t *) user_data;
s->t38_fe.rx_data_missing = TRUE;
return 0;
/* WORKAROUND: At least some Mediatrix boxes have a bug, where they can send this message at the
end of non-ECM data. We need to tolerate this. We use the generic receive complete
indication, rather than the specific HDLC carrier down. */
- /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END -
+ /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END -
i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops.
The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */
fe->hdlc_rx.len = 0;
static int t31_modem_control_handler(at_state_t *s, void *user_data, int op, const char *num)
{
t31_state_t *t;
-
+
t = (t31_state_t *) user_data;
switch (op)
{
s->audio.silence_heard = 0;
}
else
- {
+ {
if (s->audio.silence_heard <= ms_to_samples(255*10))
s->audio.silence_heard++;
/*endif*/
{
/* Pad to the requested length with silence */
memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
- len = max_len;
+ len = max_len;
}
/*endif*/
return len;
void *tx_packet_user_data)
{
t31_t38_front_end_state_t *s;
-
+
s = &t->t38_fe;
t38_core_init(&s->t38,
* Copyright (c) 1994-1996 Silicon Graphics, Inc.
* HylaFAX is a trademark of Silicon Graphics
*
- * Permission to use, copy, modify, distribute, and sell this software and
+ * Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
{5, "\x80\x00\x8A\x49\x10", "Laser Class 9000 Series"},
{5, "\x80\x00\x8A\x48\x00", "Laser Class 2060"},
{0, NULL, NULL}
-};
+};
static const model_data_t Brother[] =
{
{0, NULL, NULL}
};
-static const model_data_t PitneyBowes[] =
+static const model_data_t PitneyBowes[] =
{
{6, "\x79\x91\xB1\xB8\x7A\xD8", "9550"},
{0, NULL, NULL}
};
-static const model_data_t Dialogic[] =
+static const model_data_t Dialogic[] =
{
{8, "\x56\x8B\x06\x55\x00\x15\x00\x00", "VFX/40ESC"},
{0, NULL, NULL}
* identified by a single manufacturer byte.
*
* T.30 5.3.6.2.7 (2003) states that the NSF FIF is transmitted
- * in MSB2LSB order. Revisions of T.30 prior to 2003 did not
+ * in MSB2LSB order. Revisions of T.30 prior to 2003 did not
* contain explicit specification as to the transmit bit order.
* (Although it did otherwise state that all HDLC frame data should
* be in MSB order except as noted.) Because CSI, TSI, and other
*
* Thus, country code x61 (Korea) turns into x86 (Papua New Guinea),
* code xB5 (USA) turns into xAD (Tunisia), code x26 (China) turns
- * into x64 (Lebanon), code x04 (Germany) turns into x20 (Canada),
+ * into x64 (Lebanon), code x04 (Germany) turns into x20 (Canada),
* and code x3D (France) turns into xBC (Vietnam).
*
* For the most part it should be safe to identify a manufacturer
}
/* We need to apply realism over accuracy, though it blocks out some countries.
It is very rare to find a machine from any country but the following:
-
+
Japan 0x00 (no confusion)
Germany 0x04 (0x20) (Canada/Germany confusion)
China 0x26 (0x64) (China/Lebanon confusion)
/* Right now there are no extension codes defined by the ITU */
return NULL;
}
-
+
return t35_country_codes[country_code].name;
}
/*- End of function --------------------------------------------------------*/
- 3. the result of a hop in the sequence numbers cause by something weird from the other
end. Stream switching might cause this
- 4. missing packets.
-
+
In cases 1 and 2 we need to drop this packet. In case 2 it might make sense to try to do
something with it in the terminal case. Currently we don't. For gateway operation it will be
too late to do anything useful.
t38_core_state_t *t;
int expected;
int expected_alt;
-
+
t = &s->t38x.t38;
expected = -1;
expected_alt = -1;
static int process_rx_missing(t38_core_state_t *t, void *user_data, int rx_seq_no, int expected_seq_no)
{
t38_gateway_state_t *s;
-
+
s = (t38_gateway_state_t *) user_data;
s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].flags |= HDLC_FLAG_MISSING_DATA;
return 0;
{
xx->t38.v34_rate = t38_v34rate_to_bps(buf, len);
span_log(&s->logging, SPAN_LOG_FLOW, "V.34 rate %d bps\n", xx->t38.v34_rate);
- }
+ }
else
{
span_log(&s->logging, SPAN_LOG_FLOW, "Bad length for V34rate message - %d\n", len);
}
else
{
- /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END -
+ /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END -
i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops.
The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. In
this case we just clear out any partial frame data that might be in the buffer. */
static void set_octets_per_data_packet(t38_gateway_state_t *s, int bit_rate)
{
int octets;
-
+
octets = s->core.ms_per_tx_chunk*bit_rate/(8*1000);
if (octets < 1)
octets = 1;
t38_gateway_state_t *s;
t38_gateway_to_t38_state_t *u;
int category;
-
+
s = (t38_gateway_state_t *) t->frame_user_data;
u = &s->core.to_t38;
if ((t->raw_bit_stream & 0x80))
int len;
#if defined(LOG_FAX_AUDIO)
int required_len;
-
+
required_len = max_len;
#endif
if ((len = s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp, max_len)) < max_len)
{
/* Pad to the requested length with silence */
memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
- len = max_len;
+ len = max_len;
}
/*endif*/
#if defined(LOG_FAX_AUDIO)
An EOL 11 zeros followed by a one in a T.4 1D image or 11 zeros followed by a one followed
by a one or a zero in a T.4 2D image. An RTC consists of 6 EOLs in succession, with no
pixel data between them.
-
+
We can stuff with ones until we get the first EOL into our buffer, then we can stuff with
zeros in front of each EOL at any point up the the RTC. We should not pad between the EOLs
which make up the RTC. Most FAX machines don't care about this, but a few will not recognise
the RTC if here is padding between the EOLs.
-
+
We need to buffer whole rows before we output their beginning, so there is no possibility
of underflow mid-row. */
int stuffed;
int i;
int j;
-
+
bitstream = 0;
ones = 0;
stuffed = 0;
static int process_rx_missing(t38_core_state_t *t, void *user_data, int rx_seq_no, int expected_seq_no)
{
t38_terminal_state_t *s;
-
+
s = (t38_terminal_state_t *) user_data;
s->t38_fe.rx_data_missing = TRUE;
return 0;
{
t38_terminal_state_t *s;
t38_terminal_front_end_state_t *fe;
-
+
s = (t38_terminal_state_t *) user_data;
fe = &s->t38_fe;
/* WORKAROUND: At least some Mediatrix boxes have a bug, where they can send this message at the
end of non-ECM data. We need to tolerate this. We use the generic receive complete
indication, rather than the specific HDLC carrier down. */
- /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END -
+ /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END -
i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops.
The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */
fe->hdlc_rx.len = 0;
static int t38_terminal_t38_fe_restart(t38_terminal_state_t *t)
{
t38_terminal_front_end_state_t *s;
-
+
s = &t->t38_fe;
t38_core_restart(&s->t38);
void *tx_packet_user_data)
{
t38_terminal_front_end_state_t *s;
-
+
s = &t->t38_fe;
t38_core_init(&s->t38,
process_rx_indicator,
case COMPRESSION_CCITT_T4:
TIFFSetField(t->tiff_file, TIFFTAG_T4OPTIONS, output_t4_options);
TIFFSetField(t->tiff_file, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
- TIFFSetField(t->tiff_file, TIFFTAG_ROWSPERSTRIP, -1L);
break;
case COMPRESSION_CCITT_T6:
TIFFSetField(t->tiff_file, TIFFTAG_T6OPTIONS, 0);
TIFFSetField(t->tiff_file, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
- TIFFSetField(t->tiff_file, TIFFTAG_ROWSPERSTRIP, -1L);
break;
case COMPRESSION_T85:
TIFFSetField(t->tiff_file, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
{
if (s->current_bit_plane >= s->bit_planes - 1)
return -1;
-
+
s->current_bit_plane++;
s->tx = 0;
memset(s->buffer, 0, sizeof(s->buffer));
buf[19] = s->options;
}
/*- End of function --------------------------------------------------------*/
-
+
SPAN_DECLARE(void) t85_encode_set_options(t85_encode_state_t *s,
uint32_t l0,
int mx,
s->current_bit_plane = 0;
t85_encode_restart(s, image_width, image_length);
-
+
return s;
}
/*- End of function --------------------------------------------------------*/
s->duration[3] = d4*SAMPLE_RATE/1000;
s->repeat = repeat;
-
+
return s;
}
/*- End of function --------------------------------------------------------*/
limit = samples + s->duration[s->current_section] - s->current_position;
if (limit > max_samples)
limit = max_samples;
-
+
s->current_position += (limit - samples);
if (s->current_section & 1)
{
}
}
else
- {
+ {
s->low_samples = 0;
if (diff > s->high_sample)
s->high_sample = diff;
s->baud_phase = 0.0f;
#endif
s->baud_half = 0;
-
+
s->total_baud_timing_correction = 0;
return 0;
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+
/*! \file */
#if defined(HAVE_CONFIG_H)
/*
Ways in which a V.18 call may start
-----------------------------------
-
+
Originate:
ANS
Silence for 0.5s then send TXP
{
v18_state_t *s;
int ch;
-
+
s = (v18_state_t *) user_data;
if ((ch = queue_read_byte(&s->queue.queue)) >= 0)
return ch;
{
v18_state_t *s;
uint8_t octet;
-
+
s = (v18_state_t *) user_data;
if (byte < 0)
{
Tune the local carrier, based on the angular mismatch between the actual signal and
the decision.
-
+
Tune the equalizer, based on the mismatch between the actual signal and the decision.
Descramble and output the bits represented by the decision.
for (i = 0; i < len; i++)
{
/* Complex bandpass filter the signal, using a pair of FIRs, and RRC coeffs shifted
- to centre at 1200Hz or 2400Hz. The filters support 12 fractional phase shifts, to
+ to centre at 1200Hz or 2400Hz. The filters support 12 fractional phase shifts, to
permit signal extraction very close to the middle of a symbol. */
s->rx.rrc_filter[s->rx.rrc_filter_step] = amp[i];
if (++s->rx.rrc_filter_step >= V22BIS_RX_FILTER_STEPS)
d) 765 +-10 ms after circuit 109 has been turned ON, circuit 106 shall be conditioned to respond
to circuit 105 and the modem shall be ready to transmit data at 1200 bit/s.
-
+
6.3.1.2.2 Answering modem
a) On connection to line the answering modem shall be conditioned to transmit signals in the high
}
out_bit = (bit ^ (s->tx.scramble_reg >> 13) ^ (s->tx.scramble_reg >> 16)) & 1;
s->tx.scramble_reg = (s->tx.scramble_reg << 1) | out_bit;
-
+
if (out_bit == 1)
s->tx.scrambler_pattern_count++;
else
SPAN_DECLARE(float) v27ter_rx_symbol_timing_correction(v27ter_rx_state_t *s)
{
int steps_per_symbol;
-
+
steps_per_symbol = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5 : RX_PULSESHAPER_2400_COEFF_SETS*20/3;
return (float) s->total_baud_timing_correction/(float) steps_per_symbol;
}
s->eq_buf[s->eq_step] = *sample;
if (++s->eq_step >= V27TER_EQUALIZER_LEN)
s->eq_step = 0;
-
+
/* On alternate insertions we have a whole baud, and must process it. */
if ((s->baud_half ^= 1))
return;
}
}
else
- {
+ {
s->low_samples = 0;
if (diff > s->high_sample)
s->high_sample = diff;
static __inline__ int get_scrambled_bit(v27ter_tx_state_t *s)
{
int bit;
-
+
if ((bit = s->current_get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA)
{
/* End of real data. Switch to the fake get_bit routine, until we
got us in the right ballpark. Now we need to fine tune fairly quickly,
to get the receovered carrier more precisely on target. Then we need to
fine tune in a more damped way to keep us on target. The goal is to have
- things running really well by the time the training is complete.
+ things running really well by the time the training is complete.
We assume the frequency of the oscillators at the two ends drift only
very slowly. The PSTN has rather limited doppler problems. :-) Any
remaining FDM in the network should also drift slowly. */
}
}
else
- {
+ {
s->low_samples = 0;
if (diff > s->high_sample)
s->high_sample = diff;
" movq (%%rsi),%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" movq %%mm3,%%mm4;\n"
" pand %%mm2,%%mm3;\n" /* mm3 is mm2 masked to new max's */
" pandn %%mm0,%%mm4;\n" /* mm4 is mm0 masked to its max's */
" por %%mm3,%%mm4;\n"
" movq %%mm4,%%mm0;\n" /* Now mm0 is updated max's */
-
+
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movq %%mm0,%%mm2;\n"
" psrlq $32,%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new max's */
" pandn %%mm0,%%mm3;\n" /* mm3 is mm0 masked to its max's */
" por %%mm3,%%mm2;\n"
" movq %%mm1,%%mm2;\n"
" psrlq $32,%%mm2;\n"
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movd (%%rsi),%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" movq %%mm3,%%mm4;\n"
" pand %%mm2,%%mm3;\n" /* mm3 is mm2 masked to new max's */
" pandn %%mm0,%%mm4;\n" /* mm4 is mm0 masked to its max's */
" movq %%mm4,%%mm0;\n" /* now mm0 is updated max's */
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movq %%mm0,%%mm2;\n"
" psrlq $16,%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new max's */
" pandn %%mm0,%%mm3;\n" /* mm3 is mm0 masked to its max's */
" por %%mm3,%%mm2;\n"
" movq %%mm1,%%mm2;\n"
" psrlq $16,%%mm2;\n"
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movd %%mm2,%%eax;\n" /* ax is min so far */
-
+
" addq $2,%%rdx;\n" /* now dx = top-2 */
" cmpq %%rdx,%%rsi;\n"
" ja 6f;\n"
" movq (%%esi),%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" movq %%mm3,%%mm4;\n"
" pand %%mm2,%%mm3;\n" /* mm3 is mm2 masked to new max's */
" pandn %%mm0,%%mm4;\n" /* mm4 is mm0 masked to its max's */
" por %%mm3,%%mm4;\n"
" movq %%mm4,%%mm0;\n" /* Now mm0 is updated max's */
-
+
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movq %%mm0,%%mm2;\n"
" psrlq $32,%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new max's */
" pandn %%mm0,%%mm3;\n" /* mm3 is mm0 masked to its max's */
" por %%mm3,%%mm2;\n"
" movq %%mm1,%%mm2;\n"
" psrlq $32,%%mm2;\n"
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movd (%%esi),%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" movq %%mm3,%%mm4;\n"
" pand %%mm2,%%mm3;\n" /* mm3 is mm2 masked to new max's */
" pandn %%mm0,%%mm4;\n" /* mm4 is mm0 masked to its max's */
" movq %%mm4,%%mm0;\n" /* now mm0 is updated max's */
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movq %%mm0,%%mm2;\n"
" psrlq $16,%%mm2;\n"
" movq %%mm2,%%mm3;\n"
- " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
+ " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new max's */
" pandn %%mm0,%%mm3;\n" /* mm3 is mm0 masked to its max's */
" por %%mm3,%%mm2;\n"
" movq %%mm1,%%mm2;\n"
" psrlq $16,%%mm2;\n"
" movq %%mm1,%%mm3;\n"
- " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
+ " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */
" pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */
" pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */
" por %%mm3,%%mm2;\n"
" movd %%mm2,%%eax;\n" /* ax is min so far */
-
+
" addl $2,%%edx;\n" /* now dx = top-2 */
" cmpl %%edx,%%esi;\n"
" ja 6f;\n"
int16_t max;
int16_t temp;
int32_t z;
-
+
max = INT16_MIN;
min = INT16_MAX;
for (i = 0; i < n; i++)
{
int i;
uint8_t alaw;
-
+
for (i = 0; i < len; i++)
{
alaw = linear_to_alaw (amp[i]);
RRB% = (N+ + N-)/10
Receiver Center Frequency Offset (RCFO) is calculated as follows:
RCFO% = X + (N+ - N-)/20
-
+
Note that this test doesn't test what it says it is testing at all,
and the results are quite inaccurate, if not a downright lie! However,
it follows the Mitel procedure, so how can it be bad? :)
-
+
The spec calls for +-1.5% +-10Hz of bandwidth.
*/
printf ("Test 3: Recognition bandwidth and channel centre frequency check\n");
printf(" Passed\n");
/* Test 5: Dynamic range
- This test sends all possible digits, with gradually increasing
+ This test sends all possible digits, with gradually increasing
amplitude. We determine the span over which we achieve reliable
detection. The spec says we should detect between -14dBm and 0dBm,
but the tones clip above -3dBm, so this cannot really work. */
-
+
printf("Test 5: Dynamic range\n");
for (nplus = nminus = -1000, i = -50; i <= 3; i++)
{
printf(" Passed\n");
/* Test 6: Guard time
- This test sends all possible digits, with a gradually reducing
+ This test sends all possible digits, with a gradually reducing
duration. The spec defines a narrow range of tone duration
times we can expect, so as long as we detect reliably at the
specified minimum we should be OK. However, the spec also says
printf("Test failed.\n");
exit(2);
}
-
+
tx_bert = bert_init(NULL, 0, BERT_PATTERN_7_TO_1, 300, 20);
rx_bert = bert_init(NULL, 0, BERT_PATTERN_7_TO_1, 300, 20);
for (i = 0; i < 511*2; i++)
// bert_put_bit(bert, bit);
bert_put_bit(bert, bit);
}
-
+
printf("Tests passed.\n");
return 0;
}
static __inline__ int top_bit_dumb(unsigned int data)
{
int i;
-
+
if (data == 0)
return -1;
for (i = 31; i >= 0; i--)
static __inline__ int bottom_bit_dumb(unsigned int data)
{
int i;
-
+
if (data == 0)
return -1;
for (i = 0; i < 32; i++)
{
int i;
int result;
-
+
result = 0;
for (i = 0; i < 8; i++)
{
- result = (result << 1) | (data & 1);
+ result = (result << 1) | (data & 1);
data >>= 1;
}
return result;
{
int i;
uint32_t result;
-
+
result = 0;
for (i = 0; i < 8; i++)
{
- result = (result << 1) | (data & 0x01010101);
+ result = (result << 1) | (data & 0x01010101);
data >>= 1;
}
return result;
{
int i;
uint16_t result;
-
+
result = 0;
for (i = 0; i < 16; i++)
{
- result = (result << 1) | (data & 1);
+ result = (result << 1) | (data & 1);
data >>= 1;
}
return result;
{
int i;
uint32_t result;
-
+
result = 0;
for (i = 0; i < 32; i++)
{
- result = (result << 1) | (data & 1);
+ result = (result << 1) | (data & 1);
data >>= 1;
}
return result;
{
int i;
int bits;
-
+
bits = 0;
for (i = 0; i < 32; i++)
{
return bits;
}
/*- End of function --------------------------------------------------------*/
-
+
int main(int argc, char *argv[])
{
int i;
}
bitstream_flush(s, &w);
printf("%d bits written\n", total_bits);
-
+
for (cc = buffer; cc < w; cc++)
printf("%02X ", *cc);
printf("\n");
printf("CRC module tests\n");
/* TODO: This doesn't check every function in the module */
-
+
/* Try a few random messages through the CRC logic. */
printf("Testing the CRC-16 routines\n");
for (i = 0; i < 100; i++)
}
}
printf("Test passed.\n\n");
-
+
printf("Testing the CRC-16 byte by byte and bit by bit routines\n");
for (i = 0; i < 100; i++)
{
}
}
printf("Test passed.\n\n");
-
+
printf("Testing the CRC-32 routines\n");
for (i = 0; i < 100; i++)
{
#endif
}
s->in_ptr = 0;
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
fftw_execute(s->p);
#else
fftw_one(s->p, s->in, s->out);
for (i = 0; i < 512; i++)
{
s->spec_re_plot[2*i] = i*4000.0/512.0;
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14;
#else
s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14;
s->w->end();
s->w->show();
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE);
for (i = 0; i < 1024; i++)
{
}
/*- End of function --------------------------------------------------------*/
-void echo_can_monitor_wait_to_end(void)
+void echo_can_monitor_wait_to_end(void)
{
fd_set rfds;
int res;
}
/*- End of function --------------------------------------------------------*/
-void echo_can_monitor_update_display(void)
+void echo_can_monitor_update_display(void)
{
Fl::check();
Fl::check();
int current_tx_type;
int wait_for_silence;
-
+
int tone_state;
int64_t tone_on_time;
}
/*- End of function --------------------------------------------------------*/
-void line_model_monitor_wait_to_end(void)
+void line_model_monitor_wait_to_end(void)
{
fd_set rfds;
int res;
}
/*- End of function --------------------------------------------------------*/
-void line_model_monitor_update_display(void)
+void line_model_monitor_update_display(void)
{
Fl::check();
Fl::check();
int i;
int j;
awgn_state_t noise1;
-
+
if ((model = one_way_line_model_init(line_model_no, -50, channel_codec, rbs_pattern)) == NULL)
{
fprintf(stderr, " Failed to create line model\n");
exit(2);
}
-
+
awgn_init_dbm0(&noise1, 1234567, -10.0f);
if (speech_test)
}
for (j = 0; j < samples; j++)
{
- one_way_line_model(model,
+ one_way_line_model(model,
&output1[j],
&input1[j],
1);
int j;
awgn_state_t noise1;
awgn_state_t noise2;
-
+
if ((model = both_ways_line_model_init(line_model_no,
-50,
-15.0f,
fprintf(stderr, " Failed to create line model\n");
exit(2);
}
-
+
awgn_init_dbm0(&noise1, 1234567, -10.0f);
awgn_init_dbm0(&noise2, 1234567, -10.0f);
}
for (j = 0; j < samples; j++)
{
- both_ways_line_model(model,
+ both_ways_line_model(model,
&output1[j],
&input1[j],
&output2[j],
if (++p == 129)
p = 0;
ptr = p;
-
+
/* Apply the filter */
out = 0.0f;
for (j = 0; j < 129; j++)
fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME);
exit(2);
}
-
+
if ((lpc10_enc_state = lpc10_encode_init(NULL, TRUE)) == NULL)
{
fprintf(stderr, " Cannot create encoder\n");
exit(2);
}
-
+
if ((lpc10_dec_state = lpc10_decode_init(NULL, TRUE)) == NULL)
{
fprintf(stderr, " Cannot create decoder\n");
exit(2);
}
}
-
+
if (sf_close_telephony(outhandle))
{
fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME);
}
s->received_delays = new Ca_Line(2000, s->received_delays_plot, 0, 0, FL_BLUE, CA_NO_POINT);
-
+
if (s->sent_re)
delete s->sent_re;
s->sent_re_plot[2*(i%500) + 1] = 0.0;
}
s->sent_re_plot[2*(seq_no%500) + 1] = fdiff;
-
+
if (fdiff > s->sent_re_plot_max)
{
s->sent_re_plot_max = fdiff;
float y;
int i;
int len;
-
+
len = 128;
s->w = new Fl_Double_Window(465, 400, "IP streaming media monitor");
s->received_delays_plot_max = 0.0;
s->min_diff = 2000;
s->max_diff = 0;
-
+
s->received_delays = NULL;
s->highest_seq_no_seen = -1;
}
/*- End of function --------------------------------------------------------*/
-void media_monitor_wait_to_end(void)
+void media_monitor_wait_to_end(void)
{
fd_set rfds;
int res;
}
/*- End of function --------------------------------------------------------*/
-void media_monitor_update_display(void)
+void media_monitor_update_display(void)
{
Fl::check();
Fl::check();
Fl_Group *c_right;
Fl_Group *c_eq;
Fl_Group *c_symbol_track;
-
+
/* Constellation stuff */
Ca_Canvas *canvas_const;
Ca_X_Axis *sig_i;
if (max < coeffs[i].im)
max = coeffs[i].im;
}
-
+
s->eq_x->minimum(-len/4.0);
s->eq_x->maximum(len/4.0);
s->eq_y->maximum((max == min) ? max + 0.2 : max);
int i;
char buf[11];
double val;
-
+
for (i = 0; i < len; i++)
{
s->audio_meter->sample(amp[i]/32768.0);
float x;
float y;
qam_monitor_t *s;
-
+
if ((s = (qam_monitor_t *) malloc(sizeof(*s))) == NULL)
return NULL;
-
+
s->w = new Fl_Double_Window(905, 400, (tag) ? tag : "QAM monitor");
s->constel_scaling = 1.0/constel_scaling;
}
/*- End of function --------------------------------------------------------*/
-void qam_wait_to_end(qam_monitor_t *s)
+void qam_wait_to_end(qam_monitor_t *s)
{
fd_set rfds;
int res;
/*
* SpanDSP - a series of DSP components for telephony
*
- * t31_pseudo_terminal_tests.c -
+ * t31_pseudo_terminal_tests.c -
*
* Written by Steve Underwood <steveu@coppice.org>
*
{
int i;
char tag[20];
-
+
i = (intptr_t) user_data;
snprintf(tag, sizeof(tag), "%c: Phase E", i);
printf("Phase E handler on channel %c\n", i);
{
if (GetLastError() != ERROR_IO_PENDING)
{
- /* Something went horribly wrong with WaitCommEvent(), so
+ /* Something went horribly wrong with WaitCommEvent(), so
clear all errors and try again */
ClearCommError(modem->master, &comerrors, 0);
}
#endif
/* Test the T.31 modem against the full FAX machine in spandsp */
-
+
/* Set up the test environment */
t38_version = 1;
without_pacing = FALSE;
while (!done)
{
- /* Deal with call setup, through the AT interface. */
+ /* Deal with call setup, through the AT interface. */
if (test_sending)
{
}
{
int i;
char tag[20];
-
+
i = (intptr_t) user_data;
snprintf(tag, sizeof(tag), "%c: Phase E", i);
printf("Phase E handler on channel %c\n", i);
SNDFILE *in_handle;
/* Test the T.31 modem against the full FAX machine in spandsp */
-
+
/* Set up the test environment */
t38_version = 1;
without_pacing = FALSE;
{
if (countdown)
{
- /* Deal with call setup, through the AT interface. */
+ /* Deal with call setup, through the AT interface. */
if (answered)
{
countdown = 0;
static int tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
{
t38_core_state_t *t;
-
+
t = (t38_core_state_t *) user_data;
span_log(t38_core_get_logging_state(s), SPAN_LOG_FLOW, "Send seq %d, len %d, count %d\n", s->tx_seq_no, len, count);
if (t38_core_rx_ifp_packet(t, buf, len, seq_no) < 0)
t38_data_field_t field[MAX_FIELDS];
int i;
int j;
-
+
ok_indicator_packets = 0;
bad_indicator_packets = 0;
ok_data_packets = 0;
int len;
int i;
int j;
-
+
ok_indicator_packets = 0;
bad_indicator_packets = 0;
ok_data_packets = 0;
}
if (t38_gateway_rx(t38_gateway_state, t30_amp, t30_len))
break;
-
+
t38_len = t38_gateway_tx(t38_gateway_state, t38_amp, partial);
if (!use_transmit_on_idle)
{
uint32_t b;
uint32_t c;
uint32_t d;
-
+
a = 0;
b = 0;
c = 0;
}
}
printf(" Initial ones from an empty TCF buffer OK\n");
-
+
/* Now send some initial ones, and see that we continue to get all ones
as the stuffing. */
memset(buf, 0xFF, 500);
#if defined(SPANDSP_SUPPORT_T42x)
T4_COMPRESSION_ITU_T42,
T4_COMPRESSION_ITU_SYCC_T42,
-#endif
+#endif
#if defined(SPANDSP_SUPPORT_T43x)
T4_COMPRESSION_ITU_T43,
-#endif
+#endif
T4_COMPRESSION_ITU_T85,
T4_COMPRESSION_ITU_T85_L0,
//T4_COMPRESSION_ITU_T45,
int i;
int status;
const char *u;
-
+
i = (intptr_t) user_data;
status = T30_ERR_OK;
if ((u = t30_get_rx_ident(s)))
{
int i;
char tag[20];
-
+
i = (intptr_t) user_data;
snprintf(tag, sizeof(tag), "%c: Phase E", i);
- printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
+ printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
fax_log_final_transfer_statistics(s, tag);
fax_log_tx_parameters(s, tag);
fax_log_rx_parameters(s, tag);
static int document_handler(t30_state_t *s, void *user_data, int event)
{
int i;
-
+
i = (intptr_t) user_data;
fprintf(stderr, "%d: Document handler on channel %d - event %d\n", i, i, event);
if (next_tx_file[0])
static void string_test2(const uint8_t msg[], int len)
{
int i;
-
+
if (len > 0)
{
for (i = 0; i < len - 1; i++)
uint8_t mask[1000];
int len;
int i;
-
+
len = string_to_msg(msg, mask, buf);
printf("Len = %d: ", len);
string_test2(msg, abs(len));
s->cur = s->cur->next;
span_log(&s->logging,
- SPAN_LOG_FLOW,
+ SPAN_LOG_FLOW,
"Dir - %s, type - %s, modem - %s, value - %s, timeout - %s, tag - %s\n",
(dir) ? (const char *) dir : "",
(type) ? (const char *) type : "",
span_log_bump_samples(logging, len);
span_log_bump_samples(&s->logging, len);
-
+
len = faxtester_tx(s, amp, SAMPLES_PER_CHUNK);
if (fax_rx(fax, amp, len))
break;
xmlNodePtr cur;
xmlValidCtxt valid;
- ns = NULL;
+ ns = NULL;
xmlKeepBlanksDefault(0);
xmlCleanupParser();
if ((doc = xmlParseFile(test_file)) == NULL)
msg[i] = i + 1;
msg[127] = '\0';
printf("%s\n", msg);
-
+
v18_encode_dtmf(NULL, dtmf, msg);
printf("%s\n", dtmf);
static void put_v18_msg(void *user_data, const uint8_t *msg, int len)
{
char buf[1024];
-
+
memcpy(buf, msg, len);
buf[len] = '\0';
printf("Received (%d bytes) '%s'\n", len, buf);
static void reporter(void *user_data, int reason, bert_results_t *results)
{
endpoint_t *s;
-
+
s = (endpoint_t *) user_data;
switch (reason)
{
memcpy(&s->latest_results, results, sizeof(s->latest_results));
break;
default:
- fprintf(stderr,
+ fprintf(stderr,
"V.22bis rx %p BERT report %s\n",
user_data,
bert_event_to_str(reason));
int rbs_pattern;
int guard_tone_option;
int opt;
-
+
channel_codec = MUNGE_CODEC_NONE;
rbs_pattern = 0;
test_bps = 2400;
bert_set_report(&endpoint[i].bert_rx, 10000, reporter, &endpoint[i]);
}
-
+
#if defined(ENABLE_GUI)
if (use_gui)
{
}
#if 1
- both_ways_line_model(model,
+ both_ways_line_model(model,
model_amp[0],
amp[0],
model_amp[1],
int rbs_pattern;
int opt;
logging_state_t *logging;
-
+
channel_codec = MUNGE_CODEC_NONE;
rbs_pattern = 0;
test_bps = 9600;
fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
one_way_line_model_release(line_model);
-
+
if (signal_level > -43)
{
printf("Tests failed.\n");
static void frame_handler(void *user_data, const uint8_t *buf, int len)
{
int ret;
-
+
if ((ret = write((intptr_t) user_data, buf, len)) != len)
fprintf(stderr, "Write error %d/%d\n", ret, errno);
out_octets_to_date += len;
fprintf(stderr, "Error opening file '%s'.\n", decompressed_file);
exit(2);
}
-
+
time(&now);
state_b = v42bis_init(NULL, 3, 512, 6, frame_handler, (void *) (intptr_t) v42bis_fd, 512, data_handler, (void *) (intptr_t) out_fd, 512);
span_log_set_level(v42bis_get_logging_state(state_b), SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
static void handler(void *user_data, v8_parms_t *result)
{
const char *s;
-
+
s = (const char *) user_data;
printf("%s ", s);
for (i = 0; i < samples; i++)
out_amp[2*i] = amp[i];
/*endfor*/
-
+
samples = v8_tx(v8_answerer, amp, SAMPLES_PER_CHUNK);
if (samples < SAMPLES_PER_CHUNK)
{
for (i = 0; i < samples; i++)
out_amp[2*i] = amp[i];
/*endfor*/
-
+
samples = modem_connect_tones_tx(non_v8_answerer_tx, amp, SAMPLES_PER_CHUNK);
if (samples < SAMPLES_PER_CHUNK)
{
static void vec_copyf_dumb(float z[], const float x[], int n)
{
int i;
-
+
for (i = 0; i < n; i++)
z[i] = x[i];
}
static void vec_negatef_dumb(float z[], const float x[], int n)
{
int i;
-
+
for (i = 0; i < n; i++)
z[i] = -x[i];
}
static void vec_zerof_dumb(float z[], int n)
{
int i;
-
+
for (i = 0; i < n; i++)
z[i] = 0.0f;
}
static void vec_setf_dumb(float z[], float x, int n)
{
int i;
-
+
for (i = 0; i < n; i++)
z[i] = x;
}
int16_t max;
int16_t temp;
int32_t z;
-
+
max = INT16_MIN;
min = INT16_MAX;
for (i = 0; i < n; i++)
return max;
}
/*- End of function --------------------------------------------------------*/
-
+
static int test_vec_min_maxi16(void)
{
int i;