diff --git a/libs/spandsp/src/Makefile.am b/libs/spandsp/src/Makefile.am index 6b448ee46e..8e7cef6005 100644 --- a/libs/spandsp/src/Makefile.am +++ b/libs/spandsp/src/Makefile.am @@ -16,7 +16,7 @@ ## License along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ## -## $Id: Makefile.am,v 1.104 2008/09/20 15:44:40 steveu Exp $ +## $Id: Makefile.am,v 1.105 2008/09/30 18:12:42 steveu Exp $ AM_CFLAGS = $(COMP_VENDOR_CFLAGS) AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS) @@ -162,6 +162,7 @@ nobase_include_HEADERS = spandsp/adsi.h \ spandsp/plc.h \ spandsp/power_meter.h \ spandsp/queue.h \ + spandsp/saturated.h \ spandsp/schedule.h \ spandsp/sig_tone.h \ spandsp/silence_gen.h \ diff --git a/libs/spandsp/src/libspandsp.dsp b/libs/spandsp/src/libspandsp.dsp index fc6cda3186..b81b25850e 100644 --- a/libs/spandsp/src/libspandsp.dsp +++ b/libs/spandsp/src/libspandsp.dsp @@ -563,6 +563,10 @@ SOURCE=.\spandsp/queue.h # End Source File # Begin Source File +SOURCE=.\spandsp/saturated.h +# End Source File +# Begin Source File + SOURCE=.\spandsp/schedule.h # End Source File # Begin Source File diff --git a/libs/spandsp/src/libspandsp.vcproj b/libs/spandsp/src/libspandsp.vcproj index 3ba6d04195..65bec35e43 100644 --- a/libs/spandsp/src/libspandsp.vcproj +++ b/libs/spandsp/src/libspandsp.vcproj @@ -296,6 +296,7 @@ + diff --git a/libs/spandsp/src/spandsp/saturated.h b/libs/spandsp/src/spandsp/saturated.h new file mode 100644 index 0000000000..61cc702054 --- /dev/null +++ b/libs/spandsp/src/spandsp/saturated.h @@ -0,0 +1,199 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * saturated.h - General saturated arithmetic routines. + * + * Written by Steve Underwood + * + * Copyright (C) 2001, 2008 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. + * + * $Id: saturated.h,v 1.1 2008/09/19 14:02:05 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_SATURATED_H_) +#define _SPANDSP_SATURATED_H_ + +/*! \page saturated_page Saturated arithmetic + +\section saturated_page_sec_1 What does it do? + + +\section saturated_page_sec_2 How does it work? + +*/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +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 --------------------------------------------------------*/ + +/*! Saturate to 15 bits, rather than the usual 16 bits. This is often a useful function. */ +static __inline__ int16_t saturate15(int32_t amp) +{ + if (amp > 16383) + return 16383; + if (amp < -16384) + return -16384; + return (int16_t) amp; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t fsaturatef(float famp) +{ + if (famp > (float) INT16_MAX) + return INT16_MAX; + if (famp < (float) INT16_MIN) + return INT16_MIN; + return (int16_t) rintf(famp); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t fsaturate(double damp) +{ + if (damp > (double) INT16_MAX) + return INT16_MAX; + if (damp < (double) INT16_MIN) + return INT16_MIN; + return (int16_t) rint(damp); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ float ffsaturatef(float famp) +{ + if (famp > (float) INT16_MAX) + return (float) INT16_MAX; + if (famp < (float) INT16_MIN) + return (float) INT16_MIN; + return famp; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ double ffsaturate(double famp) +{ + if (famp > (double) INT16_MAX) + return (double) INT16_MAX; + if (famp < (double) INT16_MIN) + return (double) INT16_MIN; + return famp; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t saturated_add16(int16_t a, int16_t b) +{ +#if defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__( + " addw %2,%0;\n" + " jno 0f;\n" + " movw $0x7fff,%0;\n" + " adcw $0,%0;\n" + "0:" + : "=r" (a) + : "0" (a), "ir" (b) + : "cc" + ); + return a; +#else + return saturate((int32_t) a + (int32_t) b); +#endif +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int32_t saturated_add32(int32_t a, int32_t b) +{ +#if defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__( + " addl %2,%0;\n" + " jno 0f;\n" + " movl $0x7fffffff,%0;\n" + " adcl $0,%0;\n" + "0:" + : "=r" (a) + : "0" (a), "ir" (b) + : "cc" + ); + return a; +#else + uint32_t A; + + if (a < 0) + { + if (b >= 0) + return a + b; + /*endif*/ + A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1); + return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2; + } + /*endif*/ + if (b <= 0) + return a + b; + /*endif*/ + A = (uint32_t) a + (uint32_t) b; + return (A > INT32_MAX) ? INT32_MAX : A; +#endif +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t saturated_sub16(int16_t a, int16_t b) +{ + return saturate((int32_t) a - (int32_t) b); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t saturated_mul16(int16_t a, int16_t b) +{ + if (a == INT16_MIN && b == INT16_MIN) + return INT16_MAX; + /*endif*/ + return (int16_t) (((int32_t) a*(int32_t) b) >> 15); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int32_t saturated_mul_16_32(int16_t a, int16_t b) +{ + return ((int32_t) a*(int32_t) b) << 1; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t saturated_abs16(int16_t a) +{ + return (a == INT16_MIN) ? INT16_MAX : (int16_t) abs(a); +} +/*- End of function --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/spandsp/version.h b/libs/spandsp/src/spandsp/version.h index 3385f4aaaa..3e6ff19625 100644 --- a/libs/spandsp/src/spandsp/version.h +++ b/libs/spandsp/src/spandsp/version.h @@ -30,8 +30,8 @@ /* The date and time of the version are in UTC form. */ -#define SPANDSP_RELEASE_DATE 20080928 -#define SPANDSP_RELEASE_TIME 144338 +#define SPANDSP_RELEASE_DATE 20080930 +#define SPANDSP_RELEASE_TIME 181513 #endif /*- End of file ------------------------------------------------------------*/