00001 /**********************************************************/ 00002 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00003 /* 00004 Copyright: 1994 - Grupo de Voz (DAET) ETSII/IT-Bilbao 00005 00006 Nombre fuente................ LPCROOTS.CPP 00007 Nombre paquete............... SPL 00008 Lenguaje fuente.............. C++ (Borland C/C++ 3.1) 00009 Estado....................... Completado 00010 Dependencia Hard/OS.......... - 00011 Codigo condicional........... LP_NEGSUM 00012 00013 Codificacion................. Borja Etxebarria 00014 00015 Version dd/mm/aa Autor Proposito de la edicion 00016 ------- -------- -------- ----------------------- 00017 1.2.0 24/10/97 Borja cambio en lp_Aroots() (root_init) 00018 1.1.3 24/06/97 Borja bug en lp_Aroots() 00019 1.1.2 04/03/97 Borja eliminar uso de constructor complex(x,y) 00020 1.1.1 30/07/95 Borja scope funciones explicito 00021 1.1.0 08/12/94 Borja revision general (tipos,idx,nel,tnel...) 00022 1.0.0 06/07/93 Borja Codificacion inicial. 00023 00024 ======================== Contenido ======================== 00025 <DOC> 00026 Calculo de polos en analisis predictivo, utilizando el 00027 algoritmo de Laguerre para extraccion de raices complejas. 00028 00029 Hay codigo condicional, en funcion de como se envien los 00030 coeficientes LPC (sumatorio positivo o negativo: ver SPL5?.c 00031 controlado por el define LP_NEGSUM 00032 </DOC> 00033 =========================================================== 00034 */ 00035 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00036 /**********************************************************/ 00037 00038 #ifndef __cplusplus 00039 #error Must use C++ compiler 00040 #endif 00041 00042 /**********************************************************/ 00043 00044 #include "spl.h" 00045 #include "zroots.hpp" 00046 #include "lpcroots.hpp" 00047 00048 #ifdef __CC_MSVC__ 00049 _STD_BEGIN 00050 #endif 00051 00052 /* <DOC> */ 00053 /**********************************************************/ 00054 /* a partir de los coeficientes lpc de orden {p} en el vector 00055 {vai} ({p} elementos), calcula los ceros del A(z) (polos de H(z)) 00056 utilizando el metodo de laguerre para el calculo de raices complejas. 00057 00058 La funcion {devuelve} el numero de polos encontrados, o un numero 00059 negativo en caso de que laguerre() produzca algun error (mirar 00060 laguerre() en zroots.cpp). 00061 Los polos se almacenan como numeros complejos en el array {Roots} (de 00062 {p} elementos). 00063 La funcion necesita un array temporal de tnel_lp_Aroots(p) elementos 00064 de tipo SPL_COMPLEX. */ 00065 00066 PUBLIC SPL_INT XAPI lp_Aroots( SPL_pFLOAT vai, SPL_INT p, 00067 SPL_pCOMPLEX Roots, SPL_pCOMPLEX Tmp, SPL_BOOL root_init ) 00068 /* </DOC> */ 00069 { 00070 SPL_INT i, NumRoots; 00071 00072 #ifdef LP_NEGSUM 00073 for (i=0; i<p; i++) // crea polinomio complejo 00074 Tmp[i] = -vai[p-i-1]; 00075 #else 00076 for (i=0; i<p; i++) // crea polinomio complejo 00077 Tmp[i] = vai[p-i-1]; 00078 #endif 00079 Tmp[p]=1.0; 00080 00081 if (root_init) 00082 for (i=0; i<p; i++) Roots[i]=0; 00083 00084 i=laguerre(Tmp,p,Roots,NumRoots,Tmp+(p+1),ZROOTS_MAXITER,ZROOTS_TOL); 00085 00086 if (i>=0) 00087 return NumRoots; 00088 else 00089 return i; 00090 } 00091 00092 /* <DOC> */ 00093 /**********************************************************/ 00094 /* {devuelve} el numero de elementos de tipo SPL_COMPLEX que debe 00095 enviarse en el array temporal {Tmp} a lp_Aroots(), para un 00096 analisis de orden {p} */ 00097 00098 PUBLIC SPL_INT XAPI tnel_lp_Aroots( SPL_INT p ) 00099 /* </DOC> */ 00100 { 00101 return tnel_laguerre(p)+(p+1); 00102 } 00103 00104 /* <DOC> */ 00105 /**********************************************************/ 00106 /*convierte los polos en frecuencias y ancho de banda. 00107 Para {NumRoots} polos pasados en el array {Roots}, devuelve 00108 las correspondientes frecuencias y anchos de banda en los 00109 arrays {f} y {bw} (de {NumRoots} elementos cada uno). 00110 La frecuencia de muestreo se indica en {freq}. */ 00111 00112 PUBLIC SPL_VOID XAPI lp_roots2fbw( SPL_pCOMPLEX Roots, SPL_INT NumRoots, 00113 SPL_pFLOAT f, SPL_pFLOAT bw, SPL_FLOAT freq ) 00114 /* </DOC> */ 00115 { 00116 SPL_INT i; 00117 SPL_FLOAT d; 00118 00119 for (i=0; i<NumRoots; i++) { 00120 if (fabs(imag(Roots[i]))<=ZROOTS_TOL) 00121 //redondea a eje real 00122 d = (real(Roots[i])>=0) ? 0.0:M_PI; 00123 else 00124 d=arg(Roots[i]); 00125 if (d<0.0) // pasa de -Pi,Pi a 0,2*Pi 00126 d+=(2*M_PI); 00127 00128 f[i]= rad2hz(d,freq); 00129 bw[i]=r2bw(abs(Roots[i]),freq); 00130 } 00131 } 00132 00133 /**********************************************************/ 00134 00135 #ifdef __CC_MSVC__ 00136 _STD_END 00137 #endif