Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/src/dds_int.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
|---|---|
| date | Fri, 25 Jun 2010 15:50:58 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
|---|---|
| 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 Lesser General Public License version 2.1, | |
| 14 * as 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 Lesser General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU Lesser General Public | |
| 22 * License 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_int.c,v 1.16 2009/02/21 04:27:46 steveu Exp $ | |
| 26 */ | |
| 27 | |
| 28 /*! \file */ | |
| 29 | |
| 30 #if defined(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 #include "floating_fudge.h" | |
| 42 | |
| 43 #include "spandsp/telephony.h" | |
| 44 #include "spandsp/complex.h" | |
| 45 #include "spandsp/dds.h" | |
| 46 | |
| 47 #if !defined(M_PI) | |
| 48 # define M_PI 3.14159265358979323846 /* pi */ | |
| 49 #endif | |
| 50 | |
| 51 /* In a A-law or u-law channel, a 128 step sine table is adequate to keep the spectral | |
| 52 mess due to the DDS at a similar level to the spectral mess due to the A-law or u-law | |
| 53 compression. */ | |
| 54 #define SLENK 7 | |
| 55 #define DDS_STEPS (1 << SLENK) | |
| 56 #define DDS_SHIFT (32 - 2 - SLENK) | |
| 57 | |
| 58 /* This is a simple set of direct digital synthesis (DDS) functions to generate sine | |
| 59 waves. This version uses a 128 entry sin/cos table to cover one quadrant. */ | |
| 60 | |
| 61 static const int16_t sine_table[DDS_STEPS] = | |
| 62 { | |
| 63 201, | |
| 64 603, | |
| 65 1005, | |
| 66 1407, | |
| 67 1809, | |
| 68 2210, | |
| 69 2611, | |
| 70 3012, | |
| 71 3412, | |
| 72 3812, | |
| 73 4211, | |
| 74 4609, | |
| 75 5007, | |
| 76 5404, | |
| 77 5800, | |
| 78 6195, | |
| 79 6590, | |
| 80 6983, | |
| 81 7376, | |
| 82 7767, | |
| 83 8157, | |
| 84 8546, | |
| 85 8933, | |
| 86 9319, | |
| 87 9704, | |
| 88 10088, | |
| 89 10469, | |
| 90 10850, | |
| 91 11228, | |
| 92 11605, | |
| 93 11980, | |
| 94 12354, | |
| 95 12725, | |
| 96 13095, | |
| 97 13463, | |
| 98 13828, | |
| 99 14192, | |
| 100 14553, | |
| 101 14912, | |
| 102 15269, | |
| 103 15624, | |
| 104 15976, | |
| 105 16326, | |
| 106 16673, | |
| 107 17018, | |
| 108 17361, | |
| 109 17700, | |
| 110 18037, | |
| 111 18372, | |
| 112 18703, | |
| 113 19032, | |
| 114 19358, | |
| 115 19681, | |
| 116 20001, | |
| 117 20318, | |
| 118 20632, | |
| 119 20943, | |
| 120 21251, | |
| 121 21555, | |
| 122 21856, | |
| 123 22154, | |
| 124 22449, | |
| 125 22740, | |
| 126 23028, | |
| 127 23312, | |
| 128 23593, | |
| 129 23870, | |
| 130 24144, | |
| 131 24414, | |
| 132 24680, | |
| 133 24943, | |
| 134 25202, | |
| 135 25457, | |
| 136 25708, | |
| 137 25956, | |
| 138 26199, | |
| 139 26439, | |
| 140 26674, | |
| 141 26906, | |
| 142 27133, | |
| 143 27357, | |
| 144 27576, | |
| 145 27791, | |
| 146 28002, | |
| 147 28209, | |
| 148 28411, | |
| 149 28610, | |
| 150 28803, | |
| 151 28993, | |
| 152 29178, | |
| 153 29359, | |
| 154 29535, | |
| 155 29707, | |
| 156 29875, | |
| 157 30038, | |
| 158 30196, | |
| 159 30350, | |
| 160 30499, | |
| 161 30644, | |
| 162 30784, | |
| 163 30920, | |
| 164 31050, | |
| 165 31177, | |
| 166 31298, | |
| 167 31415, | |
| 168 31527, | |
| 169 31634, | |
| 170 31737, | |
| 171 31834, | |
| 172 31927, | |
| 173 32015, | |
| 174 32099, | |
| 175 32177, | |
| 176 32251, | |
| 177 32319, | |
| 178 32383, | |
| 179 32442, | |
| 180 32496, | |
| 181 32546, | |
| 182 32590, | |
| 183 32629, | |
| 184 32664, | |
| 185 32693, | |
| 186 32718, | |
| 187 32738, | |
| 188 32753, | |
| 189 32762, | |
| 190 32767, | |
| 191 }; | |
| 192 | |
| 193 SPAN_DECLARE(int32_t) dds_phase_rate(float frequency) | |
| 194 { | |
| 195 return (int32_t) (frequency*65536.0f*65536.0f/SAMPLE_RATE); | |
| 196 } | |
| 197 /*- End of function --------------------------------------------------------*/ | |
| 198 | |
| 199 SPAN_DECLARE(float) dds_frequency(int32_t phase_rate) | |
| 200 { | |
| 201 return (float) phase_rate*(float) SAMPLE_RATE/(65536.0f*65536.0f); | |
| 202 } | |
| 203 /*- End of function --------------------------------------------------------*/ | |
| 204 | |
| 205 SPAN_DECLARE(int16_t) dds_scaling_dbm0(float level) | |
| 206 { | |
| 207 return (int16_t) (powf(10.0f, (level - DBM0_MAX_SINE_POWER)/20.0f)*32767.0f); | |
| 208 } | |
| 209 /*- End of function --------------------------------------------------------*/ | |
| 210 | |
| 211 SPAN_DECLARE(int16_t) dds_scaling_dbov(float level) | |
| 212 { | |
| 213 return (int16_t) (powf(10.0f, (level - DBOV_MAX_SINE_POWER)/20.0f)*32767.0f); | |
| 214 } | |
| 215 /*- End of function --------------------------------------------------------*/ | |
| 216 | |
| 217 SPAN_DECLARE(int16_t) dds_lookup(uint32_t phase) | |
| 218 { | |
| 219 uint32_t step; | |
| 220 int16_t amp; | |
| 221 | |
| 222 phase >>= DDS_SHIFT; | |
| 223 step = phase & (DDS_STEPS - 1); | |
| 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 SPAN_DECLARE(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 SPAN_DECLARE(void) dds_advance(uint32_t *phase_acc, int32_t phase_rate) | |
| 240 { | |
| 241 *phase_acc += phase_rate; | |
| 242 } | |
| 243 /*- End of function --------------------------------------------------------*/ | |
| 244 | |
| 245 SPAN_DECLARE(int16_t) dds(uint32_t *phase_acc, int32_t phase_rate) | |
| 246 { | |
| 247 int16_t amp; | |
| 248 | |
| 249 amp = dds_lookup(*phase_acc); | |
| 250 *phase_acc += phase_rate; | |
| 251 return amp; | |
| 252 } | |
| 253 /*- End of function --------------------------------------------------------*/ | |
| 254 | |
| 255 SPAN_DECLARE(int16_t) dds_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase) | |
| 256 { | |
| 257 int16_t amp; | |
| 258 | |
| 259 amp = (int16_t) (((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15); | |
| 260 *phase_acc += phase_rate; | |
| 261 return amp; | |
| 262 } | |
| 263 /*- End of function --------------------------------------------------------*/ | |
| 264 | |
| 265 SPAN_DECLARE(complexi_t) dds_lookup_complexi(uint32_t phase) | |
| 266 { | |
| 267 return complex_seti(dds_lookup(phase + (1 << 30)), dds_lookup(phase)); | |
| 268 } | |
| 269 /*- End of function --------------------------------------------------------*/ | |
| 270 | |
| 271 SPAN_DECLARE(complexi_t) dds_complexi(uint32_t *phase_acc, int32_t phase_rate) | |
| 272 { | |
| 273 complexi_t amp; | |
| 274 | |
| 275 amp = complex_seti(dds_lookup(*phase_acc + (1 << 30)), dds_lookup(*phase_acc)); | |
| 276 *phase_acc += phase_rate; | |
| 277 return amp; | |
| 278 } | |
| 279 /*- End of function --------------------------------------------------------*/ | |
| 280 | |
| 281 SPAN_DECLARE(complexi_t) dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase) | |
| 282 { | |
| 283 complexi_t amp; | |
| 284 | |
| 285 amp = complex_seti(((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*(int32_t) scale) >> 15, | |
| 286 ((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15); | |
| 287 *phase_acc += phase_rate; | |
| 288 return amp; | |
| 289 } | |
| 290 /*- End of function --------------------------------------------------------*/ | |
| 291 | |
| 292 SPAN_DECLARE(complexi16_t) dds_lookup_complexi16(uint32_t phase) | |
| 293 { | |
| 294 return complex_seti16(dds_lookup(phase + (1 << 30)), dds_lookup(phase)); | |
| 295 } | |
| 296 /*- End of function --------------------------------------------------------*/ | |
| 297 | |
| 298 SPAN_DECLARE(complexi16_t) dds_complexi16(uint32_t *phase_acc, int32_t phase_rate) | |
| 299 { | |
| 300 complexi16_t amp; | |
| 301 | |
| 302 amp = complex_seti16(dds_lookup(*phase_acc + (1 << 30)), dds_lookup(*phase_acc)); | |
| 303 *phase_acc += phase_rate; | |
| 304 return amp; | |
| 305 } | |
| 306 /*- End of function --------------------------------------------------------*/ | |
| 307 | |
| 308 SPAN_DECLARE(complexi16_t) dds_complexi16_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase) | |
| 309 { | |
| 310 complexi16_t amp; | |
| 311 | |
| 312 amp = complex_seti16((int16_t) (((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*(int32_t) scale) >> 15), | |
| 313 (int16_t) (((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15)); | |
| 314 *phase_acc += phase_rate; | |
| 315 return amp; | |
| 316 } | |
| 317 /*- End of function --------------------------------------------------------*/ | |
| 318 | |
| 319 SPAN_DECLARE(complexi32_t) dds_lookup_complexi32(uint32_t phase) | |
| 320 { | |
| 321 return complex_seti32(dds_lookup(phase + (1 << 30)), dds_lookup(phase)); | |
| 322 } | |
| 323 /*- End of function --------------------------------------------------------*/ | |
| 324 | |
| 325 SPAN_DECLARE(complexi32_t) dds_complexi32(uint32_t *phase_acc, int32_t phase_rate) | |
| 326 { | |
| 327 complexi32_t amp; | |
| 328 | |
| 329 amp = complex_seti32(dds_lookup(*phase_acc + (1 << 30)), dds_lookup(*phase_acc)); | |
| 330 *phase_acc += phase_rate; | |
| 331 return amp; | |
| 332 } | |
| 333 /*- End of function --------------------------------------------------------*/ | |
| 334 | |
| 335 SPAN_DECLARE(complexi32_t) dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int16_t scale, int32_t phase) | |
| 336 { | |
| 337 complexi32_t amp; | |
| 338 | |
| 339 amp = complex_seti32(((int32_t) dds_lookup(*phase_acc + phase + (1 << 30))*(int32_t) scale) >> 15, | |
| 340 ((int32_t) dds_lookup(*phase_acc + phase)*(int32_t) scale) >> 15); | |
| 341 *phase_acc += phase_rate; | |
| 342 return amp; | |
| 343 } | |
| 344 /*- End of function --------------------------------------------------------*/ | |
| 345 /*- End of file ------------------------------------------------------------*/ |
