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