提交 9732d325 authored 作者: Steve Underwood's avatar Steve Underwood

spandsp DSP tweaks to avoid problems with the LPC10 code compiled with the…

spandsp DSP tweaks to avoid problems with the LPC10 code compiled with the latest GCC 6.2 series compilers. Various other additional tweaks to spandsp.
上级 62fe767e
......@@ -37,7 +37,7 @@ m4_include(m4/ax_c99_features.m4)
m4_include(m4/ax_check_export_capability.m4)
m4_include(m4/ax_check_arm_neon.m4)
m4_include(m4/ax_func_aligned_alloc.m4)
m4_include(m4/memmove.m4)
m4_include(m4/ac_func_memmove.m4)
AC_CONFIG_SRCDIR([src/tone_generate.c])
AC_CONFIG_AUX_DIR([config])
......
......@@ -5594,6 +5594,15 @@ SPAN_DECLARE(void) at_set_modem_control_handler(at_state_t *s,
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) at_set_at_tx_handler(at_state_t *s,
at_tx_handler_t at_tx_handler,
void *at_tx_user_data)
{
s->at_tx_handler = at_tx_handler;
s->at_tx_user_data = at_tx_user_data;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(logging_state_t *) at_get_logging_state(at_state_t *s)
{
return &s->logging;
......
......@@ -52,6 +52,11 @@
#if defined(HAVE_MATH_H)
#include <math.h>
#endif
#if defined(HAVE_STDBOOL_H)
#include <stdbool.h>
#else
#include "spandsp/stdbool.h"
#endif
#include "floating_fudge.h"
#include "spandsp/telephony.h"
......@@ -62,67 +67,76 @@
#include "spandsp/private/awgn.h"
/* Gaussian noise generator constants */
/* Random number generator constants */
#define M1 259200
#define IA1 7141
#define IC1 54773
#define RM1 (1.0/M1)
#define RM1 (1.0/(double) M1)
#define M2 134456
#define IA2 8121
#define IC2 28411
#define RM2 (1.0/M2)
#define RM2 (1.0/(double) M2)
#define M3 243000
#define IA3 4561
#define IC3 51349
static double ran1(awgn_state_t *s)
static void ran_init(awgn_state_t *s, int idum)
{
int j;
if (idum < 0)
idum = -idum;
s->ix1 = (IC1 + (int32_t) idum)%M1;
s->ix1 = (IA1*s->ix1 + IC1)%M1;
s->ix2 = s->ix1%M2;
s->ix1 = (IA1*s->ix1 + IC1)%M1;
s->ix3 = s->ix1%M3;
for (j = 0; j < 97; j++)
{
s->ix1 = (IA1*s->ix1 + IC1)%M1;
s->ix2 = (IA2*s->ix2 + IC2)%M2;
s->r[j] = (s->ix1 + s->ix2*RM2)*RM1;
}
}
/*- End of function --------------------------------------------------------*/
static double ran(awgn_state_t *s)
{
double temp;
int j;
/* This produces evenly spread random numbers between 0.0 and 1.0 */
s->ix1 = (IA1*s->ix1 + IC1)%M1;
s->ix2 = (IA2*s->ix2 + IC2)%M2;
s->ix3 = (IA3*s->ix3 + IC3)%M3;
j = 1 + ((97*s->ix3)/M3);
if (j > 97 || j < 1)
j = (97*s->ix3)/M3;
if (j > 96 || j < 0)
{
/* Error */
return -1;
temp = -1.0;
}
else
{
temp = s->r[j];
s->r[j] = (s->ix1 + s->ix2*RM2)*RM1;
}
temp = s->r[j];
s->r[j] = (s->ix1 + s->ix2*RM2)*RM1;
return temp;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(awgn_state_t *) awgn_init_dbov(awgn_state_t *s, int idum, float level)
{
int j;
if (s == NULL)
{
if ((s = (awgn_state_t *) span_alloc(sizeof(*s))) == NULL)
return NULL;
}
if (idum < 0)
idum = -idum;
s->rms = pow(10.0, level/20.0)*32768.0;
ran_init(s, idum);
s->ix1 = (IC1 + idum)%M1;
s->ix1 = (IA1*s->ix1 + IC1)%M1;
s->ix2 = s->ix1%M2;
s->ix1 = (IA1*s->ix1 + IC1)%M1;
s->ix3 = s->ix1%M3;
s->r[0] = 0.0;
for (j = 1; j <= 97; j++)
{
s->ix1 = (IA1*s->ix1 + IC1)%M1;
s->ix2 = (IA2*s->ix2 + IC2)%M2;
s->r[j] = (s->ix1 + s->ix2*RM2)*RM1;
}
s->gset = 0.0;
s->iset = 0;
s->rms = pow(10.0, level/20.0)*32768.0;
s->amp2 = 0.0;
s->odd = true;
return s;
}
/*- End of function --------------------------------------------------------*/
......@@ -148,31 +162,30 @@ SPAN_DECLARE(int) awgn_free(awgn_state_t *s)
SPAN_DECLARE(int16_t) awgn(awgn_state_t *s)
{
double fac;
double r;
double v1;
double v2;
double amp;
if (s->iset == 0)
/* The polar method of generating a Gaussian distribution */
if ((s->odd = !s->odd))
{
amp = s->amp2;
}
else
{
do
{
v1 = 2.0*ran1(s) - 1.0;
v2 = 2.0*ran1(s) - 1.0;
v1 = 2.0*ran(s) - 1.0;
v2 = 2.0*ran(s) - 1.0;
r = v1*v1 + v2*v2;
}
while (r >= 1.0);
fac = sqrt(-2.0*log(r)/r);
s->gset = v1*fac;
s->iset = 1;
amp = v2*fac*s->rms;
}
else
{
s->iset = 0;
amp = s->gset*s->rms;
r = sqrt(-2.0*log(r)/r);
s->amp2 = v1*r;
amp = v2*r;
}
amp *= s->rms;
return fsaturate(amp);
}
/*- End of function --------------------------------------------------------*/
......
......@@ -89,6 +89,7 @@ static __inline__ void octet_set_and_count(hdlc_rx_state_t *s)
{
if (s->octet_count_report_interval == 0)
return;
/*endif*/
/* If we are not in octet counting mode, we start it.
If we are in octet counting mode, we update it. */
......@@ -625,6 +626,7 @@ SPAN_DECLARE(int) hdlc_tx_get_byte(hdlc_tx_state_t *s)
/* An input byte will generate between 8 and 10 output bits */
return (s->octets_in_progress >> s->num_bits) & 0xFF;
}
/*endif*/
/* Untimed idling on flags */
if (s->tx_end)
{
......@@ -644,8 +646,10 @@ SPAN_DECLARE(int) hdlc_tx_get_bit(hdlc_tx_state_t *s)
{
if ((s->byte = hdlc_tx_get_byte(s)) < 0)
return s->byte;
/*endif*/
s->bits = 8;
}
/*endif*/
s->bits--;
txbit = (s->byte >> s->bits) & 0x01;
return txbit;
......@@ -661,8 +665,10 @@ SPAN_DECLARE(int) hdlc_tx_get(hdlc_tx_state_t *s, uint8_t buf[], size_t max_len)
{
if ((x = hdlc_tx_get_byte(s)) == SIG_STATUS_END_OF_DATA)
return i;
/*endif*/
buf[i] = (uint8_t) x;
}
/*endfor*/
return (int) i;
}
/*- End of function --------------------------------------------------------*/
......
......@@ -532,7 +532,7 @@ static int floyd_steinberg_dither_row(image_translate_state_t *s, uint8_t buf[])
s->output_row = -1;
}
}
/* Apply Floyd-Steinberg dithering to the 8 bit pixels, using a bustrophodontic
/* Apply Floyd-Steinberg dithering to the 8 bit pixels, using a bustrophedontic
scan, to reduce the grayscale image to pure black and white */
/* The first and last pixels in each row need special treatment, so we do not
step outside the row. */
......
......@@ -564,7 +564,7 @@ void lpc10_analyse(lpc10_encode_state_t *s, float speech[], int32_t voice[], int
static const float precoef = 0.9375f;
float amdf[60];
float abuf[156];
float abuf[LPC10_MIN_PITCH];
float ivrc[2];
float temp;
float phi[100] /* was [10][10] */;
......@@ -634,7 +634,7 @@ void lpc10_analyse(lpc10_encode_state_t *s, float speech[], int32_t voice[], int
s->zpre = preemp(&s->inbuf[i - 181], &s->pebuf[i - 181], LPC10_SAMPLES_PER_FRAME, precoef, s->zpre);
onset(s, s->pebuf, s->osbuf, &s->osptr, 10, 181, 720, LPC10_SAMPLES_PER_FRAME);
lpc10_placev(s->osbuf, &s->osptr, 10, &s->obound[2], s->vwin, 3, LPC10_SAMPLES_PER_FRAME, 90, 156, 307, 462);
lpc10_placev(s->osbuf, &s->osptr, 10, &s->obound[2], s->vwin, 3, LPC10_SAMPLES_PER_FRAME, 90, LPC10_MIN_PITCH, 307, 462);
/* The Pitch Extraction algorithm estimates the pitch for a frame
of speech by locating the minimum of the average magnitude difference
function (AMDF). The AMDF operates on low-pass, inverse filtered
......@@ -655,7 +655,7 @@ void lpc10_analyse(lpc10_encode_state_t *s, float speech[], int32_t voice[], int
/* eval_highres_amdf reads indices PWINL = 229 through
(PWINL-1)+MAXWIN+(TAU(LTAU)-TAU(1))/2 = 452 of IVBUF, and writes
indices 1 through LTAU = 60 of AMDF. */
eval_highres_amdf(s->ivbuf, 156, tau, 60, amdf, &minptr, &maxptr, &mintau);
eval_highres_amdf(s->ivbuf, LPC10_MIN_PITCH, tau, 60, amdf, &minptr, &maxptr, &mintau);
/* Voicing decisions are made for each half frame of input speech.
An initial voicing classification is made for each half of the
analysis frame, and the voicing decisions for the present frame
......@@ -688,7 +688,7 @@ void lpc10_analyse(lpc10_encode_state_t *s, float speech[], int32_t voice[], int
dynamic_pitch_tracking(s, amdf, 60, &minptr, s->voibuf[3][1], pitch, &midx);
ipitch = tau[midx - 1];
/* Place spectrum analysis and energy windows */
lpc10_placea(&ipitch, s->voibuf, &s->obound[2], 3, s->vwin, s->awin, ewin, LPC10_SAMPLES_PER_FRAME, 156);
lpc10_placea(&ipitch, s->voibuf, &s->obound[2], 3, s->vwin, s->awin, ewin, LPC10_SAMPLES_PER_FRAME, LPC10_MIN_PITCH);
/* Remove short term DC bias over the analysis window. */
lanal = s->awin[2][1] + 1 - s->awin[2][0];
remove_dc_bias(&s->pebuf[s->awin[2][0] - 181], lanal, abuf);
......
......@@ -54,7 +54,7 @@
#include "spandsp/lpc10.h"
#include "spandsp/private/lpc10.h"
#define LPC10_ORDER 10
#include "lpc10_encdecs.h"
#if !defined(min)
#define min(a,b) ((a) <= (b) ? (a) : (b))
......@@ -81,32 +81,6 @@ static int32_t lpc10_random(lpc10_decode_state_t *s)
}
/*- End of function --------------------------------------------------------*/
static __inline__ int32_t pow_ii(int32_t x, int32_t n)
{
int32_t pow;
uint32_t u;
if (n <= 0)
{
if (n == 0 || x == 1)
return 1;
if (x != -1)
return (x != 0) ? 1/x : 0;
n = -n;
}
u = n;
for (pow = 1; ; )
{
if ((u & 1))
pow *= x;
if ((u >>= 1) == 0)
break;
x *= x;
}
return pow;
}
/*- End of function --------------------------------------------------------*/
/* Synthesize one pitch epoch */
static void bsynz(lpc10_decode_state_t *s,
float coef[],
......@@ -127,7 +101,7 @@ static void bsynz(lpc10_decode_state_t *s,
int32_t j;
int32_t k;
int32_t px;
float noise[166];
float noise[LPC10_MIN_PITCH];
float pulse;
float r1;
float gain;
......@@ -177,14 +151,13 @@ static void bsynz(lpc10_decode_state_t *s,
}
for (i = 0; i < ip; i++)
{
noise[LPC10_ORDER + i] = lpc10_random(s)/64.0f;
hpi0 = noise[LPC10_ORDER + i];
noise[LPC10_ORDER + i] = noise[LPC10_ORDER + i]*-0.125f + s->hpi[0]*0.25f + s->hpi[1]*-0.125f;
hpi0 = lpc10_random(s)/64.0f;
noise[i] = hpi0*-0.125f + s->hpi[0]*0.25f + s->hpi[1]*-0.125f;
s->hpi[1] = s->hpi[0];
s->hpi[0] = hpi0;
}
for (i = 0; i < ip; i++)
s->exc[LPC10_ORDER + i] += noise[LPC10_ORDER + i];
s->exc[LPC10_ORDER + i] += noise[i];
}
/* Synthesis filters: */
/* Modify the excitation with all-zero filter 1 + G*SUM */
......@@ -224,20 +197,17 @@ static void bsynz(lpc10_decode_state_t *s,
/* Synthesize a single pitch epoch */
static int pitsyn(lpc10_decode_state_t *s,
int voice[],
int voice[2],
int32_t *pitch,
float *rms,
float *rc,
int32_t ivuv[],
int32_t ipiti[],
float *rmsi,
float *rci,
float rms,
float rc[LPC10_ORDER],
int32_t ivuv[16],
int32_t ipiti[16],
float rmsi[16],
float rci[16*LPC10_ORDER],
int32_t *nout,
float *ratio)
{
int32_t rci_dim1;
int32_t rci_offset;
int32_t i1;
int32_t i;
int32_t j;
int32_t vflag;
......@@ -257,16 +227,12 @@ static int pitsyn(lpc10_decode_state_t *s,
float xxy;
float msix;
rci_dim1 = LPC10_ORDER;
rci_offset = rci_dim1 + 1;
rci -= rci_offset;
if (*rms < 1.0f)
*rms = 1.0f;
if (rms < 1.0f)
rms = 1.0f;
if (s->rmso < 1.0f)
s->rmso = 1.0f;
uvpit = 0.0f;
*ratio = *rms/(s->rmso + 8.0f);
*ratio = rms/(s->rmso + 8.0f);
if (s->first_pitsyn)
{
ivoice = voice[1];
......@@ -275,14 +241,13 @@ static int pitsyn(lpc10_decode_state_t *s,
*nout = LPC10_SAMPLES_PER_FRAME / *pitch;
s->jsamp = LPC10_SAMPLES_PER_FRAME - *nout * *pitch;
i1 = *nout;
for (i = 0; i < i1; i++)
for (i = 0; i < *nout; i++)
{
for (j = 0; j < LPC10_ORDER; j++)
rci[j + (i + 1)*rci_dim1 + 1] = rc[j];
rci[j + i*LPC10_ORDER] = rc[j];
ivuv[i] = ivoice;
ipiti[i] = *pitch;
rmsi[i] = *rms;
rmsi[i] = rms;
}
s->first_pitsyn = false;
}
......@@ -301,7 +266,7 @@ static int pitsyn(lpc10_decode_state_t *s,
*pitch = LPC10_SAMPLES_PER_FRAME/4;
s->ipito = *pitch;
if (*ratio > 8.0f)
s->rmso = *rms;
s->rmso = rms;
}
/* SSVC - - 1 , 1 , 1 */
slope = (*pitch - s->ipito)/(float) lsamp;
......@@ -329,8 +294,8 @@ static int pitsyn(lpc10_decode_state_t *s,
rmsi[1] = s->rmso;
for (i = 0; i < LPC10_ORDER; i++)
{
rci[i + rci_dim1 + 1] = s->rco[i];
rci[i + (rci_dim1 << 1) + 1] = s->rco[i];
rci[i] = s->rco[i];
rci[i + LPC10_ORDER] = s->rco[i];
s->rco[i] = rc[i];
}
*nout = 2;
......@@ -434,10 +399,9 @@ static int pitsyn(lpc10_decode_state_t *s,
ip = (int32_t) uvpit;
if (ip <= i - jused)
{
++(*nout);
ipiti[*nout - 1] = ip;
ipiti[*nout] = ip;
*pitch = ip;
ivuv[*nout - 1] = ivoice;
ivuv[*nout] = ivoice;
jused += ip;
prop = (jused - ip/2)/(float) lsamp;
for (j = 0; j < LPC10_ORDER; j++)
......@@ -446,12 +410,13 @@ static int pitsyn(lpc10_decode_state_t *s,
alrn = logf((rc[j] + 1)/(1 - rc[j]));
xxy = alro + prop*(alrn - alro);
xxy = expf(xxy);
rci[j + *nout*rci_dim1 + 1] = (xxy - 1.0f)/(xxy + 1.0f);
rci[j + *nout*LPC10_ORDER] = (xxy - 1.0f)/(xxy + 1.0f);
}
msix = logf(*rms) - logf(s->rmso);
msix = logf(rms) - logf(s->rmso);
msix = prop*msix;
msix = logf(s->rmso) + msix;
rmsi[*nout - 1] = expf(msix);
rmsi[*nout] = expf(msix);
(*nout)++;
}
}
if (vflag != 1)
......@@ -465,7 +430,7 @@ static int pitsyn(lpc10_decode_state_t *s,
uvpit = (float) ((lsamp - istart)/2);
if (uvpit > 90.0f)
uvpit /= 2;
s->rmso = *rms;
s->rmso = rms;
for (i = 0; i < LPC10_ORDER; i++)
{
rc[i] = yarc[i];
......@@ -478,7 +443,7 @@ static int pitsyn(lpc10_decode_state_t *s,
{
s->ivoico = voice[1];
s->ipito = *pitch;
s->rmso = *rms;
s->rmso = rms;
for (i = 0; i < LPC10_ORDER; i++)
s->rco[i] = rc[i];
}
......@@ -532,13 +497,12 @@ static float reflection_coeffs_to_predictor_coeffs(float rc[], float pc[], float
/*- End of function --------------------------------------------------------*/
static int synths(lpc10_decode_state_t *s,
int voice[],
int voice[2],
int32_t *pitch,
float *rms,
float *rc,
float rms,
float rc[LPC10_ORDER],
float speech[])
{
int32_t i1;
int32_t ivuv[16];
int32_t ipiti[16];
int32_t nout;
......@@ -547,11 +511,10 @@ static int synths(lpc10_decode_state_t *s,
float rmsi[16];
float ratio;
float g2pass;
float pc[10];
float rci[160];
float pc[LPC10_ORDER];
float rci[16*LPC10_ORDER];
i1 = min(*pitch, 156);
*pitch = max(i1, 20);
*pitch = max(min(*pitch, LPC10_MIN_PITCH), LPC10_MAX_PITCH);
for (i = 0; i < LPC10_ORDER; i++)
rc[i] = max(min(rc[i], 0.99f), -0.99f);
pitsyn(s, voice, pitch, rms, rc, ivuv, ipiti, rmsi, rci, &nout, &ratio);
......@@ -560,14 +523,13 @@ static int synths(lpc10_decode_state_t *s,
for (j = 0; j < nout; j++)
{
/* Add synthesized speech for pitch period J to the end of s->buf. */
g2pass = reflection_coeffs_to_predictor_coeffs(&rci[j*10], pc, 0.7f);
g2pass = reflection_coeffs_to_predictor_coeffs(&rci[j*LPC10_ORDER], pc, 0.7f);
bsynz(s, pc, ipiti[j], &ivuv[j], &s->buf[s->buflen], rmsi[j], ratio, g2pass);
deemp(s, &s->buf[s->buflen], ipiti[j]);
s->buflen += ipiti[j];
}
/* Copy first MAXFRM samples from BUF to output array speech (scaling them),
and then remove them from the beginning of s->buf. */
for (i = 0; i < LPC10_SAMPLES_PER_FRAME; i++)
speech[i] = s->buf[i]/4096.0f;
s->buflen -= LPC10_SAMPLES_PER_FRAME;
......@@ -709,7 +671,7 @@ static int32_t median(int32_t d1, int32_t d2, int32_t d3)
static void decode(lpc10_decode_state_t *s,
lpc10_frame_t *t,
int voice[],
int voice[2],
int32_t *pitch,
float *rms,
float rc[])
......@@ -1110,7 +1072,7 @@ SPAN_DECLARE(int) lpc10_decode(lpc10_decode_state_t *s, int16_t amp[], const uin
{
lpc10_unpack(&frame, &code[i*7]);
decode(s, &frame, voice, &pitch, &rms, rc);
synths(s, voice, &pitch, &rms, rc, speech);
synths(s, voice, &pitch, rms, rc, speech);
base = i*LPC10_SAMPLES_PER_FRAME;
for (j = 0; j < LPC10_SAMPLES_PER_FRAME; j++)
amp[base + j] = (int16_t) lfastrintf(32768.0f*speech[j]);
......
......@@ -23,7 +23,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define LPC10_ORDER 10
#define LPC10_ORDER 10
#define LPC10_MAX_PITCH 20
#define LPC10_MIN_PITCH 156
#if !defined(min)
#define min(a,b) ((a) <= (b) ? (a) : (b))
......
......@@ -353,10 +353,6 @@ void lpc10_voicing(lpc10_encode_state_t *s,
/* Voicing decision for current half-frame: 1 = Voiced; 0 = Unvoiced */
s->voibuf[3][half] = (s->voice[2][half] > 0.0f) ? 1 : 0;
/* Skip voicing decision smoothing in first half-frame: */
/* Give a value to VSTATE, so that trace statements below will print */
/* a consistent value from one call to the next when HALF .EQ. 1. */
/* The value of VSTATE is not used for any other purpose when this is */
/* true. */
if (half != 0)
{
/* Voicing decision smoothing rules (override of linear combination): */
......
......@@ -646,7 +646,7 @@ int main(int argc, char *argv[])
exit(2);
/*endif*/
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS");
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS\n");
printf(" FILE MAY BE OVERWRITTEN DURING FUTURE BUILDS OF THE SOFTWARE */\n");
printf("\n");
......@@ -661,7 +661,7 @@ int main(int argc, char *argv[])
trie_recursive_build_packed_trie(s->root);
dump_trie();
trie_free(s);
return 0;
......
......@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
uint8_t srgb;
int i;
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS");
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS\n");
printf(" FILE MAY BE OVERWRITTEN DURING FUTURE BUILDS OF THE SOFTWARE */\n");
printf("\n");
......
......@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
double val;
int ival;
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS");
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS\n");
printf(" FILE MAY BE OVERWRITTEN DURING FUTURE BUILDS OF THE SOFTWARE */\n");
printf("\n");
......
......@@ -32,11 +32,7 @@
#include <time.h>
#include <fcntl.h>
#include <math.h>
#if defined(HAVE_STDBOOL_H)
#include <stdbool.h>
#else
#include "spandsp/stdbool.h"
#endif
#if defined(__sunos) || defined(__solaris) || defined(__sun)
#include <getopt.h>
#endif
......@@ -103,7 +99,7 @@ static void make_tx_filter(int coeff_sets,
/* Churn out the data as a C source code header file, which can be directly included by the
modem code. */
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS");
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS\n");
printf(" FILE MAY BE OVERWRITTEN DURING FUTURE BUILDS OF THE SOFTWARE */\n");
printf("\n");
printf("#if defined(SPANDSP_USE_FIXED_POINT)\n");
......
......@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
int new_gray;
int restore;
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS");
printf("/* THIS FILE WAS AUTOMATICALLY GENERATED - ANY MODIFICATIONS MADE TO THIS\n");
printf(" FILE MAY BE OVERWRITTEN DURING FUTURE BUILDS OF THE SOFTWARE */\n");
printf("\n");
......
......@@ -177,6 +177,10 @@ SPAN_DECLARE(void) at_set_modem_control_handler(at_state_t *s,
at_modem_control_handler_t modem_control_handler,
void *modem_control_user_data);
SPAN_DECLARE(void) at_set_at_tx_handler(at_state_t *s,
at_tx_handler_t at_tx_handler,
void *at_tx_user_data);
/*! Initialise an AT interpreter context.
\brief Initialise an AT interpreter context.
\param s The AT context.
......
......@@ -50,6 +50,8 @@ enum
*/
typedef struct data_modems_state_s data_modems_state_t;
typedef int (*data_modems_control_handler_t)(data_modems_state_t *s, void *user_data, int op, const char *num);
#if defined(__cplusplus)
extern "C"
{
......@@ -62,6 +64,8 @@ SPAN_DECLARE(void) data_modems_set_tep_mode(data_modems_state_t *s, int use_tep)
SPAN_DECLARE(logging_state_t *) data_modems_get_logging_state(data_modems_state_t *s);
SPAN_DECLARE(void) data_modems_call_event(data_modems_state_t *s, int event);
SPAN_DECLARE(int) data_modems_restart(data_modems_state_t *s);
SPAN_DECLARE(void) data_modems_set_async_mode(data_modems_state_t *s,
......@@ -77,8 +81,16 @@ SPAN_DECLARE(int) data_modems_rx_fillin(data_modems_state_t *s, int len);
SPAN_DECLARE(int) data_modems_tx(data_modems_state_t *s, int16_t amp[], int max_len);
SPAN_DECLARE(void) data_modems_set_at_tx_handler(data_modems_state_t *s,
at_tx_handler_t at_tx_handler,
void *at_tx_user_data);
SPAN_DECLARE(data_modems_state_t *) data_modems_init(data_modems_state_t *s,
bool calling_party,
at_tx_handler_t at_tx_handler,
void *at_tx_user_data,
data_modems_control_handler_t modem_control_handler,
void *modem_control_user_data,
put_msg_func_t put_msg,
get_msg_func_t get_msg,
void *user_data);
......
......@@ -115,7 +115,7 @@ extern "C"
/* Enable the trap as per the MIL-STD */
//#define G711_ULAW_ZEROTRAP
/*! Bias for u-law encoding from linear. */
#define G711_ULAW_BIAS 0x84
#define G711_ULAW_BIAS 0x84
/*! \brief Encode a linear sample to u-law
\param linear The sample to encode.
......
......@@ -31,13 +31,16 @@
*/
struct awgn_state_s
{
/* Scaling factor */
double rms;
long int ix1;
long int ix2;
long int ix3;
double r[98];
double gset;
int iset;
/* Working data for the Gaussian generator */
bool odd;
double amp2;
/* Working data for the random number generator */
int32_t ix1;
int32_t ix2;
int32_t ix3;
double r[97];
};
#endif
......
......@@ -43,6 +43,9 @@ struct data_modems_state_s
silent audio. */
bool transmit_on_idle;
at_state_t at_state;
data_modems_control_handler_t modem_control_handler;
void *modem_control_user_data;
get_bit_func_t get_bit;
void *get_user_data;
put_bit_func_t put_bit;
......@@ -60,6 +63,9 @@ struct data_modems_state_s
async_tx_state_t async_tx;
async_rx_state_t async_rx;
/*! \brief Samples elapsed in the current call */
int64_t call_samples;
union
{
v8_state_t v8;
......
......@@ -31,10 +31,13 @@ struct v18_state_s
/*! \brief True if we are the calling modem */
bool calling_party;
int mode;
int initial_mode;
int current_mode;
int nation;
put_msg_func_t put_msg;
void *user_data;
int repeat_shifts;
bool repeat_shifts;
bool autobauding;
union
{
......@@ -48,10 +51,38 @@ struct v18_state_s
async_tx_state_t async_tx;
int baudot_tx_shift;
int tx_signal_on;
bool tx_draining;
uint8_t next_byte;
fsk_rx_state_t fsk_rx;
dtmf_rx_state_t dtmf_rx;
#if defined(SPANDSP_USE_FIXED_POINTx)
/*! Minimum acceptable tone level for detection. */
int32_t threshold;
/*! The accumlating total energy on the same period over which the Goertzels work. */
int32_t energy;
#else
/*! Minimum acceptable tone level for detection. */
float threshold;
/*! The accumlating total energy on the same period over which the Goertzels work. */
float energy;
#endif
goertzel_state_t tone_390;
goertzel_state_t tone_980;
goertzel_state_t tone_1180;
goertzel_state_t tone_1270;
goertzel_state_t tone_1300;
goertzel_state_t tone_1400;
goertzel_state_t tone_1650;
goertzel_state_t tone_1800;
/*! The current sample number within a processing block. */
int current_sample;
/*! Tone state duration */
int duration;
int target_duration;
int in_tone;
int baudot_rx_shift;
int consecutive_ones;
uint8_t rx_msg[256 + 1];
......@@ -59,6 +90,7 @@ struct v18_state_s
int bit_pos;
int in_progress;
int rx_suppression;
int tx_suppression;
/*! \brief Error and flow logging control */
logging_state_t logging;
......
......@@ -39,15 +39,14 @@
#if !defined(__cplusplus)
#define _Bool int
#define bool int
typedef int _Bool;
typedef int bool;
#define false 0
#define true (!false)
#else
#define _Bool bool
#define bool bool
typedef bool _Bool;
#define false false
#define true true
......
......@@ -67,60 +67,64 @@ typedef int (*span_rx_fillin_handler_t)(void *s, int len);
/*! \brief A handler for transmit, where the buffer will be filled. */
typedef int (*span_tx_handler_t)(void *s, int16_t amp[], int max_len);
#define seconds_to_samples(t) ((t)*SAMPLE_RATE)
#define milliseconds_to_samples(t) ((t)*(SAMPLE_RATE/1000))
#define microseconds_to_samples(t) ((t)/(1000000/SAMPLE_RATE))
#define ms_to_samples(t) ((t)*(SAMPLE_RATE/1000))
#define us_to_samples(t) ((t)/(1000000/SAMPLE_RATE))
/* Fixed point constant macros for 16 bit values */
#define FP_Q16_0(x) ((int16_t) (1.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q15_1(x) ((int16_t) (2.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q14_2(x) ((int16_t) (4.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q13_3(x) ((int16_t) (8.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q12_4(x) ((int16_t) (16.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q11_5(x) ((int16_t) (32.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q10_6(x) ((int16_t) (64.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q9_7(x) ((int16_t) (128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q8_8(x) ((int16_t) (256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q7_9(x) ((int16_t) (512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q6_10(x) ((int16_t) (1024.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q5_11(x) ((int16_t) (2048.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q4_12(x) ((int16_t) (4096.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q3_13(x) ((int16_t) (8192.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q2_14(x) ((int16_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q1_15(x) ((int16_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q16_0(x) ((int16_t) (1.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q15_1(x) ((int16_t) (2.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q14_2(x) ((int16_t) (4.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q13_3(x) ((int16_t) (8.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q12_4(x) ((int16_t) (16.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q11_5(x) ((int16_t) (32.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q10_6(x) ((int16_t) (64.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q9_7(x) ((int16_t) (128.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q8_8(x) ((int16_t) (256.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q7_9(x) ((int16_t) (512.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q6_10(x) ((int16_t) (1024.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q5_11(x) ((int16_t) (2048.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q4_12(x) ((int16_t) (4096.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q3_13(x) ((int16_t) (8192.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q2_14(x) ((int16_t) (16384.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q1_15(x) ((int16_t) (32768.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
/* Fixed point constant macros for 32 bit values */
#define FP_Q32_0(x) ((int32_t) (1.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q31_1(x) ((int32_t) (2.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q30_2(x) ((int32_t) (4.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q29_3(x) ((int32_t) (8.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q28_4(x) ((int32_t) (16.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q27_5(x) ((int32_t) (32.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q26_6(x) ((int32_t) (64.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q25_7(x) ((int32_t) (128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q24_8(x) ((int32_t) (256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q23_9(x) ((int32_t) (512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q22_10(x) ((int32_t) (1024.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q21_11(x) ((int32_t) (2048.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q20_12(x) ((int32_t) (4096.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q19_13(x) ((int32_t) (8192.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q18_14(x) ((int32_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q17_15(x) ((int32_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q16_16(x) ((int32_t) (65536.0*1.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q15_17(x) ((int32_t) (65536.0*2.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q14_18(x) ((int32_t) (65536.0*4.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q13_19(x) ((int32_t) (65536.0*8.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q12_20(x) ((int32_t) (65536.0*16.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q11_21(x) ((int32_t) (65536.0*32.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q10_22(x) ((int32_t) (65536.0*64.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q9_23(x) ((int32_t) (65536.0*128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q8_24(x) ((int32_t) (65536.0*256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q7_25(x) ((int32_t) (65536.0*512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q6_26(x) ((int32_t) (65536.0*1024.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q5_27(x) ((int32_t) (65536.0*2048.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q4_28(x) ((int32_t) (65536.0*4096.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q3_29(x) ((int32_t) (65536.0*8192.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q2_30(x) ((int32_t) (65536.0*16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q1_31(x) ((int32_t) (65536.0*32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q32_0(x) ((int32_t) (1.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q31_1(x) ((int32_t) (2.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q30_2(x) ((int32_t) (4.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q29_3(x) ((int32_t) (8.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q28_4(x) ((int32_t) (16.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q27_5(x) ((int32_t) (32.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q26_6(x) ((int32_t) (64.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q25_7(x) ((int32_t) (128.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q24_8(x) ((int32_t) (256.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q23_9(x) ((int32_t) (512.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q22_10(x) ((int32_t) (1024.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q21_11(x) ((int32_t) (2048.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q20_12(x) ((int32_t) (4096.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q19_13(x) ((int32_t) (8192.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q18_14(x) ((int32_t) (16384.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q17_15(x) ((int32_t) (32768.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q16_16(x) ((int32_t) (65536.0*1.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q15_17(x) ((int32_t) (65536.0*2.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q14_18(x) ((int32_t) (65536.0*4.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q13_19(x) ((int32_t) (65536.0*8.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q12_20(x) ((int32_t) (65536.0*16.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q11_21(x) ((int32_t) (65536.0*32.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q10_22(x) ((int32_t) (65536.0*64.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q9_23(x) ((int32_t) (65536.0*128.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q8_24(x) ((int32_t) (65536.0*256.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q7_25(x) ((int32_t) (65536.0*512.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q6_26(x) ((int32_t) (65536.0*1024.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q5_27(x) ((int32_t) (65536.0*2048.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q4_28(x) ((int32_t) (65536.0*4096.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q3_29(x) ((int32_t) (65536.0*8192.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q2_30(x) ((int32_t) (65536.0*16384.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#define FP_Q1_31(x) ((int32_t) (65536.0*32768.0*(x) + (((x) >= 0.0) ? 0.5 : -0.5)))
#if defined(__cplusplus)
/* C++ doesn't seem to have sane rounding functions/macros yet */
......
......@@ -66,6 +66,8 @@ enum
{
V18_AUTOMODING_GLOBAL = 0,
V18_AUTOMODING_NONE,
/* 5-bit, V.21, V.23, EDT, DTMF, Bell 103 */
V18_AUTOMODING_AUSTRALIA,
V18_AUTOMODING_IRELAND,
......@@ -173,6 +175,11 @@ SPAN_DECLARE(int) v18_rx_fillin(v18_state_t *s, int len);
invalid, this function will return -1. */
SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len);
/*! \brief Get the current mode of a V.18 connection.
\param s The V.18 context.
\return The mode. */
SPAN_DECLARE(int) v18_get_current_mode(v18_state_t *s);
/*! \brief Return a short name for an V.18 mode
\param mode The code for the V.18 mode.
\return A pointer to the name.
......
......@@ -959,6 +959,7 @@ SPAN_DECLARE(void) t30_decode_dis_dtc_dcs(t30_state_t *s, const uint8_t *pkt, in
octet_bit_field(log, pkt, 96, "Extension indicator", NULL, NULL);
if (!(pkt[14] & DISBIT8))
return;
/*endif*/
if (len <= 15)
{
span_log(log, SPAN_LOG_FLOW, " Frame is short\n");
......
差异被折叠。
......@@ -5,7 +5,7 @@
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2004-2009 Steve Underwood
* Copyright (C) 2004-2015 Steve Underwood
*
* All rights reserved.
*
......
差异被折叠。
......@@ -188,6 +188,10 @@ static int modem_tests(int use_gui, int log_audio, int test_sending)
bert_set_report(bert[i], 100000, reporter, (void *) (intptr_t) i);
if ((data_modems_state[i] = data_modems_init(NULL,
calling_party,
NULL,
NULL,
NULL,
NULL,
put_msg,
get_msg,
NULL)) == NULL)
......
......@@ -67,6 +67,61 @@ int16_t wave_buffer[4096];
data_modems_state_t *data_modem_state;
int answered = false;
int done = false;
static int modem_call_control(data_modems_state_t *s, void *user_data, int op, const char *num)
{
printf("\nModem control - %s", at_modem_control_to_str(op));
switch (op)
{
case AT_MODEM_CONTROL_CALL:
printf(" %s", num);
data_modems_call_event(s, AT_CALL_EVENT_CONNECTED);
break;
case AT_MODEM_CONTROL_ANSWER:
answered = true;
data_modems_call_event(s, AT_CALL_EVENT_ANSWERED);
break;
case AT_MODEM_CONTROL_HANGUP:
done = true;
break;
case AT_MODEM_CONTROL_OFFHOOK:
break;
case AT_MODEM_CONTROL_DTR:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_RTS:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_CTS:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_CAR:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_RNG:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_DSR:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_SETID:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_RESTART:
printf(" %d", (int) (intptr_t) num);
break;
case AT_MODEM_CONTROL_DTE_TIMEOUT:
printf(" %d", (int) (intptr_t) num);
break;
}
/*endswitch*/
printf("\n");
return 0;
}
/*- End of function --------------------------------------------------------*/
static int get_msg(void *user_data, uint8_t msg[], int len)
{
return 0;
......@@ -79,17 +134,31 @@ static void put_msg(void *user_data, const uint8_t msg[], int len)
printf("Status %s\n", signal_status_to_str(len));
else
printf("Put %d '%s'\n", len, msg);
/*endif*/
}
/*- End of function --------------------------------------------------------*/
static void terminal_callback(void *user_data, const uint8_t msg[], int len)
{
data_modems_state_t *s;
int i;
s = (data_modems_state_t *) user_data;
printf("terminal callback %d\n", len);
for (i = 0; i < len; i++)
{
printf("0x%x ", msg[i]);
}
printf("\n");
at_interpreter(&s->at_state, msg, len);
}
/*- End of function --------------------------------------------------------*/
static int termios_callback(void *user_data, struct termios *termios)
{
data_modems_state_t *s;
s = (data_modems_state_t *) user_data;
printf("termios callback\n");
return 0;
}
......@@ -116,7 +185,9 @@ static int rx_callback(void *user_data, const int16_t amp[], int samples)
{
for (i = 0; i < samples; i++)
wave_buffer[2*i] = amp[i];
/*endfor*/
}
/*endif*/
return out_samples;
}
/*- End of function --------------------------------------------------------*/
......@@ -137,10 +208,13 @@ static int tx_callback(void *user_data, int16_t amp[], int samples)
{
if (out_samples < samples)
memset(&amp[out_samples], 0, (samples - out_samples)*2);
/*endif*/
for (i = 0; i < samples; i++)
wave_buffer[2*i + 1] = amp[i];
/*endfor*/
sf_writef_short(wave_handle, wave_buffer, samples);
}
/*endif*/
return samples;
}
/*- End of function --------------------------------------------------------*/
......@@ -153,6 +227,10 @@ static int modem_tests(int use_gui, int log_audio, bool calling_party)
/* Now set up and run the modems */
if ((data_modem_state = data_modems_init(NULL,
calling_party,
terminal_write,
NULL,
modem_call_control,
NULL,
put_msg,
get_msg,
NULL)) == NULL)
......@@ -160,6 +238,7 @@ static int modem_tests(int use_gui, int log_audio, bool calling_party)
fprintf(stderr, " Cannot start the data modem\n");
exit(2);
}
/*endif*/
logging = data_modems_get_logging_state(data_modem_state);
span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_DATE);
span_log_set_tag(logging, "Modem");
......@@ -180,6 +259,9 @@ static int modem_tests(int use_gui, int log_audio, bool calling_party)
fprintf(stderr, " Cannot start the socket harness\n");
exit(2);
}
/*endif*/
data_modems_set_at_tx_handler(data_modem_state, terminal_write, s);
wave_handle = NULL;
if (log_audio)
......@@ -189,9 +271,11 @@ static int modem_tests(int use_gui, int log_audio, bool calling_party)
fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
exit(2);
}
/*endif*/
}
/*endif*/
socket_harness_run(s);
socket_harness_run(s, calling_party);
if (log_audio)
{
......@@ -200,7 +284,9 @@ static int modem_tests(int use_gui, int log_audio, bool calling_party)
fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
exit(2);
}
/*endif*/
}
/*endif*/
return 0;
}
......@@ -242,10 +328,13 @@ int main(int argc, char *argv[])
exit(2);
break;
}
/*endswitch*/
}
/*endwhile*/
if (modem_tests(use_gui, log_audio, calling_party))
exit(2);
/*endif*/
printf("Tests passed\n");
return 0;
}
......
......@@ -79,7 +79,16 @@ static void log_signal(int signum)
}
/*- End of function --------------------------------------------------------*/
int socket_harness_run(socket_harness_state_t *s)
int terminal_write(void *user_data, const char *buf, int len)
{
socket_harness_state_t *s;
s = (socket_harness_state_t *) user_data;
return write(s->pty_fd, buf, len);
}
/*- End of function --------------------------------------------------------*/
int socket_harness_run(socket_harness_state_t *s, int kick)
{
struct timeval tmo;
fd_set rset;
......@@ -91,6 +100,23 @@ int socket_harness_run(socket_harness_state_t *s)
int tx_samples;
int ret;
if (kick)
{
samples = 160;
tx_samples = s->tx_callback(s->user_data, outbuf, samples);
if (tx_samples < samples)
memset(&outbuf[tx_samples], 0, (samples - tx_samples)*2);
if ((count = write(s->audio_fd, outbuf, samples*2)) < 0)
{
if (errno != EAGAIN)
{
fprintf(stderr, "Error: audio write: %s\n", strerror(errno));
return -1;
}
/* TODO: */
}
}
while (keep_running)
{
//if (s->modem->event)
......@@ -131,7 +157,6 @@ int socket_harness_run(socket_harness_state_t *s)
fprintf(stderr, "Error: select: %s\n", strerror(errno));
return ret;
}
if (ret == 0)
{
/* Timeout */
......
......@@ -53,7 +53,9 @@ typedef struct socket_harness_state_s
modem_t modem;
} socket_harness_state_t;
int socket_harness_run(socket_harness_state_t *s);
int socket_harness_run(socket_harness_state_t *s, int kick);
int terminal_write(void *user_data, const char *buf, int len);
socket_harness_state_t *socket_harness_init(socket_harness_state_t *s,
const char *socket_name,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论