dc_restore.h

Go to the documentation of this file.
00001 /*
00002  * SpanDSP - a series of DSP components for telephony
00003  *
00004  * dc_restore.h - General telephony routines to restore the zero D.C.
00005  *                level to audio which has a D.C. bias.
00006  *
00007  * Written by Steve Underwood <steveu@coppice.org>
00008  *
00009  * Copyright (C) 2001 Steve Underwood
00010  *
00011  * All rights reserved.
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU Lesser General Public License version 2.1,
00015  * as published by the Free Software Foundation.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public
00023  * License along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025  *
00026  * $Id: dc_restore.h,v 1.21 2008/04/17 14:27:00 steveu Exp $
00027  */
00028 
00029 /*! \file */
00030 
00031 #if !defined(_SPANDSP_DC_RESTORE_H_)
00032 #define _SPANDSP_DC_RESTORE_H_
00033 
00034 /*! \page dc_restore_page Removing DC bias from a signal
00035 
00036 \section dc_restore_page_sec_1 What does it do?
00037 
00038 Telecoms signals often contain considerable DC, but DC upsets a lot of signal
00039 processing functions. Placing a zero DC restorer at the front of the processing
00040 chain can often simplify the downstream processing. 
00041 
00042 \section dc_restore_page_sec_2 How does it work?
00043 
00044 The DC restorer uses a leaky integrator to provide a long-ish term estimate of
00045 the DC bias in the signal. A 32 bit estimate is used for the 16 bit audio, so
00046 the noise introduced by the estimation can be keep in the lower bits, and the 16
00047 bit DC value, which is subtracted from the signal, is fairly clean. The
00048 following code fragment shows the algorithm used. dc_bias is a 32 bit integer,
00049 while the sample and the resulting clean_sample are 16 bit integers. 
00050 
00051     dc_bias += ((((int32_t) sample << 15) - dc_bias) >> 14);
00052     clean_sample = sample - (dc_bias >> 15); 
00053 */
00054 
00055 /*!
00056     Zero DC restoration descriptor. This defines the working state for a single
00057     instance of DC content filter.
00058 */
00059 typedef struct
00060 {
00061     int32_t state;
00062 } dc_restore_state_t;
00063 
00064 #if defined(__cplusplus)
00065 extern "C"
00066 {
00067 #endif
00068 
00069 static __inline__ void dc_restore_init(dc_restore_state_t *dc)
00070 {
00071     dc->state = 0;
00072 }
00073 /*- End of function --------------------------------------------------------*/
00074 
00075 static __inline__ int16_t dc_restore(dc_restore_state_t *dc, int16_t sample)
00076 {
00077     dc->state += ((((int32_t) sample << 15) - dc->state) >> 14);
00078     return (int16_t) (sample - (dc->state >> 15));
00079 }
00080 /*- End of function --------------------------------------------------------*/
00081 
00082 static __inline__ int16_t dc_restore_estimate(dc_restore_state_t *dc)
00083 {
00084     return (int16_t) (dc->state >> 15);
00085 }
00086 /*- End of function --------------------------------------------------------*/
00087 
00088 #ifdef _MSC_VER
00089 __inline float rintf(float flt)
00090 {
00091         _asm
00092         {       fld flt
00093                 frndint
00094         }
00095 }
00096 /*- End of function --------------------------------------------------------*/
00097 
00098 __inline double rint(double dbl)
00099 {
00100     __asm 
00101         {
00102         fld dbl
00103         frndint
00104     }
00105 }
00106 /*- End of function --------------------------------------------------------*/
00107 
00108 __inline long lrintf(float flt)
00109 {
00110         long retval;
00111 
00112         _asm
00113         {       fld flt
00114                 fistp retval
00115         }
00116         return retval;
00117 }
00118 /*- End of function --------------------------------------------------------*/
00119 #endif
00120 
00121 static __inline__ int16_t saturate(int32_t amp)
00122 {
00123     int16_t amp16;
00124 
00125     /* Hopefully this is optimised for the common case - not clipping */
00126     amp16 = (int16_t) amp;
00127     if (amp == amp16)
00128         return amp16;
00129     if (amp > INT16_MAX)
00130         return  INT16_MAX;
00131     return  INT16_MIN;
00132 }
00133 /*- End of function --------------------------------------------------------*/
00134 
00135 static __inline__ int16_t fsaturatef(float famp)
00136 {
00137     if (famp > 32767.0)
00138         return  INT16_MAX;
00139     if (famp < -32768.0)
00140         return  INT16_MIN;
00141     return (int16_t) rintf(famp);
00142 }
00143 /*- End of function --------------------------------------------------------*/
00144 
00145 static __inline__ int16_t fsaturate(double damp)
00146 {
00147     if (damp > 32767.0)
00148         return  INT16_MAX;
00149     if (damp < -32768.0)
00150         return  INT16_MIN;
00151     return (int16_t) rint(damp);
00152 }
00153 /*- End of function --------------------------------------------------------*/
00154 
00155 #if defined(__cplusplus)
00156 }
00157 #endif
00158 
00159 #endif
00160 /*- End of file ------------------------------------------------------------*/

Generated on Sat Oct 5 11:04:48 2013 for libspandsp by  doxygen 1.4.6