spandsp 0.0.6
|
00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * complex.h 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2003 Steve Underwood 00009 * 00010 * All rights reserved. 00011 * 00012 * This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU Lesser General Public License version 2.1, 00014 * as published by the Free Software Foundation. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00024 * 00025 * $Id: complex.h,v 1.20 2009/02/21 05:39:08 steveu Exp $ 00026 */ 00027 00028 /*! \file */ 00029 00030 /*! \page complex_page Complex number support 00031 \section complex_page_sec_1 What does it do? 00032 Complex number support is part of the C99 standard. However, support for this 00033 in C compilers is still patchy. A set of complex number feaures is provided as 00034 a "temporary" measure, until native C language complex number support is 00035 widespread. 00036 */ 00037 00038 #if !defined(_SPANDSP_COMPLEX_H_) 00039 #define _SPANDSP_COMPLEX_H_ 00040 00041 /*! 00042 Floating complex type. 00043 */ 00044 typedef struct 00045 { 00046 /*! \brief Real part. */ 00047 float re; 00048 /*! \brief Imaginary part. */ 00049 float im; 00050 } complexf_t; 00051 00052 /*! 00053 Floating complex type. 00054 */ 00055 typedef struct 00056 { 00057 /*! \brief Real part. */ 00058 double re; 00059 /*! \brief Imaginary part. */ 00060 double im; 00061 } complex_t; 00062 00063 #if defined(HAVE_LONG_DOUBLE) 00064 /*! 00065 Long double complex type. 00066 */ 00067 typedef struct 00068 { 00069 /*! \brief Real part. */ 00070 long double re; 00071 /*! \brief Imaginary part. */ 00072 long double im; 00073 } complexl_t; 00074 #endif 00075 00076 /*! 00077 Complex integer type. 00078 */ 00079 typedef struct 00080 { 00081 /*! \brief Real part. */ 00082 int re; 00083 /*! \brief Imaginary part. */ 00084 int im; 00085 } complexi_t; 00086 00087 /*! 00088 Complex 16 bit integer type. 00089 */ 00090 typedef struct 00091 { 00092 /*! \brief Real part. */ 00093 int16_t re; 00094 /*! \brief Imaginary part. */ 00095 int16_t im; 00096 } complexi16_t; 00097 00098 /*! 00099 Complex 32 bit integer type. 00100 */ 00101 typedef struct 00102 { 00103 /*! \brief Real part. */ 00104 int32_t re; 00105 /*! \brief Imaginary part. */ 00106 int32_t im; 00107 } complexi32_t; 00108 00109 #if defined(__cplusplus) 00110 extern "C" 00111 { 00112 #endif 00113 00114 static __inline__ complexf_t complex_setf(float re, float im) 00115 { 00116 complexf_t z; 00117 00118 z.re = re; 00119 z.im = im; 00120 return z; 00121 } 00122 /*- End of function --------------------------------------------------------*/ 00123 00124 static __inline__ complex_t complex_set(double re, double im) 00125 { 00126 complex_t z; 00127 00128 z.re = re; 00129 z.im = im; 00130 return z; 00131 } 00132 /*- End of function --------------------------------------------------------*/ 00133 00134 #if defined(HAVE_LONG_DOUBLE) 00135 static __inline__ complexl_t complex_setl(long double re, long double im) 00136 { 00137 complexl_t z; 00138 00139 z.re = re; 00140 z.im = im; 00141 return z; 00142 } 00143 /*- End of function --------------------------------------------------------*/ 00144 #endif 00145 00146 static __inline__ complexi_t complex_seti(int re, int im) 00147 { 00148 complexi_t z; 00149 00150 z.re = re; 00151 z.im = im; 00152 return z; 00153 } 00154 /*- End of function --------------------------------------------------------*/ 00155 00156 static __inline__ complexi16_t complex_seti16(int16_t re, int16_t im) 00157 { 00158 complexi16_t z; 00159 00160 z.re = re; 00161 z.im = im; 00162 return z; 00163 } 00164 /*- End of function --------------------------------------------------------*/ 00165 00166 static __inline__ complexi32_t complex_seti32(int32_t re, int32_t im) 00167 { 00168 complexi32_t z; 00169 00170 z.re = re; 00171 z.im = im; 00172 return z; 00173 } 00174 /*- End of function --------------------------------------------------------*/ 00175 00176 static __inline__ complexf_t complex_addf(const complexf_t *x, const complexf_t *y) 00177 { 00178 complexf_t z; 00179 00180 z.re = x->re + y->re; 00181 z.im = x->im + y->im; 00182 return z; 00183 } 00184 /*- End of function --------------------------------------------------------*/ 00185 00186 static __inline__ complex_t complex_add(const complex_t *x, const complex_t *y) 00187 { 00188 complex_t z; 00189 00190 z.re = x->re + y->re; 00191 z.im = x->im + y->im; 00192 return z; 00193 } 00194 /*- End of function --------------------------------------------------------*/ 00195 00196 #if defined(HAVE_LONG_DOUBLE) 00197 static __inline__ complexl_t complex_addl(const complexl_t *x, const complexl_t *y) 00198 { 00199 complexl_t z; 00200 00201 z.re = x->re + y->re; 00202 z.im = x->im + y->im; 00203 return z; 00204 } 00205 /*- End of function --------------------------------------------------------*/ 00206 #endif 00207 00208 static __inline__ complexi_t complex_addi(const complexi_t *x, const complexi_t *y) 00209 { 00210 complexi_t z; 00211 00212 z.re = x->re + y->re; 00213 z.im = x->im + y->im; 00214 return z; 00215 } 00216 /*- End of function --------------------------------------------------------*/ 00217 00218 static __inline__ complexi16_t complex_addi16(const complexi16_t *x, const complexi16_t *y) 00219 { 00220 complexi16_t z; 00221 00222 z.re = x->re + y->re; 00223 z.im = x->im + y->im; 00224 return z; 00225 } 00226 /*- End of function --------------------------------------------------------*/ 00227 00228 static __inline__ complexi32_t complex_addi32(const complexi32_t *x, const complexi32_t *y) 00229 { 00230 complexi32_t z; 00231 00232 z.re = x->re + y->re; 00233 z.im = x->im + y->im; 00234 return z; 00235 } 00236 /*- End of function --------------------------------------------------------*/ 00237 00238 static __inline__ complexf_t complex_subf(const complexf_t *x, const complexf_t *y) 00239 { 00240 complexf_t z; 00241 00242 z.re = x->re - y->re; 00243 z.im = x->im - y->im; 00244 return z; 00245 } 00246 /*- End of function --------------------------------------------------------*/ 00247 00248 static __inline__ complex_t complex_sub(const complex_t *x, const complex_t *y) 00249 { 00250 complex_t z; 00251 00252 z.re = x->re - y->re; 00253 z.im = x->im - y->im; 00254 return z; 00255 } 00256 /*- End of function --------------------------------------------------------*/ 00257 00258 #if defined(HAVE_LONG_DOUBLE) 00259 static __inline__ complexl_t complex_subl(const complexl_t *x, const complexl_t *y) 00260 { 00261 complexl_t z; 00262 00263 z.re = x->re - y->re; 00264 z.im = x->im - y->im; 00265 return z; 00266 } 00267 /*- End of function --------------------------------------------------------*/ 00268 #endif 00269 00270 static __inline__ complexi_t complex_subi(const complexi_t *x, const complexi_t *y) 00271 { 00272 complexi_t z; 00273 00274 z.re = x->re - y->re; 00275 z.im = x->im - y->im; 00276 return z; 00277 } 00278 /*- End of function --------------------------------------------------------*/ 00279 00280 static __inline__ complexi16_t complex_subi16(const complexi16_t *x, const complexi16_t *y) 00281 { 00282 complexi16_t z; 00283 00284 z.re = x->re - y->re; 00285 z.im = x->im - y->im; 00286 return z; 00287 } 00288 /*- End of function --------------------------------------------------------*/ 00289 00290 static __inline__ complexi32_t complex_subi32(const complexi32_t *x, const complexi32_t *y) 00291 { 00292 complexi32_t z; 00293 00294 z.re = x->re - y->re; 00295 z.im = x->im - y->im; 00296 return z; 00297 } 00298 /*- End of function --------------------------------------------------------*/ 00299 00300 static __inline__ complexf_t complex_mulf(const complexf_t *x, const complexf_t *y) 00301 { 00302 complexf_t z; 00303 00304 z.re = x->re*y->re - x->im*y->im; 00305 z.im = x->re*y->im + x->im*y->re; 00306 return z; 00307 } 00308 /*- End of function --------------------------------------------------------*/ 00309 00310 static __inline__ complex_t complex_mul(const complex_t *x, const complex_t *y) 00311 { 00312 complex_t z; 00313 00314 z.re = x->re*y->re - x->im*y->im; 00315 z.im = x->re*y->im + x->im*y->re; 00316 return z; 00317 } 00318 /*- End of function --------------------------------------------------------*/ 00319 00320 #if defined(HAVE_LONG_DOUBLE) 00321 static __inline__ complexl_t complex_mull(const complexl_t *x, const complexl_t *y) 00322 { 00323 complexl_t z; 00324 00325 z.re = x->re*y->re - x->im*y->im; 00326 z.im = x->re*y->im + x->im*y->re; 00327 return z; 00328 } 00329 /*- End of function --------------------------------------------------------*/ 00330 #endif 00331 00332 static __inline__ complexi_t complex_muli(const complexi_t *x, const complexi_t *y) 00333 { 00334 complexi_t z; 00335 00336 z.re = x->re*y->re - x->im*y->im; 00337 z.im = x->re*y->im + x->im*y->re; 00338 return z; 00339 } 00340 /*- End of function --------------------------------------------------------*/ 00341 00342 static __inline__ complexi16_t complex_muli16(const complexi16_t *x, const complexi16_t *y) 00343 { 00344 complexi16_t z; 00345 00346 z.re = (int16_t) ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im); 00347 z.im = (int16_t) ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re); 00348 return z; 00349 } 00350 /*- End of function --------------------------------------------------------*/ 00351 00352 static __inline__ complexi16_t complex_mul_q1_15(const complexi16_t *x, const complexi16_t *y) 00353 { 00354 complexi16_t z; 00355 00356 z.re = (int16_t) (((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 15); 00357 z.im = (int16_t) (((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 15); 00358 return z; 00359 } 00360 /*- End of function --------------------------------------------------------*/ 00361 00362 static __inline__ complexi32_t complex_muli32i16(const complexi32_t *x, const complexi16_t *y) 00363 { 00364 complexi32_t z; 00365 00366 z.re = x->re*(int32_t) y->re - x->im*(int32_t) y->im; 00367 z.im = x->re*(int32_t) y->im + x->im*(int32_t) y->re; 00368 return z; 00369 } 00370 /*- End of function --------------------------------------------------------*/ 00371 00372 static __inline__ complexi32_t complex_muli32(const complexi32_t *x, const complexi32_t *y) 00373 { 00374 complexi32_t z; 00375 00376 z.re = x->re*y->re - x->im*y->im; 00377 z.im = x->re*y->im + x->im*y->re; 00378 return z; 00379 } 00380 /*- End of function --------------------------------------------------------*/ 00381 00382 static __inline__ complexf_t complex_divf(const complexf_t *x, const complexf_t *y) 00383 { 00384 complexf_t z; 00385 float f; 00386 00387 f = y->re*y->re + y->im*y->im; 00388 z.re = ( x->re*y->re + x->im*y->im)/f; 00389 z.im = (-x->re*y->im + x->im*y->re)/f; 00390 return z; 00391 } 00392 /*- End of function --------------------------------------------------------*/ 00393 00394 static __inline__ complex_t complex_div(const complex_t *x, const complex_t *y) 00395 { 00396 complex_t z; 00397 double f; 00398 00399 f = y->re*y->re + y->im*y->im; 00400 z.re = ( x->re*y->re + x->im*y->im)/f; 00401 z.im = (-x->re*y->im + x->im*y->re)/f; 00402 return z; 00403 } 00404 /*- End of function --------------------------------------------------------*/ 00405 00406 #if defined(HAVE_LONG_DOUBLE) 00407 static __inline__ complexl_t complex_divl(const complexl_t *x, const complexl_t *y) 00408 { 00409 complexl_t z; 00410 long double f; 00411 00412 f = y->re*y->re + y->im*y->im; 00413 z.re = ( x->re*y->re + x->im*y->im)/f; 00414 z.im = (-x->re*y->im + x->im*y->re)/f; 00415 return z; 00416 } 00417 /*- End of function --------------------------------------------------------*/ 00418 #endif 00419 00420 static __inline__ complexf_t complex_conjf(const complexf_t *x) 00421 { 00422 complexf_t z; 00423 00424 z.re = x->re; 00425 z.im = -x->im; 00426 return z; 00427 } 00428 /*- End of function --------------------------------------------------------*/ 00429 00430 static __inline__ complex_t complex_conj(const complex_t *x) 00431 { 00432 complex_t z; 00433 00434 z.re = x->re; 00435 z.im = -x->im; 00436 return z; 00437 } 00438 /*- End of function --------------------------------------------------------*/ 00439 00440 #if defined(HAVE_LONG_DOUBLE) 00441 static __inline__ complexl_t complex_conjl(const complexl_t *x) 00442 { 00443 complexl_t z; 00444 00445 z.re = x->re; 00446 z.im = -x->im; 00447 return z; 00448 } 00449 /*- End of function --------------------------------------------------------*/ 00450 #endif 00451 00452 static __inline__ complexi_t complex_conji(const complexi_t *x) 00453 { 00454 complexi_t z; 00455 00456 z.re = x->re; 00457 z.im = -x->im; 00458 return z; 00459 } 00460 /*- End of function --------------------------------------------------------*/ 00461 00462 static __inline__ complexi16_t complex_conji16(const complexi16_t *x) 00463 { 00464 complexi16_t z; 00465 00466 z.re = x->re; 00467 z.im = -x->im; 00468 return z; 00469 } 00470 /*- End of function --------------------------------------------------------*/ 00471 00472 static __inline__ complexi32_t complex_conji32(const complexi32_t *x) 00473 { 00474 complexi32_t z; 00475 00476 z.re = x->re; 00477 z.im = -x->im; 00478 return z; 00479 } 00480 /*- End of function --------------------------------------------------------*/ 00481 00482 static __inline__ float powerf(const complexf_t *x) 00483 { 00484 return x->re*x->re + x->im*x->im; 00485 } 00486 /*- End of function --------------------------------------------------------*/ 00487 00488 static __inline__ double power(const complex_t *x) 00489 { 00490 return x->re*x->re + x->im*x->im; 00491 } 00492 /*- End of function --------------------------------------------------------*/ 00493 00494 #if defined(HAVE_LONG_DOUBLE) 00495 static __inline__ long double powerl(const complexl_t *x) 00496 { 00497 return x->re*x->re + x->im*x->im; 00498 } 00499 /*- End of function --------------------------------------------------------*/ 00500 #endif 00501 00502 #if defined(__cplusplus) 00503 } 00504 #endif 00505 00506 #endif 00507 /*- End of file ------------------------------------------------------------*/