00001 /**********************************************************/ 00002 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00003 /* 00004 Copyright: 1994 - Grupo de Voz (DAET) ETSII/IT-Bilbao 00005 00006 Nombre fuente................ SPL10.C 00007 Nombre paquete............... SPL 00008 Lenguaje fuente.............. C (Borland C/C++ 3.1) 00009 Estado....................... Completado 00010 Dependencia Hard/OS.......... - 00011 Codigo condicional........... NDEBUG 00012 00013 Codificacion................. Borja Etxebarria 00014 00015 Version dd/mm/aa Autor Proposito de la edicion 00016 ------- -------- -------- ----------------------- 00017 2.0.1 23/03/99 Borja hz2l2() l22hz() 00018 2.0.0 01/07/97 Borja units.c --> spl10.c 00019 1.3.1 01/07/97 Borja froundf, float2int salen de SPL (uti_math) 00020 1.3.0 01/05/97 Borja xnormalize->snormalize, norm_i16, froundf... 00021 1.2.2 22/04/97 Borja quitar warnings en g++ 00022 1.2.1 30/07/95 Borja scope funciones explicito 00023 1.2.0 30/07/95 Borja sqa2dB() ---> aa2dB(), etc. (sqa-->aa) 00024 1.1.0 08/12/94 Borja revision general (tipos,idx,nel,tnel...) 00025 1.0.0 06/07/93 Borja Codificacion inicial. 00026 00027 ======================== Contenido ======================== 00028 Conversion entre diversas unidades. 00029 00030 Definir NDEBUG para desconectar la validacion de parametros 00031 con assert(). No definir este simbolo mientras se depuren 00032 aplicaciones, ya que aunque las funciones son algo mas lentas, 00033 el chequeo de validacion de parametros resuelve muchos problemas. 00034 =========================================================== 00035 */ 00036 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00037 /**********************************************************/ 00038 00039 #include <math.h> 00040 #include <assert.h> 00041 00042 #include "spli.h" 00043 00044 /**********************************************************/ 00045 00046 #define N10DLN10 4.342944819032518280 00047 #define N20DLN10 (N10DLN10*2.0) 00048 00049 /*<DOC>*/ 00050 /**********************************************************/ 00051 /* convierte y {devuelve} {samples} de muestras a milisegundos, 00052 si la frecuencia de muestreo es {freq}. 00053 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00054 00055 PUBLIC SPL_FLOAT XAPI samples2ms( SPL_FLOAT samples, SPL_FLOAT freq ) 00056 /*</DOC>*/ 00057 { 00058 assert(freq!=0.0); 00059 if (!freq) return 0.0; 00060 return (samples*1000.0)/freq; 00061 } 00062 00063 /*<DOC>*/ 00064 /**********************************************************/ 00065 /* convierte y {devuelve} {ms} de milisegundos a muestras, 00066 si la frecuencia de muestreo es {freq}. 00067 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00068 00069 PUBLIC SPL_FLOAT XAPI ms2samples( SPL_FLOAT ms, SPL_FLOAT freq ) 00070 /*</DOC>*/ 00071 { 00072 assert(freq!=0.0); 00073 return (ms*freq)/1000.0; 00074 } 00075 00076 /*<DOC>*/ 00077 /**********************************************************/ 00078 /* convierte y {devuelve} un periodo de {samples} muestras a 00079 Hz, si la frecuencia de muestreo es {freq}. 00080 Si {samples}==0 {devuelve} 0. 00081 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00082 00083 PUBLIC SPL_FLOAT XAPI samples2hz( SPL_FLOAT samples, SPL_FLOAT freq ) 00084 /*</DOC>*/ 00085 { 00086 assert(freq!=0.0); 00087 return ((!samples) ? 0.0 : freq/samples); 00088 } 00089 00090 /*<DOC>*/ 00091 /**********************************************************/ 00092 /* convierte y {devuelve} una frecuencia de {hz} Herzios a periodo 00093 en muestras, si la frecuencia de muestreo es {freq}. 00094 Si {hz}==0 {devuelve} 0. 00095 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00096 00097 PUBLIC SPL_FLOAT XAPI hz2samples( SPL_FLOAT hz, SPL_FLOAT freq ) 00098 /*</DOC>*/ 00099 { 00100 assert(freq!=0.0); 00101 return ((!hz) ? 0.0 : freq/hz); 00102 } 00103 00104 /*<DOC>*/ 00105 /**********************************************************/ 00106 /* convierte y {devuelve} una frecuencia de {hz} Herzios a periodo 00107 en milisegundos. Si {hz}==0 {devuelve} 0 */ 00108 00109 PUBLIC SPL_FLOAT XAPI hz2ms( SPL_FLOAT hz ) 00110 /*</DOC>*/ 00111 { 00112 return ((!hz) ? 0.0 : 1000.0/hz); 00113 } 00114 00115 /*<DOC>*/ 00116 /**********************************************************/ 00117 /* convierte y {devuelve} un periodo de {ms} milisegundos a 00118 frecuencia en herzios. Si {ms}==0 devuelve 0 */ 00119 00120 PUBLIC SPL_FLOAT XAPI ms2hz( SPL_FLOAT ms ) 00121 /*</DOC>*/ 00122 { 00123 return ((!ms) ? 0.0 : 1000.0/ms); 00124 } 00125 00126 /*<DOC>*/ 00127 /**********************************************************/ 00128 /* convierte y {devuelve} la frecuencia {hz} Herzios a radianes, 00129 si la frecuencia de muestreo es {freq}. 00130 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00131 00132 PUBLIC SPL_FLOAT XAPI hz2rad( SPL_FLOAT hz, SPL_FLOAT freq ) 00133 /*</DOC>*/ 00134 { 00135 assert(freq!=0.0); 00136 if (!freq) return 0.0; 00137 return (hz*(2.0*M_PI))/freq; 00138 } 00139 00140 /*<DOC>*/ 00141 /**********************************************************/ 00142 /* convierte y {devuelve} la frecuencia {rad} radianes a Herzios, 00143 si la frecuencia de muestreo es {freq}. 00144 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00145 00146 PUBLIC SPL_FLOAT XAPI rad2hz( SPL_FLOAT rad, SPL_FLOAT freq ) 00147 /*</DOC>*/ 00148 { 00149 assert(freq!=0.0); 00150 return (rad*freq)/(2.0*M_PI); 00151 } 00152 00153 /*<DOC>*/ 00154 /**********************************************************/ 00155 /* convierte y {devuelve} la frecuencia {hz} herzios 00156 a LogHz (log2(Hz)). Si {Hz}<=1 {devuelve} 0. */ 00157 00158 PUBLIC SPL_FLOAT XAPI hz2lhz( SPL_FLOAT hz ) 00159 /*</DOC>*/ 00160 { 00161 return hz>1?lin2log2(hz):0; 00162 } 00163 00164 /*<DOC>*/ 00165 /**********************************************************/ 00166 /* convierte y {devuelve} la frecuencia {l2} LogHz=log2(Hz)) 00167 a Hz. Si {l2}<=0 {devuelve} 0. */ 00168 00169 PUBLIC SPL_FLOAT XAPI lhz2hz( SPL_FLOAT l2 ) 00170 /*</DOC>*/ 00171 { 00172 return l2>0?log22lin(l2):0; 00173 } 00174 00175 /*<DOC>*/ 00176 /**********************************************************/ 00177 /* convierte y {devuelve} la frecuencia {hz} herzios 00178 a LnHz (ln(Hz)). Si {Hz}<=e {devuelve} 0. */ 00179 00180 PUBLIC SPL_FLOAT XAPI hz2lnhz( SPL_FLOAT hz ) 00181 /*</DOC>*/ 00182 { 00183 return hz>M_E?lin2ln(hz):0; 00184 } 00185 00186 /*<DOC>*/ 00187 /**********************************************************/ 00188 /* convierte y {devuelve} la frecuencia {lnhz} LnHz=ln(Hz)) 00189 a Hz. Si {lnhz}<=0 {devuelve} 0. */ 00190 00191 PUBLIC SPL_FLOAT XAPI lnhz2hz( SPL_FLOAT lnhz ) 00192 /*</DOC>*/ 00193 { 00194 return lnhz>0?ln2lin(lnhz):0; 00195 } 00196 00197 /*<DOC>*/ 00198 /**********************************************************/ 00199 /* Funciones similares a hz2lhz() y lhz2hz() pero para 00200 otras unidades (muestras y milisegundos): 00201 00202 ms2lms() 00203 lms2ms() 00204 samples2lsamples() 00205 lsamples2samples() 00206 */ 00207 /*</DOC>*/ 00208 /* definido en spl.h */ 00209 00210 00211 /*<DOC>*/ 00212 /**********************************************************/ 00213 /* Esta funcion sirve para calcular el ancho de banda a partir de 00214 la posicion de un polo dentro del circulo de radio unidad. 00215 Convierte y {devuelve} el radio {r} ({r}<1) en ancho de banda. 00216 {freq} es la frecuencia de muestreo. 00217 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00218 00219 PUBLIC SPL_FLOAT XAPI r2bw( SPL_FLOAT r, SPL_FLOAT freq ) 00220 /*</DOC>*/ 00221 { 00222 assert(freq!=0.0); 00223 return (rad2hz(-2.0*log((r<DB_MIN_A)?DB_MIN_A:r),freq)); 00224 } 00225 00226 /*<DOC>*/ 00227 /**********************************************************/ 00228 /* Esta funcion sirve para calcular la posicion de un polo (dentro 00229 del circulo de radio unidad) a partir del ancho de banda. 00230 convierte y {devuelve} el ancho de banda {bw} en radio r (r<1). 00231 {freq} es la frecuencia de muestreo. 00232 Si {frec}==0 error, o si NDEBUG activado, {devuelve} 0. */ 00233 00234 PUBLIC SPL_FLOAT XAPI bw2r( SPL_FLOAT bw, SPL_FLOAT freq ) 00235 /*</DOC>*/ 00236 { 00237 assert(freq!=0.0); 00238 return (exp(-hz2rad(bw,freq)/2.0)); 00239 } 00240 00241 /*<DOC>*/ 00242 /**********************************************************/ 00243 /* convierte y {devuelve} la amplitud lineal {a} a dB, teniendo en 00244 cuenta que el m¡nimo permitido en amplitud lineal es DB_MIN_A para 00245 evitar que se produzca una singularidad (log(0)=-INF) */ 00246 00247 PUBLIC SPL_FLOAT XAPI a2db( SPL_FLOAT a ) 00248 /*</DOC>*/ 00249 { 00250 assert(a>=0); 00251 return 20.0*log10((a<DB_MIN_A)?DB_MIN_A:a); 00252 } 00253 00254 /*<DOC>*/ 00255 /**********************************************************/ 00256 /* convierte y {devuelve} {db} de dB a amplitud lineal */ 00257 00258 PUBLIC SPL_FLOAT XAPI db2a( SPL_FLOAT db ) 00259 /*</DOC>*/ 00260 { 00261 return exp(db/(N20DLN10)); 00262 } 00263 00264 /*<DOC>*/ 00265 /**********************************************************/ 00266 /* convierte y {devuelve} de la amplitud al cuadrado {aa} a dB 00267 teniendo en cuenta que la amplitud cuadrada minima es DB_MIN_AA */ 00268 00269 PUBLIC SPL_FLOAT XAPI aa2db( SPL_FLOAT aa ) 00270 /*</DOC>*/ 00271 { 00272 assert(aa>=0); 00273 return 10.0*log10((aa<DB_MIN_AA)?DB_MIN_AA:aa); 00274 } 00275 00276 /*<DOC>*/ 00277 /**********************************************************/ 00278 /* convierte y {devuelve} {db} de dB a amplitud lineal al cuadrado */ 00279 00280 PUBLIC SPL_FLOAT XAPI db2aa( SPL_FLOAT db ) 00281 /*</DOC>*/ 00282 { 00283 return exp(db/(N10DLN10)); 00284 } 00285 00286 /*<DOC>*/ 00287 /**********************************************************/ 00288 /* convierte y {devuelve} de amplitud lineal {a} a bedelios (Bd) siendo 00289 la definicion del Bd: Bd = 10 * log10 ( {a}*{a} + 1 ) */ 00290 00291 PUBLIC SPL_FLOAT XAPI a2bd( SPL_FLOAT a ) 00292 /*</DOC>*/ 00293 { 00294 assert(a>=0); 00295 return 10.0*log10(a*a+1.0); 00296 } 00297 00298 /*<DOC>*/ 00299 /**********************************************************/ 00300 /* convierte y {devuelve} {bd} de bedelios a amplitud lineal */ 00301 00302 PUBLIC SPL_FLOAT XAPI bd2a( SPL_FLOAT bd ) 00303 /*</DOC>*/ 00304 { 00305 return sqrt(exp(bd/N10DLN10)-1.0); 00306 } 00307 00308 /*<DOC>*/ 00309 /**********************************************************/ 00310 /* convierte y {devuelve} {aa} de amplitud lineal al cuadrado 00311 a bedelios */ 00312 00313 PUBLIC SPL_FLOAT XAPI aa2bd( SPL_FLOAT aa ) 00314 /*</DOC>*/ 00315 { 00316 assert(aa>=0); 00317 return 10.0*log10(aa+1.0); 00318 } 00319 00320 /*<DOC>*/ 00321 /**********************************************************/ 00322 /* convierte y {devuelve} {bd} de bedelios a amplitud lineal al cuadrado */ 00323 00324 PUBLIC SPL_FLOAT XAPI bd2aa( SPL_FLOAT bd ) 00325 /*</DOC>*/ 00326 { 00327 return exp(bd/N10DLN10)-1.0; 00328 } 00329 00330 /*<DOC>*/ 00331 /**********************************************************/ 00332 /* normaliza (escala) el valor {n} al rango +-1, 00333 de forma que {neg1} pasa ser -1 y {pos1} pasa a ser +1. 00334 Si {n} se sale del rango {neg1,pos1} el valor normalizado 00335 tambien se sale del rango {-1,+1}. 00336 {neg1}!={pos1}, si no da 0. */ 00337 00338 PUBLIC SPL_FLOAT XAPI normalize( SPL_FLOAT n, SPL_FLOAT neg1, 00339 SPL_FLOAT pos1 ) 00340 /*</DOC>*/ 00341 { 00342 assert(neg1!=pos1); 00343 if (neg1==pos1) return 0; 00344 return ((n-neg1)*2.0)/(pos1-neg1)-1.0; 00345 } 00346 00347 /*<DOC>*/ 00348 /**********************************************************/ 00349 /* desnormaliza el valor {n} que va entre -+1 y lo pasa al valor 00350 que toque para el escalado -1--->{neg1} y +1--->{pos1}. 00351 Si {n} se sale de {-1,+1} el valor desnormalizado tambien se sale 00352 del rango {neg1,pos1} */ 00353 00354 PUBLIC SPL_FLOAT XAPI unnormalize( SPL_FLOAT n, SPL_FLOAT neg1, 00355 SPL_FLOAT pos1 ) 00356 /*</DOC>*/ 00357 { 00358 return neg1+((n+1.0)*(pos1-neg1))/2.0; 00359 } 00360 00361 /*<DOC>*/ 00362 /**********************************************************/ 00363 /* como normalize pero no permite que el valor escalado se salga 00364 de rango, truncandolo (saturando) a {-1,+1}. 00365 {neg1}!={pos1}, si no da 0. */ 00366 00367 PUBLIC SPL_FLOAT XAPI snormalize( SPL_FLOAT n, SPL_FLOAT neg1, 00368 SPL_FLOAT pos1 ) 00369 /*</DOC>*/ 00370 { 00371 SPL_FLOAT d = normalize(n,neg1,pos1); 00372 if (d>1.0) 00373 return 1.0; 00374 else if (d<-1.0) 00375 return -1.0; 00376 else 00377 return d; 00378 } 00379 00380 /*<DOC>*/ 00381 /**********************************************************/ 00382 /* como unnormalize pero no permite que el valor deescalado se 00383 salga de rango, truncandolo (saturando a {neg1, pos1} */ 00384 00385 PUBLIC SPL_FLOAT XAPI sunnormalize( SPL_FLOAT n, SPL_FLOAT neg1, 00386 SPL_FLOAT pos1 ) 00387 /*</DOC>*/ 00388 { 00389 if (n<-1.0) 00390 return unnormalize(-1.0,neg1,pos1); 00391 else if (n>1.0) 00392 return unnormalize(1.0,neg1,pos1); 00393 else 00394 return unnormalize(n,neg1,pos1); 00395 } 00396 00397 /*<DOC>*/ 00398 /**********************************************************/ 00399 /* Normaliza a +-1 un INT16 */ 00400 00401 PUBLIC SPL_FLOAT XAPI norm_i16( INT16 i16 ) 00402 /*</DOC>*/ 00403 { 00404 return ((SPL_FLOAT)i16)/((SPL_FLOAT)INT16_RANGE); 00405 } 00406 00407 /*<DOC>*/ 00408 /**********************************************************/ 00409 /* Desnormaliza de +-1 a rango INT16 */ 00410 00411 PUBLIC INT16 XAPI unnorm_i16( SPL_FLOAT f ) 00412 /*</DOC>*/ 00413 { 00414 f *= INT16_RANGE; 00415 if (f>=0) return (INT16)(f+0.5); 00416 return (INT16)(f-0.5); 00417 } 00418 00419 /*<DOC>*/ 00420 /**********************************************************/ 00421 /* Desnormaliza de +-1 a rango INT16 00422 SPL_FLOAT snorm_i16( INT16 i16) */ 00423 /*</DOC>*/ 00424 /* definido en spl.h */ 00425 00426 /* #define snorm_i16(i16) norm_i16(i16) */ 00427 00428 00429 /*<DOC>*/ 00430 /**********************************************************/ 00431 /* Desnormaliza de +-1 a rango INT16, saturando si hace falta. */ 00432 00433 PUBLIC INT16 XAPI sunnorm_i16( SPL_FLOAT f ) 00434 /*</DOC>*/ 00435 { 00436 f *= INT16_RANGE; 00437 if (f>=INT16_MAX) return INT16_MAX; 00438 else if (f<=INT16_MIN) return INT16_MIN; 00439 else if (f>=0) return (INT16)(f+0.5); 00440 return (INT16)(f-0.5); 00441 } 00442 00443 /*<DOC>*/ 00444 /**********************************************************/ 00445 /* Calcula el log2(x), con tope inferior para x<LOG2_MIN. */ 00446 00447 PUBLIC SPL_FLOAT XAPI lin2log2( SPL_FLOAT x ) 00448 /*</DOC>*/ 00449 { 00450 return log((x<LOG2_MIN )?LOG2_MIN :x)/M_LN2; 00451 } 00452 00453 /*<DOC>*/ 00454 /**********************************************************/ 00455 /* Calcula el antilog2(x) */ 00456 00457 PUBLIC SPL_FLOAT XAPI log22lin( SPL_FLOAT x ) 00458 /*</DOC>*/ 00459 { 00460 return pow(2,x); 00461 } 00462 00463 /**********************************************************/ 00464 /* Calcula el ln(x), con tope inferior para x<LN_MIN. */ 00465 00466 PUBLIC SPL_FLOAT XAPI lin2ln( SPL_FLOAT x ) 00467 /*</DOC>*/ 00468 { 00469 return log((x<LN_MIN )?LN_MIN :x); 00470 } 00471 00472 /*<DOC>*/ 00473 /**********************************************************/ 00474 /* Calcula el antilog2(x) 00475 00476 SPL_FLOAT XAPI ln2lin( SPL_FLOAT x ); 00477 </DOC> */ 00478 00479 /* definido en spl.h */ 00480 00481 /*#define ln2lin(x) exp(x)*/ 00482 00483 /**********************************************************/