5
|
1 /*
|
|
2 * SpanDSP - a series of DSP components for telephony
|
|
3 *
|
|
4 * dc_restore.h - General telephony routines to restore the zero D.C.
|
|
5 * level to audio which has a D.C. bias.
|
|
6 *
|
|
7 * Written by Steve Underwood <steveu@coppice.org>
|
|
8 *
|
|
9 * Copyright (C) 2001 Steve Underwood
|
|
10 *
|
|
11 * All rights reserved.
|
|
12 *
|
|
13 * This program is free software; you can redistribute it and/or modify
|
|
14 * it under the terms of the GNU General Public License version 2, as
|
|
15 * published by the Free Software Foundation.
|
|
16 *
|
|
17 * This program is distributed in the hope that it will be useful,
|
|
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20 * GNU General Public License for more details.
|
|
21 *
|
|
22 * You should have received a copy of the GNU General Public License
|
|
23 * along with this program; if not, write to the Free Software
|
|
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
25 *
|
|
26 * $Id: dc_restore.h,v 1.15 2006/12/01 18:00:48 steveu Exp $
|
|
27 */
|
|
28
|
|
29 /*! \file */
|
|
30
|
|
31 #if !defined(_DC_RESTORE_H_)
|
|
32 #define _DC_RESTORE_H_
|
|
33
|
|
34 /*! \page dc_restore_page Removing DC bias from a signal
|
|
35
|
|
36 \section dc_restore_page_sec_1 What does it do?
|
|
37
|
|
38 Telecoms signals often contain considerable DC, but DC upsets a lot of signal
|
|
39 processing functions. Placing a zero DC restorer at the front of the processing
|
|
40 chain can often simplify the downstream processing.
|
|
41
|
|
42 \section dc_restore_page_sec_2 How does it work?
|
|
43
|
|
44 The DC restorer uses a leaky integrator to provide a long-ish term estimate of
|
|
45 the DC bias in the signal. A 32 bit estimate is used for the 16 bit audio, so
|
|
46 the noise introduced by the estimation can be keep in the lower bits, and the 16
|
|
47 bit DC value, which is subtracted from the signal, is fairly clean. The
|
|
48 following code fragment shows the algorithm used. dc_bias is a 32 bit integer,
|
|
49 while the sample and the resulting clean_sample are 16 bit integers.
|
|
50
|
|
51 dc_bias += ((((int32_t) sample << 15) - dc_bias) >> 14);
|
|
52 clean_sample = sample - (dc_bias >> 15);
|
|
53 */
|
|
54
|
|
55 /*!
|
|
56 Zero DC restoration descriptor. This defines the working state for a single
|
|
57 instance of DC content filter.
|
|
58 */
|
|
59 typedef struct
|
|
60 {
|
|
61 int32_t state;
|
|
62 } dc_restore_state_t;
|
|
63
|
|
64 #ifdef __cplusplus
|
|
65 extern "C" {
|
|
66 #endif
|
|
67
|
|
68 static __inline__ void dc_restore_init(dc_restore_state_t *dc)
|
|
69 {
|
|
70 dc->state = 0;
|
|
71 }
|
|
72 /*- End of function --------------------------------------------------------*/
|
|
73
|
|
74 static __inline__ int16_t dc_restore(dc_restore_state_t *dc, int16_t sample)
|
|
75 {
|
|
76 dc->state += ((((int32_t) sample << 15) - dc->state) >> 14);
|
|
77 return (int16_t) (sample - (dc->state >> 15));
|
|
78 }
|
|
79 /*- End of function --------------------------------------------------------*/
|
|
80
|
|
81 static __inline__ int16_t dc_restore_estimate(dc_restore_state_t *dc)
|
|
82 {
|
|
83 return (int16_t) (dc->state >> 15);
|
|
84 }
|
|
85 /*- End of function --------------------------------------------------------*/
|
|
86
|
|
87 static __inline__ int16_t saturate(int32_t amp)
|
|
88 {
|
|
89 int16_t amp16;
|
|
90
|
|
91 /* Hopefully this is optimised for the common case - not clipping */
|
|
92 amp16 = (int16_t) amp;
|
|
93 if (amp == amp16)
|
|
94 return amp16;
|
|
95 if (amp > INT16_MAX)
|
|
96 return INT16_MAX;
|
|
97 return INT16_MIN;
|
|
98 }
|
|
99 /*- End of function --------------------------------------------------------*/
|
|
100
|
|
101 static __inline__ int16_t fsaturatef(float famp)
|
|
102 {
|
|
103 if (famp > 32767.0)
|
|
104 return INT16_MAX;
|
|
105 if (famp < -32768.0)
|
|
106 return INT16_MIN;
|
|
107 return (int16_t) rintf(famp);
|
|
108 }
|
|
109 /*- End of function --------------------------------------------------------*/
|
|
110
|
|
111 static __inline__ int16_t fsaturate(double damp)
|
|
112 {
|
|
113 if (damp > 32767.0)
|
|
114 return INT16_MAX;
|
|
115 if (damp < -32768.0)
|
|
116 return INT16_MIN;
|
|
117 return (int16_t) rint(damp);
|
|
118 }
|
|
119 /*- End of function --------------------------------------------------------*/
|
|
120
|
|
121 #ifdef __cplusplus
|
|
122 }
|
|
123 #endif
|
|
124
|
|
125 #endif
|
|
126 /*- End of file ------------------------------------------------------------*/
|