5
|
1 /*
|
|
2 * SpanDSP - a series of DSP components for telephony
|
|
3 *
|
|
4 * dds.c
|
|
5 *
|
|
6 * Written by Steve Underwood <steveu@coppice.org>
|
|
7 *
|
|
8 * Copyright (C) 2003 Steve Underwood
|
|
9 *
|
|
10 * All rights reserved.
|
|
11 *
|
|
12 * This program is free software; you can redistribute it and/or modify
|
|
13 * it under the terms of the GNU General Public License version 2, as
|
|
14 * published by the Free Software Foundation.
|
|
15 *
|
|
16 * This program is distributed in the hope that it will be useful,
|
|
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19 * GNU General Public License for more details.
|
|
20 *
|
|
21 * You should have received a copy of the GNU General Public License
|
|
22 * along with this program; if not, write to the Free Software
|
|
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
24 *
|
|
25 * $Id: dds.c,v 1.17 2006/11/19 14:07:24 steveu Exp $
|
|
26 */
|
|
27
|
|
28 /*! \file */
|
|
29
|
|
30 #ifdef HAVE_CONFIG_H
|
|
31 #include <config.h>
|
|
32 #endif
|
|
33
|
|
34 #include <inttypes.h>
|
|
35 #if defined(HAVE_TGMATH_H)
|
|
36 #include <tgmath.h>
|
|
37 #endif
|
|
38 #if defined(HAVE_MATH_H)
|
|
39 #include <math.h>
|
|
40 #endif
|
|
41
|
|
42 #include "spandsp/telephony.h"
|
|
43 #include "spandsp/dds.h"
|
|
44
|
|
45 #if !defined(M_PI)
|
|
46 # define M_PI 3.14159265358979323846 /* pi */
|
|
47 #endif
|
|
48
|
|
49 /* In a A-law or u-law channel, and 128 step sine table is adequate to keep the spectral
|
|
50 mess due to the DDS at a similar level to the spectral mess due to the A-law or u-law
|
|
51 compression. */
|
|
52 #define SLENK 7
|
|
53 #define DDS_STEPS (1 << SLENK)
|
|
54 #define DDS_SHIFT (32 - 2 - SLENK)
|
|
55
|
|
56 /* This is a simple set of direct digital synthesis (DDS) functions to generate sine
|
|
57 waves. This version uses a 128 entry sin/cos table to cover one quadrant. */
|
|
58
|
|
59 static const int16_t sine_table[DDS_STEPS] =
|
|
60 {
|
|
61 201,
|
|
62 603,
|
|
63 1005,
|
|
64 1407,
|
|
65 1809,
|
|
66 2210,
|
|
67 2611,
|
|
68 3012,
|
|
69 3412,
|
|
70 3812,
|
|
71 4211,
|
|
72 4609,
|
|
73 5007,
|
|
74 5404,
|
|
75 5800,
|
|
76 6195,
|
|
77 6590,
|
|
78 6983,
|
|
79 7376,
|
|
80 7767,
|
|
81 8157,
|
|
82 8546,
|
|
83 8933,
|
|
84 9319,
|
|
85 9704,
|
|
86 10088,
|
|
87 10469,
|
|
88 10850,
|
|
89 11228,
|
|
90 11605,
|
|
91 11980,
|
|
92 12354,
|
|
93 12725,
|
|
94 13095,
|
|
95 13463,
|
|
96 13828,
|
|
97 14192,
|
|
98 14553,
|
|
99 14912,
|
|
100 15269,
|
|
101 15624,
|
|
102 15976,
|
|
103 16326,
|
|
104 16673,
|
|
105 17018,
|
|
106 17361,
|
|
107 17700,
|
|
108 18037,
|
|
109 18372,
|
|
110 18703,
|
|
111 19032,
|
|
112 19358,
|
|
113 19681,
|
|
114 20001,
|
|
115 20318,
|
|
116 20632,
|
|
117 20943,
|
|
118 21251,
|
|
119 21555,
|
|
120 21856,
|
|
121 22154,
|
|
122 22449,
|
|
123 22740,
|
|
124 23028,
|
|
125 23312,
|
|
126 23593,
|
|
127 23870,
|
|
128 24144,
|
|
129 24414,
|
|
130 24680,
|
|
131 24943,
|
|
132 25202,
|
|
133 25457,
|
|
134 25708,
|
|
135 25956,
|
|
136 26199,
|
|
137 26439,
|
|
138 26674,
|
|
139 26906,
|
|
140 27133,
|
|
141 27357,
|
|
142 27576,
|
|
143 27791,
|
|
144 28002,
|
|
145 28209,
|
|
146 28411,
|
|
147 28610,
|
|
148 28803,
|
|
149 28993,
|
|
150 29178,
|
|
151 29359,
|
|
152 29535,
|
|
153 29707,
|
|
154 29875,
|
|
155 30038,
|
|
156 30196,
|
|
157 30350,
|
|
158 30499,
|
|
159 30644,
|
|
160 30784,
|
|
161 30920,
|
|
162 31050,
|
|
163 31177,
|
|
164 31298,
|
|
165 31415,
|
|
166 31527,
|
|
167 31634,
|
|
168 31737,
|
|
169 31834,
|
|
170 31927,
|
|
171 32015,
|
|
172 32099,
|
|
173 32177,
|
|
174 32251,
|
|
175 32319,
|
|
176 32383,
|
|
177 32442,
|
|
178 32496,
|
|
179 32546,
|
|
180 32590,
|
|
181 32629,
|
|
182 32664,
|
|
183 32693,
|
|
184 32718,
|
|
185 32738,
|
|
186 32753,
|
|
187 32762,
|
|
188 32767,
|
|
189 };
|
|
190
|
|
191 int32_t dds_phase_rate(float frequency)
|
|
192 {
|
|
193 return (int32_t) (frequency*65536.0f*65536.0f/SAMPLE_RATE);
|
|
194 }
|
|
195 /*- End of function --------------------------------------------------------*/
|
|
196
|
|
197 float dds_frequency(int32_t phase_rate)
|
|
198 {
|
|
199 return (float) phase_rate*(float) SAMPLE_RATE/(65536.0f*65536.0f);
|
|
200 }
|
|
201 /*- End of function --------------------------------------------------------*/
|
|
202
|
|
203 int dds_scaling_dbm0(float level)
|
|
204 {
|
|
205 return (int) (powf(10.0f, (level - DBM0_MAX_POWER)/20.0f)*(32767.0f*1.414214f));
|
|
206 }
|
|
207 /*- End of function --------------------------------------------------------*/
|
|
208
|
|
209 int dds_scaling_dbov(float level)
|
|
210 {
|
|
211 return (int) (powf(10.0f, (level + 3.02f)/20.0f)*(32767.0f*1.414214f));
|
|
212 }
|
|
213 /*- End of function --------------------------------------------------------*/
|
|
214
|
|
215 int16_t dds_lookup(uint32_t phase)
|
|
216 {
|
|
217 uint32_t step;
|
|
218 uint32_t fred;
|
|
219 int16_t amp;
|
|
220
|
|
221 phase >>= DDS_SHIFT;
|
|
222 step = phase & (DDS_STEPS - 1);
|
|
223 fred = step;
|
|
224 if ((phase & DDS_STEPS))
|
|
225 step = (DDS_STEPS - 1) - step;
|
|
226 amp = sine_table[step];
|
|
227 if ((phase & (2*DDS_STEPS)))
|
|
228 amp = -amp;
|
|
229 return amp;
|
|
230 }
|
|
231 /*- End of function --------------------------------------------------------*/
|
|
232
|
|
233 int16_t dds_offset(uint32_t phase_acc, int32_t phase_offset)
|
|
234 {
|
|
235 return dds_lookup(phase_acc + phase_offset);
|
|
236 }
|
|
237 /*- End of function --------------------------------------------------------*/
|
|
238
|
|
239 int16_t dds(uint32_t *phase_acc, int32_t phase_rate)
|
|
240 {
|
|
241 int16_t amp;
|
|
242
|
|
243 amp = dds_lookup(*phase_acc);
|
|
244 *phase_acc += phase_rate;
|
|
245 return amp;
|
|
246 }
|
|
247 /*- End of function --------------------------------------------------------*/
|
|
248
|
|
249 int16_t dds_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase)
|
|
250 {
|
|
251 int16_t amp;
|
|
252
|
|
253 amp = (int16_t) ((dds_lookup(*phase_acc + phase)*scale) >> 15);
|
|
254 *phase_acc += phase_rate;
|
|
255 return amp;
|
|
256 }
|
|
257 /*- End of function --------------------------------------------------------*/
|
|
258
|
|
259 icomplex_t dds_complex(uint32_t *phase_acc, int32_t phase_rate)
|
|
260 {
|
|
261 icomplex_t amp;
|
|
262
|
|
263 amp.re = dds_lookup(*phase_acc + (1 << 30));
|
|
264 amp.im = dds_lookup(*phase_acc);
|
|
265 *phase_acc += phase_rate;
|
|
266 return amp;
|
|
267 }
|
|
268 /*- End of function --------------------------------------------------------*/
|
|
269
|
|
270 icomplex_t dds_complex_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase)
|
|
271 {
|
|
272 icomplex_t amp;
|
|
273
|
|
274 amp.re = (dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15;
|
|
275 amp.im = (dds_lookup(*phase_acc + phase)*scale) >> 15;
|
|
276 *phase_acc += phase_rate;
|
|
277 return amp;
|
|
278 }
|
|
279 /*- End of function --------------------------------------------------------*/
|
|
280 /*- End of file ------------------------------------------------------------*/
|