MAINTAINERCLEANFILES = Makefile.in
DISTCLEANFILES = $(srcdir)/at_interpreter_dictionary.h \
+ $(srcdir)/math_fixed_tables.h \
$(srcdir)/v17_v32bis_rx_fixed_rrc.h \
$(srcdir)/v17_v32bis_rx_floating_rrc.h \
$(srcdir)/v17_v32bis_tx_fixed_rrc.h \
libtiff.2008.vcproj \
filter_tools.c \
make_at_dictionary.c \
+ make_math_fixed_tables.c \
make_modem_filter.c \
msvc/config.h \
msvc/Download_TIFF.2005.vcproj \
lpc10_encode.c \
lpc10_placev.c \
lpc10_voicing.c \
+ math_fixed.c \
modem_echo.c \
modem_connect_tones.c \
noise.c \
spandsp/image_translate.h \
spandsp/logging.h \
spandsp/lpc10.h \
+ spandsp/math_fixed.h \
spandsp/modem_echo.h \
spandsp/modem_connect_tones.h \
spandsp/noise.h \
make_at_dictionary$(EXEEXT): $(top_srcdir)/src/make_at_dictionary.c
$(CC_FOR_BUILD) -o make_at_dictionary$(EXEEXT) $(top_srcdir)/src/make_at_dictionary.c -DHAVE_CONFIG_H -I$(top_builddir)/src
+make_math_fixed_tables$(EXEEXT): $(top_srcdir)/src/make_math_fixed_tables.c
+ $(CC_FOR_BUILD) -o make_math_fixed_tables$(EXEEXT) $(top_srcdir)/src/make_math_fixed_tables.c -DHAVE_CONFIG_H -I$(top_builddir)/src -lm
+
make_modem_filter$(EXEEXT): $(top_srcdir)/src/make_modem_filter.c $(top_srcdir)/src/filter_tools.c
$(CC_FOR_BUILD) -o make_modem_filter$(EXEEXT) $(top_srcdir)/src/make_modem_filter.c $(top_srcdir)/src/filter_tools.c -DHAVE_CONFIG_H -I$(top_builddir)/src -lm
at_interpreter_dictionary.h: make_at_dictionary$(EXEEXT)
./make_at_dictionary$(EXEEXT) >at_interpreter_dictionary.h
+math_fixed.$(OBJEXT): math_fixed_tables.h
+
+math_fixed.lo: math_fixed_tables.h
+
+math_fixed_tables.h: make_math_fixed_tables$(EXEEXT)
+ ./make_math_fixed_tables$(EXEEXT) >math_fixed_tables.h
+
t4_rx.$(OBJEXT): spandsp/version.h
t4_rx.lo: spandsp/version.h
--- /dev/null
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * make_fixed_point_math_tables.c - Generate lookup tables for some of the
+ * fixed point maths functions.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2010 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <math.h>
+
+int main(int argc, char *argv[])
+{
+ int i;
+ double val;
+ int ival;
+
+ printf("static const uint16_t fixed_reciprocal_table[129] =\n");
+ printf("{\n");
+ for (i = 0; i < 129; i++)
+ {
+ val = 32768.0*128.0/(128 + i) + 0.5;
+ ival = val;
+ if (i < 128)
+ printf(" %6d,\n", ival);
+ else
+ printf(" %6d\n", ival);
+ }
+ printf("};\n\n");
+
+ printf("static const uint16_t fixed_sqrt_table[193] =\n");
+ printf("{\n");
+ for (i = 64; i <= 256; i++)
+ {
+ ival = sqrt(i/256.0)*65536.0 + 0.5;
+ if (ival > 65535)
+ ival = 65535;
+ if (i < 256)
+ printf(" %6d,\n", ival);
+ else
+ printf(" %6d\n", ival);
+ }
+ printf("};\n\n");
+
+ printf("static const int16_t fixed_log10_table[129] =\n");
+ printf("{\n");
+ for (i = 128; i <= 256; i++)
+ {
+ ival = log10(i/256.0)*32768.0 - 0.5;
+ if (i <= 255)
+ printf(" %6d,\n", ival);
+ else
+ printf(" %6d\n", ival);
+ }
+ printf("};\n\n");
+
+ printf("static const int16_t fixed_sine_table[257] =\n");
+ printf("{\n");
+ for (i = 0; i <= 256; i++)
+ {
+ val = sin(i*3.1415926535/512.0)*32768.0;
+ ival = val + 0.5;
+ if (ival > 32767)
+ ival = 32767;
+ if (i <= 255)
+ printf(" %6d,\n", ival);
+ else
+ printf(" %6d\n", ival);
+ }
+ printf("};\n\n");
+
+ printf("static const uint16_t fixed_arctan_table[257] =\n");
+ printf("{\n");
+ for (i = 0; i <= 256; i++)
+ {
+ val = atan(i/256.0)*65536.0/(2.0*3.1415926535);
+ ival = val + 0.5;
+ /* Nudge the result away from zero, so things sit consistently on
+ the correct side of the axes. */
+ if (ival == 0)
+ ival = 1;
+ if (i <= 255)
+ printf(" %6d,\n", ival);
+ else
+ printf(" %6d\n", ival);
+ }
+ printf("};\n\n");
+
+ return 0;
+}
--- /dev/null
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * math_fixed.c
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2010 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*! \file */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <float.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include "floating_fudge.h"
+#include <assert.h>
+
+#include "math_fixed_tables.h"
+
+#include "spandsp/telephony.h"
+#include "spandsp/bit_operations.h"
+#include "spandsp/math_fixed.h"
+
+#if defined(SPANDSP_USE_FIXED_POINT)
+SPAN_DECLARE(uint16_t) sqrtu32_u16(uint32_t x)
+{
+ uint16_t zz;
+ uint16_t z;
+ uint16_t i;
+
+ z = 0;
+ for (i = 0x8000; i; i >>= 1)
+ {
+ zz = z | i;
+ if (((int32_t) zz*zz) <= x)
+ z = zz;
+ }
+ return z;
+}
+/*- End of function --------------------------------------------------------*/
+#endif
+
+SPAN_DECLARE(uint16_t) fixed_reciprocal16(uint16_t x, int *shift)
+{
+ if (x == 0)
+ {
+ *shift = 0;
+ return 0xFFFF;
+ }
+ *shift = 15 - top_bit(x);
+ x <<= *shift;
+ return fixed_reciprocal_table[((x + 0x80) >> 8) - 128];
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(uint16_t) fixed_divide16(uint16_t y, uint16_t x)
+{
+ int shift;
+ uint32_t z;
+ uint16_t recip;
+
+ if (x == 0)
+ return 0xFFFF;
+ recip = fixed_reciprocal16(x, &shift);
+ z = (((uint32_t) y*recip) >> 15) << shift;
+ return z;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(uint16_t) fixed_divide32(uint32_t y, uint16_t x)
+{
+ int shift;
+ uint32_t z;
+ uint16_t recip;
+
+ if (x == 0)
+ return 0xFFFF;
+ recip = fixed_reciprocal16(x, &shift);
+ z = (((uint32_t) y*recip) >> 15) << shift;
+ return z;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(int16_t) fixed_log10_16(uint16_t x)
+{
+ int shift;
+
+ if (x == 0)
+ return 0;
+ shift = 14 - top_bit(x);
+ x <<= shift;
+ return (fixed_log10_table[((x + 0x40) >> 7) - 128] >> 3) - shift*1233;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(int32_t) fixed_log10_32(uint32_t x)
+{
+ int shift;
+
+ if (x == 0)
+ return 0;
+ shift = 30 - top_bit(x);
+ x <<= shift;
+ return (fixed_log10_table[((x + 0x400000) >> 23) - 128] >> 3) - shift*1233;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(uint16_t) fixed_sqrt16(uint16_t x)
+{
+ int shift;
+
+ if (x == 0)
+ return 0;
+ shift = 14 - (top_bit(x) & ~1);
+ x <<= shift;
+ //return fixed_sqrt_table[(((x + 0x80) >> 8) & 0xFF) - 64] >> (shift >> 1);
+ return fixed_sqrt_table[((x >> 8) & 0xFF) - 64] >> (shift >> 1);
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(uint16_t) fixed_sqrt32(uint32_t x)
+{
+ int shift;
+
+ if (x == 0)
+ return 0;
+ shift = 30 - (top_bit(x) & ~1);
+ x <<= shift;
+ //return fixed_sqrt_table[(((x + 0x800000) >> 24) & 0xFF) - 64] >> (shift >> 1);
+ return fixed_sqrt_table[((x >> 24) & 0xFF) - 64] >> (shift >> 1);
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(int16_t) fixed_sin(uint16_t x)
+{
+ int step;
+ int step_after;
+ int16_t frac;
+ int16_t z;
+
+ step = (x & 0x3FFF) >> 6;
+ frac = x & 0x3F;
+ if ((x & 0x4000))
+ {
+ step = 256 - step;
+ step_after = step - 1;
+ }
+ else
+ {
+ step_after = step + 1;
+ }
+ z = fixed_sine_table[step] + ((frac*(fixed_sine_table[step_after] - fixed_sine_table[step])) >> 6);
+ if ((x & 0x8000))
+ z = -z;
+ return z;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(int16_t) fixed_cos(uint16_t x)
+{
+ int step;
+ int step_after;
+ int16_t frac;
+ int16_t z;
+
+ x += 0x4000;
+ step = (x & 0x3FFF) >> 6;
+ frac = x & 0x3F;
+ if ((x & 0x4000))
+ {
+ step = 256 - step;
+ step_after = step - 1;
+ }
+ else
+ {
+ step_after = step + 1;
+ }
+ z = fixed_sine_table[step] + ((frac*(fixed_sine_table[step_after] - fixed_sine_table[step])) >> 6);
+ if ((x & 0x8000))
+ z = -z;
+ return z;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(uint16_t) fixed_atan2(int16_t y, int16_t x)
+{
+ int16_t abs_x;
+ int16_t abs_y;
+ uint16_t angle;
+ uint16_t recip;
+ uint32_t z;
+ int step;
+ int shift;
+
+ if (y == 0)
+ return (x & 0x8000);
+ if (x == 0)
+ return ((y & 0x8000) | 0x4000);
+ abs_x = abs(x);
+ abs_y = abs(y);
+
+ if (abs_y < abs_x)
+ {
+ recip = fixed_reciprocal16(abs_x, &shift);
+ z = (((uint32_t) recip*abs_y) >> 15) << shift;
+ step = z >> 7;
+ angle = fixed_arctan_table[step];
+ }
+ else
+ {
+ recip = fixed_reciprocal16(abs_y, &shift);
+ z = (((uint32_t) recip*abs_x) >> 15) << shift;
+ step = z >> 7;
+ angle = 0x4000 - fixed_arctan_table[step];
+ }
+ /* If we are in quadrant II or III, flip things around */
+ if (x < 0)
+ angle = 0x8000 - angle;
+ /* If we are in quadrant III or IV, negate to return an
+ answer in the full circle range. */
+ if (y < 0)
+ angle = -angle;
+ return (uint16_t) angle;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/
--- /dev/null
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * math_fixed.h
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2010 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if !defined(_MATH_FIXED_H_)
+#define _MATH_FIXED_H_
+
+/*! \page math_fixed_page Fixed point math functions
+
+\section math_fixed_page_sec_1 What does it do?
+
+\section math_fixed_page_sec_2 How does it work?
+*/
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#if defined(SPANDSP_USE_FIXED_POINT)
+SPAN_DECLARE(uint16_t) sqrtu32_u16(uint32_t x);
+#endif
+
+SPAN_DECLARE(uint16_t) fixed_reciprocal16(uint16_t x, int *shift);
+
+SPAN_DECLARE(uint16_t) fixed_divide16(uint16_t y, uint16_t x);
+
+SPAN_DECLARE(uint16_t) fixed_divide32(uint32_t y, uint16_t x);
+
+SPAN_DECLARE(int16_t) fixed_log10_16(uint16_t x);
+
+SPAN_DECLARE(int32_t) fixed_log10_32(uint32_t x);
+
+SPAN_DECLARE(uint16_t) fixed_sqrt16(uint16_t x);
+
+SPAN_DECLARE(uint16_t) fixed_sqrt32(uint32_t x);
+
+/*! Evaluate an approximate 16 bit fixed point sine.
+ \brief Evaluate an approximate 16 bit fixed point sine.
+ \param x A 16 bit unsigned angle, in 360/65536 degree steps.
+ \return sin(x)*32767. */
+SPAN_DECLARE(int16_t) fixed_sin(uint16_t x);
+
+/*! Evaluate an approximate 16 bit fixed point cosine.
+ \brief Evaluate an approximate 16 bit fixed point cosine.
+ \param x A 16 bit unsigned angle, in 360/65536 degree steps.
+ \return cos(x)*32767. */
+SPAN_DECLARE(int16_t) fixed_cos(uint16_t x);
+
+/*! Evaluate an approximate 16 bit fixed point sine.
+ \brief Evaluate an approximate 16 bit fixed point sine.
+ \param y .
+ \param x .
+ \return The 16 bit unsigned angle, in 360/65536 degree steps. */
+SPAN_DECLARE(uint16_t) fixed_atan2(int16_t y, int16_t x);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/
line_model_tests \
logging_tests \
lpc10_tests \
+ math_fixed_tests \
make_g168_css \
modem_connect_tones_tests \
modem_echo_tests \
lpc10_tests_SOURCES = lpc10_tests.c
lpc10_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp
+math_fixed_tests_SOURCES = math_fixed_tests.c
+math_fixed_tests_LDADD = $(LIBDIR) -lspandsp
+
make_g168_css_SOURCES = make_g168_css.c
make_g168_css_LDADD = $(LIBDIR) -lspandsp
t38_core_tests_LDADD = $(LIBDIR) -lspandsp
t38_decode_SOURCES = t38_decode.c fax_utils.c pcap_parse.c udptl.c
-t38_decode_LDADD = $(LIBDIR) -lspandsp -lpcap
+t38_decode_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp -lpcap
t38_gateway_tests_SOURCES = t38_gateway_tests.c fax_utils.c media_monitor.cpp
t38_gateway_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp
--- /dev/null
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * math_fixed_tests.c - Test the fixed point math functions.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2010 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*! \file */
+
+/*! \page math_fixed_tests_page Fixed point math function tests
+\section math_fixed_tests_page_sec_1 What does it do?
+*/
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include <sndfile.h>
+
+//#if defined(WITH_SPANDSP_INTERNALS)
+#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
+//#endif
+
+#include "spandsp.h"
+
+static void fixed_reciprocal16_tests(void)
+{
+ int x;
+ uint16_t yu16;
+ uint32_t yu32;
+ double z;
+ double ratio;
+ double max;
+ double min;
+ int shift;
+
+ /* The reciprocal should be with about 0.4%, except for 0, which is obviously a
+ special case. */
+ printf("fixed_reciprocal16() function tests\n");
+ if (fixed_reciprocal16(0, &shift) != 0xFFFF || shift != 0)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ min = 999999.0;
+ max = -999999.0;
+ for (x = 1; x < 65536; x++)
+ {
+ yu16 = fixed_reciprocal16(x, &shift);
+ yu32 = ((uint32_t) yu16) << shift;
+ z = 32768.0*32768.0/x;
+ ratio = z/yu32;
+ //printf("%6x %15d %f %f\n", x, yu32, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < 0.996 || ratio > 1.004)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_divide16_tests(void)
+{
+ int x;
+ int y;
+ uint16_t yu16;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_divide16() function tests\n");
+ if (fixed_divide16(12345, 0) != 0xFFFF)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ min = 999999.0;
+ max = -999999.0;
+ for (y = 32; y < 65536; y += 16)
+ {
+ for (x = y*16; x < 65536; x += 16)
+ {
+ yu16 = fixed_divide16(y, x);
+ z = 32768.0*y/x;
+ ratio = z/yu16;
+ //printf("%6d %6d %6d %f %f\n", x, y, yu16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < 0.996 || ratio > 1.07)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_divide32_tests(void)
+{
+ uint32_t xu32;
+ uint16_t yu16;
+ uint32_t yu32;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_divide32() function tests\n");
+ if (fixed_divide32(12345, 0) != 0xFFFF)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ min = 999999.0;
+ max = -999999.0;
+ for (yu32 = 32; yu32 < 65536; yu32 += 16)
+ {
+ for (xu32 = yu32*16; xu32 < 65535; xu32 += 16)
+ {
+ yu16 = fixed_divide32(yu32, xu32);
+ z = 32768.0*yu32/xu32;
+ ratio = z/yu16;
+ //printf("%6u %6u %6u %f %f\n", xu32, yu32, yu16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < 0.996 || ratio > 1.07)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_log10_16_tests(void)
+{
+ int x;
+ int16_t yi16;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("Log10 16 bit function tests\n");
+ min = 999999.0;
+ max = -999999.0;
+ for (x = 1; x < 32500; x++)
+ {
+ yi16 = fixed_log10_16(x);
+ z = 4096.0*log10(x/32768.0);
+ ratio = z - yi16;
+ //printf("%6d %15d %f %f\n", x, yi16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < -8.0 || ratio > 8.0)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_log10_32_tests(void)
+{
+ int x;
+ int32_t yi32;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_log10_32() function tests\n");
+ min = 999999.0;
+ max = -999999.0;
+ for (x = 1; x < 32767*65536; x += 0x4000)
+ {
+ yi32 = fixed_log10_32(x);
+ z = 4096.0*log10(x/(32768.0*65536.0));
+ ratio = z - yi32;
+ //printf("%6d %15d %f %f\n", x, yi32, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < -8.0 || ratio > 8.0)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_sqrt16_tests(void)
+{
+ int x;
+ uint16_t yu16;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_sqrt16() function tests\n");
+ min = 999999.0;
+ max = -999999.0;
+ for (x = 1; x < 65536; x++)
+ {
+ yu16 = fixed_sqrt16(x);
+ z = sqrt(x)*256.0;
+ ratio = z/yu16;
+ //printf("%6d %6d %f %f\n", x, yu16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < 0.999 || ratio > 1.008)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_sqrt32_tests(void)
+{
+ uint32_t xu32;
+ uint16_t yu16;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_sqrt32() function tests\n");
+ min = 999999.0;
+ max = -999999.0;
+ for (xu32 = 20000; xu32 < 0xFFFF0000; xu32 += 10000)
+ {
+ yu16 = fixed_sqrt32(xu32);
+ z = sqrt(xu32);
+ ratio = z/yu16;
+ //printf("%10u %6d %f %f\n", xu32, yu16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < 0.999 || ratio > 1.009)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_sin_tests(void)
+{
+ int x;
+ int16_t yi16;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_sin() function tests\n");
+ min = 999999.0;
+ max = -999999.0;
+ for (x = 0; x < 65536; x++)
+ {
+ yi16 = fixed_sin(x);
+ z = sin(2.0*3.1415926535*x/65536.0)*32768.0;
+ ratio = z - yi16;
+ //printf("%6d %6d %f %f\n", x, yi16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < -2.0 || ratio > 2.0)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_cos_tests(void)
+{
+ int x;
+ int16_t yi16;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_cos() function tests\n");
+ min = 999999.0;
+ max = -999999.0;
+ for (x = 0; x < 65536; x++)
+ {
+ yi16 = fixed_cos(x);
+ z = cos(2.0*3.1415926535*x/65536.0)*32768.0;
+ ratio = z - yi16;
+ //printf("%6d %6d %f %f\n", x, yi16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < -2.0 || ratio > 2.0)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+static void fixed_atan2_tests(void)
+{
+ int i;
+ int x;
+ int y;
+ uint16_t yu16;
+ double z;
+ double ratio;
+ double max;
+ double min;
+
+ printf("fixed_atan2() function tests\n");
+ min = 999999.0;
+ max = -999999.0;
+ for (i = 0; i < 65536; i++)
+ {
+ x = 16384.0*cos(i*2.0*3.1415926535/65536.0);
+ y = 16384.0*sin(i*2.0*3.1415926535/65536.0);
+ yu16 = fixed_atan2(y, x);
+ z = atan2(y/32768.0, x/32768.0)*65536.0/(2.0*3.1415926535);
+ if (z < 0.0)
+ z += 65536.0;
+ ratio = z - yu16;
+ //printf("%6d %6d %6d %6d %f %f\n", i, x, y, yu16, z, ratio);
+ if (ratio < min)
+ min = ratio;
+ if (ratio > max)
+ max = ratio;
+ if (ratio < -43.0 || ratio > 43.0)
+ {
+ printf("Test failed\n");
+ exit(2);
+ }
+ }
+ printf("min %f, max %f\n", min, max);
+ printf("Test passed\n");
+}
+/*- End of function --------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+ fixed_reciprocal16_tests();
+ fixed_divide16_tests();
+ fixed_divide32_tests();
+ fixed_log10_16_tests();
+ fixed_log10_32_tests();
+ fixed_sqrt16_tests();
+ fixed_sqrt32_tests();
+ fixed_sin_tests();
+ fixed_cos_tests();
+ fixed_atan2_tests();
+
+ printf("Tests passed\n");
+
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/