mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-17 01:02:12 +00:00
update to snapshot spandsp-20080919.tar.gz
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9770 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
7460c20ecd
commit
2825fb6e5b
@ -1 +1 @@
|
|||||||
Tue Sep 30 23:55:26 EDT 2008
|
Tue Sep 30 23:59:24 EDT 2008
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
## License along with this program; if not, write to the Free Software
|
## License along with this program; if not, write to the Free Software
|
||||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
##
|
##
|
||||||
## $Id: Makefile.am,v 1.101 2008/09/08 12:45:02 steveu Exp $
|
## $Id: Makefile.am,v 1.103 2008/09/19 14:02:05 steveu Exp $
|
||||||
|
|
||||||
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
||||||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||||
@ -37,6 +37,7 @@ libspandsp_la_SOURCES = adsi.c \
|
|||||||
bitstream.c \
|
bitstream.c \
|
||||||
complex_filters.c \
|
complex_filters.c \
|
||||||
complex_vector_float.c \
|
complex_vector_float.c \
|
||||||
|
complex_vector_int.c \
|
||||||
crc.c \
|
crc.c \
|
||||||
dds_float.c \
|
dds_float.c \
|
||||||
dds_int.c \
|
dds_int.c \
|
||||||
@ -45,8 +46,7 @@ libspandsp_la_SOURCES = adsi.c \
|
|||||||
fax.c \
|
fax.c \
|
||||||
fsk.c \
|
fsk.c \
|
||||||
g711.c \
|
g711.c \
|
||||||
g722_encode.c \
|
g722.c \
|
||||||
g722_decode.c \
|
|
||||||
g726.c \
|
g726.c \
|
||||||
gsm0610_decode.c \
|
gsm0610_decode.c \
|
||||||
gsm0610_encode.c \
|
gsm0610_encode.c \
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: awgn.c,v 1.16 2008/07/02 14:48:25 steveu Exp $
|
* $Id: awgn.c,v 1.17 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -57,7 +57,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/awgn.h"
|
#include "spandsp/awgn.h"
|
||||||
|
|
||||||
/* Gaussian noise generator constants */
|
/* Gaussian noise generator constants */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* SpanDSP - a series of DSP components for telephony
|
* SpanDSP - a series of DSP components for telephony
|
||||||
*
|
*
|
||||||
* vector_float.c - Floating vector arithmetic routines.
|
* complex_vector_float.c - Floating complex vector arithmetic routines.
|
||||||
*
|
*
|
||||||
* Written by Steve Underwood <steveu@coppice.org>
|
* Written by Steve Underwood <steveu@coppice.org>
|
||||||
*
|
*
|
||||||
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: complex_vector_float.c,v 1.8 2008/07/02 14:48:25 steveu Exp $
|
* $Id: complex_vector_float.c,v 1.10 2008/09/18 13:16:49 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -50,4 +50,84 @@
|
|||||||
#include "spandsp/vector_float.h"
|
#include "spandsp/vector_float.h"
|
||||||
#include "spandsp/complex_vector_float.h"
|
#include "spandsp/complex_vector_float.h"
|
||||||
|
|
||||||
|
complexf_t cvec_dot_prodf(const complexf_t x[], const complexf_t y[], int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
complexf_t z;
|
||||||
|
|
||||||
|
z = complex_setf(0.0f, 0.0f);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
z.re += (x[i].re*y[i].re - x[i].im*y[i].im);
|
||||||
|
z.im += (x[i].re*y[i].im + x[i].im*y[i].re);
|
||||||
|
}
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
complex_t cvec_dot_prod(const complex_t x[], const complex_t y[], int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
complex_t z;
|
||||||
|
|
||||||
|
z = complex_set(0.0, 0.0);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
z.re += (x[i].re*y[i].re - x[i].im*y[i].im);
|
||||||
|
z.im += (x[i].re*y[i].im + x[i].im*y[i].re);
|
||||||
|
}
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if defined(HAVE_LONG_DOUBLE)
|
||||||
|
complexl_t cvec_dot_prodl(const complexl_t x[], const complexl_t y[], int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
complexl_t z;
|
||||||
|
|
||||||
|
z = complex_setl(0.0L, 0.0L);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
z.re += (x[i].re*y[i].re - x[i].im*y[i].im);
|
||||||
|
z.im += (x[i].re*y[i].im + x[i].im*y[i].re);
|
||||||
|
}
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
complexf_t cvec_circular_dot_prodf(const complexf_t x[], const complexf_t y[], int n, int pos)
|
||||||
|
{
|
||||||
|
complexf_t z;
|
||||||
|
complexf_t z1;
|
||||||
|
|
||||||
|
z = cvec_dot_prodf(&x[pos], &y[0], n - pos);
|
||||||
|
z1 = cvec_dot_prodf(&x[0], &y[n - pos], pos);
|
||||||
|
z = complex_addf(&z, &z1);
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void cvec_lmsf(const complexf_t x[], complexf_t y[], int n, const complexf_t *error)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
y[i].re += (x[i].im*error->im + x[i].re*error->re);
|
||||||
|
y[i].im += (x[i].re*error->im - x[i].im*error->re);
|
||||||
|
/* Leak a little to tame uncontrolled wandering */
|
||||||
|
y[i].re *= 0.9999f;
|
||||||
|
y[i].im *= 0.9999f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void cvec_circular_lmsf(const complexf_t x[], complexf_t y[], int n, int pos, const complexf_t *error)
|
||||||
|
{
|
||||||
|
cvec_lmsf(&x[pos], &y[0], n - pos, error);
|
||||||
|
cvec_lmsf(&x[0], &y[n - pos], pos, error);
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
/*- End of file ------------------------------------------------------------*/
|
/*- End of file ------------------------------------------------------------*/
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: echo.c,v 1.27 2008/08/29 09:28:13 steveu Exp $
|
* $Id: echo.c,v 1.28 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -96,6 +96,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/logging.h"
|
#include "spandsp/logging.h"
|
||||||
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/dc_restore.h"
|
||||||
#include "spandsp/bit_operations.h"
|
#include "spandsp/bit_operations.h"
|
||||||
#include "spandsp/echo.h"
|
#include "spandsp/echo.h"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This code is based on the widely used GSM 06.10 code available from
|
* This code is based on the widely used GSM 06.10 code available from
|
||||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||||
*
|
*
|
||||||
* $Id: gsm0610_decode.c,v 1.21 2008/07/02 14:48:25 steveu Exp $
|
* $Id: gsm0610_decode.c,v 1.22 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/bitstream.h"
|
#include "spandsp/bitstream.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/gsm0610.h"
|
#include "spandsp/gsm0610.h"
|
||||||
|
|
||||||
#include "gsm0610_local.h"
|
#include "gsm0610_local.h"
|
||||||
@ -66,9 +66,9 @@ static void postprocessing(gsm0610_state_t *s, int16_t amp[])
|
|||||||
{
|
{
|
||||||
tmp = gsm_mult_r(msr, 28180);
|
tmp = gsm_mult_r(msr, 28180);
|
||||||
/* De-emphasis */
|
/* De-emphasis */
|
||||||
msr = gsm_add(amp[k], tmp);
|
msr = saturated_add16(amp[k], tmp);
|
||||||
/* Truncation & upscaling */
|
/* Truncation & upscaling */
|
||||||
amp[k] = (int16_t) (gsm_add(msr, msr) & 0xFFF8);
|
amp[k] = (int16_t) (saturated_add16(msr, msr) & 0xFFF8);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
s->msr = msr;
|
s->msr = msr;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This code is based on the widely used GSM 06.10 code available from
|
* This code is based on the widely used GSM 06.10 code available from
|
||||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||||
*
|
*
|
||||||
* $Id: gsm0610_encode.c,v 1.25 2008/07/02 14:48:25 steveu Exp $
|
* $Id: gsm0610_encode.c,v 1.26 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/bitstream.h"
|
#include "spandsp/bitstream.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/gsm0610.h"
|
#include "spandsp/gsm0610.h"
|
||||||
|
|
||||||
#include "gsm0610_local.h"
|
#include "gsm0610_local.h"
|
||||||
@ -93,7 +93,7 @@ static void encode_a_frame(gsm0610_state_t *s, gsm0610_frame_t *f, const int16_t
|
|||||||
gsm0610_rpe_encoding(s, s->e + 5, &f->xmaxc[k], &f->Mc[k], f->xMc[k]);
|
gsm0610_rpe_encoding(s, s->e + 5, &f->xmaxc[k], &f->Mc[k], f->xMc[k]);
|
||||||
|
|
||||||
for (i = 0; i < 40; i++)
|
for (i = 0; i < 40; i++)
|
||||||
dp[i] = gsm_add(s->e[5 + i], dpp[i]);
|
dp[i] = saturated_add16(s->e[5 + i], dpp[i]);
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
dp += 40;
|
dp += 40;
|
||||||
dpp += 40;
|
dpp += 40;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This code is based on the widely used GSM 06.10 code available from
|
* This code is based on the widely used GSM 06.10 code available from
|
||||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||||
*
|
*
|
||||||
* $Id: gsm0610_long_term.c,v 1.16 2008/07/02 14:48:25 steveu Exp $
|
* $Id: gsm0610_long_term.c,v 1.17 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/bitstream.h"
|
#include "spandsp/bitstream.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/gsm0610.h"
|
#include "spandsp/gsm0610.h"
|
||||||
|
|
||||||
#include "gsm0610_local.h"
|
#include "gsm0610_local.h"
|
||||||
@ -185,7 +185,7 @@ static int16_t evaluate_ltp_parameters(int16_t d[40],
|
|||||||
for (k = 0; k < 40; k++)
|
for (k = 0; k < 40; k++)
|
||||||
{
|
{
|
||||||
temp = d[k];
|
temp = d[k];
|
||||||
temp = gsm_abs(temp);
|
temp = saturated_abs16(temp);
|
||||||
if (temp > dmax)
|
if (temp > dmax)
|
||||||
dmax = temp;
|
dmax = temp;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
@ -314,12 +314,12 @@ static int16_t evaluate_ltp_parameters(int16_t d[40],
|
|||||||
quantization of the LTP gain b to get the coded version bc. */
|
quantization of the LTP gain b to get the coded version bc. */
|
||||||
for (bc = 0; bc <= 2; bc++)
|
for (bc = 0; bc <= 2; bc++)
|
||||||
{
|
{
|
||||||
if (R <= gsm_mult(S, gsm_DLB[bc]))
|
if (R <= saturated_mul16(S, gsm_DLB[bc]))
|
||||||
break;
|
break;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
return bc;
|
return bc;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ static void long_term_analysis_filtering(int16_t bc,
|
|||||||
for (k = 0; k < 40; k++)
|
for (k = 0; k < 40; k++)
|
||||||
{
|
{
|
||||||
dpp[k] = gsm_mult_r(gsm_QLB[bc], dp[k - Nc]);
|
dpp[k] = gsm_mult_r(gsm_QLB[bc], dp[k - Nc]);
|
||||||
e[k] = gsm_sub(d[k], dpp[k]);
|
e[k] = saturated_sub16(d[k], dpp[k]);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
}
|
}
|
||||||
@ -398,7 +398,7 @@ void gsm0610_long_term_synthesis_filtering(gsm0610_state_t *s,
|
|||||||
for (k = 0; k < 40; k++)
|
for (k = 0; k < 40; k++)
|
||||||
{
|
{
|
||||||
drpp = gsm_mult_r(brp, drp[k - Nr]);
|
drpp = gsm_mult_r(brp, drp[k - Nr]);
|
||||||
drp[k] = gsm_add(erp[k], drpp);
|
drp[k] = saturated_add16(erp[k], drpp);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This code is based on the widely used GSM 06.10 code available from
|
* This code is based on the widely used GSM 06.10 code available from
|
||||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||||
*
|
*
|
||||||
* $Id: gsm0610_lpc.c,v 1.21 2008/09/04 14:40:05 steveu Exp $
|
* $Id: gsm0610_lpc.c,v 1.22 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -49,7 +49,7 @@
|
|||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/bitstream.h"
|
#include "spandsp/bitstream.h"
|
||||||
#include "spandsp/bit_operations.h"
|
#include "spandsp/bit_operations.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/vector_int.h"
|
#include "spandsp/vector_int.h"
|
||||||
#include "spandsp/gsm0610.h"
|
#include "spandsp/gsm0610.h"
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ static void autocorrelation(int16_t amp[GSM0610_FRAME_LEN], int32_t L_ACF[9])
|
|||||||
#else
|
#else
|
||||||
for (smax = 0, k = 0; k < GSM0610_FRAME_LEN; k++)
|
for (smax = 0, k = 0; k < GSM0610_FRAME_LEN; k++)
|
||||||
{
|
{
|
||||||
temp = gsm_abs(amp[k]);
|
temp = saturated_abs16(amp[k]);
|
||||||
if (temp > smax)
|
if (temp > smax)
|
||||||
smax = (int16_t) temp;
|
smax = (int16_t) temp;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
@ -398,7 +398,7 @@ static void reflection_coefficients(int32_t L_ACF[9], int16_t r[8])
|
|||||||
for (n = 1; n <= 8; n++, r++)
|
for (n = 1; n <= 8; n++, r++)
|
||||||
{
|
{
|
||||||
temp = P[1];
|
temp = P[1];
|
||||||
temp = gsm_abs (temp);
|
temp = saturated_abs16(temp);
|
||||||
if (P[0] < temp)
|
if (P[0] < temp)
|
||||||
{
|
{
|
||||||
for (i = n; i <= 8; i++)
|
for (i = n; i <= 8; i++)
|
||||||
@ -421,15 +421,15 @@ static void reflection_coefficients(int32_t L_ACF[9], int16_t r[8])
|
|||||||
|
|
||||||
/* Schur recursion */
|
/* Schur recursion */
|
||||||
temp = gsm_mult_r(P[1], *r);
|
temp = gsm_mult_r(P[1], *r);
|
||||||
P[0] = gsm_add(P[0], temp);
|
P[0] = saturated_add16(P[0], temp);
|
||||||
|
|
||||||
for (m = 1; m <= 8 - n; m++)
|
for (m = 1; m <= 8 - n; m++)
|
||||||
{
|
{
|
||||||
temp = gsm_mult_r(K[m], *r);
|
temp = gsm_mult_r(K[m], *r);
|
||||||
P[m] = gsm_add(P[m + 1], temp);
|
P[m] = saturated_add16(P[m + 1], temp);
|
||||||
|
|
||||||
temp = gsm_mult_r(P[m + 1], *r);
|
temp = gsm_mult_r(P[m + 1], *r);
|
||||||
K[m] = gsm_add(K[m], temp);
|
K[m] = saturated_add16(K[m], temp);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
}
|
}
|
||||||
@ -453,8 +453,7 @@ static void transform_to_log_area_ratios(int16_t r[8])
|
|||||||
/* Computation of the LAR[0..7] from the r[0..7] */
|
/* Computation of the LAR[0..7] from the r[0..7] */
|
||||||
for (i = 1; i <= 8; i++, r++)
|
for (i = 1; i <= 8; i++, r++)
|
||||||
{
|
{
|
||||||
temp = *r;
|
temp = saturated_abs16(*r);
|
||||||
temp = gsm_abs(temp);
|
|
||||||
assert(temp >= 0);
|
assert(temp >= 0);
|
||||||
|
|
||||||
if (temp < 22118)
|
if (temp < 22118)
|
||||||
@ -496,9 +495,9 @@ static void quantization_and_coding(int16_t LAR[8])
|
|||||||
|
|
||||||
#undef STEP
|
#undef STEP
|
||||||
#define STEP(A,B,MAC,MIC) \
|
#define STEP(A,B,MAC,MIC) \
|
||||||
temp = gsm_mult(A, *LAR); \
|
temp = saturated_mul16(A, *LAR); \
|
||||||
temp = gsm_add(temp, B); \
|
temp = saturated_add16(temp, B); \
|
||||||
temp = gsm_add(temp, 256); \
|
temp = saturated_add16(temp, 256); \
|
||||||
temp >>= 9; \
|
temp >>= 9; \
|
||||||
*LAR = (int16_t) ((temp > MAC) \
|
*LAR = (int16_t) ((temp > MAC) \
|
||||||
? \
|
? \
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This code is based on the widely used GSM 06.10 code available from
|
* This code is based on the widely used GSM 06.10 code available from
|
||||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||||
*
|
*
|
||||||
* $Id: gsm0610_preprocess.c,v 1.13 2008/07/02 14:48:25 steveu Exp $
|
* $Id: gsm0610_preprocess.c,v 1.14 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/bitstream.h"
|
#include "spandsp/bitstream.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/gsm0610.h"
|
#include "spandsp/gsm0610.h"
|
||||||
|
|
||||||
#include "gsm0610_local.h"
|
#include "gsm0610_local.h"
|
||||||
@ -121,7 +121,7 @@ void gsm0610_preprocess(gsm0610_state_t *s, const int16_t amp[GSM0610_FRAME_LEN]
|
|||||||
* L_temp = (++L_temp) >> 1;
|
* L_temp = (++L_temp) >> 1;
|
||||||
* L_z2 = L_z2 - L_temp;
|
* L_z2 = L_z2 - L_temp;
|
||||||
*/
|
*/
|
||||||
L_z2 = gsm_l_add(L_z2, L_s2);
|
L_z2 = saturated_add32(L_z2, L_s2);
|
||||||
#else
|
#else
|
||||||
/* This does L_z2 = L_z2 * 0x7FD5/0x8000 + L_s2 */
|
/* This does L_z2 = L_z2 * 0x7FD5/0x8000 + L_s2 */
|
||||||
msp = (int16_t) (L_z2 >> 15);
|
msp = (int16_t) (L_z2 >> 15);
|
||||||
@ -129,16 +129,16 @@ void gsm0610_preprocess(gsm0610_state_t *s, const int16_t amp[GSM0610_FRAME_LEN]
|
|||||||
|
|
||||||
L_s2 += gsm_mult_r(lsp, 32735);
|
L_s2 += gsm_mult_r(lsp, 32735);
|
||||||
L_temp = (int32_t) msp*32735;
|
L_temp = (int32_t) msp*32735;
|
||||||
L_z2 = gsm_l_add(L_temp, L_s2);
|
L_z2 = saturated_add32(L_temp, L_s2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compute sof[k] with rounding */
|
/* Compute sof[k] with rounding */
|
||||||
L_temp = gsm_l_add(L_z2, 16384);
|
L_temp = saturated_add32(L_z2, 16384);
|
||||||
|
|
||||||
/* 4.2.3 Preemphasis */
|
/* 4.2.3 Preemphasis */
|
||||||
msp = gsm_mult_r(mp, -28180);
|
msp = gsm_mult_r(mp, -28180);
|
||||||
mp = (int16_t) (L_temp >> 15);
|
mp = (int16_t) (L_temp >> 15);
|
||||||
so[k] = gsm_add(mp, msp);
|
so[k] = saturated_add16(mp, msp);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This code is based on the widely used GSM 06.10 code available from
|
* This code is based on the widely used GSM 06.10 code available from
|
||||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||||
*
|
*
|
||||||
* $Id: gsm0610_rpe.c,v 1.21 2008/07/02 14:48:25 steveu Exp $
|
* $Id: gsm0610_rpe.c,v 1.22 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/bitstream.h"
|
#include "spandsp/bitstream.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/gsm0610.h"
|
#include "spandsp/gsm0610.h"
|
||||||
|
|
||||||
#include "gsm0610_local.h"
|
#include "gsm0610_local.h"
|
||||||
@ -139,8 +139,8 @@ static void weighting_filter(const int16_t *e, // signal [-5..0.39.44] IN
|
|||||||
|
|
||||||
/* for (i = 0; i <= 10; i++)
|
/* for (i = 0; i <= 10; i++)
|
||||||
* {
|
* {
|
||||||
* L_temp = gsm_l_mult(wt[k + i], gsm_H[i]);
|
* L_temp = saturated_mul_16_32(wt[k + i], gsm_H[i]);
|
||||||
* L_result = gsm_l_add(L_result, L_temp);
|
* L_result = saturated_add32(L_result, L_temp);
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ static void apcm_quantization(int16_t xM[13],
|
|||||||
for (i = 0; i < 13; i++)
|
for (i = 0; i < 13; i++)
|
||||||
{
|
{
|
||||||
temp = xM[i];
|
temp = xM[i];
|
||||||
temp = gsm_abs(temp);
|
temp = saturated_abs16(temp);
|
||||||
if (temp > xmax)
|
if (temp > xmax)
|
||||||
xmax = temp;
|
xmax = temp;
|
||||||
/*endif*/
|
/*endif*/
|
||||||
@ -379,7 +379,7 @@ static void apcm_quantization(int16_t xM[13],
|
|||||||
temp = (int16_t) (exp + 5);
|
temp = (int16_t) (exp + 5);
|
||||||
|
|
||||||
assert(temp <= 11 && temp >= 0);
|
assert(temp <= 11 && temp >= 0);
|
||||||
xmaxc = gsm_add((xmax >> temp), exp << 3);
|
xmaxc = saturated_add16((xmax >> temp), exp << 3);
|
||||||
|
|
||||||
/* Quantizing and coding of the xM[0..12] RPE sequence
|
/* Quantizing and coding of the xM[0..12] RPE sequence
|
||||||
to get the xMc[0..12] */
|
to get the xMc[0..12] */
|
||||||
@ -406,7 +406,7 @@ static void apcm_quantization(int16_t xM[13],
|
|||||||
assert(temp1 >= 0 && temp1 < 16);
|
assert(temp1 >= 0 && temp1 < 16);
|
||||||
|
|
||||||
temp = xM[i] << temp1;
|
temp = xM[i] << temp1;
|
||||||
temp = gsm_mult(temp, temp2);
|
temp = saturated_mul16(temp, temp2);
|
||||||
temp >>= 12;
|
temp >>= 12;
|
||||||
xMc[i] = (int16_t) (temp + 4); /* See note below */
|
xMc[i] = (int16_t) (temp + 4); /* See note below */
|
||||||
}
|
}
|
||||||
@ -444,9 +444,9 @@ static void apcm_inverse_quantization(int16_t xMc[13],
|
|||||||
assert(mant >= 0 && mant <= 7);
|
assert(mant >= 0 && mant <= 7);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
temp1 = gsm_FAC[mant]; /* See 4.2-15 for mant */
|
temp1 = gsm_FAC[mant]; /* See 4.2-15 for mant */
|
||||||
temp2 = gsm_sub(6, exp); /* See 4.2-15 for exp */
|
temp2 = saturated_sub16(6, exp); /* See 4.2-15 for exp */
|
||||||
temp3 = gsm_asl(1, gsm_sub (temp2, 1));
|
temp3 = gsm_asl(1, saturated_sub16(temp2, 1));
|
||||||
|
|
||||||
for (i = 0; i < 13; i++)
|
for (i = 0; i < 13; i++)
|
||||||
{
|
{
|
||||||
@ -457,7 +457,7 @@ static void apcm_inverse_quantization(int16_t xMc[13],
|
|||||||
|
|
||||||
temp <<= 12; /* 16 bit signed */
|
temp <<= 12; /* 16 bit signed */
|
||||||
temp = gsm_mult_r(temp1, temp);
|
temp = gsm_mult_r(temp1, temp);
|
||||||
temp = gsm_add(temp, temp3);
|
temp = saturated_add16(temp, temp3);
|
||||||
xMp[i] = gsm_asr(temp, temp2);
|
xMp[i] = gsm_asr(temp, temp2);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This code is based on the widely used GSM 06.10 code available from
|
* This code is based on the widely used GSM 06.10 code available from
|
||||||
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
|
||||||
*
|
*
|
||||||
* $Id: gsm0610_short_term.c,v 1.15 2008/07/02 14:48:25 steveu Exp $
|
* $Id: gsm0610_short_term.c,v 1.16 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/bitstream.h"
|
#include "spandsp/bitstream.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/gsm0610.h"
|
#include "spandsp/gsm0610.h"
|
||||||
|
|
||||||
#include "gsm0610_local.h"
|
#include "gsm0610_local.h"
|
||||||
@ -68,11 +68,11 @@ static void decode_log_area_ratios(int16_t LARc[8], int16_t *LARpp)
|
|||||||
/* Compute the LARpp[1..8] */
|
/* Compute the LARpp[1..8] */
|
||||||
|
|
||||||
#undef STEP
|
#undef STEP
|
||||||
#define STEP(B,MIC,INVA) \
|
#define STEP(B,MIC,INVA) \
|
||||||
temp1 = gsm_add(*LARc++, MIC) << 10; \
|
temp1 = saturated_add16(*LARc++, MIC) << 10; \
|
||||||
temp1 = gsm_sub(temp1, B << 1); \
|
temp1 = saturated_sub16(temp1, B << 1); \
|
||||||
temp1 = gsm_mult_r (INVA, temp1); \
|
temp1 = gsm_mult_r(INVA, temp1); \
|
||||||
*LARpp++ = gsm_add(temp1, temp1);
|
*LARpp++ = saturated_add16(temp1, temp1);
|
||||||
|
|
||||||
STEP( 0, -32, 13107);
|
STEP( 0, -32, 13107);
|
||||||
STEP( 0, -32, 13107);
|
STEP( 0, -32, 13107);
|
||||||
@ -110,8 +110,8 @@ static void coefficients_0_12(int16_t *LARpp_j_1,
|
|||||||
|
|
||||||
for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++)
|
for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++)
|
||||||
{
|
{
|
||||||
*LARp = gsm_add(*LARpp_j_1 >> 2, *LARpp_j >> 2);
|
*LARp = saturated_add16(*LARpp_j_1 >> 2, *LARpp_j >> 2);
|
||||||
*LARp = gsm_add(*LARp, *LARpp_j_1 >> 1);
|
*LARp = saturated_add16(*LARp, *LARpp_j_1 >> 1);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ static void coefficients_13_26(int16_t *LARpp_j_1,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
|
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
|
||||||
*LARp = gsm_add(*LARpp_j_1 >> 1, *LARpp_j >> 1);
|
*LARp = saturated_add16(*LARpp_j_1 >> 1, *LARpp_j >> 1);
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -137,8 +137,8 @@ static void coefficients_27_39(int16_t *LARpp_j_1,
|
|||||||
|
|
||||||
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
|
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
|
||||||
{
|
{
|
||||||
*LARp = gsm_add(*LARpp_j_1 >> 2, *LARpp_j >> 2);
|
*LARp = saturated_add16(*LARpp_j_1 >> 2, *LARpp_j >> 2);
|
||||||
*LARp = gsm_add(*LARp, *LARpp_j >> 1);
|
*LARp = saturated_add16(*LARp, *LARpp_j >> 1);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ static void larp_to_rp(int16_t LARp[8])
|
|||||||
else if (temp < 20070)
|
else if (temp < 20070)
|
||||||
temp += 11059;
|
temp += 11059;
|
||||||
else
|
else
|
||||||
temp = gsm_add(temp >> 2, 26112);
|
temp = saturated_add16(temp >> 2, 26112);
|
||||||
/*endif*/
|
/*endif*/
|
||||||
*LARpx = -temp;
|
*LARpx = -temp;
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ static void larp_to_rp(int16_t LARp[8])
|
|||||||
else if (temp < 20070)
|
else if (temp < 20070)
|
||||||
temp += 11059;
|
temp += 11059;
|
||||||
else
|
else
|
||||||
temp = gsm_add(temp >> 2, 26112);
|
temp = saturated_add16(temp >> 2, 26112);
|
||||||
/*endif*/
|
/*endif*/
|
||||||
*LARpx = temp;
|
*LARpx = temp;
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ static void short_term_synthesis_filtering(gsm0610_state_t *s,
|
|||||||
:
|
:
|
||||||
(int16_t) (((int32_t) tmp1*(int32_t) tmp2 + 16384) >> 15) & 0xFFFF);
|
(int16_t) (((int32_t) tmp1*(int32_t) tmp2 + 16384) >> 15) & 0xFFFF);
|
||||||
|
|
||||||
sri = gsm_sub(sri, tmp2);
|
sri = saturated_sub16(sri, tmp2);
|
||||||
|
|
||||||
tmp1 = ((tmp1 == INT16_MIN && sri == INT16_MIN)
|
tmp1 = ((tmp1 == INT16_MIN && sri == INT16_MIN)
|
||||||
?
|
?
|
||||||
@ -287,7 +287,7 @@ static void short_term_synthesis_filtering(gsm0610_state_t *s,
|
|||||||
:
|
:
|
||||||
(int16_t) (((int32_t) tmp1*(int32_t) sri + 16384) >> 15) & 0xFFFF);
|
(int16_t) (((int32_t) tmp1*(int32_t) sri + 16384) >> 15) & 0xFFFF);
|
||||||
|
|
||||||
v[i + 1] = gsm_add(v[i], tmp1);
|
v[i + 1] = saturated_add16(v[i], tmp1);
|
||||||
}
|
}
|
||||||
/*endfor*/
|
/*endfor*/
|
||||||
*sr++ =
|
*sr++ =
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: ima_adpcm.c,v 1.28 2008/07/02 14:48:25 steveu Exp $
|
* $Id: ima_adpcm.c,v 1.29 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -44,7 +44,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/ima_adpcm.h"
|
#include "spandsp/ima_adpcm.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -133,6 +133,10 @@ SOURCE=.\complex_vector_float.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\complex_vector_int.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\crc.c
|
SOURCE=.\crc.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@ -165,11 +169,7 @@ SOURCE=.\g711.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\g722_encode.c
|
SOURCE=.\g722.c
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\g722_decode.c
|
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: make_modem_filter.c,v 1.11 2008/07/02 14:48:25 steveu Exp $
|
* $Id: make_modem_filter.c,v 1.12 2008/09/18 14:59:30 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
#if defined(HAVE_CONFIG_H)
|
||||||
@ -158,6 +158,7 @@ static void make_rx_filter(int coeff_sets,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
int k;
|
||||||
int m;
|
int m;
|
||||||
int x;
|
int x;
|
||||||
int total_coeffs;
|
int total_coeffs;
|
||||||
@ -166,7 +167,11 @@ static void make_rx_filter(int coeff_sets,
|
|||||||
double gain;
|
double gain;
|
||||||
double peak;
|
double peak;
|
||||||
double coeffs[MAX_COEFF_SETS*MAX_COEFFS_PER_FILTER + 1];
|
double coeffs[MAX_COEFF_SETS*MAX_COEFFS_PER_FILTER + 1];
|
||||||
|
#if 0
|
||||||
complex_t co[MAX_COEFFS_PER_FILTER];
|
complex_t co[MAX_COEFFS_PER_FILTER];
|
||||||
|
#else
|
||||||
|
double cox[MAX_COEFFS_PER_FILTER];
|
||||||
|
#endif
|
||||||
|
|
||||||
total_coeffs = coeff_sets*coeffs_per_filter + 1;
|
total_coeffs = coeff_sets*coeffs_per_filter + 1;
|
||||||
alpha = baud_rate/(2.0*(double) (coeff_sets*SAMPLE_RATE));
|
alpha = baud_rate/(2.0*(double) (coeff_sets*SAMPLE_RATE));
|
||||||
@ -203,6 +208,7 @@ static void make_rx_filter(int coeff_sets,
|
|||||||
modem code. */
|
modem code. */
|
||||||
printf("#define RX_PULSESHAPER%s_GAIN %ff\n", tag, gain);
|
printf("#define RX_PULSESHAPER%s_GAIN %ff\n", tag, gain);
|
||||||
printf("#define RX_PULSESHAPER%s_COEFF_SETS %d\n", tag, coeff_sets);
|
printf("#define RX_PULSESHAPER%s_COEFF_SETS %d\n", tag, coeff_sets);
|
||||||
|
#if 0
|
||||||
printf("static const %s rx_pulseshaper%s[RX_PULSESHAPER%s_COEFF_SETS][%d] =\n",
|
printf("static const %s rx_pulseshaper%s[RX_PULSESHAPER%s_COEFF_SETS][%d] =\n",
|
||||||
(fixed_point) ? "complexi16_t" : "complexf_t",
|
(fixed_point) ? "complexi16_t" : "complexf_t",
|
||||||
tag,
|
tag,
|
||||||
@ -244,6 +250,55 @@ static void make_rx_filter(int coeff_sets,
|
|||||||
printf(" }\n");
|
printf(" }\n");
|
||||||
}
|
}
|
||||||
printf("};\n");
|
printf("};\n");
|
||||||
|
#else
|
||||||
|
for (k = 0; k < 2; k++)
|
||||||
|
{
|
||||||
|
printf("static const %s rx_pulseshaper%s_%s[RX_PULSESHAPER%s_COEFF_SETS][%d] =\n",
|
||||||
|
(fixed_point) ? "int16_t" : "float",
|
||||||
|
tag,
|
||||||
|
(k == 0) ? "re" : "im",
|
||||||
|
tag,
|
||||||
|
coeffs_per_filter);
|
||||||
|
printf("{\n");
|
||||||
|
for (j = 0; j < coeff_sets; j++)
|
||||||
|
{
|
||||||
|
/* Complex modulate the filter, to make it a complex pulse shaping bandpass filter
|
||||||
|
centred at the nominal carrier frequency. Use the same phase for all the coefficient
|
||||||
|
sets. This means the modem can step the carrier in whole samples, and not worry about
|
||||||
|
the fractional sample shift caused by selecting amongst the various coefficient sets. */
|
||||||
|
for (i = 0; i < coeffs_per_filter; i++)
|
||||||
|
{
|
||||||
|
m = i - (coeffs_per_filter >> 1);
|
||||||
|
x = i*coeff_sets + j;
|
||||||
|
if (k == 0)
|
||||||
|
cox[i] = coeffs[x]*cos(carrier*m);
|
||||||
|
else
|
||||||
|
cox[i] = coeffs[x]*sin(carrier*m);
|
||||||
|
}
|
||||||
|
printf(" {\n");
|
||||||
|
if (fixed_point)
|
||||||
|
printf(" %8d, /* Filter %d */\n", (int) cox[0], j);
|
||||||
|
else
|
||||||
|
printf(" %15.10ff, /* Filter %d */\n", cox[0], j);
|
||||||
|
for (i = 1; i < coeffs_per_filter - 1; i++)
|
||||||
|
{
|
||||||
|
if (fixed_point)
|
||||||
|
printf(" %8d,\n", (int) cox[i]);
|
||||||
|
else
|
||||||
|
printf(" %15.10ff,\n", cox[i]);
|
||||||
|
}
|
||||||
|
if (fixed_point)
|
||||||
|
printf(" %8d\n", (int) cox[i]);
|
||||||
|
else
|
||||||
|
printf(" %15.10ff\n", cox[i]);
|
||||||
|
if (j < coeff_sets - 1)
|
||||||
|
printf(" },\n");
|
||||||
|
else
|
||||||
|
printf(" }\n");
|
||||||
|
}
|
||||||
|
printf("};\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: noise.c,v 1.24 2008/08/17 14:18:11 steveu Exp $
|
* $Id: noise.c,v 1.25 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -45,7 +45,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/noise.h"
|
#include "spandsp/noise.h"
|
||||||
|
|
||||||
int16_t noise(noise_state_t *s)
|
int16_t noise(noise_state_t *s)
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: plc.c,v 1.22 2008/07/02 14:48:25 steveu Exp $
|
* $Id: plc.c,v 1.23 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -45,7 +45,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/plc.h"
|
#include "spandsp/plc.h"
|
||||||
|
|
||||||
/* We do a straight line fade to zero volume in 50ms when we are filling in for missing data. */
|
/* We do a straight line fade to zero volume in 50ms when we are filling in for missing data. */
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: sig_tone.c,v 1.24 2008/08/17 16:25:52 steveu Exp $
|
* $Id: sig_tone.c,v 1.25 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -48,6 +48,7 @@
|
|||||||
#undef SPANDSP_USE_FIXED_POINT
|
#undef SPANDSP_USE_FIXED_POINT
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/dc_restore.h"
|
#include "spandsp/dc_restore.h"
|
||||||
|
#include "spandsp/saturated.h"
|
||||||
#include "spandsp/complex.h"
|
#include "spandsp/complex.h"
|
||||||
#include "spandsp/dds.h"
|
#include "spandsp/dds.h"
|
||||||
#include "spandsp/sig_tone.h"
|
#include "spandsp/sig_tone.h"
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: spandsp.h.in,v 1.10 2008/09/01 16:07:34 steveu Exp $
|
* $Id: spandsp.h.in,v 1.11 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -69,6 +69,7 @@
|
|||||||
#include <spandsp/hdlc.h>
|
#include <spandsp/hdlc.h>
|
||||||
#include <spandsp/async.h>
|
#include <spandsp/async.h>
|
||||||
#include <spandsp/noise.h>
|
#include <spandsp/noise.h>
|
||||||
|
#include <spandsp/saturated.h>
|
||||||
#include <spandsp/time_scale.h>
|
#include <spandsp/time_scale.h>
|
||||||
#include <spandsp/tone_detect.h>
|
#include <spandsp/tone_detect.h>
|
||||||
#include <spandsp/tone_generate.h>
|
#include <spandsp/tone_generate.h>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: complex_vector_float.h,v 1.8 2008/04/17 14:27:00 steveu Exp $
|
* $Id: complex_vector_float.h,v 1.10 2008/09/18 13:16:49 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(_SPANDSP_COMPLEX_VECTOR_FLOAT_H_)
|
#if !defined(_SPANDSP_COMPLEX_VECTOR_FLOAT_H_)
|
||||||
@ -120,6 +120,42 @@ static __inline__ void cvec_setl(complexl_t z[], complexl_t *x, int n)
|
|||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two complex float vectors.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
complexf_t cvec_dot_prodf(const complexf_t x[], const complexf_t y[], int n);
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two complex double vectors.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
complex_t cvec_dot_prod(const complex_t x[], const complex_t y[], int n);
|
||||||
|
|
||||||
|
#if defined(HAVE_LONG_DOUBLE)
|
||||||
|
/*! \brief Find the dot product of two complex long double vectors.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
complexl_t cvec_dot_prodl(const complexl_t x[], const complexl_t y[], int n);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two complex float vectors, where the first is a circular buffer
|
||||||
|
with an offset for the starting position.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\param pos The starting position in the x vector.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
complexf_t cvec_circular_dot_prodf(const complexf_t x[], const complexf_t y[], int n, int pos);
|
||||||
|
|
||||||
|
void cvec_lmsf(const complexf_t x[], complexf_t y[], int n, const complexf_t *error);
|
||||||
|
|
||||||
|
void cvec_circular_lmsf(const complexf_t x[], complexf_t y[], int n, int pos, const complexf_t *error);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: complex_vector_int.h,v 1.1 2008/09/01 16:07:34 steveu Exp $
|
* $Id: complex_vector_int.h,v 1.3 2008/09/18 13:16:49 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(_SPANDSP_COMPLEX_VECTOR_INT_H_)
|
#if !defined(_SPANDSP_COMPLEX_VECTOR_INT_H_)
|
||||||
@ -96,6 +96,33 @@ static __inline__ void cvec_seti32(complexi32_t z[], complexi32_t *x, int n)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two complex int16_t vectors.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
complexi32_t cvec_dot_prodi16(const complexi16_t x[], const complexi16_t y[], int n);
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two complex int32_t vectors.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
complexi32_t cvec_dot_prodi32(const complexi32_t x[], const complexi32_t y[], int n);
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two complex int16_t vectors, where the first is a circular buffer
|
||||||
|
with an offset for the starting position.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\param pos The starting position in the x vector.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
complexi32_t cvec_circular_dot_prodi16(const complexi16_t x[], const complexi16_t y[], int n, int pos);
|
||||||
|
|
||||||
|
void cvec_lmsi16(const complexi16_t x[], complexi16_t y[], int n, const complexi16_t *error);
|
||||||
|
|
||||||
|
void cvec_circular_lmsi16(const complexi16_t x[], complexi16_t y[], int n, int pos, const complexi16_t *error);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: dc_restore.h,v 1.23 2008/08/16 14:59:50 steveu Exp $
|
* $Id: dc_restore.h,v 1.24 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -85,60 +85,6 @@ static __inline__ int16_t dc_restore_estimate(dc_restore_state_t *dc)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int16_t saturate(int32_t amp)
|
|
||||||
{
|
|
||||||
int16_t amp16;
|
|
||||||
|
|
||||||
/* Hopefully this is optimised for the common case - not clipping */
|
|
||||||
amp16 = (int16_t) amp;
|
|
||||||
if (amp == amp16)
|
|
||||||
return amp16;
|
|
||||||
if (amp > INT16_MAX)
|
|
||||||
return INT16_MAX;
|
|
||||||
return INT16_MIN;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ int16_t fsaturatef(float famp)
|
|
||||||
{
|
|
||||||
if (famp > 32767.0f)
|
|
||||||
return INT16_MAX;
|
|
||||||
if (famp < -32768.0f)
|
|
||||||
return INT16_MIN;
|
|
||||||
return (int16_t) rintf(famp);
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ int16_t fsaturate(double damp)
|
|
||||||
{
|
|
||||||
if (damp > 32767.0)
|
|
||||||
return INT16_MAX;
|
|
||||||
if (damp < -32768.0)
|
|
||||||
return INT16_MIN;
|
|
||||||
return (int16_t) rint(damp);
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ float ffsaturatef(float famp)
|
|
||||||
{
|
|
||||||
if (famp > 32767.0f)
|
|
||||||
return (float) INT16_MAX;
|
|
||||||
if (famp < -32768.0f)
|
|
||||||
return (float) INT16_MIN;
|
|
||||||
return famp;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ double ffsaturate(double famp)
|
|
||||||
{
|
|
||||||
if (famp > 32767.0)
|
|
||||||
return (double) INT16_MAX;
|
|
||||||
if (famp < -32768.0)
|
|
||||||
return (double) INT16_MIN;
|
|
||||||
return famp;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
* Computer Science, Speech Group
|
* Computer Science, Speech Group
|
||||||
* Chengxiang Lu and Alex Hauptmann
|
* Chengxiang Lu and Alex Hauptmann
|
||||||
*
|
*
|
||||||
* $Id: g722.h,v 1.19 2008/04/17 14:27:00 steveu Exp $
|
* $Id: g722.h,v 1.20 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -56,6 +56,20 @@ enum
|
|||||||
G722_PACKED = 0x0002
|
G722_PACKED = 0x0002
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*! The per band parameters for both encoding and decoding G.722 */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int16_t s;
|
||||||
|
int16_t sz;
|
||||||
|
int16_t r[3];
|
||||||
|
int16_t a[3];
|
||||||
|
int16_t p[3];
|
||||||
|
int16_t d[7];
|
||||||
|
int16_t b[7];
|
||||||
|
int16_t nb;
|
||||||
|
int16_t det;
|
||||||
|
} g722_band_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/*! TRUE if the operating in the special ITU test mode, with the band split filters
|
/*! TRUE if the operating in the special ITU test mode, with the band split filters
|
||||||
@ -69,28 +83,15 @@ typedef struct
|
|||||||
int bits_per_sample;
|
int bits_per_sample;
|
||||||
|
|
||||||
/*! Signal history for the QMF */
|
/*! Signal history for the QMF */
|
||||||
int x[24];
|
int16_t x[12];
|
||||||
|
int16_t y[12];
|
||||||
|
int ptr;
|
||||||
|
|
||||||
struct
|
g722_band_t band[2];
|
||||||
{
|
|
||||||
int s;
|
|
||||||
int sp;
|
|
||||||
int sz;
|
|
||||||
int r[3];
|
|
||||||
int a[3];
|
|
||||||
int ap[3];
|
|
||||||
int p[3];
|
|
||||||
int d[7];
|
|
||||||
int b[7];
|
|
||||||
int bp[7];
|
|
||||||
int sg[7];
|
|
||||||
int nb;
|
|
||||||
int det;
|
|
||||||
} band[2];
|
|
||||||
|
|
||||||
unsigned int in_buffer;
|
uint32_t in_buffer;
|
||||||
int in_bits;
|
int in_bits;
|
||||||
unsigned int out_buffer;
|
uint32_t out_buffer;
|
||||||
int out_bits;
|
int out_bits;
|
||||||
} g722_encode_state_t;
|
} g722_encode_state_t;
|
||||||
|
|
||||||
@ -107,28 +108,15 @@ typedef struct
|
|||||||
int bits_per_sample;
|
int bits_per_sample;
|
||||||
|
|
||||||
/*! Signal history for the QMF */
|
/*! Signal history for the QMF */
|
||||||
int x[24];
|
int16_t x[12];
|
||||||
|
int16_t y[12];
|
||||||
|
int ptr;
|
||||||
|
|
||||||
struct
|
g722_band_t band[2];
|
||||||
{
|
|
||||||
int s;
|
|
||||||
int sp;
|
|
||||||
int sz;
|
|
||||||
int r[3];
|
|
||||||
int a[3];
|
|
||||||
int ap[3];
|
|
||||||
int p[3];
|
|
||||||
int d[7];
|
|
||||||
int b[7];
|
|
||||||
int bp[7];
|
|
||||||
int sg[7];
|
|
||||||
int nb;
|
|
||||||
int det;
|
|
||||||
} band[2];
|
|
||||||
|
|
||||||
unsigned int in_buffer;
|
uint32_t in_buffer;
|
||||||
int in_bits;
|
int in_bits;
|
||||||
unsigned int out_buffer;
|
uint32_t out_buffer;
|
||||||
int out_bits;
|
int out_bits;
|
||||||
} g722_decode_state_t;
|
} g722_decode_state_t;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: v17rx.h,v 1.54 2008/09/16 13:02:05 steveu Exp $
|
* $Id: v17rx.h,v 1.57 2008/09/18 14:59:30 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -213,9 +213,8 @@ TCM absolutely transformed the phone line modem business.
|
|||||||
|
|
||||||
/* Target length for the equalizer is about 63 taps, to deal with the worst stuff
|
/* Target length for the equalizer is about 63 taps, to deal with the worst stuff
|
||||||
in V.56bis. */
|
in V.56bis. */
|
||||||
#define V17_EQUALIZER_PRE_LEN 7 /* this much before the real event */
|
#define V17_EQUALIZER_PRE_LEN 8 /* This much before the real event */
|
||||||
#define V17_EQUALIZER_POST_LEN 7 /* this much after the real event */
|
#define V17_EQUALIZER_POST_LEN 8 /* This much after the real event (must be even) */
|
||||||
#define V17_EQUALIZER_MASK 63 /* one less than a power of 2 >= (V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN) */
|
|
||||||
|
|
||||||
#define V17_RX_FILTER_STEPS 27
|
#define V17_RX_FILTER_STEPS 27
|
||||||
|
|
||||||
@ -253,9 +252,9 @@ typedef struct
|
|||||||
|
|
||||||
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
|
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
int16_t rrc_filter[2*V17_RX_FILTER_STEPS];
|
int16_t rrc_filter[V17_RX_FILTER_STEPS];
|
||||||
#else
|
#else
|
||||||
float rrc_filter[2*V17_RX_FILTER_STEPS];
|
float rrc_filter[V17_RX_FILTER_STEPS];
|
||||||
#endif
|
#endif
|
||||||
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
|
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
|
||||||
int rrc_filter_step;
|
int rrc_filter_step;
|
||||||
@ -332,7 +331,7 @@ typedef struct
|
|||||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||||
complexi16_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
complexi16_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||||
/*! \brief The equalizer signal buffer. */
|
/*! \brief The equalizer signal buffer. */
|
||||||
complexi16_t eq_buf[V17_EQUALIZER_MASK + 1];
|
complexi16_t eq_buf[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||||
|
|
||||||
/*! Low band edge filter for symbol sync. */
|
/*! Low band edge filter for symbol sync. */
|
||||||
int32_t symbol_sync_low[2];
|
int32_t symbol_sync_low[2];
|
||||||
@ -355,7 +354,7 @@ typedef struct
|
|||||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||||
complexf_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
complexf_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||||
/*! \brief The equalizer signal buffer. */
|
/*! \brief The equalizer signal buffer. */
|
||||||
complexf_t eq_buf[V17_EQUALIZER_MASK + 1];
|
complexf_t eq_buf[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||||
|
|
||||||
/*! Low band edge filter for symbol sync. */
|
/*! Low band edge filter for symbol sync. */
|
||||||
float symbol_sync_low[2];
|
float symbol_sync_low[2];
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: v27ter_rx.h,v 1.51 2008/09/16 14:12:23 steveu Exp $
|
* $Id: v27ter_rx.h,v 1.53 2008/09/18 14:59:30 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -48,9 +48,8 @@ straightforward.
|
|||||||
|
|
||||||
/* Target length for the equalizer is about 43 taps for 4800bps and 32 taps for 2400bps
|
/* Target length for the equalizer is about 43 taps for 4800bps and 32 taps for 2400bps
|
||||||
to deal with the worst stuff in V.56bis. */
|
to deal with the worst stuff in V.56bis. */
|
||||||
#define V27TER_EQUALIZER_PRE_LEN 15 /* this much before the real event */
|
#define V27TER_EQUALIZER_PRE_LEN 16 /* This much before the real event */
|
||||||
#define V27TER_EQUALIZER_POST_LEN 15 /* this much after the real event */
|
#define V27TER_EQUALIZER_POST_LEN 14 /* This much after the real event (must be even) */
|
||||||
#define V27TER_EQUALIZER_MASK 63 /* one less than a power of 2 >= (V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN) */
|
|
||||||
|
|
||||||
#define V27TER_RX_4800_FILTER_STEPS 27
|
#define V27TER_RX_4800_FILTER_STEPS 27
|
||||||
#define V27TER_RX_2400_FILTER_STEPS 27
|
#define V27TER_RX_2400_FILTER_STEPS 27
|
||||||
@ -88,9 +87,9 @@ typedef struct
|
|||||||
|
|
||||||
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
|
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
int16_t rrc_filter[2*V27TER_RX_FILTER_STEPS];
|
int16_t rrc_filter[V27TER_RX_FILTER_STEPS];
|
||||||
#else
|
#else
|
||||||
float rrc_filter[2*V27TER_RX_FILTER_STEPS];
|
float rrc_filter[V27TER_RX_FILTER_STEPS];
|
||||||
#endif
|
#endif
|
||||||
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
|
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
|
||||||
int rrc_filter_step;
|
int rrc_filter_step;
|
||||||
@ -174,7 +173,7 @@ typedef struct
|
|||||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||||
/*complexi16_t*/ complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
/*complexi16_t*/ complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||||
/*! \brief The equalizer signal buffer. */
|
/*! \brief The equalizer signal buffer. */
|
||||||
/*complexi16_t*/ complexf_t eq_buf[V27TER_EQUALIZER_MASK + 1];
|
/*complexi16_t*/ complexf_t eq_buf[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||||
#else
|
#else
|
||||||
/*! \brief The scaling factor accessed by the AGC algorithm. */
|
/*! \brief The scaling factor accessed by the AGC algorithm. */
|
||||||
float agc_scaling;
|
float agc_scaling;
|
||||||
@ -188,7 +187,7 @@ typedef struct
|
|||||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||||
complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||||
/*! \brief The equalizer signal buffer. */
|
/*! \brief The equalizer signal buffer. */
|
||||||
complexf_t eq_buf[V27TER_EQUALIZER_MASK + 1];
|
complexf_t eq_buf[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \brief Integration variable for damping the Gardner algorithm tests. */
|
/*! \brief Integration variable for damping the Gardner algorithm tests. */
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: v29rx.h,v 1.62 2008/09/16 14:12:23 steveu Exp $
|
* $Id: v29rx.h,v 1.64 2008/09/18 14:59:30 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -122,9 +122,8 @@ therefore, only tests that bits starting at bit 24 are really ones.
|
|||||||
|
|
||||||
/* Target length for the equalizer is about 63 taps, to deal with the worst stuff
|
/* Target length for the equalizer is about 63 taps, to deal with the worst stuff
|
||||||
in V.56bis. */
|
in V.56bis. */
|
||||||
#define V29_EQUALIZER_PRE_LEN 15 /* this much before the real event */
|
#define V29_EQUALIZER_PRE_LEN 16 /* This much before the real event */
|
||||||
#define V29_EQUALIZER_POST_LEN 15 /* this much after the real event */
|
#define V29_EQUALIZER_POST_LEN 14 /* This much after the real event (must be even) */
|
||||||
#define V29_EQUALIZER_MASK 63 /* one less than a power of 2 >= (2*V29_EQUALIZER_LEN + 1) */
|
|
||||||
|
|
||||||
#define V29_RX_FILTER_STEPS 27
|
#define V29_RX_FILTER_STEPS 27
|
||||||
|
|
||||||
@ -157,9 +156,9 @@ typedef struct
|
|||||||
|
|
||||||
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
|
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
int16_t rrc_filter[2*V29_RX_FILTER_STEPS];
|
int16_t rrc_filter[V29_RX_FILTER_STEPS];
|
||||||
#else
|
#else
|
||||||
float rrc_filter[2*V29_RX_FILTER_STEPS];
|
float rrc_filter[V29_RX_FILTER_STEPS];
|
||||||
#endif
|
#endif
|
||||||
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
|
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
|
||||||
int rrc_filter_step;
|
int rrc_filter_step;
|
||||||
@ -242,7 +241,7 @@ typedef struct
|
|||||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||||
complexi16_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
complexi16_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||||
/*! \brief The equalizer signal buffer. */
|
/*! \brief The equalizer signal buffer. */
|
||||||
complexi16_t eq_buf[V29_EQUALIZER_MASK + 1];
|
complexi16_t eq_buf[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||||
|
|
||||||
/*! Low band edge filter for symbol sync. */
|
/*! Low band edge filter for symbol sync. */
|
||||||
int32_t symbol_sync_low[2];
|
int32_t symbol_sync_low[2];
|
||||||
@ -265,7 +264,7 @@ typedef struct
|
|||||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||||
complexf_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
complexf_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||||
/*! \brief The equalizer signal buffer. */
|
/*! \brief The equalizer signal buffer. */
|
||||||
complexf_t eq_buf[V29_EQUALIZER_MASK + 1];
|
complexf_t eq_buf[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||||
|
|
||||||
/*! Low band edge filter for symbol sync. */
|
/*! Low band edge filter for symbol sync. */
|
||||||
float symbol_sync_low[2];
|
float symbol_sync_low[2];
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: vector_float.h,v 1.11 2008/09/01 16:07:34 steveu Exp $
|
* $Id: vector_float.h,v 1.13 2008/09/18 13:54:32 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(_SPANDSP_VECTOR_FLOAT_H_)
|
#if !defined(_SPANDSP_VECTOR_FLOAT_H_)
|
||||||
@ -128,6 +128,19 @@ double vec_dot_prod(const double x[], const double y[], int n);
|
|||||||
long double vec_dot_prodl(const long double x[], const long double y[], int n);
|
long double vec_dot_prodl(const long double x[], const long double y[], int n);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two float vectors, where the first is a circular buffer
|
||||||
|
with an offset for the starting position.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\param pos The starting position in the x vector.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
float vec_circular_dot_prodf(const float x[], const float y[], int n, int pos);
|
||||||
|
|
||||||
|
void vec_lmsf(const float x[], float y[], int n, float error);
|
||||||
|
|
||||||
|
void vec_circular_lmsf(const float x[], float y[], int n, int pos, float error);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: vector_int.h,v 1.11 2008/09/01 16:07:34 steveu Exp $
|
* $Id: vector_int.h,v 1.13 2008/09/18 13:54:32 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(_SPANDSP_VECTOR_INT_H_)
|
#if !defined(_SPANDSP_VECTOR_INT_H_)
|
||||||
@ -103,6 +103,19 @@ static __inline__ void vec_seti32(int32_t z[], int32_t x, int n)
|
|||||||
\return The dot product of the two vectors. */
|
\return The dot product of the two vectors. */
|
||||||
int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n);
|
int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n);
|
||||||
|
|
||||||
|
/*! \brief Find the dot product of two int16_t vectors, where the first is a circular buffer
|
||||||
|
with an offset for the starting position.
|
||||||
|
\param x The first vector.
|
||||||
|
\param y The first vector.
|
||||||
|
\param n The number of elements in the vectors.
|
||||||
|
\param pos The starting position in the x vector.
|
||||||
|
\return The dot product of the two vectors. */
|
||||||
|
int32_t vec_circular_dot_prodi16(const int16_t x[], const int16_t y[], int n, int pos);
|
||||||
|
|
||||||
|
void vec_lmsi16(const int16_t x[], int16_t y[], int n, int16_t error);
|
||||||
|
|
||||||
|
void vec_circular_lmsi16(const int16_t x[], int16_t y[], int n, int pos, int16_t error);
|
||||||
|
|
||||||
/*! \brief Find the minimum and maximum values in an int16_t vector.
|
/*! \brief Find the minimum and maximum values in an int16_t vector.
|
||||||
\param x The vector to be searched.
|
\param x The vector to be searched.
|
||||||
\param n The number of elements in the vector.
|
\param n The number of elements in the vector.
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
/* The date and time of the version are in UTC form. */
|
/* The date and time of the version are in UTC form. */
|
||||||
|
|
||||||
#define SPANDSP_RELEASE_DATE 20080916
|
#define SPANDSP_RELEASE_DATE 20080919
|
||||||
#define SPANDSP_RELEASE_TIME 152844
|
#define SPANDSP_RELEASE_TIME 142905
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/*- End of file ------------------------------------------------------------*/
|
/*- End of file ------------------------------------------------------------*/
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: time_scale.c,v 1.23 2008/07/28 15:14:30 steveu Exp $
|
* $Id: time_scale.c,v 1.24 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include "spandsp/telephony.h"
|
#include "spandsp/telephony.h"
|
||||||
#include "spandsp/time_scale.h"
|
#include "spandsp/time_scale.h"
|
||||||
|
#include "spandsp/saturated.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Time scaling for speech, based on the Pointer Interval Controlled
|
Time scaling for speech, based on the Pointer Interval Controlled
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: v17rx.c,v 1.118 2008/09/16 14:12:23 steveu Exp $
|
* $Id: v17rx.c,v 1.123 2008/09/18 15:59:55 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -48,6 +48,8 @@
|
|||||||
#include "spandsp/complex.h"
|
#include "spandsp/complex.h"
|
||||||
#include "spandsp/vector_float.h"
|
#include "spandsp/vector_float.h"
|
||||||
#include "spandsp/complex_vector_float.h"
|
#include "spandsp/complex_vector_float.h"
|
||||||
|
#include "spandsp/vector_int.h"
|
||||||
|
#include "spandsp/complex_vector_int.h"
|
||||||
#include "spandsp/async.h"
|
#include "spandsp/async.h"
|
||||||
#include "spandsp/power_meter.h"
|
#include "spandsp/power_meter.h"
|
||||||
#include "spandsp/arctan2.h"
|
#include "spandsp/arctan2.h"
|
||||||
@ -81,6 +83,8 @@
|
|||||||
|
|
||||||
#define V17_BRIDGE_WORD 0x8880
|
#define V17_BRIDGE_WORD 0x8880
|
||||||
|
|
||||||
|
#define V17_EQUALIZER_LEN (V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TRAINING_STAGE_NORMAL_OPERATION = 0,
|
TRAINING_STAGE_NORMAL_OPERATION = 0,
|
||||||
@ -149,16 +153,16 @@ int v17_rx_equalizer_state(v17_rx_state_t *s, complexf_t **coeffs)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
*coeffs = s->eq_coeff;
|
*coeffs = s->eq_coeff;
|
||||||
return V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN;
|
return V17_EQUALIZER_LEN;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static void equalizer_save(v17_rx_state_t *s)
|
static void equalizer_save(v17_rx_state_t *s)
|
||||||
{
|
{
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V17_EQUALIZER_LEN);
|
||||||
#else
|
#else
|
||||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V17_EQUALIZER_LEN);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -166,13 +170,13 @@ static void equalizer_save(v17_rx_state_t *s)
|
|||||||
static void equalizer_restore(v17_rx_state_t *s)
|
static void equalizer_restore(v17_rx_state_t *s)
|
||||||
{
|
{
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V17_EQUALIZER_LEN);
|
||||||
cvec_zeroi16(s->eq_buf, V17_EQUALIZER_MASK);
|
cvec_zeroi16(s->eq_buf, V17_EQUALIZER_LEN);
|
||||||
s->eq_delta = 32768.0f*EQUALIZER_SLOW_ADAPT_RATIO*EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
s->eq_delta = 32768.0f*EQUALIZER_SLOW_ADAPT_RATIO*EQUALIZER_DELTA/V17_EQUALIZER_LEN;
|
||||||
#else
|
#else
|
||||||
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V17_EQUALIZER_LEN);
|
||||||
cvec_zerof(s->eq_buf, V17_EQUALIZER_MASK);
|
cvec_zerof(s->eq_buf, V17_EQUALIZER_LEN);
|
||||||
s->eq_delta = EQUALIZER_SLOW_ADAPT_RATIO*EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
s->eq_delta = EQUALIZER_SLOW_ADAPT_RATIO*EQUALIZER_DELTA/V17_EQUALIZER_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
||||||
@ -184,15 +188,15 @@ static void equalizer_reset(v17_rx_state_t *s)
|
|||||||
{
|
{
|
||||||
/* Start with an equalizer based on everything being perfect */
|
/* Start with an equalizer based on everything being perfect */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
cvec_zeroi16(s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
cvec_zeroi16(s->eq_coeff, V17_EQUALIZER_LEN);
|
||||||
s->eq_coeff[V17_EQUALIZER_PRE_LEN] = complex_seti16(3*FP_FACTOR, 0);
|
s->eq_coeff[V17_EQUALIZER_PRE_LEN] = complex_seti16(3*FP_FACTOR, 0);
|
||||||
cvec_zeroi16(s->eq_buf, V17_EQUALIZER_MASK);
|
cvec_zeroi16(s->eq_buf, V17_EQUALIZER_LEN);
|
||||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
s->eq_delta = 32768.0f*EQUALIZER_DELTA/V17_EQUALIZER_LEN;
|
||||||
#else
|
#else
|
||||||
cvec_zerof(s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
cvec_zerof(s->eq_coeff, V17_EQUALIZER_LEN);
|
||||||
s->eq_coeff[V17_EQUALIZER_PRE_LEN] = complex_setf(3.0f, 0.0f);
|
s->eq_coeff[V17_EQUALIZER_PRE_LEN] = complex_setf(3.0f, 0.0f);
|
||||||
cvec_zerof(s->eq_buf, V17_EQUALIZER_MASK);
|
cvec_zerof(s->eq_buf, V17_EQUALIZER_LEN);
|
||||||
s->eq_delta = EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN);
|
s->eq_delta = EQUALIZER_DELTA/V17_EQUALIZER_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
||||||
@ -206,21 +210,7 @@ static __inline__ complexi16_t equalizer_get(v17_rx_state_t *s)
|
|||||||
static __inline__ complexf_t equalizer_get(v17_rx_state_t *s)
|
static __inline__ complexf_t equalizer_get(v17_rx_state_t *s)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
return cvec_circular_dot_prodf(s->eq_buf, s->eq_coeff, V17_EQUALIZER_LEN, s->eq_step);
|
||||||
int p;
|
|
||||||
complexf_t z;
|
|
||||||
complexf_t z1;
|
|
||||||
|
|
||||||
/* Get the next equalized value. */
|
|
||||||
z = complex_setf(0.0f, 0.0f);
|
|
||||||
p = s->eq_step - 1;
|
|
||||||
for (i = 0; i < V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN; i++)
|
|
||||||
{
|
|
||||||
p = (p - 1) & V17_EQUALIZER_MASK;
|
|
||||||
z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]);
|
|
||||||
z = complex_addf(&z, &z1);
|
|
||||||
}
|
|
||||||
return z;
|
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -230,28 +220,18 @@ static void tune_equalizer(v17_rx_state_t *s, const complexi16_t *z, const compl
|
|||||||
static void tune_equalizer(v17_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
static void tune_equalizer(v17_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
complexf_t err;
|
||||||
int p;
|
|
||||||
complexf_t ez;
|
|
||||||
complexf_t z1;
|
|
||||||
|
|
||||||
/* Find the x and y mismatch from the exact constellation position. */
|
/* Find the x and y mismatch from the exact constellation position. */
|
||||||
ez = complex_subf(target, z);
|
err = complex_subf(target, z);
|
||||||
//span_log(&s->logging, SPAN_LOG_FLOW, "Equalizer error %f\n", sqrt(ez.re*ez.re + ez.im*ez.im));
|
//span_log(&s->logging, SPAN_LOG_FLOW, "Equalizer error %f\n", sqrt(ez.re*ez.re + ez.im*ez.im));
|
||||||
ez.re *= s->eq_delta;
|
err.re *= s->eq_delta;
|
||||||
ez.im *= s->eq_delta;
|
err.im *= s->eq_delta;
|
||||||
|
|
||||||
p = s->eq_step - 1;
|
err = complex_subf(target, z);
|
||||||
for (i = 0; i < V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN; i++)
|
err.re *= s->eq_delta;
|
||||||
{
|
err.im *= s->eq_delta;
|
||||||
p = (p - 1) & V17_EQUALIZER_MASK;
|
cvec_circular_lmsf(s->eq_buf, s->eq_coeff, V17_EQUALIZER_LEN, s->eq_step, &err);
|
||||||
z1 = complex_conjf(&s->eq_buf[p]);
|
|
||||||
z1 = complex_mulf(&ez, &z1);
|
|
||||||
s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1);
|
|
||||||
/* Leak a little to tame uncontrolled wandering */
|
|
||||||
s->eq_coeff[i].re *= 0.9999f;
|
|
||||||
s->eq_coeff[i].im *= 0.9999f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -565,7 +545,8 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
|||||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||||
at this time. */
|
at this time. */
|
||||||
s->eq_buf[s->eq_step] = *sample;
|
s->eq_buf[s->eq_step] = *sample;
|
||||||
s->eq_step = (s->eq_step + 1) & V17_EQUALIZER_MASK;
|
if (++s->eq_step >= V17_EQUALIZER_LEN)
|
||||||
|
s->eq_step = 0;
|
||||||
|
|
||||||
/* On alternate insertions we have a whole baud and must process it. */
|
/* On alternate insertions we have a whole baud and must process it. */
|
||||||
if ((s->baud_half ^= 1))
|
if ((s->baud_half ^= 1))
|
||||||
@ -628,7 +609,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
|||||||
p = 3.14159f + angle*2.0f*3.14159f/(65536.0f*65536.0f) - 0.321751f;
|
p = 3.14159f + angle*2.0f*3.14159f/(65536.0f*65536.0f) - 0.321751f;
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Spin (short) by %.5f rads\n", p);
|
span_log(&s->logging, SPAN_LOG_FLOW, "Spin (short) by %.5f rads\n", p);
|
||||||
zz = complex_setf(cosf(p), -sinf(p));
|
zz = complex_setf(cosf(p), -sinf(p));
|
||||||
for (i = 0; i <= V17_EQUALIZER_MASK; i++)
|
for (i = 0; i < V17_EQUALIZER_LEN; i++)
|
||||||
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
||||||
s->carrier_phase += (0x80000000 + angle - 219937506);
|
s->carrier_phase += (0x80000000 + angle - 219937506);
|
||||||
|
|
||||||
@ -716,7 +697,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
|||||||
p = angle*2.0f*3.14159f/(65536.0f*65536.0f) - 0.321751f;
|
p = angle*2.0f*3.14159f/(65536.0f*65536.0f) - 0.321751f;
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Spin (long) by %.5f rads\n", p);
|
span_log(&s->logging, SPAN_LOG_FLOW, "Spin (long) by %.5f rads\n", p);
|
||||||
zz = complex_setf(cosf(p), -sinf(p));
|
zz = complex_setf(cosf(p), -sinf(p));
|
||||||
for (i = 0; i <= V17_EQUALIZER_MASK; i++)
|
for (i = 0; i < V17_EQUALIZER_LEN; i++)
|
||||||
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
||||||
s->carrier_phase += (angle - 219937506);
|
s->carrier_phase += (angle - 219937506);
|
||||||
|
|
||||||
@ -960,7 +941,6 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
|||||||
int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
|
||||||
int step;
|
int step;
|
||||||
int16_t x;
|
int16_t x;
|
||||||
int32_t diff;
|
int32_t diff;
|
||||||
@ -968,15 +948,18 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
complexf_t zz;
|
complexf_t zz;
|
||||||
complexf_t sample;
|
complexf_t sample;
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
complexi_t zi;
|
int32_t vi;
|
||||||
|
#endif
|
||||||
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
|
int32_t v;
|
||||||
|
#else
|
||||||
|
float v;
|
||||||
#endif
|
#endif
|
||||||
int32_t power;
|
int32_t power;
|
||||||
float v;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
s->rrc_filter[s->rrc_filter_step] =
|
s->rrc_filter[s->rrc_filter_step] = amp[i];
|
||||||
s->rrc_filter[s->rrc_filter_step + V17_RX_FILTER_STEPS] = amp[i];
|
|
||||||
if (++s->rrc_filter_step >= V17_RX_FILTER_STEPS)
|
if (++s->rrc_filter_step >= V17_RX_FILTER_STEPS)
|
||||||
s->rrc_filter_step = 0;
|
s->rrc_filter_step = 0;
|
||||||
|
|
||||||
@ -1052,17 +1035,13 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
if (step < 0)
|
if (step < 0)
|
||||||
step += RX_PULSESHAPER_COEFF_SETS;
|
step += RX_PULSESHAPER_COEFF_SETS;
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
zi.re = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
vi = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_re[step], V17_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V17_RX_FILTER_STEPS; j++)
|
//sample.re = (vi*(int32_t) s->agc_scaling) >> 15;
|
||||||
zi.re += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
sample.re = vi*s->agc_scaling;
|
||||||
sample.re = zi.re*s->agc_scaling;
|
|
||||||
#else
|
#else
|
||||||
zz.re = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_re[step], V17_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V17_RX_FILTER_STEPS; j++)
|
sample.re = v*s->agc_scaling;
|
||||||
zz.re += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
sample.re = zz.re*s->agc_scaling;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Symbol timing synchronisation band edge filters */
|
/* Symbol timing synchronisation band edge filters */
|
||||||
/* Low Nyquist band edge filter */
|
/* Low Nyquist band edge filter */
|
||||||
v = s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0 + s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1 + sample.re;
|
v = s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0 + s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1 + sample.re;
|
||||||
@ -1087,27 +1066,22 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
step = -s->eq_put_step;
|
step = -s->eq_put_step;
|
||||||
if (step > RX_PULSESHAPER_COEFF_SETS - 1)
|
if (step > RX_PULSESHAPER_COEFF_SETS - 1)
|
||||||
step = RX_PULSESHAPER_COEFF_SETS - 1;
|
step = RX_PULSESHAPER_COEFF_SETS - 1;
|
||||||
|
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
zi.im = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
vi = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_im[step], V17_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V17_RX_FILTER_STEPS; j++)
|
//sample.im = (vi*(int32_t) s->agc_scaling) >> 15;
|
||||||
zi.im += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
sample.im = vi*s->agc_scaling;
|
||||||
sample.im = zi.im*s->agc_scaling;
|
|
||||||
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
|
||||||
z = dds_lookup_complexf(s->carrier_phase);
|
z = dds_lookup_complexf(s->carrier_phase);
|
||||||
zz.re = sample.re*z.re - sample.im*z.im;
|
zz.re = sample.re*z.re - sample.im*z.im;
|
||||||
zz.im = -sample.re*z.im - sample.im*z.re;
|
zz.im = -sample.re*z.im - sample.im*z.re;
|
||||||
process_half_baud(s, &zz);
|
|
||||||
#else
|
#else
|
||||||
zz.im = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_im[step], V17_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V17_RX_FILTER_STEPS; j++)
|
sample.im = v*s->agc_scaling;
|
||||||
zz.im += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
sample.im = zz.im*s->agc_scaling;
|
|
||||||
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
|
||||||
z = dds_lookup_complexf(s->carrier_phase);
|
z = dds_lookup_complexf(s->carrier_phase);
|
||||||
zz.re = sample.re*z.re - sample.im*z.im;
|
zz.re = sample.re*z.re - sample.im*z.im;
|
||||||
zz.im = -sample.re*z.im - sample.im*z.re;
|
zz.im = -sample.re*z.im - sample.im*z.re;
|
||||||
process_half_baud(s, &zz);
|
|
||||||
#endif
|
#endif
|
||||||
|
process_half_baud(s, &zz);
|
||||||
}
|
}
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
dds_advance(&s->carrier_phase, s->carrier_phase_rate);
|
dds_advance(&s->carrier_phase, s->carrier_phase_rate);
|
||||||
@ -1165,7 +1139,7 @@ int v17_rx_restart(v17_rx_state_t *s, int bit_rate, int short_train)
|
|||||||
}
|
}
|
||||||
s->bit_rate = bit_rate;
|
s->bit_rate = bit_rate;
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
memset(s->rrc_filter, 0, sizeof(s->rrc_filter));
|
vec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||||
#else
|
#else
|
||||||
vec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
vec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: v22bis_rx.c,v 1.41 2008/09/07 12:45:17 steveu Exp $
|
* $Id: v22bis_rx.c,v 1.42 2008/09/18 14:59:30 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -590,15 +590,15 @@ int v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len)
|
|||||||
/* TODO: get rid of this */
|
/* TODO: get rid of this */
|
||||||
if (s->caller)
|
if (s->caller)
|
||||||
{
|
{
|
||||||
ii = rx_pulseshaper_2400[6][0].re*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
ii = rx_pulseshaper_2400_re[6][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||||
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
||||||
ii += rx_pulseshaper_2400[6][j].re*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
ii += rx_pulseshaper_2400_re[6][j]*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ii = rx_pulseshaper_1200[6][0].re*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
ii = rx_pulseshaper_1200_re[6][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||||
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
||||||
ii += rx_pulseshaper_1200[6][j].re*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
ii += rx_pulseshaper_1200_re[6][j]*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
||||||
}
|
}
|
||||||
power = power_meter_update(&(s->rx.rx_power), (int16_t) (ii/10.0f));
|
power = power_meter_update(&(s->rx.rx_power), (int16_t) (ii/10.0f));
|
||||||
if (s->rx.signal_present)
|
if (s->rx.signal_present)
|
||||||
@ -643,22 +643,22 @@ int v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len)
|
|||||||
s->rx.eq_put_step += PULSESHAPER_COEFF_SETS*40/(3*2);
|
s->rx.eq_put_step += PULSESHAPER_COEFF_SETS*40/(3*2);
|
||||||
if (s->caller)
|
if (s->caller)
|
||||||
{
|
{
|
||||||
ii = rx_pulseshaper_2400[step][0].re*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
ii = rx_pulseshaper_2400_re[step][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||||
qq = rx_pulseshaper_2400[step][0].im*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
qq = rx_pulseshaper_2400_im[step][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||||
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
||||||
{
|
{
|
||||||
ii += rx_pulseshaper_2400[step][j].re*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
ii += rx_pulseshaper_2400_re[step][j]*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
||||||
qq += rx_pulseshaper_2400[step][j].im*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
qq += rx_pulseshaper_2400_im[step][j]*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ii = rx_pulseshaper_1200[step][0].re*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
ii = rx_pulseshaper_1200_re[step][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||||
qq = rx_pulseshaper_1200[step][0].im*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
qq = rx_pulseshaper_1200_im[step][0]*s->rx.rrc_filter[s->rx.rrc_filter_step];
|
||||||
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
for (j = 1; j < V22BIS_RX_FILTER_STEPS; j++)
|
||||||
{
|
{
|
||||||
ii += rx_pulseshaper_1200[step][j].re*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
ii += rx_pulseshaper_1200_re[step][j]*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
||||||
qq += rx_pulseshaper_1200[step][j].im*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
qq += rx_pulseshaper_1200_im[step][j]*s->rx.rrc_filter[j + s->rx.rrc_filter_step];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sample.re = ii*s->rx.agc_scaling;
|
sample.re = ii*s->rx.agc_scaling;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: v27ter_rx.c,v 1.104 2008/09/16 14:12:23 steveu Exp $
|
* $Id: v27ter_rx.c,v 1.107 2008/09/18 14:59:30 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -86,6 +86,8 @@
|
|||||||
#define V27TER_TRAINING_SEG_5_LEN 1074
|
#define V27TER_TRAINING_SEG_5_LEN 1074
|
||||||
#define V27TER_TRAINING_SEG_6_LEN 8
|
#define V27TER_TRAINING_SEG_6_LEN 8
|
||||||
|
|
||||||
|
#define V27TER_EQUALIZER_LEN (V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TRAINING_STAGE_NORMAL_OPERATION = 0,
|
TRAINING_STAGE_NORMAL_OPERATION = 0,
|
||||||
@ -168,16 +170,16 @@ int v27ter_rx_equalizer_state(v27ter_rx_state_t *s, complexf_t **coeffs)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
*coeffs = s->eq_coeff;
|
*coeffs = s->eq_coeff;
|
||||||
return V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN;
|
return V27TER_EQUALIZER_LEN;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static void equalizer_save(v27ter_rx_state_t *s)
|
static void equalizer_save(v27ter_rx_state_t *s)
|
||||||
{
|
{
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_LEN);
|
||||||
#else
|
#else
|
||||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_LEN);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -185,13 +187,13 @@ static void equalizer_save(v27ter_rx_state_t *s)
|
|||||||
static void equalizer_restore(v27ter_rx_state_t *s)
|
static void equalizer_restore(v27ter_rx_state_t *s)
|
||||||
{
|
{
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_LEN);
|
||||||
cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK);
|
cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_LEN);
|
||||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
s->eq_delta = 32768.0f*EQUALIZER_DELTA/V27TER_EQUALIZER_LEN);
|
||||||
#else
|
#else
|
||||||
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_LEN);
|
||||||
cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK);
|
cvec_zerof(s->eq_buf, V27TER_EQUALIZER_LEN);
|
||||||
s->eq_delta = EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
s->eq_delta = EQUALIZER_DELTA/V27TER_EQUALIZER_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
||||||
@ -203,15 +205,15 @@ static void equalizer_reset(v27ter_rx_state_t *s)
|
|||||||
{
|
{
|
||||||
/* Start with an equalizer based on everything being perfect. */
|
/* Start with an equalizer based on everything being perfect. */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
cvec_zeroi16(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
cvec_zeroi16(s->eq_coeff, V27TER_EQUALIZER_LEN);
|
||||||
s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_seti16(1.414f*FP_FACTOR, 0);
|
s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_seti16(1.414f*FP_FACTOR, 0);
|
||||||
cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK);
|
cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_LEN);
|
||||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
s->eq_delta = 32768.0f*EQUALIZER_DELTA/V27TER_EQUALIZER_LEN);
|
||||||
#else
|
#else
|
||||||
cvec_zerof(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
cvec_zerof(s->eq_coeff, V27TER_EQUALIZER_LEN);
|
||||||
s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_setf(1.414f, 0.0f);
|
s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_setf(1.414f, 0.0f);
|
||||||
cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK);
|
cvec_zerof(s->eq_buf, V27TER_EQUALIZER_LEN);
|
||||||
s->eq_delta = EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
s->eq_delta = EQUALIZER_DELTA/V27TER_EQUALIZER_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
||||||
@ -237,36 +239,19 @@ static __inline__ complexi16_t equalizer_get(v27ter_rx_state_t *s)
|
|||||||
static __inline__ complexf_t equalizer_get(v27ter_rx_state_t *s)
|
static __inline__ complexf_t equalizer_get(v27ter_rx_state_t *s)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int p;
|
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
|
complexi32_t zz;
|
||||||
complexi16_t z;
|
complexi16_t z;
|
||||||
complexi16_t z1;
|
|
||||||
#else
|
|
||||||
complexf_t z;
|
|
||||||
complexf_t z1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get the next equalized value. */
|
/* Get the next equalized value. */
|
||||||
p = s->eq_step - 1;
|
zz = cvec_circular_dot_prodi16(s->eq_buf, s->eq_coeff, V27TER_EQUALIZER_LEN, s->eq_step);
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
z.re = zz.re >> FP_SHIFT_FACTOR;
|
||||||
z = complex_seti16(0, 0);
|
z.im = zz.im >> FP_SHIFT_FACTOR;
|
||||||
for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++)
|
|
||||||
{
|
|
||||||
p = (p - 1) & V27TER_EQUALIZER_MASK;
|
|
||||||
z1 = complex_mul_q4_12(&s->eq_coeff[i], &s->eq_buf[p]);
|
|
||||||
z = complex_addi16(&z, &z1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
z = complex_setf(0.0f, 0.0f);
|
|
||||||
for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++)
|
|
||||||
{
|
|
||||||
p = (p - 1) & V27TER_EQUALIZER_MASK;
|
|
||||||
z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]);
|
|
||||||
z = complex_addf(&z, &z1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return z;
|
return z;
|
||||||
|
#else
|
||||||
|
/* Get the next equalized value. */
|
||||||
|
return cvec_circular_dot_prodf(s->eq_buf, s->eq_coeff, V27TER_EQUALIZER_LEN, s->eq_step);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -276,45 +261,24 @@ static void tune_equalizer(v27ter_rx_state_t *s, const complexi16_t *z, const co
|
|||||||
static void tune_equalizer(v27ter_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
static void tune_equalizer(v27ter_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int p;
|
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
complexi16_t ez;
|
complexi16_t err;
|
||||||
complexi16_t z1;
|
|
||||||
#else
|
|
||||||
complexf_t ez;
|
|
||||||
complexf_t z1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Find the x and y mismatch from the exact constellation position. */
|
/* Find the x and y mismatch from the exact constellation position. */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
err.re = target->re*FP_FACTOR - z->re;
|
||||||
ez.re = target->re*FP_FACTOR - z->re;
|
err.im = target->im*FP_FACTOR - z->im;
|
||||||
ez.im = target->im*FP_FACTOR - z->im;
|
err.re = ((int32_t) err.re*(int32_t) s->eq_delta) >> 15;
|
||||||
ez.re = ((int32_t) ez.re*(int32_t) s->eq_delta) >> 15;
|
err.im = ((int32_t) err.im*(int32_t) s->eq_delta) >> 15;
|
||||||
ez.im = ((int32_t) ez.im*(int32_t) s->eq_delta) >> 15;
|
cvec_circular_lmsi16(s->eq_buf, s->eq_coeff, V27TER_EQUALIZER_LEN, s->eq_step, &err);
|
||||||
#else
|
#else
|
||||||
ez = complex_subf(target, z);
|
complexf_t err;
|
||||||
ez.re *= s->eq_delta;
|
|
||||||
ez.im *= s->eq_delta;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
p = s->eq_step - 1;
|
/* Find the x and y mismatch from the exact constellation position. */
|
||||||
for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++)
|
err = complex_subf(target, z);
|
||||||
{
|
err.re *= s->eq_delta;
|
||||||
p = (p - 1) & V27TER_EQUALIZER_MASK;
|
err.im *= s->eq_delta;
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
cvec_circular_lmsf(s->eq_buf, s->eq_coeff, V27TER_EQUALIZER_LEN, s->eq_step, &err);
|
||||||
z1 = complex_conji16(&s->eq_buf[p]);
|
|
||||||
z1 = complex_mul_q4_12(&ez, &z1);
|
|
||||||
s->eq_coeff[i] = complex_addi16(&s->eq_coeff[i], &z1);
|
|
||||||
#else
|
|
||||||
z1 = complex_conjf(&s->eq_buf[p]);
|
|
||||||
z1 = complex_mulf(&ez, &z1);
|
|
||||||
s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1);
|
|
||||||
/* Leak a little to tame uncontrolled wandering */
|
|
||||||
s->eq_coeff[i].re *= 0.9999f;
|
|
||||||
s->eq_coeff[i].im *= 0.9999f;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -508,13 +472,13 @@ static __inline__ void symbol_sync(v27ter_rx_state_t *s)
|
|||||||
/* This routine adapts the position of the half baud samples entering the equalizer. */
|
/* This routine adapts the position of the half baud samples entering the equalizer. */
|
||||||
|
|
||||||
/* Perform a Gardner test for baud alignment */
|
/* Perform a Gardner test for baud alignment */
|
||||||
p = s->eq_buf[(s->eq_step - 3) & V27TER_EQUALIZER_MASK].re
|
p = s->eq_buf[(s->eq_step - 3) & V27TER_EQUALIZER_LEN].re
|
||||||
- s->eq_buf[(s->eq_step - 1) & V27TER_EQUALIZER_MASK].re;
|
- s->eq_buf[(s->eq_step - 1) & V27TER_EQUALIZER_LEN].re;
|
||||||
p *= s->eq_buf[(s->eq_step - 2) & V27TER_EQUALIZER_MASK].re;
|
p *= s->eq_buf[(s->eq_step - 2) & V27TER_EQUALIZER_LEN].re;
|
||||||
|
|
||||||
q = s->eq_buf[(s->eq_step - 3) & V27TER_EQUALIZER_MASK].im
|
q = s->eq_buf[(s->eq_step - 3) & V27TER_EQUALIZER_LEN].im
|
||||||
- s->eq_buf[(s->eq_step - 1) & V27TER_EQUALIZER_MASK].im;
|
- s->eq_buf[(s->eq_step - 1) & V27TER_EQUALIZER_LEN].im;
|
||||||
q *= s->eq_buf[(s->eq_step - 2) & V27TER_EQUALIZER_MASK].im;
|
q *= s->eq_buf[(s->eq_step - 2) & V27TER_EQUALIZER_LEN].im;
|
||||||
|
|
||||||
s->gardner_integrate += (p + q > 0.0f) ? s->gardner_step : -s->gardner_step;
|
s->gardner_integrate += (p + q > 0.0f) ? s->gardner_step : -s->gardner_step;
|
||||||
|
|
||||||
@ -560,7 +524,8 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
|||||||
#else
|
#else
|
||||||
s->eq_buf[s->eq_step] = *sample;
|
s->eq_buf[s->eq_step] = *sample;
|
||||||
#endif
|
#endif
|
||||||
s->eq_step = (s->eq_step + 1) & V27TER_EQUALIZER_MASK;
|
if (++s->eq_step >= V27TER_EQUALIZER_LEN)
|
||||||
|
s->eq_step = 0;
|
||||||
|
|
||||||
/* On alternate insertions we have a whole baud, and must process it. */
|
/* On alternate insertions we have a whole baud, and must process it. */
|
||||||
if ((s->baud_half ^= 1))
|
if ((s->baud_half ^= 1))
|
||||||
@ -642,7 +607,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
|||||||
p = angle*2.0f*3.14159f/(65536.0f*65536.0f);
|
p = angle*2.0f*3.14159f/(65536.0f*65536.0f);
|
||||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||||
zz = complex_setf(cosf(p), -sinf(p));
|
zz = complex_setf(cosf(p), -sinf(p));
|
||||||
for (i = 0; i <= V27TER_EQUALIZER_MASK; i++)
|
for (i = 0; i < V27TER_EQUALIZER_LEN; i++)
|
||||||
{
|
{
|
||||||
z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im);
|
z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im);
|
||||||
z1 = complex_mulf(&z1, &zz);
|
z1 = complex_mulf(&z1, &zz);
|
||||||
@ -651,7 +616,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
zz = complex_setf(cosf(p), -sinf(p));
|
zz = complex_setf(cosf(p), -sinf(p));
|
||||||
for (i = 0; i <= V27TER_EQUALIZER_MASK; i++)
|
for (i = 0; i < V27TER_EQUALIZER_LEN; i++)
|
||||||
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
||||||
#endif
|
#endif
|
||||||
s->carrier_phase += angle;
|
s->carrier_phase += angle;
|
||||||
@ -774,7 +739,6 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
|||||||
int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
|
||||||
int step;
|
int step;
|
||||||
int16_t x;
|
int16_t x;
|
||||||
int32_t diff;
|
int32_t diff;
|
||||||
@ -782,11 +746,12 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
complexi16_t z;
|
complexi16_t z;
|
||||||
complexi16_t zz;
|
complexi16_t zz;
|
||||||
complexi16_t sample;
|
complexi16_t sample;
|
||||||
complexi32_t zi;
|
int32_t v;
|
||||||
#else
|
#else
|
||||||
complexf_t z;
|
complexf_t z;
|
||||||
complexf_t zz;
|
complexf_t zz;
|
||||||
complexf_t sample;
|
complexf_t sample;
|
||||||
|
float v;
|
||||||
#endif
|
#endif
|
||||||
int32_t power;
|
int32_t power;
|
||||||
|
|
||||||
@ -794,8 +759,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
{
|
{
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
s->rrc_filter[s->rrc_filter_step] =
|
s->rrc_filter[s->rrc_filter_step] = amp[i];
|
||||||
s->rrc_filter[s->rrc_filter_step + V27TER_RX_4800_FILTER_STEPS] = amp[i];
|
|
||||||
if (++s->rrc_filter_step >= V27TER_RX_4800_FILTER_STEPS)
|
if (++s->rrc_filter_step >= V27TER_RX_4800_FILTER_STEPS)
|
||||||
s->rrc_filter_step = 0;
|
s->rrc_filter_step = 0;
|
||||||
|
|
||||||
@ -887,28 +851,18 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
step = RX_PULSESHAPER_4800_COEFF_SETS - 1;
|
step = RX_PULSESHAPER_4800_COEFF_SETS - 1;
|
||||||
s->eq_put_step += RX_PULSESHAPER_4800_COEFF_SETS*5/2;
|
s->eq_put_step += RX_PULSESHAPER_4800_COEFF_SETS*5/2;
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
zi.re = (int32_t) rx_pulseshaper_4800[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_4800_re[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
zi.im = (int32_t) rx_pulseshaper_4800[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
sample.re = (v*(int32_t) s->agc_scaling) >> 15;
|
||||||
for (j = 1; j < V27TER_RX_4800_FILTER_STEPS; j++)
|
v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_4800_im[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
{
|
sample.im = (v*(int32_t) s->agc_scaling) >> 15;
|
||||||
zi.re += (int32_t) rx_pulseshaper_4800[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
zi.im += (int32_t) rx_pulseshaper_4800[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
}
|
|
||||||
sample.re = ((int32_t) zi.re*(int32_t) s->agc_scaling) >> 15;
|
|
||||||
sample.im = ((int32_t) zi.im*(int32_t) s->agc_scaling) >> 15;
|
|
||||||
z = dds_lookup_complexi16(s->carrier_phase);
|
z = dds_lookup_complexi16(s->carrier_phase);
|
||||||
zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15;
|
zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15;
|
||||||
zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15;
|
zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15;
|
||||||
#else
|
#else
|
||||||
zz.re = rx_pulseshaper_4800[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_4800_re[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
zz.im = rx_pulseshaper_4800[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
sample.re = v*s->agc_scaling;
|
||||||
for (j = 1; j < V27TER_RX_4800_FILTER_STEPS; j++)
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_4800_im[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
{
|
sample.im = v*s->agc_scaling;
|
||||||
zz.re += rx_pulseshaper_4800[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
zz.im += rx_pulseshaper_4800[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
}
|
|
||||||
sample.re = zz.re*s->agc_scaling;
|
|
||||||
sample.im = zz.im*s->agc_scaling;
|
|
||||||
z = dds_lookup_complexf(s->carrier_phase);
|
z = dds_lookup_complexf(s->carrier_phase);
|
||||||
zz.re = sample.re*z.re - sample.im*z.im;
|
zz.re = sample.re*z.re - sample.im*z.im;
|
||||||
zz.im = -sample.re*z.im - sample.im*z.re;
|
zz.im = -sample.re*z.im - sample.im*z.re;
|
||||||
@ -926,8 +880,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
{
|
{
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
s->rrc_filter[s->rrc_filter_step] =
|
s->rrc_filter[s->rrc_filter_step] = amp[i];
|
||||||
s->rrc_filter[s->rrc_filter_step + V27TER_RX_2400_FILTER_STEPS] = amp[i];
|
|
||||||
if (++s->rrc_filter_step >= V27TER_RX_2400_FILTER_STEPS)
|
if (++s->rrc_filter_step >= V27TER_RX_2400_FILTER_STEPS)
|
||||||
s->rrc_filter_step = 0;
|
s->rrc_filter_step = 0;
|
||||||
|
|
||||||
@ -1020,28 +973,18 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
step = RX_PULSESHAPER_2400_COEFF_SETS - 1;
|
step = RX_PULSESHAPER_2400_COEFF_SETS - 1;
|
||||||
s->eq_put_step += RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
s->eq_put_step += RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
zi.re = (int32_t) rx_pulseshaper_2400[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_2400_re[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
zi.im = (int32_t) rx_pulseshaper_2400[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
sample.re = (v*(int32_t) s->agc_scaling) >> 15;
|
||||||
for (j = 1; j < V27TER_RX_2400_FILTER_STEPS; j++)
|
v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_2400_im[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
{
|
sample.im = (v*(int32_t) s->agc_scaling) >> 15;
|
||||||
zi.re += (int32_t) rx_pulseshaper_2400[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
zi.im += (int32_t) rx_pulseshaper_2400[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
}
|
|
||||||
sample.re = ((int32_t) zi.re*(int32_t) s->agc_scaling) >> 15;
|
|
||||||
sample.im = ((int32_t) zi.im*(int32_t) s->agc_scaling) >> 15;
|
|
||||||
z = dds_lookup_complexi16(s->carrier_phase);
|
z = dds_lookup_complexi16(s->carrier_phase);
|
||||||
zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15;
|
zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15;
|
||||||
zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15;
|
zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15;
|
||||||
#else
|
#else
|
||||||
zz.re = rx_pulseshaper_2400[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_2400_re[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
zz.im = rx_pulseshaper_2400[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
sample.re = v*s->agc_scaling;
|
||||||
for (j = 1; j < V27TER_RX_2400_FILTER_STEPS; j++)
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_2400_im[step], V27TER_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
{
|
sample.im = v*s->agc_scaling;
|
||||||
zz.re += rx_pulseshaper_2400[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
zz.im += rx_pulseshaper_2400[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
}
|
|
||||||
sample.re = zz.re*s->agc_scaling;
|
|
||||||
sample.im = zz.im*s->agc_scaling;
|
|
||||||
z = dds_lookup_complexf(s->carrier_phase);
|
z = dds_lookup_complexf(s->carrier_phase);
|
||||||
zz.re = sample.re*z.re - sample.im*z.im;
|
zz.re = sample.re*z.re - sample.im*z.im;
|
||||||
zz.im = -sample.re*z.im - sample.im*z.re;
|
zz.im = -sample.re*z.im - sample.im*z.re;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: v29rx.c,v 1.140 2008/09/16 14:12:23 steveu Exp $
|
* $Id: v29rx.c,v 1.144 2008/09/18 14:59:30 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -79,6 +79,8 @@
|
|||||||
#define V29_TRAINING_SEG_3_LEN 384
|
#define V29_TRAINING_SEG_3_LEN 384
|
||||||
#define V29_TRAINING_SEG_4_LEN 48
|
#define V29_TRAINING_SEG_4_LEN 48
|
||||||
|
|
||||||
|
#define V29_EQUALIZER_LEN (V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TRAINING_STAGE_NORMAL_OPERATION = 0,
|
TRAINING_STAGE_NORMAL_OPERATION = 0,
|
||||||
@ -176,16 +178,16 @@ int v29_rx_equalizer_state(v29_rx_state_t *s, complexf_t **coeffs)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
*coeffs = s->eq_coeff;
|
*coeffs = s->eq_coeff;
|
||||||
return V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN;
|
return V29_EQUALIZER_LEN;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static void equalizer_save(v29_rx_state_t *s)
|
static void equalizer_save(v29_rx_state_t *s)
|
||||||
{
|
{
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_LEN);
|
||||||
#else
|
#else
|
||||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_LEN);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -193,13 +195,13 @@ static void equalizer_save(v29_rx_state_t *s)
|
|||||||
static void equalizer_restore(v29_rx_state_t *s)
|
static void equalizer_restore(v29_rx_state_t *s)
|
||||||
{
|
{
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_LEN);
|
||||||
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK);
|
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_LEN);
|
||||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
s->eq_delta = 32768.0f*EQUALIZER_DELTA/V29_EQUALIZER_LEN;
|
||||||
#else
|
#else
|
||||||
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_LEN);
|
||||||
cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK);
|
cvec_zerof(s->eq_buf, V29_EQUALIZER_LEN);
|
||||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
s->eq_delta = EQUALIZER_DELTA/V29_EQUALIZER_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
||||||
@ -211,15 +213,15 @@ static void equalizer_reset(v29_rx_state_t *s)
|
|||||||
{
|
{
|
||||||
/* Start with an equalizer based on everything being perfect */
|
/* Start with an equalizer based on everything being perfect */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
cvec_zeroi16(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
cvec_zeroi16(s->eq_coeff, V29_EQUALIZER_LEN);
|
||||||
s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_seti16(3*FP_FACTOR, 0*FP_FACTOR);
|
s->eq_coeff[V29_EQUALIZER_POST_LEN] = complex_seti16(3*FP_FACTOR, 0*FP_FACTOR);
|
||||||
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK);
|
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_LEN);
|
||||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
s->eq_delta = 32768.0f*EQUALIZER_DELTA/V29_EQUALIZER_LEN;
|
||||||
#else
|
#else
|
||||||
cvec_zerof(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
cvec_zerof(s->eq_coeff, V29_EQUALIZER_LEN);
|
||||||
s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_setf(3.0f, 0.0f);
|
s->eq_coeff[V29_EQUALIZER_POST_LEN] = complex_setf(3.0f, 0.0f);
|
||||||
cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK);
|
cvec_zerof(s->eq_buf, V29_EQUALIZER_LEN);
|
||||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
s->eq_delta = EQUALIZER_DELTA/V29_EQUALIZER_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
||||||
@ -232,8 +234,8 @@ static __inline__ complexi16_t complex_mul_q4_12(const complexi16_t *x, const co
|
|||||||
{
|
{
|
||||||
complexi16_t z;
|
complexi16_t z;
|
||||||
|
|
||||||
z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 12;
|
z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> FP_SHIFT_FACTOR;
|
||||||
z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 12;
|
z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> FP_SHIFT_FACTOR;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
@ -245,36 +247,19 @@ static __inline__ complexi16_t equalizer_get(v29_rx_state_t *s)
|
|||||||
static __inline__ complexf_t equalizer_get(v29_rx_state_t *s)
|
static __inline__ complexf_t equalizer_get(v29_rx_state_t *s)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int p;
|
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
|
complexi32_t zz;
|
||||||
complexi16_t z;
|
complexi16_t z;
|
||||||
complexi16_t z1;
|
|
||||||
#else
|
|
||||||
complexf_t z;
|
|
||||||
complexf_t z1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get the next equalized value. */
|
/* Get the next equalized value. */
|
||||||
p = s->eq_step - 1;
|
zz = cvec_circular_dot_prodi16(s->eq_buf, s->eq_coeff, V29_EQUALIZER_LEN, s->eq_step);
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
z.re = zz.re >> FP_SHIFT_FACTOR;
|
||||||
z = complex_seti16(0, 0);
|
z.im = zz.im >> FP_SHIFT_FACTOR;
|
||||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
|
||||||
{
|
|
||||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
|
||||||
z1 = complex_mul_q4_12(&s->eq_coeff[i], &s->eq_buf[p]);
|
|
||||||
z = complex_addi16(&z, &z1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
z = complex_setf(0.0f, 0.0f);
|
|
||||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
|
||||||
{
|
|
||||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
|
||||||
z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]);
|
|
||||||
z = complex_addf(&z, &z1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return z;
|
return z;
|
||||||
|
#else
|
||||||
|
/* Get the next equalized value. */
|
||||||
|
return cvec_circular_dot_prodf(s->eq_buf, s->eq_coeff, V29_EQUALIZER_LEN, s->eq_step);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -284,45 +269,24 @@ static void tune_equalizer(v29_rx_state_t *s, const complexi16_t *z, const compl
|
|||||||
static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int p;
|
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
complexi16_t ez;
|
complexi16_t err;
|
||||||
complexi16_t z1;
|
|
||||||
#else
|
|
||||||
complexf_t ez;
|
|
||||||
complexf_t z1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Find the x and y mismatch from the exact constellation position. */
|
/* Find the x and y mismatch from the exact constellation position. */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
err.re = target->re*FP_FACTOR - z->re;
|
||||||
ez.re = target->re*FP_FACTOR - z->re;
|
err.im = target->im*FP_FACTOR - z->im;
|
||||||
ez.im = target->im*FP_FACTOR - z->im;
|
err.re = ((int32_t) err.re*(int32_t) s->eq_delta) >> 15;
|
||||||
ez.re = ((int32_t) ez.re*(int32_t) s->eq_delta) >> 15;
|
err.im = ((int32_t) err.im*(int32_t) s->eq_delta) >> 15;
|
||||||
ez.im = ((int32_t) ez.im*(int32_t) s->eq_delta) >> 15;
|
cvec_circular_lmsi16(s->eq_buf, s->eq_coeff, V29_EQUALIZER_LEN, s->eq_step, &err);
|
||||||
#else
|
#else
|
||||||
ez = complex_subf(target, z);
|
complexf_t err;
|
||||||
ez.re *= s->eq_delta;
|
|
||||||
ez.im *= s->eq_delta;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
p = s->eq_step - 1;
|
/* Find the x and y mismatch from the exact constellation position. */
|
||||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
err = complex_subf(target, z);
|
||||||
{
|
err.re *= s->eq_delta;
|
||||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
err.im *= s->eq_delta;
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
cvec_circular_lmsf(s->eq_buf, s->eq_coeff, V29_EQUALIZER_LEN, s->eq_step, &err);
|
||||||
z1 = complex_conji16(&s->eq_buf[p]);
|
|
||||||
z1 = complex_mul_q4_12(&ez, &z1);
|
|
||||||
s->eq_coeff[i] = complex_addi16(&s->eq_coeff[i], &z1);
|
|
||||||
#else
|
|
||||||
z1 = complex_conjf(&s->eq_buf[p]);
|
|
||||||
z1 = complex_mulf(&ez, &z1);
|
|
||||||
s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1);
|
|
||||||
/* Leak a little to tame uncontrolled wandering */
|
|
||||||
s->eq_coeff[i].re *= 0.9999f;
|
|
||||||
s->eq_coeff[i].im *= 0.9999f;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -597,7 +561,8 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
|||||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||||
at this time. */
|
at this time. */
|
||||||
s->eq_buf[s->eq_step] = *sample;
|
s->eq_buf[s->eq_step] = *sample;
|
||||||
s->eq_step = (s->eq_step + 1) & V29_EQUALIZER_MASK;
|
if (++s->eq_step >= V29_EQUALIZER_LEN)
|
||||||
|
s->eq_step = 0;
|
||||||
|
|
||||||
/* On alternate insertions we have a whole baud, and must process it. */
|
/* On alternate insertions we have a whole baud, and must process it. */
|
||||||
if ((s->baud_half ^= 1))
|
if ((s->baud_half ^= 1))
|
||||||
@ -687,7 +652,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
|||||||
p = angle*2.0f*3.14159f/(65536.0f*65536.0f);
|
p = angle*2.0f*3.14159f/(65536.0f*65536.0f);
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
zz = complex_setf(cosf(p), -sinf(p));
|
zz = complex_setf(cosf(p), -sinf(p));
|
||||||
for (i = 0; i <= V29_EQUALIZER_MASK; i++)
|
for (i = 0; i < V29_EQUALIZER_LEN; i++)
|
||||||
{
|
{
|
||||||
z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im);
|
z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im);
|
||||||
z1 = complex_mulf(&z1, &zz);
|
z1 = complex_mulf(&z1, &zz);
|
||||||
@ -696,7 +661,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
zz = complex_setf(cosf(p), -sinf(p));
|
zz = complex_setf(cosf(p), -sinf(p));
|
||||||
for (i = 0; i <= V29_EQUALIZER_MASK; i++)
|
for (i = 0; i < V29_EQUALIZER_LEN; i++)
|
||||||
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
||||||
#endif
|
#endif
|
||||||
s->carrier_phase += angle;
|
s->carrier_phase += angle;
|
||||||
@ -860,7 +825,6 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
|||||||
int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
|
||||||
int step;
|
int step;
|
||||||
int16_t x;
|
int16_t x;
|
||||||
int32_t diff;
|
int32_t diff;
|
||||||
@ -879,8 +843,7 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
s->rrc_filter[s->rrc_filter_step] =
|
s->rrc_filter[s->rrc_filter_step] = amp[i];
|
||||||
s->rrc_filter[s->rrc_filter_step + V29_RX_FILTER_STEPS] = amp[i];
|
|
||||||
if (++s->rrc_filter_step >= V29_RX_FILTER_STEPS)
|
if (++s->rrc_filter_step >= V29_RX_FILTER_STEPS)
|
||||||
s->rrc_filter_step = 0;
|
s->rrc_filter_step = 0;
|
||||||
|
|
||||||
@ -956,25 +919,21 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
if (step < 0)
|
if (step < 0)
|
||||||
step += RX_PULSESHAPER_COEFF_SETS;
|
step += RX_PULSESHAPER_COEFF_SETS;
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
v = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_re[step], V29_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
|
||||||
v += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
sample.re = (v*s->agc_scaling) >> 15;
|
sample.re = (v*s->agc_scaling) >> 15;
|
||||||
#else
|
#else
|
||||||
v = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_re[step], V29_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
|
||||||
v += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
sample.re = v*s->agc_scaling;
|
sample.re = v*s->agc_scaling;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Symbol timing synchronisation band edge filters */
|
/* Symbol timing synchronisation band edge filters */
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
/* Low Nyquist band edge filter */
|
/* Low Nyquist band edge filter */
|
||||||
v = ((s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0) >> 12) + ((s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1) >> 12) + sample.re;
|
v = ((s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0) >> FP_SHIFT_FACTOR) + ((s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1) >> FP_SHIFT_FACTOR) + sample.re;
|
||||||
s->symbol_sync_low[1] = s->symbol_sync_low[0];
|
s->symbol_sync_low[1] = s->symbol_sync_low[0];
|
||||||
s->symbol_sync_low[0] = v;
|
s->symbol_sync_low[0] = v;
|
||||||
/* High Nyquist band edge filter */
|
/* High Nyquist band edge filter */
|
||||||
v = ((s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0) >> 12) + ((s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1) >> 12) + sample.re;
|
v = ((s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0) >> FP_SHIFT_FACTOR) + ((s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1) >> FP_SHIFT_FACTOR) + sample.re;
|
||||||
s->symbol_sync_high[1] = s->symbol_sync_high[0];
|
s->symbol_sync_high[1] = s->symbol_sync_high[0];
|
||||||
s->symbol_sync_high[0] = v;
|
s->symbol_sync_high[0] = v;
|
||||||
#else
|
#else
|
||||||
@ -1008,17 +967,13 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
|||||||
step = RX_PULSESHAPER_COEFF_SETS - 1;
|
step = RX_PULSESHAPER_COEFF_SETS - 1;
|
||||||
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
||||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||||
v = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_im[step], V29_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
|
||||||
v += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
sample.im = (v*s->agc_scaling) >> 15;
|
sample.im = (v*s->agc_scaling) >> 15;
|
||||||
z = dds_lookup_complexi16(s->carrier_phase);
|
z = dds_lookup_complexi16(s->carrier_phase);
|
||||||
zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15;
|
zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15;
|
||||||
zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15;
|
zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15;
|
||||||
#else
|
#else
|
||||||
v = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_im[step], V29_RX_FILTER_STEPS, s->rrc_filter_step);
|
||||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
|
||||||
v += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
|
||||||
sample.im = v*s->agc_scaling;
|
sample.im = v*s->agc_scaling;
|
||||||
z = dds_lookup_complexf(s->carrier_phase);
|
z = dds_lookup_complexf(s->carrier_phase);
|
||||||
zz.re = sample.re*z.re - sample.im*z.im;
|
zz.re = sample.re*z.re - sample.im*z.im;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: vector_float.c,v 1.12 2008/09/16 15:21:52 steveu Exp $
|
* $Id: vector_float.c,v 1.14 2008/09/18 13:54:32 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -337,22 +337,25 @@ float vec_dot_prodf(const float x[], const float y[], int n)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float z;
|
float z;
|
||||||
__m128 num1, num2, num3, num4;
|
__m128 n1;
|
||||||
|
__m128 n2;
|
||||||
|
__m128 n3;
|
||||||
|
__m128 n4;
|
||||||
|
|
||||||
z = 0.0f;
|
z = 0.0f;
|
||||||
if ((i = n & ~3))
|
if ((i = n & ~3))
|
||||||
{
|
{
|
||||||
num4 = _mm_setzero_ps(); //sets sum to zero
|
n4 = _mm_setzero_ps(); //sets sum to zero
|
||||||
for (i -= 4; i >= 0; i -= 4)
|
for (i -= 4; i >= 0; i -= 4)
|
||||||
{
|
{
|
||||||
num1 = _mm_loadu_ps(x + i);
|
n1 = _mm_loadu_ps(x + i);
|
||||||
num2 = _mm_loadu_ps(y + i);
|
n2 = _mm_loadu_ps(y + i);
|
||||||
num3 = _mm_mul_ps(num1, num2);
|
n3 = _mm_mul_ps(n1, n2);
|
||||||
num4 = _mm_add_ps(num4, num3);
|
n4 = _mm_add_ps(n4, n3);
|
||||||
}
|
}
|
||||||
num4 = _mm_add_ps(_mm_movehl_ps(num4, num4), num4);
|
n4 = _mm_add_ps(_mm_movehl_ps(n4, n4), n4);
|
||||||
num4 = _mm_add_ss(_mm_shuffle_ps(num4, num4, 1), num4);
|
n4 = _mm_add_ss(_mm_shuffle_ps(n4, n4, 1), n4);
|
||||||
_mm_store_ss(&z, num4);
|
_mm_store_ss(&z, n4);
|
||||||
}
|
}
|
||||||
/* Now deal with the last 1 to 3 elements, which don't fill in an SSE2 register */
|
/* Now deal with the last 1 to 3 elements, which don't fill in an SSE2 register */
|
||||||
switch (n & 3)
|
switch (n & 3)
|
||||||
@ -405,4 +408,34 @@ long double vec_dot_prodl(const long double x[], const long double y[], int n)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
float vec_circular_dot_prodf(const float x[], const float y[], int n, int pos)
|
||||||
|
{
|
||||||
|
float z;
|
||||||
|
|
||||||
|
z = vec_dot_prodf(&x[pos], &y[0], n - pos);
|
||||||
|
z += vec_dot_prodf(&x[0], &y[n - pos], pos);
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vec_lmsf(const float x[], float y[], int n, float error)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
y[i] += x[i]*error;
|
||||||
|
/* Leak a little to tame uncontrolled wandering */
|
||||||
|
y[i] *= 0.9999f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vec_circular_lmsf(const float x[], float y[], int n, int pos, float error)
|
||||||
|
{
|
||||||
|
vec_lmsf(&x[pos], &y[0], n - pos, error);
|
||||||
|
vec_lmsf(&x[0], &y[n - pos], pos, error);
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
/*- End of file ------------------------------------------------------------*/
|
/*- End of file ------------------------------------------------------------*/
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* License along with this program; if not, write to the Free Software
|
* License along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: vector_int.c,v 1.13 2008/09/16 15:21:52 steveu Exp $
|
* $Id: vector_int.c,v 1.15 2008/09/18 13:54:32 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -156,7 +156,33 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n)
|
|||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
z += (int32_t) x[i]*(int32_t) y[i];
|
z += (int32_t) x[i]*(int32_t) y[i];
|
||||||
#endif
|
#endif
|
||||||
return z;
|
return z;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
int32_t vec_circular_dot_prodi16(const int16_t x[], const int16_t y[], int n, int pos)
|
||||||
|
{
|
||||||
|
int32_t z;
|
||||||
|
|
||||||
|
z = vec_dot_prodi16(&x[pos], &y[0], n - pos);
|
||||||
|
z += vec_dot_prodi16(&x[0], &y[n - pos], pos);
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vec_lmsi16(const int16_t x[], int16_t y[], int n, int16_t error)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
y[i] += ((int32_t) x[i]*(int32_t) error) >> 15;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vec_circular_lmsi16(const int16_t x[], int16_t y[], int n, int pos, int16_t error)
|
||||||
|
{
|
||||||
|
vec_lmsi16(&x[pos], &y[0], n - pos, error);
|
||||||
|
vec_lmsi16(&x[0], &y[n - pos], pos, error);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -315,7 +341,7 @@ int32_t vec_min_maxi16(const int16_t x[], int n, int16_t out[])
|
|||||||
: "S" (x), "a" (n), "d" (out), [lower] "m" (lower_bound), [upper] "m" (upper_bound)
|
: "S" (x), "a" (n), "d" (out), [lower] "m" (lower_bound), [upper] "m" (upper_bound)
|
||||||
: "ecx"
|
: "ecx"
|
||||||
);
|
);
|
||||||
return max;
|
return max;
|
||||||
#else
|
#else
|
||||||
int i;
|
int i;
|
||||||
int16_t min;
|
int16_t min;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
## along with this program; if not, write to the Free Software
|
## along with this program; if not, write to the Free Software
|
||||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
##
|
##
|
||||||
## $Id: Makefile.am,v 1.106 2008/09/09 14:05:55 steveu Exp $
|
## $Id: Makefile.am,v 1.107 2008/09/18 12:05:35 steveu Exp $
|
||||||
|
|
||||||
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
||||||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||||
@ -41,6 +41,9 @@ noinst_PROGRAMS = adsi_tests \
|
|||||||
bell_mf_tx_tests \
|
bell_mf_tx_tests \
|
||||||
bert_tests \
|
bert_tests \
|
||||||
bit_operations_tests \
|
bit_operations_tests \
|
||||||
|
complex_tests \
|
||||||
|
complex_vector_float_tests \
|
||||||
|
complex_vector_int_tests \
|
||||||
crc_tests \
|
crc_tests \
|
||||||
dc_restore_tests \
|
dc_restore_tests \
|
||||||
dds_tests \
|
dds_tests \
|
||||||
@ -132,6 +135,15 @@ bert_tests_LDADD = $(LIBDIR) -lspandsp
|
|||||||
bit_operations_tests_SOURCES = bit_operations_tests.c
|
bit_operations_tests_SOURCES = bit_operations_tests.c
|
||||||
bit_operations_tests_LDADD = $(LIBDIR) -lspandsp
|
bit_operations_tests_LDADD = $(LIBDIR) -lspandsp
|
||||||
|
|
||||||
|
complex_tests_SOURCES = complex_tests.c
|
||||||
|
complex_tests_LDADD = $(LIBDIR) -lspandsp
|
||||||
|
|
||||||
|
complex_vector_float_tests_SOURCES = complex_vector_float_tests.c
|
||||||
|
complex_vector_float_tests_LDADD = $(LIBDIR) -lspandsp
|
||||||
|
|
||||||
|
complex_vector_int_tests_SOURCES = complex_vector_int_tests.c
|
||||||
|
complex_vector_int_tests_LDADD = $(LIBDIR) -lspandsp
|
||||||
|
|
||||||
crc_tests_SOURCES = crc_tests.c
|
crc_tests_SOURCES = crc_tests.c
|
||||||
crc_tests_LDADD = $(LIBDIR) -lspandsp
|
crc_tests_LDADD = $(LIBDIR) -lspandsp
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: g722_tests.c,v 1.26 2008/05/13 13:17:25 steveu Exp $
|
* $Id: g722_tests.c,v 1.27 2008/09/19 14:02:05 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@ -109,8 +109,10 @@ static const char *itu_test_files[] =
|
|||||||
|
|
||||||
static const char *encode_test_files[] =
|
static const char *encode_test_files[] =
|
||||||
{
|
{
|
||||||
TESTDATA_DIR "T1C1.XMT", TESTDATA_DIR "T2R1.COD",
|
TESTDATA_DIR "T1C1.XMT",
|
||||||
TESTDATA_DIR "T1C2.XMT", TESTDATA_DIR "T2R2.COD",
|
TESTDATA_DIR "T2R1.COD",
|
||||||
|
TESTDATA_DIR "T1C2.XMT",
|
||||||
|
TESTDATA_DIR "T2R2.COD",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -295,6 +297,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (itutests)
|
if (itutests)
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
/* ITU G.722 encode tests, using configuration 1. The QMF is bypassed */
|
/* ITU G.722 encode tests, using configuration 1. The QMF is bypassed */
|
||||||
for (file = 0; encode_test_files[file]; file += 2)
|
for (file = 0; encode_test_files[file]; file += 2)
|
||||||
{
|
{
|
||||||
@ -341,7 +344,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("Test passed\n");
|
printf("Test passed\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
/* ITU G.722 decode tests, using configuration 2. The QMF is bypassed */
|
/* ITU G.722 decode tests, using configuration 2. The QMF is bypassed */
|
||||||
/* Run each of the tests for each of the modes - 48kbps, 56kbps and 64kbps. */
|
/* Run each of the tests for each of the modes - 48kbps, 56kbps and 64kbps. */
|
||||||
for (mode = 1; mode <= 3; mode++)
|
for (mode = 1; mode <= 3; mode++)
|
||||||
@ -404,7 +408,7 @@ int main(int argc, char *argv[])
|
|||||||
printf("Test passed\n");
|
printf("Test passed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
printf("Tests passed.\n");
|
printf("Tests passed.\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
# License along with this program; if not, write to the Free Software
|
# License along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
#
|
#
|
||||||
# $Id: regression_tests.sh,v 1.52 2008/09/02 13:56:10 steveu Exp $
|
# $Id: regression_tests.sh,v 1.53 2008/09/18 12:09:51 steveu Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
ITUTESTS_TIF=../test-data/itu/fax/itutests.tif
|
ITUTESTS_TIF=../test-data/itu/fax/itutests.tif
|
||||||
@ -99,6 +99,33 @@ then
|
|||||||
fi
|
fi
|
||||||
echo bit_operations_tests completed OK
|
echo bit_operations_tests completed OK
|
||||||
|
|
||||||
|
./complex_tests >$STDOUT_DEST 2>$STDERR_DEST
|
||||||
|
RETVAL=$?
|
||||||
|
if [ $RETVAL != 0 ]
|
||||||
|
then
|
||||||
|
echo complex_tests failed!
|
||||||
|
exit $RETVAL
|
||||||
|
fi
|
||||||
|
echo complex_tests completed OK
|
||||||
|
|
||||||
|
./complex_vector_float_tests >$STDOUT_DEST 2>$STDERR_DEST
|
||||||
|
RETVAL=$?
|
||||||
|
if [ $RETVAL != 0 ]
|
||||||
|
then
|
||||||
|
echo complex_vector_float_tests failed!
|
||||||
|
exit $RETVAL
|
||||||
|
fi
|
||||||
|
echo complex_vector_float_tests completed OK
|
||||||
|
|
||||||
|
./complex_vector_int_tests >$STDOUT_DEST 2>$STDERR_DEST
|
||||||
|
RETVAL=$?
|
||||||
|
if [ $RETVAL != 0 ]
|
||||||
|
then
|
||||||
|
echo complex_vector_int_tests failed!
|
||||||
|
exit $RETVAL
|
||||||
|
fi
|
||||||
|
echo complex_vector_int_tests completed OK
|
||||||
|
|
||||||
./crc_tests >$STDOUT_DEST 2>$STDERR_DEST
|
./crc_tests >$STDOUT_DEST 2>$STDERR_DEST
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
if [ $RETVAL != 0 ]
|
if [ $RETVAL != 0 ]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* SpanDSP - a series of DSP components for telephony
|
* SpanDSP - a series of DSP components for telephony
|
||||||
*
|
*
|
||||||
* vector_int_tests.c
|
* complex_vector_int_tests.c
|
||||||
*
|
*
|
||||||
* Written by Steve Underwood <steveu@coppice.org>
|
* Written by Steve Underwood <steveu@coppice.org>
|
||||||
*
|
*
|
||||||
@ -22,7 +22,7 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: vector_int_tests.c,v 1.9 2008/09/16 15:21:52 steveu Exp $
|
* $Id: vector_int_tests.c,v 1.10 2008/09/18 12:05:35 steveu Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
#if defined(HAVE_CONFIG_H)
|
||||||
@ -139,10 +139,51 @@ static int test_vec_min_maxi16(void)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int test_vec_circular_dot_prodi16(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int pos;
|
||||||
|
int len;
|
||||||
|
int32_t za;
|
||||||
|
int32_t zb;
|
||||||
|
int16_t x[99];
|
||||||
|
int16_t y[99];
|
||||||
|
|
||||||
|
/* Verify that we can do circular sample buffer "dot" linear coefficient buffer
|
||||||
|
operations properly, by doing two sub-dot products. */
|
||||||
|
for (i = 0; i < 99; i++)
|
||||||
|
{
|
||||||
|
x[i] = rand();
|
||||||
|
y[i] = rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
len = 95;
|
||||||
|
for (pos = 0; pos < len; pos++)
|
||||||
|
{
|
||||||
|
za = vec_circular_dot_prodi16(x, y, len, pos);
|
||||||
|
zb = 0;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
j = (pos + i) % len;
|
||||||
|
zb += (int32_t) x[j]*(int32_t) y[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (za != zb)
|
||||||
|
{
|
||||||
|
printf("Tests failed\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
test_vec_dot_prodi16();
|
test_vec_dot_prodi16();
|
||||||
test_vec_min_maxi16();
|
test_vec_min_maxi16();
|
||||||
|
test_vec_circular_dot_prodi16();
|
||||||
|
|
||||||
printf("Tests passed.\n");
|
printf("Tests passed.\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user